@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
@@ -3,10 +3,11 @@ import { AuthenticationManager } from '../../../../workspace/authentication/lib/
3
3
  import { type AbortLinkDisposer, Agent, type AgentInputItem, type NonStreamRunOptions, RunState, type StreamRunOptions } from '../../../cbc-shared/node/index.js';
4
4
  import { type LanguageModel } from '../../../../workspace/product/lib/common/index.js';
5
5
  import { Logger } from '../../../../workspace/telemetry/lib/common/index.js';
6
+ import { type ManualCompactRequestHandler as ManualCompactRequestHandlerContract } from '../context/context-protocol';
6
7
  import { type FileRollbackOperationLock as FileRollbackOperationLockContract } from '../file-rollback/file-rollback-service-protocol';
7
8
  import { Session, SessionManager } from '../session/session-protocol';
8
9
  import { SessionRunStateMachine } from '../session/session-run-state-machine-protocol';
9
- import { type AgentCurrentContinuationOptions, AgentManager, AgentRunInterceptor, AgentRunRequest, AgentService, type AgentStandardRunOptions, RunnerProvider } from './agent-protocol';
10
+ import { type AgentCurrentContinuationOptions, AgentManager, AgentRunInterceptor, AgentRunRequest, AgentService, type AgentStandardRunOptions, type OneTimeRunOptions, RunnerProvider } from './agent-protocol';
10
11
  import { type AgentRunScope as IAgentRunScope } from './agent-run-scope';
11
12
  import { AgentPluginRefresh, AgentRunObserver, AgentRuntimeResolver } from './agent-runtime-protocol';
12
13
  export declare class AgentServiceImpl implements AgentService {
@@ -22,6 +23,7 @@ export declare class AgentServiceImpl implements AgentService {
22
23
  protected readonly agentRunInterceptorProvider: Provider<AgentRunInterceptor>;
23
24
  protected readonly fileRollbackOperationLock?: FileRollbackOperationLockContract;
24
25
  protected readonly logger: Logger;
26
+ protected readonly manualCompactRequestHandler?: ManualCompactRequestHandlerContract;
25
27
  /**
26
28
  * Preserve the pre-start cancellation snapshot across runDefault's agent
27
29
  * lookup controller and run()'s own controller. This is process-local
@@ -40,6 +42,20 @@ export declare class AgentServiceImpl implements AgentService {
40
42
  protected getLifecycleOwners(): WeakMap<Session, AbortController>;
41
43
  tryCloseTaskSession(session: Session, result: NonNullable<Session['resultSubject']['value']>): Promise<boolean>;
42
44
  retireTaskSession(session: Session): Promise<void>;
45
+ waitForRunsSettled(session: Session): Promise<void>;
46
+ /**
47
+ * 有界 join:等到该 session 上的物理 run 全部交还 lifecycle owner 与 in-flight 信号。
48
+ *
49
+ * 为什么需要它而不是直接看 `agent_end`:`finalizeRun` 晚于本轮把最终产出写进
50
+ * history,`agent_end` 却早于 `finalizeRun`。任何依赖「上一轮 history 已写完」这个
51
+ * 因果的调用方(如队列 drain)必须 join 到这里。
52
+ *
53
+ * Bounded: `runSettledSubject` is optional, so a session built without
54
+ * one has nothing to observe and would hang the caller's cleanup — which
55
+ * owns hook, MCP and background-shell teardown. `agent_end` 也可能来自没有物理
56
+ * run 的路径(skipRun / 迟到事件),无界等待会把调用方永久挂住。
57
+ */
58
+ private joinRunsSettled;
43
59
  /** compare-and-delete:仅当 token 仍指向本轮 controller 时清除。 */
44
60
  private clearLifecycleOwner;
45
61
  /** 本轮是否是当前 lifecycle owner。 */
@@ -156,6 +172,7 @@ export declare class AgentServiceImpl implements AgentService {
156
172
  protected resolveRunOneTimeModel(agentName: string, session?: Session): Promise<LanguageModel>;
157
173
  run<TAgent extends Agent<any, any>>(agent: TAgent, input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
158
174
  run<TAgent extends Agent<any, any>, TContext = Session>(agent: TAgent, input: string | AgentInputItem[] | RunState<TContext, TAgent>, options?: AgentStandardRunOptions<TContext>): Promise<void>;
175
+ private runPipeline;
159
176
  /**
160
177
  * #59319-stream: 抽取的 physical run cleanup 逻辑。
161
178
  * 非 stream 路径由 run() finally 同步调用;
@@ -189,8 +206,14 @@ export declare class AgentServiceImpl implements AgentService {
189
206
  private prepareRunAdmission;
190
207
  runDefault<TAgent extends Agent<any, any>>(input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
191
208
  runDefault<TAgent extends Agent<any, any>, TContext = Session>(input: string | AgentInputItem[] | RunState<TContext, TAgent>, options?: AgentStandardRunOptions<TContext>): Promise<void>;
192
- runOneTime<TContext = Session>(agentName: string, input: string | AgentInputItem[], options?: NonStreamRunOptions<TContext>): Promise<string>;
193
- runOneTime<TContext = Session>(agentName: string, input: string | AgentInputItem[], options?: StreamRunOptions<TContext>): Promise<string>;
209
+ /**
210
+ * Streams the text of a one-shot run on `session`. A reused caller Session is shared
211
+ * with its in-flight main run, so the call's purpose and request id live in its async
212
+ * scope instead of on the Session.
213
+ */
214
+ private streamOneTimeText;
215
+ runOneTime<TContext = Session>(agentName: string, input: string | AgentInputItem[], options?: NonStreamRunOptions<TContext> & OneTimeRunOptions): Promise<string>;
216
+ runOneTime<TContext = Session>(agentName: string, input: string | AgentInputItem[], options?: StreamRunOptions<TContext> & OneTimeRunOptions): Promise<string>;
194
217
  /**
195
218
  * Enhanced version of runOneTime that supports per-request overrides
196
219
  * for temperature, maxTokens, maxTurns, systemPrompt, and bypassPermissions.
@@ -1,5 +1,8 @@
1
1
  export * from './agent-protocol';
2
2
  export * from './agent-purpose-protocol';
3
+ export * from './agent-purpose-scope';
4
+ export * from './model-step-sequence';
5
+ export * from './model-call-failure';
3
6
  export * from './agent-runtime-protocol';
4
7
  export * from './agent-run-scope';
5
8
  export * from './agent-service';
@@ -0,0 +1,9 @@
1
+ import type { ModelCallGeneration } from '../session/session-protocol';
2
+ /**
3
+ * Marks `error` as the failure of one model call. The call's ids live in the model-call
4
+ * async scope, which does not reach the consumer of the SDK run stream; the error does.
5
+ * An error rethrown through an outer call keeps the innermost call's mark.
6
+ */
7
+ export declare function markModelCallFailure<T>(error: T, sessionId: string, generation: ModelCallGeneration): T;
8
+ /** The model call of this Session that failed with `error`; undefined when the failure is not one. */
9
+ export declare function getFailedModelCall(error: unknown, sessionId: string): ModelCallGeneration | undefined;
@@ -0,0 +1,11 @@
1
+ import type { Session } from '../session/session-protocol';
2
+ type StepSequenceSession = Pick<Session, 'id' | 'history' | 'agentPurpose' | 'modelStepSeq'>;
3
+ /** Latest step of the Session's agent loop, restored from persisted history after resume. */
4
+ export declare function currentModelStepSeq(session: StepSequenceSession): number;
5
+ /**
6
+ * Step number for the model call in the current async chain. Agent-loop calls
7
+ * advance the counter; auxiliary calls reuse the latest step. The counter never
8
+ * resets across runs, compaction continuations or teammate wake-ups.
9
+ */
10
+ export declare function allocateModelStepSeq(session: StepSequenceSession): number;
11
+ export {};
@@ -21,6 +21,14 @@ export interface ModelInputMemoryPressure {
21
21
  headroom: number;
22
22
  inputItems: number;
23
23
  estimatedInputBytes?: number;
24
+ /**
25
+ * Whether the retained-size walk finished (fully traversed, or provably ≥ the byte budget).
26
+ * `false` means the walk stopped on the node cap with bytes still under budget — the graph is
27
+ * deep/wide but not necessarily large, so `estimatedInputBytes` must NOT drive a rejection.
28
+ */
29
+ estimateComplete: boolean;
30
+ /** Real, content-independent OOM signal: heap is already near its ceiling. */
31
+ heapCritical: boolean;
24
32
  reject: boolean;
25
33
  }
26
34
  export declare function assessModelInputMemoryPressure(input: AgentInputItem[], heapUsed?: number, heapLimit?: number): ModelInputMemoryPressure;
@@ -80,8 +88,18 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
80
88
  * 否则前端的 sending 态无人清除、永久转圈(#73022)。
81
89
  */
82
90
  protected readonly acpBroadcastService?: AgentQueueOutput;
91
+ /** Sessions with a deferred emergency compaction already scheduled (see scheduleEmergencyCompact). */
92
+ private readonly emergencyCompactInFlight;
83
93
  create(config?: Partial<RunConfig>): Promise<Runner>;
84
94
  private assertModelInputCloneHeadroom;
95
+ /**
96
+ * Fire a one-shot emergency compaction for an over-large history so the user's retry can
97
+ * succeed. Deferred + de-duplicated per session; failures are swallowed because the surfaced
98
+ * error already tells the user how to recover. Mirrors checkAutoCompact's non-blocking branch
99
+ * (setImmediate keeps it off the current runner's abort signal). compactAndSummarize has its
100
+ * own session-level lock, so the in-flight set only avoids scheduling redundant callbacks.
101
+ */
102
+ private scheduleEmergencyCompact;
85
103
  /**
86
104
  * 在每次模型请求前检查是否需要自动压缩。
87
105
  * 此时所有工具都已执行完毕,可以安全地触发压缩。
@@ -90,10 +108,10 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
90
108
  /**
91
109
  * Mode B:把「立即发送」队列项注入正在运行的 turn(#73022)。
92
110
  *
93
- * 调用点在 `callModelInputFilter`(见 `create()`),即**每次模型请求之前**,
94
- * 且此时本轮工具已全部执行完、tool result 已回填。选这个边界是因为既不用
95
- * 打断在跑的工具,也不会破坏 `tool_call` 与 `tool_result` 的配对——Codex 与
96
- * Claude Code 同样选在这个位置。
111
+ * 调用点在 `callModelInputFilter`(见 `create()`),即**每次模型请求之前**。
112
+ * rich message / notification / drain prompt 仍在这里注入请求副本;真实 steer
113
+ * 由 `continuationInputProvider` 在 `prepareTurn` 前写入 SDK RunState,避免后续
114
+ * 工具 step 从权威状态重建请求时丢失。
97
115
  *
98
116
  * 注入内容已经进入本次模型请求,无需再为“曾经注入过”强制续圈。只有模型响应期间
99
117
  * 新到达、尚未被取出的消息,才由 `__codebuddySteerPending` 在收尾时实时判定是否
@@ -111,6 +129,22 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
111
129
  * `create()` 注释)。payload 与授权同为调用局部值,天然不跨 run 共享。
112
130
  */
113
131
  private injectSendNowItems;
132
+ /**
133
+ * Drain steer only at the SDK continuation boundary, before it prepares the next model step.
134
+ *
135
+ * The returned model items are installed by the SDK into RunState.generatedItems before
136
+ * `prepareTurn`. This makes steer authoritative input for every later tool/model step instead
137
+ * of an ephemeral `callModelInputFilter` addition. The visible history stays the bare user
138
+ * message; it is admitted exactly once, by the stream consumer, in RunState order.
139
+ */
140
+ private takeSteerContinuationInput;
141
+ /**
142
+ * Visible-history + ACP admission of one drained steer group.
143
+ *
144
+ * Ordering is the caller's responsibility (continuation-history-queue.ts); this only performs
145
+ * the writes and must never throw back into the run.
146
+ */
147
+ private admitSteerToVisibleHistory;
114
148
  /**
115
149
  * #100404:落定来源一(rich queue sendNow)的消费。
116
150
  *
@@ -139,11 +173,11 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
139
173
  * (`session/session-manager.ts` 的 `MODEL_STREAM_STARTED`),涉及跨模块反向布线与
140
174
  * 事件类型白名单依赖,另开 issue 跟进。
141
175
  *
142
- * **落史顺序反转(显式接受)**:`modelData.input` 的 push 顺序是来源一 → 二 → 三 → 四,
143
- * 但来源一的 `addHistory` 推迟到本方法内执行,来源二/三/四仍在 `injectSendNowItems` 里
144
- * 就地 addHistory。同一 model step 同时命中多个来源时,history 里队员消息会排在
145
- * steer / 通知之后,与模型当时看到的输入顺序相反。已确认下游按 role/type 消费、不依赖
146
- * 交错位置,故接受该反转,不做「四来源 historyItems 统一收敛」的重构。
176
+ * **落史顺序反转(显式接受)**:`modelData.input` 的 filter push 顺序是来源一 → 三 → 四,
177
+ * 但来源一的 `addHistory` 推迟到本方法内执行,来源三/四仍在 `injectSendNowItems` 里
178
+ * 就地 addHistory。同一 model step 同时命中多个来源时,history 里队员消息会排在通知
179
+ * 之后,与模型当时看到的输入顺序相反。steer 已在更早的 SDK continuation 边界同时进入
180
+ * RunState 与可见历史,不参与这段反转。下游按 role/type 消费、不依赖交错位置,故接受。
147
181
  *
148
182
  * at-most-once 由**作用域**保证,不再依赖「commit 前清暂存」这类补偿动作:`pending` 是
149
183
  * 单次 `callModelInputFilter` 调用的局部值,每次调用最多把它 commit 一次,也不可能被
@@ -27,7 +27,7 @@ export declare const TOOL_CALL_LOOP_STOPPED_MESSAGE = "Request aborted: user sto
27
27
  * - `ToolCallLoopDetector` 在**模型请求前**拦截,静默向模型注入停止消息,用户无感;
28
28
  * 它覆盖的是旧的三条规则(黑名单同参 4 次 / Read 同文件 40 次 / 非黑名单同参 40 次)。
29
29
  * - `ToolCallLoopGuard` 在**工具执行前**拦截,弹窗让用户自己决定继续还是停止;
30
- * 它覆盖新增的两条规则(同工具连续 40 次,Bash 单独放到 80 次 / 周期序列重复 10 轮)。
30
+ * 它覆盖新增的两条规则(同工具连续 40 次,Bash 与 Write 单独放到 80 次 / 周期序列重复 10 轮)。
31
31
  *
32
32
  * 两者刻意并存:旧规则的静默语义已被线上验证,不因新能力回归。
33
33
  */
@@ -5,11 +5,11 @@
5
5
  */
6
6
  import type { ToolCallLoopTriggerType } from '../../../../workspace/telemetry/lib/common/event/types/craft.js';
7
7
  export interface ToolCallLoopThresholds {
8
- /** 同一工具连续调用达到该次数即判定为循环。Bash 走单独阈值。 */
8
+ /** 同一工具连续调用达到该次数即判定为循环。Bash / Write 走单独阈值。 */
9
9
  consecutiveThreshold: number;
10
10
  /**
11
- * Bash 连续调用的单独阈值。长任务里模型会连续跑很多条不同命令,
12
- * 只看工具名时 40 次容易把正常推进误判成循环。
11
+ * Bash 与 Write 连续调用的单独阈值。长任务里模型会连续跑很多条命令、
12
+ * 或连续落很多个文件,只看工具名时 40 次容易把正常推进误判成循环。
13
13
  */
14
14
  bashConsecutiveThreshold: number;
15
15
  /** AAB 块需要连续重复的轮数。 */
@@ -22,8 +22,9 @@ export interface ToolCallLoopHit {
22
22
  /** 重复序列的周期长度;AAB 恒为 3,连续同工具恒为 1。 */
23
23
  patternLength: number;
24
24
  }
25
- /** 与 `ToolNames.BASH` 对齐。模式识别层不依赖 agent-protocol,避免把工具名枚举拉进来。 */
25
+ /** 与 `ToolNames.BASH` / `ToolNames.WRITE` 对齐。模式识别层不依赖 agent-protocol,避免把工具名枚举拉进来。 */
26
26
  export declare const BASH_LOOP_TOOL_NAME = "Bash";
27
+ export declare const WRITE_LOOP_TOOL_NAME = "Write";
27
28
  export declare const DEFAULT_TOOL_CALL_LOOP_THRESHOLDS: ToolCallLoopThresholds;
28
29
  /** AAB 块的长度。多工具循环只识别这一种形状,因此是常量而非可配阈值。 */
29
30
  export declare const AAB_PERIOD = 3;
@@ -43,7 +44,7 @@ export declare class ToolCallLoopTracker {
43
44
  * 记录一次即将执行的工具调用,返回本次是否命中循环。
44
45
  *
45
46
  * 命中优先级:先判连续同工具,再判 AAB 重复。两条规则的阈值默认不重叠
46
- * (普通工具 40 次、Bash 80 次 vs AAB 重复 10 轮),实践中不会互相抢占。
47
+ * (普通工具 40 次、Bash / Write 80 次 vs AAB 重复 10 轮),实践中不会互相抢占。
47
48
  */
48
49
  record(toolName: string): ToolCallLoopHit | undefined;
49
50
  /**
@@ -59,7 +60,7 @@ export declare class ToolCallLoopTracker {
59
60
  * - `ABC`(三者互不相同)通常是正常的多步工作流(读文件 → 改文件 → 跑测试,
60
61
  * 然后换下一个文件),按周期重复判它循环误伤面太大;
61
62
  * - `ABAB` 这类两工具交替同样不判,避免把翻页 / 分批处理误当循环;
62
- * - `AAA…` 属于连续同工具,由 consecutiveThreshold / bashConsecutiveThreshold 那条规则负责。
63
+ * - `AAA…` 属于连续同工具,由 consecutiveThreshold / bashConsecutiveThreshold(Bash、Write)那条规则负责。
63
64
  *
64
65
  * `X ≠ Y` 顺带保证了 AAB 一定是本原周期(唯一可能的更短整除周期是 1,
65
66
  * 那要求三个元素全等),所以不需要额外的本原性校验。
@@ -69,8 +70,8 @@ export declare function matchesRepeatedAabSequence(history: readonly string[], r
69
70
  * 读取阈值配置。环境变量只用于 QA 快速复现,生产不设置即走默认值。
70
71
  * AAB 的周期是形状定义的一部分,不开放配置。
71
72
  *
72
- * `CBC_LOOP_GUARD_CONSECUTIVE_THRESHOLD` 只覆盖非 Bash 工具。Bash 用
73
- * `CBC_LOOP_GUARD_BASH_CONSECUTIVE_THRESHOLD`,避免 QA 把通用阈值压低时
73
+ * `CBC_LOOP_GUARD_CONSECUTIVE_THRESHOLD` 只覆盖非 Bash / Write 工具。Bash 与 Write
74
+ * 共用 `CBC_LOOP_GUARD_BASH_CONSECUTIVE_THRESHOLD`,避免 QA 把通用阈值压低时
74
75
  * 把长任务放宽一并关掉。
75
76
  */
76
77
  export declare function resolveToolCallLoopThresholds(env?: NodeJS.ProcessEnv): ToolCallLoopThresholds;
@@ -0,0 +1,39 @@
1
+ import type { CompactionKind, CompactionTrigger } from '../../../../workspace/telemetry/lib/common/index.js';
2
+ import type { Session } from '../session/session-protocol';
3
+ export type { CompactionKind, CompactionTrigger };
4
+ export declare function compactionKindOf(trigger: CompactionTrigger): CompactionKind;
5
+ /** Compactions of a Session's context. Never resets, like `modelStepSeq`. */
6
+ export interface CompactionLineage {
7
+ /** Completed compactions. */
8
+ count: number;
9
+ /** Compaction the current context starts from. */
10
+ lastId?: string;
11
+ /** Trigger of the completed compaction the next agent-loop model call reports. */
12
+ pending?: CompactionTrigger;
13
+ }
14
+ type LineageSession = Pick<Session, 'id' | 'history' | 'compactionLineage' | 'meta'>;
15
+ /** Compaction lineage of `session`, restored from its history after resume. */
16
+ export declare function getCompactionLineage(session: LineageSession): CompactionLineage;
17
+ /**
18
+ * Numbers a compaction boundary item before it enters history and stamps the running
19
+ * compaction onto it; the next agent-loop model call reports it.
20
+ */
21
+ export declare function recordCompactionBoundary(session: LineageSession, providerData: Record<string, unknown>): void;
22
+ /** Compaction lineage of one model call (gateway headers, `chat_message_send`). */
23
+ export interface ModelCallCompaction {
24
+ /** Completed compactions of the Session when the call is sent. */
25
+ readonly count: number;
26
+ /** Compaction the call's context starts from. */
27
+ readonly id?: string;
28
+ /** Compaction calls: class of the running compaction (`X-Compaction`). */
29
+ readonly kind?: CompactionKind;
30
+ /** First agent-loop call after a compaction: its class (`X-Context-Compacted`) and trigger. */
31
+ readonly contextCompacted?: CompactionKind;
32
+ readonly trigger?: CompactionTrigger;
33
+ }
34
+ /**
35
+ * Compaction lineage for the model call in the current async chain. Only the first
36
+ * agent-loop call after a compaction reports it, like Claude Code's
37
+ * `consumePendingContextCompacted`.
38
+ */
39
+ export declare function resolveModelCallCompaction(session: LineageSession & Pick<Session, 'agentPurpose' | 'conversationRequestId'>): ModelCallCompaction;
@@ -16,6 +16,7 @@ import { CompactStrategy, type ContextCompactResult, ContextCompactSummarizeOpti
16
16
  * 不包含任何具体的压缩逻辑实现。
17
17
  */
18
18
  export declare class ContextCompactSummarizerImpl implements ContextCompactSummarizer {
19
+ private activeCompactions?;
19
20
  protected readonly productManager: ProductManager;
20
21
  protected readonly agentManager: AgentManager;
21
22
  protected readonly logger: Logger;
@@ -25,6 +26,7 @@ export declare class ContextCompactSummarizerImpl implements ContextCompactSumma
25
26
  protected readonly strategyProvider: Provider<CompactStrategy>;
26
27
  compactAndSummarize(session: Session, options?: ContextCompactSummarizeOptions): Promise<boolean>;
27
28
  compactWithResult(session: Session, options?: ContextCompactSummarizeOptions): Promise<ContextCompactResult>;
29
+ private compactWithResultOwned;
28
30
  /**
29
31
  * 按优先级匹配(PreMessage → MaxToken),跳过 Blocking(仅作最终兜底),执行第一个命中的策略;
30
32
  * 都不命中则安全网回落到 Blocking。逻辑与压缩 span 化之前完全一致,只是把散落的 `return` 收敛成
@@ -1,7 +1,10 @@
1
+ import type { AgentInputItem } from '../../../cbc-shared/node/index.js';
2
+ import type { CompactionTrigger } from '../../../../workspace/telemetry/lib/common/index.js';
1
3
  import { Session } from '../session/session-protocol';
2
4
  export declare const PromptContextProvider: unique symbol;
3
5
  export declare const PromptContextInitializer: unique symbol;
4
6
  export declare const ContextCompactSummarizer: unique symbol;
7
+ export declare const ManualCompactRequestHandler: unique symbol;
5
8
  export declare const PromptRenderer: unique symbol;
6
9
  export declare const COMPACT_PROMPT = "compact-prompt";
7
10
  export declare const DEFAULT_TOKEN_THRESHOLD = 0.7;
@@ -190,6 +193,8 @@ export interface ContextCompactSummarizeOptions {
190
193
  type?: CompactType;
191
194
  /** Stable identity shared by live updates and the durable compact boundary. */
192
195
  compactionId?: string;
196
+ /** Why this compaction runs; defaults from `type` (manual / pre_message_threshold / emergency_threshold). */
197
+ trigger?: CompactionTrigger;
193
198
  }
194
199
  export type ContextCompactSkipReason = 'already_compacting' | 'pending_interruption' | 'auto_disabled' | 'empty_history' | 'already_compacted' | 'non_default_agent' | 'below_threshold';
195
200
  export type ContextCompactFailureReason = 'strategy_failed' | 'strategy_unavailable';
@@ -214,6 +219,8 @@ export declare function createCompactionId(): string;
214
219
  export declare const SESSION_META_COMPACT_TYPE: 'compactType';
215
220
  /** Current stable compaction identity, persisted onto the boundary item. */
216
221
  export declare const SESSION_META_COMPACTION_ID: 'compactionId';
222
+ /** Trigger of the compaction the summarizer is running; unset for a typed `/compact`. */
223
+ export declare const SESSION_META_COMPACTION_TRIGGER: 'compactionTrigger';
217
224
  /**
218
225
  * session.meta 上标记当前 compact 成功后会继续执行一次真实 agent run。
219
226
  *
@@ -321,6 +328,16 @@ export interface ContextCompactSummarizer {
321
328
  /** Compatibility wrapper for existing automatic-compaction callers. */
322
329
  compactAndSummarize(session: Session, options?: ContextCompactSummarizeOptions): Promise<boolean>;
323
330
  }
331
+ /**
332
+ * Host-owned boundary for external `/compact` requests.
333
+ *
334
+ * AgentService invokes this before creating a normal run lifecycle when an
335
+ * interactive host opts in. Implementations must return false for internal compact
336
+ * inputs so strategy-owned internal runs cannot recursively re-enter this boundary.
337
+ */
338
+ export interface ManualCompactRequestHandler {
339
+ tryHandle(input: string | AgentInputItem[], session: Session): Promise<boolean>;
340
+ }
324
341
  export interface PromptRenderer {
325
342
  render(template: string, context?: PromptContext): Promise<string>;
326
343
  }
@@ -1,5 +1,7 @@
1
1
  export * from './context-protocol';
2
+ export * from './compaction-lineage';
2
3
  export * from './context-host-protocol';
4
+ export * from './mods-bridge';
3
5
  export * from './prompt-context-provider';
4
6
  export * from './prompt-renderer';
5
7
  export * from './context-compact-summarizer';
@@ -0,0 +1,115 @@
1
+ import type { AgentInputItem } from '../../../cbc-shared/node/index.js';
2
+ import type { PromptContext } from './context-protocol';
3
+ export interface ModsPromptSubmitResult {
4
+ text?: string;
5
+ drop?: string;
6
+ }
7
+ /** Host-only provenance: a mod initiated submission has already traversed the fold. */
8
+ export declare const MODS_PROMPT_SUBMITTED_KEY = "modsPromptSubmitted";
9
+ /**
10
+ * Function hooks(Claude mods)在 core 侧的**窄接口**。
11
+ *
12
+ * ## 为什么 core 不直接调 mods
13
+ *
14
+ * `cbc-core` 只允许依赖 `@genie/cbc-shared`(见仓库 CODEBUDDY.md 的单向依赖卡点,
15
+ * `package-boundaries.spec.ts` 会扫源码 import、动态 import 与依赖声明)。而 mods
16
+ * 引擎住在 `cbc-plugins`。所以 core 这一侧只声明「我会在这几个时刻问一句」,具体
17
+ * 分发由宿主实现后注入。
18
+ *
19
+ * ## 为什么形状映射也不在 core
20
+ *
21
+ * cbc 的 `PromptContext` 是一个松散字典,官方 `prompt.context` 事件是
22
+ * `{ blocks, instructionFiles }`。两者的对应关系属于**适配**,而适配是宿主的事 ——
23
+ * 让 core 认识官方 payload 等于把上游协议渗进核心包,将来上游改一次形状,core 就
24
+ * 得跟着改。因此接口按 core 自己的类型说话,桥的实现负责翻译。
25
+ *
26
+ * ## 未注入时必须是零开销
27
+ *
28
+ * function hooks 默认关闭。没有桥时每个调用点只多一次 `=== undefined` 判断,
29
+ * 不构造对象、不进 async、不改变任何既有行为。
30
+ */
31
+ export interface ModsBridge {
32
+ /**
33
+ * 上下文装配完成、尚未拼成最终 prompt 时问一句。
34
+ *
35
+ * @param context 当前这一版上下文
36
+ * @returns 可能被 mod 改写过的上下文;桥自身出问题时应原样返回入参
37
+ */
38
+ promptContext(context: PromptContext): Promise<PromptContext>;
39
+ /**
40
+ * 会话建立时通知一次。
41
+ *
42
+ * @param input 会话 cwd 与是否交互式 —— 官方 `session.start` 的入参
43
+ */
44
+ sessionStart(input: {
45
+ cwd: string;
46
+ isInteractive: boolean;
47
+ }): Promise<void>;
48
+ /**
49
+ * 用户提交输入时问一句。对齐官方 `prompt.submit`。
50
+ *
51
+ * @param input 即将送达模型的文本
52
+ * @returns `{ drop }` 阻断输入,`{ text }` 改写可见文本;附件与隐藏上下文由 core 保留。
53
+ */
54
+ promptSubmit(input: {
55
+ text: string;
56
+ sessionId?: string;
57
+ signal?: AbortSignal;
58
+ }): Promise<ModsPromptSubmitResult | undefined>;
59
+ /**
60
+ * 把一条 mod 打出来的 `$.ui.log` 行落到用户可见的会话里。
61
+ *
62
+ * ## 为什么走桥而不是让 core 直接推消息
63
+ *
64
+ * `$.ui.log` 是 mod 侧发起的用户可见事件(官方语义:进 transcript),但 core
65
+ * 不知道"当前会话"是哪一个(AsyncLocalStorage 上下文由宿主入口决定),也不认
66
+ * `plugin` 这个身份维度(那是 mods 引擎的概念)。宿主拿到这一对
67
+ * `(text, plugin)` 之后,负责取当前 session 并 push 进 `inputSubject` /
68
+ * `combineSubject` / `sessionStore.appendHistory`,就跟宿主自己的系统消息
69
+ * 是同一条路径。
70
+ *
71
+ * ## 未装桥时的兜底在哪
72
+ *
73
+ * 宿主没实现这一项时,`bindings.log` 侧应当把行文继续写到 stderr(headless /
74
+ * bootstrap 早期 / 无当前 session 时用得到)—— 那种场景下用户看不到"消息历史",
75
+ * 但仍能通过日志追溯这一行,与既有行为保持一致。
76
+ *
77
+ * @param text 已由宿主前缀好 `<plugin>: ` 的完整行文(core 不重复加前缀)
78
+ * @param meta 至少携带 `plugin`;用于前端识别 / 分组
79
+ */
80
+ pushModLog?(text: string, meta: {
81
+ plugin: string;
82
+ }): void;
83
+ }
84
+ /**
85
+ * 注入桥。宿主在 mods 运行时起来之后调用一次。
86
+ *
87
+ * @param next 桥实现;传 `undefined` 卸载(测试用)
88
+ */
89
+ export declare function setModsBridge(next: ModsBridge | undefined): void;
90
+ /** 当前桥;未注入时 undefined。 */
91
+ export declare function currentModsBridge(): ModsBridge | undefined;
92
+ /**
93
+ * 经桥过一遍上下文。
94
+ *
95
+ * **桥出问题不能影响主流程**:mod 是第三方代码,它抛错、超时、返回垃圾,都只该
96
+ * 让 function hooks 这一层失效,而不是让会话起不来。因此这里兜住一切异常并回退到
97
+ * 原上下文 —— 与「加载失败不阻塞宿主」同一条原则。
98
+ *
99
+ * @param context 当前上下文
100
+ * @returns 改写后的上下文;无桥或出错时是原对象
101
+ */
102
+ export declare function throughModsPromptContext(context: PromptContext): Promise<PromptContext>;
103
+ /** A failed third-party fold must not corrupt or lose the original input. */
104
+ export declare function throughModsPromptSubmit(text: string, sessionId?: string, signal?: AbortSignal): Promise<ModsPromptSubmitResult | undefined>;
105
+ /** Mutates only user text, before the shared history/model consumers see these items. */
106
+ export declare function applyModsPromptSubmit(items: AgentInputItem[], sessionId: string, signal?: AbortSignal): Promise<string | undefined>;
107
+ /**
108
+ * 通知会话开始。同样绝不向外抛。
109
+ *
110
+ * @param input 会话 cwd 与是否交互式
111
+ */
112
+ export declare function notifyModsSessionStart(input: {
113
+ cwd: string;
114
+ isInteractive: boolean;
115
+ }): Promise<void>;
@@ -4,8 +4,7 @@ import { CompactStrategyContext, ContextCompactSummarizeOptions } from './contex
4
4
  /**
5
5
  * PreMessage 压缩策略:在发送用户消息前触发。
6
6
  *
7
- * 触发条件:PRE_MESSAGE_AUTO 或 WorkBuddy 的 USER_COMMAND。
8
- * CBC 手动 /compact 不走该策略,继续由 compact agent 路径处理。
7
+ * 触发条件:PRE_MESSAGE_AUTO 或 USER_COMMAND(WorkBuddy / TUI 手动压缩)。
9
8
  *
10
9
  * 流程:
11
10
  * 1. Engineering compact (no LLM call)
@@ -30,12 +30,13 @@ export interface FollowupQueueSnapshot {
30
30
  items: FollowupQueueItemView[];
31
31
  }
32
32
  /** ACP `session/steer` 回调。服务不直接碰 ACP,方便单测。 */
33
- export type FollowupSteerFn = (contentBlocks: unknown[]) => Promise<{
33
+ export type FollowupSteerFn = (contentBlocks: unknown[], modsPromptSubmitted?: true) => Promise<{
34
34
  steered: boolean;
35
35
  }>;
36
36
  export interface FollowupQueueService {
37
37
  snapshot(session: Session): FollowupQueueSnapshot;
38
- enqueue(session: Session, contentBlocks: unknown[], hold: boolean): FollowupQueueSnapshot;
38
+ /** modsPromptSubmitted is host-validated provenance, never a client flag. */
39
+ enqueue(session: Session, contentBlocks: unknown[], hold: boolean, modsPromptSubmitted?: true): FollowupQueueSnapshot;
39
40
  remove(session: Session, itemId: string): FollowupQueueSnapshot;
40
41
  /**
41
42
  * 立即发送:能插入当前回合就 `steer` 并从队列拿掉;否则只摘 queueHold。
@@ -23,7 +23,7 @@ export declare class FollowupQueueServiceImpl implements FollowupQueueService {
23
23
  */
24
24
  private readonly pendingBroadcasts;
25
25
  snapshot(session: Session): FollowupQueueSnapshot;
26
- enqueue(session: Session, contentBlocks: unknown[], hold: boolean): FollowupQueueSnapshot;
26
+ enqueue(session: Session, contentBlocks: unknown[], hold: boolean, modsPromptSubmitted?: true): FollowupQueueSnapshot;
27
27
  remove(session: Session, itemId: string): FollowupQueueSnapshot;
28
28
  sendNow(session: Session, itemId: string, steer?: FollowupSteerFn): Promise<FollowupQueueSnapshot>;
29
29
  watch(session: Session): void;
@@ -28,6 +28,8 @@ export declare const SteerInputBuffer: unique symbol;
28
28
  * drain 返回的一组:待插入内容 + 独立对账 id + 客户端不透明 metadata。
29
29
  */
30
30
  export interface SteerDrainedGroup {
31
+ /** Set only after the host validates a one-time mod prompt receipt. */
32
+ readonly modsPromptSubmitted?: true;
31
33
  readonly blocks: unknown[];
32
34
  /** Native, already reviewed messages. Kept by reference for in-memory admission markers. */
33
35
  readonly messages?: readonly UserMessageItem[];
@@ -49,6 +51,8 @@ export interface SteerDrainedGroup {
49
51
  * push 的归属 + 客户端不透明 metadata 入参(合并为一个对象,避免 push 参数过多)。
50
52
  */
51
53
  export interface SteerPushInput {
54
+ /** Server-only provenance, independent of untrusted clientMeta. */
55
+ readonly modsPromptSubmitted?: true;
52
56
  /**
53
57
  * 这组消息归属的请求 id(当前正在执行的 turn 的 requestId);
54
58
  * `undefined` 表示无归属信息(drain 时按「当前也无归属」放行,退化为旧行为)。
@@ -40,6 +40,8 @@ export type PermissionResult = {
40
40
  updatedPermissions?: PermissionUpdate[];
41
41
  toolUseID?: string;
42
42
  decisionClassification?: PermissionDecisionClassification;
43
+ /** Optional host response metadata; interpreted only by the requesting tool. */
44
+ metadata?: Record<string, unknown>;
43
45
  } | {
44
46
  behavior: 'deny';
45
47
  message: string;
@@ -68,6 +70,8 @@ export interface CanUseToolOptions {
68
70
  displayName?: string;
69
71
  /** 桥端渲染的副标题说明。 */
70
72
  description?: string;
73
+ /** Tool-provided display/context metadata for host permission UIs. Not an authorization grant. */
74
+ metadata?: Record<string, unknown>;
71
75
  /** 本次工具调用在 assistant 消息内的唯一 id。 */
72
76
  toolUseID: string;
73
77
  /** 子代理上下文中触发时,子代理的 id。 */
@@ -36,6 +36,7 @@ export * from './stream-timeout-retry-budget';
36
36
  export { consumeRecoveryRequestPending } from './recovery-budget';
37
37
  export * from './session-run-state-machine-protocol';
38
38
  export * from './session-run-state-machine';
39
+ export * from './model-request-retry-phase';
39
40
  export * from './session-run-state-projection-service';
40
41
  export * from './local-jsonl-session-store';
41
42
  export * from './transcript-branch';
@@ -93,6 +93,13 @@ export declare class InterruptionServiceImpl implements InterruptionService {
93
93
  protected readonly idleQueueDrainService?: IIdleQueueDrainService;
94
94
  protected readonly traceCollector?: SessionInterruptionTraceHost;
95
95
  protected get startupProfiler(): SessionInterruptionProfilerHost;
96
+ /**
97
+ * 标记「用户取消本轮」的拒绝项(`reject(item, { cancelTurn: true })`)。
98
+ * 语义是取消当前 turn,而不是「拒绝并让模型带反馈续跑」。
99
+ * 记在 WeakSet 而不是 `rawItem.providerData`(那会落进历史),也不改
100
+ * deferred 的 reject 形状(下游按 error 类型分支的逻辑保持不变)。
101
+ */
102
+ private readonly cancelTurnItems;
96
103
  /** Claim before calling out: sandbox callbacks can throw or synchronously re-enter. */
97
104
  private takeSandboxResolve;
98
105
  approve(item: RunToolApprovalItem, options?: {
@@ -101,6 +108,7 @@ export declare class InterruptionServiceImpl implements InterruptionService {
101
108
  }): void;
102
109
  reject(item: RunToolApprovalItem, options?: {
103
110
  decision?: 'deny' | 'rejectAndExitPlan';
111
+ cancelTurn?: boolean;
104
112
  }): void;
105
113
  /**
106
114
  * 取消指定 session 上所有未决的 interruption Deferred。
@@ -0,0 +1,16 @@
1
+ import type { AgentRetryReason, Session } from './session-protocol';
2
+ import { ModelRequestRetryPhase, SessionRunStateMachine } from './session-run-state-machine-protocol';
3
+ export declare class ModelRequestRetryPhaseImpl implements ModelRequestRetryPhase {
4
+ protected readonly stateMachine: SessionRunStateMachine;
5
+ during<T>(session: Session | undefined, reason: AgentRetryReason, wait: () => Promise<T>): Promise<T>;
6
+ /**
7
+ * 辅助型调用复用主 session 却不回送 AGENT_ENDED(#52320),不得驱动其状态;
8
+ * 状态已离开 MODEL_REQUESTING 说明另有路径在推进,此时不抢写。
9
+ */
10
+ private enter;
11
+ /**
12
+ * 必须回到 MODEL_REQUESTING:RETRYING 不接收 TOOL_STARTED / MODEL_RESPONSE_DONE 等后续事件,
13
+ * 停留会让错误处理路径的转换被静默忽略。已被取消等事件推走时不再改写。
14
+ */
15
+ private leave;
16
+ }
@@ -215,6 +215,21 @@ export declare class MediaContentErrorInterceptor implements ModelResponseInterc
215
215
  private static readonly MAX_RETRY_ATTEMPTS;
216
216
  private static readonly MAX_MIME_MISMATCH_RETRY_ATTEMPTS;
217
217
  private static readonly GIF_UNSUPPORTED_ERROR_CODES;
218
+ /**
219
+ * Gateway business codes that mean "the model refused the images in this
220
+ * request" (`11135 InvalidInputImage`).
221
+ *
222
+ * The code is the only stable signal. The gateway folds several unrelated
223
+ * upstream causes into one hard-coded English sentence and overwrites the
224
+ * upstream text, so `ERROR_TYPE_PATTERNS` matching that sentence breaks the
225
+ * moment the wording is changed or localized (`docs/error-codes.md` already
226
+ * ships a Chinese user-facing string for this code). The code is carried on
227
+ * the error object all the way here — `error-analyzer` puts the parsed body
228
+ * code into the response, the SDK surfaces it as `APIError.error.code`, and
229
+ * `ErrorUtils.extractBizCode` recovers it — so key off it and keep the
230
+ * phrasing match only as a fallback for gateways that send no code.
231
+ */
232
+ private static readonly IMAGE_REJECTED_ERROR_CODES;
218
233
  private static readonly GIF_UNSUPPORTED_PLACEHOLDER;
219
234
  private static readonly ERROR_TYPE_PATTERNS;
220
235
  intercept(ctx: ModelResponseInterceptorContext): Promise<boolean | void>;