@deepstrike/sdk 0.2.52 → 0.2.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -28
- package/dist/agent-ir.d.ts +103 -0
- package/dist/agent-ir.js +134 -0
- package/dist/agent.d.ts +67 -0
- package/dist/agent.js +36 -0
- package/dist/collaboration/harness.js +1 -1
- package/dist/collaboration/modes/creator-verifier.d.ts +2 -7
- package/dist/collaboration/modes/creator-verifier.js +4 -6
- package/dist/collaboration/pool.d.ts +8 -20
- package/dist/collaboration/pool.js +27 -97
- package/dist/compat/anthropic/mcp.d.ts +15 -0
- package/dist/compat/anthropic/mcp.js +10 -0
- package/dist/compat/openai/agent.d.ts +34 -0
- package/dist/compat/openai/agent.js +24 -0
- package/dist/governance.d.ts +1 -17
- package/dist/governance.js +1 -34
- package/dist/guardrail.d.ts +6 -0
- package/dist/guardrail.js +1 -0
- package/dist/handoff-target.d.ts +12 -0
- package/dist/handoff-target.js +1 -0
- package/dist/harness/manifest.js +0 -4
- package/dist/index.d.ts +19 -7
- package/dist/index.js +8 -5
- package/dist/kernel.d.ts +2 -20
- package/dist/knowledge/public.d.ts +29 -0
- package/dist/knowledge/public.js +1 -0
- package/dist/mcp-server.d.ts +28 -0
- package/dist/mcp-server.js +1 -0
- package/dist/memory/agent.d.ts +2 -2
- package/dist/memory/agent.js +2 -2
- package/dist/memory/durable.d.ts +16 -0
- package/dist/memory/durable.js +46 -0
- package/dist/memory/in-memory-store.d.ts +9 -7
- package/dist/memory/in-memory-store.js +8 -2
- package/dist/memory/protocols.d.ts +22 -4
- package/dist/memory/public.d.ts +4 -3
- package/dist/memory/public.js +3 -2
- package/dist/os/public.d.ts +1 -1
- package/dist/os/public.js +1 -1
- package/dist/providers/anthropic-adapter.d.ts +59 -0
- package/dist/providers/anthropic-adapter.js +530 -0
- package/dist/providers/anthropic-compatible.d.ts +2 -3
- package/dist/providers/anthropic-compatible.js +8 -5
- package/dist/providers/anthropic.d.ts +20 -23
- package/dist/providers/anthropic.js +176 -395
- package/dist/providers/base.d.ts +2 -2
- package/dist/providers/base.js +50 -8
- package/dist/providers/capability-router.d.ts +29 -0
- package/dist/providers/capability-router.js +43 -0
- package/dist/providers/catalog.d.ts +16 -4
- package/dist/providers/catalog.js +112 -36
- package/dist/providers/content-normalization.d.ts +57 -0
- package/dist/providers/content-normalization.js +238 -0
- package/dist/providers/content-policy.d.ts +16 -0
- package/dist/providers/content-policy.js +39 -0
- package/dist/providers/credentials.d.ts +83 -0
- package/dist/providers/credentials.js +190 -0
- package/dist/providers/endpoints.d.ts +137 -0
- package/dist/providers/endpoints.js +128 -0
- package/dist/providers/factories.js +25 -9
- package/dist/providers/gemini-adapter.d.ts +33 -0
- package/dist/providers/gemini-adapter.js +264 -0
- package/dist/providers/gemini.d.ts +16 -3
- package/dist/providers/gemini.js +97 -195
- package/dist/providers/model-catalog.d.ts +37 -0
- package/dist/providers/model-catalog.js +62 -0
- package/dist/providers/model-registry.d.ts +119 -0
- package/dist/providers/model-registry.js +379 -0
- package/dist/providers/ollama-adapter.d.ts +65 -0
- package/dist/providers/ollama-adapter.js +188 -0
- package/dist/providers/ollama.d.ts +9 -4
- package/dist/providers/ollama.js +96 -109
- package/dist/providers/openai-chat-dialects.d.ts +154 -0
- package/dist/providers/openai-chat-dialects.js +179 -0
- package/dist/providers/openai-chat.d.ts +46 -18
- package/dist/providers/openai-chat.js +416 -51
- package/dist/providers/openai-responses-adapter.d.ts +42 -0
- package/dist/providers/openai-responses-adapter.js +343 -0
- package/dist/providers/openai-responses.d.ts +19 -33
- package/dist/providers/openai-responses.js +164 -264
- package/dist/providers/openai.d.ts +29 -76
- package/dist/providers/openai.js +195 -292
- package/dist/providers/protocol-adapter.d.ts +39 -0
- package/dist/providers/protocol-adapter.js +13 -0
- package/dist/providers/protocol-capabilities.d.ts +34 -0
- package/dist/providers/protocol-capabilities.js +44 -0
- package/dist/providers/provider-error.d.ts +31 -0
- package/dist/providers/provider-error.js +153 -0
- package/dist/providers/public.d.ts +26 -3
- package/dist/providers/public.js +13 -1
- package/dist/providers/registry.d.ts +7 -6
- package/dist/providers/registry.js +47 -20
- package/dist/providers/request-plan.d.ts +89 -0
- package/dist/providers/request-plan.js +199 -0
- package/dist/providers/usage-normalizer.d.ts +48 -0
- package/dist/providers/usage-normalizer.js +139 -0
- package/dist/providers/vendor-profiles.d.ts +2 -15
- package/dist/providers/vendor-profiles.js +14 -60
- package/dist/runtime/canonical-kernel-step.d.ts +1 -2
- package/dist/runtime/canonical-kernel-step.js +47 -12
- package/dist/runtime/context-policy.d.ts +10 -12
- package/dist/runtime/context-policy.js +6 -8
- package/dist/runtime/durable-content.d.ts +50 -0
- package/dist/runtime/durable-content.js +159 -0
- package/dist/runtime/execution-plane.d.ts +2 -2
- package/dist/runtime/execution-plane.js +2 -2
- package/dist/runtime/kernel-event-log.js +0 -1
- package/dist/runtime/kernel-step.d.ts +0 -1
- package/dist/runtime/kernel-step.js +4 -2
- package/dist/runtime/mcp-proxy-plane.d.ts +25 -1
- package/dist/runtime/mcp-proxy-plane.js +44 -6
- package/dist/runtime/output-schema.d.ts +1 -2
- package/dist/runtime/provider-replay.d.ts +5 -1
- package/dist/runtime/provider-replay.js +26 -27
- package/dist/runtime/reactive-session.d.ts +1 -1
- package/dist/runtime/reactive-session.js +2 -3
- package/dist/runtime/run-group.d.ts +1 -1
- package/dist/runtime/runner.d.ts +31 -45
- package/dist/runtime/runner.js +178 -63
- package/dist/runtime/session-log.d.ts +8 -1
- package/dist/runtime/session-log.js +42 -2
- package/dist/runtime/session-repair.d.ts +1 -1
- package/dist/runtime/session-repair.js +1 -1
- package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
- package/dist/runtime/sub-agent-orchestrator.js +8 -11
- package/dist/runtime/workflow-control-flow.d.ts +0 -4
- package/dist/runtime/workflow-control-flow.js +0 -16
- package/dist/session.d.ts +11 -0
- package/dist/session.js +1 -0
- package/dist/skill.d.ts +17 -0
- package/dist/skill.js +16 -0
- package/dist/skills/loader.d.ts +3 -0
- package/dist/tools/errors.d.ts +1 -3
- package/dist/tools/errors.js +1 -3
- package/dist/tools/index.d.ts +3 -0
- package/dist/types/agent.d.ts +21 -9
- package/dist/types/agent.js +30 -4
- package/dist/types.d.ts +135 -17
- package/package.json +4 -4
- package/dist/providers/deepseek.d.ts +0 -46
- package/dist/providers/deepseek.js +0 -97
- package/dist/providers/glm.d.ts +0 -25
- package/dist/providers/glm.js +0 -48
- package/dist/providers/kimi.d.ts +0 -23
- package/dist/providers/kimi.js +0 -30
- package/dist/providers/minimax.d.ts +0 -49
- package/dist/providers/minimax.js +0 -98
- package/dist/providers/profiles.d.ts +0 -1992
- package/dist/providers/profiles.js +0 -796
- package/dist/providers/qwen.d.ts +0 -38
- package/dist/providers/qwen.js +0 -97
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { normalizeCanonicalContext } from "./content-normalization.js";
|
|
2
|
+
import { normalizeToolCall, UnsupportedModalityError } from "./base.js";
|
|
3
|
+
import { normalizeOpenAIUsage } from "./usage-normalizer.js";
|
|
4
|
+
import { ProtocolResponseError, } from "./protocol-adapter.js";
|
|
5
|
+
import { OPENAI_RESPONSES_PROTOCOL_CAPABILITIES } from "./protocol-capabilities.js";
|
|
6
|
+
function numberField(raw, field) {
|
|
7
|
+
const value = raw[field];
|
|
8
|
+
if (value === undefined || value === null)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
11
|
+
throw new ProtocolResponseError("openai-responses", `usage.${field} must be a non-negative safe integer`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function cacheReadTokens(usage) {
|
|
16
|
+
const inputDetails = usage.input_tokens_details;
|
|
17
|
+
if (inputDetails === undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (!inputDetails || typeof inputDetails !== "object" || Array.isArray(inputDetails)) {
|
|
20
|
+
throw new ProtocolResponseError("openai-responses", "usage.input_tokens_details must be an object");
|
|
21
|
+
}
|
|
22
|
+
return numberField(inputDetails, "cached_tokens");
|
|
23
|
+
}
|
|
24
|
+
function toolResultOutput(result) {
|
|
25
|
+
const output = [];
|
|
26
|
+
for (const block of result.blocks) {
|
|
27
|
+
if (block.type === "text") {
|
|
28
|
+
output.push({ type: "input_text", text: block.text });
|
|
29
|
+
}
|
|
30
|
+
else if (block.type === "image") {
|
|
31
|
+
if (block.source.kind === "base64") {
|
|
32
|
+
output.push({
|
|
33
|
+
type: "input_image",
|
|
34
|
+
image_url: `data:${block.mediaType ?? "image/png"};base64,${block.source.data}`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else if (block.source.kind === "url") {
|
|
38
|
+
output.push({ type: "input_image", image_url: block.source.url });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
output.push({ type: "input_text", text: "[image]" });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
output.push({ type: "input_text", text: `[${block.type}]` });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result.contentForm !== "blocks" && output.length === 1 && output[0].type === "input_text"
|
|
49
|
+
? String(output[0].text ?? "")
|
|
50
|
+
: output;
|
|
51
|
+
}
|
|
52
|
+
function messageContent(message) {
|
|
53
|
+
const content = [];
|
|
54
|
+
for (const block of message.blocks) {
|
|
55
|
+
if (block.type === "tool_result")
|
|
56
|
+
continue;
|
|
57
|
+
if (block.type === "text") {
|
|
58
|
+
content.push({ type: "input_text", text: block.text });
|
|
59
|
+
}
|
|
60
|
+
else if (block.type === "image") {
|
|
61
|
+
const imageUrl = block.source.kind === "url"
|
|
62
|
+
? block.source.url
|
|
63
|
+
: block.source.kind === "base64"
|
|
64
|
+
? `data:${block.mediaType ?? "image/png"};base64,${block.source.data}`
|
|
65
|
+
: undefined;
|
|
66
|
+
if (imageUrl) {
|
|
67
|
+
content.push({
|
|
68
|
+
type: "input_image",
|
|
69
|
+
detail: String(block.providerOptions?.openai_detail ?? "auto"),
|
|
70
|
+
image_url: imageUrl,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (block.type === "file") {
|
|
75
|
+
if (block.source.kind === "fileId") {
|
|
76
|
+
content.push({ type: "input_file", file_id: block.source.id });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw new UnsupportedModalityError("file source", "openai-responses");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (block.type === "audio") {
|
|
83
|
+
throw new UnsupportedModalityError("audio", "openai-responses");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return message.contentForm !== "blocks" && content.length === 1 && content[0].type === "input_text"
|
|
87
|
+
? String(content[0].text ?? "")
|
|
88
|
+
: content;
|
|
89
|
+
}
|
|
90
|
+
function hasMessageContent(message) {
|
|
91
|
+
return message.blocks.some(block => block.type !== "tool_result" && (block.type !== "text" || block.text.length > 0));
|
|
92
|
+
}
|
|
93
|
+
function appendMessage(input, message) {
|
|
94
|
+
if (message.role === "assistant" && message.toolCalls?.length) {
|
|
95
|
+
if (hasMessageContent(message)) {
|
|
96
|
+
input.push({ role: "assistant", content: messageContent(message) });
|
|
97
|
+
}
|
|
98
|
+
for (const call of message.toolCalls) {
|
|
99
|
+
input.push({
|
|
100
|
+
type: "function_call",
|
|
101
|
+
call_id: call.id,
|
|
102
|
+
name: call.name,
|
|
103
|
+
arguments: call.arguments,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (message.role === "tool") {
|
|
109
|
+
for (const block of message.blocks) {
|
|
110
|
+
if (block.type !== "tool_result")
|
|
111
|
+
continue;
|
|
112
|
+
input.push({
|
|
113
|
+
type: "function_call_output",
|
|
114
|
+
call_id: block.callId,
|
|
115
|
+
output: toolResultOutput(block),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
input.push({ role: message.role, content: messageContent(message) });
|
|
121
|
+
}
|
|
122
|
+
function canonicalInputItems(context, state) {
|
|
123
|
+
const input = [];
|
|
124
|
+
const turns = state?.previousResponseId
|
|
125
|
+
? context.turns.slice(state.coveredMessageCount)
|
|
126
|
+
: context.turns;
|
|
127
|
+
for (const message of turns)
|
|
128
|
+
appendMessage(input, message);
|
|
129
|
+
if (context.stateTurn)
|
|
130
|
+
appendMessage(input, context.stateTurn);
|
|
131
|
+
return input;
|
|
132
|
+
}
|
|
133
|
+
function requestExtensions(extensions) {
|
|
134
|
+
const blocked = new Set([
|
|
135
|
+
"model", "input", "instructions", "tools", "stream", "previous_response_id",
|
|
136
|
+
"web_search", "builtin_tools", "__deepstrikeThinkingEnabled", "degradeMissingReasoningReplay",
|
|
137
|
+
]);
|
|
138
|
+
return Object.fromEntries(Object.entries(extensions).filter(([key]) => !blocked.has(key)));
|
|
139
|
+
}
|
|
140
|
+
function builtinTools(extensions) {
|
|
141
|
+
const output = [];
|
|
142
|
+
if (extensions.web_search) {
|
|
143
|
+
output.push(typeof extensions.web_search === "object"
|
|
144
|
+
? { type: "web_search", ...extensions.web_search }
|
|
145
|
+
: { type: "web_search" });
|
|
146
|
+
}
|
|
147
|
+
if (Array.isArray(extensions.builtin_tools)) {
|
|
148
|
+
output.push(...extensions.builtin_tools);
|
|
149
|
+
}
|
|
150
|
+
return output;
|
|
151
|
+
}
|
|
152
|
+
function decodeOutput(output) {
|
|
153
|
+
let content = "";
|
|
154
|
+
const toolCalls = [];
|
|
155
|
+
for (const item of output) {
|
|
156
|
+
if (item.type === "message") {
|
|
157
|
+
for (const part of item.content ?? []) {
|
|
158
|
+
if (part.type === "output_text")
|
|
159
|
+
content += String(part.text ?? "");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (item.type === "function_call") {
|
|
163
|
+
const call = normalizeToolCall(String(item.call_id ?? item.id ?? ""), String(item.name ?? ""), item.arguments ?? "{}");
|
|
164
|
+
if (call)
|
|
165
|
+
toolCalls.push(call);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { content, toolCalls };
|
|
169
|
+
}
|
|
170
|
+
export class OpenAIResponsesAdapter {
|
|
171
|
+
protocol = "openai-responses";
|
|
172
|
+
protocolCapabilities = OPENAI_RESPONSES_PROTOCOL_CAPABILITIES;
|
|
173
|
+
buildRequest(input, state) {
|
|
174
|
+
const functionTools = this.buildTools(input.tools);
|
|
175
|
+
const tools = [...functionTools, ...builtinTools(input.extensions)];
|
|
176
|
+
return {
|
|
177
|
+
params: {
|
|
178
|
+
...requestExtensions(input.extensions),
|
|
179
|
+
model: input.resolved.identity.modelId,
|
|
180
|
+
input: canonicalInputItems(input.context, state),
|
|
181
|
+
...(input.context.systemText ? { instructions: input.context.systemText } : {}),
|
|
182
|
+
...(state?.previousResponseId ? { previous_response_id: state.previousResponseId } : {}),
|
|
183
|
+
...(tools.length ? { tools } : {}),
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
decodeComplete(raw, _input) {
|
|
188
|
+
const decoded = decodeOutput(raw.output ?? []);
|
|
189
|
+
const usage = raw.usage && typeof raw.usage === "object"
|
|
190
|
+
? raw.usage
|
|
191
|
+
: undefined;
|
|
192
|
+
if (usage)
|
|
193
|
+
this.normalizeUsage(usage);
|
|
194
|
+
const tokenCount = usage
|
|
195
|
+
? numberField(usage, "output_tokens") ?? numberField(usage, "total_tokens")
|
|
196
|
+
: undefined;
|
|
197
|
+
return {
|
|
198
|
+
message: {
|
|
199
|
+
role: "assistant",
|
|
200
|
+
content: decoded.content,
|
|
201
|
+
toolCalls: decoded.toolCalls,
|
|
202
|
+
...(tokenCount !== undefined ? { tokenCount } : {}),
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
createStreamState(input, _state) {
|
|
207
|
+
return { input: input.input, functionCalls: new Map() };
|
|
208
|
+
}
|
|
209
|
+
pushStreamChunk(chunk, state) {
|
|
210
|
+
const events = [];
|
|
211
|
+
let runStatePatch;
|
|
212
|
+
if (chunk.type === "response.output_text.delta") {
|
|
213
|
+
events.push({ type: "text_delta", delta: chunk.delta });
|
|
214
|
+
}
|
|
215
|
+
else if (chunk.type === "response.output_item.added" && chunk.item.type === "function_call") {
|
|
216
|
+
state.functionCalls.set(chunk.output_index, {
|
|
217
|
+
id: chunk.item.call_id,
|
|
218
|
+
name: chunk.item.name,
|
|
219
|
+
argsBuffer: chunk.item.arguments ?? "",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else if (chunk.type === "response.function_call_arguments.delta") {
|
|
223
|
+
const call = state.functionCalls.get(chunk.output_index);
|
|
224
|
+
if (call)
|
|
225
|
+
call.argsBuffer += chunk.delta;
|
|
226
|
+
}
|
|
227
|
+
else if (chunk.type === "response.function_call_arguments.done") {
|
|
228
|
+
const call = state.functionCalls.get(chunk.output_index);
|
|
229
|
+
if (call)
|
|
230
|
+
call.argsBuffer = chunk.arguments;
|
|
231
|
+
}
|
|
232
|
+
else if (chunk.type === "response.output_item.done" && chunk.item.type === "function_call") {
|
|
233
|
+
const call = state.functionCalls.get(chunk.output_index) ?? {
|
|
234
|
+
id: chunk.item.call_id,
|
|
235
|
+
name: chunk.item.name,
|
|
236
|
+
argsBuffer: chunk.item.arguments ?? "{}",
|
|
237
|
+
};
|
|
238
|
+
let args = {};
|
|
239
|
+
try {
|
|
240
|
+
args = JSON.parse(call.argsBuffer || "{}");
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
args = {};
|
|
244
|
+
}
|
|
245
|
+
events.push({ type: "tool_call", id: call.id, name: call.name, arguments: args });
|
|
246
|
+
}
|
|
247
|
+
else if (chunk.type === "response.completed" || chunk.type === "response.incomplete") {
|
|
248
|
+
const response = chunk.response;
|
|
249
|
+
runStatePatch = {
|
|
250
|
+
previousResponseId: String(response.id),
|
|
251
|
+
coveredMessageCount: state.input.context.turns.length + 1,
|
|
252
|
+
};
|
|
253
|
+
const usage = response.usage;
|
|
254
|
+
if (usage) {
|
|
255
|
+
const totalTokens = numberField(usage, "total_tokens");
|
|
256
|
+
const providerUsage = this.normalizeUsage(usage);
|
|
257
|
+
const cacheReadInputTokens = cacheReadTokens(usage);
|
|
258
|
+
const inputTokens = numberField(usage, "input_tokens");
|
|
259
|
+
const outputTokens = numberField(usage, "output_tokens");
|
|
260
|
+
const rawStopReason = typeof response.incomplete_details?.reason === "string"
|
|
261
|
+
? response.incomplete_details.reason
|
|
262
|
+
: undefined;
|
|
263
|
+
const stopReason = this.normalizeStopReason(rawStopReason);
|
|
264
|
+
if (totalTokens && totalTokens > 0) {
|
|
265
|
+
events.push({
|
|
266
|
+
type: "usage",
|
|
267
|
+
totalTokens,
|
|
268
|
+
...(inputTokens ? { inputTokens } : {}),
|
|
269
|
+
...(outputTokens ? { outputTokens } : {}),
|
|
270
|
+
...(cacheReadInputTokens ? { cacheReadInputTokens } : {}),
|
|
271
|
+
...(providerUsage?.cacheTelemetryStatus
|
|
272
|
+
? { cacheTelemetryStatus: providerUsage.cacheTelemetryStatus }
|
|
273
|
+
: {}),
|
|
274
|
+
...(providerUsage?.cacheTelemetrySource
|
|
275
|
+
? { cacheTelemetrySource: providerUsage.cacheTelemetrySource }
|
|
276
|
+
: {}),
|
|
277
|
+
...(providerUsage && (inputTokens || outputTokens) ? { providerUsage } : {}),
|
|
278
|
+
...(stopReason ? { stopReason } : {}),
|
|
279
|
+
...(rawStopReason ? { rawStopReason } : {}),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return { events, ...(runStatePatch ? { runStatePatch } : {}) };
|
|
285
|
+
}
|
|
286
|
+
finishStream(_state) {
|
|
287
|
+
return { events: [] };
|
|
288
|
+
}
|
|
289
|
+
normalizeUsage(raw) {
|
|
290
|
+
if (raw === undefined || raw === null)
|
|
291
|
+
return undefined;
|
|
292
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
293
|
+
throw new ProtocolResponseError("openai-responses", "usage must be an object");
|
|
294
|
+
}
|
|
295
|
+
const usage = raw;
|
|
296
|
+
const inputTokens = numberField(usage, "input_tokens");
|
|
297
|
+
const outputTokens = numberField(usage, "output_tokens");
|
|
298
|
+
numberField(usage, "total_tokens");
|
|
299
|
+
const outputDetails = usage.output_tokens_details;
|
|
300
|
+
if (outputDetails !== undefined && (!outputDetails || typeof outputDetails !== "object" || Array.isArray(outputDetails))) {
|
|
301
|
+
throw new ProtocolResponseError("openai-responses", "usage.output_tokens_details must be an object");
|
|
302
|
+
}
|
|
303
|
+
cacheReadTokens(usage);
|
|
304
|
+
if (outputDetails)
|
|
305
|
+
numberField(outputDetails, "reasoning_tokens");
|
|
306
|
+
if (inputTokens === undefined && outputTokens === undefined)
|
|
307
|
+
return undefined;
|
|
308
|
+
return normalizeOpenAIUsage(usage);
|
|
309
|
+
}
|
|
310
|
+
normalizeStopReason(raw) {
|
|
311
|
+
if (raw === undefined)
|
|
312
|
+
return undefined;
|
|
313
|
+
if (raw === "max_output_tokens")
|
|
314
|
+
return "max_tokens";
|
|
315
|
+
if (raw === "content_filter")
|
|
316
|
+
return "content_filter";
|
|
317
|
+
return "other";
|
|
318
|
+
}
|
|
319
|
+
// Published compatibility helpers retained while internally routing through canonical input.
|
|
320
|
+
buildTools(tools) {
|
|
321
|
+
return tools.map(tool => ({
|
|
322
|
+
type: "function",
|
|
323
|
+
name: tool.name,
|
|
324
|
+
description: tool.description,
|
|
325
|
+
parameters: JSON.parse(tool.parameters),
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
buildInstructions(context) {
|
|
329
|
+
return context.systemText || undefined;
|
|
330
|
+
}
|
|
331
|
+
buildInput(context, state) {
|
|
332
|
+
return canonicalInputItems(normalizeCanonicalContext(context), state);
|
|
333
|
+
}
|
|
334
|
+
decodeOutput(output) {
|
|
335
|
+
return decodeOutput(output);
|
|
336
|
+
}
|
|
337
|
+
builtinTools(extensions) {
|
|
338
|
+
return builtinTools(extensions ?? {});
|
|
339
|
+
}
|
|
340
|
+
requestExtensions(extensions) {
|
|
341
|
+
return requestExtensions(extensions ?? {});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
@@ -1,29 +1,11 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
-
import type { Message, ProviderRunState, RenderedContext, StreamEvent, ToolSchema
|
|
2
|
+
import type { LLMProvider, Message, PromptMeasurement, ProviderRunState, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
|
|
3
3
|
import { CircuitBreaker } from "./base.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
buildTools(tools: ToolSchema[]): {
|
|
10
|
-
type: "function";
|
|
11
|
-
name: string;
|
|
12
|
-
description: string;
|
|
13
|
-
parameters: any;
|
|
14
|
-
}[];
|
|
15
|
-
buildInstructions(context: RenderedContext): string | undefined;
|
|
16
|
-
buildInput(context: RenderedContext, state?: OpenAIResponsesRunState): Array<Record<string, unknown>>;
|
|
17
|
-
decodeOutput(output: Array<Record<string, unknown>>): {
|
|
18
|
-
content: string;
|
|
19
|
-
toolCalls: Array<{
|
|
20
|
-
id: string;
|
|
21
|
-
name: string;
|
|
22
|
-
arguments: string;
|
|
23
|
-
}>;
|
|
24
|
-
};
|
|
25
|
-
private buildMessageContent;
|
|
26
|
-
}
|
|
4
|
+
import { type CanonicalAdapterInput } from "./content-normalization.js";
|
|
5
|
+
import { OpenAIResponsesAdapter, type OpenAIResponsesRunState } from "./openai-responses-adapter.js";
|
|
6
|
+
export { OpenAIResponsesAdapter } from "./openai-responses-adapter.js";
|
|
7
|
+
export type { OpenAIResponsesRequestPlan, OpenAIResponsesRunState, OpenAIResponsesStreamState, } from "./openai-responses-adapter.js";
|
|
8
|
+
type ResolvedOpenAIResponsesRuntime = CanonicalAdapterInput["resolved"];
|
|
27
9
|
export declare class OpenAIResponsesProvider implements LLMProvider {
|
|
28
10
|
protected readonly model: string;
|
|
29
11
|
protected client: OpenAI;
|
|
@@ -31,20 +13,24 @@ export declare class OpenAIResponsesProvider implements LLMProvider {
|
|
|
31
13
|
protected maxRetries: number;
|
|
32
14
|
protected baseDelay: number;
|
|
33
15
|
protected readonly responses: OpenAIResponsesAdapter;
|
|
16
|
+
private readonly resolvedRuntimePolicy;
|
|
17
|
+
private readonly directNativeTokenCounting;
|
|
18
|
+
private resolvedRuntime?;
|
|
34
19
|
constructor(apiKey: string, model?: string, retry?: {
|
|
35
20
|
maxRetries: number;
|
|
36
21
|
baseDelay: number;
|
|
37
|
-
}, baseURL?: string);
|
|
38
|
-
runtimePolicy():
|
|
22
|
+
}, baseURL?: string, runtimePolicy?: RuntimePolicy, authMode?: "api_key" | "bearer");
|
|
23
|
+
runtimePolicy(): RuntimePolicy;
|
|
24
|
+
bindResolvedRuntime(resolved: ResolvedOpenAIResponsesRuntime): void;
|
|
39
25
|
createRunState(): OpenAIResponsesRunState;
|
|
26
|
+
private adapterInput;
|
|
40
27
|
complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
/** spc_024-05: native preflight via the official Responses input-token count endpoint. Counts
|
|
29
|
+
* the exact create request plan (stateful `previous_response_id` continuation included) —
|
|
30
|
+
* native measurement belongs to the verified official endpoint, not the wire protocol. */
|
|
31
|
+
countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: ProviderRunState): Promise<PromptMeasurement>;
|
|
32
|
+
stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: ProviderRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
|
|
46
33
|
private builtinTools;
|
|
47
|
-
|
|
48
|
-
private allTools;
|
|
34
|
+
private requestExtensions;
|
|
49
35
|
private asRunState;
|
|
50
36
|
}
|