Repository navigation
feat(signals): run agent tasks in parallel with session and resource locks - #34
Open
jannikluhn wants to merge 5 commits into
Open
jannikluhn wants to merge 5 commits into
jannikluhn wants to merge 5 commits into
Conversation
… it carries A Signal Handler mints a random tag per Prompt, writes it into the Prompt text and sets it as tag on the Prompt. The agent echoes it as the concorde-run-tag header; the Worker holds live tags only while their Runs are in flight, and request.concordeRun names the Run whose tag the request carries or nothing, with no fallback to the Run in flight. A request with no header, an unknown tag or a dead tag is attributed to no Run. A Prompt whose tag is already live on another Run fails instead of taking that Run's identity. The template Handler takes a tag function and exposes the value to the template. The isolation example mints the tag and enforces its per-Run rule. The Runtime never sees the tag and nothing is stored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A queued Run starts when no earlier unfinished Run, running or waiting, names its Session; the queue is rescanned from the head on every Run end, so order among conflicting Runs is emission order. Signals are still claimed and handled one at a time, the next one only when every queued Run has started. A Signal's post phase runs once its last Run ends, Signals settle in whatever order their Runs finish, stop lets every claimed Run reach its outcome, and recovery after a restart is unchanged. Each Run's tag stays its own while Runs overlap. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A Signal Handler writes resources, an optional read-only array of strings, on a Prompt; two Runs sharing any Resource never overlap and keep their emission order. The Session is never in the array and is held separately. The template Handler takes a resources function of the Signal. The Runtime never sees the field and nothing is stored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two Users' Runs in flight at once each resolve only to their own tag, at the Worker seam through the probe route and at the Gateway seam through the cross-User hook, and a request from one Run carrying the other Run's tag is attributed to the other Run, which is the documented limit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s post phase A Run whose Handler has a post phase stays queued after it ends, until that phase returns, so a later Signal's Run in the same Session or sharing a Resource waits for the post phase too, which may still be using what the Run held. A Run whose Handler has no post phase releases at its end as before, and an ended Run never blocks a Run of its own Signal, which the post phase is waiting for. The Handler doc now also states that handle of a later Signal runs while earlier Signals' Runs and post phases are in flight. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This branch has not been deployed
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 this does
The signal worker currently runs one agent task at a time, so one user's task can hold up everyone else. This change lets runs execute in parallel when they use different sessions and resources. Runs that share either still execute in order.
Each handler can list the resources a prompt needs exclusive access to, such as a workspace, an account, or a user's budget. The worker starts a run once no earlier unfinished run uses the same session or any of those resources.
Without any resource declarations, runs in different sessions can run in parallel automatically. Resource names act as exclusive locks: any two runs naming the same resource must wait for each other. There is no configurable concurrency limit.
What a handler gains
type Prompt = { session: string | null text: string usageLimit?: number context?: unknown + resources?: readonly string[] // resources this run needs exclusive access to + tag?: string // random run tag, also included in the prompt text }Matching an agent server request to its run
With several runs active, the agent server needs a way to tell which run sent a request. The handler generates a random tag, includes it in the prompt text, and tells the agent to send it in the
concorde-run-tagheader. The worker looks up that tag and setsrequest.concordeRunto the matching run's metadata.sequenceDiagram participant H as Signal handler participant W as Signal worker participant A as Agent instance participant S as Agent server H->>W: Prompt containing the tag in text and tag fields W->>A: Start run and register its tag A->>S: Request with concorde-run-tag header S->>W: Look up tag W-->>S: request.concordeRun = { id, signalId, session, context } Note over S: Missing, unknown, or expired tag leaves concordeRun undefined W->>W: Remove tag when the run endsThe server never guesses based on which runs are active, even if there is only one. Tags help prevent injected message text from impersonating another run, but they do not provide access control. Runs share the agent instance's filesystem, where another session's tag can be read. This limitation is documented in the architecture guide.
Commits
postcallback finishes.The runtime interface stays the same. Reported validation:
npm run checkpasses. Gateway tests checkrequest.concordeRunthrough actual HTTP requests; worker tests use a fake runtime with controlled pauses to check ordering and parallel execution.