@deepstrike/sdk 0.2.28 → 0.2.31
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 +45 -21
- 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/harness/public.d.ts +4 -0
- package/dist/harness/public.js +3 -0
- package/dist/index.d.ts +21 -80
- package/dist/index.js +28 -60
- package/dist/kernel.d.ts +7 -1
- package/dist/memory/public.d.ts +4 -0
- package/dist/memory/public.js +3 -0
- package/dist/os/public.d.ts +18 -0
- package/dist/os/public.js +14 -0
- package/dist/planes/public.d.ts +13 -0
- package/dist/planes/public.js +9 -0
- package/dist/providers/anthropic-compatible.d.ts +23 -0
- package/dist/providers/anthropic-compatible.js +29 -0
- package/dist/providers/anthropic.d.ts +11 -2
- package/dist/providers/anthropic.js +14 -9
- 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.d.ts +31 -0
- package/dist/providers/factories.js +33 -0
- package/dist/providers/glm.d.ts +5 -4
- package/dist/providers/glm.js +8 -23
- 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 +32 -158
- package/dist/providers/openai.d.ts +57 -2
- package/dist/providers/openai.js +139 -70
- package/dist/providers/public.d.ts +10 -0
- package/dist/providers/public.js +11 -0
- package/dist/providers/qwen.d.ts +19 -19
- package/dist/providers/qwen.js +37 -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 +62 -0
- package/dist/runtime/event-stream.d.ts +44 -0
- package/dist/runtime/event-stream.js +39 -0
- package/dist/runtime/facade.js +6 -1
- 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 +79 -46
- 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/dist/workflow/public.d.ts +20 -0
- package/dist/workflow/public.js +15 -0
- package/package.json +54 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { WorktreeExecutionPlane, GitWorktreeManager } from "../runtime/worktree-plane.js";
|
|
2
|
+
export type { WorktreeManager } from "../runtime/worktree-plane.js";
|
|
3
|
+
export { FilteredExecutionPlane } from "../runtime/filtered-plane.js";
|
|
4
|
+
export { ProcessSandboxPlane } from "../runtime/process-sandbox-plane.js";
|
|
5
|
+
export type { SandboxOptions } from "../runtime/process-sandbox-plane.js";
|
|
6
|
+
export { McpProxyPlane } from "../runtime/mcp-proxy-plane.js";
|
|
7
|
+
export type { McpServerConfig } from "../runtime/mcp-proxy-plane.js";
|
|
8
|
+
export { RemoteVpcPlane } from "../runtime/remote-vpc-plane.js";
|
|
9
|
+
export type { RemoteVpcOptions } from "../runtime/remote-vpc-plane.js";
|
|
10
|
+
export { NullArchiveStore, FileArchiveStore } from "../runtime/archive.js";
|
|
11
|
+
export type { ArchiveStore } from "../runtime/archive.js";
|
|
12
|
+
export { EnvCredentialVault, InMemoryCredentialVault, ChainedCredentialVault } from "../runtime/credential-vault.js";
|
|
13
|
+
export type { CredentialVault } from "../runtime/credential-vault.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// `@deepstrike/sdk/planes` — advanced execution planes, archive stores, and credential vaults.
|
|
2
|
+
// The root package exports `LocalExecutionPlane`; specialized planes live here.
|
|
3
|
+
export { WorktreeExecutionPlane, GitWorktreeManager } from "../runtime/worktree-plane.js";
|
|
4
|
+
export { FilteredExecutionPlane } from "../runtime/filtered-plane.js";
|
|
5
|
+
export { ProcessSandboxPlane } from "../runtime/process-sandbox-plane.js";
|
|
6
|
+
export { McpProxyPlane } from "../runtime/mcp-proxy-plane.js";
|
|
7
|
+
export { RemoteVpcPlane } from "../runtime/remote-vpc-plane.js";
|
|
8
|
+
export { NullArchiveStore, FileArchiveStore } from "../runtime/archive.js";
|
|
9
|
+
export { EnvCredentialVault, InMemoryCredentialVault, ChainedCredentialVault } from "../runtime/credential-vault.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RuntimePolicy } from "../types.js";
|
|
2
|
+
import { AnthropicProvider } from "./anthropic.js";
|
|
3
|
+
import { type AnthropicVendorProfile } from "./vendor-profiles.js";
|
|
4
|
+
/**
|
|
5
|
+
* A vendor that exposes an Anthropic-compatible Messages endpoint (DeepSeek,
|
|
6
|
+
* Kimi, Qwen, GLM, MiniMax, …). All wire behavior is inherited from
|
|
7
|
+
* `AnthropicProvider`; the only per-vendor variation is configuration, supplied
|
|
8
|
+
* as an `AnthropicVendorProfile`. This replaces the family of near-identical
|
|
9
|
+
* `<Vendor>AnthropicProvider` subclasses that existed only to carry that config.
|
|
10
|
+
*
|
|
11
|
+
* Adding a new Anthropic-compatible vendor is now "add a profile" — no new
|
|
12
|
+
* provider class is required (the named `<Vendor>AnthropicProvider` shims are
|
|
13
|
+
* kept only for backward compatibility / `instanceof` checks).
|
|
14
|
+
*/
|
|
15
|
+
export declare class AnthropicCompatibleProvider extends AnthropicProvider {
|
|
16
|
+
private readonly vendorProfile;
|
|
17
|
+
constructor(profile: AnthropicVendorProfile, apiKey: string, model?: string, retry?: {
|
|
18
|
+
maxRetries: number;
|
|
19
|
+
baseDelay: number;
|
|
20
|
+
}, baseURL?: string);
|
|
21
|
+
protected providerName(): string;
|
|
22
|
+
runtimePolicy(): RuntimePolicy;
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnthropicProvider } from "./anthropic.js";
|
|
2
|
+
import { anthropicVendorBaseURL } from "./vendor-profiles.js";
|
|
3
|
+
/**
|
|
4
|
+
* A vendor that exposes an Anthropic-compatible Messages endpoint (DeepSeek,
|
|
5
|
+
* Kimi, Qwen, GLM, MiniMax, …). All wire behavior is inherited from
|
|
6
|
+
* `AnthropicProvider`; the only per-vendor variation is configuration, supplied
|
|
7
|
+
* as an `AnthropicVendorProfile`. This replaces the family of near-identical
|
|
8
|
+
* `<Vendor>AnthropicProvider` subclasses that existed only to carry that config.
|
|
9
|
+
*
|
|
10
|
+
* Adding a new Anthropic-compatible vendor is now "add a profile" — no new
|
|
11
|
+
* provider class is required (the named `<Vendor>AnthropicProvider` shims are
|
|
12
|
+
* kept only for backward compatibility / `instanceof` checks).
|
|
13
|
+
*/
|
|
14
|
+
export class AnthropicCompatibleProvider extends AnthropicProvider {
|
|
15
|
+
vendorProfile;
|
|
16
|
+
constructor(profile, apiKey, model, retry, baseURL) {
|
|
17
|
+
super(apiKey, model ?? profile.defaultModel, retry, {
|
|
18
|
+
baseURL: baseURL ?? anthropicVendorBaseURL(profile),
|
|
19
|
+
authMode: "api-key",
|
|
20
|
+
});
|
|
21
|
+
this.vendorProfile = profile;
|
|
22
|
+
}
|
|
23
|
+
providerName() {
|
|
24
|
+
return this.vendorProfile.providerId;
|
|
25
|
+
}
|
|
26
|
+
runtimePolicy() {
|
|
27
|
+
return this.vendorProfile.policies[this.model] ?? {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -3,14 +3,23 @@ interface AnthropicProviderOptions {
|
|
|
3
3
|
baseURL?: string;
|
|
4
4
|
authMode?: "api-key" | "bearer";
|
|
5
5
|
}
|
|
6
|
+
/** Options-object form for `AnthropicProvider` — the recommended constructor shape. */
|
|
7
|
+
export interface AnthropicProviderConfig extends AnthropicProviderOptions {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
retry?: {
|
|
11
|
+
maxRetries: number;
|
|
12
|
+
baseDelay: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
6
15
|
export declare class AnthropicProvider implements LLMProvider {
|
|
7
|
-
protected readonly model: string;
|
|
8
16
|
private client;
|
|
9
17
|
private circuit;
|
|
10
18
|
private maxRetries;
|
|
11
19
|
private baseDelay;
|
|
20
|
+
protected readonly model: string;
|
|
12
21
|
private nativeAssistantBlocks;
|
|
13
|
-
constructor(
|
|
22
|
+
constructor(apiKeyOrConfig: string | AnthropicProviderConfig, model?: string, retry?: {
|
|
14
23
|
maxRetries: number;
|
|
15
24
|
baseDelay: number;
|
|
16
25
|
}, options?: AnthropicProviderOptions);
|
|
@@ -13,23 +13,28 @@ const CLAUDE_POLICIES = {
|
|
|
13
13
|
"claude-3-5-haiku-latest": { maxTurns: 15 },
|
|
14
14
|
};
|
|
15
15
|
export class AnthropicProvider {
|
|
16
|
-
model;
|
|
17
16
|
client;
|
|
18
17
|
circuit;
|
|
19
18
|
maxRetries;
|
|
20
19
|
baseDelay;
|
|
20
|
+
model;
|
|
21
21
|
nativeAssistantBlocks = new Map();
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
// Accepts the options object (`new AnthropicProvider({ apiKey, model, baseURL })`) or the legacy
|
|
23
|
+
// positional form (still used by the Anthropic-compatible backend subclasses' `super(...)` calls).
|
|
24
|
+
constructor(apiKeyOrConfig, model = "claude-sonnet-4-6", retry = { maxRetries: 3, baseDelay: 1000 }, options = {}) {
|
|
25
|
+
const c = typeof apiKeyOrConfig === "string"
|
|
26
|
+
? { apiKey: apiKeyOrConfig, model, retry, ...options }
|
|
27
|
+
: { model: "claude-sonnet-4-6", retry: { maxRetries: 3, baseDelay: 1000 }, ...apiKeyOrConfig };
|
|
28
|
+
this.model = c.model ?? "claude-sonnet-4-6";
|
|
24
29
|
this.client = withServerRuntimeGuard(() => new Anthropic({
|
|
25
|
-
...(
|
|
26
|
-
? { authToken: apiKey, apiKey: null }
|
|
27
|
-
: { apiKey, authToken: null }),
|
|
28
|
-
...(
|
|
30
|
+
...(c.authMode === "bearer"
|
|
31
|
+
? { authToken: c.apiKey, apiKey: null }
|
|
32
|
+
: { apiKey: c.apiKey, authToken: null }),
|
|
33
|
+
...(c.baseURL ? { baseURL: c.baseURL } : {}),
|
|
29
34
|
}));
|
|
30
35
|
this.circuit = new CircuitBreaker();
|
|
31
|
-
this.maxRetries = retry
|
|
32
|
-
this.baseDelay = retry
|
|
36
|
+
this.maxRetries = c.retry?.maxRetries ?? 3;
|
|
37
|
+
this.baseDelay = c.retry?.baseDelay ?? 1000;
|
|
33
38
|
}
|
|
34
39
|
runtimePolicy() {
|
|
35
40
|
return CLAUDE_POLICIES[this.model] ?? {};
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { OpenAIChatProvider } from "./openai.js";
|
|
3
|
-
import { DeepSeekProvider, DeepSeekAnthropicProvider } from "./deepseek.js";
|
|
4
|
-
import { KimiProvider, KimiAnthropicProvider } from "./kimi.js";
|
|
5
|
-
import { OpenAIResponsesProvider } from "./openai-responses.js";
|
|
6
|
-
import { MiniMaxAnthropicProvider, MiniMaxOpenAIProvider } from "./minimax.js";
|
|
7
|
-
import { QwenProvider, QwenAnthropicProvider } from "./qwen.js";
|
|
8
|
-
import { GeminiProvider } from "./gemini.js";
|
|
9
|
-
import { GLMProvider, GLMAnthropicProvider } from "./glm.js";
|
|
1
|
+
import { PROVIDER_REGISTRY, providerRegistryKey } from "./registry.js";
|
|
10
2
|
import { endpointProfiles, getModelProfile, modelProfiles } from "./profiles.js";
|
|
11
3
|
export function createProvider(options) {
|
|
12
4
|
const profile = isModelProfileId(options.model) ? getModelProfile(options.model) : undefined;
|
|
@@ -31,50 +23,10 @@ export function createProvider(options) {
|
|
|
31
23
|
}
|
|
32
24
|
const model = modelNameForProvider(options.model, providerId);
|
|
33
25
|
const baseURL = options.baseURL ?? endpoint.baseURL;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (endpoint.protocol === "openai-chat") {
|
|
39
|
-
return new OpenAIChatProvider(options.apiKey, model, options.retry, baseURL);
|
|
40
|
-
}
|
|
41
|
-
if (endpoint.protocol === "openai-responses") {
|
|
42
|
-
return new OpenAIResponsesProvider(options.apiKey, model, options.retry, baseURL);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (providerId === "minimax" && endpoint.protocol === "anthropic-messages") {
|
|
46
|
-
return new MiniMaxAnthropicProvider(options.apiKey, model, options.retry, baseURL);
|
|
47
|
-
}
|
|
48
|
-
if (providerId === "minimax" && endpoint.protocol === "openai-chat") {
|
|
49
|
-
return new MiniMaxOpenAIProvider(options.apiKey, model, options.retry, baseURL);
|
|
50
|
-
}
|
|
51
|
-
if (providerId === "deepseek" && endpoint.protocol === "anthropic-messages") {
|
|
52
|
-
return new DeepSeekAnthropicProvider(options.apiKey, model, options.retry, baseURL);
|
|
53
|
-
}
|
|
54
|
-
if (providerId === "deepseek" && endpoint.protocol === "openai-chat") {
|
|
55
|
-
return new DeepSeekProvider(options.apiKey, model, options.retry, baseURL);
|
|
56
|
-
}
|
|
57
|
-
if (providerId === "kimi" && endpoint.protocol === "anthropic-messages") {
|
|
58
|
-
return new KimiAnthropicProvider(options.apiKey, model, options.retry, baseURL);
|
|
59
|
-
}
|
|
60
|
-
if (providerId === "kimi" && endpoint.protocol === "openai-chat") {
|
|
61
|
-
return new KimiProvider(options.apiKey, model, options.retry, baseURL);
|
|
62
|
-
}
|
|
63
|
-
if (providerId === "qwen" && endpoint.protocol === "anthropic-messages") {
|
|
64
|
-
return new QwenAnthropicProvider(options.apiKey, model, options.retry, baseURL);
|
|
65
|
-
}
|
|
66
|
-
if (providerId === "qwen" && endpoint.protocol === "openai-chat") {
|
|
67
|
-
return new QwenProvider(options.apiKey, model, options.retry, baseURL);
|
|
68
|
-
}
|
|
69
|
-
if (providerId === "gemini" && endpoint.protocol === "gemini") {
|
|
70
|
-
return new GeminiProvider(options.apiKey, model, options.retry, baseURL);
|
|
71
|
-
}
|
|
72
|
-
if (providerId === "glm" && endpoint.protocol === "anthropic-messages") {
|
|
73
|
-
return new GLMAnthropicProvider(options.apiKey, model, options.retry, baseURL);
|
|
74
|
-
}
|
|
75
|
-
if (providerId === "glm" && endpoint.protocol === "openai-chat") {
|
|
76
|
-
return new GLMProvider(options.apiKey, model, options.retry, baseURL);
|
|
77
|
-
}
|
|
26
|
+
// Single data-driven dispatch: one registry keyed by (providerId, protocol).
|
|
27
|
+
const make = PROVIDER_REGISTRY[providerRegistryKey(providerId, endpoint.protocol)];
|
|
28
|
+
if (make)
|
|
29
|
+
return make(options.apiKey, model, options.retry, baseURL);
|
|
78
30
|
throw new Error(`No Node provider factory for ${options.model} on ${endpoint.id}`);
|
|
79
31
|
}
|
|
80
32
|
function isModelProfileId(model) {
|
|
@@ -1,17 +1,25 @@
|
|
|
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
|
* DeepSeek over its Anthropic-compatible endpoint.
|
|
6
|
+
* @deprecated Prefer `deepseek({ protocol: "anthropic" })`. Behavior is now fully
|
|
7
|
+
* data-driven via `anthropicVendorProfiles.deepseek`; this thin shim is kept for
|
|
8
|
+
* backward compatibility and `instanceof` checks.
|
|
6
9
|
*/
|
|
7
|
-
export declare class DeepSeekAnthropicProvider extends
|
|
10
|
+
export declare class DeepSeekAnthropicProvider 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
|
}
|
|
16
|
+
/**
|
|
17
|
+
* DeepSeek over its OpenAI-compatible endpoint. Reasoning is carried out-of-band as
|
|
18
|
+
* `reasoning_content`; replay persists DeepSeek's schema_version-2 envelope (with the
|
|
19
|
+
* native `tool_calls` blocks). Request shaping (`reasoning_effort` + `extra_body.thinking`)
|
|
20
|
+
* and replay are supplied via the OpenAIChatProvider Template-Method hooks; the streaming /
|
|
21
|
+
* tool-call machinery is inherited from the base class.
|
|
22
|
+
*/
|
|
15
23
|
export declare class DeepSeekProvider extends OpenAIChatProvider {
|
|
16
24
|
constructor(apiKey: string, model?: string, retry?: {
|
|
17
25
|
maxRetries: number;
|
|
@@ -20,7 +28,19 @@ export declare class DeepSeekProvider extends OpenAIChatProvider {
|
|
|
20
28
|
runtimePolicy(): RuntimePolicy;
|
|
21
29
|
descriptor(): ProviderDescriptor;
|
|
22
30
|
protected requireNonEmptyReasoningReplayForToolTurns(extensions?: Record<string, unknown>): boolean;
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
protected cacheKeyParams(): Record<string, unknown>;
|
|
32
|
+
protected usesInlineThinkingTags(): boolean;
|
|
33
|
+
protected exposeReasoningDelta(extensions?: Record<string, unknown>): boolean;
|
|
34
|
+
protected prepareExtensions(extensions?: Record<string, unknown>): Record<string, unknown>;
|
|
35
|
+
protected rememberCompleteReplay(content: string, toolCalls: Array<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
arguments: string;
|
|
39
|
+
}>, r: OpenAIChatTurnReasoning): void;
|
|
40
|
+
protected rememberStreamReplay(content: string, toolCalls: Array<{
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
arguments: string;
|
|
44
|
+
}>, r: OpenAIChatTurnReasoning): void;
|
|
25
45
|
private rememberDeepSeekReplay;
|
|
26
46
|
}
|
|
@@ -1,30 +1,26 @@
|
|
|
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
|
-
"deepseek-chat": { maxTurns: 25 },
|
|
7
|
-
"deepseek-reasoner": { maxTurns: 50 },
|
|
8
|
-
"deepseek-v4-flash": { maxTurns: 20 },
|
|
9
|
-
"deepseek-v4-pro": { maxTurns: 35 },
|
|
10
|
-
};
|
|
4
|
+
import { omitExtensionKeys } from "./base.js";
|
|
5
|
+
import { DEEPSEEK_POLICIES, anthropicVendorProfiles } from "./vendor-profiles.js";
|
|
11
6
|
/**
|
|
12
7
|
* DeepSeek over its Anthropic-compatible endpoint.
|
|
8
|
+
* @deprecated Prefer `deepseek({ protocol: "anthropic" })`. Behavior is now fully
|
|
9
|
+
* data-driven via `anthropicVendorProfiles.deepseek`; this thin shim is kept for
|
|
10
|
+
* backward compatibility and `instanceof` checks.
|
|
13
11
|
*/
|
|
14
|
-
export class DeepSeekAnthropicProvider extends
|
|
15
|
-
constructor(apiKey, model
|
|
16
|
-
super(apiKey, model, retry,
|
|
17
|
-
baseURL,
|
|
18
|
-
authMode: "api-key",
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
providerName() {
|
|
22
|
-
return "deepseek";
|
|
23
|
-
}
|
|
24
|
-
runtimePolicy() {
|
|
25
|
-
return DEEPSEEK_POLICIES[this.model] ?? {};
|
|
12
|
+
export class DeepSeekAnthropicProvider extends AnthropicCompatibleProvider {
|
|
13
|
+
constructor(apiKey, model, retry, baseURL) {
|
|
14
|
+
super(anthropicVendorProfiles.deepseek, apiKey, model, retry, baseURL);
|
|
26
15
|
}
|
|
27
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* DeepSeek over its OpenAI-compatible endpoint. Reasoning is carried out-of-band as
|
|
19
|
+
* `reasoning_content`; replay persists DeepSeek's schema_version-2 envelope (with the
|
|
20
|
+
* native `tool_calls` blocks). Request shaping (`reasoning_effort` + `extra_body.thinking`)
|
|
21
|
+
* and replay are supplied via the OpenAIChatProvider Template-Method hooks; the streaming /
|
|
22
|
+
* tool-call machinery is inherited from the base class.
|
|
23
|
+
*/
|
|
28
24
|
export class DeepSeekProvider extends OpenAIChatProvider {
|
|
29
25
|
constructor(apiKey, model = "deepseek-v4-flash", retry, baseURL = endpointProfiles["deepseek.openai"].baseURL) {
|
|
30
26
|
super(apiKey, model, retry, baseURL);
|
|
@@ -53,146 +49,38 @@ export class DeepSeekProvider extends OpenAIChatProvider {
|
|
|
53
49
|
return false;
|
|
54
50
|
return extensions?.thinking !== false;
|
|
55
51
|
}
|
|
56
|
-
|
|
52
|
+
// DeepSeek strictly validates the request body and 400s on unknown params, so never send
|
|
53
|
+
// OpenAI's `prompt_cache_key` (DeepSeek auto prefix-caches anyway).
|
|
54
|
+
// Ref: https://api-docs.deepseek.com/quick_start/error_codes
|
|
55
|
+
cacheKeyParams() {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
// Reasoning arrives out-of-band as `reasoning_content`, never as inline <thinking> tags.
|
|
59
|
+
usesInlineThinkingTags() {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
exposeReasoningDelta(extensions) {
|
|
63
|
+
return (extensions?.exposeReasoning ?? false);
|
|
64
|
+
}
|
|
65
|
+
prepareExtensions(extensions) {
|
|
57
66
|
const thinking = extensions?.thinking === false ? "disabled" : "enabled";
|
|
58
67
|
const thinkingEnabled = thinking !== "disabled";
|
|
59
68
|
const reasoningEffort = extensions?.reasoningEffort === "max" ? "max" : "high";
|
|
60
|
-
|
|
69
|
+
return {
|
|
61
70
|
...omitExtensionKeys(extensions, ["thinking", "reasoningEffort", "exposeReasoning", "extra_body", "reasoning_effort"]),
|
|
62
71
|
__deepstrikeThinkingEnabled: thinkingEnabled,
|
|
63
|
-
// Re-thread the degrade control flag (omitExtensionKeys strips internal
|
|
64
|
-
//
|
|
72
|
+
// Re-thread the degrade control flag (omitExtensionKeys strips internal keys) so
|
|
73
|
+
// buildChatMessages can honor it; the base requestExtensions omit keeps it off nothing.
|
|
65
74
|
...(extensions?.degradeMissingReasoningReplay === true ? { degradeMissingReasoningReplay: true } : {}),
|
|
66
75
|
reasoning_effort: reasoningEffort,
|
|
67
76
|
extra_body: { thinking: { type: thinking } },
|
|
68
77
|
};
|
|
69
|
-
if (this.circuit.isOpen())
|
|
70
|
-
throw new Error("Circuit breaker open");
|
|
71
|
-
const msgs = this.buildChatMessages(context, requestExtensions);
|
|
72
|
-
let lastErr;
|
|
73
|
-
for (let i = 0; i < this.maxRetries; i++) {
|
|
74
|
-
try {
|
|
75
|
-
const resp = await this.client.chat.completions.create({
|
|
76
|
-
...this.requestExtensions(requestExtensions),
|
|
77
|
-
model: this.model,
|
|
78
|
-
messages: msgs,
|
|
79
|
-
...(tools.length ? { tools: this.chat.buildTools(tools) } : {}),
|
|
80
|
-
});
|
|
81
|
-
this.circuit.recordSuccess();
|
|
82
|
-
const choice = resp.choices[0].message;
|
|
83
|
-
const nativeToolCalls = choice.tool_calls ?? [];
|
|
84
|
-
const toolCalls = this.chat.normalizeToolCalls(nativeToolCalls);
|
|
85
|
-
const content = choice.content ?? "";
|
|
86
|
-
this.rememberDeepSeekReplay(content, toolCalls, choice.reasoning_content, nativeToolCalls);
|
|
87
|
-
return { role: "assistant", content, tokenCount: resp.usage?.completion_tokens ?? resp.usage?.total_tokens, toolCalls };
|
|
88
|
-
}
|
|
89
|
-
catch (err) {
|
|
90
|
-
lastErr = err;
|
|
91
|
-
this.circuit.recordFailure();
|
|
92
|
-
if (i < this.maxRetries - 1)
|
|
93
|
-
await new Promise(r => setTimeout(r, this.baseDelay * 2 ** i));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
throw lastErr;
|
|
97
78
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const toolCallBufs = {};
|
|
104
|
-
const emittedToolCallIndexes = new Set();
|
|
105
|
-
let reasoningContent = "";
|
|
106
|
-
let finalText = "";
|
|
107
|
-
const stream = await this.client.chat.completions.create({
|
|
108
|
-
...omitExtensionKeys(extensions, [
|
|
109
|
-
"model", "messages", "tools", "stream", "stream_options", "extra_body", "reasoning_effort",
|
|
110
|
-
"exposeReasoning", "thinking", "reasoningEffort", "__deepstrikeThinkingEnabled",
|
|
111
|
-
]),
|
|
112
|
-
model: this.model,
|
|
113
|
-
messages: msgs,
|
|
114
|
-
...(tools.length ? { tools: this.chat.buildTools(tools) } : {}),
|
|
115
|
-
stream: true,
|
|
116
|
-
stream_options: { include_usage: true },
|
|
117
|
-
reasoning_effort: reasoningEffort,
|
|
118
|
-
extra_body: { thinking: { type: thinking } },
|
|
119
|
-
});
|
|
120
|
-
let totalTokens = 0;
|
|
121
|
-
let inputTokens = 0;
|
|
122
|
-
let outputTokens = 0;
|
|
123
|
-
let cacheReadTokens = 0;
|
|
124
|
-
for await (const chunk of stream) {
|
|
125
|
-
if (chunk.usage) {
|
|
126
|
-
totalTokens = chunk.usage.total_tokens;
|
|
127
|
-
inputTokens = chunk.usage.prompt_tokens ?? 0;
|
|
128
|
-
outputTokens = chunk.usage.completion_tokens ?? 0;
|
|
129
|
-
cacheReadTokens = openAICachedPromptTokens(chunk.usage);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
const choice = chunk.choices[0];
|
|
133
|
-
if (!choice)
|
|
134
|
-
continue;
|
|
135
|
-
const delta = choice.delta;
|
|
136
|
-
if (!delta)
|
|
137
|
-
continue;
|
|
138
|
-
if (exposeReasoning && delta.reasoning_content) {
|
|
139
|
-
yield { type: "thinking_delta", delta: delta.reasoning_content };
|
|
140
|
-
}
|
|
141
|
-
if (delta.reasoning_content)
|
|
142
|
-
reasoningContent += String(delta.reasoning_content);
|
|
143
|
-
if (delta.content) {
|
|
144
|
-
finalText += String(delta.content);
|
|
145
|
-
yield { type: "text_delta", delta: delta.content };
|
|
146
|
-
}
|
|
147
|
-
for (const tc of delta.tool_calls ?? []) {
|
|
148
|
-
const idx = tc.index;
|
|
149
|
-
if (!toolCallBufs[idx])
|
|
150
|
-
toolCallBufs[idx] = { id: tc.id ?? "", name: "", argsBuf: "" };
|
|
151
|
-
if (tc.function?.name)
|
|
152
|
-
toolCallBufs[idx].name += tc.function.name;
|
|
153
|
-
toolCallBufs[idx].argsBuf += tc.function?.arguments ?? "";
|
|
154
|
-
}
|
|
155
|
-
if (choice.finish_reason === "tool_calls") {
|
|
156
|
-
const toolCalls = Object.values(toolCallBufs).map(tb => ({
|
|
157
|
-
id: tb.id, name: tb.name, arguments: tb.argsBuf || "{}",
|
|
158
|
-
}));
|
|
159
|
-
this.rememberDeepSeekReplay(finalText, toolCalls, reasoningContent, nativeToolCallsFromBuffers(toolCallBufs));
|
|
160
|
-
for (const [index, tb] of Object.entries(toolCallBufs)) {
|
|
161
|
-
const idx = Number(index);
|
|
162
|
-
if (emittedToolCallIndexes.has(idx))
|
|
163
|
-
continue;
|
|
164
|
-
let args = {};
|
|
165
|
-
try {
|
|
166
|
-
args = JSON.parse(tb.argsBuf || "{}");
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
args = {};
|
|
170
|
-
}
|
|
171
|
-
emittedToolCallIndexes.add(idx);
|
|
172
|
-
yield { type: "tool_call", id: tb.id, name: tb.name, arguments: args };
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
const toolCalls = Object.values(toolCallBufs).map(tb => ({
|
|
177
|
-
id: tb.id, name: tb.name, arguments: tb.argsBuf || "{}",
|
|
178
|
-
}));
|
|
179
|
-
this.rememberDeepSeekReplay(finalText, toolCalls, reasoningContent, nativeToolCallsFromBuffers(toolCallBufs));
|
|
180
|
-
for (const [index, tb] of Object.entries(toolCallBufs)) {
|
|
181
|
-
const idx = Number(index);
|
|
182
|
-
if (emittedToolCallIndexes.has(idx))
|
|
183
|
-
continue;
|
|
184
|
-
let args = {};
|
|
185
|
-
try {
|
|
186
|
-
args = JSON.parse(tb.argsBuf || "{}");
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
args = {};
|
|
190
|
-
}
|
|
191
|
-
emittedToolCallIndexes.add(idx);
|
|
192
|
-
yield { type: "tool_call", id: tb.id, name: tb.name, arguments: args };
|
|
193
|
-
}
|
|
194
|
-
if (totalTokens > 0)
|
|
195
|
-
yield { type: "usage", totalTokens, inputTokens, outputTokens, ...(cacheReadTokens > 0 ? { cacheReadInputTokens: cacheReadTokens } : {}) };
|
|
79
|
+
rememberCompleteReplay(content, toolCalls, r) {
|
|
80
|
+
this.rememberDeepSeekReplay(content, toolCalls, r.reasoningContent, r.nativeToolCalls);
|
|
81
|
+
}
|
|
82
|
+
rememberStreamReplay(content, toolCalls, r) {
|
|
83
|
+
this.rememberDeepSeekReplay(content, toolCalls, r.reasoningContent, r.nativeToolCalls);
|
|
196
84
|
}
|
|
197
85
|
rememberDeepSeekReplay(content, toolCalls, reasoningContent, nativeToolCalls) {
|
|
198
86
|
if (typeof reasoningContent !== "string" || !reasoningContent.trim())
|
|
@@ -207,10 +95,3 @@ export class DeepSeekProvider extends OpenAIChatProvider {
|
|
|
207
95
|
});
|
|
208
96
|
}
|
|
209
97
|
}
|
|
210
|
-
function nativeToolCallsFromBuffers(toolCallBufs) {
|
|
211
|
-
return Object.values(toolCallBufs).map(tb => ({
|
|
212
|
-
id: tb.id,
|
|
213
|
-
type: "function",
|
|
214
|
-
function: { name: tb.name, arguments: tb.argsBuf || "{}" },
|
|
215
|
-
}));
|
|
216
|
-
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LLMProvider } from "../types.js";
|
|
2
|
+
/** Options for a backend provider factory. `protocol` only applies to backends with both wires. */
|
|
3
|
+
export interface BackendProviderOptions {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
/** Override the endpoint base URL (defaults to the backend's profile for the chosen protocol). */
|
|
7
|
+
baseURL?: string;
|
|
8
|
+
retry?: {
|
|
9
|
+
maxRetries: number;
|
|
10
|
+
baseDelay: number;
|
|
11
|
+
};
|
|
12
|
+
/** Wire protocol for dual-protocol backends. Defaults per backend (see each factory). */
|
|
13
|
+
protocol?: "openai" | "anthropic";
|
|
14
|
+
}
|
|
15
|
+
/** DeepSeek. Defaults to the OpenAI-compatible wire (richer reasoning-replay handling). */
|
|
16
|
+
export declare function deepseek(o: BackendProviderOptions): LLMProvider;
|
|
17
|
+
/** Moonshot Kimi. Defaults to the OpenAI-compatible wire. */
|
|
18
|
+
export declare function kimi(o: BackendProviderOptions): LLMProvider;
|
|
19
|
+
/** Alibaba Qwen / DashScope. Defaults to the OpenAI-compatible (DashScope) wire. */
|
|
20
|
+
export declare function qwen(o: BackendProviderOptions): LLMProvider;
|
|
21
|
+
/** Zhipu GLM. Defaults to the OpenAI-compatible wire. */
|
|
22
|
+
export declare function glm(o: BackendProviderOptions): LLMProvider;
|
|
23
|
+
/** MiniMax. Defaults to the Anthropic-compatible wire (the primary M2.x path). */
|
|
24
|
+
export declare function minimax(o: BackendProviderOptions): LLMProvider;
|
|
25
|
+
/** Google Gemini (single wire). */
|
|
26
|
+
export declare function gemini(o: Omit<BackendProviderOptions, "protocol">): LLMProvider;
|
|
27
|
+
/** Local Ollama (single wire, no API key). */
|
|
28
|
+
export declare function ollama(o?: {
|
|
29
|
+
model?: string;
|
|
30
|
+
baseURL?: string;
|
|
31
|
+
}): LLMProvider;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PROVIDER_REGISTRY } from "./registry.js";
|
|
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
|
+
}
|
|
6
|
+
/** DeepSeek. Defaults to the OpenAI-compatible wire (richer reasoning-replay handling). */
|
|
7
|
+
export function deepseek(o) {
|
|
8
|
+
return build("deepseek", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
9
|
+
}
|
|
10
|
+
/** Moonshot Kimi. Defaults to the OpenAI-compatible wire. */
|
|
11
|
+
export function kimi(o) {
|
|
12
|
+
return build("kimi", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
13
|
+
}
|
|
14
|
+
/** Alibaba Qwen / DashScope. Defaults to the OpenAI-compatible (DashScope) wire. */
|
|
15
|
+
export function qwen(o) {
|
|
16
|
+
return build("qwen", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
17
|
+
}
|
|
18
|
+
/** Zhipu GLM. Defaults to the OpenAI-compatible wire. */
|
|
19
|
+
export function glm(o) {
|
|
20
|
+
return build("glm", o.protocol === "anthropic" ? "anthropic-messages" : "openai-chat", o);
|
|
21
|
+
}
|
|
22
|
+
/** MiniMax. Defaults to the Anthropic-compatible wire (the primary M2.x path). */
|
|
23
|
+
export function minimax(o) {
|
|
24
|
+
return build("minimax", o.protocol === "openai" ? "openai-chat" : "anthropic-messages", o);
|
|
25
|
+
}
|
|
26
|
+
/** Google Gemini (single wire). */
|
|
27
|
+
export function gemini(o) {
|
|
28
|
+
return PROVIDER_REGISTRY["gemini:gemini"](o.apiKey, o.model, o.retry, o.baseURL);
|
|
29
|
+
}
|
|
30
|
+
/** Local Ollama (single wire, no API key). */
|
|
31
|
+
export function ollama(o = {}) {
|
|
32
|
+
return new OllamaProvider(o.model, o.baseURL);
|
|
33
|
+
}
|
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?: {
|
package/dist/providers/glm.js
CHANGED
|
@@ -1,31 +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
|
-
"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 {
|
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?: {
|