@tencent-ai/agent-harness 0.2.0-beta.1 → 0.2.0-beta.2

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/cli/CHANGELOG.md +71 -0
  4. package/cli/dist-server/shared.cjs +318 -314
  5. package/cli/dist-server/types/node/acp/acp-protocol.d.ts +40 -12
  6. package/cli/dist-server/types/node/acp/usage-by-category-calculator.d.ts +21 -0
  7. package/cli/dist-server/types/node/cli/stream-json-protocol.d.ts +15 -1
  8. package/cli/dist-server/types/node/data-fs/index.d.ts +13 -1
  9. package/cli/dist-server/types/node/hooks/hook-protocol.d.ts +2 -2
  10. package/cli/dist-server/types/node/server/sessions.d.ts +24 -0
  11. package/cli/dist-server/types/node/server/types.d.ts +6 -0
  12. package/cli/dist-server/types/node/settings/settings-protocol.d.ts +5 -0
  13. package/cli/dist-server/types/node/tools/tool-protocol.d.ts +112 -2
  14. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-protocol.d.ts +29 -0
  15. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-service.d.ts +2 -0
  16. package/cli/dist-server/types/vendor/cbc-core/node/agent/index.d.ts +1 -0
  17. package/cli/dist-server/types/vendor/cbc-core/node/agent/interceptors/input-interceptors.d.ts +1 -6
  18. package/cli/dist-server/types/vendor/cbc-core/node/agent/runner-factory.d.ts +31 -11
  19. package/cli/dist-server/types/vendor/cbc-core/node/agent/speaker-label.d.ts +44 -0
  20. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-detector-service.d.ts +5 -4
  21. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  22. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-pattern.d.ts +15 -4
  23. package/cli/dist-server/types/vendor/cbc-core/node/hooks/agent-trigger.d.ts +6 -22
  24. package/cli/dist-server/types/vendor/cbc-core/node/hooks/hook-protocol.d.ts +4 -1
  25. package/cli/dist-server/types/vendor/cbc-core/node/session/idle-queue-drain-service.d.ts +4 -56
  26. package/cli/dist-server/types/vendor/cbc-core/node/session/index.d.ts +3 -0
  27. package/cli/dist-server/types/vendor/cbc-core/node/session/interruption-service.d.ts +55 -9
  28. package/cli/dist-server/types/vendor/cbc-core/node/session/model-response-interceptors.d.ts +18 -0
  29. package/cli/dist-server/types/vendor/cbc-core/node/session/recovery-budget.d.ts +55 -0
  30. package/cli/dist-server/types/vendor/cbc-core/node/session/session-hook-manager.d.ts +15 -0
  31. package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager.d.ts +10 -1
  32. package/cli/dist-server/types/vendor/cbc-core/node/session/session-persistence-error.d.ts +43 -0
  33. package/cli/dist-server/types/vendor/cbc-core/node/session/session-protocol.d.ts +63 -4
  34. package/cli/dist-server/types/vendor/cbc-core/node/session/session-run-state-machine-protocol.d.ts +1 -0
  35. package/cli/dist-server/types/vendor/cbc-core/node/session/session-runtime-lifecycle.d.ts +5 -0
  36. package/cli/dist-server/types/vendor/cbc-core/node/session/session-store.d.ts +150 -4
  37. package/cli/dist-server/types/vendor/cbc-core/node/session/stream-timeout-retry-budget.d.ts +13 -1
  38. package/cli/dist-server/types/vendor/cbc-core/node/utils/history-utils.d.ts +23 -0
  39. package/cli/dist-server/types/vendor/cbc-core/node/utils/index.d.ts +1 -0
  40. package/cli/dist-server/types/vendor/cbc-core/node/utils/message-utils.d.ts +12 -0
  41. package/cli/dist-server/types/vendor/cbc-core/node/utils/model-utils.d.ts +7 -0
  42. package/cli/dist-server/types/vendor/cbc-core/node/utils/queue-dispatch-utils.d.ts +24 -2
  43. package/cli/dist-server/types/vendor/cbc-core/node/utils/session-utils.d.ts +4 -1
  44. package/cli/dist-server/types/vendor/cbc-core/node/utils/string-retention-utils.d.ts +4 -0
  45. package/cli/dist-server/types/vendor/cbc-shared/node/hooks/hook-types.d.ts +7 -1
  46. package/cli/dist-server/types/vendor/cbc-shared/node/index.d.ts +2 -0
  47. package/cli/dist-server/types/vendor/cbc-shared/node/model/model-errors.d.ts +7 -3
  48. package/cli/dist-server/types/vendor/cbc-shared/node/tools/tool-names.d.ts +1 -0
  49. package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-backoff.d.ts +30 -0
  50. package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-policy.d.ts +26 -0
  51. package/cli/dist-server/types/workspace/authentication/lib/common/account-scoped-external-link-authentication-provider.d.ts +2 -2
  52. package/cli/dist-server/types/workspace/authentication/lib/common/account-utils.d.ts +25 -0
  53. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-manager.d.ts +2 -2
  54. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-protocol.d.ts +19 -2
  55. package/cli/dist-server/types/workspace/authentication/lib/common/external-link-authentication-provider.d.ts +2 -2
  56. package/cli/dist-server/types/workspace/authentication/lib/common/wx-authentication-provider.d.ts +2 -2
  57. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-protocol.d.ts +29 -0
  58. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-service.d.ts +2 -0
  59. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/index.d.ts +1 -0
  60. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/interceptors/input-interceptors.d.ts +1 -6
  61. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/runner-factory.d.ts +31 -11
  62. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/speaker-label.d.ts +44 -0
  63. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-detector-service.d.ts +5 -4
  64. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  65. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-pattern.d.ts +15 -4
  66. package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/agent-trigger.d.ts +6 -22
  67. package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/hook-protocol.d.ts +4 -1
  68. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/idle-queue-drain-service.d.ts +4 -56
  69. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/index.d.ts +3 -0
  70. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/interruption-service.d.ts +55 -9
  71. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/model-response-interceptors.d.ts +18 -0
  72. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/recovery-budget.d.ts +55 -0
  73. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-hook-manager.d.ts +15 -0
  74. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager.d.ts +10 -1
  75. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-persistence-error.d.ts +43 -0
  76. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-protocol.d.ts +63 -4
  77. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-run-state-machine-protocol.d.ts +1 -0
  78. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-runtime-lifecycle.d.ts +5 -0
  79. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-store.d.ts +150 -4
  80. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/stream-timeout-retry-budget.d.ts +13 -1
  81. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/history-utils.d.ts +23 -0
  82. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/index.d.ts +1 -0
  83. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/message-utils.d.ts +12 -0
  84. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/model-utils.d.ts +7 -0
  85. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/queue-dispatch-utils.d.ts +24 -2
  86. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/session-utils.d.ts +4 -1
  87. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/string-retention-utils.d.ts +4 -0
  88. package/cli/dist-server/types/workspace/cbc-shared/lib/node/hooks/hook-types.d.ts +7 -1
  89. package/cli/dist-server/types/workspace/cbc-shared/lib/node/index.d.ts +2 -0
  90. package/cli/dist-server/types/workspace/cbc-shared/lib/node/model/model-errors.d.ts +7 -3
  91. package/cli/dist-server/types/workspace/cbc-shared/lib/node/tools/tool-names.d.ts +1 -0
  92. package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-backoff.d.ts +30 -0
  93. package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-policy.d.ts +26 -0
  94. package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-execution.d.ts +14 -1
  95. package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-manager.d.ts +7 -0
  96. package/cli/dist-server/types/workspace/cbc-worktree/lib/node/worktree/worktree-session.d.ts +3 -0
  97. package/cli/dist-server/types/workspace/product/lib/common/cloud-product-provider.d.ts +9 -0
  98. package/cli/dist-server/types/workspace/product/lib/common/index.d.ts +1 -0
  99. package/cli/dist-server/types/workspace/product/lib/common/pick-market-skill-id.d.ts +13 -0
  100. package/cli/dist-server/types/workspace/product/lib/common/tool-control-catalog.d.ts +2 -2
  101. package/cli/dist-server/types/workspace/product/lib/common/types/features.d.ts +62 -2
  102. package/cli/dist-server/types/workspace/product/lib/common/types/language-model.d.ts +66 -0
  103. package/cli/dist-server/types/workspace/product/lib/common/types/product.d.ts +7 -1
  104. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/backup-policy.d.ts +10 -1
  105. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/center-protocol.generated.d.ts +370 -4
  106. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/file-policy.d.ts +1 -1
  107. package/cli/dist-server/types/workspace/sandbox-cli/lib/node/sandbox-center-client.d.ts +216 -0
  108. package/cli/package.json +1 -1
  109. package/cli/product.cloudhosted.json +2 -2
  110. package/cli/product.internal.json +259 -40
  111. package/cli/product.ioa.json +333 -148
  112. package/cli/product.json +309 -351
  113. package/cli/product.selfhosted.json +2 -2
  114. package/docs/README.md +1 -0
  115. package/docs/in-process.md +16 -0
  116. package/lib/application/services.d.ts +3 -1
  117. package/lib/application/services.js +1 -1
  118. package/lib/components/sandbox-center.d.mts +2 -0
  119. package/lib/components/sandbox-center.mjs +1 -0
  120. package/lib/components/session-config.d.mts +2 -0
  121. package/lib/components/session-config.mjs +1 -1
  122. package/lib/harness/create-harness.js +1 -1
  123. package/lib/harness/runtime.js +1 -1
  124. package/lib/harness/types.d.ts +3 -0
  125. package/lib/integration/executor-supervisor.js +1 -1
  126. package/lib/public.d.ts +1 -0
  127. package/lib/runtime/sandbox-center.d.ts +21 -0
  128. package/lib/runtime/sandbox-center.js +1 -0
  129. package/lib/server/public.d.ts +1 -0
  130. package/lib/session/agent-backend.d.ts +2 -0
  131. package/lib/session/agent-backend.js +1 -1
  132. package/lib/session/local-fs.js +1 -1
  133. package/lib/session/server-config.js +1 -1
  134. package/lib/session/server-interactions.js +1 -1
  135. package/package.json +25 -15
  136. package/lib/session/local-options.d.ts +0 -50
  137. package/lib/session/local-options.js +0 -1
@@ -3,13 +3,12 @@ import type { Agent, AgentSideConnection, AuthenticateRequest, AuthenticateRespo
3
3
  import type { Deferred } from '@celljs/core';
4
4
  import type { ModelInfo, SetSessionModelRequest, SetSessionModelResponse } from '../../workspace/agent-client-protocol/lib/common/index.js';
5
5
  import type { CheckpointBroadcastEvent, CheckpointBroadcastInfo } from '../../workspace/cbc-checkpoint/lib/node/index.js';
6
+ import type { Session } from '../../vendor/cbc-core/node/index.js';
7
+ import type { PermissionMode, RunToolApprovalItem } from '../../vendor/cbc-shared/node/index.js';
6
8
  import type { W3CTraceContextMeta } from '../../workspace/telemetry/lib/common/index.js';
7
9
  import type { Subject } from 'rxjs';
8
- import type { RunToolApprovalItem } from '../../vendor/cbc-shared/node/index.js';
9
10
  import type { CommonRequest } from '../loopback/server-protocol';
10
11
  import type { McpFirstRunStatusEvent } from '../mcp/mcp-first-run-status-protocol';
11
- import type { Session } from '../../vendor/cbc-core/node/index.js';
12
- import type { PermissionMode } from '../../vendor/cbc-shared/node/index.js';
13
12
  export * from './acp-kernel-protocol';
14
13
  /**
15
14
  * 上下文消耗 5 类目细拆 schema。
@@ -409,9 +408,26 @@ export interface AcpBroadcastService {
409
408
  * scopeId / createdAt 等实现细节给前端。
410
409
  */
411
410
  export interface GoalRecapPayload {
411
+ /**
412
+ * 本次 recap 的生成时间:宿主用它区分「新一次查询」与「同一条重复下发」
413
+ * (关掉后同一次不再弹;再问一次 /goal 会拿到新的 at,应该重新弹)。
414
+ */
415
+ at?: number;
416
+ /**
417
+ * 进行中目标的状态:除条件 / 暂停态外,带上无参 /goal 要展示的详细项
418
+ * (运行时长 / 评估 turn 数 / Token 消耗 / 最近一次评估原因)。
419
+ */
412
420
  active?: {
413
421
  condition: string;
414
422
  paused?: boolean;
423
+ /** 已运行时长(暂停态冻在 pausedAt)。 */
424
+ durationMs?: number;
425
+ /** 已评估轮次(Stop hook 评估次数)。 */
426
+ turnCount?: number;
427
+ /** 目标期间累计消耗的 token(当前会话用量 - 目标起点用量)。 */
428
+ tokenDelta?: number;
429
+ /** 最近一次 Stop hook 的评估原因(goal-progress 项的 reason)。 */
430
+ reason?: string;
415
431
  };
416
432
  latest?: {
417
433
  ok: boolean;
@@ -764,6 +780,17 @@ export declare const ACP_CANCEL_REASON_TOOL_CALL_LOOP_STOPPED: "tool_call_loop_s
764
780
  /** `codebuddy.ai/interceptType` 取值:疑似工具调用循环,请用户决定继续还是停止。 */
765
781
  export declare const TOOL_CALL_LOOP_INTERCEPT_TYPE: "tool-call-loop";
766
782
  export declare const ACP_META_SENSITIVE_INPUT_DECISION: "codebuddy.ai/sensitiveInputDecision";
783
+ /**
784
+ * `_codebuddy.ai/goalControl` 扩展方法名(宿主目标控制通道)。
785
+ *
786
+ * 必须与 workbuddy-core 的 `ConversationAcpMethod.GoalControl` 完全一致。
787
+ *
788
+ * 常量放在协议面而不是 acp-goal-control(控制实现)里:acp-stream-manager 只需要这个
789
+ * 字符串来判定 unary JSON 交付,若从实现文件取,冷启动链就会静态挂上整个控制实现
790
+ * (GoalService / broadcast / SDK 面),实现里任何新 import 都会静默落到 standby
791
+ * 冷启动路径上 —— bundle-lite-wb-prewarm-memory 卡点就是这么被顶穿的。
792
+ */
793
+ export declare const GOAL_CONTROL_METHOD: "_codebuddy.ai/goalControl";
767
794
  /**
768
795
  * Cancel 事件
769
796
  * 用于 AcpAgent 向 AcpView 传递取消指令
@@ -947,22 +974,23 @@ export interface AcpAgentManager {
947
974
  * 事件触发,**会被 250ms 节流合并**,避免高频累加 usage 时刷屏。
948
975
  * - 其它来源全部**立即推送**(绕过节流):
949
976
  * - `'new_session'` / `'load_session'` / `'resume_session'`:首发,让客户端在第一帧就拿到 0% / 模型 size
977
+ * - `'prompt_start'`:prompt 刚开始、模型思考/写文件尚未返回真实 usage 的窗口,用本地估算
978
+ * 的输入 token 推一帧占位(used 估算 + byCategory),避免上下文环空白;随后由 stream/prompt_end 校准
950
979
  * - `'prompt_end'`:prompt 出口(无论 stopReason),保证终值正确
980
+ * - `'compacted'`:压缩(自动/手动)完成后立即推一帧(used = 压缩后 history 估算),环即刻降到新值
981
+ * 而非等下一轮 prompt;publisher 同时重置 turn 高水位,使这次真实下降不被单调约束挡住
951
982
  * - `'model_changed'`:分母切换
952
983
  * - `'cancel'`:用户取消快照
953
984
  *
954
- * compact 完成不再触发 `usage_update`;上下文环数值由用户下一次 prompt 走
955
- * `combineSubject(input)` 节流路径自然回填真实 inputTokens。
956
- *
957
985
  * usageByCategory 触发拍:
958
- * - `ACP_USAGE_CATEGORY_SNAPSHOT_SOURCES` 中的路径在推送时附带
986
+ * - `ACP_USAGE_CATEGORY_SNAPSHOT_SOURCES` 中的路径走**全量**计算并附带
959
987
  * `_meta['codebuddy.ai/usageByCategory']`,sum(usageByCategory) 严格 === update.used。
960
- * - `'stream'` / `'model_changed'` 路径**不写**该字段,客户端复用上一次缓存值;
961
- * model_changed 只同步新的 context size,避免派生统计重跑动态 agent instructions
962
- * 并阻塞 set_model 控制 RPC。下一次 prompt_end 会刷新 category。
988
+ * - `'stream'` 路径走**turn 级增量**(见 usage-by-category-incremental),同样附带 usageByCategory,
989
+ * 让「对话进行中」也能实时展示 5 类明细,且不重跑动态 agent instructions(规避控制面阻塞)。
990
+ * - `'model_changed'` 路径**不写**该字段(只同步 context size),客户端复用上次缓存,下次 prompt_end 全量校准。
963
991
  * - calculator 计算异常时 publisher 也不写该字段(降级),不影响 used/size/cost 推送。
964
992
  */
965
- export type AcpUsageUpdateSource = 'new_session' | 'load_session' | 'resume_session' | 'prompt_end' | 'model_changed' | 'cancel' | 'stream';
993
+ export type AcpUsageUpdateSource = 'new_session' | 'load_session' | 'resume_session' | 'prompt_start' | 'prompt_end' | 'compacted' | 'model_changed' | 'cancel' | 'stream';
966
994
  /**
967
995
  * 附带 `usageByCategory` 语义快照的推送来源(排除语义见上方
968
996
  * `AcpUsageUpdateSource` 注释)。publisher 与其 spec 共用此唯一事实源;
@@ -1007,7 +1035,7 @@ export interface AcpUsagePublisher {
1007
1035
  * 方案 Z(终版决议,2026-05-20):移除 options.hintUsed 参数 —— compact 完成路径不
1008
1036
  * 再主动推送,由下次 prompt 走 combineSubject(input) 自然回填真实 inputTokens。
1009
1037
  */
1010
- publish(sessionId: string, source: AcpUsageUpdateSource, carrier?: W3CTraceContextMeta): Promise<void>;
1038
+ publish(sessionId: string, source: AcpUsageUpdateSource, carrier?: W3CTraceContextMeta, pendingInputText?: string): Promise<void>;
1011
1039
  /**
1012
1040
  * 推送生成工具实际消耗。调用方只提供工具执行事实,publisher 统一复用
1013
1041
  * ACP usage_update.cost.amount 链路,并在内部做 session / stageId 幂等。
@@ -40,6 +40,27 @@ export interface UsageByCategoryInput {
40
40
  /** ACP usage_update.used,作为最终归一化的总分母。 */
41
41
  totalTokens: number;
42
42
  }
43
+ export declare const IMAGE_TOKEN_PER_PIECE = 85;
43
44
  export declare class UsageByCategoryCalculator {
44
45
  static compute(input: UsageByCategoryInput): UsageByCategory;
45
46
  }
47
+ export declare function zeroUsageByCategory(): UsageByCategory;
48
+ /**
49
+ * 单条 history item 对 systemPrompt / conversation / 图片张数的字符贡献。
50
+ *
51
+ * SSOT:全量 `compute` 与增量 publisher 共用本函数,保证「进行中增量」与
52
+ * 「prompt_end 全量」的类目结果严格一致(`weighted` 逐字符可加,item 边界不切
53
+ * 代理对,故 `weighted(Σparts) === Σ weighted(part)`)。
54
+ *
55
+ * - systemPrompt 贡献:仅 user message 的 hidden context block 第一个子 section
56
+ * (UserInfoSection 等价物);解析失败/无 hidden block 时为空,整条 user 文本
57
+ * 由 conversation 承接。
58
+ * - conversation 贡献:user/assistant 文本(user 去掉第一个 hidden section)
59
+ * + function_call 的 JSON.stringify + function_call_result 的 output 文本。
60
+ * - 图片不计字符权重,按张数单独累加(由调用方 ×IMAGE_TOKEN_PER_PIECE)。
61
+ */
62
+ export declare function collectHistoryItemChars(item: unknown): {
63
+ systemPromptChars: string;
64
+ conversationChars: string;
65
+ imagePieces: number;
66
+ };
@@ -270,6 +270,20 @@ export interface ResultUsageExtension {
270
270
  modelUsage?: Record<string, ModelUsage>;
271
271
  _meta?: Record<string, unknown>;
272
272
  }
273
+ /**
274
+ * 这一轮为什么结束,取值对齐 Claude Code 的 `terminal_reason`。
275
+ *
276
+ * 目前只在被取消的一轮上给出:
277
+ * - `aborted_streaming`:中止时没有未完成的工具调用(停在模型输出上);
278
+ * - `aborted_tools`:中止时还有工具调用没执行完。
279
+ *
280
+ * 取消不是错误,所以取消的终态是 `subtype=success`、`is_error=false`,
281
+ * 消费方要靠这个字段把它与正常完成区分开,不要去匹配任何文案。
282
+ */
283
+ export type TerminalReason = 'aborted_streaming' | 'aborted_tools';
284
+ export interface ResultTerminalExtension {
285
+ terminal_reason?: TerminalReason;
286
+ }
273
287
  /** Mirrors the Claude Agent SDK's SDKPermissionDenial (E20 alignment gate). */
274
288
  export interface PermissionDenial {
275
289
  tool_name: string;
@@ -441,7 +455,7 @@ export type ResultMessage = ({
441
455
  category?: string;
442
456
  details?: string;
443
457
  } | null>;
444
- }) & ResultUsageExtension;
458
+ }) & ResultUsageExtension & ResultTerminalExtension;
445
459
  type ApiKeySource = string;
446
460
  export interface SystemMessage {
447
461
  type: 'system';
@@ -38,6 +38,9 @@ export interface FileSystem {
38
38
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
39
39
  exists(path: string): Promise<boolean>;
40
40
  stat(path: string): Promise<FileSystemStat>;
41
+ /** Optional metadata for filesystems that can identify linked paths. */
42
+ lstat?(path: string): Promise<FileSystemStat>;
43
+ realpath?(path: string): Promise<string>;
41
44
  mkdir(path: string, options?: {
42
45
  recursive?: boolean;
43
46
  }): Promise<void>;
@@ -82,6 +85,8 @@ export interface DataFs {
82
85
  withFileTypes: true;
83
86
  }): Promise<DataFsDirent[]>;
84
87
  stat(path: string): Promise<DataFsStats>;
88
+ lstat?(path: string): Promise<DataFsStats>;
89
+ realpath?(path: string): Promise<string>;
85
90
  rm(path: string, options?: {
86
91
  recursive?: boolean;
87
92
  force?: boolean;
@@ -141,7 +146,14 @@ export interface ScannedFile {
141
146
  fileName: string;
142
147
  relativePath: string;
143
148
  }
144
- export declare function scanFilesByExtension(baseDir: string, extension: string, maxDepth?: number): Promise<ScannedFile[]>;
149
+ export interface ScanFilesOptions {
150
+ maxEntries?: number;
151
+ onError?: (error: Error, path: string) => void;
152
+ signal?: AbortSignal;
153
+ /** Filesystems with link metadata can supply realpath for cycle and alias detection. */
154
+ canonicalizeDirectory?: (path: string) => Promise<string>;
155
+ }
156
+ export declare function scanFilesByExtension(baseDir: string, extension: string, maxDepth?: number, options?: ScanFilesOptions): Promise<ScannedFile[]>;
145
157
  /**
146
158
  * Wrap a config-face filesystem into the node:fs/promises-shaped provider:
147
159
  * Stats/Dirent booleans become methods, Uint8Array becomes Buffer, errno
@@ -2,6 +2,7 @@
2
2
  * Hook mechanism protocol definitions
3
3
  * Compatible with Claude Code hooks specification
4
4
  */
5
+ import type { HookInput } from '../../vendor/cbc-core/node/index.js';
5
6
  import { HookEvent, type HookExecutionOptions, type HookExecutionResult, type PromptHookResult } from '../../vendor/cbc-shared/node/index.js';
6
7
  export { HookBlockedError, HookEvent, NotificationType } from '../../vendor/cbc-shared/node/index.js';
7
8
  export type { BackgroundTaskInfo, CronTaskInfo, FinalStopReason, HookBlockingDetail, HookExecutionOptions, HookExecutionResult, HookOutput, HookPermissionMode, PromptHookResult, SessionEndReason, SessionStartSource, } from '../../vendor/cbc-shared/node/index.js';
@@ -240,8 +241,7 @@ export type HookDefinition = CommandHookDefinition | PromptHookDefinition | Agen
240
241
  * Input data passed to hook script via stdin
241
242
  * Format matches Claude Code hooks specification exactly
242
243
  */
243
- export type { HookInput } from "../../vendor/cbc-core/node/index.js";
244
- import type { HookInput } from "../../vendor/cbc-core/node/index.js";
244
+ export type { HookInput } from '../../vendor/cbc-core/node/index.js';
245
245
  /**
246
246
  * Hook Manager interface
247
247
  */
@@ -1,4 +1,9 @@
1
+ import { Session } from '../../vendor/cbc-core/node/index.js';
1
2
  import type { QueryInput, QueryOptions, QueryTicket, ReloadOptions, RewindOptions, RewindResult, SessionEventListener, SessionSubscription, SteerOptions, SteerResult } from './types';
3
+ interface SettleOutcome {
4
+ assistantText: string;
5
+ completedError?: unknown;
6
+ }
2
7
  /**
3
8
  * Submit input or a maintenance operation: creates the session on first touch, resumes it
4
9
  * otherwise. The ticket carries the run id synchronously — it is the kernel
@@ -9,6 +14,24 @@ export declare function query(sessionId: string, input: QueryInput, options?: Qu
9
14
  export declare function reload(sessionId: string, options?: ReloadOptions): void;
10
15
  /** Add input to an existing query. Rejection never creates or activates a session. */
11
16
  export declare function steer(sessionId: string, input: string | unknown[], options: SteerOptions): Promise<SteerResult>;
17
+ /**
18
+ * Settlement discipline (ordered signal): the primary lane subscribes to the
19
+ * kernel's combine result/interrupt_result events, emitted only AFTER the
20
+ * run's bookkeeping (error item into history, Stop hooks); retried failures
21
+ * are suppressed and the recovery run emits its own (#64101, same gate
22
+ * discipline as stream-json-view). Each result is judged by its stamped
23
+ * interceptorGate — willRetry (and not __cancelNudge) means not terminal.
24
+ * interrupt_result settles immediately without awaiting `completed` (it may
25
+ * never resolve on that path). The completed-promise loop remains as a raced,
26
+ * stale-aware fallback with a grace window for terminal or pre-dispatch
27
+ * failures. A gate that promises continuation must instead await an actual
28
+ * result or ordered interrupt; a pending permission is not a timeout failure.
29
+ * Never pump the item stream here; the kernel's per-session subscription is
30
+ * its consumer.
31
+ */
32
+ export declare function beginSettle(session: Session, isInterrupted: () => boolean): {
33
+ wait(): Promise<SettleOutcome>;
34
+ };
12
35
  /**
13
36
  * Turn-level cancellation: the in-flight ticket resolves normally with
14
37
  * stopReason 'aborted', never rejects. Resolves after the run state settles.
@@ -35,3 +58,4 @@ export declare function close(sessionId: string): Promise<void>;
35
58
  * Does not emit a query lifecycle or discard existing subscriptions.
36
59
  */
37
60
  export declare function rewind(sessionId: string, options: RewindOptions): Promise<RewindResult>;
61
+ export {};
@@ -159,6 +159,12 @@ export interface QueryOptions {
159
159
  multitask?: boolean;
160
160
  /** Enable the host's local sandbox. Changes apply when the session has no background work. */
161
161
  sandboxEnabled?: boolean;
162
+ /**
163
+ * Request a PTY for Bash executions, or false for separate stdout/stderr pipes.
164
+ * Omitted preserves the session's current selection and existing CLI defaults.
165
+ * Execution drivers may require pipes; this does not change sandbox permissions.
166
+ */
167
+ usePty?: boolean;
162
168
  /**
163
169
  * 会话级自定义 agent 定义(#108461 D6,形态对齐 stream-json `initialize.agents`
164
170
  * / SDK `--agents`):名字 → 定义(`prompt`/`description`/`tools`/`model`/
@@ -92,6 +92,7 @@ export declare const ENV_KEY_CODEBUDDY_IMAGE_TO_VIDEO_MODEL = "CODEBUDDY_IMAGE_T
92
92
  export declare const ENV_KEY_CODEBUDDY_IMAGE_GEN_ENABLED = "CODEBUDDY_IMAGE_GEN_ENABLED";
93
93
  export declare const ENV_KEY_CODEBUDDY_IMAGE_EDIT_ENABLED = "CODEBUDDY_IMAGE_EDIT_ENABLED";
94
94
  export declare const ENV_KEY_CODEBUDDY_VIDEO_GEN_ENABLED = "CODEBUDDY_VIDEO_GEN_ENABLED";
95
+ export declare const ENV_KEY_CODEBUDDY_AUDIO_TRANSCRIBE_ENABLED = "CODEBUDDY_AUDIO_TRANSCRIBE_ENABLED";
95
96
  export declare const ENV_KEY_CODEBUDDY_HIGH_CREDIT_APPROVAL_ENABLED = "CODEBUDDY_HIGH_CREDIT_APPROVAL_ENABLED";
96
97
  export declare const ENV_KEY_CODEBUDDY_ARTIFACT_ENABLED = "CODEBUDDY_ARTIFACT_ENABLED";
97
98
  /** @deprecated 兼容保留,请改用 CODEBUDDY_ARTIFACT_ENABLED(新名优先,旧名兜底)。 */
@@ -413,6 +414,8 @@ export interface CodebuddySettings {
413
414
  agentHome?: {
414
415
  enabled?: boolean;
415
416
  orchestration?: boolean;
417
+ /** 自动投递到主 Agent 的任务完成回执。默认 all。 */
418
+ taskReceipts?: 'all' | 'batch' | 'off';
416
419
  };
417
420
  /**
418
421
  * Web 输入框在 agent 忙碌时的发送方式(仅 agent-cli Web;不进 WorkBuddy overlay)。
@@ -643,6 +646,8 @@ export interface Hooks {
643
646
  CwdChanged?: HookConfig[];
644
647
  /** Internal-only hooks triggered when agent truly stops */
645
648
  FinalStop?: HookConfig[];
649
+ /** Hooks triggered when a user-typed command/skill expands into a prompt (matcher on command_name) */
650
+ UserPromptExpansion?: HookConfig[];
646
651
  }
647
652
  export interface StatusLine {
648
653
  /** 类型 */
@@ -32,7 +32,7 @@ export declare const MIN_SKILL_DESC_LENGTH = 20;
32
32
  * by skill name — without changing the global default, by exporting this env.
33
33
  *
34
34
  * Format: a JSON object mapping skill name → maxChars, e.g.
35
- * `{"tencent-docs-routing":300,"tencent-pptx":300}`
35
+ * `{"workbuddy-office-routing":300,"tencent-pptx":300}`
36
36
  * The value is the per-entry cap that fully replaces the default for the named skill.
37
37
  * Explicitly overridden skills are also excluded from the later total-budget redistribution,
38
38
  * so an updated bundled skill keeps the same host-selected limit when its source becomes plugin.
@@ -47,7 +47,7 @@ export declare const SKILL_DESC_MAX_OVERRIDES_ENV = "CODEBUDDY_SKILL_DESC_MAX_OV
47
47
  /**
48
48
  * Parse the {@link SKILL_DESC_MAX_OVERRIDES_ENV} raw value into a `skillName → maxChars` map.
49
49
  *
50
- * - Expects a JSON object literal, e.g. `{"tencent-docs-routing":300}`.
50
+ * - Expects a JSON object literal, e.g. `{"workbuddy-office-routing":300}`.
51
51
  * - Returns an empty map for empty/undefined input, malformed JSON, or a non-object
52
52
  * (array / string / number / null) top-level value — the caller decides whether to warn.
53
53
  * - Skips any entry with an empty (post-trim) key, a value that is not a positive integer,
@@ -494,6 +494,7 @@ export interface ToolHookManager {
494
494
  modifiedInput?: Record<string, any>;
495
495
  message?: string;
496
496
  permissionDecision?: 'allow' | 'deny' | 'ask';
497
+ preventContinuation?: boolean;
497
498
  }>;
498
499
  /**
499
500
  * Execute PostToolUse hooks after a tool completes successfully
@@ -801,6 +802,8 @@ export interface ImageGenerationResult extends GenerationCreditResult {
801
802
  }
802
803
  export interface VideoGenerationResult extends GenerationCreditResult {
803
804
  localPaths: string[];
805
+ /** 端上为适配模型能力做出的调整说明(如分辨率回落),供模型与用户知情 */
806
+ warnings?: string[];
804
807
  }
805
808
  /**
806
809
  * 图片生成结果
@@ -871,6 +874,7 @@ export interface VideoGenParams {
871
874
  image?: string;
872
875
  last_image?: string;
873
876
  resolution?: '480P' | '720P' | '1080P';
877
+ seconds?: number;
874
878
  aspect_ratio?: '16:9' | '9:16' | '1:1';
875
879
  negative_prompt?: string;
876
880
  enable_audio?: boolean;
@@ -920,3 +924,109 @@ export interface VideoService {
920
924
  /** 解析视频模型:session > env > settings > tag > fallback */
921
925
  resolveModel(session: Session | undefined, tag: string): Promise<string>;
922
926
  }
927
+ export declare const AudioTranscribeService: unique symbol;
928
+ /**
929
+ * 录音文件识别(长音频转文本)请求参数。
930
+ * `channel_num:1` 由 service 固定注入,不暴露给调用方。
931
+ */
932
+ export interface AudioTranscribeOptions {
933
+ /** 说话人分离:0 关闭(默认)/ 1 开启(需 channel_num=1) */
934
+ speaker_diarization?: 0 | 1;
935
+ /** 临时热词表 "词|权重,..."(最多 128) */
936
+ hotword_list?: string;
937
+ /** 阿拉伯数字智能转换:0 / 1 / 3 */
938
+ convert_num_mode?: 0 | 1 | 3;
939
+ /** 脏词过滤:0 / 1 / 2 */
940
+ filter_dirty?: 0 | 1 | 2;
941
+ /** 标点过滤:0 / 1 / 2 */
942
+ filter_punc?: 0 | 1 | 2;
943
+ /** 语气词过滤:0 / 1 / 2 */
944
+ filter_modal?: 0 | 1 | 2;
945
+ /** 上游附加参数(合法 JSON 字符串),如 '{"Domain":3}' */
946
+ extra?: string;
947
+ }
948
+ /** service 内部解析出的音频来源(COS-only:始终为 audio_url)。 */
949
+ export interface AudioSource {
950
+ audio_url: string;
951
+ }
952
+ /** 后端预签名返回项(`support:getPresignedUrls` 契约)。 */
953
+ export interface AsrPresignItem {
954
+ object_key: string;
955
+ upload_url: string;
956
+ download_url: string;
957
+ }
958
+ /** 预签名接口响应信封。 */
959
+ export interface AsrPresignApiResponse {
960
+ code: number;
961
+ msg?: string;
962
+ message?: string;
963
+ requestId?: string;
964
+ data?: {
965
+ expire?: number;
966
+ items?: AsrPresignItem[];
967
+ };
968
+ }
969
+ /** 提交任务响应信封(/v2/async/tasks/create)。 */
970
+ export interface AsrCreateApiResponse {
971
+ code: number;
972
+ msg: string;
973
+ requestId: string;
974
+ data?: {
975
+ task_id?: string;
976
+ scene?: string;
977
+ status?: string;
978
+ created_at?: string;
979
+ };
980
+ }
981
+ /** 查询任务响应信封(/v2/async/tasks/query)。 */
982
+ export interface AsrQueryApiResponse {
983
+ code: number;
984
+ msg: string;
985
+ requestId: string;
986
+ data?: {
987
+ task_id?: string;
988
+ scene?: string;
989
+ status?: 'queued' | 'in_progress' | 'completed' | 'failed';
990
+ created_at?: string;
991
+ completed_at?: string;
992
+ usage?: {
993
+ credit?: number;
994
+ coefficient?: number;
995
+ meters?: {
996
+ audio_second?: number;
997
+ };
998
+ };
999
+ attributes?: {
1000
+ engine?: string;
1001
+ vendor_status?: string;
1002
+ };
1003
+ error?: {
1004
+ code?: string;
1005
+ message?: string;
1006
+ };
1007
+ audio_transcription?: {
1008
+ text?: string;
1009
+ };
1010
+ };
1011
+ }
1012
+ /** 录音文件识别结果。 */
1013
+ export interface AudioTranscribeResult {
1014
+ /** 完整转写文本(上游 Result 原样透传) */
1015
+ text: string;
1016
+ /** 任务 ID */
1017
+ taskId: string;
1018
+ /** 实际音频时长(秒),计费依据 */
1019
+ audioSecond?: number;
1020
+ /** 最终积分消耗 */
1021
+ credit?: number;
1022
+ }
1023
+ /**
1024
+ * 录音文件识别服务接口。
1025
+ * COS-only:本地文件先经后端预签名上传 COS,再以 audio_url 提交异步转写并轮询。
1026
+ */
1027
+ export interface AudioTranscribeService {
1028
+ /**
1029
+ * 转写本地音频文件:预签名上传 → 提交任务 → 轮询直至终态。
1030
+ */
1031
+ transcribe(filePath: string, options: AudioTranscribeOptions, context: RunContext<Session>): Promise<AudioTranscribeResult>;
1032
+ }
@@ -179,6 +179,12 @@ export declare function isBuiltinDisableableAgent(agentName: string): boolean;
179
179
  * waste prompt tokens on a tool they can never legitimately call (the SendMessage
180
180
  * tool itself returns an error when invoked outside a team context), and for
181
181
  * structured-output agents like `compact` it can pollute the model's output.
182
+ *
183
+ * **这些名字是保留字,不得被用作子代理 / teammate 预设名**(评审 #128343):
184
+ * `resolveMessageSpeakerLabel` 把本名单的判定放在「子会话报自身身份」**之前**,因为历史与
185
+ * 用量多处按 `providerData.agent === 'compact'` 这类字符串比较判定,子会话里跑 compact 时
186
+ * 不能被身份名覆盖。反过来说,一旦有真实子代理取了这里的名字,它的消息会被标成生成器名
187
+ * 而不是自己的身份 —— 属于要靠人眼才能发现的错标。新增名字前先确认它不会与任何预设名撞。
182
188
  */
183
189
  export declare const INTERNAL_GENERATOR_AGENTS: Set<string>;
184
190
  /**
@@ -289,6 +295,13 @@ export interface AgentManager {
289
295
  * 同输入逐轮返回同一对象(prompt cache 稳定);视图字节永不写回全局物化面。
290
296
  */
291
297
  sessionScopedAgentView(session: Session, base: Agent): Promise<Agent>;
298
+ /**
299
+ * sandbox-agent-view:把 REPL 的动态 schema 按子代理身份重新物化一遍。Code Mode 的
300
+ * agent 实例进程级共享(`get('ptc')` 命中同一对象),schema 在构建期用合成会话采集 ——
301
+ * 继承模式的子代理(Explore 等)会看到模式的全量目录。派发侧知道身份,经此覆盖。
302
+ * 只克隆 REPL 一个工具,视图不进 agentMap;空身份 / 同名 / 无 REPL 时原样返回基座。
303
+ */
304
+ sandboxScopedAgentView(base: Agent, sandboxAgentName: string): Promise<Agent>;
292
305
  /** served 激活链的视图预热(默认 agent),派发路径是失效兜底。 */
293
306
  prepareSessionAgentView(session: Session): Promise<void>;
294
307
  get(agentName: string): Promise<Agent | undefined>;
@@ -543,6 +556,16 @@ export type AgentStandardRunOptions<TContext = Session> = AgentSdkRunOptions<TCo
543
556
  /** Process-local provenance for fresh user turns; stripped before SDK dispatch. */
544
557
  inputOrigin?: AgentRunOrigin;
545
558
  continuation?: never;
559
+ /**
560
+ * Per-arrival out-signal: invoked when this run was routed to the message
561
+ * queue (skipRun, session busy) instead of executing now. Callers that owe
562
+ * their caller *this* prompt's own result (print / stream-json) use it to
563
+ * keep waiting until the queue drains and their turn actually runs.
564
+ *
565
+ * A run-scoped callback (not a shared session flag) so concurrent arrivals
566
+ * cannot clobber each other's outcome.
567
+ */
568
+ onEnqueued?: () => void;
546
569
  };
547
570
  /**
548
571
  * Explicitly claim the current process-local logical turn.
@@ -558,6 +581,10 @@ export type AgentCurrentContinuationOptions = AgentSdkRunOptions<Session> & Agen
558
581
  };
559
582
  export type AgentServiceRunOptions<TContext = Session> = AgentStandardRunOptions<TContext> | AgentCurrentContinuationOptions;
560
583
  export interface AgentService {
584
+ /** Atomically close a task's runtime only after its last result and queued work settle. */
585
+ tryCloseTaskSession?(session: Session, result: NonNullable<Session['resultSubject']['value']>): Promise<boolean>;
586
+ /** Stop accepting task work and join its physical runs before releasing dependencies. */
587
+ retireTaskSession?(session: Session): Promise<void>;
561
588
  run<TAgent extends Agent<any, any>>(agent: TAgent, input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
562
589
  run<TAgent extends Agent<any, any>, TContext = Session>(agent: TAgent, input: string | AgentInputItem[] | RunState<TContext, TAgent>, options?: AgentStandardRunOptions<TContext>): Promise<void>;
563
590
  runDefault<TAgent extends Agent<any, any>>(input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
@@ -779,6 +806,8 @@ export declare enum CustomAgentSavePath {
779
806
  }
780
807
  export declare enum OutputStyleType {
781
808
  DEFAULT = "default",
809
+ PROACTIVE = "proactive",
810
+ CONCISE = "concise",
782
811
  EXPLANATORY = "explanatory",
783
812
  LEARNING = "learning"
784
813
  }
@@ -38,6 +38,8 @@ export declare class AgentServiceImpl implements AgentService {
38
38
  */
39
39
  private lifecycleOwners;
40
40
  protected getLifecycleOwners(): WeakMap<Session, AbortController>;
41
+ tryCloseTaskSession(session: Session, result: NonNullable<Session['resultSubject']['value']>): Promise<boolean>;
42
+ retireTaskSession(session: Session): Promise<void>;
41
43
  /** compare-and-delete:仅当 token 仍指向本轮 controller 时清除。 */
42
44
  private clearLifecycleOwner;
43
45
  /** 本轮是否是当前 lifecycle owner。 */
@@ -6,6 +6,7 @@ export * from './agent-service';
6
6
  export * from './agent-factory';
7
7
  export * from './runner-factory';
8
8
  export * from './runner-provider';
9
+ export * from './speaker-label';
9
10
  export * from './ordered-tools-agent';
10
11
  export * from './tool-call-loop-detector-protocol';
11
12
  export * from './tool-call-loop-detector-service';
@@ -17,12 +17,7 @@ export declare class MessageQueueAgentRunInterceptor implements AgentRunIntercep
17
17
  protected readonly logger: Logger;
18
18
  protected readonly stateMachine: SessionRunStateMachine;
19
19
  intercept(request: AgentRunRequest): Promise<void>;
20
- /**
21
- * 触发后不再重复打 error(防日志风暴);下次"有实际工作"分支复位 counter/flag,
22
- * session 自动恢复处理能力。
23
- */
24
- private trackEmptyDrainAndMaybeTripGuard;
25
- private resetEmptyDrainLoopGuard;
20
+ private consumeQueueItems;
26
21
  }
27
22
  /**
28
23
  * 用户查询包裹拦截器
@@ -1,4 +1,4 @@
1
- import { type RunConfig, Runner } from '../../../cbc-shared/node/index.js';
1
+ import { type AgentInputItem, type RunConfig, Runner } from '../../../cbc-shared/node/index.js';
2
2
  import { ProductManager } from '../../../../workspace/product/lib/common/index.js';
3
3
  import { Logger } from '../../../../workspace/telemetry/lib/common/index.js';
4
4
  import { type NotificationInjectionBuffer as INotificationInjectionBuffer } from '../message-queue/notification-injection-buffer-protocol';
@@ -15,6 +15,15 @@ import { ToolCallLoopDetector } from './tool-call-loop-detector-protocol';
15
15
  * Used by finishReasonErrorInterceptor to detect prior retries across both mechanisms.
16
16
  */
17
17
  export declare const TRUNCATION_RETRY_MARKER = "Do NOT repeat the same oversized tool call. Break it into smaller operations.";
18
+ export interface ModelInputMemoryPressure {
19
+ heapUsed: number;
20
+ heapLimit: number;
21
+ headroom: number;
22
+ inputItems: number;
23
+ estimatedInputBytes?: number;
24
+ reject: boolean;
25
+ }
26
+ export declare function assessModelInputMemoryPressure(input: AgentInputItem[], heapUsed?: number, heapLimit?: number): ModelInputMemoryPressure;
18
27
  /**
19
28
  * Tool-specific hints for how to decompose a truncated tool call into smaller operations.
20
29
  */
@@ -72,6 +81,7 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
72
81
  */
73
82
  protected readonly acpBroadcastService?: AgentQueueOutput;
74
83
  create(config?: Partial<RunConfig>): Promise<Runner>;
84
+ private assertModelInputCloneHeadroom;
75
85
  /**
76
86
  * 在每次模型请求前检查是否需要自动压缩。
77
87
  * 此时所有工具都已执行完毕,可以安全地触发压缩。
@@ -211,10 +221,10 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
211
221
  * model / agent / argumentsDisplayText 等键同样会跟着走,它们是惰性字段、上游不解读,
212
222
  * 这里不做处理;真正需要清掉的只有语义已经反转的 discard。
213
223
  *
214
- * 改写与删标记都只作用于当轮副本(见 filterTruncatedToolCalls 的
215
- * "Scope of the rewrite"),session.history 里的原值保持不变。
224
+ * 返回一个浅复制的新 item;providerData 仅在需要删除 discard 时 copy-on-write。
225
+ * session.history 与 SDK 传入的原 item 始终保持不变。
216
226
  */
217
- private rewriteCallArguments;
227
+ private withRewrittenCallArguments;
218
228
  /**
219
229
  * SDK callModelInputFilter: called before every model API request within the SDK run loop.
220
230
  *
@@ -240,13 +250,23 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
240
250
  * message instructing the model to break the call into smaller operations. This
241
251
  * turns the SDK's automatic retry into a valid, useful request.
242
252
  *
243
- * Scope of the rewrite: `agents-core`'s `applyCallModelInputFilter` hands us a
244
- * `structuredClone` of the turn input and clones our return value again, explicitly so
245
- * that filter-side mutations cannot touch cached turn state. So every rewrite here
246
- * lands on a per-turn copy only — `session.history` keeps the malformed arguments and
247
- * we redo the same rewrite on every subsequent turn. That is correct but not free:
248
- * anything reported from this path must be aggregated per turn rather than logged per
249
- * call, or a long session with N bad calls emits N log lines every turn.
253
+ * Scope of the rewrite: this filter opts into the SDK's `preserveInputIdentity` mode,
254
+ * so existing history items arrive by identity and MUST remain immutable. Repairs use
255
+ * item-level copy-on-write and array-level shallow copies; the SDK still creates isolated
256
+ * model/session copies after the filter returns. `session.history` therefore keeps the
257
+ * malformed arguments and we redo the same rewrite on every subsequent turn. Anything
258
+ * reported from this path must be aggregated per turn rather than logged per call.
259
+ */
260
+ /**
261
+ * 模型输入的两步修复,**顺序不能反**:
262
+ *
263
+ * 1. `filterTruncatedToolCalls` 先跑。截断(finish_reason=length)与坏 JSON 的
264
+ * call 正是「参数半截 + 没有任何 result」那一类;它删掉这些 call 的同时会注入
265
+ * 拆解引导与防循环停止标记。若先按配对摘掉它们,该分支因 `invalidCallIds` 为空
266
+ * 直接早退,模型拿不到任何引导,退回 #75892 那条老路,而且请求本身合法、无错可见。
267
+ * 2. `filterUnpairedToolCalls` 后跑,收掉剩下的孤儿(参数合法但结果丢失、重复 callId、
268
+ * 头部被截断留下的孤儿结果)。本地正文里的孤儿是持久化的,留着每次恢复都被上游 400。
250
269
  */
270
+ private repairModelInput;
251
271
  private filterTruncatedToolCalls;
252
272
  }