Add active-turn steering (#3394)

* feat(agents): add active-turn steering

Let users choose whether an immediate prompt interrupts or joins the active turn. The daemon owns exact-turn admission, provider delivery, safe fallback, and canonical timeline identity while queueing remains client-side.

* fix(agents): stabilize steering history and replay QA

* fix(agents): preserve steering timeline order

* fix(agents): reconcile resumed provider history

* fix(agents): serialize steering with cancellation

* test(agents): prove Claude multi-tool steering

* test(agents): force explicit history hydration

* fix(agents): flush output before steer admission
This commit is contained in:
Mohamed Boudra
2026-08-16 13:58:40 +02:00
committed by GitHub
parent 16120ebff1
commit 42245d139a
69 changed files with 5203 additions and 269 deletions
+4 -3
View File
@@ -131,7 +131,7 @@ export interface MessageInputProps {
isAgentRunning?: boolean;
/** Controls what the default send action (Enter, send button, dictation) does
* when the agent is running. "interrupt" sends immediately, "queue" queues. */
defaultSendBehavior?: "interrupt" | "queue";
defaultSendBehavior?: "interrupt" | "steer" | "queue";
/** Callback for queue button when agent is running */
onQueue?: (payload: MessagePayload) => void;
/** Optional handler used when submit button is in loading state. */
@@ -1002,7 +1002,7 @@ interface SendButtonStateInput {
isSubmitDisabled: boolean;
isSubmitLoading: boolean;
onSubmitLoadingPress: (() => void) | undefined;
defaultSendBehavior: "interrupt" | "queue";
defaultSendBehavior: "interrupt" | "steer" | "queue";
isAgentRunning: boolean;
}
@@ -1052,7 +1052,7 @@ interface ResolvedMessageInputProps {
voiceServerId: string | undefined;
voiceAgentId: string | undefined;
isAgentRunning: boolean;
defaultSendBehavior: "interrupt" | "queue";
defaultSendBehavior: "interrupt" | "steer" | "queue";
onQueue: ((payload: MessagePayload) => void) | undefined;
onSubmitLoadingPress: (() => void) | undefined;
onKeyPressCallback: ((event: { key: string; preventDefault: () => void }) => boolean) | undefined;
@@ -1608,6 +1608,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
submitButtonAccessibilityLabel,
canPressLoadingButton,
defaultActionQueues,
defaultSendBehavior,
isAgentRunning,
t,
});