Follow-ups from the #1023 process-owner reviews: usage emit order, detach checkpoint, stall guard, Ref state

Aperta
#1,029 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
42/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
backend, testing

Direzione di ricerca

Start with the two prioritized failure windows in packages/agents/src/harness/claude/claude.ts (resume) and packages/agents/src/child-host/process.ts (the lifecycle.isStopping finalizer branch); read the linked #1023 review comments for the full reports. Add the specified replay cases and wait for history to drain before the checkpoint heartbeat. Run the relevant agents tests; done means the replacement-launch and late-ack reattach cases retain the correct session total and checkpoint history.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Follow-ups from the independent reviews of #1023 (merged as 9e30c8cd). None blocks a release; the first two are small and have a concrete failure window, so do them first. The review comments on #1023 carry the full reports.

Fix first
  1. Restart usage is emitted after the replacement launch (packages/agents/src/harness/claude/claude.ts, resume, the SessionTokensUpdated emit after launchWithRetries). An orchestrator stop during that launch retains the replacement with the old processUsage, and the old process's usage is dropped from the session total on the next reattach. Emit the restart usage right after Scope.close(current.scope), before launchWithRetries. Add a replay case: stop during the replacement launch, reattach, assert the total.
  2. Detach finalizer reads delivered once (packages/agents/src/child-host/process.ts, the lifecycle.isStopping branch of the finalizer). A hook response acked after that read, about 50 ms plus the SSH round trip, replays the request and everything after it. Wait for history to drain within the existing 5 s timeout before sending the checkpoint heartbeat.
  3. Replayed assistant messages are counted again on a retained meter (packages/agents/src/harness/usage.ts, claudeTokenMeter with a seed). Same window as item 2. Seed the meter's per-message map from the checkpoint, or skip assistant usage for message ids already covered by processUsage.
Checkpoint hardening
  1. No stall guard for a control_request that is never answered (packages/agents/src/harness/claude/sdk.ts, claudeOutputCheckpoint). Today every subtype usine can receive gets a response (verified on SDK 0.3.311: hooks only, bypassPermissions, no canUseTool, MCP, elicitation or dialog handlers). A future option would stall the checkpoint for the whole session. Release a request when its control_cancel_request is read, and log the subtype of any request still pending when a result is handled. Add a test for a blocked hook still pending at the main turn's result (the mutation "result releases requests" survives today).
  2. Lines split on \n only, while the SDK's readline also splits on a lone \r. Only raw non-JSON output can trigger it. Match the SDK.
  3. Test gaps where a mutation survives: the owner ignoring skip on resume (assert in buffered-result that no ToolFinished or TextOutput is emitted before REPLAY_DONE); acknowledging before handling in drain; a control_response split across two input frames.
Effect shape
  1. Mutable closures shared across fibers: pending, input, answered in claudeOutputCheckpoint (three fibers), pending and delivered in remoteProcess (two fibers; today the worst case is an older delivered written after a newer one, more replay, never less), let acknowledgeOutput in child-host/sdk.ts reassigned from the forked runProcess with a silent drop before the spawn. One Ref with Ref.modify per owner, and a Deferred for the handle.
  2. readOutput is typed with a SessionOperationError it never produces. send in remoteProcess decodes the Base64 it encoded one line earlier; keep the bytes. remoteProcess, startChildProcess and sdkProcessSpawner now take six positional arguments; take an options record.
  3. A ChildProcessLost during the resume launch fails an idle or paused child. Accepted bound; revisit only if #603 shows a wake-sleep-wake pattern.
Observed once

The full @usine/agents suite failed once in five Linux container runs right after a mutation loop (288 passed otherwise); the failing test name was not captured and the failure did not reproduce. Watch test (rest) on main for a flaky agents test.

Lingua principale
TypeScript
Stelle
1
Fork
0
Merge medio
3h 47m
PR unite (30g)
388

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di basaltbytes/usine

Tutte le issue di basaltbytes/usine

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.