@diffexai/diffex 0.2.6 → 0.3.0
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/CHANGELOG.md +23 -0
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.js +89 -19
- package/dist/core/compaction/compaction.js +3 -1
- package/dist/core/model-runtime.js +3 -3
- package/dist/core/provider-composer.js +1 -1
- package/dist/core/sdk.d.ts +2 -1
- package/dist/core/sdk.js +18 -6
- package/dist/core/subagents/controller.d.ts +4 -3
- package/dist/core/subagents/controller.js +173 -37
- package/dist/core/subagents/types.d.ts +13 -0
- package/dist/core/tools/bash.d.ts +4 -0
- package/dist/core/tools/bash.js +14 -5
- package/dist/core/tools/subagents.d.ts +12 -10
- package/dist/core/tools/subagents.js +61 -49
- package/dist/node_modules/@diffexai/diffex-agent-core/distribution-components.json +4 -4
- package/dist/node_modules/@diffexai/diffex-agent-core/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-agent-core/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/dist/api/lazy.d.ts +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/dist/api/lazy.js +8 -8
- package/dist/node_modules/@diffexai/diffex-ai/dist/models.js +4 -4
- package/dist/node_modules/@diffexai/diffex-ai/dist/providers/data/.manifest.json +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/dist/providers/data/opencode.json +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/dist/providers/data/openrouter.json +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/node_modules/@diffexai/diffex-ai/distribution-components.json +3 -3
- package/dist/node_modules/@diffexai/diffex-ai/distribution-files.json +8 -8
- package/dist/node_modules/@diffexai/diffex-ai/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-client/distribution-components.json +3 -3
- package/dist/node_modules/@diffexai/diffex-client/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-client/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-harness-state/distribution-components.json +2 -2
- package/dist/node_modules/@diffexai/diffex-harness-state/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-harness-state/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-protocol/distribution-components.json +2 -2
- package/dist/node_modules/@diffexai/diffex-protocol/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-protocol/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-telemetry/distribution-components.json +2 -2
- package/dist/node_modules/@diffexai/diffex-telemetry/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-telemetry/package.json +1 -1
- package/dist/node_modules/@diffexai/diffex-tui/distribution-components.json +2 -2
- package/dist/node_modules/@diffexai/diffex-tui/distribution-files.json +1 -1
- package/dist/node_modules/@diffexai/diffex-tui/package.json +1 -1
- package/dist/utils/owned-shell-processes.d.ts +8 -0
- package/dist/utils/owned-shell-processes.js +61 -0
- package/distribution-components.json +11 -11
- package/distribution-files.json +51 -43
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/release/distribution-manifest.json +4 -4
- package/release/install-package-lock.json +5 -5
- package/release/install-package.json +2 -2
|
@@ -5,11 +5,11 @@ const spawnAgentSchema = Type.Object({
|
|
|
5
5
|
description: "Unique lowercase name for the child agent",
|
|
6
6
|
pattern: SUBAGENT_NAME_PATTERN.source,
|
|
7
7
|
}),
|
|
8
|
-
task: Type.String({ description: "
|
|
8
|
+
task: Type.String({ description: "Task for the child agent", minLength: 1 }),
|
|
9
9
|
});
|
|
10
10
|
const escalateToParentSchema = Type.Object({
|
|
11
11
|
message: Type.String({
|
|
12
|
-
description: "
|
|
12
|
+
description: "Checkpoint for the parent",
|
|
13
13
|
minLength: 1,
|
|
14
14
|
maxLength: 1_000,
|
|
15
15
|
}),
|
|
@@ -20,35 +20,36 @@ const targetSchema = Type.String({
|
|
|
20
20
|
});
|
|
21
21
|
const agentActionSchema = Type.Object({
|
|
22
22
|
target: targetSchema,
|
|
23
|
+
reason: Type.Optional(Type.String({
|
|
24
|
+
description: "Required for renew: justify against current progress, remaining work, and the goal",
|
|
25
|
+
minLength: 1,
|
|
26
|
+
})),
|
|
23
27
|
action: Type.Unsafe({
|
|
24
28
|
type: "string",
|
|
25
|
-
enum: ["message", "interrupt"],
|
|
29
|
+
enum: ["message", "interrupt", "renew"],
|
|
26
30
|
}),
|
|
27
31
|
message: Type.Optional(Type.String({ description: "Message for the child agent", minLength: 1 })),
|
|
28
32
|
wake: Type.Optional(Type.Boolean({ default: false })),
|
|
33
|
+
delivery: Type.Optional(Type.Union([Type.Literal("steer"), Type.Literal("follow_up")], {
|
|
34
|
+
description: "steer corrects current work at the next tool boundary (default); follow_up waits until the current work finishes",
|
|
35
|
+
default: "steer",
|
|
36
|
+
})),
|
|
29
37
|
}, { additionalProperties: false });
|
|
30
|
-
const
|
|
31
|
-
timeout_ms: Type.Integer({
|
|
32
|
-
description: "Maximum time to wait in milliseconds, or zero to return immediately",
|
|
33
|
-
minimum: 0,
|
|
34
|
-
}),
|
|
38
|
+
const agentStatusSchema = Type.Object({
|
|
35
39
|
targets: Type.Optional(Type.Array(targetSchema, {
|
|
36
|
-
description: "Child agent names to inspect
|
|
40
|
+
description: "Child agent names to inspect; omit to inspect all children",
|
|
37
41
|
minItems: 1,
|
|
38
42
|
uniqueItems: true,
|
|
39
43
|
})),
|
|
40
|
-
until: Type.Optional(Type.Union([Type.Literal("any"), Type.Literal("all")], {
|
|
41
|
-
description: "Wait until any or all selected agents reach a terminal status",
|
|
42
|
-
})),
|
|
43
44
|
}, { additionalProperties: false });
|
|
44
45
|
export function createEscalateToParentTool(escalate) {
|
|
45
46
|
return {
|
|
46
47
|
name: "escalate_to_parent",
|
|
47
48
|
label: "Escalate to Parent",
|
|
48
|
-
description: "Report
|
|
49
|
-
promptSnippet: "
|
|
49
|
+
description: "Report blockers, risks, contradictions, decisions, or extension needs to the parent.",
|
|
50
|
+
promptSnippet: "Escalate issues or request an extension",
|
|
50
51
|
promptGuidelines: [
|
|
51
|
-
"
|
|
52
|
+
"Include current progress, remaining work, the goal, and the decision or extension needed. Escalate only plan-changing information; omit tool logs. Still provide a complete final response.",
|
|
52
53
|
],
|
|
53
54
|
parameters: escalateToParentSchema,
|
|
54
55
|
executionMode: "parallel",
|
|
@@ -67,19 +68,16 @@ export function createEscalateToParentTool(escalate) {
|
|
|
67
68
|
},
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
|
-
function
|
|
71
|
+
function assertAgentStatusRequest(request) {
|
|
71
72
|
if (typeof request !== "object" || request === null || Array.isArray(request)) {
|
|
72
|
-
throw new Error("
|
|
73
|
+
throw new Error("Agent status request must be an object");
|
|
73
74
|
}
|
|
74
75
|
for (const key of Object.keys(request)) {
|
|
75
|
-
if (key !== "
|
|
76
|
-
throw new Error(`Unknown
|
|
76
|
+
if (key !== "targets") {
|
|
77
|
+
throw new Error(`Unknown agent status request field: ${key}`);
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
const {
|
|
80
|
-
if (!Number.isInteger(timeout_ms) || timeout_ms === undefined || timeout_ms < 0) {
|
|
81
|
-
throw new RangeError("timeout_ms must be a non-negative integer");
|
|
82
|
-
}
|
|
80
|
+
const { targets } = request;
|
|
83
81
|
if (targets !== undefined) {
|
|
84
82
|
if (!Array.isArray(targets) || targets.length === 0) {
|
|
85
83
|
throw new Error("targets must be a non-empty array");
|
|
@@ -95,19 +93,16 @@ function assertAgentsRequest(request) {
|
|
|
95
93
|
uniqueTargets.add(target);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
|
-
if (until !== undefined && until !== "any" && until !== "all") {
|
|
99
|
-
throw new Error(`Invalid agents wait condition: ${String(until)}`);
|
|
100
|
-
}
|
|
101
96
|
}
|
|
102
97
|
export function createSpawnAgentTool(spawn, assertCanSpawn = () => { }) {
|
|
103
98
|
return {
|
|
104
99
|
name: "spawn_agent",
|
|
105
100
|
label: "Spawn Agent",
|
|
106
|
-
description: "Start
|
|
107
|
-
promptSnippet: "Delegate
|
|
101
|
+
description: "Start a child on an independent task; return its name and queued status immediately.",
|
|
102
|
+
promptSnippet: "Delegate an independent task",
|
|
108
103
|
promptGuidelines: [
|
|
109
|
-
"
|
|
110
|
-
"Continue independent work while
|
|
104
|
+
"Request file references and evidence for research or audits. Assign non-overlapping file ownership for edits.",
|
|
105
|
+
"Continue independent work while children run. When only needed child work remains, end your response; the runtime keeps the task open and resumes you with child reports or results.",
|
|
111
106
|
],
|
|
112
107
|
parameters: spawnAgentSchema,
|
|
113
108
|
executionMode: "parallel",
|
|
@@ -131,12 +126,12 @@ export function createAgentActionTool(action) {
|
|
|
131
126
|
return {
|
|
132
127
|
name: "agent_action",
|
|
133
128
|
label: "Agent Action",
|
|
134
|
-
description: "
|
|
135
|
-
promptSnippet: "
|
|
129
|
+
description: "Message, wake, renew, or interrupt an existing child agent.",
|
|
130
|
+
promptSnippet: "Manage an existing child agent",
|
|
136
131
|
promptGuidelines: [
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
132
|
+
"Set wake: true to resume an idle child; steering an idle child without it fails.",
|
|
133
|
+
"Use action: 'renew' with a reason to approve an extension. Each approval adds one configured allowance (15 minutes by default) to the existing deadline, capped by the parent deadline. Waiting does not renew it.",
|
|
134
|
+
"Interrupt obsolete or misdirected work, or when a user request or material risk requires stopping. Otherwise let needed work finish.",
|
|
140
135
|
],
|
|
141
136
|
parameters: agentActionSchema,
|
|
142
137
|
executionMode: "parallel",
|
|
@@ -145,13 +140,32 @@ export function createAgentActionTool(action) {
|
|
|
145
140
|
throw new Error(`Invalid subagent name: ${request.target}`);
|
|
146
141
|
}
|
|
147
142
|
let normalized;
|
|
148
|
-
if (request.action === "
|
|
149
|
-
if (
|
|
143
|
+
if (request.action === "renew") {
|
|
144
|
+
if (!request.reason?.trim())
|
|
145
|
+
throw new Error("Lease renewal requires a justification");
|
|
146
|
+
if ("message" in request || "wake" in request || "delivery" in request)
|
|
147
|
+
throw new Error("Renew actions do not accept message fields");
|
|
148
|
+
normalized = {
|
|
149
|
+
target: request.target,
|
|
150
|
+
action: "renew",
|
|
151
|
+
reason: request.reason,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
else if ("reason" in request) {
|
|
155
|
+
throw new Error("Only renew actions accept a reason");
|
|
156
|
+
}
|
|
157
|
+
else if (request.action === "interrupt") {
|
|
158
|
+
if ("message" in request || "wake" in request || "delivery" in request) {
|
|
150
159
|
throw new Error("Interrupt actions do not accept message fields");
|
|
151
160
|
}
|
|
152
161
|
normalized = { target: request.target, action: request.action };
|
|
153
162
|
}
|
|
154
163
|
else {
|
|
164
|
+
if (request.action !== "message")
|
|
165
|
+
throw new Error(`Invalid subagent action: ${String(request.action)}`);
|
|
166
|
+
if (request.delivery !== undefined && request.delivery !== "steer" && request.delivery !== "follow_up") {
|
|
167
|
+
throw new Error("Invalid subagent message delivery");
|
|
168
|
+
}
|
|
155
169
|
const message = request.message;
|
|
156
170
|
if (message === undefined || message.trim().length === 0) {
|
|
157
171
|
throw new Error("Subagent message must be non-empty");
|
|
@@ -161,6 +175,7 @@ export function createAgentActionTool(action) {
|
|
|
161
175
|
action: request.action,
|
|
162
176
|
message,
|
|
163
177
|
wake: request.wake ?? false,
|
|
178
|
+
delivery: request.delivery ?? "steer",
|
|
164
179
|
};
|
|
165
180
|
}
|
|
166
181
|
const details = await action(normalized);
|
|
@@ -171,28 +186,25 @@ export function createAgentActionTool(action) {
|
|
|
171
186
|
},
|
|
172
187
|
};
|
|
173
188
|
}
|
|
174
|
-
export function
|
|
189
|
+
export function createAgentStatusTool(query) {
|
|
175
190
|
return {
|
|
176
|
-
name: "
|
|
177
|
-
label: "
|
|
178
|
-
description: "
|
|
179
|
-
promptSnippet: "
|
|
191
|
+
name: "agent_status",
|
|
192
|
+
label: "Agent Status",
|
|
193
|
+
description: "Immediately return child statuses and recorded output or errors.",
|
|
194
|
+
promptSnippet: "Inspect child agent status and results",
|
|
180
195
|
promptGuidelines: [
|
|
181
|
-
"
|
|
182
|
-
"
|
|
196
|
+
"Terminal results returned here are consumed and will not be delivered again automatically.",
|
|
197
|
+
"Do not repeatedly poll for completion.",
|
|
183
198
|
],
|
|
184
|
-
parameters:
|
|
199
|
+
parameters: agentStatusSchema,
|
|
185
200
|
executionMode: "parallel",
|
|
186
201
|
execute: async (_toolCallId, request, signal) => {
|
|
187
|
-
|
|
202
|
+
assertAgentStatusRequest(request);
|
|
188
203
|
const result = await query({
|
|
189
|
-
timeoutMs: request.timeout_ms,
|
|
190
204
|
...(request.targets === undefined ? {} : { targets: request.targets }),
|
|
191
|
-
...(request.until === undefined ? {} : { until: request.until }),
|
|
192
205
|
...(signal === undefined ? {} : { signal }),
|
|
193
206
|
});
|
|
194
207
|
const details = Object.freeze({
|
|
195
|
-
timed_out: result.timedOut,
|
|
196
208
|
agents: Object.freeze(result.agents.map((agent) => Object.freeze({
|
|
197
209
|
name: agent.name,
|
|
198
210
|
status: agent.status,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"name": "@diffexai/diffex-agent-core",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"sourceCommit": "
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"sourceCommit": "c8cec4d3820393131eaae7b43d56ac5f75d8041a",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"portions": "Diffex contributions; Pi-derived portions retain MIT terms in LICENSE",
|
|
8
8
|
"notice": "LICENSE",
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"name": "@diffexai/diffex-ai",
|
|
13
|
-
"version": "^0.
|
|
13
|
+
"version": "^0.3.0",
|
|
14
14
|
"distribution": "resolved separately by package manager; not bundled in this npm tarball"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"name": "@diffexai/diffex-telemetry",
|
|
18
|
-
"version": "^0.
|
|
18
|
+
"version": "^0.3.0",
|
|
19
19
|
"distribution": "resolved separately by package manager; not bundled in this npm tarball"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
@@ -5,7 +5,7 @@ import { AssistantMessageEventStream } from "../utils/event-stream.ts";
|
|
|
5
5
|
* lazy module loading) behind it. Setup failures terminate the stream with an
|
|
6
6
|
* error event.
|
|
7
7
|
*/
|
|
8
|
-
export declare function lazyStream(model: Model<Api>, setup: () => Promise<AsyncIterable<AssistantMessageEvent
|
|
8
|
+
export declare function lazyStream(model: Model<Api>, setup: () => Promise<AsyncIterable<AssistantMessageEvent>>, signal?: AbortSignal): AssistantMessageEventStream;
|
|
9
9
|
/**
|
|
10
10
|
* Wraps a dynamically imported API implementation module as `ProviderStreams`.
|
|
11
11
|
* The module loads on first stream call; the host's import cache deduplicates
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
2
|
-
function createSetupErrorMessage(model, error) {
|
|
2
|
+
function createSetupErrorMessage(model, error, signal) {
|
|
3
3
|
return {
|
|
4
4
|
role: "assistant",
|
|
5
5
|
content: [],
|
|
@@ -14,7 +14,7 @@ function createSetupErrorMessage(model, error) {
|
|
|
14
14
|
totalTokens: 0,
|
|
15
15
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
16
16
|
},
|
|
17
|
-
stopReason: "error",
|
|
17
|
+
stopReason: signal?.aborted ? "aborted" : "error",
|
|
18
18
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
19
19
|
timestamp: Date.now(),
|
|
20
20
|
};
|
|
@@ -33,21 +33,21 @@ async function forwardStream(target, source) {
|
|
|
33
33
|
* lazy module loading) behind it. Setup failures terminate the stream with an
|
|
34
34
|
* error event.
|
|
35
35
|
*/
|
|
36
|
-
export function lazyStream(model, setup) {
|
|
36
|
+
export function lazyStream(model, setup, signal) {
|
|
37
37
|
const outer = new AssistantMessageEventStream();
|
|
38
38
|
setup()
|
|
39
39
|
.then((inner) => forwardStream(outer, inner))
|
|
40
40
|
.catch((error) => {
|
|
41
|
-
const message = createSetupErrorMessage(model, error);
|
|
42
|
-
outer.push({ type: "error", reason: "error", error: message });
|
|
41
|
+
const message = createSetupErrorMessage(model, error, signal);
|
|
42
|
+
outer.push({ type: "error", reason: signal?.aborted ? "aborted" : "error", error: message });
|
|
43
43
|
outer.end(message);
|
|
44
44
|
});
|
|
45
45
|
return outer;
|
|
46
46
|
}
|
|
47
47
|
export function lazyApi(load, capabilities) {
|
|
48
48
|
const api = {
|
|
49
|
-
stream: (model, context, options) => lazyStream(model, async () => (await load()).stream(model, context, options)),
|
|
50
|
-
streamSimple: (model, context, options) => lazyStream(model, async () => (await load()).streamSimple(model, context, options)),
|
|
49
|
+
stream: (model, context, options) => lazyStream(model, async () => (await load()).stream(model, context, options), options?.signal),
|
|
50
|
+
streamSimple: (model, context, options) => lazyStream(model, async () => (await load()).streamSimple(model, context, options), options?.signal),
|
|
51
51
|
};
|
|
52
52
|
if (capabilities?.fetchDeferred) {
|
|
53
53
|
api.fetchDeferred = (model, handle, options) => lazyStream(model, async () => {
|
|
@@ -55,7 +55,7 @@ export function lazyApi(load, capabilities) {
|
|
|
55
55
|
if (!implementation.fetchDeferred)
|
|
56
56
|
throw new Error("API does not support deferred responses");
|
|
57
57
|
return implementation.fetchDeferred(model, handle, options);
|
|
58
|
-
});
|
|
58
|
+
}, options?.signal);
|
|
59
59
|
}
|
|
60
60
|
if (capabilities?.cancelDeferred) {
|
|
61
61
|
api.cancelDeferred = async (model, handle, options) => {
|
|
@@ -382,7 +382,7 @@ class ModelsImpl {
|
|
|
382
382
|
const provider = this.requireProvider(model);
|
|
383
383
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
384
384
|
return provider.stream(requestModel, context, requestOptions);
|
|
385
|
-
});
|
|
385
|
+
}, options?.signal);
|
|
386
386
|
}
|
|
387
387
|
async complete(model, context, options) {
|
|
388
388
|
return this.stream(model, context, options).result();
|
|
@@ -392,7 +392,7 @@ class ModelsImpl {
|
|
|
392
392
|
const provider = this.requireProvider(model);
|
|
393
393
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
394
394
|
return provider.streamSimple(requestModel, context, requestOptions);
|
|
395
|
-
});
|
|
395
|
+
}, options?.signal);
|
|
396
396
|
}
|
|
397
397
|
async completeSimple(model, context, options) {
|
|
398
398
|
return this.streamSimple(model, context, options).result();
|
|
@@ -405,7 +405,7 @@ class ModelsImpl {
|
|
|
405
405
|
}
|
|
406
406
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
407
407
|
return provider.fetchDeferred(requestModel, handle, requestOptions);
|
|
408
|
-
}).result();
|
|
408
|
+
}, options?.signal).result();
|
|
409
409
|
}
|
|
410
410
|
async cancelDeferred(model, handle, options) {
|
|
411
411
|
const provider = this.requireProvider(model);
|
|
@@ -498,7 +498,7 @@ export function createProvider(input) {
|
|
|
498
498
|
throw new ModelsError("provider", `Provider ${input.id} does not support deferred responses for "${model.api}"`);
|
|
499
499
|
}
|
|
500
500
|
return implementation.fetchDeferred(model, handle, options);
|
|
501
|
-
});
|
|
501
|
+
}, options?.signal);
|
|
502
502
|
}
|
|
503
503
|
if (streams.some((entry) => entry.cancelDeferred !== undefined)) {
|
|
504
504
|
provider.cancelDeferred = async (model, handle, options) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":3,"generatedAt":"2026-09-
|
|
1
|
+
{"schemaVersion":3,"generatedAt":"2026-09-20T03:25:28.719Z","structureHash":"b7ce3293a6e78f937e459db51021842a9b6fe649738f23b3eddb7263fe3137ec","files":{"amazon-bedrock.json":"9d3eed9613b9b56f0c5f202a61b279a7168edf01bae6c3218a7ab28664ff80ea","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"6937a397c6c7cf654990d072734efad023b652b294b04961d43a5835d7d08156","azure-openai-responses.json":"787ba62322c46fbc69bc1fcb7c7cfc100b8f74211c72adf9766b6dbf5eae0c41","baseten.json":"c7cf9a7e7e6bee9c53005acf4706c25f954adaa64a9058535fb7e5b1d6920852","cerebras.json":"9eaa554e1b02f3665f8f63e6432d253bf81351af7c72001054dd8108aa528a52","cloudflare-ai-gateway.json":"356a2892803067a5d042c5abb87051edba46f7209589c625f8bcea8c7c5ce5c9","cloudflare-workers-ai.json":"07ef63208ff7517fd1a80962f18143e21de399640423329490b157f459ccf995","deepseek.json":"0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b","fireworks.json":"4c9055f7a2c5345b808bb561b07b227fc29148e0fb774c0ac50db2b34ab89aaf","github-copilot.json":"37cfc1da3a6814e37e14c565ed0a1e41f2eb513b10aa8f11ac18f27fa392308c","google-vertex.json":"e1631109172dc1f7d7977570420a5bb86258bdd1088427e244a2c51545c4f24d","google.json":"7619bf03edd2a7acb06a2274a14b13c3a61354288abe029a758401d4de36a8fd","groq.json":"e4728fd72e358cd8f25e9a518e9b49a521ef44523d3debe38a7db9e0663c4077","huggingface.json":"a488b6f175b382277ccf7d487f877ef0c698994576bb55d2410838bf9c8c7c41","kimi-coding.json":"9da7ea8e9eb8df5d8f73acc25d3da5b41164f522c0f09b45265b4bf104743ac1","minimax-cn.json":"65d37e55a6d9585855f94b3fb7739308d107fe248ebd9e1001d1c5d4606ad2c4","minimax.json":"c7dc5765995ae77242916430929c7cc9a782589f7e483e13f7e01663190d028e","mistral.json":"be522597b22bceeb0bb9a0ba1781647649ffd19637d0c8e67b056d7b0ec33d52","moonshotai-cn.json":"63f77de8782dce6a8d4649b6075ee04c9732863ae85561e0867871220c558bde","moonshotai.json":"2a8dfb97eb905e991c22081dc09bd4a61c05b7fa9ac0d5c72d6930f601f490f1","nvidia.json":"2ff6862206269af88a694e627c4b54753055357710adaf49ac8518d102c17407","openai-codex.json":"4a73818291987693fcb53e9e61b4be3429ffd78b3f64ea877a34c5f9928c89e1","openai.json":"6fa1954abd6c5b301620a02a57412bd60bbfdf20465b9a3eb4d113f88dfb8f7b","opencode-go.json":"31c4434316c8a1b7fcc637b25f1147dd44da946a0b932ca10fb5ac594261dad7","opencode.json":"43c5d9cc6fab109411e6ac8eebac4b9fb0b00cff844cf0eb6c1559a08586525f","openrouter.json":"a6bb9631baf0a19685c1ad0c847c6ddf848ff5c7881d5bc62cc0ffeff45ec932","qwen-token-plan-cn.json":"a50420854a624ea82155d9621cd88d6cbd7802498d28fb1fd317eb7a1bc26cc7","qwen-token-plan-individual.json":"0e1578a5c0e11d65644bb42d1d6efee5af97a55a4881d0421ab68bd970d4d4ef","qwen-token-plan.json":"24285f68b2350aa1d98ecaeafe0914bce97940fe8798eff20f2a5c6d8c26bd6f","together.json":"927c707d06f2236cdab13f14c870fb58bce0614ba7287bbcd57cc9fd66d191ed","vercel-ai-gateway.json":"03b0830a794af1bc921fb504565534bedec660fcc9482adcf56ec5fb27703e60","xai.json":"282838b0546d63106c81f1703cdf5ed31ebfe0c5f13a4bec0d590472cbbe03f2","xiaomi-token-plan-ams.json":"7ce8ed244672c45737d286ff3ca9c3a2686a5d4b2f0c5f71ab9348c14b14daf3","xiaomi-token-plan-cn.json":"684892b5fe6fa371d6040d2011c0fa33facd650d2eaf19f5dbee8efb33016200","xiaomi-token-plan-sgp.json":"b19e79b82ac4fdcb080e6d220106797504c885ed70b27fc2b3c1aa4810f32963","xiaomi.json":"810368d3828c8bb9498012a0d48639030c0c216b8c13e79da02daa515aa23448","zai-coding-cn.json":"abf4cbc22507b9d545842072b5e34bce230025fc20f7b1cc67db3782c1dc4b56","zai.json":"089af736a622b0a25e417493819f4e174884afba43235c5a1f17814057875627"}}
|