@deepstrike/sdk 0.2.30 → 0.2.32
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/dist/harness/harness.d.ts +3 -2
- package/dist/harness/harness.js +15 -35
- package/dist/harness/judge.d.ts +42 -0
- package/dist/harness/judge.js +58 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4 -0
- package/dist/kernel.d.ts +7 -1
- package/dist/providers/anthropic-compatible.d.ts +23 -0
- package/dist/providers/anthropic-compatible.js +29 -0
- package/dist/providers/catalog.js +5 -53
- package/dist/providers/deepseek.d.ts +28 -8
- package/dist/providers/deepseek.js +38 -157
- package/dist/providers/factories.js +10 -22
- package/dist/providers/gemini.d.ts +12 -0
- package/dist/providers/gemini.js +38 -3
- package/dist/providers/glm.d.ts +7 -4
- package/dist/providers/glm.js +27 -24
- package/dist/providers/kimi.d.ts +5 -4
- package/dist/providers/kimi.js +8 -22
- package/dist/providers/minimax.d.ts +26 -12
- package/dist/providers/minimax.js +33 -159
- package/dist/providers/openai-responses.d.ts +6 -0
- package/dist/providers/openai-responses.js +22 -2
- package/dist/providers/openai.d.ts +52 -0
- package/dist/providers/openai.js +145 -66
- package/dist/providers/profiles.d.ts +60 -0
- package/dist/providers/profiles.js +22 -0
- package/dist/providers/qwen.d.ts +20 -19
- package/dist/providers/qwen.js +49 -176
- package/dist/providers/registry.d.ts +18 -0
- package/dist/providers/registry.js +35 -0
- package/dist/providers/vendor-profiles.d.ts +54 -0
- package/dist/providers/vendor-profiles.js +66 -0
- package/dist/runtime/event-stream.d.ts +44 -0
- package/dist/runtime/event-stream.js +39 -0
- package/dist/runtime/reactive-session.d.ts +125 -0
- package/dist/runtime/reactive-session.js +127 -0
- package/dist/runtime/run-group.d.ts +74 -0
- package/dist/runtime/run-group.js +72 -0
- package/dist/runtime/runner.d.ts +9 -0
- package/dist/runtime/runner.js +56 -7
- package/dist/runtime/session-log.d.ts +8 -0
- package/dist/runtime/turn-policy.d.ts +33 -0
- package/dist/runtime/turn-policy.js +58 -0
- package/dist/signals/gateway.d.ts +7 -2
- package/dist/signals/gateway.js +13 -3
- package/dist/signals/types.d.ts +10 -1
- package/package.json +2 -2
|
@@ -1,43 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { KimiProvider, KimiAnthropicProvider } from "./kimi.js";
|
|
3
|
-
import { QwenProvider, QwenAnthropicProvider } from "./qwen.js";
|
|
4
|
-
import { GLMProvider, GLMAnthropicProvider } from "./glm.js";
|
|
5
|
-
import { MiniMaxOpenAIProvider, MiniMaxAnthropicProvider } from "./minimax.js";
|
|
6
|
-
import { GeminiProvider } from "./gemini.js";
|
|
1
|
+
import { PROVIDER_REGISTRY } from "./registry.js";
|
|
7
2
|
import { OllamaProvider } from "./ollama.js";
|
|
3
|
+
function build(providerId, protocol, o) {
|
|
4
|
+
return PROVIDER_REGISTRY[`${providerId}:${protocol}`](o.apiKey, o.model, o.retry, o.baseURL);
|
|
5
|
+
}
|
|
8
6
|
/** DeepSeek. Defaults to the OpenAI-compatible wire (richer reasoning-replay handling). */
|
|
9
7
|
export function deepseek(o) {
|
|
10
|
-
return o.protocol === "anthropic"
|
|
11
|
-
? new DeepSeekAnthropicProvider(o.apiKey, o.model, o.retry, o.baseURL)
|
|
12
|
-
: new DeepSeekProvider(o.apiKey, o.model, o.retry, o.baseURL);
|
|
8
|
+
return build("deepseek", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
13
9
|
}
|
|
14
10
|
/** Moonshot Kimi. Defaults to the OpenAI-compatible wire. */
|
|
15
11
|
export function kimi(o) {
|
|
16
|
-
return o.protocol === "anthropic"
|
|
17
|
-
? new KimiAnthropicProvider(o.apiKey, o.model, o.retry, o.baseURL)
|
|
18
|
-
: new KimiProvider(o.apiKey, o.model, o.retry, o.baseURL);
|
|
12
|
+
return build("kimi", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
19
13
|
}
|
|
20
14
|
/** Alibaba Qwen / DashScope. Defaults to the OpenAI-compatible (DashScope) wire. */
|
|
21
15
|
export function qwen(o) {
|
|
22
|
-
return o.protocol === "anthropic"
|
|
23
|
-
? new QwenAnthropicProvider(o.apiKey, o.model, o.retry, o.baseURL)
|
|
24
|
-
: new QwenProvider(o.apiKey, o.model, o.retry, o.baseURL);
|
|
16
|
+
return build("qwen", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
25
17
|
}
|
|
26
18
|
/** Zhipu GLM. Defaults to the OpenAI-compatible wire. */
|
|
27
19
|
export function glm(o) {
|
|
28
|
-
return o.protocol === "anthropic"
|
|
29
|
-
? new GLMAnthropicProvider(o.apiKey, o.model, o.retry, o.baseURL)
|
|
30
|
-
: new GLMProvider(o.apiKey, o.model, o.retry, o.baseURL);
|
|
20
|
+
return build("glm", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
31
21
|
}
|
|
32
22
|
/** MiniMax. Defaults to the Anthropic-compatible wire (the primary M2.x path). */
|
|
33
23
|
export function minimax(o) {
|
|
34
|
-
return o.protocol === "openai"
|
|
35
|
-
? new MiniMaxOpenAIProvider(o.apiKey, o.model, o.retry, o.baseURL)
|
|
36
|
-
: new MiniMaxAnthropicProvider(o.apiKey, o.model, o.retry, o.baseURL);
|
|
24
|
+
return build("minimax", o.protocol === "openai" ? "openai-chat" : "anthropic-messages", o);
|
|
37
25
|
}
|
|
38
26
|
/** Google Gemini (single wire). */
|
|
39
27
|
export function gemini(o) {
|
|
40
|
-
return
|
|
28
|
+
return PROVIDER_REGISTRY["gemini:gemini"](o.apiKey, o.model, o.retry, o.baseURL);
|
|
41
29
|
}
|
|
42
30
|
/** Local Ollama (single wire, no API key). */
|
|
43
31
|
export function ollama(o = {}) {
|
|
@@ -16,4 +16,16 @@ export declare class GeminiProvider implements LLMProvider {
|
|
|
16
16
|
complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
|
|
17
17
|
stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
|
|
18
18
|
private modelExtensions;
|
|
19
|
+
/**
|
|
20
|
+
* Gemini vendor features from extensions, mapped to the Node SDK shape (mirrors the Python provider's
|
|
21
|
+
* extension keys for a consistent cross-SDK API):
|
|
22
|
+
* - `google_search` (truthy → default, object → config): Google Search grounding server tool
|
|
23
|
+
* (gemini-2.0+), appended to tools[].
|
|
24
|
+
* - `response_mime_type` / `response_schema`: structured output → `generationConfig` (the API rejects
|
|
25
|
+
* pairing this with google_search).
|
|
26
|
+
*/
|
|
27
|
+
vendorConfig(extensions?: Record<string, unknown>): {
|
|
28
|
+
tools?: unknown[];
|
|
29
|
+
generationConfig?: Record<string, unknown>;
|
|
30
|
+
};
|
|
19
31
|
}
|
package/dist/providers/gemini.js
CHANGED
|
@@ -116,11 +116,14 @@ export class GeminiProvider {
|
|
|
116
116
|
let lastErr;
|
|
117
117
|
for (let i = 0; i < this.maxRetries; i++) {
|
|
118
118
|
try {
|
|
119
|
+
const vc = this.vendorConfig(extensions);
|
|
120
|
+
const allTools = [...geminiTools, ...(vc.tools ?? [])];
|
|
119
121
|
const m = this.genAI.getGenerativeModel({
|
|
120
122
|
...this.modelExtensions(extensions),
|
|
121
123
|
model: this.model,
|
|
122
124
|
...(system ? { systemInstruction: system } : {}),
|
|
123
|
-
...(
|
|
125
|
+
...(allTools.length ? { tools: allTools } : {}),
|
|
126
|
+
...(vc.generationConfig ? { generationConfig: vc.generationConfig } : {}),
|
|
124
127
|
}, this.requestOptions);
|
|
125
128
|
const resp = await m.generateContent({ contents });
|
|
126
129
|
this.circuit.recordSuccess();
|
|
@@ -157,11 +160,14 @@ export class GeminiProvider {
|
|
|
157
160
|
const system = context.systemText || undefined;
|
|
158
161
|
const contents = buildContents(turnsWithStateAppended(context));
|
|
159
162
|
const geminiTools = buildTools(tools);
|
|
163
|
+
const vc = this.vendorConfig(extensions);
|
|
164
|
+
const allTools = [...geminiTools, ...(vc.tools ?? [])];
|
|
160
165
|
const m = this.genAI.getGenerativeModel({
|
|
161
166
|
...this.modelExtensions(extensions),
|
|
162
167
|
model: this.model,
|
|
163
168
|
...(system ? { systemInstruction: system } : {}),
|
|
164
|
-
...(
|
|
169
|
+
...(allTools.length ? { tools: allTools } : {}),
|
|
170
|
+
...(vc.generationConfig ? { generationConfig: vc.generationConfig } : {}),
|
|
165
171
|
}, this.requestOptions);
|
|
166
172
|
const result = await m.generateContentStream({ contents });
|
|
167
173
|
const toolCalls = [];
|
|
@@ -195,7 +201,36 @@ export class GeminiProvider {
|
|
|
195
201
|
modelExtensions(extensions) {
|
|
196
202
|
if (!extensions)
|
|
197
203
|
return {};
|
|
198
|
-
|
|
204
|
+
// Strip keys handled explicitly elsewhere (incl. the vendor server-tool / structured-output keys
|
|
205
|
+
// consumed by `vendorConfig`) so they never leak raw into getGenerativeModel.
|
|
206
|
+
// Strip keys handled explicitly: the SDK fields set below + the named vendor keys consumed by
|
|
207
|
+
// `vendorConfig`. A caller-provided raw `generationConfig` still passes through (and is merged with
|
|
208
|
+
// any structured-output config at the call site).
|
|
209
|
+
const { model: _model, systemInstruction: _systemInstruction, tools: _tools, google_search: _gs, response_mime_type: _rmt, response_schema: _rs, ...rest } = extensions;
|
|
199
210
|
return rest;
|
|
200
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Gemini vendor features from extensions, mapped to the Node SDK shape (mirrors the Python provider's
|
|
214
|
+
* extension keys for a consistent cross-SDK API):
|
|
215
|
+
* - `google_search` (truthy → default, object → config): Google Search grounding server tool
|
|
216
|
+
* (gemini-2.0+), appended to tools[].
|
|
217
|
+
* - `response_mime_type` / `response_schema`: structured output → `generationConfig` (the API rejects
|
|
218
|
+
* pairing this with google_search).
|
|
219
|
+
*/
|
|
220
|
+
vendorConfig(extensions) {
|
|
221
|
+
const ext = extensions ?? {};
|
|
222
|
+
const tools = [];
|
|
223
|
+
if (ext.google_search)
|
|
224
|
+
tools.push({ googleSearch: typeof ext.google_search === "object" ? ext.google_search : {} });
|
|
225
|
+
// Seed from any caller-provided raw generationConfig, then layer the named structured-output keys.
|
|
226
|
+
const gc = { ...ext.generationConfig };
|
|
227
|
+
if (ext.response_mime_type != null)
|
|
228
|
+
gc.responseMimeType = ext.response_mime_type;
|
|
229
|
+
if (ext.response_schema != null)
|
|
230
|
+
gc.responseSchema = ext.response_schema;
|
|
231
|
+
return {
|
|
232
|
+
...(tools.length ? { tools } : {}),
|
|
233
|
+
...(Object.keys(gc).length ? { generationConfig: gc } : {}),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
201
236
|
}
|
package/dist/providers/glm.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { ProviderDescriptor, RuntimePolicy } from "../types.js";
|
|
2
|
-
import { AnthropicProvider } from "./anthropic.js";
|
|
3
2
|
import { OpenAIChatProvider } from "./openai.js";
|
|
3
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
4
4
|
/**
|
|
5
5
|
* GLM over its Anthropic-compatible endpoint.
|
|
6
|
+
* @deprecated Prefer `glm({ protocol: "anthropic" })`. Behavior is now fully
|
|
7
|
+
* data-driven via `anthropicVendorProfiles.glm`; this thin shim is kept for
|
|
8
|
+
* backward compatibility and `instanceof` checks.
|
|
6
9
|
*/
|
|
7
|
-
export declare class GLMAnthropicProvider extends
|
|
10
|
+
export declare class GLMAnthropicProvider extends AnthropicCompatibleProvider {
|
|
8
11
|
constructor(apiKey: string, model?: string, retry?: {
|
|
9
12
|
maxRetries: number;
|
|
10
13
|
baseDelay: number;
|
|
11
14
|
}, baseURL?: string);
|
|
12
|
-
protected providerName(): string;
|
|
13
|
-
runtimePolicy(): RuntimePolicy;
|
|
14
15
|
}
|
|
15
16
|
export declare class GLMProvider extends OpenAIChatProvider {
|
|
16
17
|
constructor(apiKey: string, model?: string, retry?: {
|
|
@@ -19,4 +20,6 @@ export declare class GLMProvider extends OpenAIChatProvider {
|
|
|
19
20
|
}, baseURL?: string);
|
|
20
21
|
runtimePolicy(): RuntimePolicy;
|
|
21
22
|
descriptor(): ProviderDescriptor;
|
|
23
|
+
protected serverTools(extensions?: Record<string, unknown>): unknown[];
|
|
24
|
+
protected prepareExtensions(extensions?: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
22
25
|
}
|
package/dist/providers/glm.js
CHANGED
|
@@ -1,35 +1,20 @@
|
|
|
1
|
-
import { AnthropicProvider } from "./anthropic.js";
|
|
2
1
|
import { OpenAIChatProvider } from "./openai.js";
|
|
2
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
3
3
|
import { endpointProfiles } from "./profiles.js";
|
|
4
|
-
|
|
5
|
-
"glm-5.1": { maxTurns: 50 },
|
|
6
|
-
"glm/glm-5.1": { maxTurns: 50 },
|
|
7
|
-
"glm-4-plus": { maxTurns: 35 },
|
|
8
|
-
"glm/glm-4-plus": { maxTurns: 35 },
|
|
9
|
-
"glm-4-flash": { maxTurns: 15 },
|
|
10
|
-
"glm/glm-4-flash": { maxTurns: 15 },
|
|
11
|
-
"glm-4-air": { maxTurns: 20 },
|
|
12
|
-
"glm/glm-4-air": { maxTurns: 20 },
|
|
13
|
-
};
|
|
4
|
+
import { GLM_POLICIES, anthropicVendorProfiles } from "./vendor-profiles.js";
|
|
14
5
|
/**
|
|
15
6
|
* GLM over its Anthropic-compatible endpoint.
|
|
7
|
+
* @deprecated Prefer `glm({ protocol: "anthropic" })`. Behavior is now fully
|
|
8
|
+
* data-driven via `anthropicVendorProfiles.glm`; this thin shim is kept for
|
|
9
|
+
* backward compatibility and `instanceof` checks.
|
|
16
10
|
*/
|
|
17
|
-
export class GLMAnthropicProvider extends
|
|
18
|
-
constructor(apiKey, model
|
|
19
|
-
super(apiKey, model, retry,
|
|
20
|
-
baseURL,
|
|
21
|
-
authMode: "api-key",
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
providerName() {
|
|
25
|
-
return "glm";
|
|
26
|
-
}
|
|
27
|
-
runtimePolicy() {
|
|
28
|
-
return GLM_POLICIES[this.model] ?? {};
|
|
11
|
+
export class GLMAnthropicProvider extends AnthropicCompatibleProvider {
|
|
12
|
+
constructor(apiKey, model, retry, baseURL) {
|
|
13
|
+
super(anthropicVendorProfiles.glm, apiKey, model, retry, baseURL);
|
|
29
14
|
}
|
|
30
15
|
}
|
|
31
16
|
export class GLMProvider extends OpenAIChatProvider {
|
|
32
|
-
constructor(apiKey, model = "glm-5.
|
|
17
|
+
constructor(apiKey, model = "glm-5.2", retry, baseURL = endpointProfiles["glm.openai"].baseURL) {
|
|
33
18
|
super(apiKey, model, retry, baseURL);
|
|
34
19
|
}
|
|
35
20
|
runtimePolicy() {
|
|
@@ -42,4 +27,22 @@ export class GLMProvider extends OpenAIChatProvider {
|
|
|
42
27
|
model: this.model,
|
|
43
28
|
};
|
|
44
29
|
}
|
|
30
|
+
// ── GLM web_search (Zhipu vendor server tool; OpenAI-wire only) ──────────────
|
|
31
|
+
// Enable with `extensions={ web_search: true }` (default config) or `{ web_search: {...} }`
|
|
32
|
+
// (passthrough: search_engine, search_recency_filter, search_domain_filter, count, …). Injected as a
|
|
33
|
+
// `{ type: "web_search", web_search: {...} }` entry in tools[]; the model searches server-side and
|
|
34
|
+
// the results come back inline (no client tool-loop). Mirrors the Python GLM provider.
|
|
35
|
+
serverTools(extensions) {
|
|
36
|
+
const ws = extensions?.web_search;
|
|
37
|
+
if (!ws)
|
|
38
|
+
return [];
|
|
39
|
+
return [{ type: "web_search", web_search: typeof ws === "object" ? ws : {} }];
|
|
40
|
+
}
|
|
41
|
+
// Strip `web_search` from the passthrough so it shapes tools[] only, never leaks as a body field.
|
|
42
|
+
prepareExtensions(extensions) {
|
|
43
|
+
if (!extensions || !("web_search" in extensions))
|
|
44
|
+
return extensions;
|
|
45
|
+
const { web_search: _omit, ...rest } = extensions;
|
|
46
|
+
return rest;
|
|
47
|
+
}
|
|
45
48
|
}
|
package/dist/providers/kimi.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { ProviderDescriptor, RuntimePolicy } from "../types.js";
|
|
2
|
-
import { AnthropicProvider } from "./anthropic.js";
|
|
3
2
|
import { OpenAIChatProvider } from "./openai.js";
|
|
3
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
4
4
|
/**
|
|
5
5
|
* Kimi over its Anthropic-compatible endpoint.
|
|
6
|
+
* @deprecated Prefer `kimi({ protocol: "anthropic" })`. Behavior is now fully
|
|
7
|
+
* data-driven via `anthropicVendorProfiles.kimi`; this thin shim is kept for
|
|
8
|
+
* backward compatibility and `instanceof` checks.
|
|
6
9
|
*/
|
|
7
|
-
export declare class KimiAnthropicProvider extends
|
|
10
|
+
export declare class KimiAnthropicProvider extends AnthropicCompatibleProvider {
|
|
8
11
|
constructor(apiKey: string, model?: string, retry?: {
|
|
9
12
|
maxRetries: number;
|
|
10
13
|
baseDelay: number;
|
|
11
14
|
}, baseURL?: string);
|
|
12
|
-
protected providerName(): string;
|
|
13
|
-
runtimePolicy(): RuntimePolicy;
|
|
14
15
|
}
|
|
15
16
|
export declare class KimiProvider extends OpenAIChatProvider {
|
|
16
17
|
constructor(apiKey: string, model?: string, retry?: {
|
package/dist/providers/kimi.js
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
import { AnthropicProvider } from "./anthropic.js";
|
|
2
1
|
import { OpenAIChatProvider } from "./openai.js";
|
|
2
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
3
3
|
import { endpointProfiles } from "./profiles.js";
|
|
4
|
-
|
|
5
|
-
"moonshot-v1-8k": { maxTurns: 15 },
|
|
6
|
-
"moonshot-v1-32k": { maxTurns: 20 },
|
|
7
|
-
"moonshot-v1-128k": { maxTurns: 30 },
|
|
8
|
-
"kimi-k2.5": { maxTurns: 30 },
|
|
9
|
-
"kimi-k2.6": { maxTurns: 35 },
|
|
10
|
-
"kimi-k2-thinking": { maxTurns: 50 },
|
|
11
|
-
"kimi-k2-thinking-turbo": { maxTurns: 40 },
|
|
12
|
-
};
|
|
4
|
+
import { KIMI_POLICIES, anthropicVendorProfiles } from "./vendor-profiles.js";
|
|
13
5
|
/**
|
|
14
6
|
* Kimi over its Anthropic-compatible endpoint.
|
|
7
|
+
* @deprecated Prefer `kimi({ protocol: "anthropic" })`. Behavior is now fully
|
|
8
|
+
* data-driven via `anthropicVendorProfiles.kimi`; this thin shim is kept for
|
|
9
|
+
* backward compatibility and `instanceof` checks.
|
|
15
10
|
*/
|
|
16
|
-
export class KimiAnthropicProvider extends
|
|
17
|
-
constructor(apiKey, model
|
|
18
|
-
super(apiKey, model, retry,
|
|
19
|
-
baseURL,
|
|
20
|
-
authMode: "api-key",
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
providerName() {
|
|
24
|
-
return "kimi";
|
|
25
|
-
}
|
|
26
|
-
runtimePolicy() {
|
|
27
|
-
return KIMI_POLICIES[this.model] ?? {};
|
|
11
|
+
export class KimiAnthropicProvider extends AnthropicCompatibleProvider {
|
|
12
|
+
constructor(apiKey, model, retry, baseURL) {
|
|
13
|
+
super(anthropicVendorProfiles.kimi, apiKey, model, retry, baseURL);
|
|
28
14
|
}
|
|
29
15
|
}
|
|
30
16
|
export class KimiProvider extends OpenAIChatProvider {
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { ProviderDescriptor, RuntimePolicy } from "../types.js";
|
|
2
|
+
import { OpenAIChatProvider, type OpenAIChatTurnReasoning } from "./openai.js";
|
|
3
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
4
4
|
/**
|
|
5
5
|
* MiniMax over its Anthropic-compatible endpoint. Replay is carried as Anthropic
|
|
6
6
|
* `native_blocks` (thinking/text/tool_use), identical to the first-party
|
|
7
7
|
* Anthropic provider.
|
|
8
|
+
* @deprecated Prefer `minimax({ protocol: "anthropic" })`. Behavior is now fully
|
|
9
|
+
* data-driven via `anthropicVendorProfiles.minimax`; this thin shim is kept for
|
|
10
|
+
* backward compatibility and `instanceof` checks.
|
|
8
11
|
*/
|
|
9
|
-
export declare class MiniMaxAnthropicProvider extends
|
|
12
|
+
export declare class MiniMaxAnthropicProvider extends AnthropicCompatibleProvider {
|
|
10
13
|
constructor(apiKey: string, model?: string, retry?: {
|
|
11
14
|
maxRetries: number;
|
|
12
15
|
baseDelay: number;
|
|
13
16
|
}, baseURL?: string);
|
|
14
|
-
protected providerName(): string;
|
|
15
|
-
runtimePolicy(): RuntimePolicy;
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* MiniMax over its OpenAI-compatible endpoint. Replay is carried as
|
|
19
|
-
* `reasoning_content` / `reasoning_details` (split reasoning)
|
|
20
|
-
* default to `reasoning_split: true` so reasoning is returned
|
|
21
|
-
* than embedded in the message content.
|
|
20
|
+
* `reasoning_content` / `reasoning_details` (split reasoning) in a schema_version-2
|
|
21
|
+
* envelope; requests default to `reasoning_split: true` so reasoning is returned
|
|
22
|
+
* out-of-band rather than embedded in the message content. Request shaping and replay
|
|
23
|
+
* are supplied via the OpenAIChatProvider Template-Method hooks; the streaming /
|
|
24
|
+
* tool-call machinery is inherited from the base class.
|
|
22
25
|
*/
|
|
23
26
|
export declare class MiniMaxOpenAIProvider extends OpenAIChatProvider {
|
|
24
27
|
constructor(apiKey: string, model?: string, retry?: {
|
|
@@ -28,8 +31,19 @@ export declare class MiniMaxOpenAIProvider extends OpenAIChatProvider {
|
|
|
28
31
|
runtimePolicy(): RuntimePolicy;
|
|
29
32
|
descriptor(): ProviderDescriptor;
|
|
30
33
|
protected requireNonEmptyReasoningReplayForToolTurns(extensions?: Record<string, unknown>): boolean;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
protected cacheKeyParams(): Record<string, unknown>;
|
|
35
|
+
protected usesInlineThinkingTags(): boolean;
|
|
36
|
+
protected exposeReasoningDelta(extensions?: Record<string, unknown>): boolean;
|
|
37
|
+
protected prepareExtensions(extensions?: Record<string, unknown>): Record<string, unknown>;
|
|
38
|
+
protected rememberCompleteReplay(content: string, toolCalls: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
arguments: string;
|
|
42
|
+
}>, r: OpenAIChatTurnReasoning): void;
|
|
43
|
+
protected rememberStreamReplay(content: string, toolCalls: Array<{
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
arguments: string;
|
|
47
|
+
}>, r: OpenAIChatTurnReasoning): void;
|
|
34
48
|
private rememberMiniMaxReplay;
|
|
35
49
|
}
|
|
@@ -1,44 +1,31 @@
|
|
|
1
|
-
import { AnthropicProvider } from "./anthropic.js";
|
|
2
1
|
import { OpenAIChatProvider } from "./openai.js";
|
|
2
|
+
import { AnthropicCompatibleProvider } from "./anthropic-compatible.js";
|
|
3
3
|
import { endpointProfiles } from "./profiles.js";
|
|
4
|
-
import { omitExtensionKeys
|
|
5
|
-
|
|
6
|
-
"MiniMax-M2.7": { maxTurns: 35 },
|
|
7
|
-
"MiniMax-M2.7-highspeed": { maxTurns: 35 },
|
|
8
|
-
"MiniMax-M2.5": { maxTurns: 25 },
|
|
9
|
-
"MiniMax-M2.5-highspeed": { maxTurns: 25 },
|
|
10
|
-
"MiniMax-M2.1": { maxTurns: 25 },
|
|
11
|
-
"MiniMax-M2.1-highspeed": { maxTurns: 25 },
|
|
12
|
-
"MiniMax-M2": { maxTurns: 20 },
|
|
13
|
-
"MiniMax-Text-01": { maxTurns: 20 },
|
|
14
|
-
};
|
|
4
|
+
import { omitExtensionKeys } from "./base.js";
|
|
5
|
+
import { MINIMAX_POLICIES, anthropicVendorProfiles } from "./vendor-profiles.js";
|
|
15
6
|
/**
|
|
16
7
|
* MiniMax over its Anthropic-compatible endpoint. Replay is carried as Anthropic
|
|
17
8
|
* `native_blocks` (thinking/text/tool_use), identical to the first-party
|
|
18
9
|
* Anthropic provider.
|
|
10
|
+
* @deprecated Prefer `minimax({ protocol: "anthropic" })`. Behavior is now fully
|
|
11
|
+
* data-driven via `anthropicVendorProfiles.minimax`; this thin shim is kept for
|
|
12
|
+
* backward compatibility and `instanceof` checks.
|
|
19
13
|
*/
|
|
20
|
-
export class MiniMaxAnthropicProvider extends
|
|
21
|
-
constructor(apiKey, model
|
|
22
|
-
super(apiKey, model, retry,
|
|
23
|
-
baseURL,
|
|
24
|
-
authMode: "api-key",
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
providerName() {
|
|
28
|
-
return "minimax";
|
|
29
|
-
}
|
|
30
|
-
runtimePolicy() {
|
|
31
|
-
return MINIMAX_POLICIES[this.model] ?? {};
|
|
14
|
+
export class MiniMaxAnthropicProvider extends AnthropicCompatibleProvider {
|
|
15
|
+
constructor(apiKey, model, retry, baseURL) {
|
|
16
|
+
super(anthropicVendorProfiles.minimax, apiKey, model, retry, baseURL);
|
|
32
17
|
}
|
|
33
18
|
}
|
|
34
19
|
/**
|
|
35
20
|
* MiniMax over its OpenAI-compatible endpoint. Replay is carried as
|
|
36
|
-
* `reasoning_content` / `reasoning_details` (split reasoning)
|
|
37
|
-
* default to `reasoning_split: true` so reasoning is returned
|
|
38
|
-
* than embedded in the message content.
|
|
21
|
+
* `reasoning_content` / `reasoning_details` (split reasoning) in a schema_version-2
|
|
22
|
+
* envelope; requests default to `reasoning_split: true` so reasoning is returned
|
|
23
|
+
* out-of-band rather than embedded in the message content. Request shaping and replay
|
|
24
|
+
* are supplied via the OpenAIChatProvider Template-Method hooks; the streaming /
|
|
25
|
+
* tool-call machinery is inherited from the base class.
|
|
39
26
|
*/
|
|
40
27
|
export class MiniMaxOpenAIProvider extends OpenAIChatProvider {
|
|
41
|
-
constructor(apiKey, model = "MiniMax-
|
|
28
|
+
constructor(apiKey, model = "MiniMax-M3", retry, baseURL = endpointProfiles["minimax.openai"].baseURL) {
|
|
42
29
|
super(apiKey, model, retry, baseURL);
|
|
43
30
|
}
|
|
44
31
|
runtimePolicy() {
|
|
@@ -65,139 +52,33 @@ export class MiniMaxOpenAIProvider extends OpenAIChatProvider {
|
|
|
65
52
|
return false;
|
|
66
53
|
return extensions?.reasoning_split !== false;
|
|
67
54
|
}
|
|
68
|
-
|
|
55
|
+
// MiniMax auto prefix-caches and does not accept OpenAI's `prompt_cache_key`; omit it.
|
|
56
|
+
cacheKeyParams() {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
// Reasoning arrives out-of-band (reasoning_content / reasoning_details), never inline tags.
|
|
60
|
+
usesInlineThinkingTags() {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
exposeReasoningDelta(extensions) {
|
|
64
|
+
return (extensions?.exposeReasoning ?? false);
|
|
65
|
+
}
|
|
66
|
+
prepareExtensions(extensions) {
|
|
69
67
|
const reasoningSplit = extensions?.reasoning_split !== false;
|
|
70
68
|
return {
|
|
71
69
|
...omitExtensionKeys(extensions, ["reasoning_split", "exposeReasoning"]),
|
|
72
70
|
__deepstrikeThinkingEnabled: reasoningSplit,
|
|
73
|
-
// Re-thread the degrade control flag (omitExtensionKeys strips internal
|
|
74
|
-
//
|
|
71
|
+
// Re-thread the degrade control flag (omitExtensionKeys strips internal keys) so
|
|
72
|
+
// buildChatMessages can honor it; the wire-request omit drops it.
|
|
75
73
|
...(extensions?.degradeMissingReasoningReplay === true ? { degradeMissingReasoningReplay: true } : {}),
|
|
76
74
|
reasoning_split: reasoningSplit,
|
|
77
75
|
};
|
|
78
76
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (this.circuit.isOpen())
|
|
82
|
-
throw new Error("Circuit breaker open");
|
|
83
|
-
const msgs = this.buildChatMessages(context, requestExtensions);
|
|
84
|
-
let lastErr;
|
|
85
|
-
for (let i = 0; i < this.maxRetries; i++) {
|
|
86
|
-
try {
|
|
87
|
-
const resp = await this.client.chat.completions.create({
|
|
88
|
-
...this.requestExtensions(requestExtensions),
|
|
89
|
-
model: this.model,
|
|
90
|
-
messages: msgs,
|
|
91
|
-
...(tools.length ? { tools: this.chat.buildTools(tools) } : {}),
|
|
92
|
-
});
|
|
93
|
-
this.circuit.recordSuccess();
|
|
94
|
-
const choice = resp.choices[0].message;
|
|
95
|
-
const nativeToolCalls = choice.tool_calls ?? [];
|
|
96
|
-
const toolCalls = this.chat.normalizeToolCalls(nativeToolCalls);
|
|
97
|
-
const content = choice.content ?? "";
|
|
98
|
-
this.rememberMiniMaxReplay(content, toolCalls, choice.reasoning_content, choice.reasoning_details, nativeToolCalls);
|
|
99
|
-
return { role: "assistant", content, tokenCount: resp.usage?.completion_tokens ?? resp.usage?.total_tokens, toolCalls };
|
|
100
|
-
}
|
|
101
|
-
catch (err) {
|
|
102
|
-
lastErr = err;
|
|
103
|
-
this.circuit.recordFailure();
|
|
104
|
-
if (i < this.maxRetries - 1)
|
|
105
|
-
await new Promise(r => setTimeout(r, this.baseDelay * 2 ** i));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
throw lastErr;
|
|
77
|
+
rememberCompleteReplay(content, toolCalls, r) {
|
|
78
|
+
this.rememberMiniMaxReplay(content, toolCalls, r.reasoningContent, r.reasoningDetails, r.nativeToolCalls);
|
|
109
79
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const requestExtensions = this.buildRequestExtensions(extensions);
|
|
113
|
-
const msgs = this.buildChatMessages(context, requestExtensions);
|
|
114
|
-
const toolCallBufs = {};
|
|
115
|
-
const emittedToolCallIndexes = new Set();
|
|
116
|
-
let reasoningContent = "";
|
|
117
|
-
let reasoningDetails;
|
|
118
|
-
let finalText = "";
|
|
119
|
-
const stream = await this.client.chat.completions.create({
|
|
120
|
-
...this.requestExtensions(requestExtensions),
|
|
121
|
-
model: this.model,
|
|
122
|
-
messages: msgs,
|
|
123
|
-
...(tools.length ? { tools: this.chat.buildTools(tools) } : {}),
|
|
124
|
-
stream: true,
|
|
125
|
-
stream_options: { include_usage: true },
|
|
126
|
-
});
|
|
127
|
-
let totalTokens = 0;
|
|
128
|
-
let inputTokens = 0;
|
|
129
|
-
let outputTokens = 0;
|
|
130
|
-
let cacheReadTokens = 0;
|
|
131
|
-
for await (const chunk of stream) {
|
|
132
|
-
if (chunk.usage) {
|
|
133
|
-
totalTokens = chunk.usage.total_tokens;
|
|
134
|
-
inputTokens = chunk.usage.prompt_tokens ?? 0;
|
|
135
|
-
outputTokens = chunk.usage.completion_tokens ?? 0;
|
|
136
|
-
cacheReadTokens = openAICachedPromptTokens(chunk.usage);
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
const choice = chunk.choices[0];
|
|
140
|
-
if (!choice)
|
|
141
|
-
continue;
|
|
142
|
-
const delta = choice.delta;
|
|
143
|
-
if (!delta)
|
|
144
|
-
continue;
|
|
145
|
-
if (exposeReasoning && delta.reasoning_content) {
|
|
146
|
-
yield { type: "thinking_delta", delta: String(delta.reasoning_content) };
|
|
147
|
-
}
|
|
148
|
-
if (delta.reasoning_content)
|
|
149
|
-
reasoningContent += String(delta.reasoning_content);
|
|
150
|
-
if (delta.reasoning_details !== undefined && delta.reasoning_details !== null)
|
|
151
|
-
reasoningDetails = delta.reasoning_details;
|
|
152
|
-
if (delta.content) {
|
|
153
|
-
finalText += String(delta.content);
|
|
154
|
-
yield { type: "text_delta", delta: delta.content };
|
|
155
|
-
}
|
|
156
|
-
for (const tc of delta.tool_calls ?? []) {
|
|
157
|
-
const idx = tc.index;
|
|
158
|
-
if (!toolCallBufs[idx])
|
|
159
|
-
toolCallBufs[idx] = { id: tc.id ?? "", name: "", argsBuf: "" };
|
|
160
|
-
if (tc.function?.name)
|
|
161
|
-
toolCallBufs[idx].name += tc.function.name;
|
|
162
|
-
toolCallBufs[idx].argsBuf += tc.function?.arguments ?? "";
|
|
163
|
-
}
|
|
164
|
-
if (choice.finish_reason === "tool_calls") {
|
|
165
|
-
const toolCalls = Object.values(toolCallBufs).map(tb => ({ id: tb.id, name: tb.name, arguments: tb.argsBuf || "{}" }));
|
|
166
|
-
this.rememberMiniMaxReplay(finalText, toolCalls, reasoningContent, reasoningDetails, nativeToolCallsFromBuffers(toolCallBufs));
|
|
167
|
-
for (const [index, tb] of Object.entries(toolCallBufs)) {
|
|
168
|
-
const idx = Number(index);
|
|
169
|
-
if (emittedToolCallIndexes.has(idx))
|
|
170
|
-
continue;
|
|
171
|
-
let args = {};
|
|
172
|
-
try {
|
|
173
|
-
args = JSON.parse(tb.argsBuf || "{}");
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
args = {};
|
|
177
|
-
}
|
|
178
|
-
emittedToolCallIndexes.add(idx);
|
|
179
|
-
yield { type: "tool_call", id: tb.id, name: tb.name, arguments: args };
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
const toolCalls = Object.values(toolCallBufs).map(tb => ({ id: tb.id, name: tb.name, arguments: tb.argsBuf || "{}" }));
|
|
184
|
-
this.rememberMiniMaxReplay(finalText, toolCalls, reasoningContent, reasoningDetails, nativeToolCallsFromBuffers(toolCallBufs));
|
|
185
|
-
for (const [index, tb] of Object.entries(toolCallBufs)) {
|
|
186
|
-
const idx = Number(index);
|
|
187
|
-
if (emittedToolCallIndexes.has(idx))
|
|
188
|
-
continue;
|
|
189
|
-
let args = {};
|
|
190
|
-
try {
|
|
191
|
-
args = JSON.parse(tb.argsBuf || "{}");
|
|
192
|
-
}
|
|
193
|
-
catch {
|
|
194
|
-
args = {};
|
|
195
|
-
}
|
|
196
|
-
emittedToolCallIndexes.add(idx);
|
|
197
|
-
yield { type: "tool_call", id: tb.id, name: tb.name, arguments: args };
|
|
198
|
-
}
|
|
199
|
-
if (totalTokens > 0)
|
|
200
|
-
yield { type: "usage", totalTokens, inputTokens, outputTokens, ...(cacheReadTokens > 0 ? { cacheReadInputTokens: cacheReadTokens } : {}) };
|
|
80
|
+
rememberStreamReplay(content, toolCalls, r) {
|
|
81
|
+
this.rememberMiniMaxReplay(content, toolCalls, r.reasoningContent, r.reasoningDetails, r.nativeToolCalls);
|
|
201
82
|
}
|
|
202
83
|
rememberMiniMaxReplay(content, toolCalls, reasoningContent, reasoningDetails, nativeToolCalls) {
|
|
203
84
|
const hasReasoning = typeof reasoningContent === "string" && reasoningContent.trim().length > 0;
|
|
@@ -215,10 +96,3 @@ export class MiniMaxOpenAIProvider extends OpenAIChatProvider {
|
|
|
215
96
|
});
|
|
216
97
|
}
|
|
217
98
|
}
|
|
218
|
-
function nativeToolCallsFromBuffers(toolCallBufs) {
|
|
219
|
-
return Object.values(toolCallBufs).map(tb => ({
|
|
220
|
-
id: tb.id,
|
|
221
|
-
type: "function",
|
|
222
|
-
function: { name: tb.name, arguments: tb.argsBuf || "{}" },
|
|
223
|
-
}));
|
|
224
|
-
}
|
|
@@ -40,5 +40,11 @@ export declare class OpenAIResponsesProvider implements LLMProvider {
|
|
|
40
40
|
complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
|
|
41
41
|
stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: ProviderRunState): AsyncIterable<StreamEvent>;
|
|
42
42
|
private requestExtensions;
|
|
43
|
+
/** Responses API built-in server tools from extensions (live in the same tools[] as function tools):
|
|
44
|
+
* `web_search: true` (or a config object), plus a `builtin_tools` list passed through verbatim for
|
|
45
|
+
* file_search / code_interpreter. They run server-side; results return inline. Mirrors py. */
|
|
46
|
+
private builtinTools;
|
|
47
|
+
/** Function tools + built-in server tools merged into the wire tools[] (undefined when empty). */
|
|
48
|
+
private allTools;
|
|
43
49
|
private asRunState;
|
|
44
50
|
}
|
|
@@ -176,7 +176,7 @@ export class OpenAIResponsesProvider {
|
|
|
176
176
|
model: this.model,
|
|
177
177
|
input: this.responses.buildInput(context),
|
|
178
178
|
...(instructions ? { instructions } : {}),
|
|
179
|
-
...(
|
|
179
|
+
...((t => t ? { tools: t } : {})(this.allTools(tools, extensions))),
|
|
180
180
|
});
|
|
181
181
|
this.circuit.recordSuccess();
|
|
182
182
|
const decoded = this.responses.decodeOutput(resp.output);
|
|
@@ -206,7 +206,7 @@ export class OpenAIResponsesProvider {
|
|
|
206
206
|
input: this.responses.buildInput(context, runState),
|
|
207
207
|
...(instructions ? { instructions } : {}),
|
|
208
208
|
...(runState.previousResponseId ? { previous_response_id: runState.previousResponseId } : {}),
|
|
209
|
-
...(
|
|
209
|
+
...((t => t ? { tools: t } : {})(this.allTools(tools, extensions))),
|
|
210
210
|
stream: true,
|
|
211
211
|
});
|
|
212
212
|
for await (const evt of stream) {
|
|
@@ -266,8 +266,28 @@ export class OpenAIResponsesProvider {
|
|
|
266
266
|
requestExtensions(extensions) {
|
|
267
267
|
return omitExtensionKeys(extensions, [
|
|
268
268
|
"model", "input", "instructions", "tools", "stream", "previous_response_id",
|
|
269
|
+
"web_search", "builtin_tools",
|
|
269
270
|
]);
|
|
270
271
|
}
|
|
272
|
+
/** Responses API built-in server tools from extensions (live in the same tools[] as function tools):
|
|
273
|
+
* `web_search: true` (or a config object), plus a `builtin_tools` list passed through verbatim for
|
|
274
|
+
* file_search / code_interpreter. They run server-side; results return inline. Mirrors py. */
|
|
275
|
+
builtinTools(extensions) {
|
|
276
|
+
const ext = extensions ?? {};
|
|
277
|
+
const out = [];
|
|
278
|
+
const ws = ext.web_search;
|
|
279
|
+
if (ws)
|
|
280
|
+
out.push(typeof ws === "object" ? { type: "web_search", ...ws } : { type: "web_search" });
|
|
281
|
+
if (Array.isArray(ext.builtin_tools))
|
|
282
|
+
out.push(...ext.builtin_tools);
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
/** Function tools + built-in server tools merged into the wire tools[] (undefined when empty). */
|
|
286
|
+
allTools(tools, extensions) {
|
|
287
|
+
const fnTools = tools.length ? this.responses.buildTools(tools) : [];
|
|
288
|
+
const all = [...fnTools, ...this.builtinTools(extensions)];
|
|
289
|
+
return all.length ? all : undefined;
|
|
290
|
+
}
|
|
271
291
|
asRunState(state) {
|
|
272
292
|
if (!state)
|
|
273
293
|
return this.createRunState();
|