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.
Files changed (226) hide show
  1. package/README.md +45 -45
  2. package/package.json +56 -42
  3. package/dist/agent/agent.d.ts +0 -43
  4. package/dist/agent/agent.js +0 -113
  5. package/dist/agent/tool-loop.d.ts +0 -64
  6. package/dist/agent/tool-loop.js +0 -575
  7. package/dist/agent/types.d.ts +0 -175
  8. package/dist/agent/types.js +0 -14
  9. package/dist/cli/main.d.ts +0 -11
  10. package/dist/cli/main.js +0 -23
  11. package/dist/cli/stdio-server.d.ts +0 -45
  12. package/dist/cli/stdio-server.js +0 -463
  13. package/dist/config/config.d.ts +0 -17
  14. package/dist/config/config.js +0 -21
  15. package/dist/contracts/hooks.d.ts +0 -120
  16. package/dist/contracts/hooks.js +0 -7
  17. package/dist/contracts/index.d.ts +0 -10
  18. package/dist/contracts/index.js +0 -10
  19. package/dist/contracts/planner.d.ts +0 -35
  20. package/dist/contracts/planner.js +0 -2
  21. package/dist/contracts/skill-candidate.d.ts +0 -63
  22. package/dist/contracts/skill-candidate.js +0 -195
  23. package/dist/contracts/todo.d.ts +0 -14
  24. package/dist/contracts/todo.js +0 -9
  25. package/dist/index.d.ts +0 -13
  26. package/dist/index.js +0 -15
  27. package/dist/llm/builtin-providers.d.ts +0 -10
  28. package/dist/llm/builtin-providers.js +0 -531
  29. package/dist/llm/index.d.ts +0 -15
  30. package/dist/llm/index.js +0 -14
  31. package/dist/llm/llm-client.d.ts +0 -43
  32. package/dist/llm/llm-client.js +0 -67
  33. package/dist/llm/model-catalog.d.ts +0 -53
  34. package/dist/llm/model-catalog.js +0 -191
  35. package/dist/llm/provider-def.d.ts +0 -59
  36. package/dist/llm/provider-def.js +0 -12
  37. package/dist/llm/provider-registry.d.ts +0 -54
  38. package/dist/llm/provider-registry.js +0 -147
  39. package/dist/llm/transport.d.ts +0 -62
  40. package/dist/llm/transport.js +0 -27
  41. package/dist/llm/transports/anthropic-messages.d.ts +0 -31
  42. package/dist/llm/transports/anthropic-messages.js +0 -293
  43. package/dist/llm/transports/openai-chat.d.ts +0 -36
  44. package/dist/llm/transports/openai-chat.js +0 -165
  45. package/dist/orchestration/agent-registry.d.ts +0 -41
  46. package/dist/orchestration/agent-registry.js +0 -116
  47. package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
  48. package/dist/orchestration/approval-aware-tool-plan.js +0 -87
  49. package/dist/orchestration/context-compression.d.ts +0 -220
  50. package/dist/orchestration/context-compression.js +0 -583
  51. package/dist/orchestration/conversation-repair.d.ts +0 -61
  52. package/dist/orchestration/conversation-repair.js +0 -429
  53. package/dist/orchestration/curator-scheduler.d.ts +0 -119
  54. package/dist/orchestration/curator-scheduler.js +0 -135
  55. package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
  56. package/dist/orchestration/embedded-failover-policy.js +0 -168
  57. package/dist/orchestration/error-classification.d.ts +0 -12
  58. package/dist/orchestration/error-classification.js +0 -77
  59. package/dist/orchestration/failover-classification.d.ts +0 -8
  60. package/dist/orchestration/failover-classification.js +0 -381
  61. package/dist/orchestration/failover-error.d.ts +0 -33
  62. package/dist/orchestration/failover-error.js +0 -198
  63. package/dist/orchestration/fork-subagent.d.ts +0 -100
  64. package/dist/orchestration/fork-subagent.js +0 -98
  65. package/dist/orchestration/index.d.ts +0 -120
  66. package/dist/orchestration/index.js +0 -267
  67. package/dist/orchestration/memory-flush-policy.d.ts +0 -57
  68. package/dist/orchestration/memory-flush-policy.js +0 -85
  69. package/dist/orchestration/memory-provider.d.ts +0 -14
  70. package/dist/orchestration/memory-provider.js +0 -2
  71. package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
  72. package/dist/orchestration/parallel-tool-calls.js +0 -59
  73. package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
  74. package/dist/orchestration/prompt-cache-strategy.js +0 -228
  75. package/dist/orchestration/reactive-compact.d.ts +0 -73
  76. package/dist/orchestration/reactive-compact.js +0 -78
  77. package/dist/orchestration/retry-loop.d.ts +0 -22
  78. package/dist/orchestration/retry-loop.js +0 -24
  79. package/dist/orchestration/skill-candidate.d.ts +0 -52
  80. package/dist/orchestration/skill-candidate.js +0 -141
  81. package/dist/orchestration/skill-consolidation.d.ts +0 -123
  82. package/dist/orchestration/skill-consolidation.js +0 -220
  83. package/dist/orchestration/skill-improvement.d.ts +0 -59
  84. package/dist/orchestration/skill-improvement.js +0 -66
  85. package/dist/orchestration/skill-similarity.d.ts +0 -98
  86. package/dist/orchestration/skill-similarity.js +0 -131
  87. package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
  88. package/dist/orchestration/streaming-tool-executor.js +0 -96
  89. package/dist/orchestration/team-orchestration.d.ts +0 -195
  90. package/dist/orchestration/team-orchestration.js +0 -369
  91. package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
  92. package/dist/orchestration/team-tool-loop-wiring.js +0 -147
  93. package/dist/orchestration/tool-choice-policy.d.ts +0 -54
  94. package/dist/orchestration/tool-choice-policy.js +0 -164
  95. package/dist/orchestration/tool-loop-state.d.ts +0 -50
  96. package/dist/orchestration/tool-loop-state.js +0 -133
  97. package/dist/orchestration/tool-schema.d.ts +0 -39
  98. package/dist/orchestration/tool-schema.js +0 -297
  99. package/dist/orchestration/transcript-repair.d.ts +0 -42
  100. package/dist/orchestration/transcript-repair.js +0 -426
  101. package/dist/orchestration/turn-loop-guard.d.ts +0 -86
  102. package/dist/orchestration/turn-loop-guard.js +0 -92
  103. package/dist/orchestration/web-browser-policy.d.ts +0 -17
  104. package/dist/orchestration/web-browser-policy.js +0 -39
  105. package/dist/runtime/context-compression.d.ts +0 -61
  106. package/dist/runtime/context-compression.js +0 -274
  107. package/dist/runtime/hook-registry.d.ts +0 -12
  108. package/dist/runtime/hook-registry.js +0 -53
  109. package/dist/runtime/memory-hooks.d.ts +0 -23
  110. package/dist/runtime/memory-hooks.js +0 -65
  111. package/dist/runtime/tool-eligibility.d.ts +0 -59
  112. package/dist/runtime/tool-eligibility.js +0 -111
  113. package/dist/skills/index.d.ts +0 -108
  114. package/dist/skills/index.js +0 -82
  115. package/dist/skills/memory-extractor.d.ts +0 -64
  116. package/dist/skills/memory-extractor.js +0 -173
  117. package/dist/skills/memory-query-tool.d.ts +0 -43
  118. package/dist/skills/memory-query-tool.js +0 -127
  119. package/dist/skills/memory-store.d.ts +0 -66
  120. package/dist/skills/memory-store.js +0 -228
  121. package/dist/skills/memory-tool.d.ts +0 -67
  122. package/dist/skills/memory-tool.js +0 -192
  123. package/dist/skills/portable-tool.d.ts +0 -71
  124. package/dist/skills/portable-tool.js +0 -14
  125. package/dist/skills/qmemory-adapter.d.ts +0 -52
  126. package/dist/skills/qmemory-adapter.js +0 -165
  127. package/dist/skills/skill-frontmatter.d.ts +0 -19
  128. package/dist/skills/skill-frontmatter.js +0 -344
  129. package/dist/skills/skill-guard.d.ts +0 -23
  130. package/dist/skills/skill-guard.js +0 -229
  131. package/dist/skills/skill-loader.d.ts +0 -16
  132. package/dist/skills/skill-loader.js +0 -303
  133. package/dist/skills/skill-source.d.ts +0 -119
  134. package/dist/skills/skill-source.js +0 -126
  135. package/dist/skills/skill-types.d.ts +0 -199
  136. package/dist/skills/skill-types.js +0 -6
  137. package/dist/skills/think-tool.d.ts +0 -16
  138. package/dist/skills/think-tool.js +0 -59
  139. package/dist/skills/todo-tool.d.ts +0 -63
  140. package/dist/skills/todo-tool.js +0 -114
  141. package/dist/skills/tools/agent-tool.d.ts +0 -91
  142. package/dist/skills/tools/agent-tool.js +0 -142
  143. package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
  144. package/dist/skills/tools/apply-patch-tool.js +0 -184
  145. package/dist/skills/tools/ask-user-tool.d.ts +0 -80
  146. package/dist/skills/tools/ask-user-tool.js +0 -121
  147. package/dist/skills/tools/brief-tool.d.ts +0 -74
  148. package/dist/skills/tools/brief-tool.js +0 -95
  149. package/dist/skills/tools/browser-tool.d.ts +0 -114
  150. package/dist/skills/tools/browser-tool.js +0 -155
  151. package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
  152. package/dist/skills/tools/checkpoint-tool.js +0 -102
  153. package/dist/skills/tools/config-tool.d.ts +0 -63
  154. package/dist/skills/tools/config-tool.js +0 -143
  155. package/dist/skills/tools/cron-tool.d.ts +0 -116
  156. package/dist/skills/tools/cron-tool.js +0 -175
  157. package/dist/skills/tools/edit-tool.d.ts +0 -43
  158. package/dist/skills/tools/edit-tool.js +0 -70
  159. package/dist/skills/tools/exec-tool.d.ts +0 -102
  160. package/dist/skills/tools/exec-tool.js +0 -133
  161. package/dist/skills/tools/image-generate-tool.d.ts +0 -62
  162. package/dist/skills/tools/image-generate-tool.js +0 -67
  163. package/dist/skills/tools/instructions-tool.d.ts +0 -103
  164. package/dist/skills/tools/instructions-tool.js +0 -187
  165. package/dist/skills/tools/lsp-tool.d.ts +0 -153
  166. package/dist/skills/tools/lsp-tool.js +0 -227
  167. package/dist/skills/tools/mcp-client-types.d.ts +0 -269
  168. package/dist/skills/tools/mcp-client-types.js +0 -53
  169. package/dist/skills/tools/mcp-tool.d.ts +0 -249
  170. package/dist/skills/tools/mcp-tool.js +0 -503
  171. package/dist/skills/tools/memory-tool.d.ts +0 -74
  172. package/dist/skills/tools/memory-tool.js +0 -88
  173. package/dist/skills/tools/monitor-tool.d.ts +0 -113
  174. package/dist/skills/tools/monitor-tool.js +0 -131
  175. package/dist/skills/tools/music-generate-tool.d.ts +0 -55
  176. package/dist/skills/tools/music-generate-tool.js +0 -62
  177. package/dist/skills/tools/notify-tool.d.ts +0 -53
  178. package/dist/skills/tools/notify-tool.js +0 -62
  179. package/dist/skills/tools/patch-tool.d.ts +0 -45
  180. package/dist/skills/tools/patch-tool.js +0 -505
  181. package/dist/skills/tools/pdf-tool.d.ts +0 -66
  182. package/dist/skills/tools/pdf-tool.js +0 -88
  183. package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
  184. package/dist/skills/tools/plan-mode-tool.js +0 -122
  185. package/dist/skills/tools/read-tool.d.ts +0 -51
  186. package/dist/skills/tools/read-tool.js +0 -84
  187. package/dist/skills/tools/repl-tool.d.ts +0 -70
  188. package/dist/skills/tools/repl-tool.js +0 -69
  189. package/dist/skills/tools/search-tool.d.ts +0 -112
  190. package/dist/skills/tools/search-tool.js +0 -225
  191. package/dist/skills/tools/send-message-tool.d.ts +0 -51
  192. package/dist/skills/tools/send-message-tool.js +0 -76
  193. package/dist/skills/tools/skill-list-tool.d.ts +0 -33
  194. package/dist/skills/tools/skill-list-tool.js +0 -54
  195. package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
  196. package/dist/skills/tools/skill-manage-tool.js +0 -153
  197. package/dist/skills/tools/skill-view-tool.d.ts +0 -37
  198. package/dist/skills/tools/skill-view-tool.js +0 -72
  199. package/dist/skills/tools/sleep-tool.d.ts +0 -49
  200. package/dist/skills/tools/sleep-tool.js +0 -81
  201. package/dist/skills/tools/structured-output-tool.d.ts +0 -116
  202. package/dist/skills/tools/structured-output-tool.js +0 -176
  203. package/dist/skills/tools/task-tool.d.ts +0 -104
  204. package/dist/skills/tools/task-tool.js +0 -161
  205. package/dist/skills/tools/team-tool.d.ts +0 -89
  206. package/dist/skills/tools/team-tool.js +0 -105
  207. package/dist/skills/tools/tool-search-tool.d.ts +0 -51
  208. package/dist/skills/tools/tool-search-tool.js +0 -110
  209. package/dist/skills/tools/tts-tool.d.ts +0 -38
  210. package/dist/skills/tools/tts-tool.js +0 -45
  211. package/dist/skills/tools/video-edit-tool.d.ts +0 -69
  212. package/dist/skills/tools/video-edit-tool.js +0 -74
  213. package/dist/skills/tools/video-generate-tool.d.ts +0 -62
  214. package/dist/skills/tools/video-generate-tool.js +0 -66
  215. package/dist/skills/tools/video-merge-tool.d.ts +0 -105
  216. package/dist/skills/tools/video-merge-tool.js +0 -92
  217. package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
  218. package/dist/skills/tools/video-upscale-tool.js +0 -52
  219. package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
  220. package/dist/skills/tools/web-fetch-tool.js +0 -92
  221. package/dist/skills/tools/web-search-tool.d.ts +0 -57
  222. package/dist/skills/tools/web-search-tool.js +0 -86
  223. package/dist/skills/tools/worktree-tool.d.ts +0 -69
  224. package/dist/skills/tools/worktree-tool.js +0 -147
  225. package/dist/skills/tools/write-tool.d.ts +0 -45
  226. 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,2 +0,0 @@
1
- import { MEMORY_OBSERVATION_HOOK_VALUES, MEMORY_OBSERVATION_SOURCE_VALUES, MEMORY_WRITE_ACCESS_VALUES, } from "qlogicagent-runtime-contracts";
2
- export { MEMORY_OBSERVATION_HOOK_VALUES, MEMORY_OBSERVATION_SOURCE_VALUES, MEMORY_WRITE_ACCESS_VALUES, };
@@ -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
- };