@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.
- package/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/cli/CHANGELOG.md +71 -0
- package/cli/dist-server/shared.cjs +318 -314
- package/cli/dist-server/types/node/acp/acp-protocol.d.ts +40 -12
- package/cli/dist-server/types/node/acp/usage-by-category-calculator.d.ts +21 -0
- package/cli/dist-server/types/node/cli/stream-json-protocol.d.ts +15 -1
- package/cli/dist-server/types/node/data-fs/index.d.ts +13 -1
- package/cli/dist-server/types/node/hooks/hook-protocol.d.ts +2 -2
- package/cli/dist-server/types/node/server/sessions.d.ts +24 -0
- package/cli/dist-server/types/node/server/types.d.ts +6 -0
- package/cli/dist-server/types/node/settings/settings-protocol.d.ts +5 -0
- package/cli/dist-server/types/node/tools/tool-protocol.d.ts +112 -2
- package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-protocol.d.ts +29 -0
- package/cli/dist-server/types/vendor/cbc-core/node/agent/agent-service.d.ts +2 -0
- package/cli/dist-server/types/vendor/cbc-core/node/agent/index.d.ts +1 -0
- package/cli/dist-server/types/vendor/cbc-core/node/agent/interceptors/input-interceptors.d.ts +1 -6
- package/cli/dist-server/types/vendor/cbc-core/node/agent/runner-factory.d.ts +31 -11
- package/cli/dist-server/types/vendor/cbc-core/node/agent/speaker-label.d.ts +44 -0
- package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-detector-service.d.ts +5 -4
- package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
- package/cli/dist-server/types/vendor/cbc-core/node/agent/tool-call-loop-pattern.d.ts +15 -4
- package/cli/dist-server/types/vendor/cbc-core/node/hooks/agent-trigger.d.ts +6 -22
- package/cli/dist-server/types/vendor/cbc-core/node/hooks/hook-protocol.d.ts +4 -1
- package/cli/dist-server/types/vendor/cbc-core/node/session/idle-queue-drain-service.d.ts +4 -56
- package/cli/dist-server/types/vendor/cbc-core/node/session/index.d.ts +3 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/interruption-service.d.ts +55 -9
- package/cli/dist-server/types/vendor/cbc-core/node/session/model-response-interceptors.d.ts +18 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/recovery-budget.d.ts +55 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-hook-manager.d.ts +15 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager.d.ts +10 -1
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-persistence-error.d.ts +43 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-protocol.d.ts +63 -4
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-run-state-machine-protocol.d.ts +1 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-runtime-lifecycle.d.ts +5 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-store.d.ts +150 -4
- package/cli/dist-server/types/vendor/cbc-core/node/session/stream-timeout-retry-budget.d.ts +13 -1
- package/cli/dist-server/types/vendor/cbc-core/node/utils/history-utils.d.ts +23 -0
- package/cli/dist-server/types/vendor/cbc-core/node/utils/index.d.ts +1 -0
- package/cli/dist-server/types/vendor/cbc-core/node/utils/message-utils.d.ts +12 -0
- package/cli/dist-server/types/vendor/cbc-core/node/utils/model-utils.d.ts +7 -0
- package/cli/dist-server/types/vendor/cbc-core/node/utils/queue-dispatch-utils.d.ts +24 -2
- package/cli/dist-server/types/vendor/cbc-core/node/utils/session-utils.d.ts +4 -1
- package/cli/dist-server/types/vendor/cbc-core/node/utils/string-retention-utils.d.ts +4 -0
- package/cli/dist-server/types/vendor/cbc-shared/node/hooks/hook-types.d.ts +7 -1
- package/cli/dist-server/types/vendor/cbc-shared/node/index.d.ts +2 -0
- package/cli/dist-server/types/vendor/cbc-shared/node/model/model-errors.d.ts +7 -3
- package/cli/dist-server/types/vendor/cbc-shared/node/tools/tool-names.d.ts +1 -0
- package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-backoff.d.ts +30 -0
- package/cli/dist-server/types/vendor/cbc-shared/node/utils/retry-policy.d.ts +26 -0
- package/cli/dist-server/types/workspace/authentication/lib/common/account-scoped-external-link-authentication-provider.d.ts +2 -2
- package/cli/dist-server/types/workspace/authentication/lib/common/account-utils.d.ts +25 -0
- package/cli/dist-server/types/workspace/authentication/lib/common/authentication-manager.d.ts +2 -2
- package/cli/dist-server/types/workspace/authentication/lib/common/authentication-protocol.d.ts +19 -2
- package/cli/dist-server/types/workspace/authentication/lib/common/external-link-authentication-provider.d.ts +2 -2
- package/cli/dist-server/types/workspace/authentication/lib/common/wx-authentication-provider.d.ts +2 -2
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-protocol.d.ts +29 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/agent-service.d.ts +2 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/index.d.ts +1 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/interceptors/input-interceptors.d.ts +1 -6
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/runner-factory.d.ts +31 -11
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/speaker-label.d.ts +44 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-detector-service.d.ts +5 -4
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-guard-protocol.d.ts +1 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/tool-call-loop-pattern.d.ts +15 -4
- package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/agent-trigger.d.ts +6 -22
- package/cli/dist-server/types/workspace/cbc-core/lib/node/hooks/hook-protocol.d.ts +4 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/idle-queue-drain-service.d.ts +4 -56
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/index.d.ts +3 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/interruption-service.d.ts +55 -9
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/model-response-interceptors.d.ts +18 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/recovery-budget.d.ts +55 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-hook-manager.d.ts +15 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager.d.ts +10 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-persistence-error.d.ts +43 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-protocol.d.ts +63 -4
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-run-state-machine-protocol.d.ts +1 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-runtime-lifecycle.d.ts +5 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-store.d.ts +150 -4
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/stream-timeout-retry-budget.d.ts +13 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/history-utils.d.ts +23 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/index.d.ts +1 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/message-utils.d.ts +12 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/model-utils.d.ts +7 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/queue-dispatch-utils.d.ts +24 -2
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/session-utils.d.ts +4 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/string-retention-utils.d.ts +4 -0
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/hooks/hook-types.d.ts +7 -1
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/index.d.ts +2 -0
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/model/model-errors.d.ts +7 -3
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/tools/tool-names.d.ts +1 -0
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-backoff.d.ts +30 -0
- package/cli/dist-server/types/workspace/cbc-shared/lib/node/utils/retry-policy.d.ts +26 -0
- package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-execution.d.ts +14 -1
- package/cli/dist-server/types/workspace/cbc-workflow/lib/node/workflow/workflow-manager.d.ts +7 -0
- package/cli/dist-server/types/workspace/cbc-worktree/lib/node/worktree/worktree-session.d.ts +3 -0
- package/cli/dist-server/types/workspace/product/lib/common/cloud-product-provider.d.ts +9 -0
- package/cli/dist-server/types/workspace/product/lib/common/index.d.ts +1 -0
- package/cli/dist-server/types/workspace/product/lib/common/pick-market-skill-id.d.ts +13 -0
- package/cli/dist-server/types/workspace/product/lib/common/tool-control-catalog.d.ts +2 -2
- package/cli/dist-server/types/workspace/product/lib/common/types/features.d.ts +62 -2
- package/cli/dist-server/types/workspace/product/lib/common/types/language-model.d.ts +66 -0
- package/cli/dist-server/types/workspace/product/lib/common/types/product.d.ts +7 -1
- package/cli/dist-server/types/workspace/sandbox-cli/lib/common/backup-policy.d.ts +10 -1
- package/cli/dist-server/types/workspace/sandbox-cli/lib/common/center-protocol.generated.d.ts +370 -4
- package/cli/dist-server/types/workspace/sandbox-cli/lib/common/file-policy.d.ts +1 -1
- package/cli/dist-server/types/workspace/sandbox-cli/lib/node/sandbox-center-client.d.ts +216 -0
- package/cli/package.json +1 -1
- package/cli/product.cloudhosted.json +2 -2
- package/cli/product.internal.json +259 -40
- package/cli/product.ioa.json +333 -148
- package/cli/product.json +309 -351
- package/cli/product.selfhosted.json +2 -2
- package/docs/README.md +1 -0
- package/docs/in-process.md +16 -0
- package/lib/application/services.d.ts +3 -1
- package/lib/application/services.js +1 -1
- package/lib/components/sandbox-center.d.mts +2 -0
- package/lib/components/sandbox-center.mjs +1 -0
- package/lib/components/session-config.d.mts +2 -0
- package/lib/components/session-config.mjs +1 -1
- package/lib/harness/create-harness.js +1 -1
- package/lib/harness/runtime.js +1 -1
- package/lib/harness/types.d.ts +3 -0
- package/lib/integration/executor-supervisor.js +1 -1
- package/lib/public.d.ts +1 -0
- package/lib/runtime/sandbox-center.d.ts +21 -0
- package/lib/runtime/sandbox-center.js +1 -0
- package/lib/server/public.d.ts +1 -0
- package/lib/session/agent-backend.d.ts +2 -0
- package/lib/session/agent-backend.js +1 -1
- package/lib/session/local-fs.js +1 -1
- package/lib/session/server-config.js +1 -1
- package/lib/session/server-interactions.js +1 -1
- package/package.json +25 -15
- package/lib/session/local-options.d.ts +0 -50
- package/lib/session/local-options.js +0 -1
|
@@ -89,6 +89,7 @@ export type AgentPhase = 'preparing' | 'model_requesting' | 'model_streaming' |
|
|
|
89
89
|
export interface AgentPhaseInfo {
|
|
90
90
|
phase: AgentPhase;
|
|
91
91
|
toolName?: string;
|
|
92
|
+
toolCallId?: string;
|
|
92
93
|
streamingToolName?: string;
|
|
93
94
|
startedAt: number;
|
|
94
95
|
/**
|
|
@@ -177,6 +178,8 @@ export interface PreToolUseHookResult {
|
|
|
177
178
|
permissionDecision?: 'allow' | 'deny' | 'ask';
|
|
178
179
|
permissionDecisionReason?: string;
|
|
179
180
|
runtimeSecurity?: Record<string, unknown>;
|
|
181
|
+
/** PreToolUse `continue:false` — stop the current turn after the deny result is recorded. */
|
|
182
|
+
preventContinuation?: boolean;
|
|
180
183
|
}
|
|
181
184
|
export interface Session {
|
|
182
185
|
id: string;
|
|
@@ -206,6 +209,8 @@ export interface Session {
|
|
|
206
209
|
*/
|
|
207
210
|
replSandboxDepth?: number;
|
|
208
211
|
state?: RunState<any, any>;
|
|
212
|
+
/** Emitted after a physical run releases its lifecycle owner and abort links. */
|
|
213
|
+
runSettledSubject?: Subject<void>;
|
|
209
214
|
createdAt: number;
|
|
210
215
|
updatedAt: number;
|
|
211
216
|
meta?: Record<string, any>;
|
|
@@ -638,6 +643,12 @@ export interface Session {
|
|
|
638
643
|
* Context from UserPromptSubmit hook to be injected into current user message
|
|
639
644
|
*/
|
|
640
645
|
userPromptSubmitContext?: string;
|
|
646
|
+
/**
|
|
647
|
+
* Context from UserPromptExpansion hook (hookSpecificOutput.additionalContext),
|
|
648
|
+
* to be injected alongside the expanded prompt (Claude Code parity: same
|
|
649
|
+
* injection point as UserPromptSubmit — "alongside the submitted prompt").
|
|
650
|
+
*/
|
|
651
|
+
userPromptExpansionContext?: string;
|
|
641
652
|
/**
|
|
642
653
|
* Context from PostToolUse hook to be injected after tool execution
|
|
643
654
|
*/
|
|
@@ -915,6 +926,8 @@ export interface SessionOptions {
|
|
|
915
926
|
debugToStderr?: boolean;
|
|
916
927
|
verbose?: boolean;
|
|
917
928
|
print?: boolean;
|
|
929
|
+
/** Host Bash output preference; omitted preserves the CLI's PTY selection. */
|
|
930
|
+
usePty?: boolean;
|
|
918
931
|
outputFormat?: 'text' | 'json' | 'stream-json';
|
|
919
932
|
inputFormat?: 'text' | 'stream-json';
|
|
920
933
|
/** Whether to persist the session transcript. Defaults to true; false keeps history in memory only. */
|
|
@@ -1123,9 +1136,11 @@ export interface SessionManager {
|
|
|
1123
1136
|
*
|
|
1124
1137
|
* 幂等:未注册的 sessionId 为 no-op。
|
|
1125
1138
|
*
|
|
1126
|
-
* @param
|
|
1139
|
+
* @param target 传 Session 对象时,索引键与身份校验同源——只有注册表当前持有
|
|
1140
|
+
* 的正是这个对象才释放,复用同一 sessionId 的后继对象不会被误清。只拿得到
|
|
1141
|
+
* id 的调用方(RPC、`remove(id)`)传字符串,此时不做身份校验。
|
|
1127
1142
|
*/
|
|
1128
|
-
releaseInMemory(
|
|
1143
|
+
releaseInMemory(target: string | Session): void;
|
|
1129
1144
|
/**
|
|
1130
1145
|
* 该 sessionId 是否已在本进程通过 get() 加载过(且尚未 remove()/releaseInMemory())。
|
|
1131
1146
|
*
|
|
@@ -1216,8 +1231,31 @@ export interface SessionManager {
|
|
|
1216
1231
|
*/
|
|
1217
1232
|
flushHistory(session: Session): Promise<void>;
|
|
1218
1233
|
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Cumulative transcript persistence counters (issue #119545 埋点建议).
|
|
1236
|
+
* A best-effort side channel, so every reader must treat the numbers as a
|
|
1237
|
+
* snapshot that may be sampled at any moment.
|
|
1238
|
+
*/
|
|
1239
|
+
export interface TranscriptPersistenceMetrics {
|
|
1240
|
+
/** In-band retry attempts consumed. */
|
|
1241
|
+
retries: number;
|
|
1242
|
+
/** Batches that only landed because of a retry. */
|
|
1243
|
+
retrySucceeded: number;
|
|
1244
|
+
/** Batches given up on after the retry budget. */
|
|
1245
|
+
abandonedBatches: number;
|
|
1246
|
+
/** Lines lost with those batches. */
|
|
1247
|
+
abandonedLines: number;
|
|
1248
|
+
}
|
|
1219
1249
|
export interface SessionStore {
|
|
1220
1250
|
getSessionFilePath(id: string, parentSessionId?: string, cwd?: string): string;
|
|
1251
|
+
/**
|
|
1252
|
+
* Transcript persistence counters, when the implementation keeps any.
|
|
1253
|
+
* Optional so in-memory and host-delegating stores do not have to fake it.
|
|
1254
|
+
* Exposed so callers that observe a degradation can log the counters from
|
|
1255
|
+
* their own call site: the store's own abandon audit line is best-effort
|
|
1256
|
+
* and a lost line would otherwise take the only copy of the numbers.
|
|
1257
|
+
*/
|
|
1258
|
+
transcriptPersistenceMetrics?(): Readonly<TranscriptPersistenceMetrics>;
|
|
1221
1259
|
get(id: string, options?: SessionGetOptions): Promise<Session | undefined>;
|
|
1222
1260
|
getAcrossProjects(id: string, options?: SessionGetOptions): Promise<Session | undefined>;
|
|
1223
1261
|
save(session: Session, cwd?: string): Promise<void>;
|
|
@@ -1376,6 +1414,26 @@ export interface SessionHookManager {
|
|
|
1376
1414
|
* Does NOT support continueRequest.
|
|
1377
1415
|
*/
|
|
1378
1416
|
executeFinalStopHooks(session: Session, reason?: FinalStopReason): Promise<void>;
|
|
1417
|
+
/**
|
|
1418
|
+
* UserPromptExpansion — Claude Code 官方事件(非 cbc 专属扩展):任何用户输入的
|
|
1419
|
+
* 命令/skill 在展开成 prompt、送进模型之前统一从这里触发,可阻断展开。适用于
|
|
1420
|
+
* skill、自定义命令、Dynamic Workflow、MCP prompt 等一切"输入即展开"的路径,
|
|
1421
|
+
* 不是只服务某一个具体调用方(如统一资产门控)。
|
|
1422
|
+
*/
|
|
1423
|
+
executeUserPromptExpansionHooks(session: Session, payload: {
|
|
1424
|
+
/** Claude Code spec: 'slash_command' for skill/custom commands, 'mcp_prompt' for MCP prompts. */
|
|
1425
|
+
expansionType: 'slash_command' | 'mcp_prompt' | string;
|
|
1426
|
+
commandName: string;
|
|
1427
|
+
/** Claude Code spec: required field (empty string when no args), always sent. */
|
|
1428
|
+
commandArgs: string;
|
|
1429
|
+
/** e.g. Skill.source / Command.scope ('project' | 'user' | 'plugin' | 'mcp' | ...). */
|
|
1430
|
+
commandSource?: string;
|
|
1431
|
+
/** Claude Code spec: required field — raw, pre-expansion prompt text as typed by the user. */
|
|
1432
|
+
prompt: string;
|
|
1433
|
+
}): Promise<{
|
|
1434
|
+
allowed: boolean;
|
|
1435
|
+
message?: string;
|
|
1436
|
+
}>;
|
|
1379
1437
|
}
|
|
1380
1438
|
export interface RunItemProcessor {
|
|
1381
1439
|
process(runItem: RunItem): Promise<void>;
|
|
@@ -1494,9 +1552,10 @@ export interface InterruptionService {
|
|
|
1494
1552
|
*
|
|
1495
1553
|
* 幂等:session 未注册时为 no-op。只清内存映射,不动磁盘 jsonl。
|
|
1496
1554
|
*
|
|
1497
|
-
* @param
|
|
1555
|
+
* @param target 传 Session 对象时按对象身份校验,同 id 的后继对象不会被误清;
|
|
1556
|
+
* 只拿得到 id 的调用方传字符串,此时不做身份校验。
|
|
1498
1557
|
*/
|
|
1499
|
-
releaseSession(
|
|
1558
|
+
releaseSession(target: string | Session): void;
|
|
1500
1559
|
}
|
|
1501
1560
|
export interface MessageQueueManager {
|
|
1502
1561
|
enqueueMessage(session: Session, message: AgentInputItem): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Session } from './session-protocol';
|
|
2
|
+
export declare function isSessionRuntimeClosed(session: Session): boolean;
|
|
3
|
+
export declare function closeSessionRuntime(session: Session): void;
|
|
4
|
+
export declare function sessionRuntimeSignal(session: Session): AbortSignal;
|
|
5
|
+
export declare function assertSessionRuntimeOpen(session: Session | undefined): void;
|
|
@@ -2,7 +2,7 @@ import { Logger } from '@celljs/core';
|
|
|
2
2
|
import { type AgentInputItem } from '../../../cbc-shared/node/index.js';
|
|
3
3
|
import * as fs from 'fs/promises';
|
|
4
4
|
import { LocalJsonlSessionStore } from './local-jsonl-session-store';
|
|
5
|
-
import { type Session, SessionFactory, type SessionForkMutationOptions, type SessionGetOptions, type SessionRewindMutationOptions, SessionStore } from './session-protocol';
|
|
5
|
+
import { type Session, SessionFactory, type SessionForkMutationOptions, type SessionGetOptions, type SessionRewindMutationOptions, SessionStore, type TranscriptPersistenceMetrics } from './session-protocol';
|
|
6
6
|
import type { Lane, LanePointer, SessionKey, SessionStoreEntry } from './session-store-contract';
|
|
7
7
|
import { SessionImageStorage as ImageBlobService, SessionRestoreHost, SessionStoragePaths, SessionToolOutputStorage as ToolResultBlobService } from './session-store-host-protocol';
|
|
8
8
|
/**
|
|
@@ -10,6 +10,27 @@ import { SessionImageStorage as ImageBlobService, SessionRestoreHost, SessionSto
|
|
|
10
10
|
* 达到此阈值且遇到 user message 时停止逆序读取,避免启动时全量读 JSONL。
|
|
11
11
|
*/
|
|
12
12
|
export declare const DEFAULT_SESSION_MAX_ITEMS = 1000;
|
|
13
|
+
/**
|
|
14
|
+
* 每追加这么多条 history 行,就把当前 session-meta 快照重新补写到文件尾部。
|
|
15
|
+
*
|
|
16
|
+
* 读侧按 item 数封顶逆序读,只在窗口内找 session-meta;写侧按内容去重,身份
|
|
17
|
+
* 不变就只有创建时那一行(文件第 1 行)。会话一长,读窗口够不到它 → resume
|
|
18
|
+
* 静默丢 `codebuddy.ai/mainAgent`(PTC 掉回 cli、REPL 消失)/ `multitaskMode`
|
|
19
|
+
* / `codebuddy.ai/a2aContexts` / `codebuddy.ai/hostKind`(#128860)。
|
|
20
|
+
*
|
|
21
|
+
* 取值远小于 {@link DEFAULT_SESSION_MAX_ITEMS},读侧即使把上限调低也仍能覆盖;
|
|
22
|
+
* 代价是每 200 行多一条约 200 字节的行(≈0.1%)。
|
|
23
|
+
*
|
|
24
|
+
* **与 {@link SESSION_META_HEAD_SCAN_BYTES} 是配对约束,必须满足**
|
|
25
|
+
* `SESSION_META_TAIL_REFRESH_LINES × 单行平均字节 << SESSION_META_HEAD_SCAN_BYTES`:
|
|
26
|
+
* 写侧靠本行距把快照压在文件尾部,读侧只有 256KB 的文件头兜底窗口 —— 一旦尾部快照
|
|
27
|
+
* 滑出头部窗口,长会话 resume 丢键(#128860 本体)就会以另一种形式回归。
|
|
28
|
+
* 当前 200 × ~200B ≈ 40KB,对 256KB 有约 6× 余量。**调大本值或让单行显著变长
|
|
29
|
+
* (例如工具结果外置后仍很大的行)都必须同步核对另一侧**,spec 里有一条边界断言钉住。
|
|
30
|
+
*/
|
|
31
|
+
export declare const SESSION_META_TAIL_REFRESH_LINES = 200;
|
|
32
|
+
/** 文件头 session-meta 兜底读取的字节窗口(存量会话用,不做全量回扫)。与上者配对,见其注释。导出以便 spec 钉住配对约束。 */
|
|
33
|
+
export declare const SESSION_META_HEAD_SCAN_BYTES: number;
|
|
13
34
|
/**
|
|
14
35
|
* Keys of session.meta that persist across processes (the off-tree
|
|
15
36
|
* session-meta line; bin resume only — served sessions never write). A
|
|
@@ -22,6 +43,37 @@ export declare const DEFAULT_SESSION_MAX_ITEMS = 1000;
|
|
|
22
43
|
* Role / locks / parentSessionId stay runtime-only.
|
|
23
44
|
*/
|
|
24
45
|
export declare const PERSISTED_SESSION_META_KEYS: readonly ['codebuddy.ai/mainAgent', 'codebuddy.ai/hostKind', 'multitaskMode', 'codebuddy.ai/a2aContexts'];
|
|
46
|
+
/**
|
|
47
|
+
* 白名单里「缺席即删除」的键:只认最新那一行的存在性,不向更早的行按键继承。
|
|
48
|
+
*
|
|
49
|
+
* 其余键(mainAgent / hostKind / a2aContexts)只会被赋值、不会被 delete,所以
|
|
50
|
+
* 读侧按键继承——某个写方视野不全(只快照了自己关心的键)不能把别的键擦掉
|
|
51
|
+
* (#128860:`/multitask` 盖章写出只含 multitaskMode 的行,把 PTC 站立身份永久
|
|
52
|
+
* 抹掉,`/agent-mode` 变成 Standard(cli))。
|
|
53
|
+
*
|
|
54
|
+
* `multitaskMode` 是唯一会被真正 delete 的键(multitask/session-flags.ts 的
|
|
55
|
+
* clearMultitaskSession),所以必须留在这里,否则"关掉多任务"会被更早的
|
|
56
|
+
* `true` 复活。**新增白名单键时**:只要它的"缺席"承载语义,就必须登记到本表。
|
|
57
|
+
*
|
|
58
|
+
* 注意「缺席」要能写进文件才算数:子集被删空时 `persistSessionMeta` 会补一条
|
|
59
|
+
* `meta: {}` 的墓碑行,否则最新那条仍是删除前的快照,缺席永远不会出现。墓碑是
|
|
60
|
+
* **整份空快照**:本表登记第二个键之后,为删 A 写的墓碑会连带把 B 也判成缺席,
|
|
61
|
+
* 届时得改成按键墓碑,别直接往表里加。
|
|
62
|
+
*/
|
|
63
|
+
export declare const SNAPSHOT_ONLY_SESSION_META_KEYS: ReadonlyArray<string>;
|
|
64
|
+
/**
|
|
65
|
+
* 参与合并的一条 session-meta 行。
|
|
66
|
+
*
|
|
67
|
+
* `id` 可能是空串:#94203 才给这行加上自身 UUIDv7,更早写下的存量行没有 id
|
|
68
|
+
* (CHANGELOG 明确「兼容旧的无 ID 记录」)。任何按 id 判等的地方都必须先处理
|
|
69
|
+
* 这个缺失,见 {@link SessionStoreImpl.metaLineIdentity}。
|
|
70
|
+
*/
|
|
71
|
+
interface SessionMetaLine {
|
|
72
|
+
id: string;
|
|
73
|
+
meta: Record<string, unknown>;
|
|
74
|
+
/** 行原文(trim 后)。缺 id 的存量行靠它做判等。 */
|
|
75
|
+
raw: string;
|
|
76
|
+
}
|
|
25
77
|
/**
|
|
26
78
|
* 解析 session 历史回放的 maxItems。
|
|
27
79
|
*
|
|
@@ -46,6 +98,7 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
46
98
|
protected readonly paths: SessionStoragePaths;
|
|
47
99
|
protected readonly restoreHost: SessionRestoreHost;
|
|
48
100
|
private writeLocks;
|
|
101
|
+
private readonly transcriptMetrics;
|
|
49
102
|
private readonly transcriptAuditOnce;
|
|
50
103
|
private transcriptAuditSequence;
|
|
51
104
|
/**
|
|
@@ -113,6 +166,16 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
113
166
|
* behavioral loop: externalize → Read → externalize → Read …).
|
|
114
167
|
*/
|
|
115
168
|
private externalizeToolResultIfNeeded;
|
|
169
|
+
/**
|
|
170
|
+
* Externalize the UI-only copy of a tool result. Tool implementations commonly store
|
|
171
|
+
* the same payload again in providerData.toolResult.content/renderer; keeping that copy
|
|
172
|
+
* defeats output externalization and can make a single JSONL row hundreds of KiB.
|
|
173
|
+
*
|
|
174
|
+
* The render payload is persisted as one JSON document. History keeps a text renderer
|
|
175
|
+
* pointing at that file, so clients always have a visible fallback instead of trying to
|
|
176
|
+
* parse a <persisted-output> marker as the original media/custom renderer payload.
|
|
177
|
+
*/
|
|
178
|
+
private externalizeToolRenderDataIfNeeded;
|
|
116
179
|
/**
|
|
117
180
|
* Handle externalization for structured array output.
|
|
118
181
|
* Iterates through array elements and externalizes any input_text items that exceed the threshold.
|
|
@@ -139,7 +202,25 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
139
202
|
*/
|
|
140
203
|
getSessionMetaFilePath(id: string, parentSessionId?: string, cwd?: string): string;
|
|
141
204
|
private lastPersistedMeta;
|
|
205
|
+
/** 各转录文件「距上次 session-meta 行」的 history 行数(进程内,用于尾部刷新节流)。 */
|
|
206
|
+
private historyLinesSinceMeta;
|
|
207
|
+
/** 读侧靠文件头兜底才拿到 meta 的转录文件:下一批 append 立即把快照补到尾部。 */
|
|
208
|
+
private staleTailMeta;
|
|
209
|
+
/**
|
|
210
|
+
* 「据已知,该转录尾部最新那条 session-meta 还带着非空子集」——决定子集被删空时
|
|
211
|
+
* 要不要补墓碑。
|
|
212
|
+
*
|
|
213
|
+
* 判据必须是**文件事实**而不是"本进程写过什么":resume 只 `get()` 不 `save()`
|
|
214
|
+
* (agent-task.ts 的子代理恢复就是这样),进程内缓存恒空,冷启动后第一轮就关掉
|
|
215
|
+
* 多任务会写不出墓碑,"关掉"永远落不了盘。所以读侧 load 完也要维护它。
|
|
216
|
+
*
|
|
217
|
+
* 仍是进程内状态:同一转录被两个进程同时写时,另一方的非空写入本进程不可见
|
|
218
|
+
* (与 `lastPersistedMeta` 同一层限制)。
|
|
219
|
+
*/
|
|
220
|
+
private tailMetaNonEmpty;
|
|
142
221
|
private persistedMetaSubset;
|
|
222
|
+
/** 一条 off-tree session-meta 行的字节形式。空 `persisted` 即墓碑快照。 */
|
|
223
|
+
private metaSnapshotLine;
|
|
143
224
|
/** The off-tree session-meta line, or undefined when there is nothing to persist. */
|
|
144
225
|
protected sessionMetaLineFor(fileId: string, meta: Session['meta']): string | undefined;
|
|
145
226
|
/**
|
|
@@ -150,7 +231,59 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
150
231
|
* .meta.json overwrite. Bin surface only — served sessions never reach
|
|
151
232
|
* here (persistence gate; locked by spec).
|
|
152
233
|
*/
|
|
153
|
-
protected persistSessionMeta(fileId: string, meta: Session['meta'], parentSessionId?: string, cwd?: string
|
|
234
|
+
protected persistSessionMeta(fileId: string, meta: Session['meta'], parentSessionId?: string, cwd?: string, options?: {
|
|
235
|
+
force?: boolean;
|
|
236
|
+
}): Promise<void>;
|
|
237
|
+
/**
|
|
238
|
+
* 尾部快照刚落盘后的进程内状态收尾 —— 四份状态必须一起动。
|
|
239
|
+
*
|
|
240
|
+
* `lastPersistedMeta` / `historyLinesSinceMeta` / `staleTailMeta` / `tailMetaNonEmpty`
|
|
241
|
+
* 都以 filePath 为键、都描述「这个转录尾部最新那条 meta 现在是什么」。任何往尾部
|
|
242
|
+
* 写快照的路径(persistSessionMeta / initializeForkHistory)都要走这里:在调用点
|
|
243
|
+
* 手写四行,下一次再加状态时必然漏一处 —— fork 初始化就是这么漏的(lastPersistedMeta
|
|
244
|
+
* 写了,另外三份没写,导致 fork 后关掉多任务写不出墓碑、行数计数带着旧值)。
|
|
245
|
+
*/
|
|
246
|
+
private markTailMetaPersisted;
|
|
247
|
+
/**
|
|
248
|
+
* 让「最新 session-meta」始终留在读侧的逆序窗口内(#128860 根治的写入侧)。
|
|
249
|
+
*
|
|
250
|
+
* 只在 history 真正落盘之后调用:每 {@link SESSION_META_TAIL_REFRESH_LINES}
|
|
251
|
+
* 行补写一次快照;读侧走过文件头兜底的文件(存量长会话)立即补写一次,
|
|
252
|
+
* 这样同一个会话只会退化一次。
|
|
253
|
+
*
|
|
254
|
+
* 失败不能拖垮本轮 append —— 转录字节已经写成功了,meta 下一批还会重试。
|
|
255
|
+
*/
|
|
256
|
+
private refreshTailSessionMeta;
|
|
257
|
+
/**
|
|
258
|
+
* 文件头的 session-meta 兜底读取。
|
|
259
|
+
*
|
|
260
|
+
* `session-meta` 创建行通常在文件靠前的位置(新建会话是第 1 行;子会话/迁移过的
|
|
261
|
+
* 会话可能更靠后),而 history 逆序读有 item 上限——长会话倒着读到不了那里
|
|
262
|
+
* (#128860)。这里只读文件头一小段,不做全量回扫:
|
|
263
|
+
* 29MB 的会话里末尾 1100 行只占 20% 字节,回扫到头会把 resume 的读 I/O 放大 5×。
|
|
264
|
+
*
|
|
265
|
+
* 返回窗口内所有 session-meta 的 meta(文件序,旧→新),由
|
|
266
|
+
* {@link composeSessionMeta} 统一合并。
|
|
267
|
+
*/
|
|
268
|
+
protected readHeadSessionMeta(filePath: string): Promise<SessionMetaLine[] | undefined>;
|
|
269
|
+
/**
|
|
270
|
+
* 合并去重用的行身份。
|
|
271
|
+
*
|
|
272
|
+
* 不能直接用 `id`:#94203 之前的存量行没有 id,兜成空串会让「头部的创建行」
|
|
273
|
+
* 和「尾部的残缺行」撞成同一个键 —— 头部那条被当成"已经见过"丢掉,正好复现
|
|
274
|
+
* 本 issue 要修的丢键现场(本机实测 2607 条 meta 行里 1195 条没有 id)。
|
|
275
|
+
* 缺 id 时退回整行原文:内容相同的两行参与合并是幂等的,丢一条无害。
|
|
276
|
+
*/
|
|
277
|
+
private metaLineIdentity;
|
|
278
|
+
/**
|
|
279
|
+
* 把若干条 session-meta(文件序,旧→新)合成一份 meta 事实。
|
|
280
|
+
*
|
|
281
|
+
* - {@link SNAPSHOT_ONLY_SESSION_META_KEYS}:只认最新那一行(缺席=已删除)。
|
|
282
|
+
* - 其余白名单键:按键向更早的行继承,最新的值优先。写方只快照了自己视野
|
|
283
|
+
* 里的键时,别人的键不会被顺带擦掉(#128860 的第二处:`/multitask` 写出
|
|
284
|
+
* 只含 multitaskMode 的行,PTC 站立身份被永久抹掉)。
|
|
285
|
+
*/
|
|
286
|
+
protected composeSessionMeta(metaLinesOldestFirst: ReadonlyArray<SessionMetaLine>): Record<string, unknown> | undefined;
|
|
154
287
|
private findSubagentSessionByStoreId;
|
|
155
288
|
protected deserializeSessionFromJsonl(id: string, options?: SessionGetOptions): Promise<Session | undefined>;
|
|
156
289
|
/**
|
|
@@ -225,13 +358,25 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
225
358
|
*/
|
|
226
359
|
protected isNonUserSession(session: Session): boolean;
|
|
227
360
|
appendHistory(id: string, input: AgentInputItem[], parentSessionId?: string, session?: Session, cwd?: string): Promise<void>;
|
|
361
|
+
protected openJsonlFile(filePath: string, flags: string): ReturnType<typeof fs.open>;
|
|
362
|
+
/** Short, in-band only: this runs on the addHistory chain, so it is turn latency. */
|
|
363
|
+
protected transcriptRetryDelaysMs(): readonly number[];
|
|
364
|
+
protected sleepBeforeTranscriptRetry(delayMs: number): Promise<void>;
|
|
365
|
+
/** Cumulative transcript persistence counters (issue #119545 埋点). */
|
|
366
|
+
transcriptPersistenceMetrics(): Readonly<TranscriptPersistenceMetrics>;
|
|
228
367
|
/**
|
|
229
|
-
* The transcript-line writer
|
|
230
|
-
* appendHistory body: exclusive-create or append open, chunked line
|
|
368
|
+
* The transcript-line writer: exclusive-create or append open, chunked line
|
|
231
369
|
* writes, and on failure a rollback (unlink a file this batch created,
|
|
232
370
|
* truncate to the original size otherwise) with forensic audit logs.
|
|
371
|
+
*
|
|
372
|
+
* A retryable failure gets a short in-band retry. When the budget runs out
|
|
373
|
+
* the batch is abandoned and reported as a typed error — the local copy is
|
|
374
|
+
* allowed to lose its tail, and `addHistory` keeps the turn running. Read
|
|
375
|
+
* paths repair the gap (unpaired tool calls are filtered out of model
|
|
376
|
+
* input), so the cost of a loss is a shorter history, not a broken one.
|
|
233
377
|
*/
|
|
234
378
|
protected writeTranscriptLines(sessionFilePath: string, lines: string[], key?: SessionKey): Promise<void>;
|
|
379
|
+
private writeTranscriptLinesOnce;
|
|
235
380
|
private readonly entriesStoreInstances;
|
|
236
381
|
/**
|
|
237
382
|
* The embedded SessionStore-contract backend — the single jsonl writer
|
|
@@ -312,3 +457,4 @@ export declare class SessionStoreImpl implements SessionStore {
|
|
|
312
457
|
private cleanupFailedFork;
|
|
313
458
|
rewindSession(source: Session, options: SessionRewindMutationOptions): Promise<void>;
|
|
314
459
|
}
|
|
460
|
+
export {};
|
|
@@ -6,9 +6,21 @@ import type { Session } from './session-protocol';
|
|
|
6
6
|
* terminal results are suppressed only while a retry will actually be scheduled.
|
|
7
7
|
*/
|
|
8
8
|
export declare function hasExhaustedStreamTimeoutRetryBudget(session: Session, isFirstTokenTimeout: boolean): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* `finish_reason=error` 且没有可用输出的两种空流:reasoning-only 与 no-token。
|
|
11
|
+
* placeholder(空 200 / 心跳帧)仍是会话层终态,由拦截器切一次备站。
|
|
12
|
+
*/
|
|
9
13
|
export declare function isRetryableEmptyStreamError(error: unknown): boolean;
|
|
10
14
|
/**
|
|
11
15
|
* Empty 200 / placeholder-only:拦截器最多切一次备站,会话层终态(#115866)。
|
|
12
|
-
* reasoning-only + finish_reason=error
|
|
16
|
+
* reasoning-only / no-token + finish_reason=error:上游瞬时失败,按 error 预算重试。
|
|
17
|
+
* 流空闲超时 / 首 token 超时:按各自的超时预算重试。
|
|
13
18
|
*/
|
|
14
19
|
export declare function shouldAutoRetryStreamTimeout(session: Session, error: unknown): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* 为一次流错误恢复认领额度,返回序号(1-based);不可重试或已耗尽返回 `undefined`。
|
|
22
|
+
* 调用方必须先用 {@link shouldAutoRetryStreamTimeout} 判定,本函数只负责同步认领。
|
|
23
|
+
*/
|
|
24
|
+
export declare function claimStreamRecoveryAttempt(session: Session, error: unknown): number | undefined;
|
|
25
|
+
/** 认领后没有真正发起恢复时退回额度。 */
|
|
26
|
+
export declare function releaseStreamRecoveryAttempt(session: Session, error: unknown): void;
|
|
@@ -364,6 +364,29 @@ export declare abstract class HistoryUtils {
|
|
|
364
364
|
*/
|
|
365
365
|
static filterApiErrorMessages(history: AgentInputItem[]): AgentInputItem[];
|
|
366
366
|
static filterRenameHistory(history: AgentInputItem[]): AgentInputItem[];
|
|
367
|
+
/**
|
|
368
|
+
* 让 model input 里的 tool_call 与 tool_result 严格一一配对(issue #119545)。
|
|
369
|
+
*
|
|
370
|
+
* 背景:工具结果丢失(状态机吞掉 TOOL_ENDED、持久化缺口、压缩切断)后,历史里会留下
|
|
371
|
+
* 只有 call、没有任何 result 的孤儿。上游对 tool_calls 强制配对,一条孤儿就让整个
|
|
372
|
+
* 请求 400,会话从此不可恢复——而本地历史里的孤儿是持久化的,每次恢复都会重现。
|
|
373
|
+
*
|
|
374
|
+
* 三类都处理,因为上游拒的是"不配对"这件事本身,方向无关:
|
|
375
|
+
* 1. call 没有任何同 callId 的结果项 → 丢 call;
|
|
376
|
+
* 2. 同一 callId 出现多条 call(重放/重试残留)→ 只留最后一条;
|
|
377
|
+
* 3. 结果项的 callId 没有留下来的 call(头部被截断,或 call 属于上面两类)→ 丢结果。
|
|
378
|
+
*
|
|
379
|
+
* 判据只看"存在性",不看结果的真伪:skipRun 占位/拒绝、partial aborted 等伪结果都算
|
|
380
|
+
* 配对,它们的取舍归 filterTruncatedToolCalls,两者职责不重叠。改写只落在当轮副本上,
|
|
381
|
+
* 因此日志按轮聚合成一条并截断样本。
|
|
382
|
+
*/
|
|
383
|
+
static filterUnpairedToolCalls(modelData: {
|
|
384
|
+
input: AgentInputItem[];
|
|
385
|
+
instructions?: string;
|
|
386
|
+
}, logger?: Logger): {
|
|
387
|
+
input: AgentInputItem[];
|
|
388
|
+
instructions?: string;
|
|
389
|
+
};
|
|
367
390
|
static getItemsNeedingFill(history: AgentInputItem[]): FunctionCallItem[];
|
|
368
391
|
static getFillItemsForNeedingFill(itemsNeedingFill: FunctionCallItem[]): FunctionCallResultItem[];
|
|
369
392
|
/**
|
|
@@ -79,6 +79,18 @@ export declare abstract class MessageUtils {
|
|
|
79
79
|
static createFilteredCopyForCompaction(messages: AgentInputItem[]): AgentInputItem[];
|
|
80
80
|
private static filterHiddenSystemRemindersForCompaction;
|
|
81
81
|
static stripSystemRemindersOutsideUserQuery(text: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* 压缩链路的统计日志出口。
|
|
84
|
+
*
|
|
85
|
+
* **禁止改回 `process.stderr.write` / `process.stdout.write`**(issue #76749):
|
|
86
|
+
* TUI 下裸写 stderr 会破坏 Ink 帧间光标定位,导致行级 diff 错位、spinner 残留。
|
|
87
|
+
* 走 logger 落盘即可,既保留排查信息又不碰 TTY。
|
|
88
|
+
*
|
|
89
|
+
* `catch` 有意整段吞掉,不做分级上报:日志出口的任何失败(容器未就绪、logger 自身
|
|
90
|
+
* 抛错)都不得影响压缩本身;而「失败时改走 stderr 兜底」恰会在异常路径上重新引入
|
|
91
|
+
* 本 issue 要修掉的 TTY 裸写。统计丢失是可接受的降级。
|
|
92
|
+
*/
|
|
93
|
+
private static logCompaction;
|
|
82
94
|
/**
|
|
83
95
|
* Microcompact: clear output of old tool results (> 1 hour) to reduce token count.
|
|
84
96
|
* Modifies items in place. Should be called BEFORE createFilteredCopyForCompaction.
|
|
@@ -70,6 +70,13 @@ export declare abstract class ModelUtils {
|
|
|
70
70
|
*/
|
|
71
71
|
private static readRuntimeModelId;
|
|
72
72
|
static isHunyuanModel(session: Session): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* ImageGen 实际使用的图片模型是否为混元。
|
|
75
|
+
*
|
|
76
|
+
* 取「产品配置里第一个带 text-to-image tag 的模型」,与 image-service 的解析顺序一致;
|
|
77
|
+
* 配置里没有图片模型时会走客户端的混元兜底模型,同样按混元处理。
|
|
78
|
+
*/
|
|
79
|
+
static isHunyuanImageModel(): Promise<boolean>;
|
|
73
80
|
static isMandatoryApprovalTarget(session: Session, targetToolName: string): Promise<boolean>;
|
|
74
81
|
}
|
|
75
82
|
export {};
|
|
@@ -17,7 +17,8 @@ import type { Session } from '../session/session-protocol';
|
|
|
17
17
|
* 取;CLI **不再自动 drain**。后果有两条,改这块代码前必须知道:
|
|
18
18
|
* 1. `session.queue` 降级为 rich queue 的**展示镜像**(只给 CLI TUI 看),镜像段由
|
|
19
19
|
* `RichMessageQueueManagerImpl.syncToSessionQueue` 整体重建;
|
|
20
|
-
* 2.
|
|
20
|
+
* 2. 主会话的 legacy 自动 drain 路径被短路。子任务没有客户端派发者,仍由
|
|
21
|
+
* MessageQueueAgentRunInterceptor 消费非镜像项(包括普通 user 消息)。
|
|
21
22
|
*
|
|
22
23
|
* 因此在 Mode B 下 `session.queue` 是两个所有者共用的数组:镜像段属于 rich queue,
|
|
23
24
|
* 系统注入项(后台任务通知 / channel / teammate / ACP steer 等)属于各自的注入方。任何一方读写它时
|
|
@@ -63,9 +64,30 @@ export declare abstract class QueueDispatchUtils {
|
|
|
63
64
|
* 从 `session.queue` 里挑出「自动 drain 通道」该消费的项。
|
|
64
65
|
*
|
|
65
66
|
* Mode A:整个队列都是待发输入,原样返回(保持既有行为)。
|
|
66
|
-
* Mode B
|
|
67
|
+
* Mode B 主会话:只返回系统注入项。子任务:所有非镜像项都是真实待发输入。
|
|
67
68
|
*/
|
|
68
69
|
static ownedQueueItems(session: Session): AgentInputItem[];
|
|
70
|
+
/** Task runtimes have no client queue dispatcher, including restored child sessions. */
|
|
71
|
+
static isTaskQueue(session: Session): boolean;
|
|
72
|
+
/** The legacy interceptor owns all Mode A input and Mode B task input, never rich mirrors. */
|
|
73
|
+
static usesLocalQueueDispatch(session: Session): boolean;
|
|
74
|
+
static autoDrainQueueItems(session: Session): AgentInputItem[];
|
|
75
|
+
/**
|
|
76
|
+
* Observe which items one drain invocation actually consumed.
|
|
77
|
+
*
|
|
78
|
+
* **`input` is matched by array *identity*, not contents** — a copy observes
|
|
79
|
+
* nothing, and the caller then reads a failed drain as having consumed
|
|
80
|
+
* nothing. Per instance rather than per session because a session-wide
|
|
81
|
+
* snapshot cannot tell this batch apart from a competing run's.
|
|
82
|
+
*
|
|
83
|
+
* @returns disposer; call it once the run settles.
|
|
84
|
+
*/
|
|
85
|
+
static observeQueueDrain(input: AgentInputItem[], observer: (items: AgentInputItem[], signal?: AbortSignal) => void): () => void;
|
|
86
|
+
/**
|
|
87
|
+
* Report the items consumed for `input`. No-op when nobody observes that
|
|
88
|
+
* exact array instance — see {@link observeQueueDrain} for the contract.
|
|
89
|
+
*/
|
|
90
|
+
static recordQueueDrain(input: AgentInputItem[], items: AgentInputItem[], signal?: AbortSignal): void;
|
|
69
91
|
/**
|
|
70
92
|
* Async check — reads product config when env var is not set.
|
|
71
93
|
*/
|
|
@@ -11,7 +11,10 @@ export declare abstract class SessionUtils {
|
|
|
11
11
|
* session 中发生实际可见的 ID 冲突。
|
|
12
12
|
*/
|
|
13
13
|
static subAgentId(): string;
|
|
14
|
-
static isSubAgent(session:
|
|
14
|
+
static isSubAgent(session: {
|
|
15
|
+
id?: string;
|
|
16
|
+
storeId?: string;
|
|
17
|
+
}): boolean;
|
|
15
18
|
/**
|
|
16
19
|
* Clone one history item for a fork without duplicating large string payloads.
|
|
17
20
|
*
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Materialize an independent string without changing its UTF-16 code units. */
|
|
2
|
+
export declare function copyString(value: string): string;
|
|
3
|
+
/** Truncate by JavaScript string length and detach the retained prefix from its parent. */
|
|
4
|
+
export declare function truncateAndCopyString(value: string, maxLength: number, suffix?: string): string;
|
|
@@ -83,7 +83,13 @@ export declare enum HookEvent {
|
|
|
83
83
|
FILE_CHANGED = "FileChanged",
|
|
84
84
|
CWD_CHANGED = "CwdChanged",
|
|
85
85
|
/** Terminal event; does not support continueRequest. */
|
|
86
|
-
FINAL_STOP = "FinalStop"
|
|
86
|
+
FINAL_STOP = "FinalStop",
|
|
87
|
+
/**
|
|
88
|
+
* Triggered when a user-typed command/skill expands into a prompt, before
|
|
89
|
+
* it reaches the model. Can block the expansion.
|
|
90
|
+
* Claude Code parity: matcher filters on `command_name`.
|
|
91
|
+
*/
|
|
92
|
+
USER_PROMPT_EXPANSION = "UserPromptExpansion"
|
|
87
93
|
}
|
|
88
94
|
/** Hook script stdout payload. */
|
|
89
95
|
export interface HookOutput {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from './agent/openai-agents-types';
|
|
2
2
|
export * from './agent-home/agent-home-envelope-body';
|
|
3
3
|
export * from './utils/abort-utils';
|
|
4
|
+
export * from './utils/retry-backoff';
|
|
5
|
+
export * from './utils/retry-policy';
|
|
4
6
|
export * from './settings/settings-types';
|
|
5
7
|
export * from './tools/tool-permission-types';
|
|
6
8
|
export * from './tools/tool-permission-messages';
|
|
@@ -17,10 +17,14 @@ export declare class StreamTimeoutError extends CustomError {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* placeholder:空 200 / 心跳占位,拦截器最多切一次备站,会话层终态。
|
|
20
|
-
* reasoning-only:已流出思考、finish_reason=error 且无可用输出(#63761 / #122115
|
|
21
|
-
*
|
|
20
|
+
* reasoning-only:已流出思考、finish_reason=error 且无可用输出(#63761 / #122115)。
|
|
21
|
+
* no-token:finish_reason=error 到达时一个模型 token 都没有(连 reasoning 也没有)。
|
|
22
|
+
*
|
|
23
|
+
* reasoning-only 与 no-token 都是上游瞬时失败,会话层按 error 恢复预算重试;
|
|
24
|
+
* placeholder 必须与 no-token 分开——两者共用一个值时,放开 no-token 会连带
|
|
25
|
+
* 推翻空 200 的终态判定。
|
|
22
26
|
*/
|
|
23
|
-
export type EmptyStreamKind = 'placeholder' | 'reasoning-only';
|
|
27
|
+
export type EmptyStreamKind = 'placeholder' | 'reasoning-only' | 'no-token';
|
|
24
28
|
/**
|
|
25
29
|
* 空流错误
|
|
26
30
|
* 语义上仍然是"上游没有提供模型输出",所以继承 StreamTimeoutError
|
|
@@ -63,6 +63,7 @@ export declare enum ToolNames {
|
|
|
63
63
|
WAIT_FOR_MCP_SERVERS = "WaitForMcpServers",
|
|
64
64
|
WORKFLOW = "Workflow",
|
|
65
65
|
VIDEO_GEN = "VideoGen",
|
|
66
|
+
AUDIO_TRANSCRIBE = "AudioTranscribe",
|
|
66
67
|
REPORT_FINDINGS = "ReportFindings",
|
|
67
68
|
MONITOR = "Monitor",
|
|
68
69
|
LIST_AGENTS = "ListAgents",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自动恢复链的统一口径:最多 3 次,1s 起步、2 倍指数退避(基准 1s → 2s → 4s)。
|
|
3
|
+
*
|
|
4
|
+
* 适用于会话层的 error / 网络 / 流超时恢复,以及模型层的连接级透明重试。
|
|
5
|
+
* 第 1 层请求级(429/502/503 等)不带网关 retry_policy 时仍保持自己的 500ms 基数,
|
|
6
|
+
* 所以这里只共享算法,基数与上限由调用方传入。
|
|
7
|
+
*/
|
|
8
|
+
export declare const MAX_RECOVERY_RETRIES = 3;
|
|
9
|
+
export declare const RECOVERY_RETRY_BASE_DELAY_MS = 1000;
|
|
10
|
+
export declare const RECOVERY_RETRY_MAX_DELAY_MS = 32000;
|
|
11
|
+
export interface ExponentialBackoffOptions {
|
|
12
|
+
baseDelayMs: number;
|
|
13
|
+
maxDelayMs: number;
|
|
14
|
+
random?: () => number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `base * 2^(attempt-1)` 封顶到 `maxDelayMs`,再做 25% 下减抖动(区间 `[0.75x, 1x]`)。
|
|
18
|
+
*
|
|
19
|
+
* 必须下减而不是上加:上加会让实际等待越过 `maxDelayMs` 25%,调用方对封顶的承诺就不成立。
|
|
20
|
+
* `attempt` 从 1 起,小于 1 按 1 处理。
|
|
21
|
+
*/
|
|
22
|
+
export declare function computeExponentialBackoffMs(attempt: number, options: ExponentialBackoffOptions): number;
|
|
23
|
+
export declare function computeRecoveryBackoffMs(attempt: number, random?: () => number): number;
|
|
24
|
+
/**
|
|
25
|
+
* 可取消的等待。`signal` 在等待前或等待中 abort 时返回 `false`,正常等满返回 `true`。
|
|
26
|
+
*
|
|
27
|
+
* 返回布尔而不是 reject:恢复链上的调用方拿到 `false` 后要自己决定退还额度、跳过发起,
|
|
28
|
+
* 用异常表达会把「用户取消」和「真正的错误」混在一条 catch 路径里。
|
|
29
|
+
*/
|
|
30
|
+
export declare function waitForRecoveryBackoff(ms: number, signal?: AbortSignal): Promise<boolean>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模型网关在 HTTP 错误体里下发的重试指示,与 `code` / `msg` / `displayMsg` 同层:
|
|
3
|
+
*
|
|
4
|
+
* ```json
|
|
5
|
+
* { "code": 11101, "msg": "...", "retry_policy": { "retry": false }, "displayMsg": { ... } }
|
|
6
|
+
* ```
|
|
7
|
+
*
|
|
8
|
+
* - `force-retry`:策略是普通对象且 `retry !== false`(含 `true`、缺 `retry` 键、类型异常)。
|
|
9
|
+
* 只在本地已判定可重试的范围内把请求级重试提到 3 次,不扩大可重试状态码。
|
|
10
|
+
* - `forbid-retry`:策略是普通对象且 `retry === false`。不重试、不换模型、不重放备站、不做鉴权刷新重试。
|
|
11
|
+
* - `unset`:字段缺失、`null`、数组或其他非对象形态,完全按原有逻辑处理。
|
|
12
|
+
*
|
|
13
|
+
* 只有显式 `false` 才阻断:网关形态小改动时宁可多试一次,也不要静默丧失恢复能力。
|
|
14
|
+
*/
|
|
15
|
+
export type RetryPolicyDecision = 'force-retry' | 'forbid-retry' | 'unset';
|
|
16
|
+
export declare const RETRY_POLICY_FIELD = "retry_policy";
|
|
17
|
+
/**
|
|
18
|
+
* 按固定层级找 `retry_policy` 原值,返回第一个存在的值(可能是非法形态,由调用方裁决)。
|
|
19
|
+
*
|
|
20
|
+
* 同一份策略会以三种形态出现:网关原始错误体(顶层或 `data` / `error.data`)、错误分析器
|
|
21
|
+
* 规范化后的 `{ error: { code, message, data } }`、SDK 包装后的 APIError(`error.data`,
|
|
22
|
+
* 外层再包一层时为 `error.error.data`)。层级写死、不递归,避免在任意嵌套里误捡字段。
|
|
23
|
+
*/
|
|
24
|
+
export declare function findRetryPolicy(source: unknown): unknown;
|
|
25
|
+
export declare function decideRetryPolicy(policy: unknown): RetryPolicyDecision;
|
|
26
|
+
export declare function resolveRetryPolicy(source: unknown): RetryPolicyDecision;
|