minimal-agent 0.18.13 → 0.18.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -3
- package/plugins/workflow-runner/src/runtime/context.js +1 -1
- package/plugins/workflow-runner/src/runtime/context.ts +1 -1
- package/plugins/workflow-runner/test/embeddedExecution.test.ts +2 -5
- package/plugins/workflow-runner/test/execLifetime.test.ts +15 -2
- package/skills/ssh-remote-dev/SKILL.md +61 -0
- package/skills/ssh-remote-dev/agents/openai.yaml +4 -0
- package/src/advisor/README.md +62 -24
- package/src/advisor/advisorNudge.js +199 -0
- package/src/advisor/advisorNudge.ts +232 -0
- package/src/advisor/deliveryReview.js +35 -12
- package/src/advisor/deliveryReview.ts +35 -11
- package/src/advisor/presentation.js +7 -10
- package/src/advisor/presentation.ts +10 -13
- package/src/advisor/reviewContext.js +22 -58
- package/src/advisor/reviewContext.ts +24 -67
- package/src/cli/configMenu.js +17 -128
- package/src/cli/configMenu.tsx +17 -193
- package/src/cli/print.js +2 -0
- package/src/cli/print.ts +2 -0
- package/src/cli/streamJson.js +2 -0
- package/src/cli/streamJson.ts +2 -0
- package/src/cli/wizards/advisorWizard.js +9 -7
- package/src/cli/wizards/advisorWizard.tsx +9 -7
- package/src/cli/wizards/contextAdvisorWizard.js +9 -7
- package/src/cli/wizards/contextAdvisorWizard.tsx +9 -7
- package/src/cli/wizards/providerPresets.js +27 -1
- package/src/cli/wizards/providerPresets.ts +44 -2
- package/src/cli/wizards/providerWizard.js +51 -10
- package/src/cli/wizards/providerWizard.tsx +59 -9
- package/src/config/configDefaults.js +1 -1
- package/src/config/configDefaults.ts +1 -1
- package/src/config/configDiagnostics.js +1 -21
- package/src/config/configDiagnostics.ts +3 -23
- package/src/config/configFile.js +11 -4
- package/src/config/configFile.ts +27 -7
- package/src/config/configManagement.js +1 -0
- package/src/config/configManagement.ts +2 -0
- package/src/config/configService.js +12 -8
- package/src/config/configService.ts +16 -11
- package/src/config/numericLimits.js +0 -4
- package/src/config/numericLimits.ts +0 -4
- package/src/config/reasoningEffort.js +16 -0
- package/src/config/reasoningEffort.ts +18 -0
- package/src/context/budgetPlan.js +1 -1
- package/src/context/budgetPlan.ts +1 -1
- package/src/context/optimizeConversation.js +1 -1
- package/src/context/optimizeConversation.ts +1 -1
- package/src/harness/stallGuard.js +8 -13
- package/src/harness/stallGuard.ts +8 -12
- package/src/llm/client.js +64 -17
- package/src/llm/client.ts +62 -7
- package/src/llm/providers/openaiFormat.js +14 -3
- package/src/llm/providers/openaiFormat.ts +17 -3
- package/src/llm/providers/responsesFormat.js +275 -0
- package/src/llm/providers/responsesFormat.ts +306 -0
- package/src/loop/README.md +18 -3
- package/src/loop/liveDiagramGate.js +63 -0
- package/src/loop/liveDiagramGate.ts +61 -0
- package/src/loop/messages.js +12 -0
- package/src/loop/messages.ts +13 -0
- package/src/loop/options.ts +7 -2
- package/src/loop/toolBatch.js +0 -1
- package/src/loop/toolBatch.ts +0 -1
- package/src/loop/toolExecutor.js +11 -46
- package/src/loop/toolExecutor.ts +12 -55
- package/src/loop/toolPresentation.js +2 -13
- package/src/loop/toolPresentation.ts +2 -13
- package/src/loop/toolSemantics.js +3 -4
- package/src/loop/toolSemantics.ts +4 -6
- package/src/loop.js +222 -214
- package/src/loop.ts +226 -232
- package/src/memory/dependencies.js +11 -3
- package/src/memory/dependencies.ts +11 -3
- package/src/memory/episodicMemory.js +59 -18
- package/src/memory/episodicMemory.ts +58 -18
- package/src/memory/experienceStore.js +4 -3
- package/src/memory/experienceStore.ts +4 -3
- package/src/memory/factCandidates.js +53 -1
- package/src/memory/factCandidates.ts +54 -1
- package/src/memory/factLearning.js +2 -2
- package/src/memory/factLearning.ts +2 -2
- package/src/memory/jobPolicy.js +24 -5
- package/src/memory/jobPolicy.ts +25 -5
- package/src/memory/learning.js +2 -2
- package/src/memory/learning.ts +2 -2
- package/src/memory/learningModel.js +7 -0
- package/src/memory/learningModel.ts +7 -0
- package/src/memory/managementService.js +8 -7
- package/src/memory/managementService.ts +16 -8
- package/src/memory/memoryService.js +104 -33
- package/src/memory/memoryService.ts +132 -28
- package/src/memory/projectKnowledge.js +39 -3
- package/src/memory/projectKnowledge.ts +45 -3
- package/src/memory/recallQuery.js +56 -0
- package/src/memory/recallQuery.ts +58 -0
- package/src/memory/retrieval.js +39 -10
- package/src/memory/retrieval.ts +46 -11
- package/src/memory/turnJournal.js +75 -10
- package/src/memory/turnJournal.ts +66 -10
- package/src/memory/types.ts +7 -1
- package/src/prompts/delegation.js +2 -1
- package/src/prompts/delegation.ts +3 -1
- package/src/prompts/policyRegistry.js +9 -12
- package/src/prompts/policyRegistry.ts +9 -12
- package/src/prompts/promptAssembly.js +6 -5
- package/src/prompts/promptAssembly.ts +8 -6
- package/src/prompts/visualPresentation.js +39 -10
- package/src/prompts/visualPresentation.ts +38 -9
- package/src/runtime/answerPreparation.js +1 -1
- package/src/runtime/answerPreparation.ts +1 -1
- package/src/runtime/fileLock.js +19 -3
- package/src/runtime/fileLock.ts +19 -3
- package/src/runtime/invocationPolicy.js +1 -1
- package/src/runtime/invocationPolicy.ts +1 -1
- package/src/runtime/outputContract.js +0 -4
- package/src/runtime/outputContract.ts +0 -7
- package/src/session/runAgentTurn.js +3 -0
- package/src/session/runAgentTurn.ts +3 -0
- package/src/team/onlineToolContract.js +0 -1
- package/src/team/onlineToolContract.ts +0 -1
- package/src/tools/advisor/advisor.js +207 -365
- package/src/tools/advisor/advisor.ts +211 -383
- package/src/tools/agent/agentTypes.js +0 -1
- package/src/tools/agent/agentTypes.ts +0 -1
- package/src/tools/agent/coordinator.js +4 -1
- package/src/tools/agent/coordinator.ts +4 -1
- package/src/tools/bash/semantics.js +4 -5
- package/src/tools/bash/semantics.ts +4 -5
- package/src/tools/capabilities.js +2 -3
- package/src/tools/capabilities.ts +2 -4
- package/src/tools/index.js +0 -16
- package/src/tools/index.ts +0 -16
- package/src/tools/memory/maintenance.js +8 -9
- package/src/tools/memory/maintenance.ts +13 -11
- package/src/tools/memory/memory.js +5 -1
- package/src/tools/memory/memory.ts +5 -0
- package/src/tools/optimizeConversation/README.md +4 -6
- package/src/tools/toolPromptGuides.js +2 -9
- package/src/tools/toolPromptGuides.ts +2 -9
- package/src/types.ts +28 -105
- package/src/ui/App.js +2 -0
- package/src/ui/App.tsx +1 -0
- package/src/ui/MessageList.js +8 -44
- package/src/ui/MessageList.tsx +3 -81
- package/src/ui/hooks/useChat.js +2 -0
- package/src/ui/hooks/useChat.ts +2 -0
- package/src/ui/toolProgress.js +1 -1
- package/src/ui/toolProgress.ts +1 -1
- package/src/web/protocol.ts +10 -3
- package/src/advisor/advisorCoordinator.js +0 -734
- package/src/advisor/advisorCoordinator.ts +0 -825
- package/src/cli/wizards/sshHostWizard.js +0 -156
- package/src/cli/wizards/sshHostWizard.tsx +0 -214
- package/src/context/sshHosts.js +0 -290
- package/src/context/sshHosts.ts +0 -312
- package/src/loop/publication.js +0 -94
- package/src/loop/publication.ts +0 -124
- package/src/runtime/finalAnswer.js +0 -9
- package/src/runtime/finalAnswer.ts +0 -13
- package/src/tools/advisor/advisorDecision.js +0 -79
- package/src/tools/advisor/advisorDecision.ts +0 -92
- package/src/tools/ssh/ssh.js +0 -152
- package/src/tools/ssh/ssh.ts +0 -167
- package/src/tools/ssh/sshAvailability.js +0 -35
- package/src/tools/ssh/sshAvailability.ts +0 -39
- package/src/tools/ssh/sshClient.js +0 -177
- package/src/tools/ssh/sshClient.ts +0 -189
- package/src/tools/ssh/sshDownload.js +0 -77
- package/src/tools/ssh/sshDownload.ts +0 -92
- package/src/tools/ssh/sshHostsTool.js +0 -36
- package/src/tools/ssh/sshHostsTool.ts +0 -48
- package/src/tools/ssh/sshUpload.js +0 -72
- package/src/tools/ssh/sshUpload.ts +0 -85
package/src/types.ts
CHANGED
|
@@ -178,7 +178,7 @@ export type Message = (
|
|
|
178
178
|
role: 'assistant';
|
|
179
179
|
/** Persisted UI semantics; not a provider instruction or a success claim. */
|
|
180
180
|
presentation?: 'progress' | 'final';
|
|
181
|
-
/**
|
|
181
|
+
/** @deprecated Legacy sessions only (the retired review cycle); no longer written. Stripped before any provider request. */
|
|
182
182
|
advisorTaskVersion?: number;
|
|
183
183
|
/** 当 tool_calls 非空时 content 通常为 null(OpenAI 协议) */
|
|
184
184
|
content: string | null;
|
|
@@ -214,13 +214,13 @@ export type Message = (
|
|
|
214
214
|
display_metadata?: ToolResultMetadata;
|
|
215
215
|
/** 本地压缩策略;发送 Provider 前会剥离。 */
|
|
216
216
|
tool_result_policy?: ToolResultPolicy;
|
|
217
|
-
/**
|
|
217
|
+
/** @deprecated Legacy sessions only; no longer written. Stripped before any provider request. */
|
|
218
218
|
advisorMutatesWorkspace?: boolean;
|
|
219
219
|
timestamp?: number;
|
|
220
220
|
}
|
|
221
221
|
) & {
|
|
222
|
-
/**
|
|
223
|
-
advisorCheckpoints?:
|
|
222
|
+
/** @deprecated Legacy sessions only (the retired review checkpoints); no longer written. Stripped before any provider request. */
|
|
223
|
+
advisorCheckpoints?: unknown[];
|
|
224
224
|
/** Host-only cold history. Persist with Session; strip before any provider request. */
|
|
225
225
|
advisorHistory?: { version: 1; messages: Message[] };
|
|
226
226
|
/** Host-only: a deferred call never produced an execution observation. */
|
|
@@ -376,51 +376,6 @@ export interface ProcessExecutionMetadata {
|
|
|
376
376
|
exitCode?: number | null;
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
-
export type AdvisorCheckpoint =
|
|
380
|
-
| 'pre-execution'
|
|
381
|
-
| 'stalled'
|
|
382
|
-
| 'high-risk'
|
|
383
|
-
| 'pre-delivery';
|
|
384
|
-
|
|
385
|
-
export interface AdvisorVersions {
|
|
386
|
-
taskVersion: number;
|
|
387
|
-
workVersion: number;
|
|
388
|
-
evidenceVersion: number;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
export interface AdvisorCheckpointMetadata extends AdvisorVersions {
|
|
392
|
-
kind: 'advisor_checkpoint';
|
|
393
|
-
checkpoint: AdvisorCheckpoint;
|
|
394
|
-
checkpointKey: string;
|
|
395
|
-
status: 'required' | 'attempted-unavailable';
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
export interface AdvisorConsultationMetadata extends AdvisorVersions {
|
|
399
|
-
kind: 'advisor_consultation';
|
|
400
|
-
/** Host-recorded trigger, distinct from who emitted the tool call. Absent in old history. */
|
|
401
|
-
triggerSource?: 'checkpoint' | 'model';
|
|
402
|
-
triggerReason?: string;
|
|
403
|
-
consultationId: string;
|
|
404
|
-
checkpoint: AdvisorCheckpoint;
|
|
405
|
-
checkpointKey: string;
|
|
406
|
-
status: 'completed' | 'failed';
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export interface AdvisorDecisionMetadata extends AdvisorVersions {
|
|
410
|
-
kind: 'advisor_decision';
|
|
411
|
-
consultationId: string;
|
|
412
|
-
checkpoint: AdvisorCheckpoint;
|
|
413
|
-
checkpointKey: string;
|
|
414
|
-
decision: 'accept' | 'partial' | 'reject';
|
|
415
|
-
rationale: string;
|
|
416
|
-
acceptedPoints: string[];
|
|
417
|
-
rejectedPoints: string[];
|
|
418
|
-
verificationPlan: string[];
|
|
419
|
-
evidenceRefs?: string[];
|
|
420
|
-
/** Referenced evidence is not proof of correctness; pending never means approved. */
|
|
421
|
-
verificationStatus?: 'evidence_linked' | 'pending';
|
|
422
|
-
}
|
|
423
|
-
|
|
424
379
|
/** Agent 子任务的结构化阶段进度;仅供宿主展示,不写入会话历史或发送给 LLM。 */
|
|
425
380
|
export interface SubagentProgress {
|
|
426
381
|
kind: 'subagent';
|
|
@@ -468,9 +423,6 @@ export type ToolResultMetadata =
|
|
|
468
423
|
| FileDiscoveryMetadata
|
|
469
424
|
| ResultManifestMetadata
|
|
470
425
|
| ProcessExecutionMetadata
|
|
471
|
-
| AdvisorCheckpointMetadata
|
|
472
|
-
| AdvisorConsultationMetadata
|
|
473
|
-
| AdvisorDecisionMetadata
|
|
474
426
|
| BrowserDownloadMetadata;
|
|
475
427
|
|
|
476
428
|
/**
|
|
@@ -576,8 +528,6 @@ export type ToolResult = { problem?: ToolProblemOutcome; observation?: ReadObser
|
|
|
576
528
|
* 避免按工具名写特判分支。
|
|
577
529
|
*/
|
|
578
530
|
export interface ToolCallContext {
|
|
579
|
-
/** Run-local host initialization shared with Advisor; never a model argument. */
|
|
580
|
-
advisorConsultation?: AdvisorConsultationMetadata;
|
|
581
531
|
/** Shared per-model-response read allowance; reservations happen before IO. */
|
|
582
532
|
reserveReadChars?: (requested?: number) => number;
|
|
583
533
|
/** Host presentation only; cannot grant tools to a delegated agent. */
|
|
@@ -609,10 +559,11 @@ export interface ToolCallContext {
|
|
|
609
559
|
advisorCalls?: { used: number };
|
|
610
560
|
/** 区分主模型自动咨询与用户显式 /advisor ask。 */
|
|
611
561
|
advisorInvocation?: 'agent' | 'manual';
|
|
612
|
-
/**
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
562
|
+
/**
|
|
563
|
+
* 项目约束与记忆(它们不在对话历史里),作为"背景"附给顾问;宿主在主循环里提供,
|
|
564
|
+
* 不是工具参数,也不是给顾问的指令。
|
|
565
|
+
*/
|
|
566
|
+
advisorBackground?: () => string;
|
|
616
567
|
/**
|
|
617
568
|
* 主循环使用的 provider —— Agent 等「工具内部再起子查询」的派生工具用它
|
|
618
569
|
* 跑嵌套 runQuery(子 agent 与主 agent 同一模型,不另配凭据)。
|
|
@@ -696,45 +647,6 @@ export interface ToolCallContext {
|
|
|
696
647
|
};
|
|
697
648
|
}
|
|
698
649
|
|
|
699
|
-
export interface AdvisorContextPacket {
|
|
700
|
-
failureAttempts?: string[];
|
|
701
|
-
deliveryDraft?: string;
|
|
702
|
-
decisionVerification?: Pick<AdvisorDecisionMetadata, 'consultationId' | 'verificationStatus' | 'evidenceRefs' | 'verificationPlan' | 'decision' | 'rationale' | 'acceptedPoints' | 'rejectedPoints'>;
|
|
703
|
-
objective: string;
|
|
704
|
-
currentRequest: string;
|
|
705
|
-
checkpoint: AdvisorCheckpoint;
|
|
706
|
-
versions: AdvisorVersions;
|
|
707
|
-
changedFiles: string[];
|
|
708
|
-
evidence: string[];
|
|
709
|
-
/** Packet excerpts are a selection, not proof the reviewer saw every stored result. */
|
|
710
|
-
evidenceCoverage?: { available: number; included: number; omitted: number; excerpts: true };
|
|
711
|
-
previousAdvice?: string;
|
|
712
|
-
actionsAfterPreviousAdvice: string[];
|
|
713
|
-
openQuestions: string[];
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
export type AdvisorReason = 'uncertainty' | 'plan_review' | 'delivery_review' | 'stalled' | 'user_dissatisfaction' | 'evidence_conflict';
|
|
717
|
-
|
|
718
|
-
export interface AdvisorRuntimeBridge {
|
|
719
|
-
/** Latest advice available for the main Agent's optional decision record. */
|
|
720
|
-
readonly pendingConsultationId: string | undefined;
|
|
721
|
-
beginConsultation(reason?: AdvisorReason): AdvisorConsultationMetadata;
|
|
722
|
-
finishConsultation(
|
|
723
|
-
metadata: AdvisorConsultationMetadata,
|
|
724
|
-
ok: boolean,
|
|
725
|
-
): AdvisorConsultationMetadata;
|
|
726
|
-
recordDecision(input: {
|
|
727
|
-
consultationId: string;
|
|
728
|
-
decision: 'accept' | 'partial' | 'reject';
|
|
729
|
-
rationale: string;
|
|
730
|
-
acceptedPoints?: string[];
|
|
731
|
-
rejectedPoints?: string[];
|
|
732
|
-
verificationPlan?: string[];
|
|
733
|
-
evidenceRefs?: string[];
|
|
734
|
-
}): ToolResult;
|
|
735
|
-
contextPacket(note?: string): AdvisorContextPacket;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
650
|
export type ToolCategory =
|
|
739
651
|
| 'files'
|
|
740
652
|
| 'shell'
|
|
@@ -901,10 +813,11 @@ interface ProviderCommon {
|
|
|
901
813
|
maxTokens?: number;
|
|
902
814
|
|
|
903
815
|
/**
|
|
904
|
-
* 请求协议格式:'openai'(Chat Completions,默认)| '
|
|
816
|
+
* 请求协议格式:'openai'(Chat Completions,默认)| 'openai-responses'(OpenAI Responses API)
|
|
817
|
+
* | 'anthropic'(Messages API)。
|
|
905
818
|
* 缺省当 'openai'——兼容旧版只产出 OpenAI 格式对象的 env 自举路径。见 client.ts。
|
|
906
819
|
*/
|
|
907
|
-
apiFormat?: 'openai' | 'anthropic';
|
|
820
|
+
apiFormat?: 'openai' | 'openai-responses' | 'anthropic';
|
|
908
821
|
|
|
909
822
|
/**
|
|
910
823
|
* 该模型是否支持识图(多模态视觉)。resolveProvider 从所选 ModelConfig 归一成真布尔
|
|
@@ -917,6 +830,12 @@ interface ProviderCommon {
|
|
|
917
830
|
supportsJsonSchema?: boolean;
|
|
918
831
|
/** Explicitly request provider reasoning when the endpoint supports it. */
|
|
919
832
|
reasoning?: boolean;
|
|
833
|
+
/**
|
|
834
|
+
* 推理强度。openai-responses 发 `reasoning.effort`,openai(Chat Completions) 发
|
|
835
|
+
* `reasoning_effort`(OpenRouter 发 `reasoning.effort`)。缺省不发送,沿用服务端默认。
|
|
836
|
+
* 模型不认该档位时 client.ts 去掉参数重发一次,不让对话 400。
|
|
837
|
+
*/
|
|
838
|
+
reasoningEffort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
920
839
|
promptCache?: PromptCacheConfig;
|
|
921
840
|
|
|
922
841
|
/**
|
|
@@ -1142,8 +1061,9 @@ export type LlmStreamEvent =
|
|
|
1142
1061
|
* 工作过程显示阶段标签(UI 的 LiveArea 据此选择文字 / 决定是否隐藏整面板)。
|
|
1143
1062
|
*
|
|
1144
1063
|
* idle —— 当前没有任何工作(隐藏 LiveArea)
|
|
1145
|
-
* thinking ——
|
|
1146
|
-
* streaming ——
|
|
1064
|
+
* thinking —— 等待首个 token、工具调用或仍可能被检查退回的私有候选
|
|
1065
|
+
* streaming —— 最终回答正在显示:没有检查能再拦下时边生成边实时输出;
|
|
1066
|
+
* 否则通过全部检查后原样一次发布
|
|
1147
1067
|
* tool_executing —— 至少一个工具在跑(并行时栈式显示多个)
|
|
1148
1068
|
* compacting —— 正在跑自动 / reactive / 手动压缩
|
|
1149
1069
|
*/
|
|
@@ -1220,7 +1140,10 @@ export interface TurnResourceUsage {
|
|
|
1220
1140
|
}
|
|
1221
1141
|
|
|
1222
1142
|
export type LoopEvent =
|
|
1223
|
-
/**
|
|
1143
|
+
/**
|
|
1144
|
+
* 对用户可见的回答正文。没有任何检查能再拦下本次回答时逐段实时发出(含工具轮的
|
|
1145
|
+
* 过程说明);否则候选保持私有,通过全部检查后原样一次发出。已发出的正文不会被撤回。
|
|
1146
|
+
*/
|
|
1224
1147
|
| { type: 'text'; delta: string }
|
|
1225
1148
|
/**
|
|
1226
1149
|
* 用户消息刚 push 进 history(loop 入口)。
|
|
@@ -1242,16 +1165,16 @@ export type LoopEvent =
|
|
|
1242
1165
|
}
|
|
1243
1166
|
/**
|
|
1244
1167
|
* 内部候选正文尚不能交付,需要进入检查或补全阶段。
|
|
1245
|
-
*
|
|
1168
|
+
* 只退回从未广播的私有候选,已实时显示的正文不会被退回;textLength=0,仅表示准备/复核阶段变化。
|
|
1246
1169
|
* textLength>0 仅供旧事件兼容,不应作为正常展示路径。
|
|
1247
1170
|
*/
|
|
1248
1171
|
| {
|
|
1249
1172
|
type: 'assistant_draft_discarded';
|
|
1250
1173
|
reason:
|
|
1251
1174
|
| 'formal_delivery'
|
|
1252
|
-
| 'advisor_checkpoint'
|
|
1253
1175
|
| 'empty_response'
|
|
1254
|
-
| 'interactive_question'
|
|
1176
|
+
| 'interactive_question'
|
|
1177
|
+
| 'diagram_preparation';
|
|
1255
1178
|
textLength: number;
|
|
1256
1179
|
}
|
|
1257
1180
|
/**
|
package/src/ui/App.js
CHANGED
|
@@ -58,6 +58,8 @@ const CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
|
58
58
|
function formatProviderName(apiFormat) {
|
|
59
59
|
if (apiFormat === 'anthropic')
|
|
60
60
|
return 'Anthropic';
|
|
61
|
+
if (apiFormat === 'openai-responses')
|
|
62
|
+
return 'OpenAI Responses';
|
|
61
63
|
if (apiFormat === 'openai')
|
|
62
64
|
return 'OpenAI兼容';
|
|
63
65
|
return apiFormat;
|
package/src/ui/App.tsx
CHANGED
|
@@ -87,6 +87,7 @@ const CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
|
87
87
|
|
|
88
88
|
function formatProviderName(apiFormat: string): string {
|
|
89
89
|
if (apiFormat === 'anthropic') return 'Anthropic';
|
|
90
|
+
if (apiFormat === 'openai-responses') return 'OpenAI Responses';
|
|
90
91
|
if (apiFormat === 'openai') return 'OpenAI兼容';
|
|
91
92
|
return apiFormat;
|
|
92
93
|
}
|
package/src/ui/MessageList.js
CHANGED
|
@@ -35,7 +35,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
35
35
|
import React from 'react';
|
|
36
36
|
import { Box, Static, Text } from 'ink';
|
|
37
37
|
import { conciseToolDescription } from './toolProgress.js';
|
|
38
|
-
import { advisorOpinionText
|
|
38
|
+
import { advisorOpinionText } from '../advisor/presentation.js';
|
|
39
39
|
import { contentToDisplayText, contentToPlainText } from '../multimodal.js';
|
|
40
40
|
import { splitThinkBlocks } from '../utils/stripThink.js';
|
|
41
41
|
import { figures } from './figures.js';
|
|
@@ -104,16 +104,6 @@ export function buildToolCallIndex(history) {
|
|
|
104
104
|
}
|
|
105
105
|
return map;
|
|
106
106
|
}
|
|
107
|
-
/** 按 consultationId 关联持久化决定,供历史重载时在顾问卡片下恢复展示。 */
|
|
108
|
-
export function buildAdvisorDecisionIndex(history) {
|
|
109
|
-
const decisions = new Map();
|
|
110
|
-
for (const message of history) {
|
|
111
|
-
if (message.role !== 'tool' || message.display_metadata?.kind !== 'advisor_decision')
|
|
112
|
-
continue;
|
|
113
|
-
decisions.set(message.display_metadata.consultationId, message.display_metadata);
|
|
114
|
-
}
|
|
115
|
-
return decisions;
|
|
116
|
-
}
|
|
117
107
|
/**
|
|
118
108
|
* 从 Agent 子任务报告的统计尾巴(agent.ts 固定格式
|
|
119
109
|
* 「(子任务「x」[type]:N 轮 · M 次工具调用,K 次失败)」)解析统计数。
|
|
@@ -218,7 +208,6 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
218
208
|
const items = React.useMemo(() => {
|
|
219
209
|
const turnMetas = summarizeTurn(history);
|
|
220
210
|
const toolIndex = buildToolCallIndex(history);
|
|
221
|
-
const advisorDecisions = buildAdvisorDecisionIndex(history);
|
|
222
211
|
return [
|
|
223
212
|
...(bannerText
|
|
224
213
|
? [
|
|
@@ -234,10 +223,6 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
234
223
|
msg: m,
|
|
235
224
|
turnMeta: turnMetas[idx],
|
|
236
225
|
toolMeta: m.role === 'tool' ? (toolIndex.get(m.tool_call_id) ?? null) : null,
|
|
237
|
-
advisorDecision: m.role === 'tool'
|
|
238
|
-
&& m.display_metadata?.kind === 'advisor_consultation'
|
|
239
|
-
? (advisorDecisions.get(m.display_metadata.consultationId) ?? null)
|
|
240
|
-
: null,
|
|
241
226
|
// 纯派生 key:有 id 用 id,没有就用 idx 兜底。绝不在 render 期 mutate 消息对象
|
|
242
227
|
// (<Static> 已 commit 的行永不重绘,key 仅在 append 对账时用,idx 已足够稳定)。
|
|
243
228
|
key: m.id ?? `message-${idx}`,
|
|
@@ -250,7 +235,7 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
250
235
|
if (item.kind === 'banner') {
|
|
251
236
|
return _jsx(BannerRow, { text: item.text }, item.key);
|
|
252
237
|
}
|
|
253
|
-
return (_jsx(MessageRow, { message: item.msg, turnMeta: item.turnMeta, toolMeta: item.toolMeta,
|
|
238
|
+
return (_jsx(MessageRow, { message: item.msg, turnMeta: item.turnMeta, toolMeta: item.toolMeta, foldReasoning: foldReasoning }, item.key));
|
|
254
239
|
} }, compactGeneration));
|
|
255
240
|
});
|
|
256
241
|
function BannerRow({ text }) {
|
|
@@ -278,7 +263,7 @@ function formatToolHead(meta, shortId, statsTail) {
|
|
|
278
263
|
.trim();
|
|
279
264
|
return `[文件 · ${action}${target ? ` ${target}` : ''} · #${shortId}]${statsTail}`;
|
|
280
265
|
}
|
|
281
|
-
function MessageRow({ message, turnMeta, toolMeta,
|
|
266
|
+
function MessageRow({ message, turnMeta, toolMeta, foldReasoning, }) {
|
|
282
267
|
switch (message.role) {
|
|
283
268
|
case 'system': {
|
|
284
269
|
// v2.x:ephemeral system message 是 UI 临时提示(slash 命令输出等),
|
|
@@ -345,19 +330,10 @@ function MessageRow({ message, turnMeta, toolMeta, advisorDecision, foldReasonin
|
|
|
345
330
|
const lines = terminalText(message.content).split('\n');
|
|
346
331
|
// 顾问意见给更高的预览上限,并用默认亮色而非 dim 灰 —— 它是另一个模型说的话,
|
|
347
332
|
// 不该和 grep 输出一样被视觉降级(见 MAX_ADVISOR_PREVIEW_LINES)。
|
|
348
|
-
const advisorMeta = message.display_metadata?.kind === 'advisor_consultation'
|
|
349
|
-
? message.display_metadata
|
|
350
|
-
: null;
|
|
351
|
-
const decisionMeta = message.display_metadata?.kind === 'advisor_decision'
|
|
352
|
-
? message.display_metadata
|
|
353
|
-
: null;
|
|
354
333
|
const inferredToolName = toolMeta?.toolName
|
|
355
|
-
?? (advisorMeta ? 'Advisor' : null)
|
|
356
|
-
?? (decisionMeta ? 'AdvisorDecision' : null)
|
|
357
334
|
?? (message.display_metadata?.kind === 'result_manifest' ? 'PresentResult' : null)
|
|
358
335
|
?? (message.display_metadata?.kind === 'agent' ? 'Agent' : undefined);
|
|
359
336
|
const isAdvisor = inferredToolName === 'Advisor';
|
|
360
|
-
const isAdvisorDecision = inferredToolName === 'AdvisorDecision';
|
|
361
337
|
if (isAdvisor)
|
|
362
338
|
lines.splice(0, lines.length, ...terminalText(advisorOpinionText(message.content)).split('\n'));
|
|
363
339
|
const visibility = toolHistoryVisibility(inferredToolName, message.content);
|
|
@@ -365,9 +341,6 @@ function MessageRow({ message, turnMeta, toolMeta, advisorDecision, foldReasonin
|
|
|
365
341
|
const previewLines = lines.slice(0, previewCap);
|
|
366
342
|
const hidden = Math.max(0, lines.length - previewCap);
|
|
367
343
|
const shortId = message.tool_call_id.slice(-8);
|
|
368
|
-
if (message.display_metadata?.kind === 'advisor_checkpoint') {
|
|
369
|
-
return _jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsx(Text, { color: theme.subtle, wrap: "end", children: `已暂缓 · 顾问检查点 · 操作尚未执行(/show ${shortId} 查看详情,复核进展见后续记录)` }) });
|
|
370
|
-
}
|
|
371
344
|
// 头行升级:有 toolMeta(发起方反查命中)显示人话描述;Agent 子任务
|
|
372
345
|
// 再解析统计尾巴显示 ✓ N 轮 · M 次工具。无 meta(历史重载等)兜底旧格式。
|
|
373
346
|
const stats = inferredToolName === 'Agent' ? agentResultStats(message.content) : null;
|
|
@@ -377,25 +350,16 @@ function MessageRow({ message, turnMeta, toolMeta, advisorDecision, foldReasonin
|
|
|
377
350
|
// 顾问头行单独成文并去掉 dim:friendlyToolDescription 没有 Advisor 分支,
|
|
378
351
|
// 走兜底会显示成一串参数预览,看不出这是「第二个模型的独立意见」。
|
|
379
352
|
const headText = isAdvisor
|
|
380
|
-
? `[顾问意见 ·
|
|
381
|
-
:
|
|
382
|
-
?
|
|
383
|
-
:
|
|
384
|
-
? formatToolHead(toolMeta, shortId, statsTail)
|
|
385
|
-
: `[tool result · #${shortId}]`;
|
|
353
|
+
? `[顾问意见 · #${shortId}]`
|
|
354
|
+
: toolMeta
|
|
355
|
+
? formatToolHead(toolMeta, shortId, statsTail)
|
|
356
|
+
: `[tool result · #${shortId}]`;
|
|
386
357
|
if (visibility === 'hidden')
|
|
387
358
|
return null;
|
|
388
|
-
if (isAdvisorDecision) {
|
|
389
|
-
return _jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsxs(Text, { color: theme.subtle, wrap: "end", children: [decisionMeta
|
|
390
|
-
? `顾问意见已处理 · ${advisorDecisionLabel(decisionMeta.decision)} · ${advisorEvidenceLabel(decisionMeta.verificationStatus)}`
|
|
391
|
-
: '顾问意见登记未完成 · 可重试', `(/show ${shortId} 查看详情)`] }) });
|
|
392
|
-
}
|
|
393
359
|
if (visibility === 'compact') {
|
|
394
360
|
return (_jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsx(Text, { color: theme.subtle, dimColor: true, wrap: "end", children: terminalText(headText) }) }));
|
|
395
361
|
}
|
|
396
|
-
return (_jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, ...(isAdvisor ? {} : { dimColor: true }), wrap: "end", children: terminalText(headText) }),
|
|
397
|
-
? '顾问意见已返回,尚不代表事实核验通过'
|
|
398
|
-
: '顾问咨询未完成,已降级继续') }), advisorMeta.status === 'completed' && !advisorDecision && (_jsx(Text, { color: theme.subtle, wrap: "end", children: "\u987E\u95EE\u610F\u89C1\u5DF2\u8FD4\u56DE\uFF1B\u4E3B Agent \u7684\u6838\u9A8C\u4E0E\u91C7\u7EB3\u7ED3\u8BBA\u89C1\u540E\u7EED\u8BB0\u5F55\u3002" })), advisorDecision && (_jsx(Text, { color: theme.subtle, wrap: "end", children: terminalText(`${advisorDecision.decision} · ${advisorDecision.rationale}`) })), advisorDecision?.verificationPlan.map((item) => (_jsx(Text, { color: theme.subtle, wrap: "end", children: terminalText(`验证:${item}`) }, `advisor-card-verify-${item}`)))] })), decisionMeta && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, wrap: "end", children: terminalText(`关联咨询 ${decisionMeta.consultationId} · ${decisionMeta.rationale}`) }), decisionMeta.verificationPlan.map((item) => (_jsx(Text, { color: theme.subtle, wrap: "end", children: terminalText(`验证:${item}`) }, `advisor-verify-${item}`)))] })), previewLines.map((line, i) => (_jsx(Text, { ...(isAdvisor ? {} : { color: theme.subtle }), wrap: "end", children: line.length > 0 ? line : ' ' }, `p-${i}`))), hidden > 0 && (_jsx(Text, { color: theme.subtle, dimColor: true, children: `... ${figures.fold} 完整 ${lines.length} 行(输入 /show ${shortId} 查看)` }))] }) }));
|
|
362
|
+
return (_jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, ...(isAdvisor ? {} : { dimColor: true }), wrap: "end", children: terminalText(headText) }), previewLines.map((line, i) => (_jsx(Text, { ...(isAdvisor ? {} : { color: theme.subtle }), wrap: "end", children: line.length > 0 ? line : ' ' }, `p-${i}`))), hidden > 0 && (_jsx(Text, { color: theme.subtle, dimColor: true, children: `... ${figures.fold} 完整 ${lines.length} 行(输入 /show ${shortId} 查看)` }))] }) }));
|
|
399
363
|
}
|
|
400
364
|
}
|
|
401
365
|
}
|
package/src/ui/MessageList.tsx
CHANGED
|
@@ -36,9 +36,9 @@ import React from 'react';
|
|
|
36
36
|
import { Box, Static, Text } from 'ink';
|
|
37
37
|
|
|
38
38
|
import { conciseToolDescription } from './toolProgress.js';
|
|
39
|
-
import { advisorOpinionText
|
|
39
|
+
import { advisorOpinionText } from '../advisor/presentation.js';
|
|
40
40
|
import { contentToDisplayText, contentToPlainText } from '../multimodal.js';
|
|
41
|
-
import type {
|
|
41
|
+
import type { Message } from '../types.js';
|
|
42
42
|
import { splitThinkBlocks } from '../utils/stripThink.js';
|
|
43
43
|
import { figures } from './figures.js';
|
|
44
44
|
import { terminalText } from './terminalText.js';
|
|
@@ -72,7 +72,6 @@ type StaticItem =
|
|
|
72
72
|
turnMeta: TurnMeta | null;
|
|
73
73
|
/** tool 消息的发起方人话描述(buildToolCallIndex 反查);其余消息 null */
|
|
74
74
|
toolMeta: ToolCallMeta | null;
|
|
75
|
-
advisorDecision: AdvisorDecisionMetadata | null;
|
|
76
75
|
key: string;
|
|
77
76
|
};
|
|
78
77
|
|
|
@@ -167,18 +166,6 @@ export function buildToolCallIndex(history: Message[]): Map<string, ToolCallMeta
|
|
|
167
166
|
return map;
|
|
168
167
|
}
|
|
169
168
|
|
|
170
|
-
/** 按 consultationId 关联持久化决定,供历史重载时在顾问卡片下恢复展示。 */
|
|
171
|
-
export function buildAdvisorDecisionIndex(
|
|
172
|
-
history: Message[],
|
|
173
|
-
): Map<string, AdvisorDecisionMetadata> {
|
|
174
|
-
const decisions = new Map<string, AdvisorDecisionMetadata>();
|
|
175
|
-
for (const message of history) {
|
|
176
|
-
if (message.role !== 'tool' || message.display_metadata?.kind !== 'advisor_decision') continue;
|
|
177
|
-
decisions.set(message.display_metadata.consultationId, message.display_metadata);
|
|
178
|
-
}
|
|
179
|
-
return decisions;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
169
|
/**
|
|
183
170
|
* 从 Agent 子任务报告的统计尾巴(agent.ts 固定格式
|
|
184
171
|
* 「(子任务「x」[type]:N 轮 · M 次工具调用,K 次失败)」)解析统计数。
|
|
@@ -302,7 +289,6 @@ export const MessageList = React.memo(function MessageList({
|
|
|
302
289
|
const items: StaticItem[] = React.useMemo(() => {
|
|
303
290
|
const turnMetas = summarizeTurn(history);
|
|
304
291
|
const toolIndex = buildToolCallIndex(history);
|
|
305
|
-
const advisorDecisions = buildAdvisorDecisionIndex(history);
|
|
306
292
|
return [
|
|
307
293
|
...(bannerText
|
|
308
294
|
? [
|
|
@@ -318,10 +304,6 @@ export const MessageList = React.memo(function MessageList({
|
|
|
318
304
|
msg: m,
|
|
319
305
|
turnMeta: turnMetas[idx],
|
|
320
306
|
toolMeta: m.role === 'tool' ? (toolIndex.get(m.tool_call_id) ?? null) : null,
|
|
321
|
-
advisorDecision: m.role === 'tool'
|
|
322
|
-
&& m.display_metadata?.kind === 'advisor_consultation'
|
|
323
|
-
? (advisorDecisions.get(m.display_metadata.consultationId) ?? null)
|
|
324
|
-
: null,
|
|
325
307
|
// 纯派生 key:有 id 用 id,没有就用 idx 兜底。绝不在 render 期 mutate 消息对象
|
|
326
308
|
// (<Static> 已 commit 的行永不重绘,key 仅在 append 对账时用,idx 已足够稳定)。
|
|
327
309
|
key: m.id ?? `message-${idx}`,
|
|
@@ -345,7 +327,6 @@ export const MessageList = React.memo(function MessageList({
|
|
|
345
327
|
message={item.msg}
|
|
346
328
|
turnMeta={item.turnMeta}
|
|
347
329
|
toolMeta={item.toolMeta}
|
|
348
|
-
advisorDecision={item.advisorDecision}
|
|
349
330
|
foldReasoning={foldReasoning}
|
|
350
331
|
/>
|
|
351
332
|
);
|
|
@@ -391,13 +372,11 @@ function MessageRow({
|
|
|
391
372
|
message,
|
|
392
373
|
turnMeta,
|
|
393
374
|
toolMeta,
|
|
394
|
-
advisorDecision,
|
|
395
375
|
foldReasoning,
|
|
396
376
|
}: {
|
|
397
377
|
message: Message;
|
|
398
378
|
turnMeta: TurnMeta | null;
|
|
399
379
|
toolMeta?: ToolCallMeta | null;
|
|
400
|
-
advisorDecision?: AdvisorDecisionMetadata | null;
|
|
401
380
|
foldReasoning: boolean;
|
|
402
381
|
}): JSX.Element | null {
|
|
403
382
|
switch (message.role) {
|
|
@@ -553,30 +532,16 @@ function MessageRow({
|
|
|
553
532
|
const lines = terminalText(message.content).split('\n');
|
|
554
533
|
// 顾问意见给更高的预览上限,并用默认亮色而非 dim 灰 —— 它是另一个模型说的话,
|
|
555
534
|
// 不该和 grep 输出一样被视觉降级(见 MAX_ADVISOR_PREVIEW_LINES)。
|
|
556
|
-
const advisorMeta = message.display_metadata?.kind === 'advisor_consultation'
|
|
557
|
-
? message.display_metadata
|
|
558
|
-
: null;
|
|
559
|
-
const decisionMeta = message.display_metadata?.kind === 'advisor_decision'
|
|
560
|
-
? message.display_metadata
|
|
561
|
-
: null;
|
|
562
535
|
const inferredToolName = toolMeta?.toolName
|
|
563
|
-
?? (advisorMeta ? 'Advisor' : null)
|
|
564
|
-
?? (decisionMeta ? 'AdvisorDecision' : null)
|
|
565
536
|
?? (message.display_metadata?.kind === 'result_manifest' ? 'PresentResult' : null)
|
|
566
537
|
?? (message.display_metadata?.kind === 'agent' ? 'Agent' : undefined);
|
|
567
538
|
const isAdvisor = inferredToolName === 'Advisor';
|
|
568
|
-
const isAdvisorDecision = inferredToolName === 'AdvisorDecision';
|
|
569
539
|
if (isAdvisor) lines.splice(0, lines.length, ...terminalText(advisorOpinionText(message.content)).split('\n'));
|
|
570
540
|
const visibility = toolHistoryVisibility(inferredToolName, message.content);
|
|
571
541
|
const previewCap = toolPreviewCap(inferredToolName);
|
|
572
542
|
const previewLines = lines.slice(0, previewCap);
|
|
573
543
|
const hidden = Math.max(0, lines.length - previewCap);
|
|
574
544
|
const shortId = message.tool_call_id.slice(-8);
|
|
575
|
-
if (message.display_metadata?.kind === 'advisor_checkpoint') {
|
|
576
|
-
return <Box marginBottom={1} paddingLeft={2}><Text color={theme.subtle} wrap="end">
|
|
577
|
-
{`已暂缓 · 顾问检查点 · 操作尚未执行(/show ${shortId} 查看详情,复核进展见后续记录)`}
|
|
578
|
-
</Text></Box>;
|
|
579
|
-
}
|
|
580
545
|
// 头行升级:有 toolMeta(发起方反查命中)显示人话描述;Agent 子任务
|
|
581
546
|
// 再解析统计尾巴显示 ✓ N 轮 · M 次工具。无 meta(历史重载等)兜底旧格式。
|
|
582
547
|
const stats =
|
|
@@ -587,20 +552,11 @@ function MessageRow({
|
|
|
587
552
|
// 顾问头行单独成文并去掉 dim:friendlyToolDescription 没有 Advisor 分支,
|
|
588
553
|
// 走兜底会显示成一串参数预览,看不出这是「第二个模型的独立意见」。
|
|
589
554
|
const headText = isAdvisor
|
|
590
|
-
? `[顾问意见 ·
|
|
591
|
-
: isAdvisorDecision
|
|
592
|
-
? `[顾问意见处理 · ${decisionMeta?.decision ?? 'unknown'} · #${shortId}]`
|
|
555
|
+
? `[顾问意见 · #${shortId}]`
|
|
593
556
|
: toolMeta
|
|
594
557
|
? formatToolHead(toolMeta, shortId, statsTail)
|
|
595
558
|
: `[tool result · #${shortId}]`;
|
|
596
559
|
if (visibility === 'hidden') return null;
|
|
597
|
-
if (isAdvisorDecision) {
|
|
598
|
-
return <Box marginBottom={1} paddingLeft={2}><Text color={theme.subtle} wrap="end">
|
|
599
|
-
{decisionMeta
|
|
600
|
-
? `顾问意见已处理 · ${advisorDecisionLabel(decisionMeta.decision)} · ${advisorEvidenceLabel(decisionMeta.verificationStatus)}`
|
|
601
|
-
: '顾问意见登记未完成 · 可重试'}{`(/show ${shortId} 查看详情)`}
|
|
602
|
-
</Text></Box>;
|
|
603
|
-
}
|
|
604
560
|
if (visibility === 'compact') {
|
|
605
561
|
return (
|
|
606
562
|
<Box marginBottom={1} paddingLeft={2}>
|
|
@@ -616,40 +572,6 @@ function MessageRow({
|
|
|
616
572
|
<Text color={theme.subtle} {...(isAdvisor ? {} : { dimColor: true })} wrap="end">
|
|
617
573
|
{terminalText(headText)}
|
|
618
574
|
</Text>
|
|
619
|
-
{advisorMeta && (
|
|
620
|
-
<Box flexDirection="column">
|
|
621
|
-
<Text color={theme.subtle} wrap="end">
|
|
622
|
-
{terminalText(advisorMeta.status === 'completed'
|
|
623
|
-
? '顾问意见已返回,尚不代表事实核验通过'
|
|
624
|
-
: '顾问咨询未完成,已降级继续')}
|
|
625
|
-
</Text>
|
|
626
|
-
{advisorMeta.status === 'completed' && !advisorDecision && (
|
|
627
|
-
<Text color={theme.subtle} wrap="end">顾问意见已返回;主 Agent 的核验与采纳结论见后续记录。</Text>
|
|
628
|
-
)}
|
|
629
|
-
{advisorDecision && (
|
|
630
|
-
<Text color={theme.subtle} wrap="end">
|
|
631
|
-
{terminalText(`${advisorDecision.decision} · ${advisorDecision.rationale}`)}
|
|
632
|
-
</Text>
|
|
633
|
-
)}
|
|
634
|
-
{advisorDecision?.verificationPlan.map((item) => (
|
|
635
|
-
<Text key={`advisor-card-verify-${item}`} color={theme.subtle} wrap="end">
|
|
636
|
-
{terminalText(`验证:${item}`)}
|
|
637
|
-
</Text>
|
|
638
|
-
))}
|
|
639
|
-
</Box>
|
|
640
|
-
)}
|
|
641
|
-
{decisionMeta && (
|
|
642
|
-
<Box flexDirection="column">
|
|
643
|
-
<Text color={theme.subtle} wrap="end">
|
|
644
|
-
{terminalText(`关联咨询 ${decisionMeta.consultationId} · ${decisionMeta.rationale}`)}
|
|
645
|
-
</Text>
|
|
646
|
-
{decisionMeta.verificationPlan.map((item) => (
|
|
647
|
-
<Text key={`advisor-verify-${item}`} color={theme.subtle} wrap="end">
|
|
648
|
-
{terminalText(`验证:${item}`)}
|
|
649
|
-
</Text>
|
|
650
|
-
))}
|
|
651
|
-
</Box>
|
|
652
|
-
)}
|
|
653
575
|
{/* 逐行 wrap='end':整段默认 wrap 会注入真实换行,从预览复制会被硬断行 */}
|
|
654
576
|
{previewLines.map((line, i) => (
|
|
655
577
|
<Text key={`p-${i}`} {...(isAdvisor ? {} : { color: theme.subtle })} wrap="end">
|
package/src/ui/hooks/useChat.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* 用 version 计数器驱动 setState 触发 re-render 是更顺手的写法。
|
|
15
15
|
* ============================================================
|
|
16
16
|
*/
|
|
17
|
+
import { previousUserRequest } from '../../memory/recallQuery.js';
|
|
17
18
|
import { stat } from 'node:fs/promises';
|
|
18
19
|
import { createTurnSummary } from '../turnSummary.js';
|
|
19
20
|
import { isRecoverableLoopError } from '../../runtime/eventSemantics.js';
|
|
@@ -529,6 +530,7 @@ export function useChat(args) {
|
|
|
529
530
|
surface: 'tui',
|
|
530
531
|
cwd: effectiveCwd,
|
|
531
532
|
currentUserInput: trimmed,
|
|
533
|
+
previousUserInput: previousUserRequest(historyRef.current),
|
|
532
534
|
workspaceId: workspace?.id,
|
|
533
535
|
sessionId: activeSessionIdRef.current,
|
|
534
536
|
interactiveAsk: true,
|
package/src/ui/hooks/useChat.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* ============================================================
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { previousUserRequest } from '../../memory/recallQuery.js';
|
|
18
19
|
import { stat } from 'node:fs/promises';
|
|
19
20
|
import { createTurnSummary } from '../turnSummary.js';
|
|
20
21
|
import { isRecoverableLoopError } from '../../runtime/eventSemantics.js';
|
|
@@ -829,6 +830,7 @@ export function useChat(args: {
|
|
|
829
830
|
surface: 'tui',
|
|
830
831
|
cwd: effectiveCwd,
|
|
831
832
|
currentUserInput: trimmed,
|
|
833
|
+
previousUserInput: previousUserRequest(historyRef.current),
|
|
832
834
|
workspaceId: workspace?.id,
|
|
833
835
|
sessionId: activeSessionIdRef.current,
|
|
834
836
|
interactiveAsk: true,
|
package/src/ui/toolProgress.js
CHANGED
|
@@ -38,7 +38,7 @@ export function toolBatchSummary(calls, maxItems = 2) {
|
|
|
38
38
|
}
|
|
39
39
|
/** 成功的普通工具结果不写 scrollback;失败和高价值结果仍保留。 */
|
|
40
40
|
export function toolHistoryVisibility(toolName, content) {
|
|
41
|
-
if (toolName === 'Advisor' || toolName === '
|
|
41
|
+
if (toolName === 'Advisor' || toolName === 'PresentResult'
|
|
42
42
|
|| toolName === 'RememberMemory' || toolName === 'UpdateMemory' || toolName === 'ForgetMemory'
|
|
43
43
|
|| toolName === 'ConfirmMemory' || toolName === 'SetPersona' || toolName === 'ClearPersona')
|
|
44
44
|
return 'full';
|
package/src/ui/toolProgress.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type ToolHistoryVisibility = 'hidden' | 'compact' | 'full';
|
|
|
43
43
|
|
|
44
44
|
/** 成功的普通工具结果不写 scrollback;失败和高价值结果仍保留。 */
|
|
45
45
|
export function toolHistoryVisibility(toolName: string | undefined, content: string): ToolHistoryVisibility {
|
|
46
|
-
if (toolName === 'Advisor' || toolName === '
|
|
46
|
+
if (toolName === 'Advisor' || toolName === 'PresentResult'
|
|
47
47
|
|| toolName === 'RememberMemory' || toolName === 'UpdateMemory' || toolName === 'ForgetMemory'
|
|
48
48
|
|| toolName === 'ConfirmMemory' || toolName === 'SetPersona' || toolName === 'ClearPersona') return 'full';
|
|
49
49
|
if (toolName === 'Agent') return 'compact';
|
package/src/web/protocol.ts
CHANGED
|
@@ -295,7 +295,10 @@ export interface SkillInfo {
|
|
|
295
295
|
unavailableReason?: string;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
export type ApiFormat = 'openai' | 'anthropic';
|
|
298
|
+
export type ApiFormat = 'openai' | 'openai-responses' | 'anthropic';
|
|
299
|
+
|
|
300
|
+
/** 推理强度;缺省 = 不发送,沿用服务端对该模型的默认强度。 */
|
|
301
|
+
export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
299
302
|
|
|
300
303
|
/** 模型列表的一个条目(脱敏视图——apiKey 只给 configured 布尔位,不下发原文)。 */
|
|
301
304
|
export interface ModelView {
|
|
@@ -317,6 +320,7 @@ export interface ModelView {
|
|
|
317
320
|
contextWindow: number;
|
|
318
321
|
maxTokens?: number;
|
|
319
322
|
supportsVision?: boolean;
|
|
323
|
+
reasoningEffort?: ReasoningEffort;
|
|
320
324
|
promptCache?: { mode: 'auto' | 'session-key' | 'disabled' };
|
|
321
325
|
enabled: boolean;
|
|
322
326
|
updatedAt: number;
|
|
@@ -347,10 +351,11 @@ export interface WebchatConfig {
|
|
|
347
351
|
configured: boolean;
|
|
348
352
|
enabled: boolean;
|
|
349
353
|
mode: 'auto' | 'manual';
|
|
354
|
+
/** remind = 只提醒;followup = 实质回答未复核时再请求一次,让模型自己补问顾问。 */
|
|
355
|
+
enforcement: 'remind' | 'followup';
|
|
350
356
|
/** 引用 models[].id;null = 未选。顾问不再自带一整套独立凭据。 */
|
|
351
357
|
modelId: string | null;
|
|
352
358
|
contextPolicy: 'full-relevant';
|
|
353
|
-
shareSensitive: boolean;
|
|
354
359
|
inputTokenBudget: number;
|
|
355
360
|
timeoutMs: number;
|
|
356
361
|
};
|
|
@@ -413,6 +418,8 @@ export interface ModelPatchFields {
|
|
|
413
418
|
contextWindow?: number;
|
|
414
419
|
maxTokens?: number;
|
|
415
420
|
supportsVision?: boolean;
|
|
421
|
+
/** update 时 null = 清除,回到服务端对该模型的默认强度。 */
|
|
422
|
+
reasoningEffort?: ReasoningEffort | null;
|
|
416
423
|
promptCache?: { mode: 'auto' | 'session-key' | 'disabled' };
|
|
417
424
|
enabled?: boolean;
|
|
418
425
|
}
|
|
@@ -431,8 +438,8 @@ export interface WebchatConfigPatch {
|
|
|
431
438
|
clear?: boolean;
|
|
432
439
|
enabled?: boolean;
|
|
433
440
|
mode?: 'auto' | 'manual';
|
|
441
|
+
enforcement?: 'remind' | 'followup';
|
|
434
442
|
modelId?: string | null;
|
|
435
|
-
shareSensitive?: boolean;
|
|
436
443
|
inputTokenBudget?: number;
|
|
437
444
|
timeoutMs?: number;
|
|
438
445
|
};
|