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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/cli/CHANGELOG.md +71 -0
  4. package/cli/dist-server/shared.cjs +318 -314
  5. package/cli/dist-server/types/node/acp/acp-protocol.d.ts +40 -12
  6. package/cli/dist-server/types/node/acp/usage-by-category-calculator.d.ts +21 -0
  7. package/cli/dist-server/types/node/cli/stream-json-protocol.d.ts +15 -1
  8. package/cli/dist-server/types/node/data-fs/index.d.ts +13 -1
  9. package/cli/dist-server/types/node/hooks/hook-protocol.d.ts +2 -2
  10. package/cli/dist-server/types/node/server/sessions.d.ts +24 -0
  11. package/cli/dist-server/types/node/server/types.d.ts +6 -0
  12. package/cli/dist-server/types/node/settings/settings-protocol.d.ts +5 -0
  13. package/cli/dist-server/types/node/tools/tool-protocol.d.ts +112 -2
  14. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-protocol.d.ts +29 -0
  15. package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-service.d.ts +2 -0
  16. package/cli/dist-server/types/vendor/cbc-core/node/agent/index.d.ts +1 -0
  17. package/cli/dist-server/types/vendor/cbc-core/node/agent/interceptors/input-interceptors.d.ts +1 -6
  18. package/cli/dist-server/types/vendor/cbc-core/node/agent/runner-factory.d.ts +31 -11
  19. package/cli/dist-server/types/vendor/cbc-core/node/agent/speaker-label.d.ts +44 -0
  20. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-detector-service.d.ts +5 -4
  21. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  22. package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-pattern.d.ts +15 -4
  23. package/cli/dist-server/types/vendor/cbc-core/node/hooks/agent-trigger.d.ts +6 -22
  24. package/cli/dist-server/types/vendor/cbc-core/node/hooks/hook-protocol.d.ts +4 -1
  25. package/cli/dist-server/types/vendor/cbc-core/node/session/idle-queue-drain-service.d.ts +4 -56
  26. package/cli/dist-server/types/vendor/cbc-core/node/session/index.d.ts +3 -0
  27. package/cli/dist-server/types/vendor/cbc-core/node/session/interruption-service.d.ts +55 -9
  28. package/cli/dist-server/types/vendor/cbc-core/node/session/model-response-interceptors.d.ts +18 -0
  29. package/cli/dist-server/types/vendor/cbc-core/node/session/recovery-budget.d.ts +55 -0
  30. package/cli/dist-server/types/vendor/cbc-core/node/session/session-hook-manager.d.ts +15 -0
  31. package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager.d.ts +10 -1
  32. package/cli/dist-server/types/vendor/cbc-core/node/session/session-persistence-error.d.ts +43 -0
  33. package/cli/dist-server/types/vendor/cbc-core/node/session/session-protocol.d.ts +63 -4
  34. package/cli/dist-server/types/vendor/cbc-core/node/session/session-run-state-machine-protocol.d.ts +1 -0
  35. package/cli/dist-server/types/vendor/cbc-core/node/session/session-runtime-lifecycle.d.ts +5 -0
  36. package/cli/dist-server/types/vendor/cbc-core/node/session/session-store.d.ts +150 -4
  37. package/cli/dist-server/types/vendor/cbc-core/node/session/stream-timeout-retry-budget.d.ts +13 -1
  38. package/cli/dist-server/types/vendor/cbc-core/node/utils/history-utils.d.ts +23 -0
  39. package/cli/dist-server/types/vendor/cbc-core/node/utils/index.d.ts +1 -0
  40. package/cli/dist-server/types/vendor/cbc-core/node/utils/message-utils.d.ts +12 -0
  41. package/cli/dist-server/types/vendor/cbc-core/node/utils/model-utils.d.ts +7 -0
  42. package/cli/dist-server/types/vendor/cbc-core/node/utils/queue-dispatch-utils.d.ts +24 -2
  43. package/cli/dist-server/types/vendor/cbc-core/node/utils/session-utils.d.ts +4 -1
  44. package/cli/dist-server/types/vendor/cbc-core/node/utils/string-retention-utils.d.ts +4 -0
  45. package/cli/dist-server/types/vendor/cbc-shared/node/hooks/hook-types.d.ts +7 -1
  46. package/cli/dist-server/types/vendor/cbc-shared/node/index.d.ts +2 -0
  47. package/cli/dist-server/types/vendor/cbc-shared/node/model/model-errors.d.ts +7 -3
  48. package/cli/dist-server/types/vendor/cbc-shared/node/tools/tool-names.d.ts +1 -0
  49. package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-backoff.d.ts +30 -0
  50. package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-policy.d.ts +26 -0
  51. package/cli/dist-server/types/workspace/authentication/lib/common/account-scoped-external-link-authentication-provider.d.ts +2 -2
  52. package/cli/dist-server/types/workspace/authentication/lib/common/account-utils.d.ts +25 -0
  53. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-manager.d.ts +2 -2
  54. package/cli/dist-server/types/workspace/authentication/lib/common/authentication-protocol.d.ts +19 -2
  55. package/cli/dist-server/types/workspace/authentication/lib/common/external-link-authentication-provider.d.ts +2 -2
  56. package/cli/dist-server/types/workspace/authentication/lib/common/wx-authentication-provider.d.ts +2 -2
  57. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-protocol.d.ts +29 -0
  58. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-service.d.ts +2 -0
  59. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/index.d.ts +1 -0
  60. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/interceptors/input-interceptors.d.ts +1 -6
  61. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/runner-factory.d.ts +31 -11
  62. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/speaker-label.d.ts +44 -0
  63. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-detector-service.d.ts +5 -4
  64. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
  65. package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-pattern.d.ts +15 -4
  66. package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/agent-trigger.d.ts +6 -22
  67. package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/hook-protocol.d.ts +4 -1
  68. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/idle-queue-drain-service.d.ts +4 -56
  69. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/index.d.ts +3 -0
  70. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/interruption-service.d.ts +55 -9
  71. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/model-response-interceptors.d.ts +18 -0
  72. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/recovery-budget.d.ts +55 -0
  73. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-hook-manager.d.ts +15 -0
  74. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager.d.ts +10 -1
  75. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-persistence-error.d.ts +43 -0
  76. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-protocol.d.ts +63 -4
  77. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-run-state-machine-protocol.d.ts +1 -0
  78. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-runtime-lifecycle.d.ts +5 -0
  79. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-store.d.ts +150 -4
  80. package/cli/dist-server/types/workspace/cbc-core/lib/node/session/stream-timeout-retry-budget.d.ts +13 -1
  81. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/history-utils.d.ts +23 -0
  82. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/index.d.ts +1 -0
  83. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/message-utils.d.ts +12 -0
  84. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/model-utils.d.ts +7 -0
  85. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/queue-dispatch-utils.d.ts +24 -2
  86. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/session-utils.d.ts +4 -1
  87. package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/string-retention-utils.d.ts +4 -0
  88. package/cli/dist-server/types/workspace/cbc-shared/lib/node/hooks/hook-types.d.ts +7 -1
  89. package/cli/dist-server/types/workspace/cbc-shared/lib/node/index.d.ts +2 -0
  90. package/cli/dist-server/types/workspace/cbc-shared/lib/node/model/model-errors.d.ts +7 -3
  91. package/cli/dist-server/types/workspace/cbc-shared/lib/node/tools/tool-names.d.ts +1 -0
  92. package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-backoff.d.ts +30 -0
  93. package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-policy.d.ts +26 -0
  94. package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-execution.d.ts +14 -1
  95. package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-manager.d.ts +7 -0
  96. package/cli/dist-server/types/workspace/cbc-worktree/lib/node/worktree/worktree-session.d.ts +3 -0
  97. package/cli/dist-server/types/workspace/product/lib/common/cloud-product-provider.d.ts +9 -0
  98. package/cli/dist-server/types/workspace/product/lib/common/index.d.ts +1 -0
  99. package/cli/dist-server/types/workspace/product/lib/common/pick-market-skill-id.d.ts +13 -0
  100. package/cli/dist-server/types/workspace/product/lib/common/tool-control-catalog.d.ts +2 -2
  101. package/cli/dist-server/types/workspace/product/lib/common/types/features.d.ts +62 -2
  102. package/cli/dist-server/types/workspace/product/lib/common/types/language-model.d.ts +66 -0
  103. package/cli/dist-server/types/workspace/product/lib/common/types/product.d.ts +7 -1
  104. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/backup-policy.d.ts +10 -1
  105. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/center-protocol.generated.d.ts +370 -4
  106. package/cli/dist-server/types/workspace/sandbox-cli/lib/common/file-policy.d.ts +1 -1
  107. package/cli/dist-server/types/workspace/sandbox-cli/lib/node/sandbox-center-client.d.ts +216 -0
  108. package/cli/package.json +1 -1
  109. package/cli/product.cloudhosted.json +2 -2
  110. package/cli/product.internal.json +259 -40
  111. package/cli/product.ioa.json +333 -148
  112. package/cli/product.json +309 -351
  113. package/cli/product.selfhosted.json +2 -2
  114. package/docs/README.md +1 -0
  115. package/docs/in-process.md +16 -0
  116. package/lib/application/services.d.ts +3 -1
  117. package/lib/application/services.js +1 -1
  118. package/lib/components/sandbox-center.d.mts +2 -0
  119. package/lib/components/sandbox-center.mjs +1 -0
  120. package/lib/components/session-config.d.mts +2 -0
  121. package/lib/components/session-config.mjs +1 -1
  122. package/lib/harness/create-harness.js +1 -1
  123. package/lib/harness/runtime.js +1 -1
  124. package/lib/harness/types.d.ts +3 -0
  125. package/lib/integration/executor-supervisor.js +1 -1
  126. package/lib/public.d.ts +1 -0
  127. package/lib/runtime/sandbox-center.d.ts +21 -0
  128. package/lib/runtime/sandbox-center.js +1 -0
  129. package/lib/server/public.d.ts +1 -0
  130. package/lib/session/agent-backend.d.ts +2 -0
  131. package/lib/session/agent-backend.js +1 -1
  132. package/lib/session/local-fs.js +1 -1
  133. package/lib/session/server-config.js +1 -1
  134. package/lib/session/server-interactions.js +1 -1
  135. package/package.json +25 -15
  136. package/lib/session/local-options.d.ts +0 -50
  137. package/lib/session/local-options.js +0 -1
@@ -2,7 +2,7 @@ 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
4
  import { Logger } from '../../../telemetry/lib/common/index.js';
5
- import { Account, APIResult, AuthenticationProvider, AuthSession, AuthState, AuthToken, LoginContext, ProductEnvService, SignContext } from './authentication-protocol.js';
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.
8
8
  *
@@ -26,7 +26,7 @@ export declare class AccountScopedExternalLinkAuthenticationProvider implements
26
26
  checkNetworkConnectivity(): Promise<APIResult<boolean>>;
27
27
  createSession(ctx: SignContext): Promise<AuthSession>;
28
28
  refreshSession(session: AuthSession, ctx: SignContext): Promise<AuthSession>;
29
- removeSession(): Promise<void>;
29
+ removeSession(_session?: AuthSession, _options?: LogoutOptions): Promise<void>;
30
30
  switchAccount(account: Account, authSession: AuthSession, ctx: SignContext): Promise<AuthSession>;
31
31
  private toSessionAccountLists;
32
32
  protected openAuthUrl(authState: AuthState): Promise<void>;
@@ -51,4 +51,29 @@ export declare function mergeCurrentAccountDetails(account: Account, accounts: A
51
51
  * 仅以账号类型为准,不用 enterpriseId 反推,避免 unknown/legacy account 被误判。
52
52
  */
53
53
  export declare function isPersonalAccount(account?: Pick<Account, 'type'>): boolean;
54
+ /**
55
+ * 判断账号是否属于「个人版」这一**商业化版本**(个人版 + 个人版已订阅 Pro)。
56
+ *
57
+ * 与 {@link isPersonalAccount} 的区别,调用前请先确认要哪一个:
58
+ * - `isPersonalAccount`:严格的类型判定,只认 `type === 'personal'`,用于需要区分
59
+ * 「免费个人版」与其它一切档位的场景(如 IOA 请求头是否补默认企业 ID)。
60
+ * - `isPersonalEditionAccount`(本函数):版本归属判定,把 `pro`(「个人版已订阅 Pro」,
61
+ * 见 agent-provider `types.ts` 的 Edition 注释)也算进个人版,用于「个人版专属功能」
62
+ * 门禁——把付费个人用户挡在个人版功能外不符合产品预期。
63
+ *
64
+ * 判定采用**反向排除**而非 type 白名单,原因是 `Account.type` 在协议层仅声明为 `string`,
65
+ * 完全透传后端 `/console/accounts`,前端不做任何映射校正:
66
+ * - 历史上出现过空串 type,白名单写法会把付费账号整块漏掉(见 agent-provider
67
+ * `backend-provider.ts:getEditionDisplayType` 的同款踩坑注释);反向排除对未知值
68
+ * 降级为「个人版」,与该处「其余(含 type 为空串 / 未知值)按个人账号推导」一致。
69
+ * - `enterpriseId` 非空一律视为企业租户:它是 enterprise-policy 包区分
70
+ * personal / enterprise 的唯一依据(`bypass-personal` 语义),也是现有 4 处
71
+ * `isPersonalAccount()` 调用统一叠加 `&& !enterpriseId` 的原因。这样即便后端返回
72
+ * `type=personal` + 非空 enterpriseId(IOA 个人账号即属此类),也不会误放行。
73
+ *
74
+ * **未登录(`account` 为空)返回 `false`**:此时无从判断版本归属,不能因为「查不到企业
75
+ * 特征」就当成个人版放行个人版专属能力。这与上面对「已登录但 type 未知」降级为个人版
76
+ * 是两件事——后者至少确认了不是企业租户。
77
+ */
78
+ export declare function isPersonalEditionAccount(account?: Pick<Account, 'type' | 'enterpriseId'>): boolean;
54
79
  export {};
@@ -5,7 +5,7 @@ import { AuthenticationType, ProductManager } from '../../../product/lib/common/
5
5
  import { Notifier } from '../../../runtime/lib/common/index.js';
6
6
  import { EventService, Logger, TraceService } from '../../../telemetry/lib/common/index.js';
7
7
  import { BehaviorSubject } from 'rxjs';
8
- import { Account, APIResult, AuthenticationManager, AuthenticationProvider, type AuthenticationStartupGate as IAuthenticationStartupGate, AuthenticationStorage, AuthSession, LoginContext, type PrewarmActivationGate as IPrewarmActivationGate, ProductEnvService } from './authentication-protocol.js';
8
+ import { Account, APIResult, AuthenticationManager, AuthenticationProvider, type AuthenticationStartupGate as IAuthenticationStartupGate, AuthenticationStorage, AuthSession, LoginContext, LogoutOptions, type PrewarmActivationGate as IPrewarmActivationGate, ProductEnvService } from './authentication-protocol.js';
9
9
  /**
10
10
  * 注入 doInit 二级探针 sink。仅供 daemon 装配层调用,把 [AuthDoInitProbe] 复制一路
11
11
  * 落到 daemon.log;main.log 主 sink 走 celljs Logger 不受影响。
@@ -97,7 +97,7 @@ export declare class AuthenticationManagerImpl implements AuthenticationManager
97
97
  cancelLogin(): void;
98
98
  private clearLastAuthUrl;
99
99
  login(ctx?: LoginContext): Promise<boolean>;
100
- logout(): Promise<void>;
100
+ logout(options?: LogoutOptions): Promise<void>;
101
101
  refreshSession(): Promise<void>;
102
102
  waitForSessionRefresh(): Promise<void>;
103
103
  refreshSessionForAuthenticationFailure(): Promise<AuthSession>;
@@ -159,12 +159,29 @@ export interface AuthDevice {
159
159
  expiresIn: number;
160
160
  interval: number;
161
161
  }
162
+ /**
163
+ * Options shared by the logout decision point (`AuthenticationManager.logout`)
164
+ * and the provider hook (`AuthenticationProvider.removeSession`).
165
+ */
166
+ export interface LogoutOptions {
167
+ /**
168
+ * Whether to revoke the session on the server (call the server logout
169
+ * endpoint) in addition to clearing local state.
170
+ *
171
+ * Only user-initiated ("manual") logout should set this to `true`. Passive
172
+ * logout (e.g. auto-logout triggered by a 401 on an auth verification path)
173
+ * must leave it `false`/unset: at that point the token is already rejected
174
+ * by the server and the endpoint/refresh-token context is unreliable, so a
175
+ * server revoke call would be useless noise. Defaults to `false`.
176
+ */
177
+ revokeServerSession?: boolean;
178
+ }
162
179
  export interface AuthenticationProvider {
163
180
  getAuthenticationType(): Promise<AuthenticationType[]>;
164
181
  support(ctx?: LoginContext): Promise<boolean>;
165
182
  createSession(ctx: SignContext): Promise<AuthSession>;
166
183
  refreshSession(session: AuthSession, ctx: SignContext): Promise<AuthSession>;
167
- removeSession(session: AuthSession): Promise<void>;
184
+ removeSession(session: AuthSession, options?: LogoutOptions): Promise<void>;
168
185
  switchAccount(account: Account, authSession: AuthSession, ctx: SignContext): Promise<AuthSession>;
169
186
  checkNetworkConnectivity?(): Promise<APIResult<boolean>>;
170
187
  }
@@ -217,7 +234,7 @@ export interface AuthenticationManager {
217
234
  currentSessionSubject: BehaviorSubject<AuthSession | undefined>;
218
235
  login(ctx?: LoginContext): Promise<boolean>;
219
236
  cancelLogin(): void;
220
- logout(): Promise<void>;
237
+ logout(options?: LogoutOptions): Promise<void>;
221
238
  refreshSession(): Promise<void>;
222
239
  waitForSessionRefresh(): Promise<void>;
223
240
  /** Force one authoritative, singleflight refresh after an auth failure. */
@@ -2,7 +2,7 @@ import { RestOperations } from '@celljs/http';
2
2
  import { AuthenticationType, ClientInfoProvider, ProductManager } from '../../../product/lib/common/index.js';
3
3
  import { ExternalUriOpener } from '../../../runtime/lib/common/index.js';
4
4
  import { Logger } from '../../../telemetry/lib/common/index.js';
5
- import { Account, APIResult, AuthenticationProvider, AuthSession, LoginContext, ProductEnvService, SignContext, SignLicenseError } from './authentication-protocol.js';
5
+ import { Account, APIResult, AuthenticationProvider, AuthSession, LoginContext, LogoutOptions, ProductEnvService, SignContext, SignLicenseError } from './authentication-protocol.js';
6
6
  /** 登录漏斗步骤回调,由外部消费者(如 workbuddy-server)注入上报逻辑。 */
7
7
  export type LoginStepCallback = (step: string, dims: Record<string, string>) => void;
8
8
  /**
@@ -55,7 +55,7 @@ export declare class ExternalLinkAuthenticationProvider implements Authenticatio
55
55
  getAuthenticationType(): Promise<AuthenticationType[]>;
56
56
  createSession(ctx: SignContext): Promise<AuthSession>;
57
57
  refreshSession(session: AuthSession, ctx: SignContext): Promise<AuthSession>;
58
- removeSession(): Promise<void>;
58
+ removeSession(session?: AuthSession, options?: LogoutOptions): Promise<void>;
59
59
  switchAccount(account: Account, authSession: AuthSession, ctx: SignContext): Promise<AuthSession>;
60
60
  private fetchAuthState;
61
61
  protected openAuthUrl(authState: AuthState): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { Logger } from '@celljs/core';
2
2
  import { RestOperations } from '@celljs/http';
3
3
  import { AuthenticationType, ProductManager } from '../../../product/lib/common/index.js';
4
- import { Account, AuthenticationProvider, AuthSession, SignContext } from './authentication-protocol.js';
4
+ import { Account, AuthenticationProvider, AuthSession, LogoutOptions, SignContext } from './authentication-protocol.js';
5
5
  export declare class WxAuthenticationProvider implements AuthenticationProvider {
6
6
  protected readonly restOperations: RestOperations;
7
7
  protected readonly productManager: ProductManager;
@@ -12,7 +12,7 @@ export declare class WxAuthenticationProvider implements AuthenticationProvider
12
12
  getAuthenticationType(): Promise<AuthenticationType[]>;
13
13
  createSession(ctx: SignContext): Promise<AuthSession>;
14
14
  refreshSession(session: AuthSession, ctx: SignContext): Promise<AuthSession>;
15
- removeSession(): Promise<void>;
15
+ removeSession(_session?: AuthSession, _options?: LogoutOptions): Promise<void>;
16
16
  switchAccount(account: Account, authSession: AuthSession, ctx: SignContext): Promise<AuthSession>;
17
17
  private fetchTokenByTmpCode;
18
18
  private fetchAccounts;
@@ -179,6 +179,12 @@ export declare function isBuiltinDisableableAgent(agentName: string): boolean;
179
179
  * waste prompt tokens on a tool they can never legitimately call (the SendMessage
180
180
  * tool itself returns an error when invoked outside a team context), and for
181
181
  * structured-output agents like `compact` it can pollute the model's output.
182
+ *
183
+ * **这些名字是保留字,不得被用作子代理 / teammate 预设名**(评审 #128343):
184
+ * `resolveMessageSpeakerLabel` 把本名单的判定放在「子会话报自身身份」**之前**,因为历史与
185
+ * 用量多处按 `providerData.agent === 'compact'` 这类字符串比较判定,子会话里跑 compact 时
186
+ * 不能被身份名覆盖。反过来说,一旦有真实子代理取了这里的名字,它的消息会被标成生成器名
187
+ * 而不是自己的身份 —— 属于要靠人眼才能发现的错标。新增名字前先确认它不会与任何预设名撞。
182
188
  */
183
189
  export declare const INTERNAL_GENERATOR_AGENTS: Set<string>;
184
190
  /**
@@ -289,6 +295,13 @@ export interface AgentManager {
289
295
  * 同输入逐轮返回同一对象(prompt cache 稳定);视图字节永不写回全局物化面。
290
296
  */
291
297
  sessionScopedAgentView(session: Session, base: Agent): Promise<Agent>;
298
+ /**
299
+ * sandbox-agent-view:把 REPL 的动态 schema 按子代理身份重新物化一遍。Code Mode 的
300
+ * agent 实例进程级共享(`get('ptc')` 命中同一对象),schema 在构建期用合成会话采集 ——
301
+ * 继承模式的子代理(Explore 等)会看到模式的全量目录。派发侧知道身份,经此覆盖。
302
+ * 只克隆 REPL 一个工具,视图不进 agentMap;空身份 / 同名 / 无 REPL 时原样返回基座。
303
+ */
304
+ sandboxScopedAgentView(base: Agent, sandboxAgentName: string): Promise<Agent>;
292
305
  /** served 激活链的视图预热(默认 agent),派发路径是失效兜底。 */
293
306
  prepareSessionAgentView(session: Session): Promise<void>;
294
307
  get(agentName: string): Promise<Agent | undefined>;
@@ -543,6 +556,16 @@ export type AgentStandardRunOptions<TContext = Session> = AgentSdkRunOptions<TCo
543
556
  /** Process-local provenance for fresh user turns; stripped before SDK dispatch. */
544
557
  inputOrigin?: AgentRunOrigin;
545
558
  continuation?: never;
559
+ /**
560
+ * Per-arrival out-signal: invoked when this run was routed to the message
561
+ * queue (skipRun, session busy) instead of executing now. Callers that owe
562
+ * their caller *this* prompt's own result (print / stream-json) use it to
563
+ * keep waiting until the queue drains and their turn actually runs.
564
+ *
565
+ * A run-scoped callback (not a shared session flag) so concurrent arrivals
566
+ * cannot clobber each other's outcome.
567
+ */
568
+ onEnqueued?: () => void;
546
569
  };
547
570
  /**
548
571
  * Explicitly claim the current process-local logical turn.
@@ -558,6 +581,10 @@ export type AgentCurrentContinuationOptions = AgentSdkRunOptions<Session> & Agen
558
581
  };
559
582
  export type AgentServiceRunOptions<TContext = Session> = AgentStandardRunOptions<TContext> | AgentCurrentContinuationOptions;
560
583
  export interface AgentService {
584
+ /** Atomically close a task's runtime only after its last result and queued work settle. */
585
+ tryCloseTaskSession?(session: Session, result: NonNullable<Session['resultSubject']['value']>): Promise<boolean>;
586
+ /** Stop accepting task work and join its physical runs before releasing dependencies. */
587
+ retireTaskSession?(session: Session): Promise<void>;
561
588
  run<TAgent extends Agent<any, any>>(agent: TAgent, input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
562
589
  run<TAgent extends Agent<any, any>, TContext = Session>(agent: TAgent, input: string | AgentInputItem[] | RunState<TContext, TAgent>, options?: AgentStandardRunOptions<TContext>): Promise<void>;
563
590
  runDefault<TAgent extends Agent<any, any>>(input: string | AgentInputItem[], options: AgentCurrentContinuationOptions): Promise<void>;
@@ -779,6 +806,8 @@ export declare enum CustomAgentSavePath {
779
806
  }
780
807
  export declare enum OutputStyleType {
781
808
  DEFAULT = "default",
809
+ PROACTIVE = "proactive",
810
+ CONCISE = "concise",
782
811
  EXPLANATORY = "explanatory",
783
812
  LEARNING = "learning"
784
813
  }
@@ -38,6 +38,8 @@ export declare class AgentServiceImpl implements AgentService {
38
38
  */
39
39
  private lifecycleOwners;
40
40
  protected getLifecycleOwners(): WeakMap<Session, AbortController>;
41
+ tryCloseTaskSession(session: Session, result: NonNullable<Session['resultSubject']['value']>): Promise<boolean>;
42
+ retireTaskSession(session: Session): Promise<void>;
41
43
  /** compare-and-delete:仅当 token 仍指向本轮 controller 时清除。 */
42
44
  private clearLifecycleOwner;
43
45
  /** 本轮是否是当前 lifecycle owner。 */
@@ -6,6 +6,7 @@ export * from './agent-service.js';
6
6
  export * from './agent-factory.js';
7
7
  export * from './runner-factory.js';
8
8
  export * from './runner-provider.js';
9
+ export * from './speaker-label.js';
9
10
  export * from './ordered-tools-agent.js';
10
11
  export * from './tool-call-loop-detector-protocol.js';
11
12
  export * from './tool-call-loop-detector-service.js';
@@ -17,12 +17,7 @@ export declare class MessageQueueAgentRunInterceptor implements AgentRunIntercep
17
17
  protected readonly logger: Logger;
18
18
  protected readonly stateMachine: SessionRunStateMachine;
19
19
  intercept(request: AgentRunRequest): Promise<void>;
20
- /**
21
- * 触发后不再重复打 error(防日志风暴);下次"有实际工作"分支复位 counter/flag,
22
- * session 自动恢复处理能力。
23
- */
24
- private trackEmptyDrainAndMaybeTripGuard;
25
- private resetEmptyDrainLoopGuard;
20
+ private consumeQueueItems;
26
21
  }
27
22
  /**
28
23
  * 用户查询包裹拦截器
@@ -1,4 +1,4 @@
1
- import { type RunConfig, Runner } from '../../../../cbc-shared/lib/node/index.js';
1
+ import { type AgentInputItem, type RunConfig, Runner } from '../../../../cbc-shared/lib/node/index.js';
2
2
  import { ProductManager } from '../../../../product/lib/common/index.js';
3
3
  import { Logger } from '../../../../telemetry/lib/common/index.js';
4
4
  import { type NotificationInjectionBuffer as INotificationInjectionBuffer } from '../message-queue/notification-injection-buffer-protocol.js';
@@ -15,6 +15,15 @@ import { ToolCallLoopDetector } from './tool-call-loop-detector-protocol.js';
15
15
  * Used by finishReasonErrorInterceptor to detect prior retries across both mechanisms.
16
16
  */
17
17
  export declare const TRUNCATION_RETRY_MARKER = "Do NOT repeat the same oversized tool call. Break it into smaller operations.";
18
+ export interface ModelInputMemoryPressure {
19
+ heapUsed: number;
20
+ heapLimit: number;
21
+ headroom: number;
22
+ inputItems: number;
23
+ estimatedInputBytes?: number;
24
+ reject: boolean;
25
+ }
26
+ export declare function assessModelInputMemoryPressure(input: AgentInputItem[], heapUsed?: number, heapLimit?: number): ModelInputMemoryPressure;
18
27
  /**
19
28
  * Tool-specific hints for how to decompose a truncated tool call into smaller operations.
20
29
  */
@@ -72,6 +81,7 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
72
81
  */
73
82
  protected readonly acpBroadcastService?: AgentQueueOutput;
74
83
  create(config?: Partial<RunConfig>): Promise<Runner>;
84
+ private assertModelInputCloneHeadroom;
75
85
  /**
76
86
  * 在每次模型请求前检查是否需要自动压缩。
77
87
  * 此时所有工具都已执行完毕,可以安全地触发压缩。
@@ -211,10 +221,10 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
211
221
  * model / agent / argumentsDisplayText 等键同样会跟着走,它们是惰性字段、上游不解读,
212
222
  * 这里不做处理;真正需要清掉的只有语义已经反转的 discard。
213
223
  *
214
- * 改写与删标记都只作用于当轮副本(见 filterTruncatedToolCalls 的
215
- * "Scope of the rewrite"),session.history 里的原值保持不变。
224
+ * 返回一个浅复制的新 item;providerData 仅在需要删除 discard 时 copy-on-write。
225
+ * session.history 与 SDK 传入的原 item 始终保持不变。
216
226
  */
217
- private rewriteCallArguments;
227
+ private withRewrittenCallArguments;
218
228
  /**
219
229
  * SDK callModelInputFilter: called before every model API request within the SDK run loop.
220
230
  *
@@ -240,13 +250,23 @@ export declare class RunnerFactoryImpl implements RunnerFactory {
240
250
  * message instructing the model to break the call into smaller operations. This
241
251
  * turns the SDK's automatic retry into a valid, useful request.
242
252
  *
243
- * Scope of the rewrite: `agents-core`'s `applyCallModelInputFilter` hands us a
244
- * `structuredClone` of the turn input and clones our return value again, explicitly so
245
- * that filter-side mutations cannot touch cached turn state. So every rewrite here
246
- * lands on a per-turn copy only — `session.history` keeps the malformed arguments and
247
- * we redo the same rewrite on every subsequent turn. That is correct but not free:
248
- * anything reported from this path must be aggregated per turn rather than logged per
249
- * call, or a long session with N bad calls emits N log lines every turn.
253
+ * Scope of the rewrite: this filter opts into the SDK's `preserveInputIdentity` mode,
254
+ * so existing history items arrive by identity and MUST remain immutable. Repairs use
255
+ * item-level copy-on-write and array-level shallow copies; the SDK still creates isolated
256
+ * model/session copies after the filter returns. `session.history` therefore keeps the
257
+ * malformed arguments and we redo the same rewrite on every subsequent turn. Anything
258
+ * reported from this path must be aggregated per turn rather than logged per call.
259
+ */
260
+ /**
261
+ * 模型输入的两步修复,**顺序不能反**:
262
+ *
263
+ * 1. `filterTruncatedToolCalls` 先跑。截断(finish_reason=length)与坏 JSON 的
264
+ * call 正是「参数半截 + 没有任何 result」那一类;它删掉这些 call 的同时会注入
265
+ * 拆解引导与防循环停止标记。若先按配对摘掉它们,该分支因 `invalidCallIds` 为空
266
+ * 直接早退,模型拿不到任何引导,退回 #75892 那条老路,而且请求本身合法、无错可见。
267
+ * 2. `filterUnpairedToolCalls` 后跑,收掉剩下的孤儿(参数合法但结果丢失、重复 callId、
268
+ * 头部被截断留下的孤儿结果)。本地正文里的孤儿是持久化的,留着每次恢复都被上游 400。
250
269
  */
270
+ private repairModelInput;
251
271
  private filterTruncatedToolCalls;
252
272
  }
@@ -0,0 +1,44 @@
1
+ export declare function resolveMessageSpeakerLabel(input: {
2
+ session?: {
3
+ id?: string;
4
+ storeId?: string;
5
+ meta?: Record<string, unknown>;
6
+ } | undefined;
7
+ runAgentName?: string;
8
+ }): string | undefined;
9
+ /**
10
+ * 子会话的**展示名**(给人看):团队成员用成员名,其余子代理用自身预设名(`meta.agentName`);
11
+ * 主会话 / 无会话 / 无身份线索返回 undefined。**只用于展示与遥测标签,不要拿它查表。**
12
+ */
13
+ export declare function resolveSubAgentDisplayName(session: {
14
+ id?: string;
15
+ storeId?: string;
16
+ meta?: Record<string, unknown>;
17
+ } | undefined): string | undefined;
18
+ /**
19
+ * 子会话的**查表键**(REPL 沙箱白名单 / overlay 缓存用):只认「预设名」这一种语义。
20
+ *
21
+ * 与展示名刻意分开(评审):团队成员会把自己的成员名写进 `meta.agentName`(teammate-runner),
22
+ * 于是 `meta.agentName` 同时承载「预设名」与「成员名」两种含义 —— 拿成员名去查 agent 配置查不到,
23
+ * 只能落到默认 agent 的兜底(既不是成员自己的白名单、也不是「不过滤」)。取不到可信的预设名时
24
+ * 返回 undefined = 不额外收窄(与改动前一致),不去猜。
25
+ */
26
+ export declare function resolveSubAgentAgentKey(session: {
27
+ id?: string;
28
+ storeId?: string;
29
+ meta?: Record<string, unknown>;
30
+ } | undefined): string | undefined;
31
+ /** 展示名的**派发侧镜像**:子会话还没建时拿不到 `meta.teamContext`,但这对值就是稍后写进 session 的同一对。 */
32
+ export declare function resolveSubAgentDisplayNameFromParts(input: {
33
+ memberName?: string;
34
+ presetName?: string;
35
+ }): string | undefined;
36
+ /**
37
+ * 查表键的**派发侧镜像**(AgentManager.sandboxScopedAgentView 传身份用):
38
+ * 预设名与成员名**同值**(团队成员把自己的名字写进 meta.agentName)时判为「没有可信预设名」→ undefined,
39
+ * 与运行期 `resolveSubAgentAgentKey` 同源 —— 否则派发侧按成员名收窄、执行侧判不到,两边分叉。
40
+ */
41
+ export declare function resolveSubAgentAgentKeyFromParts(input: {
42
+ memberName?: string;
43
+ presetName?: string;
44
+ }): string | undefined;
@@ -6,9 +6,9 @@
6
6
  * wastes tokens/credits.
7
7
  *
8
8
  * Detection rules:
9
- * 1. Generic loop: blacklisted tool with identical arguments 4 consecutive times
9
+ * 1. Generic loop: blacklisted tool with semantically identical JSON arguments 4 consecutive times
10
10
  * 2. Read file loop: Read tool targeting the same file_path 40 consecutive times
11
- * 3. Non-blacklist loop: any tool NOT in blacklist with identical arguments 40 consecutive times
11
+ * 3. Non-blacklist loop: any tool NOT in blacklist with semantically identical JSON arguments 40 consecutive times
12
12
  */
13
13
  import type { AgentInputItem } from '../../../../cbc-shared/lib/node/index.js';
14
14
  import { Logger } from '../../../../telemetry/lib/common/index.js';
@@ -38,14 +38,15 @@ export declare class ToolCallLoopDetectorImpl implements ToolCallLoopDetector {
38
38
  arguments: string;
39
39
  }>;
40
40
  /**
41
- * Check for generic loop: same tool with identical arguments N consecutive times.
41
+ * Check for generic loop: same tool with semantically identical JSON arguments
42
+ * N consecutive times. Malformed or very large argument payloads retain exact-string semantics.
42
43
  */
43
44
  protected checkGenericLoop(tailCalls: Array<{
44
45
  name: string;
45
46
  arguments: string;
46
47
  }>): LoopDetectionResult;
47
48
  /**
48
- * Check for non-blacklist tool loop: any tool NOT in the blacklist with identical arguments
49
+ * Check for non-blacklist tool loop: any tool NOT in the blacklist with semantically identical JSON arguments
49
50
  * called N consecutive times (threshold: NON_BLACKLIST_LOOP_THRESHOLD).
50
51
  * Scans from the tail of input, collecting only non-blacklist function_call items.
51
52
  */
@@ -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 次 / 周期序列重复 10 轮)。
30
+ * 它覆盖新增的两条规则(同工具连续 40 次,Bash 单独放到 80 次 / 周期序列重复 10 轮)。
31
31
  *
32
32
  * 两者刻意并存:旧规则的静默语义已被线上验证,不因新能力回归。
33
33
  */
@@ -5,8 +5,13 @@
5
5
  */
6
6
  import type { ToolCallLoopTriggerType } from '../../../../telemetry/lib/common/event/types/craft.js';
7
7
  export interface ToolCallLoopThresholds {
8
- /** 同一工具连续调用达到该次数即判定为循环。 */
8
+ /** 同一工具连续调用达到该次数即判定为循环。Bash 走单独阈值。 */
9
9
  consecutiveThreshold: number;
10
+ /**
11
+ * Bash 连续调用的单独阈值。长任务里模型会连续跑很多条不同命令,
12
+ * 只看工具名时 40 次容易把正常推进误判成循环。
13
+ */
14
+ bashConsecutiveThreshold: number;
10
15
  /** AAB 块需要连续重复的轮数。 */
11
16
  sequenceRepeats: number;
12
17
  }
@@ -17,6 +22,8 @@ export interface ToolCallLoopHit {
17
22
  /** 重复序列的周期长度;AAB 恒为 3,连续同工具恒为 1。 */
18
23
  patternLength: number;
19
24
  }
25
+ /** 与 `ToolNames.BASH` 对齐。模式识别层不依赖 agent-protocol,避免把工具名枚举拉进来。 */
26
+ export declare const BASH_LOOP_TOOL_NAME = "Bash";
20
27
  export declare const DEFAULT_TOOL_CALL_LOOP_THRESHOLDS: ToolCallLoopThresholds;
21
28
  /** AAB 块的长度。多工具循环只识别这一种形状,因此是常量而非可配阈值。 */
22
29
  export declare const AAB_PERIOD = 3;
@@ -36,7 +43,7 @@ export declare class ToolCallLoopTracker {
36
43
  * 记录一次即将执行的工具调用,返回本次是否命中循环。
37
44
  *
38
45
  * 命中优先级:先判连续同工具,再判 AAB 重复。两条规则的阈值默认不重叠
39
- * (40 次 vs AAB 重复 10 轮),实践中不会互相抢占。
46
+ * (普通工具 40 次、Bash 80 次 vs AAB 重复 10 轮),实践中不会互相抢占。
40
47
  */
41
48
  record(toolName: string): ToolCallLoopHit | undefined;
42
49
  /**
@@ -52,14 +59,18 @@ export declare class ToolCallLoopTracker {
52
59
  * - `ABC`(三者互不相同)通常是正常的多步工作流(读文件 → 改文件 → 跑测试,
53
60
  * 然后换下一个文件),按周期重复判它循环误伤面太大;
54
61
  * - `ABAB` 这类两工具交替同样不判,避免把翻页 / 分批处理误当循环;
55
- * - `AAA…` 属于连续同工具,由 consecutiveThreshold 那条规则负责。
62
+ * - `AAA…` 属于连续同工具,由 consecutiveThreshold / bashConsecutiveThreshold 那条规则负责。
56
63
  *
57
64
  * `X ≠ Y` 顺带保证了 AAB 一定是本原周期(唯一可能的更短整除周期是 1,
58
65
  * 那要求三个元素全等),所以不需要额外的本原性校验。
59
66
  */
60
67
  export declare function matchesRepeatedAabSequence(history: readonly string[], repeats: number): boolean;
61
68
  /**
62
- * 读取阈值配置。两个环境变量只用于 QA 快速复现,生产不设置即走默认值。
69
+ * 读取阈值配置。环境变量只用于 QA 快速复现,生产不设置即走默认值。
63
70
  * AAB 的周期是形状定义的一部分,不开放配置。
71
+ *
72
+ * `CBC_LOOP_GUARD_CONSECUTIVE_THRESHOLD` 只覆盖非 Bash 工具。Bash 用
73
+ * `CBC_LOOP_GUARD_BASH_CONSECUTIVE_THRESHOLD`,避免 QA 把通用阈值压低时
74
+ * 把长任务放宽一并关掉。
64
75
  */
65
76
  export declare function resolveToolCallLoopThresholds(env?: NodeJS.ProcessEnv): ToolCallLoopThresholds;
@@ -1,31 +1,15 @@
1
- /**
2
- * Agent-trigger payload helper, shared by SessionHookManager and ToolHookManager.
3
- *
4
- * Mirrors Claude Code's `createBaseHookInput` (utils/hooks.ts) so that every
5
- * hook event carries enough context for users to branch on
6
- * "main thread vs sub-agent" inside their Settings-level hooks.
7
- *
8
- * Rules (CC parity):
9
- * - `agent_type` is the agent's display name; populated from `session.agentName`
10
- * when set. On the main thread this is the `--agent` flag (when used) or the
11
- * default agent name. Inside a sub-agent this is the sub-agent's `name`
12
- * (e.g. "Explore", "Plan", "general-purpose").
13
- * - `agent_id` is only meaningful inside a sub-agent run — CC leaves it
14
- * `undefined` on the main thread. We honour the same convention by only
15
- * emitting it when `session.storeId` is present (sub-agent sessions get a
16
- * `agent-{8}` storeId; main sessions do not).
17
- *
18
- * Kept dependency-free so it can be imported from anywhere — including modules
19
- * that must avoid pulling the full `../session` barrel (which transitively
20
- * loads SessionManager / tips and triggers IoC initialisation).
21
- */
22
1
  export interface AgentTriggerLike {
23
2
  id?: string;
24
3
  agentName?: string;
25
4
  storeId?: string;
5
+ /** 会话 meta:身份标签要读 agentName / teamContext.memberName,parentSessionId 供子会话判定。 */
26
6
  meta?: {
27
7
  parentSessionId?: string;
28
- };
8
+ agentName?: string;
9
+ teamContext?: {
10
+ memberName?: unknown;
11
+ };
12
+ } & Record<string, unknown>;
29
13
  }
30
14
  export declare function buildAgentTrigger(session: AgentTriggerLike | undefined | null): {
31
15
  agent_id?: string;
@@ -31,7 +31,10 @@ export interface HookInput {
31
31
  */
32
32
  reason?: SessionEndReason;
33
33
  /**
34
- * User prompt content (for UserPromptSubmit event)
34
+ * User prompt content.
35
+ * - UserPromptSubmit: the submitted prompt text.
36
+ * - UserPromptExpansion: Claude Code spec required field, always sent — the
37
+ * raw, pre-expansion text as typed by the user (e.g. "/deploy prod").
35
38
  */
36
39
  prompt?: string;
37
40
  /**
@@ -1,44 +1,7 @@
1
1
  /**
2
- * Idle Queue Drain Service (Mode A `session.queue` 通道)
3
- *
4
- * 为什么需要这个 service
5
- * =====================
6
- * 用户在 agent 还在跑(streaming 末尾、工具执行中等)时输入新消息,UI 调
7
- * `agentService.run([userMsg])` 进来,`MessageQueueAgentRunInterceptor`
8
- * (input-interceptors.ts:77-84) 看到 `inConversation=true`,把消息塞进
9
- * `session.queue` 并设 `skipRun=true`。当前 turn 自然结束、emit `agent_end`,
10
- * 但**没有任何组件**会主动调一次 `agentService.run([], session)` 来触发
11
- * interceptor 的 drain 分支(input-interceptors.ts:85-103,那条分支会
12
- * `mergeConsecutiveUserMessages` 把队列里的消息拍成一个新 turn)。
13
- *
14
- * 结果:消息僵在 `session.queue`,UI 显示"已发送",agent 永远不回。
15
- *
16
- * `TeamInboxDispatchService` 看起来形态对,但它只检查
17
- * `RichMessageQueueManager`(团队成员消息进的那个 queue),全 codebase 只有
18
- * `team-create-tool.ts:332` 一处往 rich queue 写 —— 普通 TUI 用户输入完全
19
- * 走 `session.queue`,团队 dispatcher 看不到。
20
- *
21
- * 这个 service 就填这个空:每个 session 都订阅 `agent_end`,guard 通过后
22
- * 调一次空 input 的 `agentService.run`,让现有 interceptor 自己合并消费。
23
- *
24
- * 与 TeamInboxDispatchService 的关系
25
- * ==================================
26
- * - Mode A(默认):`isDeferredDispatchEnabledSync()===false`。
27
- * IdleQueueDrainService 接管 `session.queue` 的 drain;TeamInboxDispatchService
28
- * 也订阅了,但它看 rich queue(一般为空)→ short-circuit。
29
- * - Mode B:`isDeferredDispatchEnabledSync()===true`。
30
- * IdleQueueDrainService 入口 short-circuit;TeamInboxDispatchService 走
31
- * rich queue 的 immediate/pending 路径。
32
- * 两 service 各自有 `dispatching` Set,最坏情况下都是 short-circuit return,
33
- * 不会双重发起 run。
34
- *
35
- * 它不做的事
36
- * ==========
37
- * - 不动 `session.queue` 里的内容(让 interceptor 现有 mergeConsecutive 逻辑
38
- * 作为唯一消费点,避免逻辑漂移)。
39
- * - 不在 compact 中触发(`session.isCompressing` guard)。
40
- * - 不在 Mode B 中触发。
41
- * - 不影响 cancel 路径的 abort 行为(只在 `agent_end` 后做兜底)。
2
+ * Wake local queues after a turn ends. Mode A owns session.queue; Mode B tasks
3
+ * own its non-mirror items. Mode B main sessions remain with rich queue.
4
+ * MessageQueueAgentRunInterceptor remains the only dequeue/merge point.
42
5
  */
43
6
  import { Logger } from '../../../../telemetry/lib/common/index.js';
44
7
  import { AgentManager, AgentService } from '../agent/agent-protocol.js';
@@ -64,21 +27,6 @@ export declare class IdleQueueDrainServiceImpl implements IdleQueueDrainService
64
27
  * 空队列直接返回。
65
28
  */
66
29
  requestDrain(session: Session): void;
67
- /**
68
- * Guard 链 + 调 agentService.run 触发 interceptor 的 drain 分支。
69
- *
70
- * Guard 顺序(逐个 short-circuit return):
71
- * 1. 重入:同 session 上一次 tryDrain 还没 await 完。
72
- * 2. compact 中:`session.isCompressing===true`。compact 自身的
73
- * continue-run 也会 emit `agent_end`,必须避让。
74
- * 3. Mode B:rich queue 通道由 TeamInboxDispatchService 处理。
75
- * 4. DI 兜底:headless 等变体可能没拉到 AgentService/AgentManager。
76
- * 5. 空队列:没东西好 drain。
77
- * 6. 取消记账在途:见下方注释。
78
- *
79
- * 失败回灌:interceptor 在 line 95 已经 `clearQueue`,如果后续 run 抛错,
80
- * 队列里的消息会"被消费但又没真消费",相当于丢了。所以在调 run 之前
81
- * 快照 queue,run 抛错时检查 queue 是否被清空、被清空就把快照灌回。
82
- */
30
+ /** Reuse the existing idle drain and its pre-result failure restoration. */
83
31
  private tryDrain;
84
32
  }
@@ -8,6 +8,7 @@ export * from './session-response-host-protocol.js';
8
8
  export * from './background-task-protocol.js';
9
9
  export * from './root-session-scope.js';
10
10
  export * from './session-factory.js';
11
+ export { assertSessionRuntimeOpen, closeSessionRuntime, isSessionRuntimeClosed, sessionRuntimeSignal, } from './session-runtime-lifecycle.js';
11
12
  export * from './session-admission-service.js';
12
13
  export * from './session-manager.js';
13
14
  export * from './session-store.js';
@@ -25,12 +26,14 @@ export { getSessionCanUseTool, resolveCanUseTool, resolveCanUseToolOwner, setSes
25
26
  export type { CanUseTool, CanUseToolOptions, CanUseToolOwner, PermissionBehavior, PermissionDecisionClassification, PermissionResult as CanUseToolPermissionResult, PermissionRuleValue, PermissionUpdate as CanUseToolPermissionUpdate, PermissionUpdateDestination, } from './can-use-tool.js';
26
27
  export * from './dual-channel-interaction.js';
27
28
  export * from './session-persistence.js';
29
+ export * from './session-persistence-error.js';
28
30
  export * from './session-set-current.js';
29
31
  export * from './cancel-session-runtime-state.js';
30
32
  export * from './user-request-boundary.js';
31
33
  export { isTruncationRecoveryActive } from './truncation-recovery.js';
32
34
  export * from './aborted-stream-draft-store.js';
33
35
  export * from './stream-timeout-retry-budget.js';
36
+ export { consumeRecoveryRequestPending } from './recovery-budget.js';
34
37
  export * from './session-run-state-machine-protocol.js';
35
38
  export * from './session-run-state-machine.js';
36
39
  export * from './session-run-state-projection-service.js';