feat: add support for Codex's request_user_input tool

Implement full support for the request_user_input tool with both Web UI and CLI
components. This includes:

- New view and footer components for request_user_input tool UI
- Tool registration in knownTools and view registries
- Nested answer format support (Record<string, { answers: string[] }>)
- Backward compatibility with flat answer format (Record<string, string[]>)
- Permission handler updates for CLI request_user_input acceptance
- Type definitions and schema updates across shared/cli/server/web packages
- Translation strings for request_user_input UI elements
- Conditional footer rendering in ToolCard for question tools
This commit is contained in:
weishu
2026-01-26 11:58:36 +08:00
parent 8137ce4f23
commit ae9650ca7c
18 changed files with 754 additions and 27 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ export class RpcGateway {
mode?: PermissionMode,
allowTools?: string[],
decision?: 'approved' | 'approved_for_session' | 'denied' | 'abort',
answers?: Record<string, string[]>
answers?: Record<string, string[]> | Record<string, { answers: string[] }>
): Promise<void> {
await this.sessionRpc(sessionId, 'permission', {
id: requestId,
+1 -1
View File
@@ -212,7 +212,7 @@ export class SyncEngine {
mode?: PermissionMode,
allowTools?: string[],
decision?: 'approved' | 'approved_for_session' | 'denied' | 'abort',
answers?: Record<string, string[]>
answers?: Record<string, string[]> | Record<string, { answers: string[] }>
): Promise<void> {
await this.rpcGateway.approvePermission(sessionId, requestId, mode, allowTools, decision, answers)
}
+8 -1
View File
@@ -8,11 +8,18 @@ import { requireSessionFromParam, requireSyncEngine } from './guards'
const decisionSchema = z.enum(['approved', 'approved_for_session', 'denied', 'abort'])
// Flat format: Record<string, string[]> (AskUserQuestion)
// Nested format: Record<string, { answers: string[] }> (request_user_input)
const answersSchema = z.union([
z.record(z.string(), z.array(z.string())),
z.record(z.string(), z.object({ answers: z.array(z.string()) }))
])
const approveBodySchema = z.object({
mode: PermissionModeSchema.optional(),
allowTools: z.array(z.string()).optional(),
decision: decisionSchema.optional(),
answers: z.record(z.string(), z.array(z.string())).optional()
answers: answersSchema.optional()
})
const denyBodySchema = z.object({