@deepstrike/sdk 0.2.51 → 0.2.60

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 (148) 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/providers/anthropic-adapter.d.ts +47 -0
  39. package/dist/providers/anthropic-adapter.js +444 -0
  40. package/dist/providers/anthropic-compatible.d.ts +2 -3
  41. package/dist/providers/anthropic-compatible.js +8 -5
  42. package/dist/providers/anthropic.d.ts +19 -23
  43. package/dist/providers/anthropic.js +169 -395
  44. package/dist/providers/base.js +43 -3
  45. package/dist/providers/capability-router.d.ts +29 -0
  46. package/dist/providers/capability-router.js +43 -0
  47. package/dist/providers/catalog.d.ts +16 -4
  48. package/dist/providers/catalog.js +112 -21
  49. package/dist/providers/content-normalization.d.ts +57 -0
  50. package/dist/providers/content-normalization.js +238 -0
  51. package/dist/providers/content-policy.d.ts +16 -0
  52. package/dist/providers/content-policy.js +39 -0
  53. package/dist/providers/credentials.d.ts +83 -0
  54. package/dist/providers/credentials.js +190 -0
  55. package/dist/providers/endpoints.d.ts +137 -0
  56. package/dist/providers/endpoints.js +128 -0
  57. package/dist/providers/factories.js +9 -3
  58. package/dist/providers/gemini-adapter.d.ts +33 -0
  59. package/dist/providers/gemini-adapter.js +272 -0
  60. package/dist/providers/gemini.d.ts +16 -3
  61. package/dist/providers/gemini.js +97 -195
  62. package/dist/providers/model-catalog.d.ts +37 -0
  63. package/dist/providers/model-catalog.js +62 -0
  64. package/dist/providers/model-registry.d.ts +98 -0
  65. package/dist/providers/model-registry.js +315 -0
  66. package/dist/providers/ollama-adapter.d.ts +65 -0
  67. package/dist/providers/ollama-adapter.js +188 -0
  68. package/dist/providers/ollama.d.ts +9 -4
  69. package/dist/providers/ollama.js +96 -109
  70. package/dist/providers/openai-chat-dialects.d.ts +154 -0
  71. package/dist/providers/openai-chat-dialects.js +179 -0
  72. package/dist/providers/openai-chat.d.ts +46 -18
  73. package/dist/providers/openai-chat.js +418 -51
  74. package/dist/providers/openai-responses-adapter.d.ts +42 -0
  75. package/dist/providers/openai-responses-adapter.js +341 -0
  76. package/dist/providers/openai-responses.d.ts +14 -33
  77. package/dist/providers/openai-responses.js +131 -264
  78. package/dist/providers/openai.d.ts +29 -76
  79. package/dist/providers/openai.js +195 -292
  80. package/dist/providers/protocol-adapter.d.ts +34 -0
  81. package/dist/providers/protocol-adapter.js +9 -0
  82. package/dist/providers/protocol-capabilities.d.ts +34 -0
  83. package/dist/providers/protocol-capabilities.js +44 -0
  84. package/dist/providers/provider-error.d.ts +31 -0
  85. package/dist/providers/provider-error.js +149 -0
  86. package/dist/providers/public.d.ts +26 -3
  87. package/dist/providers/public.js +13 -1
  88. package/dist/providers/registry.d.ts +7 -6
  89. package/dist/providers/registry.js +47 -20
  90. package/dist/providers/request-plan.d.ts +86 -0
  91. package/dist/providers/request-plan.js +175 -0
  92. package/dist/providers/usage-normalizer.d.ts +48 -0
  93. package/dist/providers/usage-normalizer.js +96 -0
  94. package/dist/providers/vendor-profiles.d.ts +2 -15
  95. package/dist/providers/vendor-profiles.js +14 -60
  96. package/dist/runtime/canonical-kernel-step.d.ts +10 -2
  97. package/dist/runtime/canonical-kernel-step.js +106 -32
  98. package/dist/runtime/context-policy.d.ts +10 -12
  99. package/dist/runtime/context-policy.js +6 -8
  100. package/dist/runtime/durable-content.d.ts +50 -0
  101. package/dist/runtime/durable-content.js +159 -0
  102. package/dist/runtime/execution-plane.d.ts +2 -2
  103. package/dist/runtime/execution-plane.js +2 -2
  104. package/dist/runtime/kernel-event-log.js +0 -1
  105. package/dist/runtime/kernel-step.d.ts +0 -1
  106. package/dist/runtime/kernel-step.js +4 -2
  107. package/dist/runtime/mcp-proxy-plane.d.ts +25 -1
  108. package/dist/runtime/mcp-proxy-plane.js +44 -6
  109. package/dist/runtime/output-schema.d.ts +1 -2
  110. package/dist/runtime/provider-replay.d.ts +1 -1
  111. package/dist/runtime/provider-replay.js +12 -27
  112. package/dist/runtime/reactive-session.d.ts +1 -1
  113. package/dist/runtime/reactive-session.js +2 -3
  114. package/dist/runtime/run-group.d.ts +1 -1
  115. package/dist/runtime/runner.d.ts +26 -40
  116. package/dist/runtime/runner.js +145 -63
  117. package/dist/runtime/session-log.d.ts +8 -1
  118. package/dist/runtime/session-log.js +42 -2
  119. package/dist/runtime/session-repair.d.ts +1 -1
  120. package/dist/runtime/session-repair.js +1 -1
  121. package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
  122. package/dist/runtime/sub-agent-orchestrator.js +8 -11
  123. package/dist/runtime/workflow-control-flow.d.ts +0 -4
  124. package/dist/runtime/workflow-control-flow.js +0 -16
  125. package/dist/session.d.ts +11 -0
  126. package/dist/session.js +1 -0
  127. package/dist/skill.d.ts +17 -0
  128. package/dist/skill.js +16 -0
  129. package/dist/skills/loader.d.ts +3 -0
  130. package/dist/tools/errors.d.ts +1 -3
  131. package/dist/tools/errors.js +1 -3
  132. package/dist/tools/index.d.ts +3 -0
  133. package/dist/types/agent.d.ts +21 -9
  134. package/dist/types/agent.js +30 -4
  135. package/dist/types.d.ts +128 -13
  136. package/package.json +3 -3
  137. package/dist/providers/deepseek.d.ts +0 -46
  138. package/dist/providers/deepseek.js +0 -97
  139. package/dist/providers/glm.d.ts +0 -25
  140. package/dist/providers/glm.js +0 -48
  141. package/dist/providers/kimi.d.ts +0 -23
  142. package/dist/providers/kimi.js +0 -30
  143. package/dist/providers/minimax.d.ts +0 -49
  144. package/dist/providers/minimax.js +0 -98
  145. package/dist/providers/profiles.d.ts +0 -1992
  146. package/dist/providers/profiles.js +0 -796
  147. package/dist/providers/qwen.d.ts +0 -38
  148. package/dist/providers/qwen.js +0 -97
@@ -0,0 +1,48 @@
1
+ /**
2
+ * spc_011-C-07: normalizes each vendor's raw postflight usage object into the shared
3
+ * `ProviderUsage` shape (`../types.js`). One function per wire family, not one
4
+ * per provider — DeepSeek/Kimi/GLM/Qwen/MiniMax's OpenAI-wire variants all route through
5
+ * `normalizeOpenAIUsage` via `OpenAIChatProvider` inheritance, and their Anthropic-wire variants
6
+ * route through `normalizeAnthropicUsage` via `AnthropicCompatibleProvider` inheritance — the
7
+ * "8 providers" the spec counts are 8 *providers*, not 8 independent parsing implementations.
8
+ *
9
+ * Reuses `openAICachedPromptTokens` (`./base.js`) for the OpenAI-family cache figure rather than
10
+ * re-deriving it — that function already covers the OpenAI/Qwen/MiniMax/GLM/Kimi standard shape
11
+ * plus DeepSeek's `prompt_cache_hit_tokens` variant.
12
+ *
13
+ * `TokenUsage`/`UsageEvent` are otherwise untouched by this module. Missing or malformed usage
14
+ * returns `undefined`; absence is not a zero-token measurement.
15
+ */
16
+ import type { ProviderUsage } from "../types.js";
17
+ /**
18
+ * Covers both OpenAI wire shapes actually in use: Chat Completions (`prompt_tokens`/
19
+ * `completion_tokens`/`completion_tokens_details.reasoning_tokens`, used by `openai.ts` and every
20
+ * `OpenAIChatProvider` subclass) and the Responses API (`input_tokens`/`output_tokens`/
21
+ * `output_tokens_details.reasoning_tokens`, used by `openai-responses.ts`) — the two field-name
22
+ * conventions are read via fallback, and only one will ever be present on a given raw object.
23
+ */
24
+ export declare function normalizeOpenAIUsage(usage: unknown): ProviderUsage | undefined;
25
+ /**
26
+ * Anthropic's raw `input_tokens` is UNCACHED input only (unlike OpenAI's `prompt_tokens`, which
27
+ * is already cache-inclusive) — `anthropic.ts`'s own `stream()` sums `input_tokens +
28
+ * cache_read_input_tokens + cache_creation_input_tokens` into the full prompt size for the same
29
+ * reason context-pressure accounting needs it (see that file's comment on why excluding cached
30
+ * tokens would suppress compaction until a 413). This function replicates that same sum so
31
+ * `ProviderUsage.inputTokens` means the same "full prompt size" thing across vendors — reading
32
+ * raw `input_tokens` alone here would silently undercount every cache-heavy Anthropic turn.
33
+ * No `reasoning_tokens`-equivalent field exists in this SDK's `Usage` type, so that field stays
34
+ * unset rather than guessed.
35
+ */
36
+ export declare function normalizeAnthropicUsage(usage: unknown): ProviderUsage | undefined;
37
+ /**
38
+ * `@google/generative-ai`'s `UsageMetadata` has no reasoning/thoughts token field and no separate
39
+ * cache-write count (only `cachedContentTokenCount`, a read figure) — `reasoningTokens` and
40
+ * `cacheCreationInputTokens` stay unset rather than invented.
41
+ */
42
+ export declare function normalizeGeminiUsage(usage: unknown): ProviderUsage | undefined;
43
+ /**
44
+ * Ollama's final stream chunk (`done: true`) carries `prompt_eval_count`/`eval_count` — no cache
45
+ * or reasoning concept exists in its API at all, so both stay unset. Before this card `ollama.ts`
46
+ * read neither field; this is the first usage extraction it has ever had.
47
+ */
48
+ export declare function normalizeOllamaUsage(chunk: unknown): ProviderUsage | undefined;
@@ -0,0 +1,96 @@
1
+ import { openAICachedPromptTokens } from "./base.js";
2
+ function readNumber(obj, key) {
3
+ const value = obj?.[key];
4
+ return typeof value === "number" ? value : undefined;
5
+ }
6
+ /**
7
+ * Covers both OpenAI wire shapes actually in use: Chat Completions (`prompt_tokens`/
8
+ * `completion_tokens`/`completion_tokens_details.reasoning_tokens`, used by `openai.ts` and every
9
+ * `OpenAIChatProvider` subclass) and the Responses API (`input_tokens`/`output_tokens`/
10
+ * `output_tokens_details.reasoning_tokens`, used by `openai-responses.ts`) — the two field-name
11
+ * conventions are read via fallback, and only one will ever be present on a given raw object.
12
+ */
13
+ export function normalizeOpenAIUsage(usage) {
14
+ const u = usage && typeof usage === "object" ? usage : undefined;
15
+ const rawInput = readNumber(u, "prompt_tokens") ?? readNumber(u, "input_tokens");
16
+ const rawOutput = readNumber(u, "completion_tokens") ?? readNumber(u, "output_tokens");
17
+ if (rawInput === undefined && rawOutput === undefined)
18
+ return undefined;
19
+ const inputTokens = rawInput ?? 0;
20
+ const outputTokens = rawOutput ?? 0;
21
+ const cacheReadInputTokens = openAICachedPromptTokens(usage);
22
+ const details = (u?.completion_tokens_details ?? u?.output_tokens_details);
23
+ const reasoningTokens = readNumber(details, "reasoning_tokens");
24
+ const providerUsage = {
25
+ inputTokens,
26
+ outputTokens,
27
+ ...(cacheReadInputTokens > 0 ? { cacheReadInputTokens } : {}),
28
+ ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),
29
+ };
30
+ return providerUsage;
31
+ }
32
+ /**
33
+ * Anthropic's raw `input_tokens` is UNCACHED input only (unlike OpenAI's `prompt_tokens`, which
34
+ * is already cache-inclusive) — `anthropic.ts`'s own `stream()` sums `input_tokens +
35
+ * cache_read_input_tokens + cache_creation_input_tokens` into the full prompt size for the same
36
+ * reason context-pressure accounting needs it (see that file's comment on why excluding cached
37
+ * tokens would suppress compaction until a 413). This function replicates that same sum so
38
+ * `ProviderUsage.inputTokens` means the same "full prompt size" thing across vendors — reading
39
+ * raw `input_tokens` alone here would silently undercount every cache-heavy Anthropic turn.
40
+ * No `reasoning_tokens`-equivalent field exists in this SDK's `Usage` type, so that field stays
41
+ * unset rather than guessed.
42
+ */
43
+ export function normalizeAnthropicUsage(usage) {
44
+ const u = usage && typeof usage === "object" ? usage : undefined;
45
+ const rawUncachedInput = readNumber(u, "input_tokens");
46
+ const rawCacheRead = readNumber(u, "cache_read_input_tokens");
47
+ const rawCacheCreation = readNumber(u, "cache_creation_input_tokens");
48
+ const rawOutput = readNumber(u, "output_tokens");
49
+ if (rawUncachedInput === undefined && rawCacheRead === undefined && rawCacheCreation === undefined && rawOutput === undefined)
50
+ return undefined;
51
+ const uncachedInput = rawUncachedInput ?? 0;
52
+ const cacheReadInputTokens = rawCacheRead ?? 0;
53
+ const cacheCreationInputTokens = rawCacheCreation ?? 0;
54
+ const outputTokens = rawOutput ?? 0;
55
+ const providerUsage = {
56
+ inputTokens: uncachedInput + cacheReadInputTokens + cacheCreationInputTokens,
57
+ outputTokens,
58
+ ...(cacheReadInputTokens > 0 ? { cacheReadInputTokens } : {}),
59
+ ...(cacheCreationInputTokens > 0 ? { cacheCreationInputTokens } : {}),
60
+ };
61
+ return providerUsage;
62
+ }
63
+ /**
64
+ * `@google/generative-ai`'s `UsageMetadata` has no reasoning/thoughts token field and no separate
65
+ * cache-write count (only `cachedContentTokenCount`, a read figure) — `reasoningTokens` and
66
+ * `cacheCreationInputTokens` stay unset rather than invented.
67
+ */
68
+ export function normalizeGeminiUsage(usage) {
69
+ const u = usage && typeof usage === "object" ? usage : undefined;
70
+ const rawInput = readNumber(u, "promptTokenCount");
71
+ const rawOutput = readNumber(u, "candidatesTokenCount");
72
+ if (rawInput === undefined && rawOutput === undefined)
73
+ return undefined;
74
+ const inputTokens = rawInput ?? 0;
75
+ const outputTokens = rawOutput ?? 0;
76
+ const cacheReadInputTokens = readNumber(u, "cachedContentTokenCount");
77
+ const providerUsage = {
78
+ inputTokens,
79
+ outputTokens,
80
+ ...(cacheReadInputTokens ? { cacheReadInputTokens } : {}),
81
+ };
82
+ return providerUsage;
83
+ }
84
+ /**
85
+ * Ollama's final stream chunk (`done: true`) carries `prompt_eval_count`/`eval_count` — no cache
86
+ * or reasoning concept exists in its API at all, so both stay unset. Before this card `ollama.ts`
87
+ * read neither field; this is the first usage extraction it has ever had.
88
+ */
89
+ export function normalizeOllamaUsage(chunk) {
90
+ const u = chunk && typeof chunk === "object" ? chunk : undefined;
91
+ const rawInput = readNumber(u, "prompt_eval_count");
92
+ const rawOutput = readNumber(u, "eval_count");
93
+ if (rawInput === undefined && rawOutput === undefined)
94
+ return undefined;
95
+ return { inputTokens: rawInput ?? 0, outputTokens: rawOutput ?? 0 };
96
+ }
@@ -1,6 +1,5 @@
1
- import type { RuntimePolicy } from "../types.js";
2
- import { endpointProfiles } from "./profiles.js";
3
- import type { ProviderId } from "./profiles.js";
1
+ import { endpointProfiles } from "./endpoints.js";
2
+ import type { ProviderId } from "./endpoints.js";
4
3
  export type EndpointProfileKey = keyof typeof endpointProfiles;
5
4
  export interface AnthropicVendorProfile {
6
5
  /** Identity advertised in `descriptor().provider`. */
@@ -9,44 +8,32 @@ export interface AnthropicVendorProfile {
9
8
  defaultModel: string;
10
9
  /** Endpoint profile whose `baseURL` is the Anthropic-compatible wire for this vendor. */
11
10
  baseURLProfileKey: EndpointProfileKey;
12
- /** Recommended `maxTurns` per model id; missing model → empty policy. */
13
- policies: Record<string, RuntimePolicy>;
14
11
  }
15
- export declare const DEEPSEEK_POLICIES: Record<string, RuntimePolicy>;
16
- export declare const KIMI_POLICIES: Record<string, RuntimePolicy>;
17
- export declare const QWEN_POLICIES: Record<string, RuntimePolicy>;
18
- export declare const GLM_POLICIES: Record<string, RuntimePolicy>;
19
- export declare const MINIMAX_POLICIES: Record<string, RuntimePolicy>;
20
12
  export declare const anthropicVendorProfiles: {
21
13
  deepseek: {
22
14
  providerId: "deepseek";
23
15
  defaultModel: string;
24
16
  baseURLProfileKey: "deepseek.anthropic";
25
- policies: Record<string, RuntimePolicy>;
26
17
  };
27
18
  kimi: {
28
19
  providerId: "kimi";
29
20
  defaultModel: string;
30
21
  baseURLProfileKey: "kimi.anthropic";
31
- policies: Record<string, RuntimePolicy>;
32
22
  };
33
23
  qwen: {
34
24
  providerId: "qwen";
35
25
  defaultModel: string;
36
26
  baseURLProfileKey: "qwen.anthropic";
37
- policies: Record<string, RuntimePolicy>;
38
27
  };
39
28
  glm: {
40
29
  providerId: "glm";
41
30
  defaultModel: string;
42
31
  baseURLProfileKey: "glm.anthropic";
43
- policies: Record<string, RuntimePolicy>;
44
32
  };
45
33
  minimax: {
46
34
  providerId: "minimax";
47
35
  defaultModel: string;
48
36
  baseURLProfileKey: "minimax.anthropic";
49
- policies: Record<string, RuntimePolicy>;
50
37
  };
51
38
  };
52
39
  export type AnthropicVendorId = keyof typeof anthropicVendorProfiles;
@@ -1,64 +1,18 @@
1
- import { endpointProfiles } from "./profiles.js";
2
- export const DEEPSEEK_POLICIES = {
3
- "deepseek-chat": { maxTurns: 25 },
4
- "deepseek-reasoner": { maxTurns: 50 },
5
- "deepseek-v4-flash": { maxTurns: 20 },
6
- "deepseek-v4-pro": { maxTurns: 35 },
7
- };
8
- export const KIMI_POLICIES = {
9
- "moonshot-v1-8k": { maxTurns: 15 },
10
- "moonshot-v1-32k": { maxTurns: 20 },
11
- "moonshot-v1-128k": { maxTurns: 30 },
12
- "kimi-k2.5": { maxTurns: 30 },
13
- "kimi-k2.6": { maxTurns: 35 },
14
- "kimi-k2-thinking": { maxTurns: 50 },
15
- "kimi-k2-thinking-turbo": { maxTurns: 40 },
16
- };
17
- export const QWEN_POLICIES = {
18
- "qwen3.7-max-preview": { maxTurns: 45 },
19
- "qwen3.7-plus-preview": { maxTurns: 40 },
20
- "qwen3.6-max-preview": { maxTurns: 40 },
21
- "qwen3.6-plus": { maxTurns: 35 },
22
- "qwen3.6-flash": { maxTurns: 20 },
23
- "qwen3.6-35b-a3b": { maxTurns: 25 },
24
- "qwen3.6-27b": { maxTurns: 25 },
25
- "qwen3.5-plus": { maxTurns: 35 },
26
- "qwen3.5-flash": { maxTurns: 20 },
27
- "qwen3.5-397b-a17b": { maxTurns: 35 },
28
- "qwen3.5-122b-a10b": { maxTurns: 25 },
29
- "qwen3.5-35b-a3b": { maxTurns: 20 },
30
- "qwen3.5-27b": { maxTurns: 20 },
31
- };
32
- export const GLM_POLICIES = {
33
- "glm-5.2": { maxTurns: 50 },
34
- "glm/glm-5.2": { maxTurns: 50 },
35
- "glm-5.1": { maxTurns: 50 },
36
- "glm/glm-5.1": { maxTurns: 50 },
37
- "glm-4-plus": { maxTurns: 35 },
38
- "glm/glm-4-plus": { maxTurns: 35 },
39
- "glm-4-flash": { maxTurns: 15 },
40
- "glm/glm-4-flash": { maxTurns: 15 },
41
- "glm-4-air": { maxTurns: 20 },
42
- "glm/glm-4-air": { maxTurns: 20 },
43
- };
44
- export const MINIMAX_POLICIES = {
45
- "MiniMax-M3": { maxTurns: 35 },
46
- "MiniMax-M3-highspeed": { maxTurns: 35 },
47
- "MiniMax-M2.7": { maxTurns: 35 },
48
- "MiniMax-M2.7-highspeed": { maxTurns: 35 },
49
- "MiniMax-M2.5": { maxTurns: 25 },
50
- "MiniMax-M2.5-highspeed": { maxTurns: 25 },
51
- "MiniMax-M2.1": { maxTurns: 25 },
52
- "MiniMax-M2.1-highspeed": { maxTurns: 25 },
53
- "MiniMax-M2": { maxTurns: 20 },
54
- "MiniMax-Text-01": { maxTurns: 20 },
55
- };
1
+ // Single source of truth for the Anthropic-compatible vendor backends (DeepSeek,
2
+ // Kimi, Qwen, GLM, MiniMax). Each backend differs only by data — provider id,
3
+ // default model, endpoint, and per-model runtime policy so the generic
4
+ // `AnthropicCompatibleProvider` reads a profile from here instead of every
5
+ // backend subclassing `AnthropicProvider` purely to carry configuration.
6
+ //
7
+ // Runtime policy and default model resolution live in ModelRegistry; this module
8
+ // only carries Anthropic-compatible transport configuration.
9
+ import { endpointProfiles } from "./endpoints.js";
56
10
  export const anthropicVendorProfiles = {
57
- deepseek: { providerId: "deepseek", defaultModel: "deepseek-v4-flash", baseURLProfileKey: "deepseek.anthropic", policies: DEEPSEEK_POLICIES },
58
- kimi: { providerId: "kimi", defaultModel: "kimi-k2.6", baseURLProfileKey: "kimi.anthropic", policies: KIMI_POLICIES },
59
- qwen: { providerId: "qwen", defaultModel: "qwen3.6-plus", baseURLProfileKey: "qwen.anthropic", policies: QWEN_POLICIES },
60
- glm: { providerId: "glm", defaultModel: "glm-5.2", baseURLProfileKey: "glm.anthropic", policies: GLM_POLICIES },
61
- minimax: { providerId: "minimax", defaultModel: "MiniMax-M3", baseURLProfileKey: "minimax.anthropic", policies: MINIMAX_POLICIES },
11
+ deepseek: { providerId: "deepseek", defaultModel: "deepseek-v4-flash", baseURLProfileKey: "deepseek.anthropic" },
12
+ kimi: { providerId: "kimi", defaultModel: "kimi-k2.6", baseURLProfileKey: "kimi.anthropic" },
13
+ qwen: { providerId: "qwen", defaultModel: "qwen3.6-plus", baseURLProfileKey: "qwen.anthropic" },
14
+ glm: { providerId: "glm", defaultModel: "glm-5.2", baseURLProfileKey: "glm.anthropic" },
15
+ minimax: { providerId: "minimax", defaultModel: "MiniMax-M3", baseURLProfileKey: "minimax.anthropic" },
62
16
  };
63
17
  /** Resolve the Anthropic-compatible base URL for a vendor profile. */
64
18
  export function anthropicVendorBaseURL(profile) {
@@ -30,6 +30,10 @@ export interface CanonicalTransition {
30
30
  recordDigest: string;
31
31
  plannedStep: CanonicalPlannedStep;
32
32
  checkpointAdvice?: Record<string, unknown>;
33
+ /** Set when the advised §12.3 checkpoint failed AFTER this step was durably committed.
34
+ * The step itself is published and authoritative; the checkpoint is deferred
35
+ * housekeeping retried at the next advice or forced by the checkpoint_required gate. */
36
+ checkpointFailure?: string;
33
37
  replayed: boolean;
34
38
  }
35
39
  export declare function canonicalUnsupportedEffectResolution(effectId: string, effectKind: string): CanonicalKernelInput;
@@ -44,8 +48,13 @@ export declare class CanonicalKernelRejectedError extends Error {
44
48
  * is therefore a rebuild boundary, never an abort boundary.
45
49
  */
46
50
  export declare class CanonicalKernelRebuildRequiredError extends Error {
51
+ /** True when the runtime was already rebuilt from the journal with the durable record
52
+ * applied — the caller can resync and continue. False when the rebuild itself failed
53
+ * and the operation cannot proceed without journal repair. */
54
+ readonly rebuilt: boolean;
47
55
  constructor(message: string, options?: {
48
56
  cause?: unknown;
57
+ rebuilt?: boolean;
49
58
  });
50
59
  }
51
60
  /**
@@ -86,8 +95,7 @@ export interface CanonicalRunnerRuntimeOptions {
86
95
  }
87
96
  /**
88
97
  * Canonical operation runtime used by the Node host.
89
- * Every durable transition below is one of the canonical ABI's five input classes; no legacy
90
- * envelope or synthesized host transaction reaches core or storage.
98
+ * Every durable transition below is one of the canonical contract's five input classes.
91
99
  */
92
100
  export declare class CanonicalRunnerRuntime {
93
101
  private readonly options;
@@ -1,5 +1,4 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
- import { getKernel } from "../kernel.js";
3
2
  import { JournalCasConflictError, MAX_CHAIN_POSITION as JOURNAL_MAX_CHAIN_POSITION, } from "./kernel-journal.js";
4
3
  import { encodeCanonicalContentParts, kernelMessageToSdk, renderedContextToSdk, } from "./kernel-step.js";
5
4
  export const MAX_CHAIN_POSITION = JOURNAL_MAX_CHAIN_POSITION;
@@ -12,6 +11,21 @@ function totalUsageTokens(terminal) {
12
11
  const output = Number(usage.output_tokens ?? 0);
13
12
  return Number.isSafeInteger(input + output) ? input + output : 0;
14
13
  }
14
+ function canonicalProviderFailureKind(kind) {
15
+ switch (kind) {
16
+ case "transport":
17
+ case "rate_limit":
18
+ case "model_unavailable":
19
+ return "transport_exhausted";
20
+ case "auth":
21
+ case "invalid_request":
22
+ case "modality":
23
+ case "protocol":
24
+ return "protocol_error";
25
+ default:
26
+ return "unknown";
27
+ }
28
+ }
15
29
  export function canonicalUnsupportedEffectResolution(effectId, effectKind) {
16
30
  return {
17
31
  kind: "resolve_effect",
@@ -281,9 +295,14 @@ export class CanonicalKernelRejectedError extends Error {
281
295
  * is therefore a rebuild boundary, never an abort boundary.
282
296
  */
283
297
  export class CanonicalKernelRebuildRequiredError extends Error {
298
+ /** True when the runtime was already rebuilt from the journal with the durable record
299
+ * applied — the caller can resync and continue. False when the rebuild itself failed
300
+ * and the operation cannot proceed without journal repair. */
301
+ rebuilt;
284
302
  constructor(message, options) {
285
- super(message, options);
303
+ super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);
286
304
  this.name = "CanonicalKernelRebuildRequiredError";
305
+ this.rebuilt = options?.rebuilt ?? false;
287
306
  }
288
307
  }
289
308
  function chainPosition(value, label) {
@@ -338,7 +357,6 @@ export class CanonicalKernelHost {
338
357
  }
339
358
  async transition(input, options = {}) {
340
359
  const inputJson = JSON.stringify({
341
- abi_version: getKernel().kernelAbiVersion(),
342
360
  operation_id: this.operationId,
343
361
  input_id: options.inputId ?? `node-input-${randomUUID()}`,
344
362
  observed_at_ms: options.observedAtMs ?? String(Date.now()),
@@ -434,6 +452,7 @@ export class CanonicalKernelHost {
434
452
  }
435
453
  const stepSeq = chainPosition(preparation.stepSeq, "prepared stepSeq");
436
454
  let appended = false;
455
+ let transition;
437
456
  try {
438
457
  const receipt = await this.journal.compareAndAppend(this.operationId, preparation.expectedHead, {
439
458
  step_seq: stepSeq,
@@ -447,7 +466,7 @@ export class CanonicalKernelHost {
447
466
  throw new Error("canonical commit receipt disagrees with the durably appended record");
448
467
  }
449
468
  const checkpointAdvice = parseAdvice(committed.checkpointAdviceJson);
450
- const transition = {
469
+ transition = {
451
470
  inputJson,
452
471
  stepSeq,
453
472
  recordDigest: committed.recordDigest,
@@ -455,9 +474,6 @@ export class CanonicalKernelHost {
455
474
  ...(checkpointAdvice ? { checkpointAdvice } : {}),
456
475
  replayed: false,
457
476
  };
458
- if (checkpointAdvice)
459
- await this.checkpoint();
460
- return transition;
461
477
  }
462
478
  catch (error) {
463
479
  if (appended) {
@@ -467,7 +483,7 @@ export class CanonicalKernelHost {
467
483
  catch (restoreError) {
468
484
  throw new CanonicalKernelRebuildRequiredError("canonical record is durable, commit failed, and journal rebuild also failed", { cause: new AggregateError([error, restoreError]) });
469
485
  }
470
- throw new CanonicalKernelRebuildRequiredError("canonical record is durable but commit could not be published; runtime rebuilt from journal", { cause: error });
486
+ throw new CanonicalKernelRebuildRequiredError("canonical record is durable but commit could not be published; runtime rebuilt from journal", { cause: error, rebuilt: true });
471
487
  }
472
488
  try {
473
489
  this.kernel.abort(preparation.prepareToken);
@@ -481,6 +497,19 @@ export class CanonicalKernelHost {
481
497
  }
482
498
  throw error;
483
499
  }
500
+ // Past this point the step is durable AND committed. A failing advised checkpoint
501
+ // must not be misdiagnosed as a lost commit: it is deferred housekeeping — the next
502
+ // advice retries it, and the checkpoint_required prepare gate is the hard backstop.
503
+ if (transition.checkpointAdvice) {
504
+ try {
505
+ await this.checkpoint();
506
+ }
507
+ catch (checkpointError) {
508
+ transition.checkpointFailure =
509
+ checkpointError instanceof Error ? checkpointError.message : String(checkpointError);
510
+ }
511
+ }
512
+ return transition;
484
513
  }
485
514
  }
486
515
  function canonicalProviderMessage(raw) {
@@ -575,7 +604,7 @@ function logicalRunSpec(raw, goal) {
575
604
  ...(raw.metadata && typeof raw.metadata === "object" ? { metadata: raw.metadata } : {}),
576
605
  };
577
606
  }
578
- function canonicalWorkflowSpec(raw) {
607
+ function canonicalWorkflowSpec(raw, allowHostSchedulingFactors = false) {
579
608
  const nodes = Array.isArray(raw.nodes) ? raw.nodes.map(asObject) : [];
580
609
  const nodeIds = nodes.map((_node, index) => `wf-node${index}`);
581
610
  return {
@@ -598,6 +627,9 @@ function canonicalWorkflowSpec(raw) {
598
627
  unsupported.push("max_turns");
599
628
  if (node.max_wall_ms !== undefined || node.maxWallMs !== undefined)
600
629
  unsupported.push("max_wall_ms");
630
+ const schedulingFactors = node.scheduling_factors ?? node.schedulingFactors;
631
+ if (schedulingFactors !== undefined && !allowHostSchedulingFactors)
632
+ unsupported.push("scheduling_factors");
601
633
  const inheritance = node.context_inheritance ?? node.contextInheritance;
602
634
  if (unsupported.length > 0) {
603
635
  throw new CanonicalKernelRejectedError(JSON.stringify({
@@ -618,16 +650,20 @@ function canonicalWorkflowSpec(raw) {
618
650
  : [];
619
651
  const modelHint = node.model_hint ?? node.modelHint;
620
652
  const outputSchema = node.output_schema ?? node.outputSchema;
653
+ const canonicalSchedulingFactors = schedulingFactors === undefined
654
+ ? undefined
655
+ : canonicalSchedulingFactorsForHost(schedulingFactors);
621
656
  const runSpec = logicalRunSpec({
622
657
  goal,
623
658
  ...(node.role ? { role: node.role } : {}),
624
659
  ...(node.isolation ? { isolation: node.isolation } : {}),
625
660
  ...(inheritance ? { context_inheritance: inheritance } : {}),
626
- ...((modelHint !== undefined || outputSchema !== undefined)
661
+ ...((modelHint !== undefined || outputSchema !== undefined || canonicalSchedulingFactors !== undefined)
627
662
  ? {
628
663
  metadata: {
629
664
  ...(modelHint !== undefined ? { model_hint: modelHint } : {}),
630
665
  ...(outputSchema !== undefined ? { output_schema: outputSchema } : {}),
666
+ ...(canonicalSchedulingFactors !== undefined ? { scheduling_factors: canonicalSchedulingFactors } : {}),
631
667
  },
632
668
  }
633
669
  : {}),
@@ -645,6 +681,24 @@ function canonicalWorkflowSpec(raw) {
645
681
  }),
646
682
  };
647
683
  }
684
+ function canonicalSchedulingFactorsForHost(value) {
685
+ const raw = asObject(value);
686
+ const allowed = new Set(["deadline_urgency", "process_priority", "resource_pressure", "budget_pressure"]);
687
+ const unknown = Object.keys(raw).filter(key => !allowed.has(key));
688
+ if (unknown.length > 0)
689
+ throw new TypeError(`unknown scheduling factor(s): ${unknown.join(", ")}`);
690
+ const factors = {};
691
+ for (const key of allowed) {
692
+ const factor = raw[key];
693
+ if (factor === undefined)
694
+ continue;
695
+ if (!Number.isSafeInteger(factor) || factor < 0) {
696
+ throw new RangeError(`scheduling_factors.${key} must be a non-negative safe integer`);
697
+ }
698
+ factors[key] = factor;
699
+ }
700
+ return factors;
701
+ }
648
702
  function sha256(value) {
649
703
  return `sha256:${createHash("sha256").update(value).digest("hex")}`;
650
704
  }
@@ -659,8 +713,7 @@ function providerStopReason(value) {
659
713
  }
660
714
  /**
661
715
  * Canonical operation runtime used by the Node host.
662
- * Every durable transition below is one of the canonical ABI's five input classes; no legacy
663
- * envelope or synthesized host transaction reaches core or storage.
716
+ * Every durable transition below is one of the canonical contract's five input classes.
664
717
  */
665
718
  export class CanonicalRunnerRuntime {
666
719
  options;
@@ -786,7 +839,7 @@ export class CanonicalRunnerRuntime {
786
839
  kind: "start_operation",
787
840
  entry: {
788
841
  kind: "workflow",
789
- spec: canonicalWorkflowSpec(specValue),
842
+ spec: canonicalWorkflowSpec(specValue, true),
790
843
  },
791
844
  initial_context: this.initialContext,
792
845
  });
@@ -840,7 +893,8 @@ export class CanonicalRunnerRuntime {
840
893
  }
841
894
  case "provider_error": {
842
895
  const message = String(event.message ?? "");
843
- const contextOverflow = /context|token.*limit|too long/i.test(message);
896
+ const hasStructuredKind = typeof event.error_kind === "string";
897
+ const contextOverflow = event.error_kind === "context_overflow";
844
898
  input = contextOverflow
845
899
  ? {
846
900
  kind: "resolve_effect",
@@ -850,7 +904,7 @@ export class CanonicalRunnerRuntime {
850
904
  result: { kind: "provider", outcome: { kind: "context_overflow" } },
851
905
  },
852
906
  }
853
- : this.failedEffect(event, "transport_exhausted", message, true);
907
+ : this.failedEffect(event, hasStructuredKind ? canonicalProviderFailureKind(event.error_kind) : "transport_exhausted", message, typeof event.retryable === "boolean" ? event.retryable : true);
854
908
  break;
855
909
  }
856
910
  case "tool_results": {
@@ -1100,22 +1154,45 @@ export class CanonicalRunnerRuntime {
1100
1154
  async commit(input) {
1101
1155
  let nextInput = input;
1102
1156
  for (;;) {
1103
- const transition = await this.host.transition(nextInput);
1104
- if (!transition.replayed) {
1105
- for (const raw of transition.plannedStep.observations ?? []) {
1106
- const kind = String(raw.kind ?? "");
1107
- if (!kind)
1108
- throw new Error("canonical observation is missing kind");
1109
- this.hostObservations.push({ ...raw, kind });
1110
- }
1111
- if (transition.checkpointAdvice) {
1112
- this.hostObservations.push({
1113
- kind: "checkpoint_advised",
1114
- ...transition.checkpointAdvice,
1115
- });
1157
+ let transition;
1158
+ try {
1159
+ transition = await this.host.transition(nextInput);
1160
+ }
1161
+ catch (error) {
1162
+ if (!(error instanceof CanonicalKernelRebuildRequiredError) || !error.rebuilt)
1163
+ throw error;
1164
+ // The input's record is durable and the kernel was rebuilt from the journal with it
1165
+ // applied; only that step's observations are lost (the crash-window cost). Resync and
1166
+ // publish the rebuilt kernel's pending work instead of failing a healthy run.
1167
+ const lifecycle = this.host.kernel.lifecycle();
1168
+ this.configured = lifecycle !== "created";
1169
+ this.started = !["created", "configured"].includes(lifecycle);
1170
+ this.hostObservations.push({ kind: "kernel_rebuilt", reason: error.message });
1171
+ this.lastAction = this.currentAction();
1172
+ }
1173
+ if (transition) {
1174
+ if (!transition.replayed) {
1175
+ for (const raw of transition.plannedStep.observations ?? []) {
1176
+ const kind = String(raw.kind ?? "");
1177
+ if (!kind)
1178
+ throw new Error("canonical observation is missing kind");
1179
+ this.hostObservations.push({ ...raw, kind });
1180
+ }
1181
+ if (transition.checkpointAdvice) {
1182
+ this.hostObservations.push({
1183
+ kind: "checkpoint_advised",
1184
+ ...transition.checkpointAdvice,
1185
+ });
1186
+ }
1187
+ if (transition.checkpointFailure) {
1188
+ this.hostObservations.push({
1189
+ kind: "checkpoint_deferred",
1190
+ reason: transition.checkpointFailure,
1191
+ });
1192
+ }
1116
1193
  }
1194
+ this.lastAction = canonicalActionFromPlannedStep(transition.plannedStep);
1117
1195
  }
1118
- this.lastAction = canonicalActionFromPlannedStep(transition.plannedStep);
1119
1196
  if (this.lastAction?.kind !== "unsupported_effect")
1120
1197
  return this.lastAction;
1121
1198
  nextInput = canonicalUnsupportedEffectResolution(this.lastAction.effectId, this.lastAction.effectKind);
@@ -1386,9 +1463,6 @@ export class CanonicalRunnerRuntime {
1386
1463
  delete asObject(execution.entropy_watch).threshold;
1387
1464
  delete asObject(execution.entropy_watch).hysteresis;
1388
1465
  }
1389
- if (config.tool_dispatch_gate !== undefined) {
1390
- this.featurePolicy().tool_dispatch_gate = config.tool_dispatch_gate;
1391
- }
1392
1466
  if (config.knowledge_budget_ratio !== undefined) {
1393
1467
  const context = asObject(this.config.context_policy);
1394
1468
  context.knowledge_budget_ppm = Math.round(Number(config.knowledge_budget_ratio) * 1_000_000);
@@ -1,35 +1,33 @@
1
- export declare const CONTEXT_POLICY_VERSION: 1;
2
1
  export declare const PPM_SCALE: 1000000;
3
- export interface ContextPressureThresholdsV1 {
2
+ export interface ContextPressureThresholds {
4
3
  snip: number;
5
4
  micro: number;
6
5
  collapse: number;
7
6
  auto: number;
8
7
  renewal: number;
9
8
  }
10
- export interface ContextPolicyV1 {
11
- pressureThresholds: ContextPressureThresholdsV1;
9
+ export interface ContextPolicy {
10
+ pressureThresholds: ContextPressureThresholds;
12
11
  targetAfterCompress: number;
13
12
  preserveRecentTurns: number;
14
13
  renewalCarryover: number;
15
14
  collapseOldAssistantNarration: boolean;
16
15
  idleMicroCompactMinutes: number;
17
16
  }
18
- export interface ContextPolicyWireV1 {
19
- version: typeof CONTEXT_POLICY_VERSION;
20
- pressure_thresholds_ppm: ContextPressureThresholdsV1;
17
+ export interface ContextPolicyWire {
18
+ pressure_thresholds_ppm: ContextPressureThresholds;
21
19
  target_after_compress_ppm: number;
22
20
  preserve_recent_turns: number;
23
21
  renewal_carryover_ppm: number;
24
22
  collapse_old_assistant_narration: boolean;
25
23
  idle_micro_compact_minutes: number;
26
24
  }
27
- export interface ContextPolicyOverridesV1 extends Partial<Omit<ContextPolicyV1, "pressureThresholds">> {
28
- pressureThresholds?: Partial<ContextPressureThresholdsV1>;
25
+ export interface ContextPolicyOverrides extends Partial<Omit<ContextPolicy, "pressureThresholds">> {
26
+ pressureThresholds?: Partial<ContextPressureThresholds>;
29
27
  }
30
- export declare const DEFAULT_CONTEXT_POLICY_V1: Readonly<ContextPolicyV1>;
28
+ export declare const DEFAULT_CONTEXT_POLICY: Readonly<ContextPolicy>;
31
29
  /** Resolve ergonomic partial SDK options into one complete, atomically validated policy. */
32
- export declare function contextPolicyV1(overrides?: ContextPolicyOverridesV1): ContextPolicyV1;
30
+ export declare function contextPolicy(overrides?: ContextPolicyOverrides): ContextPolicy;
33
31
  /** Convert the public ratio-based policy to the canonical integer-only ABI wire shape. */
34
- export declare function normalizeContextPolicyV1(policy: ContextPolicyV1): ContextPolicyWireV1;
32
+ export declare function normalizeContextPolicy(policy: ContextPolicy): ContextPolicyWire;
35
33
  export declare function ratioToPpm(value: number, field?: string): number;