Files
Codewalkers/src/agent/schema.ts
Lukas May 151a4c99f7 feat(10-01): extend agent schema to multi-question array
- Change status from 'question' to 'questions' (plural)
- Add QuestionItem with id field for answer matching
- Update PendingQuestion to PendingQuestions with questions array
- Update AgentWaitingEvent payload to questions array
- Update ClaudeAgentManager and MockAgentManager adapters
- Update TestHarness and all test files
2026-01-31 17:57:34 +01:00

114 lines
2.9 KiB
TypeScript

/**
* Agent Output Schema
*
* Defines structured output schema for Claude agents using discriminated unions.
* Replaces broken AskUserQuestion detection with explicit agent status signaling.
*/
import { z } from 'zod';
/**
* Option for questions - allows agent to present choices to user
*/
const optionSchema = z.object({
label: z.string(),
description: z.string().optional(),
});
/**
* Individual question item with unique ID for answer matching
*/
const questionItemSchema = z.object({
id: z.string(),
question: z.string(),
options: z.array(optionSchema).optional(),
multiSelect: z.boolean().optional(),
});
/**
* Discriminated union for agent output.
*
* Agent must return one of:
* - done: Task completed successfully
* - questions: Agent needs user input to continue (supports multiple questions)
* - unrecoverable_error: Agent hit an error it cannot recover from
*/
export const agentOutputSchema = z.discriminatedUnion('status', [
// Agent completed successfully
z.object({
status: z.literal('done'),
result: z.string(),
filesModified: z.array(z.string()).optional(),
}),
// Agent needs user input to continue (one or more questions)
z.object({
status: z.literal('questions'),
questions: z.array(questionItemSchema),
}),
// Agent hit unrecoverable error
z.object({
status: z.literal('unrecoverable_error'),
error: z.string(),
attempted: z.string().optional(),
}),
]);
export type AgentOutput = z.infer<typeof agentOutputSchema>;
/**
* JSON Schema for --json-schema flag (convert Zod to JSON Schema).
* This is passed to Claude CLI to enforce structured output.
*/
export const agentOutputJsonSchema = {
type: 'object',
oneOf: [
{
properties: {
status: { const: 'done' },
result: { type: 'string' },
filesModified: { type: 'array', items: { type: 'string' } },
},
required: ['status', 'result'],
},
{
properties: {
status: { const: 'questions' },
questions: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string' },
question: { type: 'string' },
options: {
type: 'array',
items: {
type: 'object',
properties: {
label: { type: 'string' },
description: { type: 'string' },
},
required: ['label'],
},
},
multiSelect: { type: 'boolean' },
},
required: ['id', 'question'],
},
},
},
required: ['status', 'questions'],
},
{
properties: {
status: { const: 'unrecoverable_error' },
error: { type: 'string' },
attempted: { type: 'string' },
},
required: ['status', 'error'],
},
],
};