@deepstrike/sdk 0.2.52 → 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 +1 -2
  97. package/dist/runtime/canonical-kernel-step.js +47 -12
  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,37 @@
1
+ import type { ModelRegistration } from "./model-registry.js";
2
+ export type { ModelRegistration } from "./model-registry.js";
3
+ /** A query-only model catalog. Catalogs describe models; selection policy belongs to CapabilityRouter. */
4
+ export interface ModelCatalog {
5
+ list(): Promise<readonly ModelRegistration[]>;
6
+ get(modelId: string): Promise<ModelRegistration | undefined>;
7
+ }
8
+ export interface ModelCatalogSource {
9
+ list(): Promise<readonly ModelRegistration[]>;
10
+ }
11
+ export type ModelCatalogRefreshResult = {
12
+ ok: true;
13
+ } | {
14
+ ok: false;
15
+ errorCode: "refresh_failed";
16
+ };
17
+ /** Immutable, deterministic model facts supplied by the SDK or an application. */
18
+ export declare class StaticModelCatalog implements ModelCatalog {
19
+ private readonly registrations;
20
+ private readonly byId;
21
+ constructor(registrations: readonly ModelRegistration[]);
22
+ list(): Promise<readonly ModelRegistration[]>;
23
+ get(modelId: string): Promise<ModelRegistration | undefined>;
24
+ }
25
+ /**
26
+ * A host-owned discovery cache. Refresh never throws and never deletes the last good snapshot;
27
+ * callers can keep using the static catalog when a remote provider is unavailable.
28
+ */
29
+ export declare class DynamicModelCatalog implements ModelCatalog {
30
+ private readonly source;
31
+ private readonly fallback;
32
+ private snapshot;
33
+ constructor(source: ModelCatalogSource, fallback?: ModelCatalog);
34
+ list(): Promise<readonly ModelRegistration[]>;
35
+ get(modelId: string): Promise<ModelRegistration | undefined>;
36
+ refresh(): Promise<ModelCatalogRefreshResult>;
37
+ }
@@ -0,0 +1,62 @@
1
+ /** Immutable, deterministic model facts supplied by the SDK or an application. */
2
+ export class StaticModelCatalog {
3
+ registrations;
4
+ byId;
5
+ constructor(registrations) {
6
+ const byId = new Map();
7
+ for (const registration of registrations) {
8
+ const id = registration.descriptor.id;
9
+ if (byId.has(id))
10
+ throw new Error(`Duplicate model catalog entry: ${id}`);
11
+ byId.set(id, registration);
12
+ }
13
+ this.registrations = [...byId.values()].sort((a, b) => a.descriptor.id.localeCompare(b.descriptor.id));
14
+ this.byId = byId;
15
+ }
16
+ async list() {
17
+ return this.registrations;
18
+ }
19
+ async get(modelId) {
20
+ return this.byId.get(modelId);
21
+ }
22
+ }
23
+ /**
24
+ * A host-owned discovery cache. Refresh never throws and never deletes the last good snapshot;
25
+ * callers can keep using the static catalog when a remote provider is unavailable.
26
+ */
27
+ export class DynamicModelCatalog {
28
+ source;
29
+ fallback;
30
+ snapshot = new Map();
31
+ constructor(source, fallback = new StaticModelCatalog([])) {
32
+ this.source = source;
33
+ this.fallback = fallback;
34
+ }
35
+ async list() {
36
+ const merged = new Map();
37
+ for (const registration of await this.fallback.list())
38
+ merged.set(registration.descriptor.id, registration);
39
+ for (const registration of this.snapshot.values())
40
+ merged.set(registration.descriptor.id, registration);
41
+ return [...merged.values()].sort((a, b) => a.descriptor.id.localeCompare(b.descriptor.id));
42
+ }
43
+ async get(modelId) {
44
+ return this.snapshot.get(modelId) ?? await this.fallback.get(modelId);
45
+ }
46
+ async refresh() {
47
+ try {
48
+ const next = new Map();
49
+ for (const registration of await this.source.list()) {
50
+ const id = registration.descriptor.id;
51
+ if (next.has(id))
52
+ throw new Error("duplicate dynamic model catalog entry");
53
+ next.set(id, registration);
54
+ }
55
+ this.snapshot = next;
56
+ return { ok: true };
57
+ }
58
+ catch {
59
+ return { ok: false, errorCode: "refresh_failed" };
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,98 @@
1
+ import type { LLMProvider, RuntimePolicy } from "../types.js";
2
+ import { type EndpointProfile, type EndpointProfileId, type EndpointProtocol, type ProviderId } from "./endpoints.js";
3
+ import { type GenerationProtocol, type InputModality, type OutputModality, type ProtocolRuntimeCapabilities, type ProtocolRuntimeCapabilityOverrides } from "./protocol-capabilities.js";
4
+ export type { GenerationProtocol, InputModality, OutputModality, ProtocolRuntimeCapabilities, ProtocolRuntimeCapabilityOverrides, } from "./protocol-capabilities.js";
5
+ export type ModelKind = "generation" | "embedding";
6
+ export type CapabilityState = "supported" | "unsupported" | "unknown";
7
+ export declare const MODEL_CAPABILITY_STATES: readonly CapabilityState[];
8
+ export interface ModelDescriptor {
9
+ id: string;
10
+ providerId: string;
11
+ kind: ModelKind;
12
+ contextWindow?: number;
13
+ maxOutputTokens?: number;
14
+ intrinsic: {
15
+ inputModalities?: readonly InputModality[];
16
+ outputModalities?: readonly OutputModality[];
17
+ tools?: boolean;
18
+ reasoning?: boolean;
19
+ };
20
+ }
21
+ export interface ModelRegistration {
22
+ descriptor: ModelDescriptor;
23
+ defaultEndpointId: EndpointProfileId;
24
+ recommendedRuntimePolicy?: RuntimePolicy;
25
+ }
26
+ export interface DynamicModelDescriptorResolver {
27
+ readonly providerId: ProviderId;
28
+ resolve(modelId: string): ModelRegistration;
29
+ }
30
+ export interface EndpointRuntimeCapabilities {
31
+ nativeTokenCounting?: boolean;
32
+ protocolOverrides?: ProtocolRuntimeCapabilityOverrides;
33
+ }
34
+ export type CapabilityEvidenceLayer = "model" | "protocol" | "endpoint";
35
+ export interface EffectiveCapability<T = boolean> {
36
+ state: CapabilityState;
37
+ value?: T;
38
+ evidence: readonly CapabilityEvidenceLayer[];
39
+ }
40
+ export interface EffectiveModelCapabilities {
41
+ inputModalities: Record<InputModality, EffectiveCapability>;
42
+ outputModalities: Record<OutputModality, EffectiveCapability>;
43
+ tools: EffectiveCapability;
44
+ reasoning: EffectiveCapability;
45
+ parallelToolCalls: EffectiveCapability;
46
+ structuredOutput: EffectiveCapability;
47
+ promptCaching: EffectiveCapability;
48
+ nativeTokenCounting: EffectiveCapability;
49
+ mediaForms: {
50
+ imageUrl: EffectiveCapability;
51
+ imageBase64: EffectiveCapability;
52
+ fileId: EffectiveCapability;
53
+ audioUrl: EffectiveCapability;
54
+ audioBase64: EffectiveCapability;
55
+ };
56
+ }
57
+ export interface ResolvedProviderRuntime<TAdapter = LLMProvider> {
58
+ identity: {
59
+ providerId: ProviderId;
60
+ modelId: string;
61
+ endpointId: EndpointProfileId;
62
+ protocol: GenerationProtocol;
63
+ };
64
+ model: ModelDescriptor;
65
+ endpoint: EndpointProfile;
66
+ adapter: TAdapter;
67
+ effectiveCapabilities: EffectiveModelCapabilities;
68
+ runtimePolicy?: RuntimePolicy;
69
+ }
70
+ export interface RegistryRuleEvidence {
71
+ ruleId: string;
72
+ classification: "routing" | "policy" | "protocol" | "endpoint";
73
+ source: string;
74
+ verifiedAt: "2026-08-12";
75
+ }
76
+ export declare const registryEvidence: readonly RegistryRuleEvidence[];
77
+ export declare function defaultModelForProvider(providerId: ProviderId): string;
78
+ export declare class ModelRegistry {
79
+ resolve(modelId: string, providerId?: ProviderId): ModelRegistration | undefined;
80
+ }
81
+ export declare const modelRegistry: ModelRegistry;
82
+ export declare function normalizeModelId(providerId: string, modelId: string): string;
83
+ export declare function getRuntimePolicy(providerId: string, modelId: string): RuntimePolicy;
84
+ export declare const protocolRuntimeCapabilities: Record<GenerationProtocol, ProtocolRuntimeCapabilities>;
85
+ export declare const endpointRuntimeCapabilities: Partial<Record<EndpointProfileId, EndpointRuntimeCapabilities>>;
86
+ export declare function resolveEffectiveCapability<T = boolean>(layers: readonly {
87
+ layer: CapabilityEvidenceLayer;
88
+ state: CapabilityState;
89
+ value?: T;
90
+ }[]): EffectiveCapability<T>;
91
+ export declare function resolveEffectiveModelCapabilities(input: {
92
+ model: ModelDescriptor;
93
+ protocol: GenerationProtocol;
94
+ endpointCapabilities?: EndpointRuntimeCapabilities;
95
+ }): EffectiveModelCapabilities;
96
+ export declare function generationProtocol(protocol: EndpointProtocol): GenerationProtocol | undefined;
97
+ export declare function endpointCapabilitiesFor(endpointId: EndpointProfileId, preserveEndpointIdentity: boolean): EndpointRuntimeCapabilities | undefined;
98
+ export declare function isKnownProviderId(value: string): value is ProviderId;
@@ -0,0 +1,315 @@
1
+ import { endpointProfiles, } from "./endpoints.js";
2
+ import { ANTHROPIC_PROTOCOL_CAPABILITIES, GEMINI_PROTOCOL_CAPABILITIES, OLLAMA_PROTOCOL_CAPABILITIES, OPENAI_CHAT_PROTOCOL_CAPABILITIES, OPENAI_RESPONSES_PROTOCOL_CAPABILITIES, } from "./protocol-capabilities.js";
3
+ export const MODEL_CAPABILITY_STATES = [
4
+ "supported",
5
+ "unsupported",
6
+ "unknown",
7
+ ];
8
+ export const registryEvidence = [
9
+ {
10
+ ruleId: "provider-prefix-routing",
11
+ classification: "routing",
12
+ source: "node/tests/model-registry.test.ts",
13
+ verifiedAt: "2026-08-12",
14
+ },
15
+ {
16
+ ruleId: "runtime-policy-resolution",
17
+ classification: "policy",
18
+ source: "node/tests/model-registry.test.ts",
19
+ verifiedAt: "2026-08-12",
20
+ },
21
+ {
22
+ ruleId: "protocol-wire-capabilities",
23
+ classification: "protocol",
24
+ source: "node/tests/characterization/wire-request.test.ts",
25
+ verifiedAt: "2026-08-12",
26
+ },
27
+ {
28
+ ruleId: "native-token-counting",
29
+ classification: "endpoint",
30
+ source: "node/tests/anthropic-count-tokens.test.ts; node/tests/gemini-count-tokens.test.ts",
31
+ verifiedAt: "2026-08-12",
32
+ },
33
+ ];
34
+ const POLICY = {
35
+ "anthropic/claude-opus-4-1": { maxTurns: 50 },
36
+ "anthropic/claude-opus-4-7": { maxTurns: 50 },
37
+ "anthropic/claude-opus-4-6": { maxTurns: 50 },
38
+ "anthropic/claude-opus-4-0": { maxTurns: 50 },
39
+ "anthropic/claude-sonnet-4-6": { maxTurns: 25 },
40
+ "anthropic/claude-sonnet-4-0": { maxTurns: 25 },
41
+ "anthropic/claude-haiku-4-5": { maxTurns: 15 },
42
+ "anthropic/claude-3-5-haiku-latest": { maxTurns: 15 },
43
+ "deepseek/deepseek-chat": { maxTurns: 25 },
44
+ "deepseek/deepseek-reasoner": { maxTurns: 50 },
45
+ "deepseek/deepseek-v4-flash": { maxTurns: 20 },
46
+ "deepseek/deepseek-v4-pro": { maxTurns: 35 },
47
+ "kimi/moonshot-v1-8k": { maxTurns: 15 },
48
+ "kimi/moonshot-v1-32k": { maxTurns: 20 },
49
+ "kimi/moonshot-v1-128k": { maxTurns: 30 },
50
+ "kimi/kimi-k2.5": { maxTurns: 30 },
51
+ "kimi/kimi-k2.6": { maxTurns: 35 },
52
+ "kimi/kimi-k2-thinking": { maxTurns: 50 },
53
+ "kimi/kimi-k2-thinking-turbo": { maxTurns: 40 },
54
+ "qwen/qwen3.7-max-preview": { maxTurns: 45 },
55
+ "qwen/qwen3.7-plus-preview": { maxTurns: 40 },
56
+ "qwen/qwen3.6-max-preview": { maxTurns: 40 },
57
+ "qwen/qwen3.6-plus": { maxTurns: 35 },
58
+ "qwen/qwen3.6-flash": { maxTurns: 20 },
59
+ "qwen/qwen3.6-35b-a3b": { maxTurns: 25 },
60
+ "qwen/qwen3.6-27b": { maxTurns: 25 },
61
+ "qwen/qwen3.5-plus": { maxTurns: 35 },
62
+ "qwen/qwen3.5-flash": { maxTurns: 20 },
63
+ "qwen/qwen3.5-397b-a17b": { maxTurns: 35 },
64
+ "qwen/qwen3.5-122b-a10b": { maxTurns: 25 },
65
+ "qwen/qwen3.5-35b-a3b": { maxTurns: 20 },
66
+ "qwen/qwen3.5-27b": { maxTurns: 20 },
67
+ "glm/glm-5.2": { maxTurns: 50 },
68
+ "glm/glm-5.1": { maxTurns: 50 },
69
+ "glm/glm-4-plus": { maxTurns: 35 },
70
+ "glm/glm-4-flash": { maxTurns: 15 },
71
+ "glm/glm-4-air": { maxTurns: 20 },
72
+ "minimax/MiniMax-M3": { maxTurns: 35 },
73
+ "minimax/MiniMax-M3-highspeed": { maxTurns: 35 },
74
+ "minimax/MiniMax-M2.7": { maxTurns: 35 },
75
+ "minimax/MiniMax-M2.7-highspeed": { maxTurns: 35 },
76
+ "minimax/MiniMax-M2.5": { maxTurns: 25 },
77
+ "minimax/MiniMax-M2.5-highspeed": { maxTurns: 25 },
78
+ "minimax/MiniMax-M2.1": { maxTurns: 25 },
79
+ "minimax/MiniMax-M2.1-highspeed": { maxTurns: 25 },
80
+ "minimax/MiniMax-M2": { maxTurns: 20 },
81
+ "minimax/MiniMax-Text-01": { maxTurns: 20 },
82
+ "gemini/gemini-3-pro-preview": { maxTurns: 50 },
83
+ "gemini/gemini-3-flash-preview": { maxTurns: 25 },
84
+ "gemini/gemini-3.5-flash": { maxTurns: 30 },
85
+ "gemini/gemini-2.5-pro": { maxTurns: 35 },
86
+ "gemini/gemini-2.5-flash": { maxTurns: 20 },
87
+ "gemini/gemini-2.0-flash": { maxTurns: 15 },
88
+ "gemini/gemini-2.0-flash-lite": { maxTurns: 10 },
89
+ "gemini/gemini-1.5-pro": { maxTurns: 30 },
90
+ "gemini/gemini-1.5-flash": { maxTurns: 15 },
91
+ "openai/gpt-5.5": { maxTurns: 60 },
92
+ "openai/gpt-5.4": { maxTurns: 50 },
93
+ "openai/gpt-5.4-mini": { maxTurns: 25 },
94
+ "openai/gpt-5.4-nano": { maxTurns: 15 },
95
+ "openai/gpt-5.2": { maxTurns: 50 },
96
+ "openai/gpt-5.2-pro": { maxTurns: 60 },
97
+ "openai/gpt-5.1": { maxTurns: 50 },
98
+ "openai/gpt-4o": { maxTurns: 25 },
99
+ "openai/gpt-4o-mini": { maxTurns: 15 },
100
+ "openai/gpt-4.1": { maxTurns: 35 },
101
+ "openai/gpt-4.1-mini": { maxTurns: 20 },
102
+ "openai/gpt-4.1-nano": { maxTurns: 15 },
103
+ "openai/gpt-5": { maxTurns: 50 },
104
+ "openai/gpt-5-pro": { maxTurns: 60 },
105
+ "openai/gpt-5-mini": { maxTurns: 25 },
106
+ "openai/gpt-5-nano": { maxTurns: 15 },
107
+ "openai/o1": { maxTurns: 50 },
108
+ "openai/o1-mini": { maxTurns: 25 },
109
+ "openai/o3": { maxTurns: 50 },
110
+ "openai/o3-mini": { maxTurns: 25 },
111
+ "openai/o4-mini": { maxTurns: 25 },
112
+ };
113
+ const DEFAULT_ENDPOINT = {
114
+ anthropic: "anthropic.messages",
115
+ openai: "openai.chat",
116
+ minimax: "minimax.anthropic",
117
+ deepseek: "deepseek.anthropic",
118
+ kimi: "kimi.anthropic",
119
+ qwen: "qwen.anthropic",
120
+ gemini: "gemini.google",
121
+ glm: "glm.anthropic",
122
+ baai: "baai.self-hosted.embeddings",
123
+ ollama: "ollama.local",
124
+ };
125
+ const DEFAULT_MODEL = {
126
+ anthropic: "claude-sonnet-4-6",
127
+ openai: "gpt-4o",
128
+ minimax: "MiniMax-M3",
129
+ deepseek: "deepseek-v4-flash",
130
+ kimi: "kimi-k2.6",
131
+ qwen: "qwen3.6-plus",
132
+ gemini: "gemini-2.0-flash",
133
+ glm: "glm-5.2",
134
+ baai: "bge-m3",
135
+ ollama: "llama3",
136
+ };
137
+ export function defaultModelForProvider(providerId) {
138
+ return DEFAULT_MODEL[providerId];
139
+ }
140
+ function endpointFor(providerId, modelId) {
141
+ if (providerId === "openai") {
142
+ if (modelId.startsWith("text-embedding-"))
143
+ return "openai.embeddings";
144
+ if (/^(gpt-5|gpt-4\.1|o3|o4-mini)/.test(modelId))
145
+ return "openai.responses";
146
+ }
147
+ if (providerId === "qwen") {
148
+ if (modelId.startsWith("text-embedding-"))
149
+ return "qwen.dashscope.embeddings";
150
+ if (/^(qwen2\.5-vl-embedding|qwen3-vl-embedding)$/.test(modelId)) {
151
+ return "qwen.dashscope.multimodal-embeddings";
152
+ }
153
+ }
154
+ if (providerId === "gemini" && modelId.startsWith("gemini-embedding-")) {
155
+ return "gemini.google.embeddings";
156
+ }
157
+ if (providerId === "glm" && modelId.startsWith("embedding-")) {
158
+ return "glm.openai.embeddings";
159
+ }
160
+ return DEFAULT_ENDPOINT[providerId];
161
+ }
162
+ function modelKind(endpointId) {
163
+ return generationProtocol(endpointProfiles[endpointId].protocol) ? "generation" : "embedding";
164
+ }
165
+ function registration(providerId, rawModelId) {
166
+ const modelId = normalizeModelId(providerId, rawModelId);
167
+ const endpointId = endpointFor(providerId, modelId);
168
+ const policy = providerId === "ollama" ? ollamaPolicy(modelId) : POLICY[`${providerId}/${modelId}`];
169
+ return {
170
+ descriptor: {
171
+ id: `${providerId}/${modelId}`,
172
+ providerId,
173
+ kind: modelKind(endpointId),
174
+ intrinsic: {},
175
+ },
176
+ defaultEndpointId: endpointId,
177
+ ...(policy ? { recommendedRuntimePolicy: policy } : {}),
178
+ };
179
+ }
180
+ const dynamicResolvers = Object.fromEntries(Object.keys(DEFAULT_ENDPOINT).map(providerId => [providerId, {
181
+ providerId,
182
+ resolve(modelId) {
183
+ return registration(providerId, modelId);
184
+ },
185
+ }]));
186
+ export class ModelRegistry {
187
+ resolve(modelId, providerId) {
188
+ const resolvedProvider = providerId ?? providerPrefix(modelId);
189
+ if (!resolvedProvider)
190
+ return undefined;
191
+ return dynamicResolvers[resolvedProvider].resolve(modelId);
192
+ }
193
+ }
194
+ export const modelRegistry = new ModelRegistry();
195
+ export function normalizeModelId(providerId, modelId) {
196
+ const prefix = `${providerId}/`;
197
+ return modelId.startsWith(prefix) ? modelId.slice(prefix.length) : modelId;
198
+ }
199
+ export function getRuntimePolicy(providerId, modelId) {
200
+ if (!isKnownProviderId(providerId))
201
+ return {};
202
+ return modelRegistry.resolve(modelId, providerId)?.recommendedRuntimePolicy ?? {};
203
+ }
204
+ function providerPrefix(modelId) {
205
+ const slash = modelId.indexOf("/");
206
+ if (slash <= 0)
207
+ return undefined;
208
+ const value = modelId.slice(0, slash);
209
+ return isKnownProviderId(value) ? value : undefined;
210
+ }
211
+ function ollamaPolicy(modelId) {
212
+ const lower = modelId.toLowerCase();
213
+ const rows = [
214
+ ["deepseek-r1", 40], ["qwq", 35], ["llama3.3", 25], ["llama3.2", 20],
215
+ ["llama3.1", 20], ["llama3", 20], ["mistral", 20], ["gemma2", 20],
216
+ ["phi4", 20], ["phi3", 15], ["codellama", 20],
217
+ ];
218
+ return { maxTurns: rows.find(([prefix]) => lower.startsWith(prefix))?.[1] ?? 20 };
219
+ }
220
+ export const protocolRuntimeCapabilities = {
221
+ "anthropic-messages": ANTHROPIC_PROTOCOL_CAPABILITIES,
222
+ "openai-chat": OPENAI_CHAT_PROTOCOL_CAPABILITIES,
223
+ "openai-responses": OPENAI_RESPONSES_PROTOCOL_CAPABILITIES,
224
+ gemini: GEMINI_PROTOCOL_CAPABILITIES,
225
+ "ollama-chat": OLLAMA_PROTOCOL_CAPABILITIES,
226
+ };
227
+ export const endpointRuntimeCapabilities = {
228
+ "anthropic.messages": { nativeTokenCounting: true },
229
+ "gemini.google": { nativeTokenCounting: true },
230
+ };
231
+ export function resolveEffectiveCapability(layers) {
232
+ const evidence = layers.filter(layer => layer.state !== "unknown").map(layer => layer.layer);
233
+ if (layers.some(layer => layer.state === "unsupported"))
234
+ return { state: "unsupported", evidence };
235
+ if (layers.length > 0 && layers.every(layer => layer.state === "supported")) {
236
+ const valued = [...layers].reverse().find(layer => layer.value !== undefined);
237
+ return { state: "supported", ...(valued ? { value: valued.value } : {}), evidence };
238
+ }
239
+ return { state: "unknown", evidence };
240
+ }
241
+ const inputModalities = ["text", "image", "audio", "video", "file"];
242
+ const outputModalities = ["text", "image", "audio", "embedding"];
243
+ function booleanState(value) {
244
+ return value === undefined ? "unknown" : value ? "supported" : "unsupported";
245
+ }
246
+ function membershipState(values, value) {
247
+ return values === undefined ? "unknown" : values.includes(value) ? "supported" : "unsupported";
248
+ }
249
+ export function resolveEffectiveModelCapabilities(input) {
250
+ const protocol = protocolRuntimeCapabilities[input.protocol];
251
+ const overrides = input.endpointCapabilities?.protocolOverrides;
252
+ const modality = (layer, value) => {
253
+ const modelValues = layer === "input"
254
+ ? input.model.intrinsic.inputModalities
255
+ : input.model.intrinsic.outputModalities;
256
+ const protocolValues = layer === "input"
257
+ ? protocol.acceptedInputModalities
258
+ : protocol.emittedOutputModalities;
259
+ const overrideValues = layer === "input"
260
+ ? overrides?.acceptedInputModalities
261
+ : overrides?.emittedOutputModalities;
262
+ return resolveEffectiveCapability([
263
+ { layer: "model", state: membershipState(modelValues, value) },
264
+ { layer: "protocol", state: membershipState(protocolValues, value) },
265
+ ...(overrideValues ? [{ layer: "endpoint", state: membershipState(overrideValues, value) }] : []),
266
+ ]);
267
+ };
268
+ const booleanCapability = (modelValue, protocolValue, endpointValue) => resolveEffectiveCapability([
269
+ { layer: "model", state: booleanState(modelValue) },
270
+ { layer: "protocol", state: booleanState(protocolValue) },
271
+ ...(endpointValue === undefined ? [] : [{ layer: "endpoint", state: booleanState(endpointValue) }]),
272
+ ]);
273
+ const protocolBoolean = (protocolValue, endpointValue) => resolveEffectiveCapability([
274
+ { layer: "protocol", state: booleanState(protocolValue) },
275
+ ...(endpointValue === undefined ? [] : [{ layer: "endpoint", state: booleanState(endpointValue) }]),
276
+ ]);
277
+ const media = (key) => protocolBoolean(protocol.mediaForms[key], overrides?.mediaForms?.[key]);
278
+ return {
279
+ inputModalities: Object.fromEntries(inputModalities.map(value => [value, modality("input", value)])),
280
+ outputModalities: Object.fromEntries(outputModalities.map(value => [value, modality("output", value)])),
281
+ tools: booleanCapability(input.model.intrinsic.tools, protocol.tools, overrides?.tools),
282
+ reasoning: resolveEffectiveCapability([
283
+ { layer: "model", state: booleanState(input.model.intrinsic.reasoning) },
284
+ { layer: "protocol", state: protocol.reasoningReplay === "none" ? "unknown" : "supported" },
285
+ ]),
286
+ parallelToolCalls: protocolBoolean(protocol.parallelToolCalls, overrides?.parallelToolCalls),
287
+ structuredOutput: protocolBoolean(protocol.structuredOutput, overrides?.structuredOutput),
288
+ promptCaching: protocolBoolean(protocol.promptCaching, overrides?.promptCaching),
289
+ nativeTokenCounting: resolveEffectiveCapability([
290
+ { layer: "endpoint", state: booleanState(input.endpointCapabilities?.nativeTokenCounting) },
291
+ ]),
292
+ mediaForms: {
293
+ imageUrl: media("imageUrl"), imageBase64: media("imageBase64"), fileId: media("fileId"),
294
+ audioUrl: media("audioUrl"), audioBase64: media("audioBase64"),
295
+ },
296
+ };
297
+ }
298
+ export function generationProtocol(protocol) {
299
+ switch (protocol) {
300
+ case "anthropic-messages":
301
+ case "openai-chat":
302
+ case "openai-responses":
303
+ case "gemini":
304
+ case "ollama-chat":
305
+ return protocol;
306
+ default:
307
+ return undefined;
308
+ }
309
+ }
310
+ export function endpointCapabilitiesFor(endpointId, preserveEndpointIdentity) {
311
+ return preserveEndpointIdentity ? endpointRuntimeCapabilities[endpointId] : undefined;
312
+ }
313
+ export function isKnownProviderId(value) {
314
+ return value in DEFAULT_ENDPOINT;
315
+ }
@@ -0,0 +1,65 @@
1
+ import type { Message, ProviderUsage } from "../types.js";
2
+ import type { CanonicalAdapterInput } from "./content-normalization.js";
3
+ import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
4
+ export interface OllamaMessage {
5
+ role: string;
6
+ content: string;
7
+ images?: string[];
8
+ }
9
+ export interface OllamaRequest {
10
+ model: string;
11
+ messages: OllamaMessage[];
12
+ tools?: Array<{
13
+ type: "function";
14
+ function: {
15
+ name: string;
16
+ description: string;
17
+ parameters: unknown;
18
+ };
19
+ }>;
20
+ [key: string]: unknown;
21
+ }
22
+ export interface OllamaChunk {
23
+ message?: {
24
+ content?: string;
25
+ tool_calls?: Array<{
26
+ function: {
27
+ name: string;
28
+ arguments: unknown;
29
+ };
30
+ }>;
31
+ };
32
+ done?: boolean;
33
+ done_reason?: string;
34
+ prompt_eval_count?: number;
35
+ eval_count?: number;
36
+ }
37
+ export interface OllamaStreamState {
38
+ readonly input: CanonicalAdapterInput;
39
+ readonly pendingToolCalls: Map<string, {
40
+ id: string;
41
+ name: string;
42
+ arguments: Record<string, unknown>;
43
+ }>;
44
+ finalChunk?: OllamaChunk;
45
+ }
46
+ export declare class OllamaNdjsonDecoder {
47
+ private buffer;
48
+ push(text: string): OllamaChunk[];
49
+ finish(text?: string): OllamaChunk[];
50
+ private parse;
51
+ }
52
+ export declare class OllamaAdapter implements ProtocolAdapter<OllamaRequest, OllamaChunk, OllamaChunk, OllamaStreamState, OllamaChunk | undefined> {
53
+ readonly protocol: "ollama-chat";
54
+ readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
55
+ buildRequest(input: CanonicalAdapterInput): OllamaRequest;
56
+ decodeComplete(raw: OllamaChunk, _input: AdapterDecodeInput): {
57
+ message: Message;
58
+ };
59
+ createStreamState(input: AdapterStreamInput): OllamaStreamState;
60
+ pushStreamChunk(chunk: OllamaChunk, state: OllamaStreamState): AdapterOutput;
61
+ finishStream(state: OllamaStreamState, final: OllamaChunk | undefined): AdapterOutput;
62
+ normalizeUsage(raw: unknown): ProviderUsage | undefined;
63
+ normalizeStopReason(raw: string | undefined): CanonicalStopReason | undefined;
64
+ createNdjsonDecoder(): OllamaNdjsonDecoder;
65
+ }