maestro-agent-sdk 0.1.26 → 0.1.27
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 +20 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/platform/config.d.ts +5 -0
- package/dist/platform/config.d.ts.map +1 -1
- package/dist/platform/config.js +9 -0
- package/dist/platform/config.js.map +1 -1
- package/dist/platform/version.d.ts +1 -1
- package/dist/platform/version.js +1 -1
- package/dist/provider.d.ts +16 -4
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +39 -4
- package/dist/provider.js.map +1 -1
- package/dist/providers/codex-auth.d.ts +149 -0
- package/dist/providers/codex-auth.d.ts.map +1 -0
- package/dist/providers/codex-auth.js +312 -0
- package/dist/providers/codex-auth.js.map +1 -0
- package/dist/providers/codex-stream.d.ts +42 -0
- package/dist/providers/codex-stream.d.ts.map +1 -0
- package/dist/providers/codex-stream.js +330 -0
- package/dist/providers/codex-stream.js.map +1 -0
- package/dist/providers/codex-translators.d.ts +105 -0
- package/dist/providers/codex-translators.d.ts.map +1 -0
- package/dist/providers/codex-translators.js +244 -0
- package/dist/providers/codex-translators.js.map +1 -0
- package/dist/providers/codex.d.ts +117 -0
- package/dist/providers/codex.d.ts.map +1 -0
- package/dist/providers/codex.js +334 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +25 -1
- package/dist/registry.js.map +1 -1
- package/package.json +17 -1
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Responses API SSE stream → Maestro `ProviderStreamChunk` adapter.
|
|
3
|
+
*
|
|
4
|
+
* The Responses API SSE protocol is event-typed (each event has a `type`
|
|
5
|
+
* field plus a `data` JSON payload). The events of interest:
|
|
6
|
+
*
|
|
7
|
+
* - `response.output_item.added` — a new top-level output item began
|
|
8
|
+
* (message | function_call | reasoning). Use to learn the item's
|
|
9
|
+
* `id` / `name` / kind before deltas start arriving.
|
|
10
|
+
* - `response.output_text.delta` — text chunk for the current message item.
|
|
11
|
+
* - `response.function_call_arguments.delta` — JSON-args chunk for the
|
|
12
|
+
* current function_call item.
|
|
13
|
+
* - `response.function_call_arguments.done` — args finalized.
|
|
14
|
+
* - `response.output_item.done` — the item is closed; carries the full
|
|
15
|
+
* completed item (with final args, content, status).
|
|
16
|
+
* - `response.reasoning_summary_text.delta` / `.done` — reasoning summary
|
|
17
|
+
* stream (only when `reasoning.summary` was enabled).
|
|
18
|
+
* - `response.completed` — terminal. Carries `response.usage` and the
|
|
19
|
+
* full output array.
|
|
20
|
+
* - `response.incomplete` / `response.failed` — terminal failures.
|
|
21
|
+
*
|
|
22
|
+
* The codex backend has a known bug where `get_final_response()` returns an
|
|
23
|
+
* empty `output` even after valid items streamed — hermes patches this with
|
|
24
|
+
* "synthesize from deltas" backfill. We do the same here: keep a parallel
|
|
25
|
+
* accumulator and use it as the source of truth for `message_complete`,
|
|
26
|
+
* ignoring the `response.completed.response.output` array.
|
|
27
|
+
*
|
|
28
|
+
* The output is the same `ProviderStreamChunk` vocabulary the agent loop
|
|
29
|
+
* already consumes for Anthropic / DeepSeek, so adding Codex requires no
|
|
30
|
+
* changes to `core/loop.ts`.
|
|
31
|
+
*/
|
|
32
|
+
// ── Public entry point ──────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Convert a Responses API SSE stream (the raw `Response.body` from `fetch`)
|
|
35
|
+
* into the maestro `ProviderStreamChunk` async iterable.
|
|
36
|
+
*
|
|
37
|
+
* Aborts when `abortSignal` fires by cancelling the underlying reader; the
|
|
38
|
+
* generator yields nothing further and any in-progress items become stale
|
|
39
|
+
* (the agent loop will reconcile on its end via the abort flag).
|
|
40
|
+
*/
|
|
41
|
+
export async function* parseCodexStream(body, abortSignal) {
|
|
42
|
+
// Per-item accumulators keyed by output_index. We can't key by
|
|
43
|
+
// `item_id` because text deltas reference `item_id` while
|
|
44
|
+
// function_call arg deltas reference `output_index` only in older
|
|
45
|
+
// backend builds — output_index is the one field both shapes ship
|
|
46
|
+
// reliably.
|
|
47
|
+
const itemsByIndex = new Map();
|
|
48
|
+
let stopReason = "end_turn";
|
|
49
|
+
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
50
|
+
// Reasoning summary lives outside the item map because it can arrive
|
|
51
|
+
// interleaved across multiple reasoning items in one turn; the loop
|
|
52
|
+
// only wants one consolidated `thinking_complete` block at the end.
|
|
53
|
+
let reasoningSummaryBuf = "";
|
|
54
|
+
let sawReasoning = false;
|
|
55
|
+
for await (const evt of parseSseFrames(body, abortSignal)) {
|
|
56
|
+
const t = evt.type ?? "";
|
|
57
|
+
// ── 1. New item begins ────────────────────────────────────────────────
|
|
58
|
+
if (t === "response.output_item.added" && typeof evt.output_index === "number" && evt.item) {
|
|
59
|
+
const kind = evt.item.type === "message"
|
|
60
|
+
? "message"
|
|
61
|
+
: evt.item.type === "function_call"
|
|
62
|
+
? "function_call"
|
|
63
|
+
: evt.item.type === "reasoning"
|
|
64
|
+
? "reasoning"
|
|
65
|
+
: "unknown";
|
|
66
|
+
itemsByIndex.set(evt.output_index, {
|
|
67
|
+
kind,
|
|
68
|
+
id: evt.item.id ?? "",
|
|
69
|
+
callId: evt.item.call_id ?? "",
|
|
70
|
+
name: evt.item.name ?? "",
|
|
71
|
+
argsBuf: "",
|
|
72
|
+
textBuf: "",
|
|
73
|
+
reasoningBuf: "",
|
|
74
|
+
toolStartEmitted: false,
|
|
75
|
+
toolCompleteEmitted: false,
|
|
76
|
+
});
|
|
77
|
+
// For tool calls we can emit `tool_use_start` immediately — `call_id`
|
|
78
|
+
// and `name` arrive in the same event. Arg deltas follow.
|
|
79
|
+
if (kind === "function_call") {
|
|
80
|
+
const entry = itemsByIndex.get(evt.output_index);
|
|
81
|
+
const id = entry.callId || entry.id;
|
|
82
|
+
if (id && entry.name && !entry.toolStartEmitted) {
|
|
83
|
+
entry.toolStartEmitted = true;
|
|
84
|
+
yield { type: "tool_use_start", id, name: entry.name };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
// ── 2. Text deltas ────────────────────────────────────────────────────
|
|
90
|
+
if (t === "response.output_text.delta" && typeof evt.delta === "string" && evt.delta.length > 0) {
|
|
91
|
+
// text_delta is fire-and-forget — the loop accumulates per-message
|
|
92
|
+
// text on its own side. We also accumulate locally so the final
|
|
93
|
+
// `message_complete` event's optional backfill has a source.
|
|
94
|
+
const entry = typeof evt.output_index === "number" ? itemsByIndex.get(evt.output_index) : undefined;
|
|
95
|
+
if (entry)
|
|
96
|
+
entry.textBuf += evt.delta;
|
|
97
|
+
yield { type: "text_delta", text: evt.delta };
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// ── 3. Function-call argument deltas ─────────────────────────────────
|
|
101
|
+
if (t === "response.function_call_arguments.delta" &&
|
|
102
|
+
typeof evt.output_index === "number") {
|
|
103
|
+
const entry = itemsByIndex.get(evt.output_index);
|
|
104
|
+
if (!entry || entry.kind !== "function_call")
|
|
105
|
+
continue;
|
|
106
|
+
const chunk = evt.delta ?? evt.arguments ?? "";
|
|
107
|
+
if (chunk.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
entry.argsBuf += chunk;
|
|
110
|
+
const id = entry.callId || entry.id;
|
|
111
|
+
if (id) {
|
|
112
|
+
yield { type: "tool_use_input_delta", id, partial_json: chunk };
|
|
113
|
+
}
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (t === "response.function_call_arguments.done" &&
|
|
117
|
+
typeof evt.output_index === "number") {
|
|
118
|
+
const entry = itemsByIndex.get(evt.output_index);
|
|
119
|
+
if (!entry || entry.kind !== "function_call")
|
|
120
|
+
continue;
|
|
121
|
+
// The .done event sometimes carries the FULL arguments string. If our
|
|
122
|
+
// accumulator is empty (no deltas arrived — codex's chatgpt backend
|
|
123
|
+
// occasionally streams the args only at completion), backfill from
|
|
124
|
+
// the .done payload.
|
|
125
|
+
if (entry.argsBuf.length === 0 && typeof evt.arguments === "string") {
|
|
126
|
+
entry.argsBuf = evt.arguments;
|
|
127
|
+
const id = entry.callId || entry.id;
|
|
128
|
+
if (id) {
|
|
129
|
+
yield { type: "tool_use_input_delta", id, partial_json: evt.arguments };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// ── 4. Reasoning summary deltas ──────────────────────────────────────
|
|
135
|
+
// Only fired when `reasoning.summary` was requested. The raw reasoning
|
|
136
|
+
// content (encrypted) arrives on the closing `output_item.done` for the
|
|
137
|
+
// reasoning item — we keep that in the entry for a potential future
|
|
138
|
+
// encrypted-replay path.
|
|
139
|
+
if (typeof t === "string" &&
|
|
140
|
+
t.startsWith("response.reasoning_summary_text") &&
|
|
141
|
+
typeof evt.delta === "string") {
|
|
142
|
+
sawReasoning = true;
|
|
143
|
+
reasoningSummaryBuf += evt.delta;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (typeof t === "string" &&
|
|
147
|
+
t.startsWith("response.reasoning_text") &&
|
|
148
|
+
typeof evt.delta === "string") {
|
|
149
|
+
sawReasoning = true;
|
|
150
|
+
reasoningSummaryBuf += evt.delta;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// ── 5. Item closed ────────────────────────────────────────────────────
|
|
154
|
+
if (t === "response.output_item.done" && typeof evt.output_index === "number") {
|
|
155
|
+
const entry = itemsByIndex.get(evt.output_index);
|
|
156
|
+
if (!entry)
|
|
157
|
+
continue;
|
|
158
|
+
if (entry.kind === "function_call" && !entry.toolCompleteEmitted) {
|
|
159
|
+
entry.toolCompleteEmitted = true;
|
|
160
|
+
const id = entry.callId || entry.id;
|
|
161
|
+
if (id && entry.name) {
|
|
162
|
+
// Backfill args from the closed item payload if our accumulator
|
|
163
|
+
// is empty (some codex builds skip the delta phase entirely).
|
|
164
|
+
if (entry.argsBuf.length === 0 && typeof evt.item?.arguments === "string") {
|
|
165
|
+
entry.argsBuf = evt.item.arguments;
|
|
166
|
+
yield {
|
|
167
|
+
type: "tool_use_input_delta",
|
|
168
|
+
id,
|
|
169
|
+
partial_json: entry.argsBuf,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
yield { type: "tool_use_complete", id, name: entry.name };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
// ── 6. Terminal events ────────────────────────────────────────────────
|
|
178
|
+
if (t === "response.completed") {
|
|
179
|
+
if (evt.response?.usage)
|
|
180
|
+
usage = mapUsage(evt.response.usage);
|
|
181
|
+
// codex's chatgpt backend sometimes returns status "incomplete" here
|
|
182
|
+
// (e.g. context cap hit). Treat the granular reason as the stop_reason
|
|
183
|
+
// so the loop sees a familiar value.
|
|
184
|
+
const status = evt.response?.status;
|
|
185
|
+
if (status === "incomplete") {
|
|
186
|
+
stopReason = mapIncompleteReason(evt.response?.incomplete_details?.reason);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
if (t === "response.incomplete") {
|
|
191
|
+
stopReason = mapIncompleteReason(evt.response?.incomplete_details?.reason);
|
|
192
|
+
if (evt.response?.usage)
|
|
193
|
+
usage = mapUsage(evt.response.usage);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (t === "response.failed") {
|
|
197
|
+
stopReason = "error";
|
|
198
|
+
if (evt.response?.usage)
|
|
199
|
+
usage = mapUsage(evt.response.usage);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
// Other event types (response.created, response.in_progress,
|
|
203
|
+
// response.content_part.added/done, etc.) carry no information the
|
|
204
|
+
// loop needs — drop silently.
|
|
205
|
+
}
|
|
206
|
+
// ── 7. Flush reasoning summary as a single thinking block ─────────────
|
|
207
|
+
// Convention matches DeepseekProvider: emit thinking BEFORE
|
|
208
|
+
// message_complete so the loop appends it to assistantBlocks alongside
|
|
209
|
+
// text + tool_use.
|
|
210
|
+
if (sawReasoning && reasoningSummaryBuf.length > 0) {
|
|
211
|
+
const block = {
|
|
212
|
+
type: "thinking",
|
|
213
|
+
thinking: reasoningSummaryBuf,
|
|
214
|
+
};
|
|
215
|
+
yield { type: "thinking_complete", block };
|
|
216
|
+
}
|
|
217
|
+
yield { type: "message_complete", stopReason, usage };
|
|
218
|
+
}
|
|
219
|
+
// ── Usage / stopReason helpers ──────────────────────────────────────────────
|
|
220
|
+
function mapUsage(u) {
|
|
221
|
+
const out = {
|
|
222
|
+
inputTokens: u.input_tokens ?? 0,
|
|
223
|
+
outputTokens: u.output_tokens ?? 0,
|
|
224
|
+
};
|
|
225
|
+
const cached = u.input_tokens_details?.cached_tokens;
|
|
226
|
+
if (typeof cached === "number")
|
|
227
|
+
out.cacheReadInputTokens = cached;
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Map a codex `response.incomplete_details.reason` value to the loose
|
|
232
|
+
* stop_reason string the agent loop / conversation log carries. The loop
|
|
233
|
+
* itself doesn't branch on the value — it just propagates it into the
|
|
234
|
+
* `result` event — but the host display layer asserts on familiar names
|
|
235
|
+
* (`max_tokens`, `end_turn`, `tool_use`), so we normalize here.
|
|
236
|
+
*/
|
|
237
|
+
function mapIncompleteReason(reason) {
|
|
238
|
+
switch (reason) {
|
|
239
|
+
case "max_output_tokens":
|
|
240
|
+
case "max_tokens":
|
|
241
|
+
return "max_tokens";
|
|
242
|
+
case "content_filter":
|
|
243
|
+
return "stop";
|
|
244
|
+
default:
|
|
245
|
+
return reason ?? "end_turn";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ── SSE framing ─────────────────────────────────────────────────────────────
|
|
249
|
+
/**
|
|
250
|
+
* Parse the raw HTTP body as an SSE stream and yield one event payload per
|
|
251
|
+
* `\n\n`-delimited frame. Honours `event: <type>` lines so the caller can
|
|
252
|
+
* dispatch on event type even though all data lines are JSON.
|
|
253
|
+
*
|
|
254
|
+
* Unlike OpenAI Chat Completions' SSE (which uses `data: [DONE]` to signal
|
|
255
|
+
* end-of-stream), the Responses API terminates with a `response.completed`
|
|
256
|
+
* (or `.failed`/`.incomplete`) event and then closes the connection — there
|
|
257
|
+
* is no `[DONE]` sentinel. We tolerate one if it shows up anyway.
|
|
258
|
+
*/
|
|
259
|
+
async function* parseSseFrames(body, abortSignal) {
|
|
260
|
+
const reader = body.getReader();
|
|
261
|
+
const decoder = new TextDecoder("utf-8");
|
|
262
|
+
let buf = "";
|
|
263
|
+
const onAbort = () => {
|
|
264
|
+
reader.cancel("aborted").catch(() => { });
|
|
265
|
+
};
|
|
266
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
267
|
+
try {
|
|
268
|
+
while (true) {
|
|
269
|
+
const { value, done } = await reader.read();
|
|
270
|
+
if (done)
|
|
271
|
+
break;
|
|
272
|
+
buf += decoder.decode(value, { stream: true });
|
|
273
|
+
let idx = buf.indexOf("\n\n");
|
|
274
|
+
while (idx >= 0) {
|
|
275
|
+
const frame = buf.slice(0, idx);
|
|
276
|
+
buf = buf.slice(idx + 2);
|
|
277
|
+
const parsed = parseOneFrame(frame);
|
|
278
|
+
if (parsed)
|
|
279
|
+
yield parsed;
|
|
280
|
+
idx = buf.indexOf("\n\n");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Tail flush — some servers don't terminate the final frame with `\n\n`.
|
|
284
|
+
if (buf.trim().length > 0) {
|
|
285
|
+
const parsed = parseOneFrame(buf);
|
|
286
|
+
if (parsed)
|
|
287
|
+
yield parsed;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
abortSignal?.removeEventListener("abort", onAbort);
|
|
292
|
+
try {
|
|
293
|
+
reader.releaseLock();
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// Reader may already be cancelled / released — ignore.
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function parseOneFrame(frame) {
|
|
301
|
+
let eventType = "";
|
|
302
|
+
const dataLines = [];
|
|
303
|
+
for (const rawLine of frame.split("\n")) {
|
|
304
|
+
const line = rawLine.trimEnd();
|
|
305
|
+
if (line.startsWith("event:")) {
|
|
306
|
+
eventType = line.slice("event:".length).trim();
|
|
307
|
+
}
|
|
308
|
+
else if (line.startsWith("data:")) {
|
|
309
|
+
dataLines.push(line.slice("data:".length).trim());
|
|
310
|
+
}
|
|
311
|
+
// Comment lines (`: keep-alive`) and id: lines are ignored.
|
|
312
|
+
}
|
|
313
|
+
if (dataLines.length === 0)
|
|
314
|
+
return undefined;
|
|
315
|
+
const dataStr = dataLines.join("");
|
|
316
|
+
if (dataStr === "[DONE]")
|
|
317
|
+
return undefined;
|
|
318
|
+
try {
|
|
319
|
+
const parsed = JSON.parse(dataStr);
|
|
320
|
+
// Prefer the event:-line type when the JSON payload omits it (some
|
|
321
|
+
// intermediate proxies strip the `type` field).
|
|
322
|
+
if (!parsed.type && eventType)
|
|
323
|
+
parsed.type = eventType;
|
|
324
|
+
return parsed;
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=codex-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-stream.js","sourceRoot":"","sources":["../../src/providers/codex-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maestro ↔ Codex Responses API format translators.
|
|
3
|
+
*
|
|
4
|
+
* The Responses API is OpenAI's newer thread-style endpoint. It speaks a
|
|
5
|
+
* different shape than Chat Completions:
|
|
6
|
+
*
|
|
7
|
+
* - Messages aren't a `messages` array — they're "input items" with
|
|
8
|
+
* polymorphic types (`message`, `function_call`, `function_call_output`,
|
|
9
|
+
* `reasoning`).
|
|
10
|
+
* - Tools live as top-level items, not inside an assistant message.
|
|
11
|
+
* - Text parts split by direction: user → `input_text`, assistant →
|
|
12
|
+
* `output_text`. Mixing them yields 400.
|
|
13
|
+
* - There is no `system` role; the instructions ride in a top-level
|
|
14
|
+
* `instructions` field on the request body.
|
|
15
|
+
*
|
|
16
|
+
* This module owns those translations and nothing else — the provider class
|
|
17
|
+
* stays focused on HTTP / streaming concerns.
|
|
18
|
+
*
|
|
19
|
+
* Hermes reference: `agent/codex_responses_adapter.py::_chat_messages_to_responses_input`
|
|
20
|
+
* and `_responses_tools`. We diverge from hermes in two places:
|
|
21
|
+
*
|
|
22
|
+
* 1. We start from Maestro's Anthropic-shaped `ProviderContentBlock[]`, not
|
|
23
|
+
* from OpenAI Chat Completions messages. Hermes does this conversion in
|
|
24
|
+
* two hops (Anthropic → ChatCompletions → Responses); we do it in one to
|
|
25
|
+
* keep the data path shorter and the type signatures honest.
|
|
26
|
+
*
|
|
27
|
+
* 2. We don't replay `codex_reasoning_items` / `codex_message_items` from
|
|
28
|
+
* prior turns yet. Reasoning replay (with `encrypted_content`) is what
|
|
29
|
+
* lets the Responses API maintain a coherent reasoning chain across
|
|
30
|
+
* turns — but maestro's loop currently drops the encrypted blobs after
|
|
31
|
+
* each turn, so there's nothing to replay. A future PR can extend
|
|
32
|
+
* `ProviderContentBlock` with a `codex_encrypted_reasoning` variant and
|
|
33
|
+
* wire the replay here.
|
|
34
|
+
*/
|
|
35
|
+
import type { ProviderMessage, ProviderToolSchema } from "../providers/base.js";
|
|
36
|
+
/**
|
|
37
|
+
* Function-tool entry as the Responses API expects it at top level.
|
|
38
|
+
*
|
|
39
|
+
* Differences from Chat Completions function format:
|
|
40
|
+
* - No `function` wrapper — `name` / `description` / `parameters` are flat.
|
|
41
|
+
* - `strict: false` is the safe default. `strict: true` would constrain the
|
|
42
|
+
* model's tool arguments to a JSON-Schema subset (no `additionalProperties`,
|
|
43
|
+
* no enums on objects, etc.). Maestro tool schemas vary in shape and
|
|
44
|
+
* several would 400 under strict mode, so we punt that decision.
|
|
45
|
+
*/
|
|
46
|
+
export interface ResponsesFunctionTool {
|
|
47
|
+
type: "function";
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
strict: boolean;
|
|
51
|
+
parameters: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
export declare function translateToolsToResponses(tools: readonly ProviderToolSchema[] | undefined): ResponsesFunctionTool[] | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Union of every input-item shape we currently produce. The Responses API
|
|
56
|
+
* supports more (built-in tools, web_search hosted tools, file_search), but
|
|
57
|
+
* Maestro only emits these four — adding more is a one-discriminant extension.
|
|
58
|
+
*/
|
|
59
|
+
export type ResponsesInputItem = {
|
|
60
|
+
type?: "message";
|
|
61
|
+
role: "user" | "assistant";
|
|
62
|
+
/** String content (legacy fast path) OR a parts array (multimodal). */
|
|
63
|
+
content: string | ResponsesContentPart[];
|
|
64
|
+
} | {
|
|
65
|
+
type: "function_call";
|
|
66
|
+
call_id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
arguments: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "function_call_output";
|
|
71
|
+
call_id: string;
|
|
72
|
+
/** String for text-only tool results; array for multimodal results. */
|
|
73
|
+
output: string | ResponsesContentPart[];
|
|
74
|
+
};
|
|
75
|
+
export type ResponsesContentPart = {
|
|
76
|
+
type: "input_text";
|
|
77
|
+
text: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: "output_text";
|
|
80
|
+
text: string;
|
|
81
|
+
} | {
|
|
82
|
+
type: "input_image";
|
|
83
|
+
image_url: string;
|
|
84
|
+
detail?: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Convert one Maestro message into one-or-more Responses input items.
|
|
88
|
+
*
|
|
89
|
+
* Why one message can produce multiple items:
|
|
90
|
+
* - An assistant message with `text` + `tool_use` emits a `message` item AND
|
|
91
|
+
* one `function_call` per tool_use, in that exact order.
|
|
92
|
+
* - A user message with `tool_result` blocks emits a separate
|
|
93
|
+
* `function_call_output` per result. Text/image blocks accompanying the
|
|
94
|
+
* tool_results are flushed as their own `message` item before each result
|
|
95
|
+
* so call-result ordering with surrounding text is preserved (matches
|
|
96
|
+
* DeepSeek/Anthropic intent).
|
|
97
|
+
*/
|
|
98
|
+
export declare function translateMessageToResponsesItems(msg: ProviderMessage): ResponsesInputItem[];
|
|
99
|
+
/**
|
|
100
|
+
* Top-level: translate the full Maestro message history into a flat array of
|
|
101
|
+
* Responses input items. The `system` string is consumed by the provider into
|
|
102
|
+
* the request's `instructions` field — it does NOT appear here.
|
|
103
|
+
*/
|
|
104
|
+
export declare function translateMessagesToResponses(messages: readonly ProviderMessage[]): ResponsesInputItem[];
|
|
105
|
+
//# sourceMappingURL=codex-translators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-translators.d.ts","sourceRoot":"","sources":["../../src/providers/codex-translators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAGV,eAAe,EACf,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAI1B;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,GAC/C,qBAAqB,EAAE,GAAG,SAAS,CAiBrC;AAID;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,uEAAuE;IACvE,OAAO,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAAC;CAC1C,GACD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC3E;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAAC;CACzC,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,eAAe,GACnB,kBAAkB,EAAE,CAgBtB;AA2JD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,SAAS,eAAe,EAAE,GACnC,kBAAkB,EAAE,CAQtB"}
|