feat(core): add subagent protocol enhancements

- AgentCapabilitiesSchema with supportsStreaming/Reasoning/Background flags
- supportsStreaming and supportsReasoningStream fields in ProviderSnapshotEntry
- new_task tool: background mode flag for non-blocking subtask dispatch
This commit is contained in:
2026-06-07 17:57:49 +00:00
parent 02bb355a09
commit cdc782e044
3 changed files with 18 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ const NewTaskInput = z.object({
input: z.string().min(1).describe('Task description for the child subtask'), input: z.string().min(1).describe('Task description for the child subtask'),
agent: z.string().optional().describe('Optional: dispatch to a specific agent'), agent: z.string().optional().describe('Optional: dispatch to a specific agent'),
model: z.string().optional().describe('Optional: model override for the subtask'), model: z.string().optional().describe('Optional: model override for the subtask'),
background: z.boolean().optional().describe('If true, return immediately without blocking on completion'),
}); });
type NewTaskInputT = z.infer<typeof NewTaskInput>; type NewTaskInputT = z.infer<typeof NewTaskInput>;
@@ -30,6 +31,7 @@ export const newTaskTool: ToolDef<NewTaskInputT> = {
input: { type: 'string', description: 'Task description for the child subtask' }, input: { type: 'string', description: 'Task description for the child subtask' },
agent: { type: 'string', description: 'Optional: dispatch to a specific agent' }, agent: { type: 'string', description: 'Optional: dispatch to a specific agent' },
model: { type: 'string', description: 'Optional: model override for the subtask' }, model: { type: 'string', description: 'Optional: model override for the subtask' },
background: { type: 'boolean', description: 'If true, returns immediately without waiting' },
}, },
required: ['input'], required: ['input'],
}, },
@@ -50,6 +52,7 @@ export const newTaskTool: ToolDef<NewTaskInputT> = {
return { error: 'Cannot determine project_id from current session' }; return { error: 'Cannot determine project_id from current session' };
} }
const isBg = input.background === true;
const [task] = await sql<{ id: string; state: string }[]>` const [task] = await sql<{ id: string; state: string }[]>`
INSERT INTO tasks (project_id, parent_task_id, input, agent, model) INSERT INTO tasks (project_id, parent_task_id, input, agent, model)
VALUES (${session.project_id}, ${currentTaskId}, ${input.input}, ${input.agent ?? null}, ${input.model ?? null}) VALUES (${session.project_id}, ${currentTaskId}, ${input.input}, ${input.agent ?? null}, ${input.model ?? null})
@@ -57,9 +60,12 @@ export const newTaskTool: ToolDef<NewTaskInputT> = {
`; `;
return { return {
message: `Subtask created (id: ${task!.id}). It will run in isolation. Use check_task_status to monitor.`, message: isBg
? `Background subtask created (id: ${task!.id}). It will continue independently.`
: `Subtask created (id: ${task!.id}). It will run in isolation. Use check_task_status to monitor.`,
task_id: task!.id, task_id: task!.id,
state: task!.state, state: task!.state,
background: isBg,
}; };
}, },
}; };

View File

@@ -0,0 +1,9 @@
import { z } from 'zod';
export const AgentCapabilitiesSchema = z.object({
supportsStreaming: z.boolean().default(true),
supportsReasoningStream: z.boolean().default(false),
supportsBackgroundExecution: z.boolean().default(false),
});
export type AgentCapabilities = z.infer<typeof AgentCapabilitiesSchema>;

View File

@@ -49,4 +49,6 @@ export interface ProviderSnapshotEntry {
commands: AgentCommand[]; commands: AgentCommand[];
error?: string; error?: string;
fetchedAt?: string; fetchedAt?: string;
supportsStreaming?: boolean;
supportsReasoningStream?: boolean;
} }