You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Accept a clientRequestId retry key on t3_thread_launch
#16186
Let agents pass a clientRequestId to t3_thread_launch so that retrying a launch after an error or lost response returns the thread already created instead of launching another one, matching the retry contract of the other mutating orchestration tools.
Problem to solve
t3_thread_launch is the tool agents use for user-requested independent work in its own worktree. Its description says "Each call creates a new launch with no retry key; retain threadId and use t3_thread_read/t3_thread_wait to follow preparation. After errors or lost responses, inspect t3_thread_list before retrying." When a launch response is lost (client timeout, transport error, server restart), the agent cannot tell whether the thread exists. A blind retry creates a second thread, a second worktree and branch, and a second agent working on the same task. Inspecting t3_thread_list first is a manual, racy check while the first launch is still in its preparing state, and agents frequently skip it. delegate_task, create_threads, schedule_task, t3_thread_send, t3_thread_interrupt, and thread metadata updates already accept clientRequestId, so launch is the outlier.
Proposed behavior
t3_thread_launch accepts an optional clientRequestId. Calls without it behave as today. A call that repeats the same clientRequestId with the same caller scope returns the same threadId and launch state as the first call and creates no additional thread, worktree, branch, message, or provider run. A repeated key with different launch input is either rejected with a clear error or returns the original launch, consistent with how the other tools treat key reuse. The tool description and injected agent instructions describe the key the same way as for the other tools.
Acceptance criteria
Two t3_thread_launch calls with identical input and the same clientRequestId from the same thread produce one thread, one workspace, and one first message; both responses carry the same threadId.
A retry issued while the first launch is still preparing returns that launch rather than starting a second preparation.
Calls without clientRequestId still create a new thread each time.
The same clientRequestId string used from two different calling threads creates two independent launches.
The t3_thread_launch tool description no longer says it has no retry key, and documents the new parameter.
Affected area
apps/server/src/mcp/toolkits/project/tools.ts (t3_thread_launch definition, L105), apps/server/src/mcp/toolkits/project/handlers.ts (ids derived from a fresh newCommandId() at L60-62), and the launch path in apps/server/src/orchestration-v2/ThreadLaunchService.ts, which already reads a command receipt before creating and has a replay path for accepted creates (L706-722). Whether that replay path applies when the handler passes an explicit threadId was not verified.
Non-goals
Changing launch semantics, workspace strategies, or the full-access/default caller requirement.
Adding a retry key to run_scheduled_task_now, which could be considered separately.
Keep the current guidance to inspect t3_thread_list before retrying: it is racy during preparation and depends on every agent following it.
Let the caller supply the threadId: shifts id allocation to agents and diverges from the other tools' clientRequestId pattern.
Supporting context
Tool and retry text are pinned at project/tools.ts:105. Searches for existing issues or discussions about a launch retry key found none; #11168 is the same class of lost-response duplication for delegate_task.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
Let agents pass a
clientRequestIdtot3_thread_launchso that retrying a launch after an error or lost response returns the thread already created instead of launching another one, matching the retry contract of the other mutating orchestration tools.Problem to solve
t3_thread_launchis the tool agents use for user-requested independent work in its own worktree. Its description says "Each call creates a new launch with no retry key; retain threadId and use t3_thread_read/t3_thread_wait to follow preparation. After errors or lost responses, inspect t3_thread_list before retrying." When a launch response is lost (client timeout, transport error, server restart), the agent cannot tell whether the thread exists. A blind retry creates a second thread, a second worktree and branch, and a second agent working on the same task. Inspectingt3_thread_listfirst is a manual, racy check while the first launch is still in itspreparingstate, and agents frequently skip it.delegate_task,create_threads,schedule_task,t3_thread_send,t3_thread_interrupt, and thread metadata updates already acceptclientRequestId, so launch is the outlier.Proposed behavior
t3_thread_launchaccepts an optionalclientRequestId. Calls without it behave as today. A call that repeats the sameclientRequestIdwith the same caller scope returns the samethreadIdand launch state as the first call and creates no additional thread, worktree, branch, message, or provider run. A repeated key with different launch input is either rejected with a clear error or returns the original launch, consistent with how the other tools treat key reuse. The tool description and injected agent instructions describe the key the same way as for the other tools.Acceptance criteria
t3_thread_launchcalls with identical input and the sameclientRequestIdfrom the same thread produce one thread, one workspace, and one first message; both responses carry the samethreadId.preparingreturns that launch rather than starting a second preparation.clientRequestIdstill create a new thread each time.clientRequestIdstring used from two different calling threads creates two independent launches.t3_thread_launchtool description no longer says it has no retry key, and documents the new parameter.Affected area
apps/server/src/mcp/toolkits/project/tools.ts(t3_thread_launchdefinition, L105),apps/server/src/mcp/toolkits/project/handlers.ts(ids derived from a freshnewCommandId()at L60-62), and the launch path inapps/server/src/orchestration-v2/ThreadLaunchService.ts, which already reads a command receipt before creating and has a replay path for accepted creates (L706-722). Whether that replay path applies when the handler passes an explicitthreadIdwas not verified.Non-goals
run_scheduled_task_now, which could be considered separately.Alternatives considered
t3_thread_listbefore retrying: it is racy during preparation and depends on every agent following it.threadId: shifts id allocation to agents and diverges from the other tools'clientRequestIdpattern.Supporting context
Tool and retry text are pinned at project/tools.ts:105. Searches for existing issues or discussions about a launch retry key found none; #11168 is the same class of lost-response duplication for
delegate_task.All reactions