@deepstrike/sdk 0.2.52 → 0.2.61

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 (151) hide show
  1. package/README.md +28 -28
  2. package/dist/agent-ir.d.ts +103 -0
  3. package/dist/agent-ir.js +134 -0
  4. package/dist/agent.d.ts +67 -0
  5. package/dist/agent.js +36 -0
  6. package/dist/collaboration/harness.js +1 -1
  7. package/dist/collaboration/modes/creator-verifier.d.ts +2 -7
  8. package/dist/collaboration/modes/creator-verifier.js +4 -6
  9. package/dist/collaboration/pool.d.ts +8 -20
  10. package/dist/collaboration/pool.js +27 -97
  11. package/dist/compat/anthropic/mcp.d.ts +15 -0
  12. package/dist/compat/anthropic/mcp.js +10 -0
  13. package/dist/compat/openai/agent.d.ts +34 -0
  14. package/dist/compat/openai/agent.js +24 -0
  15. package/dist/governance.d.ts +1 -17
  16. package/dist/governance.js +1 -34
  17. package/dist/guardrail.d.ts +6 -0
  18. package/dist/guardrail.js +1 -0
  19. package/dist/handoff-target.d.ts +12 -0
  20. package/dist/handoff-target.js +1 -0
  21. package/dist/harness/manifest.js +0 -4
  22. package/dist/index.d.ts +19 -7
  23. package/dist/index.js +8 -5
  24. package/dist/kernel.d.ts +2 -20
  25. package/dist/knowledge/public.d.ts +29 -0
  26. package/dist/knowledge/public.js +1 -0
  27. package/dist/mcp-server.d.ts +28 -0
  28. package/dist/mcp-server.js +1 -0
  29. package/dist/memory/agent.d.ts +2 -2
  30. package/dist/memory/agent.js +2 -2
  31. package/dist/memory/durable.d.ts +16 -0
  32. package/dist/memory/durable.js +46 -0
  33. package/dist/memory/in-memory-store.d.ts +9 -7
  34. package/dist/memory/in-memory-store.js +8 -2
  35. package/dist/memory/protocols.d.ts +22 -4
  36. package/dist/memory/public.d.ts +4 -3
  37. package/dist/memory/public.js +3 -2
  38. package/dist/os/public.d.ts +1 -1
  39. package/dist/os/public.js +1 -1
  40. package/dist/providers/anthropic-adapter.d.ts +59 -0
  41. package/dist/providers/anthropic-adapter.js +530 -0
  42. package/dist/providers/anthropic-compatible.d.ts +2 -3
  43. package/dist/providers/anthropic-compatible.js +8 -5
  44. package/dist/providers/anthropic.d.ts +20 -23
  45. package/dist/providers/anthropic.js +176 -395
  46. package/dist/providers/base.d.ts +2 -2
  47. package/dist/providers/base.js +50 -8
  48. package/dist/providers/capability-router.d.ts +29 -0
  49. package/dist/providers/capability-router.js +43 -0
  50. package/dist/providers/catalog.d.ts +16 -4
  51. package/dist/providers/catalog.js +112 -36
  52. package/dist/providers/content-normalization.d.ts +57 -0
  53. package/dist/providers/content-normalization.js +238 -0
  54. package/dist/providers/content-policy.d.ts +16 -0
  55. package/dist/providers/content-policy.js +39 -0
  56. package/dist/providers/credentials.d.ts +83 -0
  57. package/dist/providers/credentials.js +190 -0
  58. package/dist/providers/endpoints.d.ts +137 -0
  59. package/dist/providers/endpoints.js +128 -0
  60. package/dist/providers/factories.js +25 -9
  61. package/dist/providers/gemini-adapter.d.ts +33 -0
  62. package/dist/providers/gemini-adapter.js +264 -0
  63. package/dist/providers/gemini.d.ts +16 -3
  64. package/dist/providers/gemini.js +97 -195
  65. package/dist/providers/model-catalog.d.ts +37 -0
  66. package/dist/providers/model-catalog.js +62 -0
  67. package/dist/providers/model-registry.d.ts +119 -0
  68. package/dist/providers/model-registry.js +379 -0
  69. package/dist/providers/ollama-adapter.d.ts +65 -0
  70. package/dist/providers/ollama-adapter.js +188 -0
  71. package/dist/providers/ollama.d.ts +9 -4
  72. package/dist/providers/ollama.js +96 -109
  73. package/dist/providers/openai-chat-dialects.d.ts +154 -0
  74. package/dist/providers/openai-chat-dialects.js +179 -0
  75. package/dist/providers/openai-chat.d.ts +46 -18
  76. package/dist/providers/openai-chat.js +416 -51
  77. package/dist/providers/openai-responses-adapter.d.ts +42 -0
  78. package/dist/providers/openai-responses-adapter.js +343 -0
  79. package/dist/providers/openai-responses.d.ts +19 -33
  80. package/dist/providers/openai-responses.js +164 -264
  81. package/dist/providers/openai.d.ts +29 -76
  82. package/dist/providers/openai.js +195 -292
  83. package/dist/providers/protocol-adapter.d.ts +39 -0
  84. package/dist/providers/protocol-adapter.js +13 -0
  85. package/dist/providers/protocol-capabilities.d.ts +34 -0
  86. package/dist/providers/protocol-capabilities.js +44 -0
  87. package/dist/providers/provider-error.d.ts +31 -0
  88. package/dist/providers/provider-error.js +153 -0
  89. package/dist/providers/public.d.ts +26 -3
  90. package/dist/providers/public.js +13 -1
  91. package/dist/providers/registry.d.ts +7 -6
  92. package/dist/providers/registry.js +47 -20
  93. package/dist/providers/request-plan.d.ts +89 -0
  94. package/dist/providers/request-plan.js +199 -0
  95. package/dist/providers/usage-normalizer.d.ts +48 -0
  96. package/dist/providers/usage-normalizer.js +139 -0
  97. package/dist/providers/vendor-profiles.d.ts +2 -15
  98. package/dist/providers/vendor-profiles.js +14 -60
  99. package/dist/runtime/canonical-kernel-step.d.ts +1 -2
  100. package/dist/runtime/canonical-kernel-step.js +47 -12
  101. package/dist/runtime/context-policy.d.ts +10 -12
  102. package/dist/runtime/context-policy.js +6 -8
  103. package/dist/runtime/durable-content.d.ts +50 -0
  104. package/dist/runtime/durable-content.js +159 -0
  105. package/dist/runtime/execution-plane.d.ts +2 -2
  106. package/dist/runtime/execution-plane.js +2 -2
  107. package/dist/runtime/kernel-event-log.js +0 -1
  108. package/dist/runtime/kernel-step.d.ts +0 -1
  109. package/dist/runtime/kernel-step.js +4 -2
  110. package/dist/runtime/mcp-proxy-plane.d.ts +25 -1
  111. package/dist/runtime/mcp-proxy-plane.js +44 -6
  112. package/dist/runtime/output-schema.d.ts +1 -2
  113. package/dist/runtime/provider-replay.d.ts +5 -1
  114. package/dist/runtime/provider-replay.js +26 -27
  115. package/dist/runtime/reactive-session.d.ts +1 -1
  116. package/dist/runtime/reactive-session.js +2 -3
  117. package/dist/runtime/run-group.d.ts +1 -1
  118. package/dist/runtime/runner.d.ts +31 -45
  119. package/dist/runtime/runner.js +178 -63
  120. package/dist/runtime/session-log.d.ts +8 -1
  121. package/dist/runtime/session-log.js +42 -2
  122. package/dist/runtime/session-repair.d.ts +1 -1
  123. package/dist/runtime/session-repair.js +1 -1
  124. package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
  125. package/dist/runtime/sub-agent-orchestrator.js +8 -11
  126. package/dist/runtime/workflow-control-flow.d.ts +0 -4
  127. package/dist/runtime/workflow-control-flow.js +0 -16
  128. package/dist/session.d.ts +11 -0
  129. package/dist/session.js +1 -0
  130. package/dist/skill.d.ts +17 -0
  131. package/dist/skill.js +16 -0
  132. package/dist/skills/loader.d.ts +3 -0
  133. package/dist/tools/errors.d.ts +1 -3
  134. package/dist/tools/errors.js +1 -3
  135. package/dist/tools/index.d.ts +3 -0
  136. package/dist/types/agent.d.ts +21 -9
  137. package/dist/types/agent.js +30 -4
  138. package/dist/types.d.ts +135 -17
  139. package/package.json +4 -4
  140. package/dist/providers/deepseek.d.ts +0 -46
  141. package/dist/providers/deepseek.js +0 -97
  142. package/dist/providers/glm.d.ts +0 -25
  143. package/dist/providers/glm.js +0 -48
  144. package/dist/providers/kimi.d.ts +0 -23
  145. package/dist/providers/kimi.js +0 -30
  146. package/dist/providers/minimax.d.ts +0 -49
  147. package/dist/providers/minimax.js +0 -98
  148. package/dist/providers/profiles.d.ts +0 -1992
  149. package/dist/providers/profiles.js +0 -796
  150. package/dist/providers/qwen.d.ts +0 -38
  151. package/dist/providers/qwen.js +0 -97
@@ -0,0 +1,530 @@
1
+ import { normalizeToolCall } from "./base.js";
2
+ import { ProtocolResponseError, } from "./protocol-adapter.js";
3
+ import { ANTHROPIC_PROTOCOL_CAPABILITIES } from "./protocol-capabilities.js";
4
+ import { endpointProfiles } from "./endpoints.js";
5
+ export const ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER = "<||DSML||tool_calls>";
6
+ const TEXTUAL_TOOL_CALL_CAPTURE_LIMIT = 64 * 1024;
7
+ const CACHE_BREAKPOINT_STRATEGIES = new Set([
8
+ "default", "tools-only", "system-only", "frozen-prefix", "none",
9
+ ]);
10
+ function cacheStrategy(extensions) {
11
+ const raw = extensions.cacheBreakpointStrategy;
12
+ return typeof raw === "string" && CACHE_BREAKPOINT_STRATEGIES.has(raw)
13
+ ? raw
14
+ : "default";
15
+ }
16
+ function extensionsForWire(extensions) {
17
+ const blocked = new Set([
18
+ "model", "messages", "system", "tools", "max_tokens", "stream",
19
+ "__deepstrikeThinkingEnabled", "degradeMissingReasoningReplay", "textualToolCallPolicy",
20
+ ]);
21
+ return Object.fromEntries(Object.entries(extensions).filter(([key]) => !blocked.has(key)));
22
+ }
23
+ function textualToolCallPolicy(input) {
24
+ if (input.tools.length === 0)
25
+ return "off";
26
+ const explicit = input.extensions.textualToolCallPolicy;
27
+ if (explicit === "off" || explicit === "reject")
28
+ return explicit;
29
+ const official = endpointProfiles["anthropic.messages"];
30
+ const endpoint = input.resolved.endpoint;
31
+ const isOfficial = input.resolved.identity.endpointId === official.id
32
+ && (!endpoint || endpoint.baseURL === official.baseURL);
33
+ return isOfficial ? "off" : "reject";
34
+ }
35
+ function textualToolCallError() {
36
+ return new ProtocolResponseError("anthropic-messages", "Provider emitted a tool call as text instead of a native tool block", { providerCode: "textual_tool_call", retryable: true });
37
+ }
38
+ function hasTextualToolCall(text, input) {
39
+ return textualToolCallPolicy(input) === "reject"
40
+ && text.includes(ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER);
41
+ }
42
+ function markerTailLength(text) {
43
+ const max = Math.min(text.length, ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER.length - 1);
44
+ for (let length = max; length > 0; length -= 1) {
45
+ if (text.endsWith(ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER.slice(0, length)))
46
+ return length;
47
+ }
48
+ return 0;
49
+ }
50
+ function utf8Length(text) {
51
+ return Buffer.byteLength(text, "utf8");
52
+ }
53
+ function guardTextDelta(text, guard) {
54
+ if (guard.policy === "off")
55
+ return text;
56
+ if (guard.mode === "candidate") {
57
+ guard.capturedLength += utf8Length(text);
58
+ if (guard.capturedLength > TEXTUAL_TOOL_CALL_CAPTURE_LIMIT)
59
+ throw textualToolCallError();
60
+ return "";
61
+ }
62
+ const combined = guard.tail + text;
63
+ const markerIndex = combined.indexOf(ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER);
64
+ if (markerIndex >= 0) {
65
+ guard.mode = "candidate";
66
+ guard.tail = "";
67
+ guard.capturedLength = utf8Length(combined.slice(markerIndex));
68
+ if (guard.capturedLength > TEXTUAL_TOOL_CALL_CAPTURE_LIMIT)
69
+ throw textualToolCallError();
70
+ return combined.slice(0, markerIndex);
71
+ }
72
+ const tailLength = markerTailLength(combined);
73
+ guard.tail = tailLength > 0 ? combined.slice(-tailLength) : "";
74
+ return tailLength > 0 ? combined.slice(0, -tailLength) : combined;
75
+ }
76
+ function systemBlocks(context, strategy) {
77
+ if (!context.systemStable && !context.systemKnowledge) {
78
+ return context.systemText || undefined;
79
+ }
80
+ const cache = strategy === "default" || strategy === "system-only";
81
+ const blocks = [];
82
+ if (context.systemStable) {
83
+ blocks.push({
84
+ type: "text",
85
+ text: context.systemStable,
86
+ ...(cache ? { cache_control: { type: "ephemeral" } } : {}),
87
+ });
88
+ }
89
+ if (context.systemKnowledge) {
90
+ blocks.push({
91
+ type: "text",
92
+ text: context.systemKnowledge,
93
+ ...(cache ? { cache_control: { type: "ephemeral" } } : {}),
94
+ });
95
+ }
96
+ return blocks.length ? blocks : undefined;
97
+ }
98
+ function toolResult(result) {
99
+ const blocks = result.blocks;
100
+ const native = blocks.map(block => {
101
+ if (block.type === "text")
102
+ return { type: "text", text: block.text };
103
+ if (block.type === "image") {
104
+ if (block.source.kind === "base64") {
105
+ return {
106
+ type: "image",
107
+ source: {
108
+ type: "base64",
109
+ media_type: block.mediaType ?? "image/png",
110
+ data: block.source.data,
111
+ },
112
+ };
113
+ }
114
+ if (block.source.kind === "url") {
115
+ return { type: "image", source: { type: "url", url: block.source.url } };
116
+ }
117
+ }
118
+ return { type: "text", text: `[${block.type}]` };
119
+ });
120
+ return {
121
+ type: "tool_result",
122
+ tool_use_id: result.callId,
123
+ content: result.contentForm !== "blocks" && blocks.length === 1 && blocks[0].type === "text"
124
+ ? blocks[0].text
125
+ : native,
126
+ is_error: result.isError,
127
+ };
128
+ }
129
+ function canonicalMessage(message) {
130
+ if (message.role === "assistant"
131
+ && message.toolCalls?.length
132
+ && message.providerReplay?.native_blocks?.length) {
133
+ return { role: "assistant", content: ensureAssistantToolText(message.providerReplay.native_blocks) };
134
+ }
135
+ const content = [];
136
+ for (const item of message.blocks) {
137
+ if (item.type === "tool_result") {
138
+ content.push(toolResult(item));
139
+ }
140
+ else if (item.type === "text") {
141
+ if (item.text)
142
+ content.push({ type: "text", text: item.text });
143
+ }
144
+ else if (item.type === "image") {
145
+ if (item.source.kind === "base64") {
146
+ content.push({
147
+ type: "image",
148
+ source: {
149
+ type: "base64",
150
+ media_type: item.mediaType ?? "image/png",
151
+ data: item.source.data,
152
+ },
153
+ });
154
+ }
155
+ else if (item.source.kind === "url") {
156
+ content.push({ type: "image", source: { type: "url", url: item.source.url } });
157
+ }
158
+ }
159
+ }
160
+ if (message.role === "assistant" && message.toolCalls?.length) {
161
+ if (!content.length)
162
+ content.push({ type: "text", text: "Tool call requested." });
163
+ for (const call of message.toolCalls) {
164
+ let args = {};
165
+ try {
166
+ args = JSON.parse(call.arguments);
167
+ }
168
+ catch {
169
+ args = {};
170
+ }
171
+ content.push({ type: "tool_use", id: call.id, name: call.name, input: args });
172
+ }
173
+ }
174
+ if (message.role === "tool" && !content.some(block => block.type === "tool_result")) {
175
+ return undefined;
176
+ }
177
+ return {
178
+ role: message.role === "tool" ? "user" : message.role,
179
+ content: message.contentForm !== "blocks" && content.length === 1 && content[0].type === "text"
180
+ ? content[0].text
181
+ : content,
182
+ };
183
+ }
184
+ function ensureAssistantToolText(blocks) {
185
+ if (!blocks.some(block => block.type === "tool_use"))
186
+ return blocks;
187
+ if (blocks.some(block => block.type === "text" && String(block.text ?? "").trim()))
188
+ return blocks;
189
+ if (blocks.some(block => block.type === "thinking"))
190
+ return blocks;
191
+ return [{ type: "text", text: "Tool call requested." }, ...blocks];
192
+ }
193
+ function markLastBlockCacheable(message) {
194
+ const cache_control = { type: "ephemeral" };
195
+ if (typeof message.content === "string") {
196
+ if (message.content) {
197
+ message.content = [{ type: "text", text: message.content, cache_control }];
198
+ }
199
+ return;
200
+ }
201
+ if (Array.isArray(message.content) && message.content.length) {
202
+ const last = message.content.at(-1);
203
+ last.cache_control = cache_control;
204
+ }
205
+ }
206
+ function applyMessageCacheControl(messages, frozenPrefixLen, strategy) {
207
+ if (!messages.length || ["tools-only", "system-only", "none"].includes(strategy))
208
+ return;
209
+ const targets = new Set([messages.length - 1]);
210
+ if (typeof frozenPrefixLen === "number" && frozenPrefixLen >= 1 && frozenPrefixLen < messages.length) {
211
+ targets.add(frozenPrefixLen - 1);
212
+ }
213
+ else if (strategy === "default") {
214
+ for (let index = messages.length - 2; index >= 0 && targets.size < 2; index--) {
215
+ if (messages[index].role === "user")
216
+ targets.add(index);
217
+ }
218
+ }
219
+ for (const index of targets)
220
+ markLastBlockCacheable(messages[index]);
221
+ }
222
+ function requestTools(input, system, strategy) {
223
+ if (!input.tools.length)
224
+ return undefined;
225
+ const anchor = !Array.isArray(system)
226
+ && (strategy === "default" || strategy === "tools-only");
227
+ return input.tools.map((tool, index) => ({
228
+ name: tool.name,
229
+ description: tool.description,
230
+ input_schema: JSON.parse(tool.parameters),
231
+ ...(anchor && index === input.tools.length - 1
232
+ ? { cache_control: { type: "ephemeral" } }
233
+ : {}),
234
+ }));
235
+ }
236
+ function countSlots(system, tools, messages) {
237
+ return {
238
+ system: Array.isArray(system) && system.some(block => block.cache_control),
239
+ tools: !!tools?.some(tool => tool.cache_control),
240
+ messages: messages.some(message => Array.isArray(message.content)
241
+ && message.content.some(block => block.cache_control)),
242
+ };
243
+ }
244
+ function countCacheBreakpoints(value) {
245
+ if (Array.isArray(value))
246
+ return value.reduce((total, item) => total + countCacheBreakpoints(item), 0);
247
+ if (!value || typeof value !== "object")
248
+ return 0;
249
+ const record = value;
250
+ return (record.cache_control ? 1 : 0)
251
+ + Object.entries(record)
252
+ .filter(([key]) => key !== "cache_control")
253
+ .reduce((total, [, item]) => total + countCacheBreakpoints(item), 0);
254
+ }
255
+ function assertCacheBudget(params) {
256
+ const count = countCacheBreakpoints({
257
+ system: params.system,
258
+ tools: params.tools,
259
+ messages: params.messages,
260
+ });
261
+ if (count > 4) {
262
+ throw new Error(`Anthropic cache_control budget exceeded: ${count} > 4`);
263
+ }
264
+ }
265
+ function numeric(raw, field) {
266
+ const value = raw[field];
267
+ if (value === undefined || value === null)
268
+ return undefined;
269
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
270
+ throw new ProtocolResponseError("anthropic-messages", `usage.${field} must be a non-negative safe integer`);
271
+ }
272
+ return value;
273
+ }
274
+ export class AnthropicMessagesAdapter {
275
+ protocol = "anthropic-messages";
276
+ protocolCapabilities = ANTHROPIC_PROTOCOL_CAPABILITIES;
277
+ buildRequest(input) {
278
+ const strategy = cacheStrategy(input.extensions);
279
+ const system = systemBlocks(input.context, strategy);
280
+ const messages = input.context.turns
281
+ .map(canonicalMessage)
282
+ .filter((message) => message !== undefined);
283
+ applyMessageCacheControl(messages, input.context.frozenPrefixLen, strategy);
284
+ if (input.context.stateTurn) {
285
+ const stateMessage = canonicalMessage(input.context.stateTurn);
286
+ if (stateMessage)
287
+ messages.push(stateMessage);
288
+ }
289
+ if (!messages.length)
290
+ messages.push({ role: "user", content: "Proceed." });
291
+ const tools = requestTools(input, system, strategy);
292
+ const wire = extensionsForWire(input.extensions);
293
+ const betas = Array.isArray(input.extensions.betas) && input.extensions.betas.length
294
+ ? input.extensions.betas
295
+ : undefined;
296
+ const params = {
297
+ ...wire,
298
+ model: input.resolved.identity.modelId,
299
+ max_tokens: typeof input.extensions.max_tokens === "number"
300
+ ? input.extensions.max_tokens
301
+ : 8096,
302
+ ...(system ? { system } : {}),
303
+ messages,
304
+ ...(tools ? { tools } : {}),
305
+ ...(betas ? { betas } : {}),
306
+ };
307
+ assertCacheBudget(params);
308
+ return {
309
+ transport: betas ? "beta" : "stable",
310
+ params,
311
+ cacheSlots: countSlots(system, tools, messages),
312
+ };
313
+ }
314
+ decodeComplete(raw, decodeInput) {
315
+ let content = "";
316
+ const toolCalls = [];
317
+ for (const block of raw.content ?? []) {
318
+ if (block.type === "text")
319
+ content += block.text;
320
+ else if (block.type === "tool_use") {
321
+ const call = normalizeToolCall(block.id, block.name, block.input);
322
+ if (call)
323
+ toolCalls.push(call);
324
+ }
325
+ }
326
+ if (hasTextualToolCall(content, decodeInput.input))
327
+ throw textualToolCallError();
328
+ const usage = this.normalizeUsage(raw.usage);
329
+ const blocks = raw.content;
330
+ return {
331
+ message: {
332
+ role: "assistant",
333
+ content,
334
+ ...(usage ? { tokenCount: usage.outputTokens } : {}),
335
+ toolCalls,
336
+ },
337
+ ...(blocks?.length ? { replay: { protocol: "anthropic-messages", native_blocks: blocks } } : {}),
338
+ };
339
+ }
340
+ createStreamState(input) {
341
+ const plan = this.buildRequest(input.input);
342
+ return {
343
+ input: input.input,
344
+ cacheSlots: plan.cacheSlots,
345
+ toolBlocks: {},
346
+ nativeBlocks: {},
347
+ finalToolCalls: [],
348
+ textualToolCallGuard: {
349
+ policy: textualToolCallPolicy(input.input),
350
+ mode: "passthrough",
351
+ tail: "",
352
+ capturedLength: 0,
353
+ sawNativeToolCall: false,
354
+ },
355
+ finalText: "",
356
+ uncachedInput: 0,
357
+ cacheReadTokens: 0,
358
+ cacheCreationTokens: 0,
359
+ cacheTelemetryMeasured: false,
360
+ outputTokens: 0,
361
+ };
362
+ }
363
+ pushStreamChunk(chunk, state) {
364
+ const events = [];
365
+ if (chunk.type === "message_start" || chunk.type === "message_delta") {
366
+ const raw = chunk.usage ?? chunk.message?.usage;
367
+ if (raw) {
368
+ if (Object.prototype.hasOwnProperty.call(raw, "cache_read_input_tokens")
369
+ || Object.prototype.hasOwnProperty.call(raw, "cache_creation_input_tokens")) {
370
+ state.cacheTelemetryMeasured = true;
371
+ }
372
+ state.uncachedInput = Math.max(state.uncachedInput, numeric(raw, "input_tokens") ?? 0);
373
+ state.cacheReadTokens = Math.max(state.cacheReadTokens, numeric(raw, "cache_read_input_tokens") ?? 0);
374
+ state.cacheCreationTokens = Math.max(state.cacheCreationTokens, numeric(raw, "cache_creation_input_tokens") ?? 0);
375
+ state.outputTokens = Math.max(state.outputTokens, numeric(raw, "output_tokens") ?? 0);
376
+ const inputTokens = state.uncachedInput + state.cacheReadTokens + state.cacheCreationTokens;
377
+ const cacheTelemetryStatus = state.cacheTelemetryMeasured ? "measured" : "unavailable";
378
+ const providerUsage = {
379
+ inputTokens,
380
+ outputTokens: state.outputTokens,
381
+ ...(state.cacheReadTokens ? { cacheReadInputTokens: state.cacheReadTokens } : {}),
382
+ ...(state.cacheCreationTokens ? { cacheCreationInputTokens: state.cacheCreationTokens } : {}),
383
+ cacheTelemetryStatus,
384
+ ...(state.cacheTelemetryMeasured ? { cacheTelemetrySource: "anthropic_usage" } : {}),
385
+ };
386
+ const rawStopReason = chunk.delta?.stop_reason;
387
+ const stopReason = this.normalizeStopReason(rawStopReason);
388
+ events.push({
389
+ type: "usage",
390
+ totalTokens: inputTokens + state.outputTokens,
391
+ inputTokens,
392
+ outputTokens: state.outputTokens,
393
+ cacheReadInputTokens: state.cacheReadTokens,
394
+ cacheCreationInputTokens: state.cacheCreationTokens,
395
+ cacheTelemetryStatus,
396
+ ...(state.cacheTelemetryMeasured ? { cacheTelemetrySource: "anthropic_usage" } : {}),
397
+ ...(stopReason ? { stopReason } : {}),
398
+ ...(rawStopReason ? { rawStopReason } : {}),
399
+ providerUsage,
400
+ });
401
+ }
402
+ }
403
+ else if (chunk.type === "content_block_start") {
404
+ state.nativeBlocks[chunk.index] = { ...chunk.content_block };
405
+ if (chunk.content_block.type === "text") {
406
+ const initialText = String(chunk.content_block.text ?? "");
407
+ const visibleText = guardTextDelta(initialText, state.textualToolCallGuard);
408
+ state.finalText += visibleText;
409
+ if (visibleText)
410
+ events.push({ type: "text_delta", delta: visibleText });
411
+ }
412
+ else if (chunk.content_block.type === "tool_use") {
413
+ state.textualToolCallGuard.sawNativeToolCall = true;
414
+ state.toolBlocks[chunk.index] = {
415
+ id: chunk.content_block.id,
416
+ name: chunk.content_block.name,
417
+ argsBuffer: "",
418
+ };
419
+ }
420
+ }
421
+ else if (chunk.type === "content_block_delta") {
422
+ const delta = chunk.delta;
423
+ if (delta.type === "text_delta") {
424
+ const visibleText = guardTextDelta(delta.text, state.textualToolCallGuard);
425
+ state.finalText += visibleText;
426
+ state.nativeBlocks[chunk.index] = {
427
+ ...state.nativeBlocks[chunk.index],
428
+ text: String(state.nativeBlocks[chunk.index]?.text ?? "") + delta.text,
429
+ };
430
+ if (visibleText)
431
+ events.push({ type: "text_delta", delta: visibleText });
432
+ }
433
+ else if (delta.type === "thinking_delta") {
434
+ state.nativeBlocks[chunk.index] = {
435
+ ...state.nativeBlocks[chunk.index],
436
+ thinking: String(state.nativeBlocks[chunk.index]?.thinking ?? "") + delta.thinking,
437
+ };
438
+ events.push({ type: "thinking_delta", delta: delta.thinking });
439
+ }
440
+ else if (delta.type === "signature_delta") {
441
+ state.nativeBlocks[chunk.index] = {
442
+ ...state.nativeBlocks[chunk.index],
443
+ signature: String(state.nativeBlocks[chunk.index]?.signature ?? "") + delta.signature,
444
+ };
445
+ }
446
+ else if (delta.type === "input_json_delta" && state.toolBlocks[chunk.index]) {
447
+ state.toolBlocks[chunk.index].argsBuffer += delta.partial_json;
448
+ }
449
+ }
450
+ else if (chunk.type === "content_block_stop" && state.toolBlocks[chunk.index]) {
451
+ const tool = state.toolBlocks[chunk.index];
452
+ delete state.toolBlocks[chunk.index];
453
+ let args = {};
454
+ try {
455
+ args = JSON.parse(tool.argsBuffer || "{}");
456
+ }
457
+ catch {
458
+ args = {};
459
+ }
460
+ state.nativeBlocks[chunk.index] = { ...state.nativeBlocks[chunk.index], input: args };
461
+ state.finalToolCalls.push({
462
+ id: tool.id,
463
+ name: tool.name,
464
+ arguments: JSON.stringify(args),
465
+ });
466
+ events.push({
467
+ type: "tool_call",
468
+ id: tool.id,
469
+ name: tool.name,
470
+ arguments: args,
471
+ });
472
+ }
473
+ return { events };
474
+ }
475
+ finishStream(state) {
476
+ if (state.textualToolCallGuard.mode === "candidate")
477
+ throw textualToolCallError();
478
+ const events = [];
479
+ if (state.textualToolCallGuard.tail) {
480
+ const tail = state.textualToolCallGuard.tail;
481
+ state.textualToolCallGuard.tail = "";
482
+ state.finalText += tail;
483
+ events.push({ type: "text_delta", delta: tail });
484
+ }
485
+ const blocks = Object.keys(state.nativeBlocks)
486
+ .map(Number)
487
+ .sort((left, right) => left - right)
488
+ .map(index => state.nativeBlocks[index]);
489
+ return {
490
+ events,
491
+ ...(blocks.length ? { replay: { protocol: "anthropic-messages", native_blocks: blocks } } : {}),
492
+ };
493
+ }
494
+ normalizeUsage(raw) {
495
+ if (raw === undefined || raw === null)
496
+ return undefined;
497
+ if (typeof raw !== "object" || Array.isArray(raw)) {
498
+ throw new ProtocolResponseError("anthropic-messages", "usage must be an object");
499
+ }
500
+ const record = raw;
501
+ const uncached = numeric(record, "input_tokens");
502
+ const cacheRead = numeric(record, "cache_read_input_tokens");
503
+ const cacheCreation = numeric(record, "cache_creation_input_tokens");
504
+ const output = numeric(record, "output_tokens");
505
+ if (uncached === undefined && cacheRead === undefined
506
+ && cacheCreation === undefined && output === undefined)
507
+ return undefined;
508
+ return {
509
+ inputTokens: (uncached ?? 0) + (cacheRead ?? 0) + (cacheCreation ?? 0),
510
+ outputTokens: output ?? 0,
511
+ ...(cacheRead ? { cacheReadInputTokens: cacheRead } : {}),
512
+ ...(cacheCreation ? { cacheCreationInputTokens: cacheCreation } : {}),
513
+ ...(Object.prototype.hasOwnProperty.call(record, "cache_read_input_tokens")
514
+ || Object.prototype.hasOwnProperty.call(record, "cache_creation_input_tokens")
515
+ ? { cacheTelemetryStatus: "measured", cacheTelemetrySource: "anthropic_usage" }
516
+ : { cacheTelemetryStatus: "unavailable" }),
517
+ };
518
+ }
519
+ normalizeStopReason(raw) {
520
+ if (raw === undefined)
521
+ return undefined;
522
+ switch (raw) {
523
+ case "end_turn": return "end_turn";
524
+ case "tool_use": return "tool_use";
525
+ case "max_tokens": return "max_tokens";
526
+ case "stop_sequence": return "stop_sequence";
527
+ default: return "other";
528
+ }
529
+ }
530
+ }
@@ -9,15 +9,14 @@ import { type AnthropicVendorProfile } from "./vendor-profiles.js";
9
9
  * `<Vendor>AnthropicProvider` subclasses that existed only to carry that config.
10
10
  *
11
11
  * Adding a new Anthropic-compatible vendor is now "add a profile" — no new
12
- * provider class is required (the named `<Vendor>AnthropicProvider` shims are
13
- * kept only for backward compatibility / `instanceof` checks).
12
+ * provider class is required.
14
13
  */
15
14
  export declare class AnthropicCompatibleProvider extends AnthropicProvider {
16
15
  private readonly vendorProfile;
17
16
  constructor(profile: AnthropicVendorProfile, apiKey: string, model?: string, retry?: {
18
17
  maxRetries: number;
19
18
  baseDelay: number;
20
- }, baseURL?: string);
19
+ }, baseURL?: string, runtimePolicy?: RuntimePolicy);
21
20
  protected providerName(): string;
22
21
  runtimePolicy(): RuntimePolicy;
23
22
  }
@@ -8,15 +8,18 @@ import { anthropicVendorBaseURL } from "./vendor-profiles.js";
8
8
  * `<Vendor>AnthropicProvider` subclasses that existed only to carry that config.
9
9
  *
10
10
  * Adding a new Anthropic-compatible vendor is now "add a profile" — no new
11
- * provider class is required (the named `<Vendor>AnthropicProvider` shims are
12
- * kept only for backward compatibility / `instanceof` checks).
11
+ * provider class is required.
13
12
  */
14
13
  export class AnthropicCompatibleProvider extends AnthropicProvider {
15
14
  vendorProfile;
16
- constructor(profile, apiKey, model, retry, baseURL) {
17
- super(apiKey, model ?? profile.defaultModel, retry, {
15
+ constructor(profile, apiKey, model, retry, baseURL, runtimePolicy) {
16
+ super({
17
+ apiKey,
18
+ model: model ?? profile.defaultModel,
19
+ retry,
18
20
  baseURL: baseURL ?? anthropicVendorBaseURL(profile),
19
21
  authMode: "api-key",
22
+ runtimePolicy,
20
23
  });
21
24
  this.vendorProfile = profile;
22
25
  }
@@ -24,6 +27,6 @@ export class AnthropicCompatibleProvider extends AnthropicProvider {
24
27
  return this.vendorProfile.providerId;
25
28
  }
26
29
  runtimePolicy() {
27
- return this.vendorProfile.policies[this.model] ?? {};
30
+ return super.runtimePolicy();
28
31
  }
29
32
  }
@@ -1,46 +1,43 @@
1
- import type { Message, ProviderDescriptor, ProviderReplay, ProviderRunState, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy } from "../types.js";
2
- interface AnthropicProviderOptions {
3
- baseURL?: string;
4
- authMode?: "api-key" | "bearer";
5
- }
6
- /** Options-object form for `AnthropicProvider` — the recommended constructor shape. */
7
- export interface AnthropicProviderConfig extends AnthropicProviderOptions {
1
+ import type { LLMProvider, Message, PromptMeasurement, ProviderDescriptor, ProviderReplay, ProviderRunState, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
2
+ import { type CanonicalAdapterInput } from "./content-normalization.js";
3
+ export interface AnthropicProviderConfig {
8
4
  apiKey: string;
9
5
  model?: string;
10
6
  retry?: {
11
7
  maxRetries: number;
12
8
  baseDelay: number;
13
9
  };
10
+ baseURL?: string;
11
+ authMode?: "api-key" | "bearer";
12
+ runtimePolicy?: RuntimePolicy;
14
13
  }
14
+ type ResolvedAnthropicRuntime = CanonicalAdapterInput["resolved"];
15
15
  export declare class AnthropicProvider implements LLMProvider {
16
16
  private client;
17
17
  private circuit;
18
18
  private maxRetries;
19
19
  private baseDelay;
20
20
  protected readonly model: string;
21
- private nativeAssistantBlocks;
22
- constructor(apiKeyOrConfig: string | AnthropicProviderConfig, model?: string, retry?: {
23
- maxRetries: number;
24
- baseDelay: number;
25
- }, options?: AnthropicProviderOptions);
21
+ private readonly adapter;
22
+ private readonly nativeAssistantBlocks;
23
+ private readonly resolvedRuntimePolicy;
24
+ private readonly directNativeTokenCounting;
25
+ private readonly defaultTextualToolCallPolicy;
26
+ private resolvedRuntime?;
27
+ constructor(config: AnthropicProviderConfig);
26
28
  runtimePolicy(): RuntimePolicy;
27
- /** Identity advertised in the descriptor; overridden by Anthropic-compatible vendors (e.g. MiniMax). */
29
+ /** Identity advertised in the descriptor; overridden by Anthropic-compatible vendors. */
28
30
  protected providerName(): string;
29
31
  descriptor(): ProviderDescriptor;
32
+ bindResolvedRuntime(resolved: ResolvedAnthropicRuntime): void;
30
33
  peekProviderReplay(message: Pick<Message, "content" | "toolCalls">): ProviderReplay | undefined;
31
34
  seedProviderReplay(message: Pick<Message, "content" | "toolCalls">, replay: ProviderReplay): void;
32
- /**
33
- * Build tool definitions. A cache breakpoint is anchored on the final tool
34
- * only when the system blocks won't carry one (`anchorCache`). When structured
35
- * system blocks are present, their breakpoints already cache the tools prefix
36
- * (tools render before system), so a redundant tool breakpoint would only burn
37
- * one of Anthropic's 4 cache_control slots — slots the message history needs.
38
- */
39
- private buildTools;
35
+ private adapterInput;
36
+ private buildPlan;
40
37
  complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
38
+ /** Native measurement belongs to the verified official endpoint, not the wire protocol. */
39
+ countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<PromptMeasurement>;
41
40
  stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, _state?: ProviderRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
42
- private requestExtensions;
43
- private hasBetas;
44
41
  private createMessage;
45
42
  private streamMessage;
46
43
  private buildSystem;