qlogicagent 0.2.1 → 0.4.0
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/README.md +45 -45
- package/package.json +56 -42
- package/dist/agent/agent.d.ts +0 -43
- package/dist/agent/agent.js +0 -113
- package/dist/agent/tool-loop.d.ts +0 -64
- package/dist/agent/tool-loop.js +0 -575
- package/dist/agent/types.d.ts +0 -175
- package/dist/agent/types.js +0 -14
- package/dist/cli/main.d.ts +0 -11
- package/dist/cli/main.js +0 -23
- package/dist/cli/stdio-server.d.ts +0 -45
- package/dist/cli/stdio-server.js +0 -463
- package/dist/config/config.d.ts +0 -17
- package/dist/config/config.js +0 -21
- package/dist/contracts/hooks.d.ts +0 -120
- package/dist/contracts/hooks.js +0 -7
- package/dist/contracts/index.d.ts +0 -10
- package/dist/contracts/index.js +0 -10
- package/dist/contracts/planner.d.ts +0 -35
- package/dist/contracts/planner.js +0 -2
- package/dist/contracts/skill-candidate.d.ts +0 -63
- package/dist/contracts/skill-candidate.js +0 -195
- package/dist/contracts/todo.d.ts +0 -14
- package/dist/contracts/todo.js +0 -9
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -15
- package/dist/llm/builtin-providers.d.ts +0 -10
- package/dist/llm/builtin-providers.js +0 -531
- package/dist/llm/index.d.ts +0 -15
- package/dist/llm/index.js +0 -14
- package/dist/llm/llm-client.d.ts +0 -43
- package/dist/llm/llm-client.js +0 -67
- package/dist/llm/model-catalog.d.ts +0 -53
- package/dist/llm/model-catalog.js +0 -191
- package/dist/llm/provider-def.d.ts +0 -59
- package/dist/llm/provider-def.js +0 -12
- package/dist/llm/provider-registry.d.ts +0 -54
- package/dist/llm/provider-registry.js +0 -147
- package/dist/llm/transport.d.ts +0 -62
- package/dist/llm/transport.js +0 -27
- package/dist/llm/transports/anthropic-messages.d.ts +0 -31
- package/dist/llm/transports/anthropic-messages.js +0 -293
- package/dist/llm/transports/openai-chat.d.ts +0 -36
- package/dist/llm/transports/openai-chat.js +0 -165
- package/dist/orchestration/agent-registry.d.ts +0 -41
- package/dist/orchestration/agent-registry.js +0 -116
- package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
- package/dist/orchestration/approval-aware-tool-plan.js +0 -87
- package/dist/orchestration/context-compression.d.ts +0 -220
- package/dist/orchestration/context-compression.js +0 -583
- package/dist/orchestration/conversation-repair.d.ts +0 -61
- package/dist/orchestration/conversation-repair.js +0 -429
- package/dist/orchestration/curator-scheduler.d.ts +0 -119
- package/dist/orchestration/curator-scheduler.js +0 -135
- package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
- package/dist/orchestration/embedded-failover-policy.js +0 -168
- package/dist/orchestration/error-classification.d.ts +0 -12
- package/dist/orchestration/error-classification.js +0 -77
- package/dist/orchestration/failover-classification.d.ts +0 -8
- package/dist/orchestration/failover-classification.js +0 -381
- package/dist/orchestration/failover-error.d.ts +0 -33
- package/dist/orchestration/failover-error.js +0 -198
- package/dist/orchestration/fork-subagent.d.ts +0 -100
- package/dist/orchestration/fork-subagent.js +0 -98
- package/dist/orchestration/index.d.ts +0 -120
- package/dist/orchestration/index.js +0 -267
- package/dist/orchestration/memory-flush-policy.d.ts +0 -57
- package/dist/orchestration/memory-flush-policy.js +0 -85
- package/dist/orchestration/memory-provider.d.ts +0 -14
- package/dist/orchestration/memory-provider.js +0 -2
- package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
- package/dist/orchestration/parallel-tool-calls.js +0 -59
- package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
- package/dist/orchestration/prompt-cache-strategy.js +0 -228
- package/dist/orchestration/reactive-compact.d.ts +0 -73
- package/dist/orchestration/reactive-compact.js +0 -78
- package/dist/orchestration/retry-loop.d.ts +0 -22
- package/dist/orchestration/retry-loop.js +0 -24
- package/dist/orchestration/skill-candidate.d.ts +0 -52
- package/dist/orchestration/skill-candidate.js +0 -141
- package/dist/orchestration/skill-consolidation.d.ts +0 -123
- package/dist/orchestration/skill-consolidation.js +0 -220
- package/dist/orchestration/skill-improvement.d.ts +0 -59
- package/dist/orchestration/skill-improvement.js +0 -66
- package/dist/orchestration/skill-similarity.d.ts +0 -98
- package/dist/orchestration/skill-similarity.js +0 -131
- package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
- package/dist/orchestration/streaming-tool-executor.js +0 -96
- package/dist/orchestration/team-orchestration.d.ts +0 -195
- package/dist/orchestration/team-orchestration.js +0 -369
- package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
- package/dist/orchestration/team-tool-loop-wiring.js +0 -147
- package/dist/orchestration/tool-choice-policy.d.ts +0 -54
- package/dist/orchestration/tool-choice-policy.js +0 -164
- package/dist/orchestration/tool-loop-state.d.ts +0 -50
- package/dist/orchestration/tool-loop-state.js +0 -133
- package/dist/orchestration/tool-schema.d.ts +0 -39
- package/dist/orchestration/tool-schema.js +0 -297
- package/dist/orchestration/transcript-repair.d.ts +0 -42
- package/dist/orchestration/transcript-repair.js +0 -426
- package/dist/orchestration/turn-loop-guard.d.ts +0 -86
- package/dist/orchestration/turn-loop-guard.js +0 -92
- package/dist/orchestration/web-browser-policy.d.ts +0 -17
- package/dist/orchestration/web-browser-policy.js +0 -39
- package/dist/runtime/context-compression.d.ts +0 -61
- package/dist/runtime/context-compression.js +0 -274
- package/dist/runtime/hook-registry.d.ts +0 -12
- package/dist/runtime/hook-registry.js +0 -53
- package/dist/runtime/memory-hooks.d.ts +0 -23
- package/dist/runtime/memory-hooks.js +0 -65
- package/dist/runtime/tool-eligibility.d.ts +0 -59
- package/dist/runtime/tool-eligibility.js +0 -111
- package/dist/skills/index.d.ts +0 -108
- package/dist/skills/index.js +0 -82
- package/dist/skills/memory-extractor.d.ts +0 -64
- package/dist/skills/memory-extractor.js +0 -173
- package/dist/skills/memory-query-tool.d.ts +0 -43
- package/dist/skills/memory-query-tool.js +0 -127
- package/dist/skills/memory-store.d.ts +0 -66
- package/dist/skills/memory-store.js +0 -228
- package/dist/skills/memory-tool.d.ts +0 -67
- package/dist/skills/memory-tool.js +0 -192
- package/dist/skills/portable-tool.d.ts +0 -71
- package/dist/skills/portable-tool.js +0 -14
- package/dist/skills/qmemory-adapter.d.ts +0 -52
- package/dist/skills/qmemory-adapter.js +0 -165
- package/dist/skills/skill-frontmatter.d.ts +0 -19
- package/dist/skills/skill-frontmatter.js +0 -344
- package/dist/skills/skill-guard.d.ts +0 -23
- package/dist/skills/skill-guard.js +0 -229
- package/dist/skills/skill-loader.d.ts +0 -16
- package/dist/skills/skill-loader.js +0 -303
- package/dist/skills/skill-source.d.ts +0 -119
- package/dist/skills/skill-source.js +0 -126
- package/dist/skills/skill-types.d.ts +0 -199
- package/dist/skills/skill-types.js +0 -6
- package/dist/skills/think-tool.d.ts +0 -16
- package/dist/skills/think-tool.js +0 -59
- package/dist/skills/todo-tool.d.ts +0 -63
- package/dist/skills/todo-tool.js +0 -114
- package/dist/skills/tools/agent-tool.d.ts +0 -91
- package/dist/skills/tools/agent-tool.js +0 -142
- package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
- package/dist/skills/tools/apply-patch-tool.js +0 -184
- package/dist/skills/tools/ask-user-tool.d.ts +0 -80
- package/dist/skills/tools/ask-user-tool.js +0 -121
- package/dist/skills/tools/brief-tool.d.ts +0 -74
- package/dist/skills/tools/brief-tool.js +0 -95
- package/dist/skills/tools/browser-tool.d.ts +0 -114
- package/dist/skills/tools/browser-tool.js +0 -155
- package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
- package/dist/skills/tools/checkpoint-tool.js +0 -102
- package/dist/skills/tools/config-tool.d.ts +0 -63
- package/dist/skills/tools/config-tool.js +0 -143
- package/dist/skills/tools/cron-tool.d.ts +0 -116
- package/dist/skills/tools/cron-tool.js +0 -175
- package/dist/skills/tools/edit-tool.d.ts +0 -43
- package/dist/skills/tools/edit-tool.js +0 -70
- package/dist/skills/tools/exec-tool.d.ts +0 -102
- package/dist/skills/tools/exec-tool.js +0 -133
- package/dist/skills/tools/image-generate-tool.d.ts +0 -62
- package/dist/skills/tools/image-generate-tool.js +0 -67
- package/dist/skills/tools/instructions-tool.d.ts +0 -103
- package/dist/skills/tools/instructions-tool.js +0 -187
- package/dist/skills/tools/lsp-tool.d.ts +0 -153
- package/dist/skills/tools/lsp-tool.js +0 -227
- package/dist/skills/tools/mcp-client-types.d.ts +0 -269
- package/dist/skills/tools/mcp-client-types.js +0 -53
- package/dist/skills/tools/mcp-tool.d.ts +0 -249
- package/dist/skills/tools/mcp-tool.js +0 -503
- package/dist/skills/tools/memory-tool.d.ts +0 -74
- package/dist/skills/tools/memory-tool.js +0 -88
- package/dist/skills/tools/monitor-tool.d.ts +0 -113
- package/dist/skills/tools/monitor-tool.js +0 -131
- package/dist/skills/tools/music-generate-tool.d.ts +0 -55
- package/dist/skills/tools/music-generate-tool.js +0 -62
- package/dist/skills/tools/notify-tool.d.ts +0 -53
- package/dist/skills/tools/notify-tool.js +0 -62
- package/dist/skills/tools/patch-tool.d.ts +0 -45
- package/dist/skills/tools/patch-tool.js +0 -505
- package/dist/skills/tools/pdf-tool.d.ts +0 -66
- package/dist/skills/tools/pdf-tool.js +0 -88
- package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
- package/dist/skills/tools/plan-mode-tool.js +0 -122
- package/dist/skills/tools/read-tool.d.ts +0 -51
- package/dist/skills/tools/read-tool.js +0 -84
- package/dist/skills/tools/repl-tool.d.ts +0 -70
- package/dist/skills/tools/repl-tool.js +0 -69
- package/dist/skills/tools/search-tool.d.ts +0 -112
- package/dist/skills/tools/search-tool.js +0 -225
- package/dist/skills/tools/send-message-tool.d.ts +0 -51
- package/dist/skills/tools/send-message-tool.js +0 -76
- package/dist/skills/tools/skill-list-tool.d.ts +0 -33
- package/dist/skills/tools/skill-list-tool.js +0 -54
- package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
- package/dist/skills/tools/skill-manage-tool.js +0 -153
- package/dist/skills/tools/skill-view-tool.d.ts +0 -37
- package/dist/skills/tools/skill-view-tool.js +0 -72
- package/dist/skills/tools/sleep-tool.d.ts +0 -49
- package/dist/skills/tools/sleep-tool.js +0 -81
- package/dist/skills/tools/structured-output-tool.d.ts +0 -116
- package/dist/skills/tools/structured-output-tool.js +0 -176
- package/dist/skills/tools/task-tool.d.ts +0 -104
- package/dist/skills/tools/task-tool.js +0 -161
- package/dist/skills/tools/team-tool.d.ts +0 -89
- package/dist/skills/tools/team-tool.js +0 -105
- package/dist/skills/tools/tool-search-tool.d.ts +0 -51
- package/dist/skills/tools/tool-search-tool.js +0 -110
- package/dist/skills/tools/tts-tool.d.ts +0 -38
- package/dist/skills/tools/tts-tool.js +0 -45
- package/dist/skills/tools/video-edit-tool.d.ts +0 -69
- package/dist/skills/tools/video-edit-tool.js +0 -74
- package/dist/skills/tools/video-generate-tool.d.ts +0 -62
- package/dist/skills/tools/video-generate-tool.js +0 -66
- package/dist/skills/tools/video-merge-tool.d.ts +0 -105
- package/dist/skills/tools/video-merge-tool.js +0 -92
- package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
- package/dist/skills/tools/video-upscale-tool.js +0 -52
- package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
- package/dist/skills/tools/web-fetch-tool.js +0 -92
- package/dist/skills/tools/web-search-tool.d.ts +0 -57
- package/dist/skills/tools/web-search-tool.js +0 -86
- package/dist/skills/tools/worktree-tool.d.ts +0 -69
- package/dist/skills/tools/worktree-tool.js +0 -147
- package/dist/skills/tools/write-tool.d.ts +0 -45
- package/dist/skills/tools/write-tool.js +0 -81
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
export function hasAlreadyFlushedForCurrentCompaction(entry) {
|
|
2
|
-
const compactionCount = entry.compactionCount ?? 0;
|
|
3
|
-
const lastFlushAt = entry.memoryFlushCompactionCount;
|
|
4
|
-
return typeof lastFlushAt === "number" && lastFlushAt === compactionCount;
|
|
5
|
-
}
|
|
6
|
-
export function shouldRunMemoryFlush(params) {
|
|
7
|
-
if (!params.entry) {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
const override = params.tokenCount;
|
|
11
|
-
const overrideTokens = typeof override === "number" && Number.isFinite(override) && override > 0
|
|
12
|
-
? Math.floor(override)
|
|
13
|
-
: undefined;
|
|
14
|
-
const totalTokens = overrideTokens ?? params.resolveFreshSessionTotalTokens(params.entry);
|
|
15
|
-
if (!totalTokens || totalTokens <= 0) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
const contextWindow = Math.max(1, Math.floor(params.contextWindowTokens));
|
|
19
|
-
const reserveTokens = Math.max(0, Math.floor(params.reserveTokensFloor));
|
|
20
|
-
const softThreshold = Math.max(0, Math.floor(params.softThresholdTokens));
|
|
21
|
-
const threshold = Math.max(0, contextWindow - reserveTokens - softThreshold);
|
|
22
|
-
if (threshold <= 0 || totalTokens < threshold) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
if (hasAlreadyFlushedForCurrentCompaction(params.entry)) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
export function resolveMemoryFlushReadPlan(params) {
|
|
31
|
-
const canAttemptFlush = params.memoryFlushWritable && !params.isHeartbeat && !params.isCli;
|
|
32
|
-
const flushThreshold = params.contextWindowTokens - params.reserveTokensFloor - params.softThresholdTokens;
|
|
33
|
-
const shouldReadTranscriptForOutput = canAttemptFlush &&
|
|
34
|
-
params.hasSessionEntry &&
|
|
35
|
-
params.hasFreshPersistedPromptTokens &&
|
|
36
|
-
typeof params.promptTokenEstimate === "number" &&
|
|
37
|
-
Number.isFinite(params.promptTokenEstimate) &&
|
|
38
|
-
flushThreshold > 0 &&
|
|
39
|
-
(params.persistedPromptTokens ?? 0) + params.promptTokenEstimate >=
|
|
40
|
-
flushThreshold - params.transcriptOutputReadBufferTokens;
|
|
41
|
-
const shouldReadTranscript = Boolean(canAttemptFlush &&
|
|
42
|
-
params.hasSessionEntry &&
|
|
43
|
-
(!params.hasFreshPersistedPromptTokens || shouldReadTranscriptForOutput));
|
|
44
|
-
const shouldCheckTranscriptSizeForForcedFlush = Boolean(canAttemptFlush &&
|
|
45
|
-
params.hasSessionEntry &&
|
|
46
|
-
Number.isFinite(params.forceFlushTranscriptBytes) &&
|
|
47
|
-
params.forceFlushTranscriptBytes > 0);
|
|
48
|
-
return {
|
|
49
|
-
canAttemptFlush,
|
|
50
|
-
flushThreshold,
|
|
51
|
-
shouldReadTranscriptForOutput,
|
|
52
|
-
shouldReadTranscript,
|
|
53
|
-
shouldCheckTranscriptSizeForForcedFlush,
|
|
54
|
-
shouldReadSessionLog: shouldReadTranscript || shouldCheckTranscriptSizeForForcedFlush,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
export function resolveMemoryFlushProjection(params) {
|
|
58
|
-
const shouldForceFlushByTranscriptSize = typeof params.transcriptByteSize === "number" &&
|
|
59
|
-
params.transcriptByteSize >= params.forceFlushTranscriptBytes;
|
|
60
|
-
const hasReliableTranscriptPromptTokens = typeof params.transcriptPromptTokens === "number" &&
|
|
61
|
-
Number.isFinite(params.transcriptPromptTokens) &&
|
|
62
|
-
params.transcriptPromptTokens > 0;
|
|
63
|
-
const shouldPersistTranscriptPromptTokens = hasReliableTranscriptPromptTokens &&
|
|
64
|
-
(!params.hasFreshPersistedPromptTokens ||
|
|
65
|
-
(params.transcriptPromptTokens ?? 0) > (params.persistedPromptTokens ?? 0));
|
|
66
|
-
const promptTokensSnapshot = Math.max(params.hasFreshPersistedPromptTokens ? (params.persistedPromptTokens ?? 0) : 0, hasReliableTranscriptPromptTokens ? (params.transcriptPromptTokens ?? 0) : 0);
|
|
67
|
-
const hasFreshPromptTokensSnapshot = promptTokensSnapshot > 0 &&
|
|
68
|
-
(params.hasFreshPersistedPromptTokens || hasReliableTranscriptPromptTokens);
|
|
69
|
-
const projectedTokenCount = hasFreshPromptTokensSnapshot
|
|
70
|
-
? params.resolveEffectivePromptTokens(promptTokensSnapshot, params.transcriptOutputTokens, params.promptTokenEstimate)
|
|
71
|
-
: undefined;
|
|
72
|
-
const tokenCountForFlush = typeof projectedTokenCount === "number" &&
|
|
73
|
-
Number.isFinite(projectedTokenCount) &&
|
|
74
|
-
projectedTokenCount > 0
|
|
75
|
-
? projectedTokenCount
|
|
76
|
-
: undefined;
|
|
77
|
-
return {
|
|
78
|
-
shouldForceFlushByTranscriptSize,
|
|
79
|
-
shouldPersistTranscriptPromptTokens,
|
|
80
|
-
promptTokensSnapshot,
|
|
81
|
-
hasFreshPromptTokensSnapshot,
|
|
82
|
-
projectedTokenCount,
|
|
83
|
-
tokenCountForFlush,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { MEMORY_OBSERVATION_HOOK_VALUES, type MemoryObservationHook, MEMORY_OBSERVATION_SOURCE_VALUES, type MemoryObservationSource, MEMORY_WRITE_ACCESS_VALUES, type MemoryWriteAccess } from "qlogicagent-runtime-contracts";
|
|
2
|
-
export { MEMORY_OBSERVATION_HOOK_VALUES, type MemoryObservationHook, MEMORY_OBSERVATION_SOURCE_VALUES, type MemoryObservationSource, MEMORY_WRITE_ACCESS_VALUES, type MemoryWriteAccess, };
|
|
3
|
-
export interface MemoryProviderLifecycleInvocation {
|
|
4
|
-
hook: MemoryObservationHook;
|
|
5
|
-
source: MemoryObservationSource;
|
|
6
|
-
sessionId: string;
|
|
7
|
-
turnId?: string;
|
|
8
|
-
executionId?: string;
|
|
9
|
-
rootExecutionId?: string;
|
|
10
|
-
parentExecutionId?: string;
|
|
11
|
-
sidechainId?: string;
|
|
12
|
-
attemptId?: string;
|
|
13
|
-
writeAccess: MemoryWriteAccess;
|
|
14
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export type ParallelToolCallsPreference = {
|
|
2
|
-
kind: "enabled";
|
|
3
|
-
enabled: boolean;
|
|
4
|
-
} | {
|
|
5
|
-
kind: "suppressed";
|
|
6
|
-
} | {
|
|
7
|
-
kind: "invalid";
|
|
8
|
-
summary: string;
|
|
9
|
-
};
|
|
10
|
-
export interface ToolCallLike {
|
|
11
|
-
id: string;
|
|
12
|
-
function: {
|
|
13
|
-
name: string;
|
|
14
|
-
arguments?: string;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export interface ToolCapabilityLike {
|
|
18
|
-
name: string;
|
|
19
|
-
requiresApproval?: boolean;
|
|
20
|
-
approvalMode?: string;
|
|
21
|
-
parallelSafe?: boolean;
|
|
22
|
-
serialOnly?: boolean;
|
|
23
|
-
}
|
|
24
|
-
export interface ToolCallBatch<TCall extends ToolCallLike> {
|
|
25
|
-
mode: "parallel" | "serial";
|
|
26
|
-
calls: TCall[];
|
|
27
|
-
}
|
|
28
|
-
export interface ResolveParallelToolCallSchedulingInput<TCall extends ToolCallLike, TCapability extends ToolCapabilityLike> {
|
|
29
|
-
requestedPreference?: unknown;
|
|
30
|
-
providerSupportsParallel?: boolean;
|
|
31
|
-
toolCalls: readonly TCall[];
|
|
32
|
-
toolCapabilities?: readonly TCapability[];
|
|
33
|
-
}
|
|
34
|
-
export interface ResolveParallelToolCallSchedulingResult<TCall extends ToolCallLike> {
|
|
35
|
-
enabled: boolean;
|
|
36
|
-
mode: "parallel" | "serial";
|
|
37
|
-
batches: Array<ToolCallBatch<TCall>>;
|
|
38
|
-
warnings: string[];
|
|
39
|
-
}
|
|
40
|
-
export declare function normalizeParallelToolCallsPreference(rawValue: unknown): ParallelToolCallsPreference | undefined;
|
|
41
|
-
export declare function resolveParallelToolCallScheduling<TCall extends ToolCallLike, TCapability extends ToolCapabilityLike>(params: ResolveParallelToolCallSchedulingInput<TCall, TCapability>): ResolveParallelToolCallSchedulingResult<TCall>;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export function normalizeParallelToolCallsPreference(rawValue) {
|
|
2
|
-
if (rawValue === undefined) {
|
|
3
|
-
return undefined;
|
|
4
|
-
}
|
|
5
|
-
if (typeof rawValue === "boolean") {
|
|
6
|
-
return { kind: "enabled", enabled: rawValue };
|
|
7
|
-
}
|
|
8
|
-
if (rawValue === null) {
|
|
9
|
-
return { kind: "suppressed" };
|
|
10
|
-
}
|
|
11
|
-
return {
|
|
12
|
-
kind: "invalid",
|
|
13
|
-
summary: typeof rawValue === "string" ? rawValue : typeof rawValue,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export function resolveParallelToolCallScheduling(params) {
|
|
17
|
-
const warnings = [];
|
|
18
|
-
const preference = normalizeParallelToolCallsPreference(params.requestedPreference);
|
|
19
|
-
const capabilityMap = new Map((params.toolCapabilities ?? []).map((capability) => [capability.name, capability]));
|
|
20
|
-
let enabled = params.providerSupportsParallel !== false;
|
|
21
|
-
if (preference?.kind === "enabled") {
|
|
22
|
-
enabled = preference.enabled && params.providerSupportsParallel !== false;
|
|
23
|
-
}
|
|
24
|
-
else if (preference?.kind === "suppressed") {
|
|
25
|
-
enabled = false;
|
|
26
|
-
}
|
|
27
|
-
else if (preference?.kind === "invalid") {
|
|
28
|
-
warnings.push(`ignoring invalid parallel_tool_calls param: ${preference.summary}`);
|
|
29
|
-
}
|
|
30
|
-
if (enabled && params.providerSupportsParallel === false) {
|
|
31
|
-
warnings.push("provider does not support parallel tool calls; downgraded to serial execution.");
|
|
32
|
-
}
|
|
33
|
-
const batches = [];
|
|
34
|
-
let currentParallelBatch = [];
|
|
35
|
-
const flushParallelBatch = () => {
|
|
36
|
-
if (currentParallelBatch.length === 0) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
batches.push({ mode: "parallel", calls: currentParallelBatch });
|
|
40
|
-
currentParallelBatch = [];
|
|
41
|
-
};
|
|
42
|
-
for (const toolCall of params.toolCalls) {
|
|
43
|
-
const capability = capabilityMap.get(toolCall.function.name);
|
|
44
|
-
const mustSerialize = !enabled || capability?.requiresApproval === true || capability?.serialOnly === true || capability?.parallelSafe === false || capability?.approvalMode === "user-confirm";
|
|
45
|
-
if (mustSerialize) {
|
|
46
|
-
flushParallelBatch();
|
|
47
|
-
batches.push({ mode: "serial", calls: [toolCall] });
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
currentParallelBatch.push(toolCall);
|
|
51
|
-
}
|
|
52
|
-
flushParallelBatch();
|
|
53
|
-
return {
|
|
54
|
-
enabled,
|
|
55
|
-
mode: batches.some((batch) => batch.mode === "parallel" && batch.calls.length > 1) ? "parallel" : "serial",
|
|
56
|
-
batches,
|
|
57
|
-
warnings,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/** Retention hint passed to the provider. */
|
|
2
|
-
export type CacheRetention = "none" | "short" | "long";
|
|
3
|
-
/** A message in the conversation array eligible for cache marking. */
|
|
4
|
-
export interface CacheableMessage {
|
|
5
|
-
role: string;
|
|
6
|
-
content?: string | unknown;
|
|
7
|
-
name?: string;
|
|
8
|
-
tool_calls?: unknown;
|
|
9
|
-
tool_call_id?: string;
|
|
10
|
-
}
|
|
11
|
-
/** Segment classification for stability analysis. */
|
|
12
|
-
export type CacheSegmentKind = "system" | "tool-definition" | "conversation" | "recent";
|
|
13
|
-
/** Configuration for the cache marking policy. */
|
|
14
|
-
export interface PromptCachePolicy {
|
|
15
|
-
/** Max breakpoints the provider supports (Anthropic: 4). */
|
|
16
|
-
maxBreakpoints: number;
|
|
17
|
-
/** Cache retention hint. */
|
|
18
|
-
retention: CacheRetention;
|
|
19
|
-
/** Minimum estimated tokens in a segment to justify a breakpoint. */
|
|
20
|
-
minSegmentTokens: number;
|
|
21
|
-
/** Number of trailing messages considered "recent" (never marked). */
|
|
22
|
-
recentTailCount: number;
|
|
23
|
-
/** Whether tool-definition blocks should be treated as stable prefix. */
|
|
24
|
-
markToolDefinitions: boolean;
|
|
25
|
-
}
|
|
26
|
-
/** A computed breakpoint recommendation. */
|
|
27
|
-
export interface CacheBreakpoint {
|
|
28
|
-
/** Zero-based index in the original message array. */
|
|
29
|
-
index: number;
|
|
30
|
-
/** Classification of the segment ending at this index. */
|
|
31
|
-
segment: CacheSegmentKind;
|
|
32
|
-
/** Estimated tokens in this segment (if estimator provided). */
|
|
33
|
-
estimatedTokens?: number;
|
|
34
|
-
}
|
|
35
|
-
/** Result of the cache marking analysis. */
|
|
36
|
-
export interface CacheMarkingResult {
|
|
37
|
-
/** Recommended breakpoints, ordered by index ascending. */
|
|
38
|
-
breakpoints: CacheBreakpoint[];
|
|
39
|
-
/** Total estimated cacheable tokens (sum of breakpoint segments). */
|
|
40
|
-
estimatedCacheableTokens: number;
|
|
41
|
-
/** The retention hint from policy. */
|
|
42
|
-
retention: CacheRetention;
|
|
43
|
-
}
|
|
44
|
-
export declare const DEFAULT_PROMPT_CACHE_POLICY: PromptCachePolicy;
|
|
45
|
-
/**
|
|
46
|
-
* Analyse a message array and return recommended cache breakpoints.
|
|
47
|
-
*
|
|
48
|
-
* The algorithm:
|
|
49
|
-
* 1. Classify each message into segments (system / tool-def / conversation / recent).
|
|
50
|
-
* 2. Identify segment boundaries where the classification changes.
|
|
51
|
-
* 3. Rank boundaries by estimated token cost (heaviest first).
|
|
52
|
-
* 4. Select the top `maxBreakpoints` that meet `minSegmentTokens`.
|
|
53
|
-
*
|
|
54
|
-
* @param messages The conversation message array (in order).
|
|
55
|
-
* @param estimateTokens Optional per-message token estimator. Falls back to
|
|
56
|
-
* character-length heuristic (1 token ≈ 4 chars).
|
|
57
|
-
* @param policy Cache marking policy (uses defaults if omitted).
|
|
58
|
-
*/
|
|
59
|
-
export declare function computeCacheBreakpoints(messages: readonly CacheableMessage[], estimateTokens?: (msg: CacheableMessage) => number, policy?: Partial<PromptCachePolicy>): CacheMarkingResult;
|
|
60
|
-
/**
|
|
61
|
-
* Apply cache_control markers to a mutable message array based on breakpoints.
|
|
62
|
-
*
|
|
63
|
-
* For each breakpoint index, the last content block of that message gets a
|
|
64
|
-
* `cache_control: { type: "ephemeral" }` annotation (Anthropic format).
|
|
65
|
-
* String content is promoted to a text content block array.
|
|
66
|
-
*
|
|
67
|
-
* This is a pure transform — it returns a new array with shallow-cloned messages.
|
|
68
|
-
*/
|
|
69
|
-
export declare function applyCacheMarkers<T extends CacheableMessage>(messages: readonly T[], breakpoints: readonly CacheBreakpoint[]): T[];
|
|
70
|
-
/**
|
|
71
|
-
* Estimate the cache savings ratio for a turn.
|
|
72
|
-
*
|
|
73
|
-
* @param totalTokens Total input tokens for the turn.
|
|
74
|
-
* @param cacheableTokens Tokens covered by cache breakpoints.
|
|
75
|
-
* @param cacheHitRatio Fraction of cacheable tokens actually served from cache (0–1).
|
|
76
|
-
* @returns Estimated fraction of input tokens saved (0–1).
|
|
77
|
-
*/
|
|
78
|
-
export declare function estimateCacheSavingsRatio(totalTokens: number, cacheableTokens: number, cacheHitRatio?: number): number;
|
|
79
|
-
/**
|
|
80
|
-
* Determine the optimal cache marker position for fork scenarios.
|
|
81
|
-
*
|
|
82
|
-
* CC pattern:
|
|
83
|
-
* - Normal request: marker on messages[length - 1] (last message)
|
|
84
|
-
* - Fork (skipCacheWrite): marker on messages[length - 2] (shared prefix point)
|
|
85
|
-
*
|
|
86
|
-
* This ensures all fork children produce byte-identical API request prefix up to
|
|
87
|
-
* the marker, maximising cache reuse.
|
|
88
|
-
*/
|
|
89
|
-
export declare function resolveForkCacheMarkerIndex(messagesLength: number, options?: {
|
|
90
|
-
isForkChild?: boolean;
|
|
91
|
-
skipCacheWrite?: boolean;
|
|
92
|
-
}): number;
|
|
93
|
-
/**
|
|
94
|
-
* A cache break occurs when any property of the API request that affects
|
|
95
|
-
* the prefix cache changes between requests. Track these to diagnose
|
|
96
|
-
* unexpected cache misses.
|
|
97
|
-
*/
|
|
98
|
-
export interface CacheBreakDetectionState {
|
|
99
|
-
systemHash: string | null;
|
|
100
|
-
toolsHash: string | null;
|
|
101
|
-
modelId: string | null;
|
|
102
|
-
thinkingEnabled: boolean | null;
|
|
103
|
-
}
|
|
104
|
-
export declare function createCacheBreakDetectionState(): CacheBreakDetectionState;
|
|
105
|
-
export interface CacheBreakEvent {
|
|
106
|
-
field: "system" | "tools" | "model" | "thinking";
|
|
107
|
-
previousHash: string | null;
|
|
108
|
-
currentHash: string | null;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Detect if a cache break has occurred by comparing current request properties
|
|
112
|
-
* against the last known state.
|
|
113
|
-
*
|
|
114
|
-
* Returns the list of fields that changed (empty = no break).
|
|
115
|
-
*/
|
|
116
|
-
export declare function detectCacheBreaks(state: CacheBreakDetectionState, current: {
|
|
117
|
-
systemHash: string;
|
|
118
|
-
toolsHash: string;
|
|
119
|
-
modelId: string;
|
|
120
|
-
thinkingEnabled: boolean;
|
|
121
|
-
}): CacheBreakEvent[];
|
|
122
|
-
/**
|
|
123
|
-
* Compute a lightweight hash for cache break detection.
|
|
124
|
-
* Uses DJB2 algorithm (fast, good distribution for strings).
|
|
125
|
-
*/
|
|
126
|
-
export declare function quickHash(input: string): string;
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Prompt cache marking strategy — identify optimal breakpoints
|
|
3
|
-
// in a message array for provider-level prefix caching.
|
|
4
|
-
//
|
|
5
|
-
// Providers like Anthropic cache message prefixes: if consecutive
|
|
6
|
-
// requests share identical leading messages, the cached portion
|
|
7
|
-
// skips re-tokenization and re-processing. The strategy here
|
|
8
|
-
// decides WHERE to place cache breakpoints (up to maxBreakpoints)
|
|
9
|
-
// to maximise prefix reuse across turns.
|
|
10
|
-
// ============================================================
|
|
11
|
-
// ── Defaults ────────────────────────────────────────────────
|
|
12
|
-
export const DEFAULT_PROMPT_CACHE_POLICY = {
|
|
13
|
-
maxBreakpoints: 4,
|
|
14
|
-
retention: "short",
|
|
15
|
-
minSegmentTokens: 256,
|
|
16
|
-
recentTailCount: 2,
|
|
17
|
-
markToolDefinitions: true,
|
|
18
|
-
};
|
|
19
|
-
// ── Core strategy ───────────────────────────────────────────
|
|
20
|
-
/**
|
|
21
|
-
* Analyse a message array and return recommended cache breakpoints.
|
|
22
|
-
*
|
|
23
|
-
* The algorithm:
|
|
24
|
-
* 1. Classify each message into segments (system / tool-def / conversation / recent).
|
|
25
|
-
* 2. Identify segment boundaries where the classification changes.
|
|
26
|
-
* 3. Rank boundaries by estimated token cost (heaviest first).
|
|
27
|
-
* 4. Select the top `maxBreakpoints` that meet `minSegmentTokens`.
|
|
28
|
-
*
|
|
29
|
-
* @param messages The conversation message array (in order).
|
|
30
|
-
* @param estimateTokens Optional per-message token estimator. Falls back to
|
|
31
|
-
* character-length heuristic (1 token ≈ 4 chars).
|
|
32
|
-
* @param policy Cache marking policy (uses defaults if omitted).
|
|
33
|
-
*/
|
|
34
|
-
export function computeCacheBreakpoints(messages, estimateTokens, policy = {}) {
|
|
35
|
-
const p = { ...DEFAULT_PROMPT_CACHE_POLICY, ...policy };
|
|
36
|
-
const estimate = estimateTokens ?? defaultTokenEstimator;
|
|
37
|
-
if (p.retention === "none" || messages.length === 0) {
|
|
38
|
-
return { breakpoints: [], estimatedCacheableTokens: 0, retention: p.retention };
|
|
39
|
-
}
|
|
40
|
-
// Classify every message
|
|
41
|
-
const recentStart = Math.max(0, messages.length - p.recentTailCount);
|
|
42
|
-
const classified = messages.map((msg, i) => ({
|
|
43
|
-
index: i,
|
|
44
|
-
kind: i >= recentStart ? "recent" : classifyMessage(msg, p),
|
|
45
|
-
tokens: estimate(msg),
|
|
46
|
-
}));
|
|
47
|
-
// Build contiguous segments by kind
|
|
48
|
-
const segments = [];
|
|
49
|
-
let current;
|
|
50
|
-
for (const entry of classified) {
|
|
51
|
-
if (!current || current.kind !== entry.kind) {
|
|
52
|
-
if (current)
|
|
53
|
-
segments.push(current);
|
|
54
|
-
current = { kind: entry.kind, startIndex: entry.index, endIndex: entry.index, tokens: entry.tokens };
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
current.endIndex = entry.index;
|
|
58
|
-
current.tokens += entry.tokens;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (current)
|
|
62
|
-
segments.push(current);
|
|
63
|
-
// Candidate breakpoints: end of each non-recent segment meeting the threshold
|
|
64
|
-
const candidates = [];
|
|
65
|
-
for (const seg of segments) {
|
|
66
|
-
if (seg.kind === "recent")
|
|
67
|
-
continue;
|
|
68
|
-
if (seg.tokens < p.minSegmentTokens)
|
|
69
|
-
continue;
|
|
70
|
-
candidates.push({
|
|
71
|
-
index: seg.endIndex,
|
|
72
|
-
segment: seg.kind,
|
|
73
|
-
estimatedTokens: seg.tokens,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
// Rank by tokens descending, pick top N
|
|
77
|
-
candidates.sort((a, b) => (b.estimatedTokens ?? 0) - (a.estimatedTokens ?? 0));
|
|
78
|
-
const selected = candidates.slice(0, p.maxBreakpoints);
|
|
79
|
-
// Re-sort by index ascending for stable output
|
|
80
|
-
selected.sort((a, b) => a.index - b.index);
|
|
81
|
-
const estimatedCacheableTokens = selected.reduce((sum, bp) => sum + (bp.estimatedTokens ?? 0), 0);
|
|
82
|
-
return { breakpoints: selected, estimatedCacheableTokens, retention: p.retention };
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Apply cache_control markers to a mutable message array based on breakpoints.
|
|
86
|
-
*
|
|
87
|
-
* For each breakpoint index, the last content block of that message gets a
|
|
88
|
-
* `cache_control: { type: "ephemeral" }` annotation (Anthropic format).
|
|
89
|
-
* String content is promoted to a text content block array.
|
|
90
|
-
*
|
|
91
|
-
* This is a pure transform — it returns a new array with shallow-cloned messages.
|
|
92
|
-
*/
|
|
93
|
-
export function applyCacheMarkers(messages, breakpoints) {
|
|
94
|
-
const bpSet = new Set(breakpoints.map((bp) => bp.index));
|
|
95
|
-
return messages.map((msg, i) => {
|
|
96
|
-
if (!bpSet.has(i))
|
|
97
|
-
return msg;
|
|
98
|
-
return injectCacheControl(msg);
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Estimate the cache savings ratio for a turn.
|
|
103
|
-
*
|
|
104
|
-
* @param totalTokens Total input tokens for the turn.
|
|
105
|
-
* @param cacheableTokens Tokens covered by cache breakpoints.
|
|
106
|
-
* @param cacheHitRatio Fraction of cacheable tokens actually served from cache (0–1).
|
|
107
|
-
* @returns Estimated fraction of input tokens saved (0–1).
|
|
108
|
-
*/
|
|
109
|
-
export function estimateCacheSavingsRatio(totalTokens, cacheableTokens, cacheHitRatio = 1) {
|
|
110
|
-
if (totalTokens <= 0 || cacheableTokens <= 0)
|
|
111
|
-
return 0;
|
|
112
|
-
return Math.min(1, (cacheableTokens * Math.max(0, Math.min(1, cacheHitRatio))) / totalTokens);
|
|
113
|
-
}
|
|
114
|
-
// ── Helpers ─────────────────────────────────────────────────
|
|
115
|
-
function classifyMessage(msg, policy) {
|
|
116
|
-
const role = msg.role;
|
|
117
|
-
if (role === "system" || role === "developer")
|
|
118
|
-
return "system";
|
|
119
|
-
if (policy.markToolDefinitions && role === "tool")
|
|
120
|
-
return "conversation";
|
|
121
|
-
// Tool-call results are part of conversation flow
|
|
122
|
-
if (msg.tool_call_id)
|
|
123
|
-
return "conversation";
|
|
124
|
-
return "conversation";
|
|
125
|
-
}
|
|
126
|
-
function defaultTokenEstimator(msg) {
|
|
127
|
-
const content = msg.content;
|
|
128
|
-
if (typeof content === "string")
|
|
129
|
-
return Math.ceil(content.length / 4);
|
|
130
|
-
if (Array.isArray(content)) {
|
|
131
|
-
let chars = 0;
|
|
132
|
-
for (const part of content) {
|
|
133
|
-
if (typeof part === "string")
|
|
134
|
-
chars += part.length;
|
|
135
|
-
else if (part && typeof part === "object" && "text" in part) {
|
|
136
|
-
chars += typeof part.text === "string"
|
|
137
|
-
? (part.text).length
|
|
138
|
-
: 0;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return Math.ceil(chars / 4);
|
|
142
|
-
}
|
|
143
|
-
return 0;
|
|
144
|
-
}
|
|
145
|
-
function injectCacheControl(msg) {
|
|
146
|
-
const clone = { ...msg };
|
|
147
|
-
const content = clone.content;
|
|
148
|
-
if (typeof content === "string") {
|
|
149
|
-
// Promote string to text content block with cache_control
|
|
150
|
-
clone.content = [
|
|
151
|
-
{ type: "text", text: content, cache_control: { type: "ephemeral" } },
|
|
152
|
-
];
|
|
153
|
-
}
|
|
154
|
-
else if (Array.isArray(content) && content.length > 0) {
|
|
155
|
-
const newContent = content.map((part, idx) => {
|
|
156
|
-
if (idx !== content.length - 1)
|
|
157
|
-
return part;
|
|
158
|
-
if (part && typeof part === "object") {
|
|
159
|
-
return { ...part, cache_control: { type: "ephemeral" } };
|
|
160
|
-
}
|
|
161
|
-
return part;
|
|
162
|
-
});
|
|
163
|
-
clone.content = newContent;
|
|
164
|
-
}
|
|
165
|
-
return clone;
|
|
166
|
-
}
|
|
167
|
-
// ── CC-aligned Fork Prefix Cache ────────────────────────────
|
|
168
|
-
/**
|
|
169
|
-
* Determine the optimal cache marker position for fork scenarios.
|
|
170
|
-
*
|
|
171
|
-
* CC pattern:
|
|
172
|
-
* - Normal request: marker on messages[length - 1] (last message)
|
|
173
|
-
* - Fork (skipCacheWrite): marker on messages[length - 2] (shared prefix point)
|
|
174
|
-
*
|
|
175
|
-
* This ensures all fork children produce byte-identical API request prefix up to
|
|
176
|
-
* the marker, maximising cache reuse.
|
|
177
|
-
*/
|
|
178
|
-
export function resolveForkCacheMarkerIndex(messagesLength, options = {}) {
|
|
179
|
-
if (messagesLength <= 0)
|
|
180
|
-
return -1;
|
|
181
|
-
if (options.skipCacheWrite || options.isForkChild) {
|
|
182
|
-
// Fork children: marker goes on the shared prefix (second-to-last message)
|
|
183
|
-
return Math.max(0, messagesLength - 2);
|
|
184
|
-
}
|
|
185
|
-
// Normal: marker on last message
|
|
186
|
-
return messagesLength - 1;
|
|
187
|
-
}
|
|
188
|
-
export function createCacheBreakDetectionState() {
|
|
189
|
-
return { systemHash: null, toolsHash: null, modelId: null, thinkingEnabled: null };
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Detect if a cache break has occurred by comparing current request properties
|
|
193
|
-
* against the last known state.
|
|
194
|
-
*
|
|
195
|
-
* Returns the list of fields that changed (empty = no break).
|
|
196
|
-
*/
|
|
197
|
-
export function detectCacheBreaks(state, current) {
|
|
198
|
-
const events = [];
|
|
199
|
-
if (state.systemHash !== null && state.systemHash !== current.systemHash) {
|
|
200
|
-
events.push({ field: "system", previousHash: state.systemHash, currentHash: current.systemHash });
|
|
201
|
-
}
|
|
202
|
-
if (state.toolsHash !== null && state.toolsHash !== current.toolsHash) {
|
|
203
|
-
events.push({ field: "tools", previousHash: state.toolsHash, currentHash: current.toolsHash });
|
|
204
|
-
}
|
|
205
|
-
if (state.modelId !== null && state.modelId !== current.modelId) {
|
|
206
|
-
events.push({ field: "model", previousHash: state.modelId, currentHash: current.modelId });
|
|
207
|
-
}
|
|
208
|
-
if (state.thinkingEnabled !== null && state.thinkingEnabled !== current.thinkingEnabled) {
|
|
209
|
-
events.push({ field: "thinking", previousHash: String(state.thinkingEnabled), currentHash: String(current.thinkingEnabled) });
|
|
210
|
-
}
|
|
211
|
-
// Update state
|
|
212
|
-
state.systemHash = current.systemHash;
|
|
213
|
-
state.toolsHash = current.toolsHash;
|
|
214
|
-
state.modelId = current.modelId;
|
|
215
|
-
state.thinkingEnabled = current.thinkingEnabled;
|
|
216
|
-
return events;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Compute a lightweight hash for cache break detection.
|
|
220
|
-
* Uses DJB2 algorithm (fast, good distribution for strings).
|
|
221
|
-
*/
|
|
222
|
-
export function quickHash(input) {
|
|
223
|
-
let hash = 5381;
|
|
224
|
-
for (let i = 0; i < input.length; i++) {
|
|
225
|
-
hash = ((hash << 5) + hash + input.charCodeAt(i)) | 0;
|
|
226
|
-
}
|
|
227
|
-
return (hash >>> 0).toString(36);
|
|
228
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reactive Compact — Emergency context compression when API returns prompt-too-long.
|
|
3
|
-
*
|
|
4
|
-
* Aligned with Claude Code's reactive compact chain:
|
|
5
|
-
* 1. API 413 → withhold error → attempt reactive compact → retry
|
|
6
|
-
* 2. Only one reactive compact attempt per turn (prevent infinite loops)
|
|
7
|
-
* 3. Falls back to abort if compact fails
|
|
8
|
-
*
|
|
9
|
-
* Also handles post-compact restoration:
|
|
10
|
-
* - Todo list re-injection
|
|
11
|
-
* - Skill context re-injection
|
|
12
|
-
* - Tool delta re-injection (new/removed tools since last compact)
|
|
13
|
-
*/
|
|
14
|
-
export interface ReactiveCompactConfig {
|
|
15
|
-
/** Maximum consecutive auto-compact failures before giving up (CC: 3). */
|
|
16
|
-
maxConsecutiveFailures: number;
|
|
17
|
-
/** Minimum messages to keep after reactive compact. */
|
|
18
|
-
minMessagesAfterCompact: number;
|
|
19
|
-
/** Target token usage after compact (percentage of context window). */
|
|
20
|
-
targetUsagePercent: number;
|
|
21
|
-
}
|
|
22
|
-
export declare const DEFAULT_REACTIVE_COMPACT_CONFIG: ReactiveCompactConfig;
|
|
23
|
-
export interface PostCompactRestorationPayload {
|
|
24
|
-
/** Current active todo list to re-inject after compact. */
|
|
25
|
-
todoList?: Array<{
|
|
26
|
-
id: number;
|
|
27
|
-
title: string;
|
|
28
|
-
status: string;
|
|
29
|
-
}>;
|
|
30
|
-
/** Active skill context (if LLM is executing a skill). */
|
|
31
|
-
activeSkillContext?: {
|
|
32
|
-
name: string;
|
|
33
|
-
step: number;
|
|
34
|
-
instructions: string;
|
|
35
|
-
};
|
|
36
|
-
/** Tool delta since last compact (tools added/removed from available set). */
|
|
37
|
-
toolDelta?: {
|
|
38
|
-
added: string[];
|
|
39
|
-
removed: string[];
|
|
40
|
-
};
|
|
41
|
-
/** Custom restoration blocks from memory hooks. */
|
|
42
|
-
customBlocks?: Array<{
|
|
43
|
-
label: string;
|
|
44
|
-
content: string;
|
|
45
|
-
}>;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Build the restoration message to inject after a compact operation.
|
|
49
|
-
* This ensures critical state survives context compression.
|
|
50
|
-
*/
|
|
51
|
-
export declare function buildPostCompactRestorationMessage(payload: PostCompactRestorationPayload): string | null;
|
|
52
|
-
export interface ReactiveCompactState {
|
|
53
|
-
/** Number of consecutive compact failures. */
|
|
54
|
-
consecutiveFailures: number;
|
|
55
|
-
/** Whether reactive compact has been attempted in this turn. */
|
|
56
|
-
attemptedThisTurn: boolean;
|
|
57
|
-
/** Last compact timestamp. */
|
|
58
|
-
lastCompactAt: number | null;
|
|
59
|
-
/** Tool names at time of last compact (for delta calculation). */
|
|
60
|
-
toolsAtLastCompact: string[];
|
|
61
|
-
}
|
|
62
|
-
export declare function createReactiveCompactState(): ReactiveCompactState;
|
|
63
|
-
/**
|
|
64
|
-
* Determine if reactive compact should be attempted.
|
|
65
|
-
*/
|
|
66
|
-
export declare function shouldAttemptReactiveCompact(state: ReactiveCompactState, config?: ReactiveCompactConfig): boolean;
|
|
67
|
-
/**
|
|
68
|
-
* Calculate the tool delta since last compact.
|
|
69
|
-
*/
|
|
70
|
-
export declare function computeToolDelta(currentTools: string[], toolsAtLastCompact: string[]): {
|
|
71
|
-
added: string[];
|
|
72
|
-
removed: string[];
|
|
73
|
-
};
|