From 8034fd5f825af1f022998d9968d14ad7c25447ec Mon Sep 17 00:00:00 2001 From: "mingholy.lmh" Date: Fri, 31 Oct 2025 12:57:54 +0800 Subject: [PATCH] fix: refine protocol types --- packages/cli/src/config/config.ts | 6 +-- packages/cli/src/gemini.tsx | 25 +++++------ packages/cli/src/nonInteractiveCli.ts | 3 +- .../controllers/permissionController.ts | 7 +++- packages/cli/src/types/protocol.ts | 42 ++++++++++++++----- 5 files changed, 51 insertions(+), 32 deletions(-) diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 72852d98..e6107f29 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -131,7 +131,7 @@ function normalizeOutputFormat( if (!format) { return undefined; } - if (format === 'stream-json') { + if (format === OutputFormat.STREAM_JSON) { return OutputFormat.STREAM_JSON; } if (format === 'json' || format === OutputFormat.JSON) { @@ -417,7 +417,7 @@ export async function parseArguments(settings: Settings): Promise { } if ( argv['includePartialMessages'] && - argv['outputFormat'] !== 'stream-json' + argv['outputFormat'] !== OutputFormat.STREAM_JSON ) { return '--include-partial-messages requires --output-format stream-json'; } @@ -661,7 +661,7 @@ export async function loadCliConfig( // Interactive mode: explicit -i flag or (TTY + no args + no -p flag) const hasQuery = !!argv.query; const interactive = - inputFormat === 'stream-json' + inputFormat === InputFormat.STREAM_JSON ? false : !!argv.promptInteractive || (process.stdin.isTTY && !hasQuery && !argv.prompt); diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx index 401e9123..4cc86cce 100644 --- a/packages/cli/src/gemini.tsx +++ b/packages/cli/src/gemini.tsx @@ -8,6 +8,7 @@ import type { Config } from '@qwen-code/qwen-code-core'; import { AuthType, getOauthClient, + InputFormat, logUserPrompt, } from '@qwen-code/qwen-code-core'; import { render } from 'ink'; @@ -418,16 +419,17 @@ export async function main() { const inputFormat = typeof config.getInputFormat === 'function' ? config.getInputFormat() - : 'text'; + : InputFormat.TEXT; - if (inputFormat === 'stream-json') { + const nonInteractiveConfig = await validateNonInteractiveAuth( + settings.merged.security?.auth?.selectedType, + settings.merged.security?.auth?.useExternal, + config, + settings, + ); + + if (inputFormat === InputFormat.STREAM_JSON) { const trimmedInput = (input ?? '').trim(); - const nonInteractiveConfig = await validateNonInteractiveAuth( - settings.merged.security?.auth?.selectedType, - settings.merged.security?.auth?.useExternal, - config, - settings, - ); await runStreamJsonSession( nonInteractiveConfig, @@ -455,13 +457,6 @@ export async function main() { prompt_length: input.length, }); - const nonInteractiveConfig = await validateNonInteractiveAuth( - settings.merged.security?.auth?.selectedType, - settings.merged.security?.auth?.useExternal, - config, - settings, - ); - if (config.getDebugMode()) { console.log('Session ID: %s', sessionId); } diff --git a/packages/cli/src/nonInteractiveCli.ts b/packages/cli/src/nonInteractiveCli.ts index a71e5bba..e8a30eff 100644 --- a/packages/cli/src/nonInteractiveCli.ts +++ b/packages/cli/src/nonInteractiveCli.ts @@ -171,7 +171,8 @@ export async function runNonInteractive( debugMode: config.getDebugMode(), }); - const isStreamJsonOutput = config.getOutputFormat() === 'stream-json'; + const isStreamJsonOutput = + config.getOutputFormat() === OutputFormat.STREAM_JSON; const streamJsonContext = options.streamJson; const streamJsonWriter = isStreamJsonOutput ? (streamJsonContext?.writer ?? diff --git a/packages/cli/src/services/control/controllers/permissionController.ts b/packages/cli/src/services/control/controllers/permissionController.ts index 46eeeb08..35b99d7a 100644 --- a/packages/cli/src/services/control/controllers/permissionController.ts +++ b/packages/cli/src/services/control/controllers/permissionController.ts @@ -18,7 +18,10 @@ import type { ToolCallRequestInfo, WaitingToolCall, } from '@qwen-code/qwen-code-core'; -import { ToolConfirmationOutcome } from '@qwen-code/qwen-code-core'; +import { + InputFormat, + ToolConfirmationOutcome, +} from '@qwen-code/qwen-code-core'; import type { CLIControlPermissionRequest, CLIControlSetPermissionModeRequest, @@ -409,7 +412,7 @@ export class PermissionController extends BaseController { ): Promise { try { const inputFormat = this.context.config.getInputFormat?.(); - const isStreamJsonMode = inputFormat === 'stream-json'; + const isStreamJsonMode = inputFormat === InputFormat.STREAM_JSON; if (!isStreamJsonMode) { // No SDK available - use local permission check diff --git a/packages/cli/src/types/protocol.ts b/packages/cli/src/types/protocol.ts index 2343a622..fe3f68c5 100644 --- a/packages/cli/src/types/protocol.ts +++ b/packages/cli/src/types/protocol.ts @@ -1,5 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +/** + * Annotation for attaching metadata to content blocks + */ +export interface Annotation { + type: string; + value: string; +} + /** * Usage information types */ @@ -37,7 +45,7 @@ export interface ModelUsage { export interface CLIPermissionDenial { tool_name: string; tool_use_id: string; - tool_input: Record; + tool_input: unknown; } /** @@ -46,26 +54,30 @@ export interface CLIPermissionDenial { export interface TextBlock { type: 'text'; text: string; + annotations?: Annotation[]; } export interface ThinkingBlock { type: 'thinking'; thinking: string; - signature: string; + signature?: string; + annotations?: Annotation[]; } export interface ToolUseBlock { type: 'tool_use'; id: string; name: string; - input: Record; + input: unknown; + annotations?: Annotation[]; } export interface ToolResultBlock { type: 'tool_result'; tool_use_id: string; - content: string | Array> | null; + content?: string | ContentBlock[]; is_error?: boolean; + annotations?: Annotation[]; } export type ContentBlock = @@ -79,7 +91,7 @@ export type ContentBlock = */ export interface APIUserMessage { role: 'user'; - content: string | ToolResultBlock[]; + content: string | ContentBlock[]; } export interface APIAssistantMessage { @@ -101,6 +113,7 @@ export interface CLIUserMessage { session_id: string; message: APIUserMessage; parent_tool_use_id: string | null; + options?: Record; } export interface CLIAssistantMessage { @@ -151,6 +164,7 @@ export interface CLIResultMessageSuccess { usage: ExtendedUsage; modelUsage?: Record; permission_denials: CLIPermissionDenial[]; + [key: string]: unknown; } export interface CLIResultMessageError { @@ -166,6 +180,12 @@ export interface CLIResultMessageError { usage: ExtendedUsage; modelUsage?: Record; permission_denials: CLIPermissionDenial[]; + error?: { + type?: string; + message: string; + [key: string]: unknown; + }; + [key: string]: unknown; } export type CLIResultMessage = CLIResultMessageSuccess | CLIResultMessageError; @@ -232,7 +252,7 @@ export interface PermissionSuggestion { type: 'allow' | 'deny' | 'modify'; label: string; description?: string; - modifiedInput?: Record; + modifiedInput?: unknown; } /** @@ -261,7 +281,7 @@ export interface CLIControlPermissionRequest { subtype: 'can_use_tool'; tool_name: string; tool_use_id: string; - input: Record; + input: unknown; permission_suggestions: PermissionSuggestion[] | null; blocked_path: string | null; } @@ -280,7 +300,7 @@ export interface CLIControlSetPermissionModeRequest { export interface CLIHookCallbackRequest { subtype: 'hook_callback'; callback_id: string; - input: any; + input: unknown; tool_use_id: string | null; } @@ -331,19 +351,19 @@ export interface CLIControlRequest { export interface PermissionApproval { allowed: boolean; reason?: string; - modifiedInput?: Record; + modifiedInput?: unknown; } export interface ControlResponse { subtype: 'success'; request_id: string; - response: Record | null; + response: unknown; } export interface ControlErrorResponse { subtype: 'error'; request_id: string; - error: string; + error: string | { message: string; [key: string]: unknown }; } export interface CLIControlResponse {