Add webhookUrl terminal callback to /repo/agent and make request state durable#1482
Merged
Conversation
…e durable
- POST /repo/agent (non-streaming) accepts an optional webhookUrl; the
terminal payload ({request_id, status, result|error} — same shape as
GET /progress) is POSTed to it with retries when the run completes or
fails, so callers no longer need a poll loop alive for the life of
the run. Best-effort: delivery can never affect the recorded status,
and /progress remains the fallback.
- Isolate bus.emit on both terminal paths so a post-completion side
effect throwing can no longer flip a just-written "completed" status
to "failed" via the promise .catch.
- reqs.ts: checkReq now reads the .reqs/<id>.json file directly instead
of gating on the in-memory META map, so a process restart no longer
404s a completed run whose file survived; finishReq/failReq write to
disk even when the entry was evicted past MAX_REQS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Long-running
/repo/agentconsumers (e.g. Hive'sworkflow_explorer_agent) currently pull results viaGET /progressfrom inside a duration-capped lambda — runs longer than the caller's poll budget lose their result even though the swarm finished fine. This flips delivery from pull to push and hardens the request-state layer.webhookUrl terminal callback
POST /repo/agent(non-streaming path) accepts an optionalwebhookUrlin the body. When the run reaches a terminal state, the swarm POSTs:{ request_id, status: "completed", result: { success, final_answer, content, tool_use, usage, sessionId } }{ request_id, status: "failed", error }(aborts arrive aserror: "aborted")Same shape as
GET /progress, withrequest_idadded for correlation. Delivery retries 3× (0s / +5s / +30s, 15s timeout each) and is strictly best-effort — it can never affect the run's recorded status, and/progresspolling still works as a fallback. The URL is opaque to the swarm; callers embed their own auth (per-run token / JWT) in it.Completion-race fix
bus.emiton both terminal paths is now isolated in try/catch, so a post-completion side effect throwing can no longer fall into the promise.catch()and overwrite a just-writtencompletedstatus withfailed.Durable request state (reqs.ts)
checkReqreads the.reqs/<id>.jsonfile directly instead of gating on the in-memoryMETAmap — a process restart no longer 404s a completed run whose file survived on disk.finishReq/failReqwrite to disk even when the entry was evicted pastMAX_REQS, so a long run outliving eviction still records its terminal state.Testing
tsc --noEmitclean.startReq+finishReq, a fresh process (emptyMETA)checkReqs the id — previouslyundefined(404), now returns the completed result.🤖 Generated with Claude Code