@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.
- package/README.md +28 -28
- package/dist/agent-ir.d.ts +103 -0
- package/dist/agent-ir.js +134 -0
- package/dist/agent.d.ts +67 -0
- package/dist/agent.js +36 -0
- package/dist/collaboration/harness.js +1 -1
- package/dist/collaboration/modes/creator-verifier.d.ts +2 -7
- package/dist/collaboration/modes/creator-verifier.js +4 -6
- package/dist/collaboration/pool.d.ts +8 -20
- package/dist/collaboration/pool.js +27 -97
- package/dist/compat/anthropic/mcp.d.ts +15 -0
- package/dist/compat/anthropic/mcp.js +10 -0
- package/dist/compat/openai/agent.d.ts +34 -0
- package/dist/compat/openai/agent.js +24 -0
- package/dist/governance.d.ts +1 -17
- package/dist/governance.js +1 -34
- package/dist/guardrail.d.ts +6 -0
- package/dist/guardrail.js +1 -0
- package/dist/handoff-target.d.ts +12 -0
- package/dist/handoff-target.js +1 -0
- package/dist/harness/manifest.js +0 -4
- package/dist/index.d.ts +19 -7
- package/dist/index.js +8 -5
- package/dist/kernel.d.ts +2 -20
- package/dist/knowledge/public.d.ts +29 -0
- package/dist/knowledge/public.js +1 -0
- package/dist/mcp-server.d.ts +28 -0
- package/dist/mcp-server.js +1 -0
- package/dist/memory/agent.d.ts +2 -2
- package/dist/memory/agent.js +2 -2
- package/dist/memory/durable.d.ts +16 -0
- package/dist/memory/durable.js +46 -0
- package/dist/memory/in-memory-store.d.ts +9 -7
- package/dist/memory/in-memory-store.js +8 -2
- package/dist/memory/protocols.d.ts +22 -4
- package/dist/memory/public.d.ts +4 -3
- package/dist/memory/public.js +3 -2
- package/dist/os/public.d.ts +1 -1
- package/dist/os/public.js +1 -1
- package/dist/providers/anthropic-adapter.d.ts +59 -0
- package/dist/providers/anthropic-adapter.js +530 -0
- package/dist/providers/anthropic-compatible.d.ts +2 -3
- package/dist/providers/anthropic-compatible.js +8 -5
- package/dist/providers/anthropic.d.ts +20 -23
- package/dist/providers/anthropic.js +176 -395
- package/dist/providers/base.d.ts +2 -2
- package/dist/providers/base.js +50 -8
- package/dist/providers/capability-router.d.ts +29 -0
- package/dist/providers/capability-router.js +43 -0
- package/dist/providers/catalog.d.ts +16 -4
- package/dist/providers/catalog.js +112 -36
- package/dist/providers/content-normalization.d.ts +57 -0
- package/dist/providers/content-normalization.js +238 -0
- package/dist/providers/content-policy.d.ts +16 -0
- package/dist/providers/content-policy.js +39 -0
- package/dist/providers/credentials.d.ts +83 -0
- package/dist/providers/credentials.js +190 -0
- package/dist/providers/endpoints.d.ts +137 -0
- package/dist/providers/endpoints.js +128 -0
- package/dist/providers/factories.js +25 -9
- package/dist/providers/gemini-adapter.d.ts +33 -0
- package/dist/providers/gemini-adapter.js +264 -0
- package/dist/providers/gemini.d.ts +16 -3
- package/dist/providers/gemini.js +97 -195
- package/dist/providers/model-catalog.d.ts +37 -0
- package/dist/providers/model-catalog.js +62 -0
- package/dist/providers/model-registry.d.ts +119 -0
- package/dist/providers/model-registry.js +379 -0
- package/dist/providers/ollama-adapter.d.ts +65 -0
- package/dist/providers/ollama-adapter.js +188 -0
- package/dist/providers/ollama.d.ts +9 -4
- package/dist/providers/ollama.js +96 -109
- package/dist/providers/openai-chat-dialects.d.ts +154 -0
- package/dist/providers/openai-chat-dialects.js +179 -0
- package/dist/providers/openai-chat.d.ts +46 -18
- package/dist/providers/openai-chat.js +416 -51
- package/dist/providers/openai-responses-adapter.d.ts +42 -0
- package/dist/providers/openai-responses-adapter.js +343 -0
- package/dist/providers/openai-responses.d.ts +19 -33
- package/dist/providers/openai-responses.js +164 -264
- package/dist/providers/openai.d.ts +29 -76
- package/dist/providers/openai.js +195 -292
- package/dist/providers/protocol-adapter.d.ts +39 -0
- package/dist/providers/protocol-adapter.js +13 -0
- package/dist/providers/protocol-capabilities.d.ts +34 -0
- package/dist/providers/protocol-capabilities.js +44 -0
- package/dist/providers/provider-error.d.ts +31 -0
- package/dist/providers/provider-error.js +153 -0
- package/dist/providers/public.d.ts +26 -3
- package/dist/providers/public.js +13 -1
- package/dist/providers/registry.d.ts +7 -6
- package/dist/providers/registry.js +47 -20
- package/dist/providers/request-plan.d.ts +89 -0
- package/dist/providers/request-plan.js +199 -0
- package/dist/providers/usage-normalizer.d.ts +48 -0
- package/dist/providers/usage-normalizer.js +139 -0
- package/dist/providers/vendor-profiles.d.ts +2 -15
- package/dist/providers/vendor-profiles.js +14 -60
- package/dist/runtime/canonical-kernel-step.d.ts +1 -2
- package/dist/runtime/canonical-kernel-step.js +47 -12
- package/dist/runtime/context-policy.d.ts +10 -12
- package/dist/runtime/context-policy.js +6 -8
- package/dist/runtime/durable-content.d.ts +50 -0
- package/dist/runtime/durable-content.js +159 -0
- package/dist/runtime/execution-plane.d.ts +2 -2
- package/dist/runtime/execution-plane.js +2 -2
- package/dist/runtime/kernel-event-log.js +0 -1
- package/dist/runtime/kernel-step.d.ts +0 -1
- package/dist/runtime/kernel-step.js +4 -2
- package/dist/runtime/mcp-proxy-plane.d.ts +25 -1
- package/dist/runtime/mcp-proxy-plane.js +44 -6
- package/dist/runtime/output-schema.d.ts +1 -2
- package/dist/runtime/provider-replay.d.ts +5 -1
- package/dist/runtime/provider-replay.js +26 -27
- package/dist/runtime/reactive-session.d.ts +1 -1
- package/dist/runtime/reactive-session.js +2 -3
- package/dist/runtime/run-group.d.ts +1 -1
- package/dist/runtime/runner.d.ts +31 -45
- package/dist/runtime/runner.js +178 -63
- package/dist/runtime/session-log.d.ts +8 -1
- package/dist/runtime/session-log.js +42 -2
- package/dist/runtime/session-repair.d.ts +1 -1
- package/dist/runtime/session-repair.js +1 -1
- package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
- package/dist/runtime/sub-agent-orchestrator.js +8 -11
- package/dist/runtime/workflow-control-flow.d.ts +0 -4
- package/dist/runtime/workflow-control-flow.js +0 -16
- package/dist/session.d.ts +11 -0
- package/dist/session.js +1 -0
- package/dist/skill.d.ts +17 -0
- package/dist/skill.js +16 -0
- package/dist/skills/loader.d.ts +3 -0
- package/dist/tools/errors.d.ts +1 -3
- package/dist/tools/errors.js +1 -3
- package/dist/tools/index.d.ts +3 -0
- package/dist/types/agent.d.ts +21 -9
- package/dist/types/agent.js +30 -4
- package/dist/types.d.ts +135 -17
- package/package.json +4 -4
- package/dist/providers/deepseek.d.ts +0 -46
- package/dist/providers/deepseek.js +0 -97
- package/dist/providers/glm.d.ts +0 -25
- package/dist/providers/glm.js +0 -48
- package/dist/providers/kimi.d.ts +0 -23
- package/dist/providers/kimi.js +0 -30
- package/dist/providers/minimax.d.ts +0 -49
- package/dist/providers/minimax.js +0 -98
- package/dist/providers/profiles.d.ts +0 -1992
- package/dist/providers/profiles.js +0 -796
- package/dist/providers/qwen.d.ts +0 -38
- package/dist/providers/qwen.js +0 -97
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
export type ProviderId = "anthropic" | "openai" | "minimax" | "deepseek" | "kimi" | "qwen" | "gemini" | "glm" | "baai" | "ollama";
|
|
2
|
+
export type EndpointProtocol = "anthropic-messages" | "openai-chat" | "openai-responses" | "openai-embeddings" | "dashscope-multimodal-embeddings" | "gemini" | "gemini-embeddings" | "self-hosted-embeddings" | "ollama-chat";
|
|
3
|
+
export interface EndpointProfile {
|
|
4
|
+
id: string;
|
|
5
|
+
providerId: ProviderId;
|
|
6
|
+
protocol: EndpointProtocol;
|
|
7
|
+
baseURL: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const endpointProfiles: {
|
|
10
|
+
readonly "anthropic.messages": {
|
|
11
|
+
readonly id: "anthropic.messages";
|
|
12
|
+
readonly providerId: "anthropic";
|
|
13
|
+
readonly protocol: "anthropic-messages";
|
|
14
|
+
readonly baseURL: "https://api.anthropic.com";
|
|
15
|
+
};
|
|
16
|
+
readonly "openai.chat": {
|
|
17
|
+
readonly id: "openai.chat";
|
|
18
|
+
readonly providerId: "openai";
|
|
19
|
+
readonly protocol: "openai-chat";
|
|
20
|
+
readonly baseURL: "https://api.openai.com/v1";
|
|
21
|
+
};
|
|
22
|
+
readonly "openai.responses": {
|
|
23
|
+
readonly id: "openai.responses";
|
|
24
|
+
readonly providerId: "openai";
|
|
25
|
+
readonly protocol: "openai-responses";
|
|
26
|
+
readonly baseURL: "https://api.openai.com/v1";
|
|
27
|
+
};
|
|
28
|
+
readonly "openai.embeddings": {
|
|
29
|
+
readonly id: "openai.embeddings";
|
|
30
|
+
readonly providerId: "openai";
|
|
31
|
+
readonly protocol: "openai-embeddings";
|
|
32
|
+
readonly baseURL: "https://api.openai.com/v1";
|
|
33
|
+
};
|
|
34
|
+
readonly "minimax.anthropic": {
|
|
35
|
+
readonly id: "minimax.anthropic";
|
|
36
|
+
readonly providerId: "minimax";
|
|
37
|
+
readonly protocol: "anthropic-messages";
|
|
38
|
+
readonly baseURL: "https://api.minimaxi.com/anthropic";
|
|
39
|
+
};
|
|
40
|
+
readonly "minimax.openai": {
|
|
41
|
+
readonly id: "minimax.openai";
|
|
42
|
+
readonly providerId: "minimax";
|
|
43
|
+
readonly protocol: "openai-chat";
|
|
44
|
+
readonly baseURL: "https://api.minimaxi.com/v1";
|
|
45
|
+
};
|
|
46
|
+
readonly "deepseek.anthropic": {
|
|
47
|
+
readonly id: "deepseek.anthropic";
|
|
48
|
+
readonly providerId: "deepseek";
|
|
49
|
+
readonly protocol: "anthropic-messages";
|
|
50
|
+
readonly baseURL: "https://api.deepseek.com/anthropic";
|
|
51
|
+
};
|
|
52
|
+
readonly "deepseek.openai": {
|
|
53
|
+
readonly id: "deepseek.openai";
|
|
54
|
+
readonly providerId: "deepseek";
|
|
55
|
+
readonly protocol: "openai-chat";
|
|
56
|
+
readonly baseURL: "https://api.deepseek.com";
|
|
57
|
+
};
|
|
58
|
+
readonly "kimi.anthropic": {
|
|
59
|
+
readonly id: "kimi.anthropic";
|
|
60
|
+
readonly providerId: "kimi";
|
|
61
|
+
readonly protocol: "anthropic-messages";
|
|
62
|
+
readonly baseURL: "https://api.moonshot.cn/anthropic";
|
|
63
|
+
};
|
|
64
|
+
readonly "kimi.openai": {
|
|
65
|
+
readonly id: "kimi.openai";
|
|
66
|
+
readonly providerId: "kimi";
|
|
67
|
+
readonly protocol: "openai-chat";
|
|
68
|
+
readonly baseURL: "https://api.moonshot.cn/v1";
|
|
69
|
+
};
|
|
70
|
+
readonly "qwen.anthropic": {
|
|
71
|
+
readonly id: "qwen.anthropic";
|
|
72
|
+
readonly providerId: "qwen";
|
|
73
|
+
readonly protocol: "anthropic-messages";
|
|
74
|
+
readonly baseURL: "https://dashscope-intl.aliyuncs.com/apps/anthropic";
|
|
75
|
+
};
|
|
76
|
+
readonly "qwen.dashscope": {
|
|
77
|
+
readonly id: "qwen.dashscope";
|
|
78
|
+
readonly providerId: "qwen";
|
|
79
|
+
readonly protocol: "openai-chat";
|
|
80
|
+
readonly baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
81
|
+
};
|
|
82
|
+
readonly "qwen.dashscope.embeddings": {
|
|
83
|
+
readonly id: "qwen.dashscope.embeddings";
|
|
84
|
+
readonly providerId: "qwen";
|
|
85
|
+
readonly protocol: "openai-embeddings";
|
|
86
|
+
readonly baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
87
|
+
};
|
|
88
|
+
readonly "qwen.dashscope.multimodal-embeddings": {
|
|
89
|
+
readonly id: "qwen.dashscope.multimodal-embeddings";
|
|
90
|
+
readonly providerId: "qwen";
|
|
91
|
+
readonly protocol: "dashscope-multimodal-embeddings";
|
|
92
|
+
readonly baseURL: "https://dashscope.aliyuncs.com/api/v1/services/embeddings/multimodal-embedding/multimodal-embedding";
|
|
93
|
+
};
|
|
94
|
+
readonly "gemini.google": {
|
|
95
|
+
readonly id: "gemini.google";
|
|
96
|
+
readonly providerId: "gemini";
|
|
97
|
+
readonly protocol: "gemini";
|
|
98
|
+
readonly baseURL: "https://generativelanguage.googleapis.com";
|
|
99
|
+
};
|
|
100
|
+
readonly "gemini.google.embeddings": {
|
|
101
|
+
readonly id: "gemini.google.embeddings";
|
|
102
|
+
readonly providerId: "gemini";
|
|
103
|
+
readonly protocol: "gemini-embeddings";
|
|
104
|
+
readonly baseURL: "https://generativelanguage.googleapis.com";
|
|
105
|
+
};
|
|
106
|
+
readonly "glm.anthropic": {
|
|
107
|
+
readonly id: "glm.anthropic";
|
|
108
|
+
readonly providerId: "glm";
|
|
109
|
+
readonly protocol: "anthropic-messages";
|
|
110
|
+
readonly baseURL: "https://open.bigmodel.cn/api/anthropic";
|
|
111
|
+
};
|
|
112
|
+
readonly "glm.openai": {
|
|
113
|
+
readonly id: "glm.openai";
|
|
114
|
+
readonly providerId: "glm";
|
|
115
|
+
readonly protocol: "openai-chat";
|
|
116
|
+
readonly baseURL: "https://open.bigmodel.cn/api/paas/v4";
|
|
117
|
+
};
|
|
118
|
+
readonly "glm.openai.embeddings": {
|
|
119
|
+
readonly id: "glm.openai.embeddings";
|
|
120
|
+
readonly providerId: "glm";
|
|
121
|
+
readonly protocol: "openai-embeddings";
|
|
122
|
+
readonly baseURL: "https://open.bigmodel.cn/api/paas/v4";
|
|
123
|
+
};
|
|
124
|
+
readonly "baai.self-hosted.embeddings": {
|
|
125
|
+
readonly id: "baai.self-hosted.embeddings";
|
|
126
|
+
readonly providerId: "baai";
|
|
127
|
+
readonly protocol: "self-hosted-embeddings";
|
|
128
|
+
readonly baseURL: "https://huggingface.co/BAAI";
|
|
129
|
+
};
|
|
130
|
+
readonly "ollama.local": {
|
|
131
|
+
readonly id: "ollama.local";
|
|
132
|
+
readonly providerId: "ollama";
|
|
133
|
+
readonly protocol: "ollama-chat";
|
|
134
|
+
readonly baseURL: "http://localhost:11434";
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export type EndpointProfileId = keyof typeof endpointProfiles;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export const endpointProfiles = {
|
|
2
|
+
"anthropic.messages": {
|
|
3
|
+
id: "anthropic.messages",
|
|
4
|
+
providerId: "anthropic",
|
|
5
|
+
protocol: "anthropic-messages",
|
|
6
|
+
baseURL: "https://api.anthropic.com",
|
|
7
|
+
},
|
|
8
|
+
"openai.chat": {
|
|
9
|
+
id: "openai.chat",
|
|
10
|
+
providerId: "openai",
|
|
11
|
+
protocol: "openai-chat",
|
|
12
|
+
baseURL: "https://api.openai.com/v1",
|
|
13
|
+
},
|
|
14
|
+
"openai.responses": {
|
|
15
|
+
id: "openai.responses",
|
|
16
|
+
providerId: "openai",
|
|
17
|
+
protocol: "openai-responses",
|
|
18
|
+
baseURL: "https://api.openai.com/v1",
|
|
19
|
+
},
|
|
20
|
+
"openai.embeddings": {
|
|
21
|
+
id: "openai.embeddings",
|
|
22
|
+
providerId: "openai",
|
|
23
|
+
protocol: "openai-embeddings",
|
|
24
|
+
baseURL: "https://api.openai.com/v1",
|
|
25
|
+
},
|
|
26
|
+
"minimax.anthropic": {
|
|
27
|
+
id: "minimax.anthropic",
|
|
28
|
+
providerId: "minimax",
|
|
29
|
+
protocol: "anthropic-messages",
|
|
30
|
+
baseURL: "https://api.minimaxi.com/anthropic",
|
|
31
|
+
},
|
|
32
|
+
"minimax.openai": {
|
|
33
|
+
id: "minimax.openai",
|
|
34
|
+
providerId: "minimax",
|
|
35
|
+
protocol: "openai-chat",
|
|
36
|
+
baseURL: "https://api.minimaxi.com/v1",
|
|
37
|
+
},
|
|
38
|
+
"deepseek.anthropic": {
|
|
39
|
+
id: "deepseek.anthropic",
|
|
40
|
+
providerId: "deepseek",
|
|
41
|
+
protocol: "anthropic-messages",
|
|
42
|
+
baseURL: "https://api.deepseek.com/anthropic",
|
|
43
|
+
},
|
|
44
|
+
"deepseek.openai": {
|
|
45
|
+
id: "deepseek.openai",
|
|
46
|
+
providerId: "deepseek",
|
|
47
|
+
protocol: "openai-chat",
|
|
48
|
+
baseURL: "https://api.deepseek.com",
|
|
49
|
+
},
|
|
50
|
+
"kimi.anthropic": {
|
|
51
|
+
id: "kimi.anthropic",
|
|
52
|
+
providerId: "kimi",
|
|
53
|
+
protocol: "anthropic-messages",
|
|
54
|
+
baseURL: "https://api.moonshot.cn/anthropic",
|
|
55
|
+
},
|
|
56
|
+
"kimi.openai": {
|
|
57
|
+
id: "kimi.openai",
|
|
58
|
+
providerId: "kimi",
|
|
59
|
+
protocol: "openai-chat",
|
|
60
|
+
baseURL: "https://api.moonshot.cn/v1",
|
|
61
|
+
},
|
|
62
|
+
"qwen.anthropic": {
|
|
63
|
+
id: "qwen.anthropic",
|
|
64
|
+
providerId: "qwen",
|
|
65
|
+
protocol: "anthropic-messages",
|
|
66
|
+
baseURL: "https://dashscope-intl.aliyuncs.com/apps/anthropic",
|
|
67
|
+
},
|
|
68
|
+
"qwen.dashscope": {
|
|
69
|
+
id: "qwen.dashscope",
|
|
70
|
+
providerId: "qwen",
|
|
71
|
+
protocol: "openai-chat",
|
|
72
|
+
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
73
|
+
},
|
|
74
|
+
"qwen.dashscope.embeddings": {
|
|
75
|
+
id: "qwen.dashscope.embeddings",
|
|
76
|
+
providerId: "qwen",
|
|
77
|
+
protocol: "openai-embeddings",
|
|
78
|
+
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
79
|
+
},
|
|
80
|
+
"qwen.dashscope.multimodal-embeddings": {
|
|
81
|
+
id: "qwen.dashscope.multimodal-embeddings",
|
|
82
|
+
providerId: "qwen",
|
|
83
|
+
protocol: "dashscope-multimodal-embeddings",
|
|
84
|
+
baseURL: "https://dashscope.aliyuncs.com/api/v1/services/embeddings/multimodal-embedding/multimodal-embedding",
|
|
85
|
+
},
|
|
86
|
+
"gemini.google": {
|
|
87
|
+
id: "gemini.google",
|
|
88
|
+
providerId: "gemini",
|
|
89
|
+
protocol: "gemini",
|
|
90
|
+
baseURL: "https://generativelanguage.googleapis.com",
|
|
91
|
+
},
|
|
92
|
+
"gemini.google.embeddings": {
|
|
93
|
+
id: "gemini.google.embeddings",
|
|
94
|
+
providerId: "gemini",
|
|
95
|
+
protocol: "gemini-embeddings",
|
|
96
|
+
baseURL: "https://generativelanguage.googleapis.com",
|
|
97
|
+
},
|
|
98
|
+
"glm.anthropic": {
|
|
99
|
+
id: "glm.anthropic",
|
|
100
|
+
providerId: "glm",
|
|
101
|
+
protocol: "anthropic-messages",
|
|
102
|
+
baseURL: "https://open.bigmodel.cn/api/anthropic",
|
|
103
|
+
},
|
|
104
|
+
"glm.openai": {
|
|
105
|
+
id: "glm.openai",
|
|
106
|
+
providerId: "glm",
|
|
107
|
+
protocol: "openai-chat",
|
|
108
|
+
baseURL: "https://open.bigmodel.cn/api/paas/v4",
|
|
109
|
+
},
|
|
110
|
+
"glm.openai.embeddings": {
|
|
111
|
+
id: "glm.openai.embeddings",
|
|
112
|
+
providerId: "glm",
|
|
113
|
+
protocol: "openai-embeddings",
|
|
114
|
+
baseURL: "https://open.bigmodel.cn/api/paas/v4",
|
|
115
|
+
},
|
|
116
|
+
"baai.self-hosted.embeddings": {
|
|
117
|
+
id: "baai.self-hosted.embeddings",
|
|
118
|
+
providerId: "baai",
|
|
119
|
+
protocol: "self-hosted-embeddings",
|
|
120
|
+
baseURL: "https://huggingface.co/BAAI",
|
|
121
|
+
},
|
|
122
|
+
"ollama.local": {
|
|
123
|
+
id: "ollama.local",
|
|
124
|
+
providerId: "ollama",
|
|
125
|
+
protocol: "ollama-chat",
|
|
126
|
+
baseURL: "http://localhost:11434",
|
|
127
|
+
},
|
|
128
|
+
};
|
|
@@ -1,33 +1,49 @@
|
|
|
1
1
|
import { PROVIDER_REGISTRY } from "./registry.js";
|
|
2
2
|
import { OllamaProvider } from "./ollama.js";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { defaultEndpointForProvider, defaultModelForProvider, getRuntimePolicy, isKnownProviderId } from "./model-registry.js";
|
|
4
|
+
import { endpointProfiles } from "./endpoints.js";
|
|
5
|
+
function build(providerId, o) {
|
|
6
|
+
if (!isKnownProviderId(providerId))
|
|
7
|
+
throw new Error(`Unknown provider: ${providerId}`);
|
|
8
|
+
const defaultProtocol = endpointProfiles[defaultEndpointForProvider(providerId)].protocol;
|
|
9
|
+
const protocol = o.protocol === "openai"
|
|
10
|
+
? "openai-chat"
|
|
11
|
+
: o.protocol === "anthropic"
|
|
12
|
+
? "anthropic-messages"
|
|
13
|
+
: defaultProtocol;
|
|
14
|
+
if (protocol !== "openai-chat" && protocol !== "anthropic-messages") {
|
|
15
|
+
throw new Error(`Provider ${providerId} does not use an OpenAI- or Anthropic-compatible default`);
|
|
16
|
+
}
|
|
17
|
+
const model = o.model ?? defaultModelForProvider(providerId);
|
|
18
|
+
return PROVIDER_REGISTRY[`${providerId}:${protocol}`](o.apiKey, model, o.retry, o.baseURL, getRuntimePolicy(providerId, model));
|
|
5
19
|
}
|
|
6
20
|
/** DeepSeek. Defaults to the OpenAI-compatible wire (richer reasoning-replay handling). */
|
|
7
21
|
export function deepseek(o) {
|
|
8
|
-
return build("deepseek", o
|
|
22
|
+
return build("deepseek", o);
|
|
9
23
|
}
|
|
10
24
|
/** Moonshot Kimi. Defaults to the OpenAI-compatible wire. */
|
|
11
25
|
export function kimi(o) {
|
|
12
|
-
return build("kimi", o
|
|
26
|
+
return build("kimi", o);
|
|
13
27
|
}
|
|
14
28
|
/** Alibaba Qwen / DashScope. Defaults to the OpenAI-compatible (DashScope) wire. */
|
|
15
29
|
export function qwen(o) {
|
|
16
|
-
return build("qwen", o
|
|
30
|
+
return build("qwen", o);
|
|
17
31
|
}
|
|
18
32
|
/** Zhipu GLM. Defaults to the OpenAI-compatible wire. */
|
|
19
33
|
export function glm(o) {
|
|
20
|
-
return build("glm", o
|
|
34
|
+
return build("glm", o);
|
|
21
35
|
}
|
|
22
36
|
/** MiniMax. Defaults to the Anthropic-compatible wire (the primary M2.x path). */
|
|
23
37
|
export function minimax(o) {
|
|
24
|
-
return build("minimax", o
|
|
38
|
+
return build("minimax", o);
|
|
25
39
|
}
|
|
26
40
|
/** Google Gemini (single wire). */
|
|
27
41
|
export function gemini(o) {
|
|
28
|
-
|
|
42
|
+
const model = o.model ?? defaultModelForProvider("gemini");
|
|
43
|
+
return PROVIDER_REGISTRY["gemini:gemini"](o.apiKey, model, o.retry, o.baseURL, getRuntimePolicy("gemini", model));
|
|
29
44
|
}
|
|
30
45
|
/** Local Ollama (single wire, no API key). */
|
|
31
46
|
export function ollama(o = {}) {
|
|
32
|
-
|
|
47
|
+
const model = o.model ?? defaultModelForProvider("ollama");
|
|
48
|
+
return new OllamaProvider(model, o.baseURL, getRuntimePolicy("ollama", model));
|
|
33
49
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Content, GenerateContentRequest, GenerateContentResponse, ModelParams, Tool } from "@google/generative-ai";
|
|
2
|
+
import type { Message, ProviderUsage } from "../types.js";
|
|
3
|
+
import type { CanonicalAdapterInput } from "./content-normalization.js";
|
|
4
|
+
import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
|
|
5
|
+
export interface GeminiRequestPlan {
|
|
6
|
+
modelParams: ModelParams & Record<string, unknown>;
|
|
7
|
+
request: GenerateContentRequest;
|
|
8
|
+
}
|
|
9
|
+
export interface GeminiStreamState {
|
|
10
|
+
readonly input: CanonicalAdapterInput;
|
|
11
|
+
readonly toolCalls: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
args: Record<string, unknown>;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export declare function canonicalGeminiContents(context: CanonicalAdapterInput["context"]): Content[];
|
|
17
|
+
export declare function geminiVendorConfig(extensions: Readonly<Record<string, unknown>>): {
|
|
18
|
+
tools?: Tool[];
|
|
19
|
+
generationConfig?: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
export declare class GeminiAdapter implements ProtocolAdapter<GeminiRequestPlan, GenerateContentResponse, GenerateContentResponse, GeminiStreamState, GenerateContentResponse> {
|
|
22
|
+
readonly protocol: "gemini";
|
|
23
|
+
readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
|
|
24
|
+
buildRequest(input: CanonicalAdapterInput): GeminiRequestPlan;
|
|
25
|
+
decodeComplete(raw: GenerateContentResponse, _input: AdapterDecodeInput): {
|
|
26
|
+
message: Message;
|
|
27
|
+
};
|
|
28
|
+
createStreamState(input: AdapterStreamInput): GeminiStreamState;
|
|
29
|
+
pushStreamChunk(chunk: GenerateContentResponse, state: GeminiStreamState): AdapterOutput;
|
|
30
|
+
finishStream(state: GeminiStreamState, final: GenerateContentResponse): AdapterOutput;
|
|
31
|
+
normalizeUsage(raw: unknown): ProviderUsage | undefined;
|
|
32
|
+
normalizeStopReason(raw: string | undefined): CanonicalStopReason | undefined;
|
|
33
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { projectToolOutputToText } from "./content-normalization.js";
|
|
2
|
+
import { normalizeToolCall } from "./base.js";
|
|
3
|
+
import { normalizeGeminiUsage } from "./usage-normalizer.js";
|
|
4
|
+
import { ProtocolResponseError, GEMINI_PROTOCOL_CAPABILITIES, } from "./protocol-adapter.js";
|
|
5
|
+
// Google Generate Content streams response chunks, while @google/generative-ai 0.24.1 exposes
|
|
6
|
+
// a separate promise for the aggregated response. Candidate finishReason and aggregate usage are
|
|
7
|
+
// therefore decoded only by finishStream.
|
|
8
|
+
// Source: https://ai.google.dev/api/generate-content#method:-models.streamgeneratecontent
|
|
9
|
+
// Source: https://github.com/google-gemini/deprecated-generative-ai-js/blob/v0.24.1/types/responses.ts
|
|
10
|
+
function parseArguments(argumentsJson) {
|
|
11
|
+
try {
|
|
12
|
+
const value = JSON.parse(argumentsJson);
|
|
13
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
14
|
+
? value
|
|
15
|
+
: {};
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function toolName(callId, messages) {
|
|
22
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
23
|
+
const match = messages[index].toolCalls?.find(call => call.id === callId);
|
|
24
|
+
if (match)
|
|
25
|
+
return match.name;
|
|
26
|
+
}
|
|
27
|
+
return callId;
|
|
28
|
+
}
|
|
29
|
+
function toolResultPart(result, messages) {
|
|
30
|
+
return {
|
|
31
|
+
functionResponse: {
|
|
32
|
+
name: toolName(result.callId, messages),
|
|
33
|
+
response: { output: projectToolOutputToText(result.blocks) },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function contentPart(block) {
|
|
38
|
+
if (block.type === "text")
|
|
39
|
+
return block.text ? { text: block.text } : undefined;
|
|
40
|
+
if (block.type === "image" || block.type === "audio") {
|
|
41
|
+
if (block.source.kind === "base64") {
|
|
42
|
+
return {
|
|
43
|
+
inlineData: {
|
|
44
|
+
mimeType: block.mediaType ?? (block.type === "image" ? "image/png" : "audio/wav"),
|
|
45
|
+
data: block.source.data,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (block.source.kind === "url") {
|
|
50
|
+
return {
|
|
51
|
+
fileData: {
|
|
52
|
+
mimeType: block.mediaType ?? (block.type === "image" ? "image/png" : "audio/wav"),
|
|
53
|
+
fileUri: block.source.url,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (block.type === "video" || block.type === "file") {
|
|
59
|
+
throw new ProtocolResponseError("gemini", `cannot serialize ${block.type}`);
|
|
60
|
+
}
|
|
61
|
+
throw new ProtocolResponseError("gemini", `cannot serialize ${block.type} source`);
|
|
62
|
+
}
|
|
63
|
+
export function canonicalGeminiContents(context) {
|
|
64
|
+
const messages = context.stateTurn ? [...context.turns, context.stateTurn] : context.turns;
|
|
65
|
+
const contents = [];
|
|
66
|
+
for (const message of messages) {
|
|
67
|
+
const parts = [];
|
|
68
|
+
for (const call of message.toolCalls ?? []) {
|
|
69
|
+
parts.push({
|
|
70
|
+
functionCall: { name: call.name, args: parseArguments(call.arguments) },
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
for (const block of message.blocks) {
|
|
74
|
+
if (block.type === "tool_result") {
|
|
75
|
+
parts.push(toolResultPart(block, messages));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const part = contentPart(block);
|
|
79
|
+
if (part)
|
|
80
|
+
parts.push(part);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!parts.length)
|
|
84
|
+
continue;
|
|
85
|
+
contents.push({
|
|
86
|
+
role: message.role === "assistant" ? "model" : "user",
|
|
87
|
+
parts,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return contents;
|
|
91
|
+
}
|
|
92
|
+
function buildTools(tools) {
|
|
93
|
+
if (!tools.length)
|
|
94
|
+
return [];
|
|
95
|
+
return [{
|
|
96
|
+
functionDeclarations: tools.map(tool => ({
|
|
97
|
+
name: tool.name,
|
|
98
|
+
description: tool.description,
|
|
99
|
+
parameters: JSON.parse(tool.parameters),
|
|
100
|
+
})),
|
|
101
|
+
}];
|
|
102
|
+
}
|
|
103
|
+
function modelExtensions(extensions) {
|
|
104
|
+
const { model: _model, systemInstruction: _systemInstruction, tools: _tools, google_search: _googleSearch, response_mime_type: _responseMimeType, response_schema: _responseSchema, generationConfig: _generationConfig, ...rest } = extensions;
|
|
105
|
+
return rest;
|
|
106
|
+
}
|
|
107
|
+
export function geminiVendorConfig(extensions) {
|
|
108
|
+
const tools = [];
|
|
109
|
+
if (extensions.google_search) {
|
|
110
|
+
tools.push({
|
|
111
|
+
googleSearch: typeof extensions.google_search === "object"
|
|
112
|
+
? extensions.google_search
|
|
113
|
+
: {},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const generationConfig = {
|
|
117
|
+
...extensions.generationConfig,
|
|
118
|
+
};
|
|
119
|
+
if (extensions.response_mime_type != null) {
|
|
120
|
+
generationConfig.responseMimeType = extensions.response_mime_type;
|
|
121
|
+
}
|
|
122
|
+
if (extensions.response_schema != null) {
|
|
123
|
+
generationConfig.responseSchema = extensions.response_schema;
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
...(tools.length ? { tools } : {}),
|
|
127
|
+
...(Object.keys(generationConfig).length ? { generationConfig } : {}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function decodeParts(raw) {
|
|
131
|
+
const candidate = raw.candidates?.[0];
|
|
132
|
+
let content = "";
|
|
133
|
+
const toolCalls = [];
|
|
134
|
+
for (const part of candidate?.content.parts ?? []) {
|
|
135
|
+
if (part.text)
|
|
136
|
+
content += part.text;
|
|
137
|
+
else if (part.functionCall) {
|
|
138
|
+
const call = normalizeToolCall(part.functionCall.name, part.functionCall.name, part.functionCall.args);
|
|
139
|
+
if (call)
|
|
140
|
+
toolCalls.push(call);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { content, toolCalls };
|
|
144
|
+
}
|
|
145
|
+
function numberField(raw, field) {
|
|
146
|
+
const value = raw[field];
|
|
147
|
+
if (value === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
150
|
+
throw new ProtocolResponseError("gemini", `usage.${field} must be a non-negative safe integer`);
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
export class GeminiAdapter {
|
|
155
|
+
protocol = "gemini";
|
|
156
|
+
protocolCapabilities = GEMINI_PROTOCOL_CAPABILITIES;
|
|
157
|
+
buildRequest(input) {
|
|
158
|
+
const extensions = input.extensions;
|
|
159
|
+
const vendor = geminiVendorConfig(extensions);
|
|
160
|
+
const tools = [...buildTools(input.tools), ...(vendor.tools ?? [])];
|
|
161
|
+
return {
|
|
162
|
+
modelParams: {
|
|
163
|
+
...modelExtensions(extensions),
|
|
164
|
+
model: input.resolved.identity.modelId,
|
|
165
|
+
...(input.context.systemText ? { systemInstruction: input.context.systemText } : {}),
|
|
166
|
+
...(tools.length ? { tools } : {}),
|
|
167
|
+
...(vendor.generationConfig ? { generationConfig: vendor.generationConfig } : {}),
|
|
168
|
+
},
|
|
169
|
+
request: { contents: canonicalGeminiContents(input.context) },
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
decodeComplete(raw, _input) {
|
|
173
|
+
const decoded = decodeParts(raw);
|
|
174
|
+
const usage = this.normalizeUsage(raw.usageMetadata);
|
|
175
|
+
const rawUsage = raw.usageMetadata;
|
|
176
|
+
const tokenCount = usage?.outputTokens
|
|
177
|
+
?? (rawUsage ? numberField(rawUsage, "totalTokenCount") : undefined);
|
|
178
|
+
return {
|
|
179
|
+
message: {
|
|
180
|
+
role: "assistant",
|
|
181
|
+
content: decoded.content,
|
|
182
|
+
...(tokenCount !== undefined ? { tokenCount } : {}),
|
|
183
|
+
toolCalls: decoded.toolCalls,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
createStreamState(input) {
|
|
188
|
+
return { input: input.input, toolCalls: [] };
|
|
189
|
+
}
|
|
190
|
+
pushStreamChunk(chunk, state) {
|
|
191
|
+
const events = [];
|
|
192
|
+
for (const part of chunk.candidates?.[0]?.content.parts ?? []) {
|
|
193
|
+
if (part.text)
|
|
194
|
+
events.push({ type: "text_delta", delta: part.text });
|
|
195
|
+
else if (part.functionCall) {
|
|
196
|
+
state.toolCalls.push({
|
|
197
|
+
name: part.functionCall.name,
|
|
198
|
+
args: part.functionCall.args,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return { events };
|
|
203
|
+
}
|
|
204
|
+
finishStream(state, final) {
|
|
205
|
+
const events = state.toolCalls.map((call, index) => ({
|
|
206
|
+
type: "tool_call",
|
|
207
|
+
id: `call_${index + 1}`,
|
|
208
|
+
name: call.name,
|
|
209
|
+
arguments: call.args,
|
|
210
|
+
}));
|
|
211
|
+
const usage = this.normalizeUsage(final.usageMetadata);
|
|
212
|
+
const rawStopReason = final.candidates?.[0]?.finishReason;
|
|
213
|
+
const stopReason = this.normalizeStopReason(rawStopReason);
|
|
214
|
+
if (usage) {
|
|
215
|
+
const raw = final.usageMetadata;
|
|
216
|
+
const totalTokens = numberField(raw, "totalTokenCount")
|
|
217
|
+
?? usage.inputTokens + usage.outputTokens;
|
|
218
|
+
events.push({
|
|
219
|
+
type: "usage",
|
|
220
|
+
totalTokens,
|
|
221
|
+
inputTokens: usage.inputTokens,
|
|
222
|
+
outputTokens: usage.outputTokens,
|
|
223
|
+
...(usage.cacheReadInputTokens
|
|
224
|
+
? { cacheReadInputTokens: usage.cacheReadInputTokens }
|
|
225
|
+
: {}),
|
|
226
|
+
...(usage.cacheTelemetryStatus ? { cacheTelemetryStatus: usage.cacheTelemetryStatus } : {}),
|
|
227
|
+
...(usage.cacheTelemetrySource ? { cacheTelemetrySource: usage.cacheTelemetrySource } : {}),
|
|
228
|
+
providerUsage: usage,
|
|
229
|
+
...(stopReason ? { stopReason } : {}),
|
|
230
|
+
...(rawStopReason ? { rawStopReason } : {}),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return { events };
|
|
234
|
+
}
|
|
235
|
+
normalizeUsage(raw) {
|
|
236
|
+
if (raw === undefined || raw === null)
|
|
237
|
+
return undefined;
|
|
238
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
239
|
+
throw new ProtocolResponseError("gemini", "usage must be an object");
|
|
240
|
+
}
|
|
241
|
+
const usage = raw;
|
|
242
|
+
numberField(usage, "totalTokenCount");
|
|
243
|
+
return normalizeGeminiUsage(usage);
|
|
244
|
+
}
|
|
245
|
+
normalizeStopReason(raw) {
|
|
246
|
+
if (raw === undefined)
|
|
247
|
+
return undefined;
|
|
248
|
+
switch (raw) {
|
|
249
|
+
case "STOP":
|
|
250
|
+
case "FINISH_REASON_STOP":
|
|
251
|
+
return "end_turn";
|
|
252
|
+
case "MAX_TOKENS":
|
|
253
|
+
return "max_tokens";
|
|
254
|
+
case "SAFETY":
|
|
255
|
+
case "RECITATION":
|
|
256
|
+
case "BLOCKLIST":
|
|
257
|
+
case "PROHIBITED_CONTENT":
|
|
258
|
+
case "SPII":
|
|
259
|
+
return "content_filter";
|
|
260
|
+
default:
|
|
261
|
+
return "other";
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { type Content } from "@google/generative-ai";
|
|
2
|
-
import type { Message, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy } from "../types.js";
|
|
2
|
+
import type { Message, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy, PromptMeasurement } from "../types.js";
|
|
3
|
+
import { type CanonicalAdapterInput } from "./content-normalization.js";
|
|
4
|
+
type ResolvedGeminiRuntime = CanonicalAdapterInput["resolved"];
|
|
3
5
|
export declare function buildContents(turns: Message[]): Content[];
|
|
4
6
|
export declare class GeminiProvider implements LLMProvider {
|
|
5
7
|
private readonly model;
|
|
8
|
+
private resolvedRuntime?;
|
|
6
9
|
private genAI;
|
|
7
10
|
private circuit;
|
|
8
11
|
private maxRetries;
|
|
9
12
|
private baseDelay;
|
|
10
13
|
private requestOptions;
|
|
14
|
+
private readonly resolvedRuntimePolicy;
|
|
15
|
+
private readonly adapter;
|
|
11
16
|
constructor(apiKey: string, model?: string, retry?: {
|
|
12
17
|
maxRetries: number;
|
|
13
18
|
baseDelay: number;
|
|
14
|
-
}, baseURL?: string);
|
|
19
|
+
}, baseURL?: string, runtimePolicy?: RuntimePolicy, resolvedRuntime?: ResolvedGeminiRuntime | undefined);
|
|
15
20
|
runtimePolicy(): RuntimePolicy;
|
|
21
|
+
bindResolvedRuntime(resolved: ResolvedGeminiRuntime): void;
|
|
22
|
+
private adapterInput;
|
|
16
23
|
complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
|
|
17
24
|
stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
|
|
18
|
-
|
|
25
|
+
/**
|
|
26
|
+
* spc_011-C-05: preflight native token count via `GenerativeModel.countTokens` — reuses the
|
|
27
|
+
* same contents/tools/vendorConfig construction `complete()` uses so the counted request and
|
|
28
|
+
* the sent request never diverge.
|
|
29
|
+
*/
|
|
30
|
+
countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<PromptMeasurement>;
|
|
19
31
|
/**
|
|
20
32
|
* Gemini vendor features from extensions, mapped to the Node SDK shape (mirrors the Python provider's
|
|
21
33
|
* extension keys for a consistent cross-SDK API):
|
|
@@ -29,3 +41,4 @@ export declare class GeminiProvider implements LLMProvider {
|
|
|
29
41
|
generationConfig?: Record<string, unknown>;
|
|
30
42
|
};
|
|
31
43
|
}
|
|
44
|
+
export {};
|