@warmdrift/kgauto-compiler 2.0.0-alpha.33 → 2.0.0-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-P3TOAEG4.mjs +56 -0
- package/dist/glassbox/index.d.mts +3 -3
- package/dist/glassbox/index.d.ts +3 -3
- package/dist/glassbox-routes/format.d.mts +24 -0
- package/dist/glassbox-routes/format.d.ts +24 -0
- package/dist/glassbox-routes/format.js +86 -0
- package/dist/glassbox-routes/format.mjs +18 -0
- package/dist/glassbox-routes/index.d.mts +5 -149
- package/dist/glassbox-routes/index.d.ts +5 -149
- package/dist/glassbox-routes/react/index.d.mts +74 -0
- package/dist/glassbox-routes/react/index.d.ts +74 -0
- package/dist/glassbox-routes/react/index.js +819 -0
- package/dist/glassbox-routes/react/index.mjs +754 -0
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +325 -17
- package/dist/index.mjs +325 -17
- package/dist/{ir-DubC20e3.d.mts → ir-BAAHLfFL.d.mts} +37 -0
- package/dist/{ir-GnYPkpGo.d.ts → ir-B_ygNURd.d.ts} +37 -0
- package/dist/profiles.d.mts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{types-2QzI0Ep1.d.mts → types-BoqPXoUb.d.mts} +1 -1
- package/dist/types-CJz1Ebvb.d.ts +149 -0
- package/dist/{types-DYcO82xh.d.ts → types-CXyKj6-K.d.ts} +1 -1
- package/dist/types-DDX6K2-p.d.mts +149 -0
- package/package.json +32 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, B as BestPracticeAdvisory, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-
|
|
2
|
-
export { m as CallAttempt, n as CallError, o as ChainWithGrounding, p as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, q as MutationApplied, r as NormalizedTokens, s as OutcomeKind, t as PerAxisMetricsByModel, u as PromptSection, v as SectionKind, T as ToolCall, w as ToolDefinition } from './ir-
|
|
1
|
+
import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, B as BestPracticeAdvisory, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-BAAHLfFL.mjs';
|
|
2
|
+
export { m as CallAttempt, n as CallError, o as ChainWithGrounding, p as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, q as MutationApplied, r as NormalizedTokens, s as OutcomeKind, t as PerAxisMetricsByModel, u as PromptSection, v as SectionKind, T as ToolCall, w as ToolDefinition } from './ir-BAAHLfFL.mjs';
|
|
3
3
|
import { ModelProfile } from './profiles.mjs';
|
|
4
4
|
export { ALIASES, CacheStrategy, CliffRule, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, profilesByProvider, tryGetProfile } from './profiles.mjs';
|
|
5
5
|
import { IntentArchetypeName } from './dialect.mjs';
|
|
@@ -54,6 +54,15 @@ interface ExecuteOptions {
|
|
|
54
54
|
apiKeys?: ApiKeys;
|
|
55
55
|
fetchImpl?: typeof fetch;
|
|
56
56
|
providerOverrides?: ProviderOverrides;
|
|
57
|
+
/**
|
|
58
|
+
* alpha.34. When supplied AND the chosen provider supports streaming, the
|
|
59
|
+
* execute() per-provider branch switches to SSE wire format and invokes
|
|
60
|
+
* `onChunk(delta)` once per text-delta event. Single-shot behavior
|
|
61
|
+
* preserved when omitted (current consumers unaffected). Wired from
|
|
62
|
+
* `CallOptions.onChunk` by `call()` after gating on `profile.streaming`
|
|
63
|
+
* and `!opts.noStream`.
|
|
64
|
+
*/
|
|
65
|
+
onChunk?: (chunk: string) => void;
|
|
57
66
|
}
|
|
58
67
|
interface ExecuteOk {
|
|
59
68
|
ok: true;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, B as BestPracticeAdvisory, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-
|
|
2
|
-
export { m as CallAttempt, n as CallError, o as ChainWithGrounding, p as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, q as MutationApplied, r as NormalizedTokens, s as OutcomeKind, t as PerAxisMetricsByModel, u as PromptSection, v as SectionKind, T as ToolCall, w as ToolDefinition } from './ir-
|
|
1
|
+
import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, B as BestPracticeAdvisory, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-B_ygNURd.js';
|
|
2
|
+
export { m as CallAttempt, n as CallError, o as ChainWithGrounding, p as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, q as MutationApplied, r as NormalizedTokens, s as OutcomeKind, t as PerAxisMetricsByModel, u as PromptSection, v as SectionKind, T as ToolCall, w as ToolDefinition } from './ir-B_ygNURd.js';
|
|
3
3
|
import { ModelProfile } from './profiles.js';
|
|
4
4
|
export { ALIASES, CacheStrategy, CliffRule, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, profilesByProvider, tryGetProfile } from './profiles.js';
|
|
5
5
|
import { IntentArchetypeName } from './dialect.js';
|
|
@@ -54,6 +54,15 @@ interface ExecuteOptions {
|
|
|
54
54
|
apiKeys?: ApiKeys;
|
|
55
55
|
fetchImpl?: typeof fetch;
|
|
56
56
|
providerOverrides?: ProviderOverrides;
|
|
57
|
+
/**
|
|
58
|
+
* alpha.34. When supplied AND the chosen provider supports streaming, the
|
|
59
|
+
* execute() per-provider branch switches to SSE wire format and invokes
|
|
60
|
+
* `onChunk(delta)` once per text-delta event. Single-shot behavior
|
|
61
|
+
* preserved when omitted (current consumers unaffected). Wired from
|
|
62
|
+
* `CallOptions.onChunk` by `call()` after gating on `profile.streaming`
|
|
63
|
+
* and `!opts.noStream`.
|
|
64
|
+
*/
|
|
65
|
+
onChunk?: (chunk: string) => void;
|
|
57
66
|
}
|
|
58
67
|
interface ExecuteOk {
|
|
59
68
|
ok: true;
|
package/dist/index.js
CHANGED
|
@@ -3361,8 +3361,295 @@ function getReachabilityDiagnostic(opts = {}) {
|
|
|
3361
3361
|
return out;
|
|
3362
3362
|
}
|
|
3363
3363
|
|
|
3364
|
-
// src/
|
|
3364
|
+
// src/streaming.ts
|
|
3365
3365
|
var ANTHROPIC_URL = "https://api.anthropic.com/v1/messages";
|
|
3366
|
+
async function streamAnthropic(request, apiKey, opts) {
|
|
3367
|
+
const { provider: _provider, ...body } = request;
|
|
3368
|
+
const fetchFn = opts.fetchImpl ?? fetch;
|
|
3369
|
+
let res;
|
|
3370
|
+
try {
|
|
3371
|
+
res = await fetchFn(ANTHROPIC_URL, {
|
|
3372
|
+
method: "POST",
|
|
3373
|
+
headers: {
|
|
3374
|
+
"x-api-key": apiKey,
|
|
3375
|
+
"anthropic-version": "2023-06-01",
|
|
3376
|
+
"content-type": "application/json"
|
|
3377
|
+
},
|
|
3378
|
+
body: JSON.stringify({ ...body, stream: true })
|
|
3379
|
+
});
|
|
3380
|
+
} catch (err) {
|
|
3381
|
+
return retryableError(0, "network_error", String(err), null);
|
|
3382
|
+
}
|
|
3383
|
+
if (!res.ok) {
|
|
3384
|
+
const errBody = await res.json().catch(() => ({}));
|
|
3385
|
+
return classifyHttpError(res.status, errBody);
|
|
3386
|
+
}
|
|
3387
|
+
let text = "";
|
|
3388
|
+
let inputTokens = 0;
|
|
3389
|
+
let outputTokens = 0;
|
|
3390
|
+
let cacheReadTokens;
|
|
3391
|
+
let cacheCreatedTokens;
|
|
3392
|
+
let stopReason;
|
|
3393
|
+
const toolBlocks = /* @__PURE__ */ new Map();
|
|
3394
|
+
try {
|
|
3395
|
+
await parseSSEStream(res, (event) => {
|
|
3396
|
+
if (!event.data) return;
|
|
3397
|
+
let payload;
|
|
3398
|
+
try {
|
|
3399
|
+
payload = JSON.parse(event.data);
|
|
3400
|
+
} catch {
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
const type = payload.type;
|
|
3404
|
+
if (type === "message_start") {
|
|
3405
|
+
const msg = payload.message;
|
|
3406
|
+
const usage = msg?.usage;
|
|
3407
|
+
if (usage) {
|
|
3408
|
+
inputTokens = usage.input_tokens ?? 0;
|
|
3409
|
+
outputTokens = usage.output_tokens ?? 0;
|
|
3410
|
+
if (typeof usage.cache_read_input_tokens === "number")
|
|
3411
|
+
cacheReadTokens = usage.cache_read_input_tokens;
|
|
3412
|
+
if (typeof usage.cache_creation_input_tokens === "number")
|
|
3413
|
+
cacheCreatedTokens = usage.cache_creation_input_tokens;
|
|
3414
|
+
}
|
|
3415
|
+
return;
|
|
3416
|
+
}
|
|
3417
|
+
if (type === "content_block_start") {
|
|
3418
|
+
const p = payload;
|
|
3419
|
+
const idx = p.index ?? 0;
|
|
3420
|
+
const block = p.content_block;
|
|
3421
|
+
if (block?.type === "tool_use" && block.id && block.name) {
|
|
3422
|
+
toolBlocks.set(idx, { id: block.id, name: block.name, argsJson: "" });
|
|
3423
|
+
}
|
|
3424
|
+
return;
|
|
3425
|
+
}
|
|
3426
|
+
if (type === "content_block_delta") {
|
|
3427
|
+
const p = payload;
|
|
3428
|
+
const delta = p.delta;
|
|
3429
|
+
if (!delta) return;
|
|
3430
|
+
if (delta.type === "text_delta" && typeof delta.text === "string") {
|
|
3431
|
+
text += delta.text;
|
|
3432
|
+
opts.onChunk(delta.text);
|
|
3433
|
+
} else if (delta.type === "input_json_delta" && typeof delta.partial_json === "string") {
|
|
3434
|
+
const idx = p.index ?? 0;
|
|
3435
|
+
const tool = toolBlocks.get(idx);
|
|
3436
|
+
if (tool) tool.argsJson += delta.partial_json;
|
|
3437
|
+
}
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
if (type === "message_delta") {
|
|
3441
|
+
const p = payload;
|
|
3442
|
+
if (p.delta?.stop_reason) stopReason = p.delta.stop_reason;
|
|
3443
|
+
if (typeof p.usage?.output_tokens === "number") outputTokens = p.usage.output_tokens;
|
|
3444
|
+
return;
|
|
3445
|
+
}
|
|
3446
|
+
});
|
|
3447
|
+
} catch (err) {
|
|
3448
|
+
return retryableError(0, "stream_interrupted", String(err), null);
|
|
3449
|
+
}
|
|
3450
|
+
const toolCalls = Array.from(toolBlocks.values()).map((b) => ({
|
|
3451
|
+
id: b.id,
|
|
3452
|
+
name: b.name,
|
|
3453
|
+
args: tryParseJson(b.argsJson) ?? {}
|
|
3454
|
+
}));
|
|
3455
|
+
const tokens = {
|
|
3456
|
+
input: inputTokens,
|
|
3457
|
+
output: outputTokens,
|
|
3458
|
+
total: inputTokens + outputTokens,
|
|
3459
|
+
cached: cacheReadTokens,
|
|
3460
|
+
cacheCreated: cacheCreatedTokens
|
|
3461
|
+
};
|
|
3462
|
+
const response = {
|
|
3463
|
+
text,
|
|
3464
|
+
structuredOutput: null,
|
|
3465
|
+
toolCalls,
|
|
3466
|
+
tokens,
|
|
3467
|
+
finishReason: stopReason,
|
|
3468
|
+
raw: { streamed: true, provider: "anthropic" }
|
|
3469
|
+
};
|
|
3470
|
+
return { ok: true, status: res.status, response };
|
|
3471
|
+
}
|
|
3472
|
+
async function streamOpenAILike(url, request, apiKey, providerLabel, opts) {
|
|
3473
|
+
const { provider: _provider, ...body } = request;
|
|
3474
|
+
const fetchFn = opts.fetchImpl ?? fetch;
|
|
3475
|
+
const reqBody = {
|
|
3476
|
+
...body,
|
|
3477
|
+
stream: true,
|
|
3478
|
+
stream_options: {
|
|
3479
|
+
...body.stream_options ?? {},
|
|
3480
|
+
include_usage: true
|
|
3481
|
+
}
|
|
3482
|
+
};
|
|
3483
|
+
let res;
|
|
3484
|
+
try {
|
|
3485
|
+
res = await fetchFn(url, {
|
|
3486
|
+
method: "POST",
|
|
3487
|
+
headers: {
|
|
3488
|
+
authorization: `Bearer ${apiKey}`,
|
|
3489
|
+
"content-type": "application/json"
|
|
3490
|
+
},
|
|
3491
|
+
body: JSON.stringify(reqBody)
|
|
3492
|
+
});
|
|
3493
|
+
} catch (err) {
|
|
3494
|
+
return retryableError(0, "network_error", String(err), null);
|
|
3495
|
+
}
|
|
3496
|
+
if (!res.ok) {
|
|
3497
|
+
const errBody = await res.json().catch(() => ({}));
|
|
3498
|
+
return classifyHttpError(res.status, errBody);
|
|
3499
|
+
}
|
|
3500
|
+
let text = "";
|
|
3501
|
+
let finishReason;
|
|
3502
|
+
let inputTokens = 0;
|
|
3503
|
+
let outputTokens = 0;
|
|
3504
|
+
let totalTokens;
|
|
3505
|
+
let cachedTokens;
|
|
3506
|
+
const toolBuffers = /* @__PURE__ */ new Map();
|
|
3507
|
+
try {
|
|
3508
|
+
await parseSSEStream(res, (event) => {
|
|
3509
|
+
if (!event.data) return;
|
|
3510
|
+
if (event.data === "[DONE]") return;
|
|
3511
|
+
let payload;
|
|
3512
|
+
try {
|
|
3513
|
+
payload = JSON.parse(event.data);
|
|
3514
|
+
} catch {
|
|
3515
|
+
return;
|
|
3516
|
+
}
|
|
3517
|
+
const choices = payload.choices;
|
|
3518
|
+
if (choices && choices.length > 0) {
|
|
3519
|
+
const choice = choices[0];
|
|
3520
|
+
const deltaContent = choice.delta?.content;
|
|
3521
|
+
if (typeof deltaContent === "string" && deltaContent.length > 0) {
|
|
3522
|
+
text += deltaContent;
|
|
3523
|
+
opts.onChunk(deltaContent);
|
|
3524
|
+
}
|
|
3525
|
+
const toolDeltas = choice.delta?.tool_calls;
|
|
3526
|
+
if (toolDeltas) {
|
|
3527
|
+
for (const tcDelta of toolDeltas) {
|
|
3528
|
+
const idx = tcDelta.index ?? 0;
|
|
3529
|
+
let buf = toolBuffers.get(idx);
|
|
3530
|
+
if (!buf) {
|
|
3531
|
+
buf = { id: tcDelta.id ?? `tc-${idx}`, name: "", argsJson: "" };
|
|
3532
|
+
toolBuffers.set(idx, buf);
|
|
3533
|
+
}
|
|
3534
|
+
if (tcDelta.id) buf.id = tcDelta.id;
|
|
3535
|
+
if (tcDelta.function?.name) buf.name += tcDelta.function.name;
|
|
3536
|
+
if (tcDelta.function?.arguments) buf.argsJson += tcDelta.function.arguments;
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
if (choice.finish_reason) finishReason = choice.finish_reason;
|
|
3540
|
+
}
|
|
3541
|
+
const usage = payload.usage;
|
|
3542
|
+
if (usage) {
|
|
3543
|
+
if (typeof usage.prompt_tokens === "number") inputTokens = usage.prompt_tokens;
|
|
3544
|
+
if (typeof usage.completion_tokens === "number") outputTokens = usage.completion_tokens;
|
|
3545
|
+
if (typeof usage.total_tokens === "number") totalTokens = usage.total_tokens;
|
|
3546
|
+
const details = usage.prompt_tokens_details;
|
|
3547
|
+
if (typeof details?.cached_tokens === "number") cachedTokens = details.cached_tokens;
|
|
3548
|
+
}
|
|
3549
|
+
});
|
|
3550
|
+
} catch (err) {
|
|
3551
|
+
return retryableError(0, "stream_interrupted", String(err), null);
|
|
3552
|
+
}
|
|
3553
|
+
const toolCalls = Array.from(toolBuffers.values()).filter((b) => b.name.length > 0).map((b) => ({
|
|
3554
|
+
id: b.id,
|
|
3555
|
+
name: b.name,
|
|
3556
|
+
args: tryParseJson(b.argsJson) ?? {}
|
|
3557
|
+
}));
|
|
3558
|
+
const tokens = {
|
|
3559
|
+
input: inputTokens,
|
|
3560
|
+
output: outputTokens,
|
|
3561
|
+
total: totalTokens ?? inputTokens + outputTokens,
|
|
3562
|
+
cached: cachedTokens
|
|
3563
|
+
};
|
|
3564
|
+
const response = {
|
|
3565
|
+
text,
|
|
3566
|
+
structuredOutput: null,
|
|
3567
|
+
toolCalls,
|
|
3568
|
+
tokens,
|
|
3569
|
+
finishReason,
|
|
3570
|
+
raw: { streamed: true, provider: providerLabel }
|
|
3571
|
+
};
|
|
3572
|
+
return { ok: true, status: res.status, response };
|
|
3573
|
+
}
|
|
3574
|
+
async function parseSSEStream(response, handler) {
|
|
3575
|
+
const body = response.body;
|
|
3576
|
+
if (!body) throw new Error("Response has no body for SSE parse");
|
|
3577
|
+
const reader = body.getReader();
|
|
3578
|
+
const decoder = new TextDecoder("utf-8");
|
|
3579
|
+
let buffer = "";
|
|
3580
|
+
for (; ; ) {
|
|
3581
|
+
const { value, done } = await reader.read();
|
|
3582
|
+
if (done) break;
|
|
3583
|
+
buffer += decoder.decode(value, { stream: true });
|
|
3584
|
+
let sep;
|
|
3585
|
+
while (sep = buffer.indexOf("\n\n"), sep !== -1) {
|
|
3586
|
+
const block = buffer.slice(0, sep);
|
|
3587
|
+
buffer = buffer.slice(sep + 2);
|
|
3588
|
+
const event = parseSSEBlock(block);
|
|
3589
|
+
if (event) handler(event);
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
if (buffer.length > 0) {
|
|
3593
|
+
const event = parseSSEBlock(buffer);
|
|
3594
|
+
if (event) handler(event);
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
function parseSSEBlock(block) {
|
|
3598
|
+
const lines = block.split(/\r?\n/);
|
|
3599
|
+
let eventName;
|
|
3600
|
+
const dataLines = [];
|
|
3601
|
+
for (const line of lines) {
|
|
3602
|
+
if (line.startsWith(":")) continue;
|
|
3603
|
+
if (line.startsWith("event:")) {
|
|
3604
|
+
eventName = line.slice(6).trim();
|
|
3605
|
+
} else if (line.startsWith("data:")) {
|
|
3606
|
+
dataLines.push(line.slice(5).trim());
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
if (dataLines.length === 0) return void 0;
|
|
3610
|
+
return { event: eventName, data: dataLines.join("\n") };
|
|
3611
|
+
}
|
|
3612
|
+
function tryParseJson(s) {
|
|
3613
|
+
if (typeof s !== "string" || s.length === 0) return void 0;
|
|
3614
|
+
try {
|
|
3615
|
+
const parsed = JSON.parse(s);
|
|
3616
|
+
return typeof parsed === "object" && parsed !== null ? parsed : void 0;
|
|
3617
|
+
} catch {
|
|
3618
|
+
return void 0;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
function classifyHttpError(status, body) {
|
|
3622
|
+
const message = extractErrorMessage(body) ?? `HTTP ${status}`;
|
|
3623
|
+
if (status === 429)
|
|
3624
|
+
return { ok: false, status, errorType: "retryable", errorCode: "rate_limit", message, raw: body };
|
|
3625
|
+
if (status === 408)
|
|
3626
|
+
return { ok: false, status, errorType: "retryable", errorCode: "timeout", message, raw: body };
|
|
3627
|
+
if (status >= 500)
|
|
3628
|
+
return { ok: false, status, errorType: "retryable", errorCode: "server_error", message, raw: body };
|
|
3629
|
+
if (status === 404)
|
|
3630
|
+
return { ok: false, status, errorType: "retryable", errorCode: "model_not_found", message, raw: body };
|
|
3631
|
+
if (status === 401 || status === 403)
|
|
3632
|
+
return { ok: false, status, errorType: "terminal", errorCode: "auth", message, raw: body };
|
|
3633
|
+
if (status === 400)
|
|
3634
|
+
return { ok: false, status, errorType: "terminal", errorCode: "invalid_request", message, raw: body };
|
|
3635
|
+
return { ok: false, status, errorType: "terminal", errorCode: "unknown", message, raw: body };
|
|
3636
|
+
}
|
|
3637
|
+
function extractErrorMessage(body) {
|
|
3638
|
+
if (!body || typeof body !== "object") return void 0;
|
|
3639
|
+
const b = body;
|
|
3640
|
+
if (b.error && typeof b.error === "object") {
|
|
3641
|
+
const e = b.error;
|
|
3642
|
+
if (typeof e.message === "string") return e.message;
|
|
3643
|
+
}
|
|
3644
|
+
if (typeof b.message === "string") return b.message;
|
|
3645
|
+
return void 0;
|
|
3646
|
+
}
|
|
3647
|
+
function retryableError(status, code, message, raw) {
|
|
3648
|
+
return { ok: false, status, errorType: "retryable", errorCode: code, message, raw };
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
// src/execute.ts
|
|
3652
|
+
var ANTHROPIC_URL2 = "https://api.anthropic.com/v1/messages";
|
|
3366
3653
|
var OPENAI_URL = "https://api.openai.com/v1/chat/completions";
|
|
3367
3654
|
var DEEPSEEK_URL = "https://api.deepseek.com/chat/completions";
|
|
3368
3655
|
async function execute(request, opts = {}) {
|
|
@@ -3387,12 +3674,18 @@ async function executeAnthropic(request, opts) {
|
|
|
3387
3674
|
if (!apiKey) {
|
|
3388
3675
|
return terminalError(401, "auth", "ANTHROPIC_API_KEY missing");
|
|
3389
3676
|
}
|
|
3677
|
+
if (opts.onChunk) {
|
|
3678
|
+
return streamAnthropic(request, apiKey, {
|
|
3679
|
+
onChunk: opts.onChunk,
|
|
3680
|
+
fetchImpl: opts.fetchImpl
|
|
3681
|
+
});
|
|
3682
|
+
}
|
|
3390
3683
|
const { provider: _provider, ...body } = request;
|
|
3391
3684
|
const fetchFn = opts.fetchImpl ?? fetch;
|
|
3392
3685
|
let res;
|
|
3393
3686
|
let json;
|
|
3394
3687
|
try {
|
|
3395
|
-
res = await fetchFn(
|
|
3688
|
+
res = await fetchFn(ANTHROPIC_URL2, {
|
|
3396
3689
|
method: "POST",
|
|
3397
3690
|
headers: {
|
|
3398
3691
|
"x-api-key": apiKey,
|
|
@@ -3403,9 +3696,9 @@ async function executeAnthropic(request, opts) {
|
|
|
3403
3696
|
});
|
|
3404
3697
|
json = await res.json().catch(() => ({}));
|
|
3405
3698
|
} catch (err) {
|
|
3406
|
-
return
|
|
3699
|
+
return retryableError2(0, "network_error", String(err), null);
|
|
3407
3700
|
}
|
|
3408
|
-
if (!res.ok) return
|
|
3701
|
+
if (!res.ok) return classifyHttpError2(res.status, json);
|
|
3409
3702
|
return { ok: true, status: res.status, response: normalizeAnthropic(json) };
|
|
3410
3703
|
}
|
|
3411
3704
|
function normalizeAnthropic(raw) {
|
|
@@ -3439,9 +3732,9 @@ async function executeGoogle(request, opts) {
|
|
|
3439
3732
|
});
|
|
3440
3733
|
json = await res.json().catch(() => ({}));
|
|
3441
3734
|
} catch (err) {
|
|
3442
|
-
return
|
|
3735
|
+
return retryableError2(0, "network_error", String(err), null);
|
|
3443
3736
|
}
|
|
3444
|
-
if (!res.ok) return
|
|
3737
|
+
if (!res.ok) return classifyHttpError2(res.status, json);
|
|
3445
3738
|
return { ok: true, status: res.status, response: normalizeGoogle(json) };
|
|
3446
3739
|
}
|
|
3447
3740
|
function normalizeGoogle(raw) {
|
|
@@ -3468,6 +3761,12 @@ async function executeOpenAI(request, opts) {
|
|
|
3468
3761
|
if (!apiKey) {
|
|
3469
3762
|
return terminalError(401, "auth", "OPENAI_API_KEY missing");
|
|
3470
3763
|
}
|
|
3764
|
+
if (opts.onChunk) {
|
|
3765
|
+
return streamOpenAILike(OPENAI_URL, request, apiKey, "openai", {
|
|
3766
|
+
onChunk: opts.onChunk,
|
|
3767
|
+
fetchImpl: opts.fetchImpl
|
|
3768
|
+
});
|
|
3769
|
+
}
|
|
3471
3770
|
const { provider: _provider, ...body } = request;
|
|
3472
3771
|
const fetchFn = opts.fetchImpl ?? fetch;
|
|
3473
3772
|
let res;
|
|
@@ -3480,9 +3779,9 @@ async function executeOpenAI(request, opts) {
|
|
|
3480
3779
|
});
|
|
3481
3780
|
json = await res.json().catch(() => ({}));
|
|
3482
3781
|
} catch (err) {
|
|
3483
|
-
return
|
|
3782
|
+
return retryableError2(0, "network_error", String(err), null);
|
|
3484
3783
|
}
|
|
3485
|
-
if (!res.ok) return
|
|
3784
|
+
if (!res.ok) return classifyHttpError2(res.status, json);
|
|
3486
3785
|
return { ok: true, status: res.status, response: normalizeOpenAILike(json) };
|
|
3487
3786
|
}
|
|
3488
3787
|
async function executeDeepSeek(request, opts) {
|
|
@@ -3490,6 +3789,12 @@ async function executeDeepSeek(request, opts) {
|
|
|
3490
3789
|
if (!apiKey) {
|
|
3491
3790
|
return terminalError(401, "auth", "DEEPSEEK_API_KEY missing");
|
|
3492
3791
|
}
|
|
3792
|
+
if (opts.onChunk) {
|
|
3793
|
+
return streamOpenAILike(DEEPSEEK_URL, request, apiKey, "deepseek", {
|
|
3794
|
+
onChunk: opts.onChunk,
|
|
3795
|
+
fetchImpl: opts.fetchImpl
|
|
3796
|
+
});
|
|
3797
|
+
}
|
|
3493
3798
|
const { provider: _provider, ...body } = request;
|
|
3494
3799
|
const fetchFn = opts.fetchImpl ?? fetch;
|
|
3495
3800
|
let res;
|
|
@@ -3502,9 +3807,9 @@ async function executeDeepSeek(request, opts) {
|
|
|
3502
3807
|
});
|
|
3503
3808
|
json = await res.json().catch(() => ({}));
|
|
3504
3809
|
} catch (err) {
|
|
3505
|
-
return
|
|
3810
|
+
return retryableError2(0, "network_error", String(err), null);
|
|
3506
3811
|
}
|
|
3507
|
-
if (!res.ok) return
|
|
3812
|
+
if (!res.ok) return classifyHttpError2(res.status, json);
|
|
3508
3813
|
return { ok: true, status: res.status, response: normalizeOpenAILike(json) };
|
|
3509
3814
|
}
|
|
3510
3815
|
function normalizeOpenAILike(raw) {
|
|
@@ -3514,7 +3819,7 @@ function normalizeOpenAILike(raw) {
|
|
|
3514
3819
|
const toolCalls = (choice?.message?.tool_calls ?? []).filter((tc) => tc.function?.name).map((tc, i) => ({
|
|
3515
3820
|
id: tc.id ?? `tc-${i}`,
|
|
3516
3821
|
name: tc.function.name,
|
|
3517
|
-
args:
|
|
3822
|
+
args: tryParseJson2(tc.function?.arguments) ?? {}
|
|
3518
3823
|
}));
|
|
3519
3824
|
const u = r.usage ?? {};
|
|
3520
3825
|
const tokens = {
|
|
@@ -3531,8 +3836,8 @@ function applyOverrides(request, overrides) {
|
|
|
3531
3836
|
if (!layer) return request;
|
|
3532
3837
|
return { ...request, ...layer };
|
|
3533
3838
|
}
|
|
3534
|
-
function
|
|
3535
|
-
const message =
|
|
3839
|
+
function classifyHttpError2(status, body) {
|
|
3840
|
+
const message = extractErrorMessage2(body) ?? `HTTP ${status}`;
|
|
3536
3841
|
if (status === 429) {
|
|
3537
3842
|
return { ok: false, status, errorType: "retryable", errorCode: "rate_limit", message, raw: body };
|
|
3538
3843
|
}
|
|
@@ -3553,7 +3858,7 @@ function classifyHttpError(status, body) {
|
|
|
3553
3858
|
}
|
|
3554
3859
|
return { ok: false, status, errorType: "terminal", errorCode: "unknown", message, raw: body };
|
|
3555
3860
|
}
|
|
3556
|
-
function
|
|
3861
|
+
function extractErrorMessage2(body) {
|
|
3557
3862
|
if (!body || typeof body !== "object") return void 0;
|
|
3558
3863
|
const b = body;
|
|
3559
3864
|
if (b.error && typeof b.error === "object") {
|
|
@@ -3566,10 +3871,10 @@ function extractErrorMessage(body) {
|
|
|
3566
3871
|
function terminalError(status, code, message) {
|
|
3567
3872
|
return { ok: false, status, errorType: "terminal", errorCode: code, message, raw: null };
|
|
3568
3873
|
}
|
|
3569
|
-
function
|
|
3874
|
+
function retryableError2(status, code, message, raw) {
|
|
3570
3875
|
return { ok: false, status, errorType: "retryable", errorCode: code, message, raw };
|
|
3571
3876
|
}
|
|
3572
|
-
function
|
|
3877
|
+
function tryParseJson2(s) {
|
|
3573
3878
|
if (typeof s !== "string" || s.length === 0) return void 0;
|
|
3574
3879
|
try {
|
|
3575
3880
|
const parsed = JSON.parse(s);
|
|
@@ -4383,10 +4688,13 @@ async function call(ir, opts = {}) {
|
|
|
4383
4688
|
safeEmit(
|
|
4384
4689
|
() => emitExecuteAttempt(traceId, ir.appId, { model: targetModel, attemptIndex: i })
|
|
4385
4690
|
);
|
|
4691
|
+
const targetSupportsStreaming = targetProfile?.streaming === true;
|
|
4692
|
+
const streamingOnChunk = opts.onChunk && !opts.noStream && targetSupportsStreaming ? opts.onChunk : void 0;
|
|
4386
4693
|
const exec = await execute(activeCompile.request, {
|
|
4387
4694
|
apiKeys: opts.apiKeys,
|
|
4388
4695
|
fetchImpl: opts.fetchImpl,
|
|
4389
|
-
providerOverrides: opts.providerOverrides
|
|
4696
|
+
providerOverrides: opts.providerOverrides,
|
|
4697
|
+
onChunk: streamingOnChunk
|
|
4390
4698
|
});
|
|
4391
4699
|
const validated = exec.ok ? validateStructuredContract(exec, ir) : exec;
|
|
4392
4700
|
if (validated.ok) {
|