@cognipeer/agent-sdk 0.7.0 → 0.7.1
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/index.cjs +544 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -3
- package/dist/index.d.ts +109 -3
- package/dist/index.mjs +543 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3335,15 +3335,40 @@ function countToolCallsInLastTurn(state) {
|
|
|
3335
3335
|
function stripReflectionAskMessages(messages) {
|
|
3336
3336
|
return messages.filter((m) => !(m?.role === "user" && m?.name === REFLECTION_ASK_NAME));
|
|
3337
3337
|
}
|
|
3338
|
+
function lastTwoToolTurns(state) {
|
|
3339
|
+
const groups = [];
|
|
3340
|
+
let cur = [];
|
|
3341
|
+
let sawTool = false;
|
|
3342
|
+
for (let i = state.messages.length - 1; i >= 0; i--) {
|
|
3343
|
+
const m = state.messages[i];
|
|
3344
|
+
if (m?.role === "tool") {
|
|
3345
|
+
if (m.name) cur.push(m.name);
|
|
3346
|
+
sawTool = true;
|
|
3347
|
+
} else if (m?.role === "assistant") {
|
|
3348
|
+
if (sawTool) {
|
|
3349
|
+
groups.push(cur);
|
|
3350
|
+
cur = [];
|
|
3351
|
+
sawTool = false;
|
|
3352
|
+
if (groups.length >= 2) break;
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
if (sawTool && cur.length) groups.push(cur);
|
|
3357
|
+
return { current: groups[0] ?? [], previous: groups[1] ?? [] };
|
|
3358
|
+
}
|
|
3338
3359
|
function shouldRunReflection(cadence, state, ranToolsThisTurn) {
|
|
3339
3360
|
if (cadence === "off") return false;
|
|
3340
3361
|
if (cadence === "every_turn") return true;
|
|
3341
3362
|
if (cadence === "after_tool") return ranToolsThisTurn;
|
|
3363
|
+
if (cadence === "initial_then_after_tool") return ranToolsThisTurn;
|
|
3342
3364
|
if (cadence === "on_branch") {
|
|
3343
|
-
const
|
|
3344
|
-
|
|
3345
|
-
const
|
|
3346
|
-
|
|
3365
|
+
const { current, previous } = lastTwoToolTurns(state);
|
|
3366
|
+
if (previous.length === 0) return true;
|
|
3367
|
+
const a = new Set(current);
|
|
3368
|
+
const b = new Set(previous);
|
|
3369
|
+
for (const n of a) if (!b.has(n)) return true;
|
|
3370
|
+
for (const n of b) if (!a.has(n)) return true;
|
|
3371
|
+
return false;
|
|
3347
3372
|
}
|
|
3348
3373
|
return false;
|
|
3349
3374
|
}
|
|
@@ -3360,7 +3385,10 @@ function createReflectionNode(opts, resolved) {
|
|
|
3360
3385
|
const onEvent = state.ctx?.__onEvent;
|
|
3361
3386
|
const traceSession = state.ctx?.__traceSession;
|
|
3362
3387
|
const maxChars = resolved.maxChars;
|
|
3363
|
-
const
|
|
3388
|
+
const turnNow = state.toolCallCount ?? 0;
|
|
3389
|
+
const hookCtx = { state, turn: turnNow, trigger, ranToolsThisTurn: true };
|
|
3390
|
+
const defaultPrompt = (resolved.promptTemplate || DEFAULT_REFLECT_PROMPT).replace(/\$\{maxChars\}/g, String(maxChars));
|
|
3391
|
+
const promptBody = resolved.buildPrompt ? String(resolved.buildPrompt({ ...hookCtx, defaultPrompt, maxChars }) ?? defaultPrompt) : defaultPrompt;
|
|
3364
3392
|
const baseMessages = stripReflectionAskMessages([...state.messages]);
|
|
3365
3393
|
const askMessage = {
|
|
3366
3394
|
role: "user",
|
|
@@ -3394,6 +3422,8 @@ function createReflectionNode(opts, resolved) {
|
|
|
3394
3422
|
const rawText = extractText(response);
|
|
3395
3423
|
const text = trimToChars(String(rawText ?? "").trim(), maxChars);
|
|
3396
3424
|
if (!text) return {};
|
|
3425
|
+
const prevText = (state.reflections?.[state.reflections.length - 1]?.text || "").trim();
|
|
3426
|
+
if (prevText && isNearDuplicate(prevText, text)) return {};
|
|
3397
3427
|
const rawUsage = response?.usage_metadata || response?.response_metadata?.usage || response?.usage || response?.additional_kwargs?.usage;
|
|
3398
3428
|
const usage = normalizeUsage(rawUsage);
|
|
3399
3429
|
const { ids, names } = countToolCallsInLastTurn(state);
|
|
@@ -3442,6 +3472,12 @@ function createReflectionNode(opts, resolved) {
|
|
|
3442
3472
|
} catch (e) {
|
|
3443
3473
|
}
|
|
3444
3474
|
}
|
|
3475
|
+
if (resolved.onReflection) {
|
|
3476
|
+
try {
|
|
3477
|
+
resolved.onReflection(record, hookCtx);
|
|
3478
|
+
} catch {
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3445
3481
|
const nextMessages = stripReflectionAskMessages([...state.messages]);
|
|
3446
3482
|
const reflections = [...state.reflections || [], record];
|
|
3447
3483
|
const kept = reflections.slice(-Math.max(1, resolved.keepLast));
|
|
@@ -3458,7 +3494,20 @@ ${r.text}
|
|
|
3458
3494
|
metadata: { reflectionId: r.id, reflectionTurn: r.turn, reflectionTrigger: r.trigger }
|
|
3459
3495
|
});
|
|
3460
3496
|
}
|
|
3461
|
-
|
|
3497
|
+
const patch = { messages: prunedMessages, reflections };
|
|
3498
|
+
if (resolved.feedTo === "memory") {
|
|
3499
|
+
const fact = {
|
|
3500
|
+
key: `reflection_turn_${turn}`,
|
|
3501
|
+
value: text,
|
|
3502
|
+
sourceTurn: turn,
|
|
3503
|
+
confidence: 0.3,
|
|
3504
|
+
tags: ["reflection"]
|
|
3505
|
+
};
|
|
3506
|
+
patch.memoryFacts = [...state.memoryFacts || [], fact];
|
|
3507
|
+
} else if (resolved.feedTo === "plan" && state.plan) {
|
|
3508
|
+
patch.plan = { ...state.plan, lastReflection: text };
|
|
3509
|
+
}
|
|
3510
|
+
return patch;
|
|
3462
3511
|
};
|
|
3463
3512
|
}
|
|
3464
3513
|
function extractText(chunk) {
|
|
@@ -3487,24 +3536,75 @@ function safeRandomId() {
|
|
|
3487
3536
|
return `r_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`;
|
|
3488
3537
|
}
|
|
3489
3538
|
}
|
|
3539
|
+
function isNearDuplicate(a, b) {
|
|
3540
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
3541
|
+
const na = norm(a);
|
|
3542
|
+
const nb = norm(b);
|
|
3543
|
+
if (na === nb) return true;
|
|
3544
|
+
const tokensA = new Set(na.split(" ").filter(Boolean));
|
|
3545
|
+
const tokensB = new Set(nb.split(" ").filter(Boolean));
|
|
3546
|
+
if (tokensA.size === 0 || tokensB.size === 0) return false;
|
|
3547
|
+
let inter = 0;
|
|
3548
|
+
for (const t of tokensA) if (tokensB.has(t)) inter++;
|
|
3549
|
+
const union = tokensA.size + tokensB.size - inter;
|
|
3550
|
+
return union > 0 && inter / union >= 0.9;
|
|
3551
|
+
}
|
|
3490
3552
|
|
|
3491
3553
|
// src/smart/reasoning.ts
|
|
3492
3554
|
var LEVEL_DEFAULTS = {
|
|
3555
|
+
minimal: {
|
|
3556
|
+
native: { effort: "minimal" },
|
|
3557
|
+
reflection: { maxTokens: 150, maxChars: 400, cadence: "off" }
|
|
3558
|
+
},
|
|
3493
3559
|
low: {
|
|
3494
3560
|
native: { effort: "low" },
|
|
3495
3561
|
reflection: { maxTokens: 200, maxChars: 600, cadence: "on_branch" }
|
|
3496
3562
|
},
|
|
3497
3563
|
medium: {
|
|
3498
3564
|
native: { effort: "medium" },
|
|
3499
|
-
reflection: { maxTokens: 350, maxChars: 1200, cadence: "
|
|
3565
|
+
reflection: { maxTokens: 350, maxChars: 1200, cadence: "initial_then_after_tool" }
|
|
3500
3566
|
},
|
|
3501
3567
|
high: {
|
|
3502
3568
|
native: { effort: "high" },
|
|
3503
|
-
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "
|
|
3569
|
+
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "initial_then_after_tool" }
|
|
3504
3570
|
}
|
|
3505
3571
|
};
|
|
3572
|
+
var VALID_LEVELS = ["minimal", "low", "medium", "high"];
|
|
3573
|
+
var VALID_CADENCES = ["off", "every_turn", "after_tool", "on_branch", "initial_then_after_tool"];
|
|
3574
|
+
var VALID_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
3575
|
+
function validateReasoningConfig(input) {
|
|
3576
|
+
if (!input) return;
|
|
3577
|
+
if (input.level !== void 0 && !VALID_LEVELS.includes(input.level)) {
|
|
3578
|
+
throw new Error(`reasoning.level must be one of ${VALID_LEVELS.join(", ")} (got "${input.level}")`);
|
|
3579
|
+
}
|
|
3580
|
+
if (input.native) {
|
|
3581
|
+
const n = input.native;
|
|
3582
|
+
if (n.effort !== void 0 && !VALID_EFFORTS.includes(n.effort)) {
|
|
3583
|
+
throw new Error(`reasoning.native.effort must be one of ${VALID_EFFORTS.join(", ")} (got "${n.effort}")`);
|
|
3584
|
+
}
|
|
3585
|
+
if (n.budgetTokens !== void 0 && (!Number.isFinite(n.budgetTokens) || n.budgetTokens < 0)) {
|
|
3586
|
+
throw new Error(`reasoning.native.budgetTokens must be a non-negative number (got ${n.budgetTokens})`);
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
if (input.reflection) {
|
|
3590
|
+
const r = input.reflection;
|
|
3591
|
+
if (r.cadence !== void 0 && !VALID_CADENCES.includes(r.cadence)) {
|
|
3592
|
+
throw new Error(`reasoning.reflection.cadence must be one of ${VALID_CADENCES.join(", ")} (got "${r.cadence}")`);
|
|
3593
|
+
}
|
|
3594
|
+
if (r.maxPerRun !== void 0 && (!Number.isFinite(r.maxPerRun) || r.maxPerRun < 0)) {
|
|
3595
|
+
throw new Error(`reasoning.reflection.maxPerRun must be a non-negative number (got ${r.maxPerRun})`);
|
|
3596
|
+
}
|
|
3597
|
+
if (r.everyNTurns !== void 0 && (!Number.isFinite(r.everyNTurns) || r.everyNTurns < 1)) {
|
|
3598
|
+
throw new Error(`reasoning.reflection.everyNTurns must be >= 1 (got ${r.everyNTurns})`);
|
|
3599
|
+
}
|
|
3600
|
+
if (r.feedTo !== void 0 && !["memory", "plan", "none"].includes(r.feedTo)) {
|
|
3601
|
+
throw new Error(`reasoning.reflection.feedTo must be "memory", "plan", or "none" (got "${r.feedTo}")`);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3506
3605
|
function resolveReasoning(input) {
|
|
3507
3606
|
if (!input || input.enabled === false) return void 0;
|
|
3607
|
+
validateReasoningConfig(input);
|
|
3508
3608
|
const enabled = input.enabled ?? (input.native !== void 0 || input.reflection !== void 0 || input.level !== void 0);
|
|
3509
3609
|
if (!enabled) return void 0;
|
|
3510
3610
|
const level = input.level ?? "medium";
|
|
@@ -3529,7 +3629,8 @@ function resolveReflection(input, preset) {
|
|
|
3529
3629
|
keepLast: 3,
|
|
3530
3630
|
summarize: false,
|
|
3531
3631
|
emitEvents: true,
|
|
3532
|
-
everyNTurns: 1
|
|
3632
|
+
everyNTurns: 1,
|
|
3633
|
+
feedTo: "none"
|
|
3533
3634
|
};
|
|
3534
3635
|
}
|
|
3535
3636
|
const cfg = input ?? {};
|
|
@@ -3546,7 +3647,11 @@ function resolveReflection(input, preset) {
|
|
|
3546
3647
|
promptTemplate: cfg.promptTemplate,
|
|
3547
3648
|
emitEvents: cfg.emitEvents ?? true,
|
|
3548
3649
|
maxPerRun: typeof cfg.maxPerRun === "number" && cfg.maxPerRun >= 0 ? cfg.maxPerRun : void 0,
|
|
3549
|
-
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1))
|
|
3650
|
+
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1)),
|
|
3651
|
+
feedTo: cfg.feedTo ?? "none",
|
|
3652
|
+
shouldReflect: cfg.shouldReflect,
|
|
3653
|
+
buildPrompt: cfg.buildPrompt,
|
|
3654
|
+
onReflection: cfg.onReflection
|
|
3550
3655
|
};
|
|
3551
3656
|
}
|
|
3552
3657
|
function ensureArray(value) {
|
|
@@ -4272,12 +4377,14 @@ function createAgent(opts) {
|
|
|
4272
4377
|
if (summarizationThreshold === void 0) {
|
|
4273
4378
|
state = clearNeedsSummarization(state);
|
|
4274
4379
|
}
|
|
4275
|
-
if (resolvedReasoning
|
|
4380
|
+
if (resolvedReasoning) {
|
|
4276
4381
|
const ctx = { ...state.ctx || {} };
|
|
4277
|
-
if (
|
|
4382
|
+
if (resolvedReasoning.native) {
|
|
4278
4383
|
ctx.__reasoning = resolvedReasoning.native;
|
|
4279
|
-
|
|
4384
|
+
} else {
|
|
4385
|
+
delete ctx.__reasoning;
|
|
4280
4386
|
}
|
|
4387
|
+
state = { ...state, ctx: Object.keys(ctx).length > 0 ? ctx : void 0 };
|
|
4281
4388
|
}
|
|
4282
4389
|
const mergedLimits = {
|
|
4283
4390
|
...opts.limits || {},
|
|
@@ -4325,6 +4432,7 @@ function createAgent(opts) {
|
|
|
4325
4432
|
return { breached: false };
|
|
4326
4433
|
};
|
|
4327
4434
|
let iterations = 0;
|
|
4435
|
+
let reflectionsThisRun = 0;
|
|
4328
4436
|
const onStateChange = config?.onStateChange;
|
|
4329
4437
|
const checkpointReason = config?.checkpointReason;
|
|
4330
4438
|
let pausedStage = null;
|
|
@@ -4370,6 +4478,16 @@ function createAgent(opts) {
|
|
|
4370
4478
|
pausedStage = stage;
|
|
4371
4479
|
return true;
|
|
4372
4480
|
};
|
|
4481
|
+
if (reflectNode && resolvedReasoning?.reflection.enabled && resolvedReasoning.reflection.cadence === "initial_then_after_tool" && resumeStage === null && !state.ctx?.__awaitingApproval && !state.ctx?.__awaitingUserQuestion && !state.messages.some((m) => m?.role === "assistant")) {
|
|
4482
|
+
try {
|
|
4483
|
+
const patch = await reflectNode(state, "initial_then_after_tool");
|
|
4484
|
+
if (patch && Object.keys(patch).length > 0) {
|
|
4485
|
+
state = { ...state, ...patch };
|
|
4486
|
+
reflectionsThisRun++;
|
|
4487
|
+
}
|
|
4488
|
+
} catch {
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4373
4491
|
while (iterations < iterationLimit) {
|
|
4374
4492
|
iterations++;
|
|
4375
4493
|
const budget = checkBudgetBreached();
|
|
@@ -4546,16 +4664,18 @@ function createAgent(opts) {
|
|
|
4546
4664
|
if (reflectNode && resolvedReasoning?.reflection.enabled) {
|
|
4547
4665
|
const cadence = resolvedReasoning.reflection.cadence;
|
|
4548
4666
|
const refl = resolvedReasoning.reflection;
|
|
4549
|
-
const reflectionsSoFar = state.reflections?.length ?? 0;
|
|
4550
4667
|
const lastTurn = state.reflections?.at(-1)?.turn ?? -Infinity;
|
|
4551
4668
|
const currentTurn = state.toolCallCount || 0;
|
|
4552
|
-
const budgetExceeded = typeof refl.maxPerRun === "number" &&
|
|
4553
|
-
const
|
|
4554
|
-
|
|
4669
|
+
const budgetExceeded = typeof refl.maxPerRun === "number" && reflectionsThisRun >= refl.maxPerRun;
|
|
4670
|
+
const sinceLast = currentTurn - (Number.isFinite(lastTurn) ? lastTurn : -refl.everyNTurns);
|
|
4671
|
+
const cadenceGap = sinceLast < refl.everyNTurns;
|
|
4672
|
+
const cadenceWantsIt = refl.shouldReflect ? !!refl.shouldReflect({ state, turn: currentTurn, trigger: cadence, ranToolsThisTurn: true }) : shouldRunReflection(cadence, state, true);
|
|
4673
|
+
if (!budgetExceeded && !cadenceGap && cadenceWantsIt) {
|
|
4555
4674
|
try {
|
|
4556
4675
|
const patch = await reflectNode(state, cadence);
|
|
4557
4676
|
if (patch && Object.keys(patch).length > 0) {
|
|
4558
4677
|
state = { ...state, ...patch };
|
|
4678
|
+
reflectionsThisRun++;
|
|
4559
4679
|
}
|
|
4560
4680
|
} catch {
|
|
4561
4681
|
}
|
|
@@ -6818,6 +6938,20 @@ function parseSSEBlock(block) {
|
|
|
6818
6938
|
}
|
|
6819
6939
|
|
|
6820
6940
|
// src/providers/utils/reasoning.ts
|
|
6941
|
+
var ANTHROPIC_EFFORT_BUDGET = {
|
|
6942
|
+
minimal: 1024,
|
|
6943
|
+
low: 2048,
|
|
6944
|
+
medium: 8192,
|
|
6945
|
+
high: 16384
|
|
6946
|
+
};
|
|
6947
|
+
var GEMINI_EFFORT_BUDGET = {
|
|
6948
|
+
minimal: 512,
|
|
6949
|
+
low: 1024,
|
|
6950
|
+
medium: 4096,
|
|
6951
|
+
high: 12e3
|
|
6952
|
+
};
|
|
6953
|
+
var THINKING_OUTPUT_RESERVE = 1024;
|
|
6954
|
+
var THINKING_MIN_MAX_TOKENS = 4096;
|
|
6821
6955
|
function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
6822
6956
|
if (!reasoning) return;
|
|
6823
6957
|
const effort = normalizeEffort(reasoning.effort);
|
|
@@ -6834,21 +6968,56 @@ function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
|
6834
6968
|
}
|
|
6835
6969
|
function applyAnthropicReasoning(body, reasoning) {
|
|
6836
6970
|
if (!reasoning) return;
|
|
6837
|
-
|
|
6971
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
6838
6972
|
if (!budget) return;
|
|
6973
|
+
const currentMax = typeof body.max_tokens === "number" ? body.max_tokens : 0;
|
|
6974
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
6975
|
+
if (currentMax < requiredMax) {
|
|
6976
|
+
body.max_tokens = requiredMax;
|
|
6977
|
+
}
|
|
6978
|
+
budget = clampBudget(budget, body.max_tokens);
|
|
6839
6979
|
const thinking = { type: "enabled", budget_tokens: budget };
|
|
6840
6980
|
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
6841
6981
|
body.thinking = thinking;
|
|
6982
|
+
stripSamplingParams(body, ["temperature", "top_p", "top_k"]);
|
|
6983
|
+
}
|
|
6984
|
+
function applyBedrockReasoning(body, reasoning) {
|
|
6985
|
+
if (!reasoning) return;
|
|
6986
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
6987
|
+
if (!budget) return;
|
|
6988
|
+
const inference = body.inferenceConfig ?? (body.inferenceConfig = {});
|
|
6989
|
+
const currentMax = typeof inference.maxTokens === "number" ? inference.maxTokens : 0;
|
|
6990
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
6991
|
+
if (currentMax < requiredMax) {
|
|
6992
|
+
inference.maxTokens = requiredMax;
|
|
6993
|
+
}
|
|
6994
|
+
budget = clampBudget(budget, inference.maxTokens);
|
|
6995
|
+
const extra = body.additionalModelRequestFields ?? (body.additionalModelRequestFields = {});
|
|
6996
|
+
const thinking = { type: "enabled", budget_tokens: budget };
|
|
6997
|
+
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
6998
|
+
extra.thinking = thinking;
|
|
6999
|
+
stripSamplingParams(inference, ["temperature", "topP"]);
|
|
6842
7000
|
}
|
|
6843
7001
|
function applyGeminiReasoning(generationConfig, reasoning) {
|
|
6844
7002
|
if (!reasoning) return;
|
|
6845
|
-
const budget = resolveBudget(reasoning,
|
|
7003
|
+
const budget = resolveBudget(reasoning, GEMINI_EFFORT_BUDGET);
|
|
6846
7004
|
if (budget == null) return;
|
|
6847
7005
|
const thinkingConfig = { thinkingBudget: budget };
|
|
6848
7006
|
if (reasoning.includeThoughts) thinkingConfig.includeThoughts = true;
|
|
6849
7007
|
if (reasoning.providerExtras) Object.assign(thinkingConfig, reasoning.providerExtras);
|
|
6850
7008
|
generationConfig.thinkingConfig = thinkingConfig;
|
|
6851
7009
|
}
|
|
7010
|
+
function stripSamplingParams(target, keys) {
|
|
7011
|
+
for (const k of keys) {
|
|
7012
|
+
if (k in target) delete target[k];
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
function clampBudget(budget, maxTokens) {
|
|
7016
|
+
if (typeof maxTokens !== "number" || maxTokens <= 0) return budget;
|
|
7017
|
+
const ceiling = maxTokens - THINKING_OUTPUT_RESERVE;
|
|
7018
|
+
if (ceiling < 1024) return Math.max(1024, Math.floor(maxTokens / 2));
|
|
7019
|
+
return Math.min(budget, ceiling);
|
|
7020
|
+
}
|
|
6852
7021
|
function normalizeEffort(effort) {
|
|
6853
7022
|
if (!effort) return void 0;
|
|
6854
7023
|
const allowed = ["minimal", "low", "medium", "high"];
|
|
@@ -6877,13 +7046,38 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6877
7046
|
};
|
|
6878
7047
|
if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
|
|
6879
7048
|
}
|
|
7049
|
+
/** True when the request targets a reasoning model (o-series / gpt-5) so we
|
|
7050
|
+
* should route through the Responses API, which exposes `reasoning.effort`
|
|
7051
|
+
* and reasoning summaries. Chat Completions silently drops these. */
|
|
7052
|
+
useResponsesApi(request) {
|
|
7053
|
+
if (!request.reasoning) return false;
|
|
7054
|
+
return isReasoningModel(request.model || this.defaultModel);
|
|
7055
|
+
}
|
|
6880
7056
|
async complete(request) {
|
|
7057
|
+
if (this.useResponsesApi(request)) {
|
|
7058
|
+
return this.completeResponses(request);
|
|
7059
|
+
}
|
|
6881
7060
|
const body = this.buildRequestBody(request, false);
|
|
6882
7061
|
const res = await this.doFetch(body);
|
|
6883
7062
|
const json = await res.json();
|
|
6884
7063
|
return this.parseResponse(json);
|
|
6885
7064
|
}
|
|
6886
7065
|
async *completeStream(request) {
|
|
7066
|
+
if (this.useResponsesApi(request)) {
|
|
7067
|
+
const response = await this.completeResponses(request);
|
|
7068
|
+
yield {
|
|
7069
|
+
id: response.id,
|
|
7070
|
+
model: response.model,
|
|
7071
|
+
delta: {
|
|
7072
|
+
content: response.content ?? void 0,
|
|
7073
|
+
toolCalls: response.toolCalls.length > 0 ? response.toolCalls : void 0,
|
|
7074
|
+
reasoning: response.reasoning
|
|
7075
|
+
},
|
|
7076
|
+
usage: response.usage,
|
|
7077
|
+
finishReason: response.finishReason
|
|
7078
|
+
};
|
|
7079
|
+
return;
|
|
7080
|
+
}
|
|
6887
7081
|
const body = this.buildRequestBody(request, true);
|
|
6888
7082
|
const res = await this.doFetch(body);
|
|
6889
7083
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
@@ -6982,6 +7176,156 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6982
7176
|
applyOpenAIReasoning(body, request.reasoning, "legacy_effort");
|
|
6983
7177
|
return body;
|
|
6984
7178
|
}
|
|
7179
|
+
// ─── Responses API (reasoning models) ──────────────────────────────────────
|
|
7180
|
+
async completeResponses(request) {
|
|
7181
|
+
const body = this.buildResponsesBody(request);
|
|
7182
|
+
const res = await this.responsesFetch(body);
|
|
7183
|
+
const json = await res.json();
|
|
7184
|
+
return this.parseResponsesResponse(json, request.model || this.defaultModel);
|
|
7185
|
+
}
|
|
7186
|
+
buildResponsesBody(request) {
|
|
7187
|
+
const body = {
|
|
7188
|
+
model: request.model || this.defaultModel,
|
|
7189
|
+
input: request.messages.map((m) => this.toResponsesInput(m))
|
|
7190
|
+
};
|
|
7191
|
+
if (request.maxTokens != null) body.max_output_tokens = request.maxTokens;
|
|
7192
|
+
if (request.topP != null) body.top_p = request.topP;
|
|
7193
|
+
if (request.tools?.length) {
|
|
7194
|
+
body.tools = request.tools.map((t) => ({
|
|
7195
|
+
type: "function",
|
|
7196
|
+
name: t.name,
|
|
7197
|
+
description: t.description,
|
|
7198
|
+
parameters: t.parameters,
|
|
7199
|
+
...t.strict ? { strict: true } : {}
|
|
7200
|
+
}));
|
|
7201
|
+
}
|
|
7202
|
+
if (request.toolChoice != null && request.tools?.length) {
|
|
7203
|
+
if (typeof request.toolChoice === "string") {
|
|
7204
|
+
body.tool_choice = request.toolChoice;
|
|
7205
|
+
} else {
|
|
7206
|
+
body.tool_choice = { type: "function", name: request.toolChoice.name };
|
|
7207
|
+
}
|
|
7208
|
+
}
|
|
7209
|
+
if (request.responseFormat) {
|
|
7210
|
+
if (request.responseFormat.type === "json_schema") {
|
|
7211
|
+
body.text = {
|
|
7212
|
+
format: {
|
|
7213
|
+
type: "json_schema",
|
|
7214
|
+
name: request.responseFormat.name ?? "response",
|
|
7215
|
+
schema: request.responseFormat.schema,
|
|
7216
|
+
strict: true
|
|
7217
|
+
}
|
|
7218
|
+
};
|
|
7219
|
+
} else if (request.responseFormat.type === "json_object") {
|
|
7220
|
+
body.text = { format: { type: "json_object" } };
|
|
7221
|
+
}
|
|
7222
|
+
}
|
|
7223
|
+
if (request.extra) Object.assign(body, request.extra);
|
|
7224
|
+
applyOpenAIReasoning(body, request.reasoning, "responses");
|
|
7225
|
+
return body;
|
|
7226
|
+
}
|
|
7227
|
+
/** Maps a unified message to a Responses API `input` item. */
|
|
7228
|
+
toResponsesInput(m) {
|
|
7229
|
+
if (m.role === "tool" && m.toolCallId) {
|
|
7230
|
+
const output = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
|
|
7231
|
+
return { type: "function_call_output", call_id: m.toolCallId, output };
|
|
7232
|
+
}
|
|
7233
|
+
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7234
|
+
return {
|
|
7235
|
+
__assistantWithCalls: true,
|
|
7236
|
+
text: typeof m.content === "string" ? m.content : "",
|
|
7237
|
+
calls: m.toolCalls.map((tc) => ({
|
|
7238
|
+
type: "function_call",
|
|
7239
|
+
call_id: tc.id,
|
|
7240
|
+
name: tc.name,
|
|
7241
|
+
arguments: tc.arguments
|
|
7242
|
+
}))
|
|
7243
|
+
};
|
|
7244
|
+
}
|
|
7245
|
+
const role = m.role === "system" ? "system" : m.role === "assistant" ? "assistant" : "user";
|
|
7246
|
+
const textType = role === "assistant" ? "output_text" : "input_text";
|
|
7247
|
+
if (typeof m.content === "string") {
|
|
7248
|
+
return { role, content: [{ type: textType, text: m.content }] };
|
|
7249
|
+
}
|
|
7250
|
+
const content = m.content.map((part) => {
|
|
7251
|
+
if (part.type === "text") return { type: textType, text: part.text };
|
|
7252
|
+
if (part.type === "image") {
|
|
7253
|
+
const src = part.source;
|
|
7254
|
+
const url = src.type === "url" ? src.url : `data:${src.mediaType};base64,${src.data}`;
|
|
7255
|
+
return { type: "input_image", image_url: url };
|
|
7256
|
+
}
|
|
7257
|
+
return { type: textType, text: "" };
|
|
7258
|
+
});
|
|
7259
|
+
return { role, content };
|
|
7260
|
+
}
|
|
7261
|
+
async responsesFetch(body) {
|
|
7262
|
+
body.input = expandResponsesInput(body.input);
|
|
7263
|
+
const url = `${this.baseURL}/responses`;
|
|
7264
|
+
const headers = {
|
|
7265
|
+
"Content-Type": "application/json",
|
|
7266
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
7267
|
+
...this.defaultHeaders
|
|
7268
|
+
};
|
|
7269
|
+
const payload = JSON.stringify(body);
|
|
7270
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
7271
|
+
if (!res.ok) {
|
|
7272
|
+
const text = await res.text().catch(() => "");
|
|
7273
|
+
throw new ProviderError(
|
|
7274
|
+
`OpenAI Responses API error ${res.status}: ${text}`,
|
|
7275
|
+
this.providerName,
|
|
7276
|
+
res.status,
|
|
7277
|
+
text
|
|
7278
|
+
);
|
|
7279
|
+
}
|
|
7280
|
+
return res;
|
|
7281
|
+
}
|
|
7282
|
+
parseResponsesResponse(json, modelId) {
|
|
7283
|
+
const textParts = [];
|
|
7284
|
+
const toolCalls = [];
|
|
7285
|
+
const summaryParts = [];
|
|
7286
|
+
for (const item of json.output ?? []) {
|
|
7287
|
+
if (item.type === "message") {
|
|
7288
|
+
for (const c of item.content ?? []) {
|
|
7289
|
+
if (c.type === "output_text" && typeof c.text === "string") textParts.push(c.text);
|
|
7290
|
+
}
|
|
7291
|
+
} else if (item.type === "function_call") {
|
|
7292
|
+
toolCalls.push({
|
|
7293
|
+
id: item.call_id ?? item.id ?? "",
|
|
7294
|
+
name: item.name ?? "",
|
|
7295
|
+
arguments: typeof item.arguments === "string" ? item.arguments : JSON.stringify(item.arguments ?? {})
|
|
7296
|
+
});
|
|
7297
|
+
} else if (item.type === "reasoning") {
|
|
7298
|
+
for (const s of item.summary ?? []) {
|
|
7299
|
+
if (typeof s.text === "string") summaryParts.push(s.text);
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7302
|
+
}
|
|
7303
|
+
if (textParts.length === 0 && typeof json.output_text === "string") {
|
|
7304
|
+
textParts.push(json.output_text);
|
|
7305
|
+
}
|
|
7306
|
+
const usage = json.usage ?? {};
|
|
7307
|
+
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0;
|
|
7308
|
+
const tokenUsage = {
|
|
7309
|
+
inputTokens: usage.input_tokens ?? 0,
|
|
7310
|
+
outputTokens: usage.output_tokens ?? 0,
|
|
7311
|
+
totalTokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
|
|
7312
|
+
cachedInputTokens: usage.input_tokens_details?.cached_tokens ?? 0,
|
|
7313
|
+
cachedWriteTokens: 0,
|
|
7314
|
+
cachedOutputTokens: 0,
|
|
7315
|
+
reasoningTokens
|
|
7316
|
+
};
|
|
7317
|
+
const finishReason = toolCalls.length > 0 ? "tool_calls" : json.status === "incomplete" ? "length" : "stop";
|
|
7318
|
+
return {
|
|
7319
|
+
id: json.id ?? "",
|
|
7320
|
+
model: json.model ?? modelId,
|
|
7321
|
+
content: textParts.join("") || null,
|
|
7322
|
+
toolCalls,
|
|
7323
|
+
usage: tokenUsage,
|
|
7324
|
+
finishReason,
|
|
7325
|
+
reasoning: summaryParts.length > 0 ? { summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7326
|
+
raw: json
|
|
7327
|
+
};
|
|
7328
|
+
}
|
|
6985
7329
|
toOpenAIMessage(m) {
|
|
6986
7330
|
const msg = { role: m.role };
|
|
6987
7331
|
if (typeof m.content === "string") {
|
|
@@ -7074,6 +7418,25 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
7074
7418
|
};
|
|
7075
7419
|
}
|
|
7076
7420
|
};
|
|
7421
|
+
function isReasoningModel(model) {
|
|
7422
|
+
if (!model) return false;
|
|
7423
|
+
const m = model.toLowerCase();
|
|
7424
|
+
return /(^|[/_-])o[0-9]/.test(m) || m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.includes("gpt-5") || m.includes("gpt5");
|
|
7425
|
+
}
|
|
7426
|
+
function expandResponsesInput(input) {
|
|
7427
|
+
const out = [];
|
|
7428
|
+
for (const item of input) {
|
|
7429
|
+
if (item && item.__assistantWithCalls) {
|
|
7430
|
+
if (item.text) {
|
|
7431
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
7432
|
+
}
|
|
7433
|
+
for (const call of item.calls) out.push(call);
|
|
7434
|
+
} else {
|
|
7435
|
+
out.push(item);
|
|
7436
|
+
}
|
|
7437
|
+
}
|
|
7438
|
+
return out;
|
|
7439
|
+
}
|
|
7077
7440
|
function mapFinishReason(reason) {
|
|
7078
7441
|
switch (reason) {
|
|
7079
7442
|
case "stop":
|
|
@@ -7119,6 +7482,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7119
7482
|
let cacheReadInputTokens = 0;
|
|
7120
7483
|
let cacheCreationInputTokens = 0;
|
|
7121
7484
|
const currentToolCalls = /* @__PURE__ */ new Map();
|
|
7485
|
+
const reasoningBlocks = /* @__PURE__ */ new Map();
|
|
7122
7486
|
for await (const event of parseSSEStream(res.body)) {
|
|
7123
7487
|
let data;
|
|
7124
7488
|
try {
|
|
@@ -7148,6 +7512,10 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7148
7512
|
name: block.name ?? "",
|
|
7149
7513
|
arguments: ""
|
|
7150
7514
|
});
|
|
7515
|
+
} else if (block?.type === "thinking") {
|
|
7516
|
+
reasoningBlocks.set(idx, { type: "thinking", text: block.thinking ?? "", signature: block.signature });
|
|
7517
|
+
} else if (block?.type === "redacted_thinking") {
|
|
7518
|
+
reasoningBlocks.set(idx, { type: "redacted_thinking", data: block.data });
|
|
7151
7519
|
}
|
|
7152
7520
|
break;
|
|
7153
7521
|
}
|
|
@@ -7160,6 +7528,19 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7160
7528
|
model,
|
|
7161
7529
|
delta: { content: delta.text }
|
|
7162
7530
|
};
|
|
7531
|
+
} else if (delta?.type === "thinking_delta" && delta.thinking) {
|
|
7532
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7533
|
+
blk.text = (blk.text ?? "") + delta.thinking;
|
|
7534
|
+
reasoningBlocks.set(idx, blk);
|
|
7535
|
+
yield {
|
|
7536
|
+
id,
|
|
7537
|
+
model,
|
|
7538
|
+
delta: { reasoning: { summary: delta.thinking } }
|
|
7539
|
+
};
|
|
7540
|
+
} else if (delta?.type === "signature_delta" && delta.signature) {
|
|
7541
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7542
|
+
blk.signature = (blk.signature ?? "") + delta.signature;
|
|
7543
|
+
reasoningBlocks.set(idx, blk);
|
|
7163
7544
|
} else if (delta?.type === "input_json_delta" && delta.partial_json) {
|
|
7164
7545
|
const tc = currentToolCalls.get(idx);
|
|
7165
7546
|
if (tc) {
|
|
@@ -7192,10 +7573,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7192
7573
|
cachedOutputTokens: 0,
|
|
7193
7574
|
reasoningTokens: 0
|
|
7194
7575
|
};
|
|
7576
|
+
const blocks = [...reasoningBlocks.values()].filter(
|
|
7577
|
+
(b) => b.type === "thinking" && b.signature || b.type === "redacted_thinking" && b.data
|
|
7578
|
+
);
|
|
7195
7579
|
yield {
|
|
7196
7580
|
id,
|
|
7197
7581
|
model,
|
|
7198
|
-
delta: {},
|
|
7582
|
+
delta: blocks.length > 0 ? { reasoning: { blocks } } : {},
|
|
7199
7583
|
finishReason,
|
|
7200
7584
|
usage
|
|
7201
7585
|
};
|
|
@@ -7287,6 +7671,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7287
7671
|
}
|
|
7288
7672
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7289
7673
|
const content = [];
|
|
7674
|
+
appendReasoningBlocks(content, m.reasoning?.blocks);
|
|
7290
7675
|
if (typeof m.content === "string" && m.content) {
|
|
7291
7676
|
content.push({ type: "text", text: m.content });
|
|
7292
7677
|
}
|
|
@@ -7300,6 +7685,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7300
7685
|
}
|
|
7301
7686
|
return { role: "assistant", content };
|
|
7302
7687
|
}
|
|
7688
|
+
if (m.role === "assistant" && m.reasoning?.blocks?.length) {
|
|
7689
|
+
const content = [];
|
|
7690
|
+
appendReasoningBlocks(content, m.reasoning.blocks);
|
|
7691
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
7692
|
+
if (text) content.push({ type: "text", text });
|
|
7693
|
+
return { role: "assistant", content };
|
|
7694
|
+
}
|
|
7303
7695
|
const msg = { role: m.role };
|
|
7304
7696
|
if (typeof m.content === "string") {
|
|
7305
7697
|
msg.content = m.content;
|
|
@@ -7355,9 +7747,20 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7355
7747
|
parseResponse(json) {
|
|
7356
7748
|
const textParts = [];
|
|
7357
7749
|
const toolCalls = [];
|
|
7750
|
+
const reasoningBlocks = [];
|
|
7751
|
+
const summaryParts = [];
|
|
7358
7752
|
for (const block of json.content ?? []) {
|
|
7359
7753
|
if (block.type === "text") {
|
|
7360
7754
|
textParts.push(block.text);
|
|
7755
|
+
} else if (block.type === "thinking") {
|
|
7756
|
+
reasoningBlocks.push({
|
|
7757
|
+
type: "thinking",
|
|
7758
|
+
text: block.thinking ?? "",
|
|
7759
|
+
signature: block.signature
|
|
7760
|
+
});
|
|
7761
|
+
if (block.thinking) summaryParts.push(block.thinking);
|
|
7762
|
+
} else if (block.type === "redacted_thinking") {
|
|
7763
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: block.data });
|
|
7361
7764
|
} else if (block.type === "tool_use") {
|
|
7362
7765
|
toolCalls.push({
|
|
7363
7766
|
id: block.id,
|
|
@@ -7374,6 +7777,9 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7374
7777
|
cachedInputTokens: usage.cache_read_input_tokens ?? 0,
|
|
7375
7778
|
cachedWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
7376
7779
|
cachedOutputTokens: 0,
|
|
7780
|
+
// Anthropic bills thinking tokens inside `output_tokens` and does not
|
|
7781
|
+
// expose a separate count, so reasoningTokens stays 0 here (cost is still
|
|
7782
|
+
// captured via outputTokens). See docs for the limitation.
|
|
7377
7783
|
reasoningTokens: 0
|
|
7378
7784
|
};
|
|
7379
7785
|
return {
|
|
@@ -7383,6 +7789,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7383
7789
|
toolCalls,
|
|
7384
7790
|
usage: tokenUsage,
|
|
7385
7791
|
finishReason: mapAnthropicStopReason(json.stop_reason),
|
|
7792
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7386
7793
|
raw: json
|
|
7387
7794
|
};
|
|
7388
7795
|
}
|
|
@@ -7407,6 +7814,18 @@ function safeJsonParse(str) {
|
|
|
7407
7814
|
return {};
|
|
7408
7815
|
}
|
|
7409
7816
|
}
|
|
7817
|
+
function appendReasoningBlocks(content, blocks) {
|
|
7818
|
+
if (!blocks?.length) return;
|
|
7819
|
+
for (const b of blocks) {
|
|
7820
|
+
if (b.type === "redacted_thinking") {
|
|
7821
|
+
if (b.data) content.push({ type: "redacted_thinking", data: b.data });
|
|
7822
|
+
} else if (b.type === "thinking") {
|
|
7823
|
+
if (b.signature) {
|
|
7824
|
+
content.push({ type: "thinking", thinking: b.text ?? "", signature: b.signature });
|
|
7825
|
+
}
|
|
7826
|
+
}
|
|
7827
|
+
}
|
|
7828
|
+
}
|
|
7410
7829
|
|
|
7411
7830
|
// src/providers/azure.ts
|
|
7412
7831
|
var AzureProvider = class extends OpenAIProvider {
|
|
@@ -7450,7 +7869,52 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
7450
7869
|
}
|
|
7451
7870
|
return res;
|
|
7452
7871
|
}
|
|
7872
|
+
/** Azure exposes the Responses API at /openai/responses with api-key auth.
|
|
7873
|
+
* Reasoning summaries require a preview api-version; callers can override via
|
|
7874
|
+
* the `apiVersion` config. */
|
|
7875
|
+
async responsesFetch(body) {
|
|
7876
|
+
body.input = expandAzureResponsesInput(body.input);
|
|
7877
|
+
const deployment = this.deploymentName ?? body.model;
|
|
7878
|
+
if (!deployment) {
|
|
7879
|
+
throw new ProviderError("Azure requires a deploymentName or model", this.providerName);
|
|
7880
|
+
}
|
|
7881
|
+
const url = `${this.endpoint}/openai/responses?api-version=${this.apiVersion}`;
|
|
7882
|
+
const payload = JSON.stringify({ ...body, model: deployment });
|
|
7883
|
+
const res = await fetch(url, {
|
|
7884
|
+
method: "POST",
|
|
7885
|
+
headers: {
|
|
7886
|
+
"Content-Type": "application/json",
|
|
7887
|
+
"api-key": this.azureApiKey,
|
|
7888
|
+
...this.defaultHeaders
|
|
7889
|
+
},
|
|
7890
|
+
body: payload
|
|
7891
|
+
});
|
|
7892
|
+
if (!res.ok) {
|
|
7893
|
+
const text = await res.text().catch(() => "");
|
|
7894
|
+
throw new ProviderError(
|
|
7895
|
+
`Azure OpenAI Responses API error ${res.status}: ${text}`,
|
|
7896
|
+
this.providerName,
|
|
7897
|
+
res.status,
|
|
7898
|
+
text
|
|
7899
|
+
);
|
|
7900
|
+
}
|
|
7901
|
+
return res;
|
|
7902
|
+
}
|
|
7453
7903
|
};
|
|
7904
|
+
function expandAzureResponsesInput(input) {
|
|
7905
|
+
const out = [];
|
|
7906
|
+
for (const item of input) {
|
|
7907
|
+
if (item && item.__assistantWithCalls) {
|
|
7908
|
+
if (item.text) {
|
|
7909
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
7910
|
+
}
|
|
7911
|
+
for (const call of item.calls) out.push(call);
|
|
7912
|
+
} else {
|
|
7913
|
+
out.push(item);
|
|
7914
|
+
}
|
|
7915
|
+
}
|
|
7916
|
+
return out;
|
|
7917
|
+
}
|
|
7454
7918
|
|
|
7455
7919
|
// src/providers/openaiCompatible.ts
|
|
7456
7920
|
var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
@@ -7623,6 +8087,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7623
8087
|
if (request.extra) {
|
|
7624
8088
|
Object.assign(body, request.extra);
|
|
7625
8089
|
}
|
|
8090
|
+
applyBedrockReasoning(body, request.reasoning);
|
|
7626
8091
|
return body;
|
|
7627
8092
|
}
|
|
7628
8093
|
splitSystemMessages(messages) {
|
|
@@ -7656,6 +8121,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7656
8121
|
}
|
|
7657
8122
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7658
8123
|
const content2 = [];
|
|
8124
|
+
appendBedrockReasoning(content2, m.reasoning?.blocks);
|
|
7659
8125
|
if (typeof m.content === "string" && m.content) {
|
|
7660
8126
|
content2.push({ text: m.content });
|
|
7661
8127
|
}
|
|
@@ -7736,9 +8202,23 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7736
8202
|
const output = json.output?.message;
|
|
7737
8203
|
const textParts = [];
|
|
7738
8204
|
const toolCalls = [];
|
|
8205
|
+
const reasoningBlocks = [];
|
|
8206
|
+
const summaryParts = [];
|
|
7739
8207
|
for (const block of output?.content ?? []) {
|
|
7740
8208
|
if (block.text) {
|
|
7741
8209
|
textParts.push(block.text);
|
|
8210
|
+
} else if (block.reasoningContent) {
|
|
8211
|
+
const rc = block.reasoningContent;
|
|
8212
|
+
if (rc.reasoningText) {
|
|
8213
|
+
reasoningBlocks.push({
|
|
8214
|
+
type: "thinking",
|
|
8215
|
+
text: rc.reasoningText.text ?? "",
|
|
8216
|
+
signature: rc.reasoningText.signature
|
|
8217
|
+
});
|
|
8218
|
+
if (rc.reasoningText.text) summaryParts.push(rc.reasoningText.text);
|
|
8219
|
+
} else if (rc.redactedContent) {
|
|
8220
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: rc.redactedContent });
|
|
8221
|
+
}
|
|
7742
8222
|
} else if (block.toolUse) {
|
|
7743
8223
|
toolCalls.push({
|
|
7744
8224
|
id: block.toolUse.toolUseId,
|
|
@@ -7755,6 +8235,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7755
8235
|
cachedInputTokens: usage.cacheReadInputTokenCount ?? 0,
|
|
7756
8236
|
cachedWriteTokens: usage.cacheWriteInputTokenCount ?? 0,
|
|
7757
8237
|
cachedOutputTokens: 0,
|
|
8238
|
+
// Bedrock bills thinking tokens inside outputTokens; no separate count.
|
|
7758
8239
|
reasoningTokens: 0
|
|
7759
8240
|
};
|
|
7760
8241
|
return {
|
|
@@ -7764,10 +8245,25 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7764
8245
|
toolCalls,
|
|
7765
8246
|
usage: tokenUsage,
|
|
7766
8247
|
finishReason: mapBedrockStopReason(json.stopReason),
|
|
8248
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7767
8249
|
raw: json
|
|
7768
8250
|
};
|
|
7769
8251
|
}
|
|
7770
8252
|
};
|
|
8253
|
+
function appendBedrockReasoning(content, blocks) {
|
|
8254
|
+
if (!blocks?.length) return;
|
|
8255
|
+
for (const b of blocks) {
|
|
8256
|
+
if (b.type === "redacted_thinking") {
|
|
8257
|
+
if (b.data) content.push({ reasoningContent: { redactedContent: b.data } });
|
|
8258
|
+
} else if (b.type === "thinking") {
|
|
8259
|
+
if (b.signature) {
|
|
8260
|
+
content.push({
|
|
8261
|
+
reasoningContent: { reasoningText: { text: b.text ?? "", signature: b.signature } }
|
|
8262
|
+
});
|
|
8263
|
+
}
|
|
8264
|
+
}
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
7771
8267
|
function mapBedrockStopReason(reason) {
|
|
7772
8268
|
switch (reason) {
|
|
7773
8269
|
case "end_turn":
|
|
@@ -8090,10 +8586,15 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8090
8586
|
const parts = candidate?.content?.parts ?? [];
|
|
8091
8587
|
const textParts = [];
|
|
8092
8588
|
const toolCalls = [];
|
|
8589
|
+
const thoughtParts = [];
|
|
8093
8590
|
let toolCallIdx = 0;
|
|
8094
8591
|
for (const part of parts) {
|
|
8095
8592
|
if (part.text) {
|
|
8096
|
-
|
|
8593
|
+
if (part.thought === true) {
|
|
8594
|
+
thoughtParts.push(part.text);
|
|
8595
|
+
} else {
|
|
8596
|
+
textParts.push(part.text);
|
|
8597
|
+
}
|
|
8097
8598
|
} else if (part.functionCall) {
|
|
8098
8599
|
toolCalls.push({
|
|
8099
8600
|
id: `call_${toolCallIdx++}`,
|
|
@@ -8119,6 +8620,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8119
8620
|
toolCalls,
|
|
8120
8621
|
usage: tokenUsage,
|
|
8121
8622
|
finishReason: mapGeminiFinishReason(candidate?.finishReason),
|
|
8623
|
+
reasoning: thoughtParts.length > 0 ? { summary: thoughtParts.join("\n").trim() || void 0 } : void 0,
|
|
8122
8624
|
raw: json
|
|
8123
8625
|
};
|
|
8124
8626
|
}
|
|
@@ -8128,7 +8630,11 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8128
8630
|
const delta = {};
|
|
8129
8631
|
for (const part of parts) {
|
|
8130
8632
|
if (part.text) {
|
|
8131
|
-
|
|
8633
|
+
if (part.thought === true) {
|
|
8634
|
+
delta.reasoning = { summary: (delta.reasoning?.summary ?? "") + part.text };
|
|
8635
|
+
} else {
|
|
8636
|
+
delta.content = (delta.content ?? "") + part.text;
|
|
8637
|
+
}
|
|
8132
8638
|
} else if (part.functionCall) {
|
|
8133
8639
|
if (!delta.toolCalls) delta.toolCalls = [];
|
|
8134
8640
|
delta.toolCalls.push({
|
|
@@ -8202,12 +8708,16 @@ function fromNativeProvider(provider, options) {
|
|
|
8202
8708
|
let fullContent = "";
|
|
8203
8709
|
let allToolCalls = [];
|
|
8204
8710
|
let lastUsage;
|
|
8711
|
+
let reasoningBlocks;
|
|
8205
8712
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
8206
8713
|
for await (const chunk of provider.completeStream(request)) {
|
|
8207
8714
|
if (chunk.delta.content) {
|
|
8208
8715
|
fullContent += chunk.delta.content;
|
|
8209
8716
|
yield chunk.delta.content;
|
|
8210
8717
|
}
|
|
8718
|
+
if (chunk.delta.reasoning?.blocks?.length) {
|
|
8719
|
+
reasoningBlocks = chunk.delta.reasoning.blocks;
|
|
8720
|
+
}
|
|
8211
8721
|
if (chunk.delta.toolCalls) {
|
|
8212
8722
|
for (const tc of chunk.delta.toolCalls) {
|
|
8213
8723
|
if (tc.id) {
|
|
@@ -8228,6 +8738,9 @@ function fromNativeProvider(provider, options) {
|
|
|
8228
8738
|
}
|
|
8229
8739
|
allToolCalls = [...toolCallBuffers.values()];
|
|
8230
8740
|
const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
|
|
8741
|
+
if (reasoningBlocks?.length) {
|
|
8742
|
+
finalMessage.reasoning = { blocks: reasoningBlocks };
|
|
8743
|
+
}
|
|
8231
8744
|
yield finalMessage;
|
|
8232
8745
|
},
|
|
8233
8746
|
bindTools: (tools, _bindOptions) => {
|
|
@@ -8290,6 +8803,10 @@ function toUnifiedMessage(msg) {
|
|
|
8290
8803
|
arguments: tc.function?.arguments ?? tc.arguments ?? "{}"
|
|
8291
8804
|
}));
|
|
8292
8805
|
}
|
|
8806
|
+
const reasoning = msg.reasoning;
|
|
8807
|
+
if (reasoning && (reasoning.blocks?.length || reasoning.summary)) {
|
|
8808
|
+
unified.reasoning = reasoning;
|
|
8809
|
+
}
|
|
8293
8810
|
return unified;
|
|
8294
8811
|
}
|
|
8295
8812
|
function convertContent(content) {
|
|
@@ -8498,6 +9015,9 @@ function toBaseChatMessage(response) {
|
|
|
8498
9015
|
function: { name: tc.name, arguments: tc.arguments }
|
|
8499
9016
|
}));
|
|
8500
9017
|
}
|
|
9018
|
+
if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
|
|
9019
|
+
msg.reasoning = response.reasoning;
|
|
9020
|
+
}
|
|
8501
9021
|
return msg;
|
|
8502
9022
|
}
|
|
8503
9023
|
function assembleMessage(content, toolCalls, usage) {
|
|
@@ -8594,6 +9114,6 @@ function createProvider(config) {
|
|
|
8594
9114
|
}
|
|
8595
9115
|
}
|
|
8596
9116
|
|
|
8597
|
-
export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, DEFAULT_PROFILE_CONFIGS, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, buildSystemPrompt, captureSnapshot, codePresenceRule, cognipeerSink, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createCodeGuardrail, createContextSummarizeNode, createContextTools, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createProvider, createRegexGuardrail, createResolverNode, createSmartAgent, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, defaultTokenCounter, emptyUsage, evaluateGuardrails, fileSink, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, normalizeSmartAgentOptions, otlpSink, readMemoryFacts, regexRule, resolveMemoryStore, resolveStrategy, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, setTokenCounter, startStreamingSession, traceSessionToOtlp, withTools, writeSummaryFactsToMemory };
|
|
9117
|
+
export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, DEFAULT_PROFILE_CONFIGS, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, buildSystemPrompt, captureSnapshot, codePresenceRule, cognipeerSink, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createCodeGuardrail, createContextSummarizeNode, createContextTools, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createProvider, createRegexGuardrail, createResolverNode, createSmartAgent, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, defaultTokenCounter, emptyUsage, evaluateGuardrails, fileSink, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, normalizeSmartAgentOptions, otlpSink, readMemoryFacts, regexRule, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, setTokenCounter, startStreamingSession, traceSessionToOtlp, validateReasoningConfig, withTools, writeSummaryFactsToMemory };
|
|
8598
9118
|
//# sourceMappingURL=index.mjs.map
|
|
8599
9119
|
//# sourceMappingURL=index.mjs.map
|