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

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 (182) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/cli/CHANGELOG.md +64 -0
  3. package/cli/dist-server/shared.cjs +450 -329
  4. package/cli/dist-server/types/node/acp/acp-protocol.d.ts +8 -0
  5. package/cli/dist-server/types/node/bash-sandbox/bash-sandbox-protocol.d.ts +3 -0
  6. package/cli/dist-server/types/node/cli/cli-protocol.d.ts +3 -0
  7. package/cli/dist-server/types/node/cli/stream-json-protocol.d.ts +8 -1
  8. package/cli/dist-server/types/node/loopback/server-protocol.d.ts +5 -0
  9. package/cli/dist-server/types/node/sensitive-content/sensitive-content-protocol.d.ts +7 -0
  10. package/cli/dist-server/types/node/server/boot.d.ts +7 -4
  11. package/{lib/components → cli/dist-server/types/node/server/formats}/acp/acp-error-model.d.ts +1 -1
  12. package/{lib/components → cli/dist-server/types/node/server/formats}/acp/acp-protocol.d.ts +2 -3
  13. package/cli/dist-server/types/node/server/formats/acp/index.d.ts +12 -0
  14. package/cli/dist-server/types/node/server/formats/acp/projection.d.ts +10 -0
  15. package/cli/dist-server/types/node/server/index.d.ts +1 -1
  16. package/cli/dist-server/types/node/server/sessions.d.ts +3 -2
  17. package/cli/dist-server/types/node/server/types.d.ts +59 -7
  18. package/cli/dist-server/types/node/tools/tool-protocol.d.ts +39 -24
  19. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-protocol.d.ts +31 -2
  20. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-purpose-protocol.d.ts +8 -4
  21. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-purpose-scope.d.ts +46 -0
  22. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-service.d.ts +26 -3
  23. package/cli/dist-server/types/vendor/cbc-core/node/agent/index.d.ts +3 -0
  24. package/cli/dist-server/types/vendor/cbc-core/node/agent/model-call-failure.d.ts +9 -0
  25. package/cli/dist-server/types/vendor/cbc-core/node/agent/model-step-sequence.d.ts +11 -0
  26. package/cli/dist-server/types/vendor/cbc-core/node/agent/runner-factory.d.ts +43 -9
  27. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  28. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-pattern.d.ts +9 -8
  29. package/cli/dist-server/types/vendor/cbc-core/node/context/compaction-lineage.d.ts +39 -0
  30. package/cli/dist-server/types/vendor/cbc-core/node/context/context-compact-summarizer.d.ts +2 -0
  31. package/cli/dist-server/types/vendor/cbc-core/node/context/context-protocol.d.ts +17 -0
  32. package/cli/dist-server/types/vendor/cbc-core/node/context/index.d.ts +2 -0
  33. package/cli/dist-server/types/vendor/cbc-core/node/context/mods-bridge.d.ts +115 -0
  34. package/cli/dist-server/types/vendor/cbc-core/node/context/pre-message-compact-strategy.d.ts +1 -2
  35. package/cli/dist-server/types/vendor/cbc-core/node/message-queue/followup-queue-protocol.d.ts +3 -2
  36. package/cli/dist-server/types/vendor/cbc-core/node/message-queue/followup-queue.d.ts +1 -1
  37. package/cli/dist-server/types/vendor/cbc-core/node/message-queue/steer-input-buffer-protocol.d.ts +4 -0
  38. package/cli/dist-server/types/vendor/cbc-core/node/session/can-use-tool.d.ts +4 -0
  39. package/cli/dist-server/types/vendor/cbc-core/node/session/index.d.ts +1 -0
  40. package/cli/dist-server/types/vendor/cbc-core/node/session/interruption-service.d.ts +8 -0
  41. package/cli/dist-server/types/vendor/cbc-core/node/session/model-request-retry-phase.d.ts +16 -0
  42. package/cli/dist-server/types/vendor/cbc-core/node/session/model-response-interceptors.d.ts +15 -0
  43. package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager-host-protocol.d.ts +3 -2
  44. package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager.d.ts +37 -3
  45. package/cli/dist-server/types/vendor/cbc-core/node/session/session-protocol.d.ts +59 -5
  46. package/cli/dist-server/types/vendor/cbc-core/node/session/session-run-state-machine-protocol.d.ts +14 -1
  47. package/cli/dist-server/types/vendor/cbc-core/node/session/stream-timeout-retry-budget.d.ts +8 -1
  48. package/cli/dist-server/types/vendor/cbc-core/node/trace/turn-context.d.ts +28 -1
  49. package/cli/dist-server/types/vendor/cbc-core/node/utils/command-message-utils.d.ts +20 -0
  50. package/cli/dist-server/types/vendor/cbc-core/node/utils/history-utils.d.ts +4 -4
  51. package/cli/dist-server/types/vendor/cbc-core/node/utils/input-item-utils.d.ts +9 -1
  52. package/cli/dist-server/types/vendor/cbc-core/node/utils/token-utils.d.ts +3 -1
  53. package/cli/dist-server/types/vendor/cbc-shared/node/agent/openai-agents-types.d.ts +1 -0
  54. package/cli/dist-server/types/vendor/cbc-shared/node/checkpoint/checkpoint-types.d.ts +6 -0
  55. package/cli/dist-server/types/vendor/cbc-shared/node/model/model-errors.d.ts +30 -2
  56. package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/index.d.ts +1 -0
  57. package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/prompt-codec.d.ts +4 -0
  58. package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/sandbox-rule-context.d.ts +38 -0
  59. package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/types.d.ts +15 -1
  60. package/cli/dist-server/types/workspace/authentication/lib/common/account-scoped-external-link-authentication-provider.d.ts +3 -3
  61. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-manager.d.ts +6 -0
  62. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-observation.d.ts +36 -0
  63. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-protocol.d.ts +21 -0
  64. package/cli/dist-server/types/workspace/authentication/lib/common/external-link-authentication-provider.d.ts +20 -4
  65. package/cli/dist-server/types/workspace/authentication/lib/common/index.d.ts +1 -0
  66. package/cli/dist-server/types/workspace/cbc-checkpoint/lib/node/checkpoint/checkpoint-protocol.d.ts +2 -0
  67. package/cli/dist-server/types/workspace/cbc-checkpoint/lib/node/checkpoint/checkpoint-service.d.ts +1 -0
  68. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-protocol.d.ts +31 -2
  69. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-purpose-protocol.d.ts +8 -4
  70. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-purpose-scope.d.ts +46 -0
  71. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-service.d.ts +26 -3
  72. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/index.d.ts +3 -0
  73. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/model-call-failure.d.ts +9 -0
  74. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/model-step-sequence.d.ts +11 -0
  75. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/runner-factory.d.ts +43 -9
  76. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  77. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-pattern.d.ts +9 -8
  78. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/compaction-lineage.d.ts +39 -0
  79. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/context-compact-summarizer.d.ts +2 -0
  80. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/context-protocol.d.ts +17 -0
  81. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/index.d.ts +2 -0
  82. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/mods-bridge.d.ts +115 -0
  83. package/cli/dist-server/types/workspace/cbc-core/lib/node/context/pre-message-compact-strategy.d.ts +1 -2
  84. package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/followup-queue-protocol.d.ts +3 -2
  85. package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/followup-queue.d.ts +1 -1
  86. package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/steer-input-buffer-protocol.d.ts +4 -0
  87. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/can-use-tool.d.ts +4 -0
  88. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/index.d.ts +1 -0
  89. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/interruption-service.d.ts +8 -0
  90. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/model-request-retry-phase.d.ts +16 -0
  91. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/model-response-interceptors.d.ts +15 -0
  92. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager-host-protocol.d.ts +3 -2
  93. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager.d.ts +37 -3
  94. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-protocol.d.ts +59 -5
  95. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-run-state-machine-protocol.d.ts +14 -1
  96. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/stream-timeout-retry-budget.d.ts +8 -1
  97. package/cli/dist-server/types/workspace/cbc-core/lib/node/trace/turn-context.d.ts +28 -1
  98. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/command-message-utils.d.ts +20 -0
  99. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/history-utils.d.ts +4 -4
  100. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/input-item-utils.d.ts +9 -1
  101. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/token-utils.d.ts +3 -1
  102. package/cli/dist-server/types/workspace/cbc-shared/lib/node/agent/openai-agents-types.d.ts +1 -0
  103. package/cli/dist-server/types/workspace/cbc-shared/lib/node/checkpoint/checkpoint-types.d.ts +6 -0
  104. package/cli/dist-server/types/workspace/cbc-shared/lib/node/model/model-errors.d.ts +30 -2
  105. package/cli/dist-server/types/workspace/cbc-worktree/lib/node/worktree/worktree-service.d.ts +5 -0
  106. package/cli/dist-server/types/workspace/core/lib/common/protocol.d.ts +8 -1
  107. package/cli/dist-server/types/workspace/product/lib/common/index.d.ts +1 -0
  108. package/cli/dist-server/types/workspace/product/lib/common/tencent-docs-endpoint.d.ts +37 -0
  109. package/cli/dist-server/types/workspace/product/lib/common/types/config.d.ts +12 -0
  110. package/cli/dist-server/types/workspace/product/lib/common/types/features.d.ts +17 -9
  111. package/cli/dist-server/types/workspace/product/lib/common/types/product.d.ts +15 -0
  112. package/cli/dist-server/types/workspace/prompts/lib/common/product-prompt-provider.d.ts +3 -1
  113. package/cli/dist-server/types/workspace/prompts/lib/common/prompt-protocol.d.ts +6 -0
  114. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/center-protocol.generated.d.ts +5 -0
  115. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/file-policy.d.ts +4 -1
  116. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/http-policy.d.ts +20 -0
  117. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/rule-config.d.ts +10 -0
  118. package/cli/dist-server/types/workspace/sandbox-cli/lib/node/sandbox-center-client.d.ts +3 -0
  119. package/cli/dist-server/types/workspace/telemetry/lib/common/event/types/craft.d.ts +43 -3
  120. package/cli/package.json +1 -1
  121. package/cli/product.cloudhosted.json +1 -803
  122. package/cli/product.internal.json +1 -1057
  123. package/cli/product.ioa.json +1 -1515
  124. package/cli/product.json +1 -2189
  125. package/cli/product.selfhosted.json +1 -364
  126. package/cli/vendor/shim/brokered-bin/7z +675 -0
  127. package/cli/vendor/shim/brokered-bin/7za +675 -0
  128. package/cli/vendor/shim/brokered-bin/7zz +675 -0
  129. package/cli/vendor/shim/brokered-bin/rar +675 -0
  130. package/cli/vendor/shim/brokered-bin/tar +675 -0
  131. package/cli/vendor/shim/brokered-bin/zip +187 -0
  132. package/docs/acp-v2.md +19 -0
  133. package/docs/client.md +7 -0
  134. package/docs/in-process.md +26 -2
  135. package/docs/product.md +4 -0
  136. package/docs/protocol.md +10 -2
  137. package/docs/server.md +2 -0
  138. package/lib/agent/v2.js +1 -1
  139. package/lib/application/services.js +1 -1
  140. package/lib/auth/module.d.ts +3 -1
  141. package/lib/auth/module.js +1 -1
  142. package/lib/client/client.js +1 -1
  143. package/lib/client/mcp.d.ts +1 -1
  144. package/lib/client/mcp.js +1 -1
  145. package/lib/components/acp-mcp-transport.d.mts +84 -1
  146. package/lib/components/question-elicitation.d.mts +20 -1
  147. package/lib/components/sandbox.d.mts +2 -0
  148. package/lib/components/sandbox.mjs +1 -0
  149. package/lib/components/{acp/acp-prompt-input.d.ts → session/prompt-input.d.ts} +1 -1
  150. package/lib/components/session-replay.d.mts +8 -7
  151. package/lib/components/session-replay.mjs +1 -1
  152. package/lib/effect-runtime/concurrency.d.mts +2 -4
  153. package/lib/effect-runtime/concurrency.mjs +1 -1
  154. package/lib/effect-runtime/mcp-lifecycle.mjs +1 -1
  155. package/lib/effect-runtime/process-runtime-context.d.ts +5 -1
  156. package/lib/harness/create-harness.js +1 -1
  157. package/lib/integration/agent-integration.d.ts +5 -0
  158. package/lib/protocol/acp-v2-credits.d.ts +10 -0
  159. package/lib/protocol/acp-v2-credits.js +1 -0
  160. package/lib/protocol/acp-v2-private-client.d.ts +1 -10
  161. package/lib/runtime/codebuddy-auth.d.ts +5 -3
  162. package/lib/runtime/codebuddy-auth.js +1 -1
  163. package/lib/runtime/private-runtime-role.js +1 -1
  164. package/lib/session/agent-backend.d.ts +3 -0
  165. package/lib/session/agent-backend.js +1 -1
  166. package/lib/session/config-defaults.d.ts +4 -0
  167. package/lib/session/config-defaults.js +1 -0
  168. package/lib/session/config-store.d.ts +1 -1
  169. package/lib/session/config-store.js +1 -1
  170. package/lib/session/replay.d.ts +3 -3
  171. package/lib/session/replay.js +1 -1
  172. package/lib/session/server-config.d.ts +11 -2
  173. package/lib/session/server-config.js +1 -1
  174. package/lib/session/server-events.d.ts +10 -8
  175. package/lib/session/server-events.js +1 -1
  176. package/lib/session/server-interactions.js +1 -1
  177. package/lib/session/server-mcp.js +1 -1
  178. package/lib/subagent/history.js +1 -1
  179. package/package.json +26 -20
  180. package/lib/components/acp/acp-client-channel.d.ts +0 -36
  181. package/lib/components/acp/acp-mcp-transport.d.ts +0 -84
  182. package/lib/components/acp/acp-question-elicitation.d.ts +0 -20
@@ -1,5 +1,5 @@
1
1
  import type { AgentInputItem } from '../../../cbc-shared/node/index.js';
2
- import type { ModelResponseMetadata, Session } from './session-protocol';
2
+ import type { ModelCallGeneration, ModelResponseMetadata, Session } from './session-protocol';
3
3
  export declare const SessionCheckpointHost: unique symbol;
4
4
  export interface SessionCheckpointHost {
5
5
  createCheckpoint(session: Session): Promise<void>;
@@ -57,7 +57,8 @@ export declare const SessionResponseTelemetryHost: unique symbol;
57
57
  export interface SessionResponseTelemetryHost {
58
58
  reportChatRequestResponseTelemetry(session: Session, result: NonNullable<Session['resultSubject']['value']>, isSuccessful: boolean, error: unknown, metadata: ModelResponseMetadata): Promise<void>;
59
59
  reportMessageResponseTelemetryStream(session: Session, usage: SessionResponseUsage | undefined, metadata: ModelResponseMetadata, error: unknown): Promise<void>;
60
- reportChatMessageStatus(session: Session, errorCode: string, error?: unknown): Promise<void>;
60
+ /** Status of one model call (`generation`); run failures no model call owns are not reported. */
61
+ reportChatMessageStatus(session: Session, errorCode: string, generation: ModelCallGeneration, error?: unknown): Promise<void>;
61
62
  }
62
63
  export type SessionResponseTelemetrySnapshot = Pick<NonNullable<Session['telemetry']>, 'modelId' | 'modelName' | 'currentTurn' | 'traceId'>;
63
64
  export declare const SessionResponseObserver: unique symbol;
@@ -4,7 +4,7 @@ import { Logger } from '../../../../workspace/telemetry/lib/common/index.js';
4
4
  import { BehaviorSubject } from 'rxjs';
5
5
  import { SessionRequestContextHost, SessionSettingsHost as SettingsManager, SessionUsageHost as UserStateManager } from './session-host-protocol';
6
6
  import { SessionBackgroundTaskHost as ToolManager, SessionCheckpointHost as CheckpointService, SessionProgressHost as ProgressSyncService, SessionResponseObserver as GalileoSessionBridge, SessionResponseTelemetryHost as TelemetryService, SessionSchedulerHost as CronSchedulerService, SessionSensitiveProjectionHost, SessionTaskLifecycleHost as AgentTaskManager } from './session-manager-host-protocol';
7
- import { AgentInputItemProcessor, InterruptionService, ModelResponseInterceptor, ModelResponseMetadata, Session, SessionFactory, SessionGetOptions, SessionHookManager, SessionManager, SessionStore } from './session-protocol';
7
+ import { AgentInputItemProcessor, InterruptionService, ModelResponseInterceptor, ModelResponseMetadata, OverrideModelSource, Session, SessionFactory, SessionGetOptions, SessionHookManager, SessionManager, SessionStore } from './session-protocol';
8
8
  import { SessionRunStateMachine } from './session-run-state-machine-protocol';
9
9
  export declare class SessionManagerImpl implements SessionManager, ApplicationLifecycle<Application> {
10
10
  protected readonly sessionFactory: SessionFactory;
@@ -32,6 +32,7 @@ export declare class SessionManagerImpl implements SessionManager, ApplicationLi
32
32
  private skipHistoryContext;
33
33
  private sessionStartTimes;
34
34
  private addHistoryLocks;
35
+ private promptAdmissions;
35
36
  private resultSubscriptions;
36
37
  private readonly resultSubscriptionOwners;
37
38
  /**
@@ -44,6 +45,8 @@ export declare class SessionManagerImpl implements SessionManager, ApplicationLi
44
45
  private readonly liveSessionsById;
45
46
  private overridePermissionModes;
46
47
  private overrideModels;
48
+ /** 与 overrideModels 同生命周期的意图来源(user / declared / materialized)。 */
49
+ private overrideModelSources;
47
50
  /**
48
51
  * Issue #12554:会话级 thinking override(按 sessionId 隔离)。
49
52
  * 由 ACP setSessionConfigOption('thought_level') 或 prompt _meta 写入。
@@ -106,6 +109,7 @@ export declare class SessionManagerImpl implements SessionManager, ApplicationLi
106
109
  private readonly loadedSessionIds;
107
110
  private resetIdleTimer;
108
111
  addHistory(session: Session, input: string | AgentInputItem[]): Promise<void>;
112
+ private writeHistory;
109
113
  /**
110
114
  * Record a UserPromptSubmit hook block as an in-band assistant message
111
115
  * (issue #71907, cc-aligned: cc surfaces a warning system message and ends the
@@ -123,6 +127,34 @@ export declare class SessionManagerImpl implements SessionManager, ApplicationLi
123
127
  * (use-message-sender). chalk=false because ACP does not strip ANSI codes.
124
128
  */
125
129
  private recordHookBlockedMessage;
130
+ /**
131
+ * 把一条 mod 打出来的 `$.ui.log` 落到当前 session 的可见消息流里。
132
+ *
133
+ * ## 与 `recordHookBlockedMessage` 的关系
134
+ *
135
+ * 二者走**同一条落地路径**(history + inputSubject + combineSubject +
136
+ * sessionStore.appendHistory),因此 TUI / ACP / persisted transcript 都用
137
+ * 既有渲染,不必新增 sessionUpdate 类型(对齐根 CODEBUDDY.md 的 ACP 约束)。
138
+ *
139
+ * ## 与 hook 阻断消息刻意不同的三点
140
+ *
141
+ * 1. **不动 `session.lastMessageId`**:hook-block 是回合终点,需要挂上 replay
142
+ * 分支;mod-log 是**装饰性**通知,如果推进 lastMessageId 会让 `/rewind`
143
+ * 退到"一条 log 中间",语义混乱。
144
+ * 2. **不挂 `parentId`**:同样出于 replay 分支洁净。
145
+ * 3. **`chalk: false`**:ACP 侧不剥 ANSI,chalk 转义码会露出到 Web UI;此外
146
+ * 宿主已在 `<plugin>: <text>` 里给足了归属信号,terminal 也不再需要额外
147
+ * 颜色包装(TUI 侧后续可按 `hookStatus === 'mod-log'` 做专属渲染)。
148
+ *
149
+ * ## 失败语义
150
+ *
151
+ * 与 hook-block 同款:写盘失败只记日志,不向外抛 —— mod 打日志不该把 CLI 弄挂。
152
+ *
153
+ * @param session 目标 session(宿主取当前 session 后传入)
154
+ * @param text 已由宿主前缀成 `<plugin>: <text>` 的完整行文
155
+ * @param plugin 发起本次调用的 mod 名(`origin.plugin`),用于前端识别
156
+ */
157
+ recordModLogMessage(session: Session, text: string, plugin: string): Promise<void>;
126
158
  private readonly inflightSessionStarts;
127
159
  emitSessionStart(session: Session, source: SessionStartSource): Promise<void>;
128
160
  create(options?: Partial<Session>, needHandleRunResult?: boolean, parentSession?: Session): Promise<Session>;
@@ -190,9 +222,11 @@ export declare class SessionManagerImpl implements SessionManager, ApplicationLi
190
222
  rename(session: Session, name: string): Promise<void>;
191
223
  setOverridePermissionMode(sessionId: string, mode: PermissionMode): void;
192
224
  getOverridePermissionMode(sessionId: string): PermissionMode | undefined;
193
- setOverrideModel(sessionId: string, model: string): void;
225
+ setOverrideModel(sessionId: string, model: string, source?: OverrideModelSource): void;
194
226
  getOverrideModel(sessionId: string): string | undefined;
195
- setRuntimeModel(session: Session | undefined, modelId: string): void;
227
+ getOverrideModelSource(sessionId: string): OverrideModelSource | undefined;
228
+ clearOverrideModel(sessionId: string): void;
229
+ setRuntimeModel(session: Session | undefined, modelId: string, source?: OverrideModelSource): void;
196
230
  setRuntimeOutputStyle(session: Session | undefined, style: string): void;
197
231
  /**
198
232
  * Issue #83229:把 settings.json 中的 model / outputStyle 读一次"钉"进 session.options,
@@ -2,6 +2,7 @@ import { Deferred } from '@celljs/core';
2
2
  import { type AgentInputItem, ApprovalOptions, type Checkpoint, FinalStopReason, NotificationType, PermissionMode, ReasoningEffortLevel, type ResponseStreamEvent, type RunItem, type RunResult, type RunState, type RunToolApprovalItem, type SdkCapabilities, SessionEndReason, SessionStartSource, type StreamedRunResult, type TerminalEvent, type ToolDeferOverlaySnapshot, ToolPermissionContext, type Usage } from '../../../cbc-shared/node/index.js';
3
3
  import { Command } from '../../../../workspace/product/lib/common/index.js';
4
4
  import { BehaviorSubject, Subject } from 'rxjs';
5
+ import type { CompactionLineage } from '../context/compaction-lineage';
5
6
  import { BackgroundTask } from './background-task-protocol';
6
7
  import type { SessionRunStateSnapshot } from './session-run-state-machine-protocol';
7
8
  import type { Lane, LanePointer, SessionKey, SessionStoreEntry } from './session-store-contract';
@@ -86,6 +87,7 @@ export type AgentState = 'agent_pending' | 'agent_start' | 'agent_tool_start' |
86
87
  * 则 emit,触发 UI 显示"正在同步文件"提示)
87
88
  */
88
89
  export type AgentPhase = 'preparing' | 'model_requesting' | 'model_streaming' | 'model_done' | 'tool_executing' | 'waiting_for_permission' | 'waiting_for_user' | 'retrying' | 'finalization_file_projection_sync' | 'finalization_file_projection_sync_notify' | 'idle';
90
+ export type AgentRetryReason = 'network';
89
91
  export interface AgentPhaseInfo {
90
92
  phase: AgentPhase;
91
93
  toolName?: string;
@@ -102,6 +104,13 @@ export interface AgentPhaseInfo {
102
104
  current: number;
103
105
  total: number;
104
106
  };
107
+ /**
108
+ * 仅 retrying phase 使用,经 ACP `_meta['codebuddy.ai/agentPhase']` 透传给上层。
109
+ * 缺省表示原因未分类(如流超时),不代表网络正常。
110
+ */
111
+ retry?: {
112
+ reason: AgentRetryReason;
113
+ };
105
114
  }
106
115
  export declare const AgentPhaseUtils: {
107
116
  /** Create an AgentPhaseInfo with the current timestamp. */
@@ -353,6 +362,14 @@ export interface Session {
353
362
  * field and pass it through as `options.maxTurns` explicitly.
354
363
  */
355
364
  lastRunMaxTurns?: number;
365
+ /**
366
+ * Latest agent-loop model call number (`providerData.stepSeq`). Unlike the
367
+ * SDK turn counter it survives runs, compaction and resume; see
368
+ * `allocateModelStepSeq`.
369
+ */
370
+ modelStepSeq?: number;
371
+ /** Compactions of this Session's context; see `getCompactionLineage`. */
372
+ compactionLineage?: CompactionLineage;
356
373
  queue: AgentInputItem[];
357
374
  queueSubject: BehaviorSubject<AgentInputItem[]>;
358
375
  /**
@@ -860,7 +877,7 @@ export interface SubagentInvocationRecord {
860
877
  lifecycle: SubagentLifecycleSnapshot;
861
878
  }
862
879
  export type SubagentLifecycleDescriptor = Omit<SubagentLifecycleSnapshot, 'status' | 'updatedAt' | 'usage'>;
863
- export type CombineEvent = (AgentInputItemEvent | ModelRawResponseEvent | ResultEndEvent | InterruptResultEvent | NoticeEvent | SubagentStatusEvent | CompactionLifecycleEvent | TerminalEvent) & CombineEventMeta;
880
+ export type CombineEvent = (AgentInputItemEvent | AgentSdkStreamEvent | ModelRawResponseEvent | ResultEndEvent | InterruptResultEvent | NoticeEvent | SubagentStatusEvent | CompactionLifecycleEvent | TerminalEvent) & CombineEventMeta;
864
881
  export interface CompactionLifecycleEvent {
865
882
  type: 'compaction';
866
883
  data: {
@@ -875,6 +892,11 @@ export interface SubagentStatusEvent {
875
892
  type: 'subagent_status';
876
893
  data: SubagentLifecycleSnapshot;
877
894
  }
895
+ /** Original SDK stream payload, observed by the existing single stream consumer. */
896
+ export interface AgentSdkStreamEvent {
897
+ type: 'sdk';
898
+ data: import('../../../cbc-shared/node/index.js').RunStreamEvent;
899
+ }
878
900
  export interface AgentInputItemEvent {
879
901
  type: 'input';
880
902
  data: AgentInputItem;
@@ -1063,6 +1085,13 @@ export interface SessionRewindMutationOptions {
1063
1085
  cwd: string;
1064
1086
  headMessageId: string | undefined;
1065
1087
  }
1088
+ /**
1089
+ * model override 的意图来源:决定该值是否等价于「用户显式选择」。
1090
+ * - 'user':/model 命令、ACP set_model、SDK 控制信号等用户动作;
1091
+ * - 'declared':主 Agent 声明模型(declaredModel)联动写入;
1092
+ * - 'materialized':Web UI 会话装配期钉住的兜底解析值(非用户意图)。
1093
+ */
1094
+ export type OverrideModelSource = 'user' | 'declared' | 'materialized';
1066
1095
  export interface SessionManager {
1067
1096
  getCurrent(): Session;
1068
1097
  setCurrent(session: Session): void;
@@ -1088,6 +1117,18 @@ export interface SessionManager {
1088
1117
  * before injecting `additionalContext`.
1089
1118
  */
1090
1119
  emitSessionStart(session: Session, source: SessionStartSource): Promise<void>;
1120
+ /**
1121
+ * Record a mod-plugin `$.ui.log` line as a user-visible message on the
1122
+ * session transcript (mirrors `recordHookBlockedMessage` — same
1123
+ * inputSubject / combineSubject / sessionStore path — but leaves
1124
+ * `lastMessageId` and `parentId` untouched because mod logs are
1125
+ * decorative and must not become anchors on the replay branch).
1126
+ *
1127
+ * @param session target session (host resolves current session and passes it in)
1128
+ * @param text already prefixed as `<plugin>: <text>` by the host bridge
1129
+ * @param plugin the calling mod's name (`origin.plugin`), for provider metadata
1130
+ */
1131
+ recordModLogMessage(session: Session, text: string, plugin: string): Promise<void>;
1091
1132
  addHistory(session: Session, input: string | AgentInputItem[]): Promise<void>;
1092
1133
  save(session: Session): Promise<void>;
1093
1134
  /** Initialize an immutable full snapshot for a new fork; target must be absent or empty. */
@@ -1165,11 +1206,15 @@ export interface SessionManager {
1165
1206
  setOverridePermissionMode(sessionId: string, mode: PermissionMode): void;
1166
1207
  getOverridePermissionMode(sessionId: string): PermissionMode | undefined;
1167
1208
  /**
1168
- * 设置 session 的 model 覆盖值(来自 SDK control signal)
1169
- * 这些值会覆盖 CLI 参数和配置文件的设置
1209
+ * 设置 session 的 model 覆盖值。source 记录意图来源,供「是否用户显式选择」判定:
1210
+ * - 'user'(默认):/model 命令、ACP set_model、SDK 控制信号等用户动作;
1211
+ * - 'declared':主 Agent 声明模型(declaredModel)联动写入;
1212
+ * - 'materialized':Web UI 会话装配期钉住的兜底解析值(非用户意图)。
1170
1213
  */
1171
- setOverrideModel(sessionId: string, model: string): void;
1214
+ setOverrideModel(sessionId: string, model: string, source?: OverrideModelSource): void;
1172
1215
  getOverrideModel(sessionId: string): string | undefined;
1216
+ getOverrideModelSource(sessionId: string): OverrideModelSource | undefined;
1217
+ clearOverrideModel(sessionId: string): void;
1173
1218
  /**
1174
1219
  * 设置会话运行时模型:同步写 session.options.model + requestOptions.model + override map。
1175
1220
  *
@@ -1178,7 +1223,7 @@ export interface SessionManager {
1178
1223
  * 供 applyOverrideModel 每轮重建 requestOptions(Issue #82146)。/model 命令与模型面板
1179
1224
  * 共用此入口;ACP set_model(applyRuntimeSessionModel)仍为独立实现,待统一收敛。
1180
1225
  */
1181
- setRuntimeModel(session: Session | undefined, modelId: string): void;
1226
+ setRuntimeModel(session: Session | undefined, modelId: string, source?: OverrideModelSource): void;
1182
1227
  /**
1183
1228
  * 设置会话运行时 outputStyle:同步写 session.options.outputStyle。
1184
1229
  *
@@ -1502,6 +1547,7 @@ export interface InterruptionService {
1502
1547
  approve(item: RunToolApprovalItem, options?: ApprovalOptions): void;
1503
1548
  reject(item: RunToolApprovalItem, options?: {
1504
1549
  decision?: 'deny' | 'rejectAndExitPlan';
1550
+ cancelTurn?: boolean;
1505
1551
  }): void;
1506
1552
  waitFor(session: Session): Promise<void>;
1507
1553
  /** Resolve the main/leader session for a given session (returns self if already main). */
@@ -1712,6 +1758,12 @@ export interface TurnMetricsReporter {
1712
1758
  */
1713
1759
  unregister(sessionId: string): void;
1714
1760
  }
1761
+ /** Ids of one model call, as stamped by the model wrapper. */
1762
+ export interface ModelCallGeneration {
1763
+ messageId: string;
1764
+ conversationRequestId?: string;
1765
+ stepSeq?: number;
1766
+ }
1715
1767
  export interface ModelResponseMetadata {
1716
1768
  /** 响应中的模型 ID */
1717
1769
  model?: string;
@@ -1725,6 +1777,8 @@ export interface ModelResponseMetadata {
1725
1777
  * 都带 providerData.messageId === 此值,handleContentFilteredResponse 据此剔除并替换为安全提示。
1726
1778
  */
1727
1779
  contentFilterMessageId?: string;
1780
+ /** Correlation of the generation that just completed, as stamped by the model wrapper. */
1781
+ generation?: ModelCallGeneration;
1728
1782
  usage?: {
1729
1783
  prompt_tokens: number;
1730
1784
  completion_tokens: number;
@@ -1,5 +1,5 @@
1
1
  import type { Observable } from 'rxjs';
2
- import type { Session } from './session-protocol';
2
+ import type { AgentRetryReason, Session } from './session-protocol';
3
3
  export declare const SessionRunStateMachine: unique symbol;
4
4
  export declare const SessionRunStateProjectionService: unique symbol;
5
5
  export declare const SESSION_RUN_STATE_PROJECTION_SCHEMA: 'session-run-state.v1';
@@ -144,6 +144,7 @@ export type SessionRunEvent = {
144
144
  } | {
145
145
  type: SessionRunEventType.RETRYING;
146
146
  reason?: string;
147
+ retryReason?: AgentRetryReason;
147
148
  } | {
148
149
  type: SessionRunEventType.COMPACT_STARTED;
149
150
  reason?: string;
@@ -189,6 +190,18 @@ export interface SessionRunStateMachine {
189
190
  */
190
191
  getChange$(session: Session, skipFirst?: boolean): Observable<void>;
191
192
  }
193
+ export declare const ModelRequestRetryPhase: unique symbol;
194
+ /**
195
+ * 模型请求层(宿主 provider)在同一次请求内部退避重发时,借此把会话投影为 retrying。
196
+ * 状态写入与守卫收口在 core,宿主只包住退避等待,不直接驱动状态机。
197
+ */
198
+ export interface ModelRequestRetryPhase {
199
+ /**
200
+ * `wait` 期间会话显示 retrying 并携带 `reason`;结束(含抛错 / 取消)后恢复 model_requesting。
201
+ * 非本轮主请求(无 session、辅助型 purpose、状态不在 model_requesting)时只执行 `wait`。
202
+ */
203
+ during<T>(session: Session | undefined, reason: AgentRetryReason, wait: () => Promise<T>): Promise<T>;
204
+ }
192
205
  /**
193
206
  * Pure derivations from a `SessionRunStatus`. The state machine implementation
194
207
  * MUST keep its instance methods (`getLifecycle`, `isBusy`, etc.) consistent
@@ -9,11 +9,18 @@ export declare function hasExhaustedStreamTimeoutRetryBudget(session: Session, i
9
9
  /**
10
10
  * `finish_reason=error` 且没有可用输出的两种空流:reasoning-only 与 no-token。
11
11
  * placeholder(空 200 / 心跳帧)仍是会话层终态,由拦截器切一次备站。
12
+ *
13
+ * 额外的时长闸门(#132616):这两种 kind 之所以可重试,前提是「上游瞬时失败」——秒级
14
+ * 空响应重跑一次大概率就好了。但当这条流已经跑满上游的硬时限才收到 error 时,前提不成立:
15
+ * 同一段 prompt 重跑必然再次跑满同一个时限。实测 7 个会话全部重试、全部再次撞墙、0 次恢复,
16
+ * 而 `#130098` 把预算从 1 提到 3 之后,同样的输入会从 2×900s 变成 4×900s ≈ 60 分钟静默。
17
+ * 重试的期望收益不随 elapsed 增长,成本却线性增长,所以按 elapsed 收口。
12
18
  */
13
19
  export declare function isRetryableEmptyStreamError(error: unknown): boolean;
14
20
  /**
15
21
  * Empty 200 / placeholder-only:拦截器最多切一次备站,会话层终态(#115866)。
16
- * reasoning-only / no-token + finish_reason=error:上游瞬时失败,按 error 预算重试。
22
+ * reasoning-only / no-token + finish_reason=error:上游瞬时失败,按 error 预算重试;
23
+ * 已烧满上游硬时限的那些除外,见 {@link isRetryableEmptyStreamError} 的时长闸门(#132616)。
17
24
  * 流空闲超时 / 首 token 超时:按各自的超时预算重试。
18
25
  */
19
26
  export declare function shouldAutoRetryStreamTimeout(session: Session, error: unknown): boolean;
@@ -34,6 +34,33 @@ export interface TurnContext {
34
34
  /** Canonical id assigned when the external user input is admitted. */
35
35
  conversationRequestId?: string;
36
36
  }
37
+ export interface RequestOwner {
38
+ readonly session: Session;
39
+ readonly requestId: string;
40
+ readonly turn: TurnContext;
41
+ latestExecution?: object;
42
+ }
43
+ export type RequestTerminalOutcome = 'written' | 'failed' | 'unconfirmed';
44
+ export interface RequestTerminal {
45
+ readonly attempt: object;
46
+ outcome?: RequestTerminalOutcome;
47
+ readonly completed: Promise<RequestTerminalOutcome>;
48
+ }
49
+ export declare function getRequestOwner(ref: object): RequestOwner | undefined;
50
+ export declare function getRequestExecution(ref: object): object | undefined;
51
+ export declare function associateRequestOwner(ref: object, owner: RequestOwner, execution?: object): void;
52
+ /** Carry physical execution through admission without inventing a request owner. */
53
+ export declare function associateRequestExecution(ref: object, execution: object): void;
54
+ /** Reserve completion ownership at admission, retaining the prior result if startup fails. */
55
+ export declare function beginRequestExecution(owner: RequestOwner, execution: object): void;
56
+ /** A failed startup never owns a result; restore only the execution it actually replaced. */
57
+ export declare function abandonRequestExecution(execution: object): Session['resultSubject']['value'];
58
+ export declare function getRequestTerminal(owner: RequestOwner, destination: string): RequestTerminal | undefined;
59
+ export declare function claimRequestTerminal(owner: RequestOwner, destination: string, attempt: object): boolean;
60
+ export declare function settleRequestTerminal(owner: RequestOwner, destination: string, attempt: object, outcome: RequestTerminalOutcome): void;
61
+ /** The admission boundary, not trace binding, creates a new logical request. */
62
+ export declare function admitRequestOwner(session: Session, requestId: string): RequestOwner;
63
+ export declare function runInRequestOwner<T>(owner: RequestOwner, callback: () => T): T;
37
64
  /** Transient provider-data key; stripped before history/model persistence. */
38
65
  export declare const TURN_CARRIER_CANDIDATE_KEY = "codebuddy.ai/turnCarrierCandidate";
39
66
  export declare const BAGGAGE_KEY_SESSION_ID = "codebuddy.session_id";
@@ -83,7 +110,7 @@ export declare function bindCurrentTurnContext(session: Session, conversationReq
83
110
  /** Carrier for one exact admitted request; never returns the latest other turn. */
84
111
  export declare function turnCarrierForRequest(session: Session, conversationRequestId: string | undefined): W3CTraceContextMeta;
85
112
  /** Release an exact request binding. */
86
- export declare function releaseTurnContext(session: Session, conversationRequestId: string | undefined): void;
113
+ export declare function releaseTurnContext(session: Session, conversationRequestId: string | undefined, owner?: RequestOwner): void;
87
114
  /** The current turn as an injectable three-key carrier; `{}` outside a turn. */
88
115
  export declare function currentTurnCarrier(): W3CTraceContextMeta;
89
116
  /**
@@ -58,6 +58,26 @@ export declare abstract class CommandMessageUtils {
58
58
  * 解析XML格式的命令输出
59
59
  */
60
60
  static parseOutput(xmlText: string): ParseCommandMessage | undefined;
61
+ /**
62
+ * 是否为本地命令在会话历史里留下的记账项:caveat、命令回显(`<command-name>`)、
63
+ * 命令输出(`<local-command-stdout>`)、本地 bash 的输入输出、plan 输出。
64
+ *
65
+ * 这些 item 的 role 是 user、也不带 skipRun,因此按「真实用户消息」判定会命中;
66
+ * 但它们只是本地命令的痕迹,**不代表用户开启了新一轮对话**。调用方(如 TUI 的
67
+ * loading 计时器)需要区分「新一轮」和「本地命令留痕」时用这个判据。
68
+ *
69
+ * 识别口径复用 parseInput / parseOutput / parsePlanOutput,避免调用方各自
70
+ * 维护一份 XML 标签清单而漂移。
71
+ */
72
+ static isLocalCommandRecord(text: string): boolean;
73
+ /**
74
+ * {@link isLocalCommandRecord} 的 item 版本。
75
+ *
76
+ * 必须读 **原始** content:`MessageContentUtils.extractTextContent` 已经把命令 XML
77
+ * 拆开(`<command-name>/doctor</command-name>` → `/doctor`),拿它的结果再判就永远
78
+ * 判不出来。
79
+ */
80
+ static isLocalCommandRecordItem(item: UserMessageItem): boolean;
61
81
  /**
62
82
  * 解析计划输出
63
83
  */
@@ -226,10 +226,10 @@ export declare abstract class HistoryUtils {
226
226
  * <conversation_history_summary>…</conversation_history_summary> 包裹的正文)。
227
227
  *
228
228
  * 规则(与 replaceCompactWithSummary / getCompactHistory 对齐):
229
- * 1. 仅查看 `providerData.agent === AgentNames.COMPACT` 且为 assistant 的 message
230
- * 2. 从后向前扫描,命中第一条满足格式的 compact assistant 即返回
231
- * 3. "满足格式"由 `SummaryUtils.extractCompactSummaryFromText` 统一判定
232
- * (内含结构校验 + 非空正文双闸)
229
+ * 1. 查看 compact-agent assistant,或 PreMessage/MaxToken 写入的显式 compact boundary
230
+ * 2. 从后向前扫描,命中第一条可用摘要即返回
231
+ * 3. compact assistant 继续要求结构化 summary envelope;显式 boundary 同时支持
232
+ * 工程压缩的 `<cb_summary>` 与 LLM summary envelope
233
233
  * 4. 全程扫描都拿不到 → 返回 `undefined`(history 中**从未**出现过合法摘要)
234
234
  *
235
235
  * ⚠️ 不适合用于"判断本次 compact run 是否成功"!
@@ -1,6 +1,6 @@
1
1
  import { type AcpTerminalStateItem, type AgentInputItem, type AssistantMessageItem, type CustomTitleItem, type FileHistorySnapshotItem, type FunctionCallItem, type FunctionCallResultItem, type HookBlockingDetail, HookEvent, type ResendForkNoticeItem, type UserMessageItem } from '../../../cbc-shared/node/index.js';
2
2
  type ItemStatus = 'in_progress' | 'completed' | 'incomplete';
3
- export type HookStatus = 'success' | 'blocked' | 'warning' | 'error';
3
+ export type HookStatus = 'success' | 'blocked' | 'warning' | 'error' | 'mod-log';
4
4
  interface ItemOptions {
5
5
  readonly skipRun?: boolean;
6
6
  readonly status?: ItemStatus;
@@ -256,6 +256,14 @@ export declare abstract class InputItemUtils {
256
256
  static isUserInterrupted(item: AgentInputItem): boolean;
257
257
  static isSuccessfulFunctionCallResultItem(item: AgentInputItem): item is FunctionCallResultItem;
258
258
  static isCompactBoundaryMessage(item: AgentInputItem): boolean;
259
+ /**
260
+ * 仅凭 providerData 结构化标记判定 compact boundary,不使用内容正则兜底。
261
+ *
262
+ * 会删除或改写消息的路径(如 replaceCompactWithSummary)必须用这个版本:
263
+ * 内容兜底会把用户粘贴的 `<cb_summary>` / `<conversation_history_summary>` 文本
264
+ * 误判为 boundary,导致真实用户输入被移除。
265
+ */
266
+ static isStructuredCompactBoundaryMessage(item: AgentInputItem): boolean;
259
267
  static isReplayRecoverableCompactMessage(item: AgentInputItem): item is UserMessageItem;
260
268
  static isCompactUserMessage(item: AgentInputItem): item is UserMessageItem;
261
269
  private static hasCompactBoundaryContent;
@@ -64,7 +64,9 @@ export declare class TokenUtils {
64
64
  * tool call 执行后产生的 function_call_result(这些结果在 API 返回后才追加到 history)。
65
65
  * 为了更准确地判断是否需要触发压缩,需要把这部分 token 补上。
66
66
  *
67
- * 从 history 末尾往前扫描,收集连续的 function_call_result 条目直到遇到其他类型为止。
67
+ * 从 history 末尾往前扫描,只收集紧挨在末尾的连续 function_call_result。
68
+ * 一遇到非 function_call_result(含 function_call)即停止:function_call 属于上一轮
69
+ * 已经进过请求的内容,穿过它会把更早轮次的 result 重复计入 inputTokens(#133055)。
68
70
  * 注意:估算前会移除图片内容,避免 base64 图片数据导致 token 严重偏高。
69
71
  */
70
72
  static estimateTrailingToolResultTokens(history: any[]): number;
@@ -31,6 +31,7 @@ import type { AgentOutputType, getAllMcpTools as getAllMcpToolsFn, MaxTurnsExcee
31
31
  import type { TextOutput, UnknownContext, UserContent } from '@openai/agents-core/types';
32
32
  import type { AcpTerminalStateItem, FileHistorySnapshotItem, ModelUsageItem, ResendForkNoticeItem } from './custom-input-item-types';
33
33
  export * from './custom-input-item-types';
34
+ export type { RunStreamEvent } from '@openai/agents-core';
34
35
  export type Agent<TContext = UnknownContext, TOutput extends AgentOutputType = TextOutput> = AgentTypeCtor<TContext, TOutput>;
35
36
  export type RunContext<TContext = UnknownContext> = RunContextTypeCtor<TContext>;
36
37
  export type Runner = RunnerTypeCtor;
@@ -64,4 +64,10 @@ export interface CheckpointFileChangeStats {
64
64
  additions: number;
65
65
  /** 删除行数 */
66
66
  deletions: number;
67
+ /**
68
+ * 行数为近似值(PTC/Code Mode 兜底:files 来自本轮 trackFile 快照,additions/deletions
69
+ * 暂记 0)。需要精确行数的调用方(如 TUI rewind 面板)据此异步调用
70
+ * compareWithCurrentFiles 补齐后清除本标记。仅内存态,不持久化。
71
+ */
72
+ approximate?: boolean;
67
73
  }
@@ -20,11 +20,23 @@ export declare class StreamTimeoutError extends CustomError {
20
20
  * reasoning-only:已流出思考、finish_reason=error 且无可用输出(#63761 / #122115)。
21
21
  * no-token:finish_reason=error 到达时一个模型 token 都没有(连 reasoning 也没有)。
22
22
  *
23
- * reasoning-only 与 no-token 都是上游瞬时失败,会话层按 error 恢复预算重试;
23
+ * reasoning-only 与 no-token 按「上游瞬时失败」处理,会话层按 error 恢复预算重试——
24
+ * 但仅限流没跑太久的那些:已经烧满上游硬时限的同样形态重跑必然再次跑满,由
25
+ * `isRetryableEmptyStreamError` 按 {@link EmptyStreamError.elapsedMs} 收口(#132616)。
24
26
  * placeholder 必须与 no-token 分开——两者共用一个值时,放开 no-token 会连带
25
27
  * 推翻空 200 的终态判定。
26
28
  */
27
29
  export type EmptyStreamKind = 'placeholder' | 'reasoning-only' | 'no-token';
30
+ /**
31
+ * 空流错误的结构化 category,两条上报通道共用一个值。
32
+ *
33
+ * ACP 侧 `classifyErrorAsRequestError` 早就用它(前端按此映射业务码 3008「模型服务未返回消息」);
34
+ * stream-json 侧此前没有任何结构化维度,`errors_info` 整体缺席,sandbox-proxy 的
35
+ * `BuildErrorMessageFromCLIErrors` 只能兜底成 `category=internal`,再由
36
+ * `ClassifyInBandPromptError` 推出 `error_origin=cli`——把上游故障记成 CLI 内部错误。
37
+ * 挂到错误对象的 `data` 上让两条通道读到同一个值,不再各说各话。
38
+ */
39
+ export declare const EMPTY_STREAM_ERROR_CATEGORY = "empty_model_response";
28
40
  /**
29
41
  * 空流错误
30
42
  * 语义上仍然是"上游没有提供模型输出",所以继承 StreamTimeoutError
@@ -33,10 +45,26 @@ export type EmptyStreamKind = 'placeholder' | 'reasoning-only' | 'no-token';
33
45
  * 典型触发:某些 OpenAI 兼容网关在后端异常时没有透传错误码,而是发一帧全空
34
46
  * `{"delta":{"role":"assistant","content":"","tool_calls":[],"refusal":""},"finish_reason":""}`
35
47
  * 然后直接关闭连接——用户看到的现象是 cbc 当前轮"空响应"并被 ACP 分类为 refusal。
48
+ *
49
+ * message **必须**按 kind 分开写:三种 kind 共用一句「only placeholder chunks」会谎报失败形态。
50
+ * 0924 沙箱实测的 reasoning-only 样本里上游发了 20397 帧 / 9.5 MB 真实 reasoning,
51
+ * 与「只有占位帧」正相反;而下游报表、看板、排障全靠这个字符串归因,于是把上游
52
+ * ~900s 时限问题记成了 CLI 内部错误(#132616)。
36
53
  */
37
54
  export declare class EmptyStreamError extends StreamTimeoutError {
38
55
  readonly emptyStreamKind: EmptyStreamKind;
39
- constructor(chunkCount: number, totalBytes: number, kind?: EmptyStreamKind);
56
+ /**
57
+ * 流从打开到判定空流的时长。
58
+ *
59
+ * 用来区分「上游瞬时抖动(秒级空响应)」和「跑满上游硬时限(0924 实测 ~900s)」——
60
+ * 后者重跑同一段 prompt 必然再次跑满,重试只是把静默时长翻倍,见
61
+ * `isRetryableEmptyStreamError` 的时长闸门。
62
+ */
63
+ readonly elapsedMs: number;
64
+ readonly data: Readonly<{
65
+ category: "empty_model_response";
66
+ }>;
67
+ constructor(chunkCount: number, totalBytes: number, kind?: EmptyStreamKind, elapsedMs?: number);
40
68
  }
41
69
  /**
42
70
  * 认证缺失错误
@@ -3,6 +3,7 @@ export * from './prompt-codec.js';
3
3
  export * from './prompt-context-xml.js';
4
4
  export * from './to-resolve-blocks.js';
5
5
  export * from './interactive-question-tools.js';
6
+ export * from './sandbox-rule-context.js';
6
7
  export * from './sdk.js';
7
8
  export * from './transport/streamable-http.js';
8
9
  export * from './client/index.js';
@@ -24,6 +24,8 @@ export interface AcpResourceLinkProviderData {
24
24
  [extra: string]: unknown;
25
25
  }
26
26
  export interface DecodeInputTextToAcpContentBlocksOptions {
27
+ /** Defaults to legacy badge parsing. False restores only explicit resource metadata. */
28
+ parseInlineReferences?: boolean;
27
29
  resolveImageOrdinal?: (ordinal: number, label: string) => ContentBlock | undefined;
28
30
  /** 标题/摘要等纯展示场景允许缺少 providerData 的 badge 降级为不可交互的可读块。 */
29
31
  allowDisplayOnlyFallback?: boolean;
@@ -36,6 +38,8 @@ export interface DecodeInputTextToAcpContentBlocksOptions {
36
38
  allowUnicodeSlashTokens?: boolean;
37
39
  }
38
40
  export interface DecodePersistedUserContentToAcpContentBlocksOptions {
41
+ /** Keep ordinary text literal while restoring explicitly encoded attachments. */
42
+ parseInlineReferences?: boolean;
39
43
  convertPersistedImageBlock?: (block: Record<string, any>) => ContentBlock | undefined;
40
44
  }
41
45
  export declare function getAcpResourceLinkDisplayName(uri: string, name?: string): string;
@@ -0,0 +1,38 @@
1
+ export type SandboxRuleDomain = 'file' | 'command' | 'network';
2
+ export type SandboxRuleSource = 'enterprise' | 'preset' | 'user';
3
+ export type SandboxRuleCause = {
4
+ kind: 'ordered-rule';
5
+ domain: SandboxRuleDomain;
6
+ ruleRef: string;
7
+ } | {
8
+ kind: 'sensitive-rule';
9
+ ruleId: string;
10
+ source?: SandboxRuleSource;
11
+ } | {
12
+ kind: 'policy';
13
+ code: string;
14
+ };
15
+ export interface SandboxRuleContext {
16
+ causes: SandboxRuleCause[];
17
+ }
18
+ export interface FileApprovalScope {
19
+ directory: string;
20
+ operation: 'read' | 'write' | 'delete';
21
+ recursive: boolean;
22
+ lifetime: 'session';
23
+ }
24
+ export declare const SANDBOX_RULE_CONTEXT_META_KEY = "codebuddy.ai/sandboxRuleContext";
25
+ export declare const FILE_APPROVAL_SCOPE_META_KEY = "codebuddy.ai/fileApprovalScope";
26
+ /** 仅复制显示所需字段,不能将归因标识作为授权凭证。 */
27
+ export declare function parseSandboxRuleContext(value: unknown): SandboxRuleContext | undefined;
28
+ export declare function parseFileApprovalScope(value: unknown): FileApprovalScope | undefined;
29
+ /**
30
+ * 目录授权的专用应答 optionId,不出现在 requestPermission 的选项列表中。
31
+ * 只有展示了 fileApprovalScope 的卡片会回传它;按选项 kind 自动应答的 IM、
32
+ * 自动化或旧 UI 选不到它,因而无法替用户登记目录授权。
33
+ */
34
+ export declare const FILE_DIRECTORY_APPROVAL_OPTION_ID = "allow_directory";
35
+ export declare function parseSandboxPermissionMetadata(meta: unknown): {
36
+ ruleContext?: SandboxRuleContext;
37
+ fileApprovalScope?: FileApprovalScope;
38
+ };
@@ -41,12 +41,26 @@ export declare const ExtensionMethod: {
41
41
  readonly DELEGATE_TOOLS_CHANGED: '_codebuddy.ai/delegateToolsChanged';
42
42
  /** UI control for operating Web UI elements */
43
43
  readonly UI_CONTROL: '_codebuddy.ai/uiControl';
44
+ /**
45
+ * A `--plugin-dir` mod's `ui.render` output — one serialized tree per
46
+ * paint. Payload: `{ sessionId, plugin, tree }`. The webui / desktop
47
+ * surface re-hydrates the tree into React nodes; a `<Button>` in the
48
+ * tree renders as a real HTML button whose click sends MOD_PRESS.
49
+ */
50
+ readonly MOD_RENDER: '_codebuddy.ai/modRender';
51
+ /**
52
+ * Interaction back-channel for MOD_RENDER trees. Payload:
53
+ * `{ sessionId, plugin, element, surface }`. The agent dispatches
54
+ * `ui.press` and runs the closure the mod registered under that
55
+ * element key.
56
+ */
57
+ readonly MOD_PRESS: '_codebuddy.ai/modPress';
44
58
  };
45
59
  export type ExtensionMethodName = (typeof ExtensionMethod)[keyof typeof ExtensionMethod];
46
60
  /**
47
61
  * All known extension methods
48
62
  */
49
- export declare const KNOWN_EXTENSIONS: readonly ["_codebuddy.ai/artifact", "_codebuddy.ai/artifactBatch", "_codebuddy.ai/question", "_codebuddy.ai/checkpoint", "_codebuddy.ai/command", "_codebuddy.ai/authUrl", "_codebuddy.ai/file_history_snapshot", "_codebuddy.ai/delegateTool", "_codebuddy.ai/delegateToolsChanged"];
63
+ export declare const KNOWN_EXTENSIONS: readonly ["_codebuddy.ai/artifact", "_codebuddy.ai/artifactBatch", "_codebuddy.ai/question", "_codebuddy.ai/checkpoint", "_codebuddy.ai/command", "_codebuddy.ai/authUrl", "_codebuddy.ai/file_history_snapshot", "_codebuddy.ai/delegateTool", "_codebuddy.ai/delegateToolsChanged", "_codebuddy.ai/modRender", "_codebuddy.ai/modPress"];
50
64
  /**
51
65
  * 恶意网站拦截的错误码标记,随工具调用结果经 ACP 传给客户端。
52
66
  *
@@ -1,7 +1,7 @@
1
1
  import { RestOperations } from '@celljs/http';
2
2
  import { AuthenticationType, ClientInfoProvider, ProductConfiguration, ProductManager } from '../../../product/lib/common/index.js';
3
3
  import { ExternalUriOpener } from '../../../runtime/lib/common/index.js';
4
- import { Logger } from '../../../telemetry/lib/common/index.js';
4
+ import { Logger, type Span } from '../../../telemetry/lib/common/index.js';
5
5
  import { Account, APIResult, AuthenticationProvider, AuthSession, AuthState, AuthToken, LoginContext, LogoutOptions, ProductEnvService, SignContext } from './authentication-protocol.js';
6
6
  /**
7
7
  * External-link auth variant whose current account is scoped by the token.
@@ -29,11 +29,11 @@ export declare class AccountScopedExternalLinkAuthenticationProvider implements
29
29
  removeSession(_session?: AuthSession, _options?: LogoutOptions): Promise<void>;
30
30
  switchAccount(account: Account, authSession: AuthSession, ctx: SignContext): Promise<AuthSession>;
31
31
  private toSessionAccountLists;
32
- protected openAuthUrl(authState: AuthState): Promise<void>;
32
+ protected openAuthUrl(authState: AuthState, handoffSpan?: Span): Promise<void>;
33
33
  private fetchAuthState;
34
34
  private loopGetToken;
35
35
  private loopGetCurrentAccount;
36
- protected fetchCurrentAccount(auth: AuthToken, ctx: SignContext): Promise<Account>;
36
+ protected fetchCurrentAccount(auth: AuthToken, ctx: SignContext, requestSpan?: Span): Promise<Account>;
37
37
  protected enterpriseHeaders(auth?: AuthToken): Record<string, string>;
38
38
  protected calculateExpiresAt(authToken: AuthToken): void;
39
39
  private isAuthenticationInvalidError;