@cognipeer/agent-sdk 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -1
- package/dist/index.cjs +784 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +235 -3
- package/dist/index.d.ts +235 -3
- package/dist/index.mjs +771 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3036,6 +3036,17 @@ function createToolsNode(initialTools, opts) {
|
|
|
3036
3036
|
}
|
|
3037
3037
|
const durationMs = Date.now() - start;
|
|
3038
3038
|
const executionId = nanoid.nanoid();
|
|
3039
|
+
if (output && typeof output === "object" && Array.isArray(output.__runtimeToolsDelta)) {
|
|
3040
|
+
const delta = output.__runtimeToolsDelta;
|
|
3041
|
+
delete output.__runtimeToolsDelta;
|
|
3042
|
+
const currentRuntime = state.agent || runtime;
|
|
3043
|
+
const currentTools = currentRuntime?.tools ?? [];
|
|
3044
|
+
const present = new Set(currentTools.map((tool2) => tool2?.name));
|
|
3045
|
+
const additions = delta.filter((tool2) => tool2 && tool2.name && !present.has(tool2.name));
|
|
3046
|
+
if (additions.length > 0 && currentRuntime) {
|
|
3047
|
+
state.agent = { ...currentRuntime, tools: [...currentTools, ...additions] };
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3039
3050
|
if (output && typeof output === "object" && output.__handoff && output.__handoff.runtime) {
|
|
3040
3051
|
toolHistory.push({ executionId, toolName, args, output: "handoff:ok", rawOutput: output, timestamp: (/* @__PURE__ */ new Date()).toISOString(), tool_call_id: tc.id, status: "handoff" });
|
|
3041
3052
|
push({ role: "tool", content: "ok", tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
|
|
@@ -3345,15 +3356,40 @@ function countToolCallsInLastTurn(state) {
|
|
|
3345
3356
|
function stripReflectionAskMessages(messages) {
|
|
3346
3357
|
return messages.filter((m) => !(m?.role === "user" && m?.name === REFLECTION_ASK_NAME));
|
|
3347
3358
|
}
|
|
3359
|
+
function lastTwoToolTurns(state) {
|
|
3360
|
+
const groups = [];
|
|
3361
|
+
let cur = [];
|
|
3362
|
+
let sawTool = false;
|
|
3363
|
+
for (let i = state.messages.length - 1; i >= 0; i--) {
|
|
3364
|
+
const m = state.messages[i];
|
|
3365
|
+
if (m?.role === "tool") {
|
|
3366
|
+
if (m.name) cur.push(m.name);
|
|
3367
|
+
sawTool = true;
|
|
3368
|
+
} else if (m?.role === "assistant") {
|
|
3369
|
+
if (sawTool) {
|
|
3370
|
+
groups.push(cur);
|
|
3371
|
+
cur = [];
|
|
3372
|
+
sawTool = false;
|
|
3373
|
+
if (groups.length >= 2) break;
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
if (sawTool && cur.length) groups.push(cur);
|
|
3378
|
+
return { current: groups[0] ?? [], previous: groups[1] ?? [] };
|
|
3379
|
+
}
|
|
3348
3380
|
function shouldRunReflection(cadence, state, ranToolsThisTurn) {
|
|
3349
3381
|
if (cadence === "off") return false;
|
|
3350
3382
|
if (cadence === "every_turn") return true;
|
|
3351
3383
|
if (cadence === "after_tool") return ranToolsThisTurn;
|
|
3384
|
+
if (cadence === "initial_then_after_tool") return ranToolsThisTurn;
|
|
3352
3385
|
if (cadence === "on_branch") {
|
|
3353
|
-
const
|
|
3354
|
-
|
|
3355
|
-
const
|
|
3356
|
-
|
|
3386
|
+
const { current, previous } = lastTwoToolTurns(state);
|
|
3387
|
+
if (previous.length === 0) return true;
|
|
3388
|
+
const a = new Set(current);
|
|
3389
|
+
const b = new Set(previous);
|
|
3390
|
+
for (const n of a) if (!b.has(n)) return true;
|
|
3391
|
+
for (const n of b) if (!a.has(n)) return true;
|
|
3392
|
+
return false;
|
|
3357
3393
|
}
|
|
3358
3394
|
return false;
|
|
3359
3395
|
}
|
|
@@ -3370,7 +3406,10 @@ function createReflectionNode(opts, resolved) {
|
|
|
3370
3406
|
const onEvent = state.ctx?.__onEvent;
|
|
3371
3407
|
const traceSession = state.ctx?.__traceSession;
|
|
3372
3408
|
const maxChars = resolved.maxChars;
|
|
3373
|
-
const
|
|
3409
|
+
const turnNow = state.toolCallCount ?? 0;
|
|
3410
|
+
const hookCtx = { state, turn: turnNow, trigger, ranToolsThisTurn: true };
|
|
3411
|
+
const defaultPrompt = (resolved.promptTemplate || DEFAULT_REFLECT_PROMPT).replace(/\$\{maxChars\}/g, String(maxChars));
|
|
3412
|
+
const promptBody = resolved.buildPrompt ? String(resolved.buildPrompt({ ...hookCtx, defaultPrompt, maxChars }) ?? defaultPrompt) : defaultPrompt;
|
|
3374
3413
|
const baseMessages = stripReflectionAskMessages([...state.messages]);
|
|
3375
3414
|
const askMessage = {
|
|
3376
3415
|
role: "user",
|
|
@@ -3404,6 +3443,8 @@ function createReflectionNode(opts, resolved) {
|
|
|
3404
3443
|
const rawText = extractText(response);
|
|
3405
3444
|
const text = trimToChars(String(rawText ?? "").trim(), maxChars);
|
|
3406
3445
|
if (!text) return {};
|
|
3446
|
+
const prevText = (state.reflections?.[state.reflections.length - 1]?.text || "").trim();
|
|
3447
|
+
if (prevText && isNearDuplicate(prevText, text)) return {};
|
|
3407
3448
|
const rawUsage = response?.usage_metadata || response?.response_metadata?.usage || response?.usage || response?.additional_kwargs?.usage;
|
|
3408
3449
|
const usage = normalizeUsage(rawUsage);
|
|
3409
3450
|
const { ids, names } = countToolCallsInLastTurn(state);
|
|
@@ -3452,6 +3493,12 @@ function createReflectionNode(opts, resolved) {
|
|
|
3452
3493
|
} catch (e) {
|
|
3453
3494
|
}
|
|
3454
3495
|
}
|
|
3496
|
+
if (resolved.onReflection) {
|
|
3497
|
+
try {
|
|
3498
|
+
resolved.onReflection(record, hookCtx);
|
|
3499
|
+
} catch {
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3455
3502
|
const nextMessages = stripReflectionAskMessages([...state.messages]);
|
|
3456
3503
|
const reflections = [...state.reflections || [], record];
|
|
3457
3504
|
const kept = reflections.slice(-Math.max(1, resolved.keepLast));
|
|
@@ -3468,7 +3515,20 @@ ${r.text}
|
|
|
3468
3515
|
metadata: { reflectionId: r.id, reflectionTurn: r.turn, reflectionTrigger: r.trigger }
|
|
3469
3516
|
});
|
|
3470
3517
|
}
|
|
3471
|
-
|
|
3518
|
+
const patch = { messages: prunedMessages, reflections };
|
|
3519
|
+
if (resolved.feedTo === "memory") {
|
|
3520
|
+
const fact = {
|
|
3521
|
+
key: `reflection_turn_${turn}`,
|
|
3522
|
+
value: text,
|
|
3523
|
+
sourceTurn: turn,
|
|
3524
|
+
confidence: 0.3,
|
|
3525
|
+
tags: ["reflection"]
|
|
3526
|
+
};
|
|
3527
|
+
patch.memoryFacts = [...state.memoryFacts || [], fact];
|
|
3528
|
+
} else if (resolved.feedTo === "plan" && state.plan) {
|
|
3529
|
+
patch.plan = { ...state.plan, lastReflection: text };
|
|
3530
|
+
}
|
|
3531
|
+
return patch;
|
|
3472
3532
|
};
|
|
3473
3533
|
}
|
|
3474
3534
|
function extractText(chunk) {
|
|
@@ -3497,24 +3557,75 @@ function safeRandomId() {
|
|
|
3497
3557
|
return `r_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`;
|
|
3498
3558
|
}
|
|
3499
3559
|
}
|
|
3560
|
+
function isNearDuplicate(a, b) {
|
|
3561
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
3562
|
+
const na = norm(a);
|
|
3563
|
+
const nb = norm(b);
|
|
3564
|
+
if (na === nb) return true;
|
|
3565
|
+
const tokensA = new Set(na.split(" ").filter(Boolean));
|
|
3566
|
+
const tokensB = new Set(nb.split(" ").filter(Boolean));
|
|
3567
|
+
if (tokensA.size === 0 || tokensB.size === 0) return false;
|
|
3568
|
+
let inter = 0;
|
|
3569
|
+
for (const t of tokensA) if (tokensB.has(t)) inter++;
|
|
3570
|
+
const union = tokensA.size + tokensB.size - inter;
|
|
3571
|
+
return union > 0 && inter / union >= 0.9;
|
|
3572
|
+
}
|
|
3500
3573
|
|
|
3501
3574
|
// src/smart/reasoning.ts
|
|
3502
3575
|
var LEVEL_DEFAULTS = {
|
|
3576
|
+
minimal: {
|
|
3577
|
+
native: { effort: "minimal" },
|
|
3578
|
+
reflection: { maxTokens: 150, maxChars: 400, cadence: "off" }
|
|
3579
|
+
},
|
|
3503
3580
|
low: {
|
|
3504
3581
|
native: { effort: "low" },
|
|
3505
3582
|
reflection: { maxTokens: 200, maxChars: 600, cadence: "on_branch" }
|
|
3506
3583
|
},
|
|
3507
3584
|
medium: {
|
|
3508
3585
|
native: { effort: "medium" },
|
|
3509
|
-
reflection: { maxTokens: 350, maxChars: 1200, cadence: "
|
|
3586
|
+
reflection: { maxTokens: 350, maxChars: 1200, cadence: "initial_then_after_tool" }
|
|
3510
3587
|
},
|
|
3511
3588
|
high: {
|
|
3512
3589
|
native: { effort: "high" },
|
|
3513
|
-
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "
|
|
3590
|
+
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "initial_then_after_tool" }
|
|
3514
3591
|
}
|
|
3515
3592
|
};
|
|
3593
|
+
var VALID_LEVELS = ["minimal", "low", "medium", "high"];
|
|
3594
|
+
var VALID_CADENCES = ["off", "every_turn", "after_tool", "on_branch", "initial_then_after_tool"];
|
|
3595
|
+
var VALID_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
3596
|
+
function validateReasoningConfig(input) {
|
|
3597
|
+
if (!input) return;
|
|
3598
|
+
if (input.level !== void 0 && !VALID_LEVELS.includes(input.level)) {
|
|
3599
|
+
throw new Error(`reasoning.level must be one of ${VALID_LEVELS.join(", ")} (got "${input.level}")`);
|
|
3600
|
+
}
|
|
3601
|
+
if (input.native) {
|
|
3602
|
+
const n = input.native;
|
|
3603
|
+
if (n.effort !== void 0 && !VALID_EFFORTS.includes(n.effort)) {
|
|
3604
|
+
throw new Error(`reasoning.native.effort must be one of ${VALID_EFFORTS.join(", ")} (got "${n.effort}")`);
|
|
3605
|
+
}
|
|
3606
|
+
if (n.budgetTokens !== void 0 && (!Number.isFinite(n.budgetTokens) || n.budgetTokens < 0)) {
|
|
3607
|
+
throw new Error(`reasoning.native.budgetTokens must be a non-negative number (got ${n.budgetTokens})`);
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
if (input.reflection) {
|
|
3611
|
+
const r = input.reflection;
|
|
3612
|
+
if (r.cadence !== void 0 && !VALID_CADENCES.includes(r.cadence)) {
|
|
3613
|
+
throw new Error(`reasoning.reflection.cadence must be one of ${VALID_CADENCES.join(", ")} (got "${r.cadence}")`);
|
|
3614
|
+
}
|
|
3615
|
+
if (r.maxPerRun !== void 0 && (!Number.isFinite(r.maxPerRun) || r.maxPerRun < 0)) {
|
|
3616
|
+
throw new Error(`reasoning.reflection.maxPerRun must be a non-negative number (got ${r.maxPerRun})`);
|
|
3617
|
+
}
|
|
3618
|
+
if (r.everyNTurns !== void 0 && (!Number.isFinite(r.everyNTurns) || r.everyNTurns < 1)) {
|
|
3619
|
+
throw new Error(`reasoning.reflection.everyNTurns must be >= 1 (got ${r.everyNTurns})`);
|
|
3620
|
+
}
|
|
3621
|
+
if (r.feedTo !== void 0 && !["memory", "plan", "none"].includes(r.feedTo)) {
|
|
3622
|
+
throw new Error(`reasoning.reflection.feedTo must be "memory", "plan", or "none" (got "${r.feedTo}")`);
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3516
3626
|
function resolveReasoning(input) {
|
|
3517
3627
|
if (!input || input.enabled === false) return void 0;
|
|
3628
|
+
validateReasoningConfig(input);
|
|
3518
3629
|
const enabled = input.enabled ?? (input.native !== void 0 || input.reflection !== void 0 || input.level !== void 0);
|
|
3519
3630
|
if (!enabled) return void 0;
|
|
3520
3631
|
const level = input.level ?? "medium";
|
|
@@ -3539,7 +3650,8 @@ function resolveReflection(input, preset) {
|
|
|
3539
3650
|
keepLast: 3,
|
|
3540
3651
|
summarize: false,
|
|
3541
3652
|
emitEvents: true,
|
|
3542
|
-
everyNTurns: 1
|
|
3653
|
+
everyNTurns: 1,
|
|
3654
|
+
feedTo: "none"
|
|
3543
3655
|
};
|
|
3544
3656
|
}
|
|
3545
3657
|
const cfg = input ?? {};
|
|
@@ -3556,7 +3668,11 @@ function resolveReflection(input, preset) {
|
|
|
3556
3668
|
promptTemplate: cfg.promptTemplate,
|
|
3557
3669
|
emitEvents: cfg.emitEvents ?? true,
|
|
3558
3670
|
maxPerRun: typeof cfg.maxPerRun === "number" && cfg.maxPerRun >= 0 ? cfg.maxPerRun : void 0,
|
|
3559
|
-
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1))
|
|
3671
|
+
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1)),
|
|
3672
|
+
feedTo: cfg.feedTo ?? "none",
|
|
3673
|
+
shouldReflect: cfg.shouldReflect,
|
|
3674
|
+
buildPrompt: cfg.buildPrompt,
|
|
3675
|
+
onReflection: cfg.onReflection
|
|
3560
3676
|
};
|
|
3561
3677
|
}
|
|
3562
3678
|
function ensureArray(value) {
|
|
@@ -4282,12 +4398,14 @@ function createAgent(opts) {
|
|
|
4282
4398
|
if (summarizationThreshold === void 0) {
|
|
4283
4399
|
state = clearNeedsSummarization(state);
|
|
4284
4400
|
}
|
|
4285
|
-
if (resolvedReasoning
|
|
4401
|
+
if (resolvedReasoning) {
|
|
4286
4402
|
const ctx = { ...state.ctx || {} };
|
|
4287
|
-
if (
|
|
4403
|
+
if (resolvedReasoning.native) {
|
|
4288
4404
|
ctx.__reasoning = resolvedReasoning.native;
|
|
4289
|
-
|
|
4405
|
+
} else {
|
|
4406
|
+
delete ctx.__reasoning;
|
|
4290
4407
|
}
|
|
4408
|
+
state = { ...state, ctx: Object.keys(ctx).length > 0 ? ctx : void 0 };
|
|
4291
4409
|
}
|
|
4292
4410
|
const mergedLimits = {
|
|
4293
4411
|
...opts.limits || {},
|
|
@@ -4335,6 +4453,7 @@ function createAgent(opts) {
|
|
|
4335
4453
|
return { breached: false };
|
|
4336
4454
|
};
|
|
4337
4455
|
let iterations = 0;
|
|
4456
|
+
let reflectionsThisRun = 0;
|
|
4338
4457
|
const onStateChange = config?.onStateChange;
|
|
4339
4458
|
const checkpointReason = config?.checkpointReason;
|
|
4340
4459
|
let pausedStage = null;
|
|
@@ -4380,6 +4499,16 @@ function createAgent(opts) {
|
|
|
4380
4499
|
pausedStage = stage;
|
|
4381
4500
|
return true;
|
|
4382
4501
|
};
|
|
4502
|
+
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")) {
|
|
4503
|
+
try {
|
|
4504
|
+
const patch = await reflectNode(state, "initial_then_after_tool");
|
|
4505
|
+
if (patch && Object.keys(patch).length > 0) {
|
|
4506
|
+
state = { ...state, ...patch };
|
|
4507
|
+
reflectionsThisRun++;
|
|
4508
|
+
}
|
|
4509
|
+
} catch {
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4383
4512
|
while (iterations < iterationLimit) {
|
|
4384
4513
|
iterations++;
|
|
4385
4514
|
const budget = checkBudgetBreached();
|
|
@@ -4556,16 +4685,18 @@ function createAgent(opts) {
|
|
|
4556
4685
|
if (reflectNode && resolvedReasoning?.reflection.enabled) {
|
|
4557
4686
|
const cadence = resolvedReasoning.reflection.cadence;
|
|
4558
4687
|
const refl = resolvedReasoning.reflection;
|
|
4559
|
-
const reflectionsSoFar = state.reflections?.length ?? 0;
|
|
4560
4688
|
const lastTurn = state.reflections?.at(-1)?.turn ?? -Infinity;
|
|
4561
4689
|
const currentTurn = state.toolCallCount || 0;
|
|
4562
|
-
const budgetExceeded = typeof refl.maxPerRun === "number" &&
|
|
4563
|
-
const
|
|
4564
|
-
|
|
4690
|
+
const budgetExceeded = typeof refl.maxPerRun === "number" && reflectionsThisRun >= refl.maxPerRun;
|
|
4691
|
+
const sinceLast = currentTurn - (Number.isFinite(lastTurn) ? lastTurn : -refl.everyNTurns);
|
|
4692
|
+
const cadenceGap = sinceLast < refl.everyNTurns;
|
|
4693
|
+
const cadenceWantsIt = refl.shouldReflect ? !!refl.shouldReflect({ state, turn: currentTurn, trigger: cadence, ranToolsThisTurn: true }) : shouldRunReflection(cadence, state, true);
|
|
4694
|
+
if (!budgetExceeded && !cadenceGap && cadenceWantsIt) {
|
|
4565
4695
|
try {
|
|
4566
4696
|
const patch = await reflectNode(state, cadence);
|
|
4567
4697
|
if (patch && Object.keys(patch).length > 0) {
|
|
4568
4698
|
state = { ...state, ...patch };
|
|
4699
|
+
reflectionsThisRun++;
|
|
4569
4700
|
}
|
|
4570
4701
|
} catch {
|
|
4571
4702
|
}
|
|
@@ -6073,6 +6204,190 @@ async function writeSummaryFactsToMemory(store, config, summary, sourceTurn) {
|
|
|
6073
6204
|
return store.get(config.memory.scope, { limit: config.context.lastTurnsToKeep + summary.stable_facts.length });
|
|
6074
6205
|
}
|
|
6075
6206
|
|
|
6207
|
+
// src/smart/skills/types.ts
|
|
6208
|
+
var DEFAULT_SKILL_POLICY = {
|
|
6209
|
+
maxOpenSkills: 4,
|
|
6210
|
+
maxBoundToolsPerSkill: 12,
|
|
6211
|
+
maxBoundToolsTotal: 40
|
|
6212
|
+
};
|
|
6213
|
+
var SMALL_TIER_SKILL_POLICY = {
|
|
6214
|
+
maxOpenSkills: 1,
|
|
6215
|
+
maxBoundToolsPerSkill: 6,
|
|
6216
|
+
maxBoundToolsTotal: 18,
|
|
6217
|
+
modelTier: "small"
|
|
6218
|
+
};
|
|
6219
|
+
function createSkillRegistryRef() {
|
|
6220
|
+
return { openedSkillKeys: [], boundSkillTools: [] };
|
|
6221
|
+
}
|
|
6222
|
+
|
|
6223
|
+
// src/smart/skills/registry.ts
|
|
6224
|
+
function composeToolSets(input) {
|
|
6225
|
+
const without = [...input.base, ...input.boundSkillTools];
|
|
6226
|
+
const withRec = input.recoveryTool ? [...without, input.recoveryTool] : [...without];
|
|
6227
|
+
return { toolsWithoutRecovery: without, toolsWithRecovery: withRec };
|
|
6228
|
+
}
|
|
6229
|
+
function appendBoundTools(ref, newTools, policy) {
|
|
6230
|
+
const present = new Set(ref.boundSkillTools.map((tool) => tool.name));
|
|
6231
|
+
const added = [];
|
|
6232
|
+
for (const tool of newTools) {
|
|
6233
|
+
if (ref.boundSkillTools.length >= policy.maxBoundToolsTotal) break;
|
|
6234
|
+
if (present.has(tool.name)) continue;
|
|
6235
|
+
present.add(tool.name);
|
|
6236
|
+
ref.boundSkillTools.push(tool);
|
|
6237
|
+
added.push(tool);
|
|
6238
|
+
}
|
|
6239
|
+
return added;
|
|
6240
|
+
}
|
|
6241
|
+
function canOpenSkill(ref, policy) {
|
|
6242
|
+
if (ref.openedSkillKeys.length >= policy.maxOpenSkills) {
|
|
6243
|
+
return { ok: false, reason: `max ${policy.maxOpenSkills} skill(s) already open` };
|
|
6244
|
+
}
|
|
6245
|
+
if (ref.boundSkillTools.length >= policy.maxBoundToolsTotal) {
|
|
6246
|
+
return { ok: false, reason: "skill tool budget exhausted" };
|
|
6247
|
+
}
|
|
6248
|
+
return { ok: true };
|
|
6249
|
+
}
|
|
6250
|
+
async function resolveAvailableSkills(skills, opts = {}) {
|
|
6251
|
+
const out = [];
|
|
6252
|
+
for (const skill of skills) {
|
|
6253
|
+
if (skill.minModelTier === "large" && opts.modelTier === "small") continue;
|
|
6254
|
+
const available = skill.isAvailable ? await skill.isAvailable() : true;
|
|
6255
|
+
if (available) out.push(skill);
|
|
6256
|
+
}
|
|
6257
|
+
return out;
|
|
6258
|
+
}
|
|
6259
|
+
function buildSkillHeaderBlock(skills) {
|
|
6260
|
+
if (skills.length === 0) return "";
|
|
6261
|
+
const lines = skills.map((skill) => `- ${skill.key}: ${skill.header}`);
|
|
6262
|
+
return [
|
|
6263
|
+
"<available_skills>",
|
|
6264
|
+
"Open a skill with open_skill(skillKey) to load its tools on demand. Only open what the task needs; close nothing \u2014 opened skills stay available for the rest of the run.",
|
|
6265
|
+
...lines,
|
|
6266
|
+
"</available_skills>"
|
|
6267
|
+
].join("\n");
|
|
6268
|
+
}
|
|
6269
|
+
function dedupeToolsByName(tools) {
|
|
6270
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6271
|
+
const out = [];
|
|
6272
|
+
for (const tool of tools) {
|
|
6273
|
+
if (seen.has(tool.name)) continue;
|
|
6274
|
+
seen.add(tool.name);
|
|
6275
|
+
out.push(tool);
|
|
6276
|
+
}
|
|
6277
|
+
return out;
|
|
6278
|
+
}
|
|
6279
|
+
|
|
6280
|
+
// src/smart/skills/skillTools.ts
|
|
6281
|
+
var MAX_RETURNED_INDEX = 40;
|
|
6282
|
+
var OPEN_SKILL_DESCRIPTION = "Load a capability on demand. Pass a skillKey from <available_skills>. A small skill binds all its tools immediately; a large one returns a tool index \u2014 then call bind_skill_tools with only the tools you need. Open only what the task needs.";
|
|
6283
|
+
var BIND_SKILL_TOOLS_DESCRIPTION = "After open_skill on a large skill, bind a chosen subset of its tools by name. Pick the few tools the task actually needs.";
|
|
6284
|
+
function findSkill(deps, key) {
|
|
6285
|
+
return deps.skills.find((skill) => skill.key === key);
|
|
6286
|
+
}
|
|
6287
|
+
function createOpenSkillTool(deps) {
|
|
6288
|
+
const tool = createTool({
|
|
6289
|
+
name: "open_skill",
|
|
6290
|
+
description: OPEN_SKILL_DESCRIPTION,
|
|
6291
|
+
schema: zod.z.object({
|
|
6292
|
+
skillKey: zod.z.string().min(1).describe("A key from <available_skills>."),
|
|
6293
|
+
query: zod.z.string().optional().describe("What you need from the skill \u2014 used to rank a large skill's tools.")
|
|
6294
|
+
}).strict(),
|
|
6295
|
+
func: async ({ skillKey, query }) => {
|
|
6296
|
+
const { registryRef: ref, policy } = tool._deps;
|
|
6297
|
+
const skill = findSkill(tool._deps, skillKey);
|
|
6298
|
+
if (!skill) {
|
|
6299
|
+
return { error: `Unknown skill: ${skillKey}. Choose a key listed in <available_skills>.` };
|
|
6300
|
+
}
|
|
6301
|
+
if (skill.isAvailable && !await skill.isAvailable()) {
|
|
6302
|
+
return { error: `Skill ${skillKey} is not available in this workspace.` };
|
|
6303
|
+
}
|
|
6304
|
+
const alreadyOpen = ref.openedSkillKeys.includes(skillKey);
|
|
6305
|
+
if (!alreadyOpen) {
|
|
6306
|
+
const guard = canOpenSkill(ref, policy);
|
|
6307
|
+
if (!guard.ok) {
|
|
6308
|
+
return {
|
|
6309
|
+
error: `Cannot open ${skillKey}: ${guard.reason}. Work with the skills already open.`
|
|
6310
|
+
};
|
|
6311
|
+
}
|
|
6312
|
+
ref.openedSkillKeys.push(skillKey);
|
|
6313
|
+
}
|
|
6314
|
+
const prompt = typeof skill.prompt === "function" ? await skill.prompt() : skill.prompt;
|
|
6315
|
+
const index = await skill.listToolIndex();
|
|
6316
|
+
if (index.length <= policy.maxBoundToolsPerSkill) {
|
|
6317
|
+
const bound = await skill.bindTools();
|
|
6318
|
+
const added = appendBoundTools(ref, bound, policy);
|
|
6319
|
+
if (added.length > 0) ref.__onToolsChanged?.();
|
|
6320
|
+
return {
|
|
6321
|
+
skillKey,
|
|
6322
|
+
prompt,
|
|
6323
|
+
needsSandbox: Boolean(skill.needsSandbox),
|
|
6324
|
+
boundTools: added.map((t) => t.name),
|
|
6325
|
+
// Inject the bound tools into the live runtime for this loop.
|
|
6326
|
+
__runtimeToolsDelta: added
|
|
6327
|
+
};
|
|
6328
|
+
}
|
|
6329
|
+
let defaultBound = [];
|
|
6330
|
+
let defaultAdded = [];
|
|
6331
|
+
if ((!query || query.trim().length < 3) && skill.defaultBindNames?.length) {
|
|
6332
|
+
const bound = await skill.bindTools(skill.defaultBindNames.slice(0, policy.maxBoundToolsPerSkill));
|
|
6333
|
+
defaultAdded = appendBoundTools(ref, bound, policy);
|
|
6334
|
+
if (defaultAdded.length > 0) ref.__onToolsChanged?.();
|
|
6335
|
+
defaultBound = defaultAdded.map((t) => t.name);
|
|
6336
|
+
}
|
|
6337
|
+
const headers = query && query.trim().length >= 3 && skill.rankToolHeaders ? await skill.rankToolHeaders(query, index) : index;
|
|
6338
|
+
return {
|
|
6339
|
+
skillKey,
|
|
6340
|
+
prompt,
|
|
6341
|
+
needsSandbox: Boolean(skill.needsSandbox),
|
|
6342
|
+
boundTools: defaultBound,
|
|
6343
|
+
toolIndex: headers.slice(0, MAX_RETURNED_INDEX).map((h) => ({ name: h.name, description: h.description })),
|
|
6344
|
+
hint: "Call bind_skill_tools(skillKey, toolNames) with only the tools you need.",
|
|
6345
|
+
...defaultAdded.length > 0 ? { __runtimeToolsDelta: defaultAdded } : {}
|
|
6346
|
+
};
|
|
6347
|
+
}
|
|
6348
|
+
});
|
|
6349
|
+
tool._deps = deps;
|
|
6350
|
+
tool.__source = "smart-skills";
|
|
6351
|
+
return tool;
|
|
6352
|
+
}
|
|
6353
|
+
function createBindSkillToolsTool(deps) {
|
|
6354
|
+
const tool = createTool({
|
|
6355
|
+
name: "bind_skill_tools",
|
|
6356
|
+
description: BIND_SKILL_TOOLS_DESCRIPTION,
|
|
6357
|
+
schema: zod.z.object({
|
|
6358
|
+
skillKey: zod.z.string().min(1),
|
|
6359
|
+
toolNames: zod.z.array(zod.z.string().min(1)).min(1).describe("Tool names from the skill's index.")
|
|
6360
|
+
}).strict(),
|
|
6361
|
+
func: async ({ skillKey, toolNames }) => {
|
|
6362
|
+
const { registryRef: ref, policy } = tool._deps;
|
|
6363
|
+
const skill = findSkill(tool._deps, skillKey);
|
|
6364
|
+
if (!skill) {
|
|
6365
|
+
return { error: `Unknown skill: ${skillKey}.` };
|
|
6366
|
+
}
|
|
6367
|
+
if (!ref.openedSkillKeys.includes(skillKey)) {
|
|
6368
|
+
return { error: `Call open_skill("${skillKey}") before binding its tools.` };
|
|
6369
|
+
}
|
|
6370
|
+
const capped = toolNames.slice(0, policy.maxBoundToolsPerSkill);
|
|
6371
|
+
const bound = await skill.bindTools(capped);
|
|
6372
|
+
const added = appendBoundTools(ref, bound, policy);
|
|
6373
|
+
if (added.length > 0) ref.__onToolsChanged?.();
|
|
6374
|
+
return {
|
|
6375
|
+
skillKey,
|
|
6376
|
+
boundTools: added.map((t) => t.name),
|
|
6377
|
+
requested: capped.length,
|
|
6378
|
+
truncated: toolNames.length > capped.length,
|
|
6379
|
+
...added.length > 0 ? { __runtimeToolsDelta: added } : {}
|
|
6380
|
+
};
|
|
6381
|
+
}
|
|
6382
|
+
});
|
|
6383
|
+
tool._deps = deps;
|
|
6384
|
+
tool.__source = "smart-skills";
|
|
6385
|
+
return tool;
|
|
6386
|
+
}
|
|
6387
|
+
function createSkillTools(deps) {
|
|
6388
|
+
return [createOpenSkillTool(deps), createBindSkillToolsTool(deps)];
|
|
6389
|
+
}
|
|
6390
|
+
|
|
6076
6391
|
// src/smart/index.ts
|
|
6077
6392
|
function createSmartAgent(opts) {
|
|
6078
6393
|
const resolved = normalizeSmartAgentOptions(opts);
|
|
@@ -6107,6 +6422,9 @@ function createSmartAgent(opts) {
|
|
|
6107
6422
|
if (askUserConfig) {
|
|
6108
6423
|
factoryToolsWithoutRecovery.push(createAskUserQuestionTool(factoryStateRef, askUserConfig));
|
|
6109
6424
|
}
|
|
6425
|
+
const skills = opts.skills ?? [];
|
|
6426
|
+
const skillPolicy = opts.skillPolicy ?? DEFAULT_SKILL_POLICY;
|
|
6427
|
+
const skillsEnabled = skills.length > 0;
|
|
6110
6428
|
const soManagerFactory = opts.outputSchema ? new StructuredOutputManager(opts.outputSchema, resolveStrategy(opts.model)) : void 0;
|
|
6111
6429
|
const modelCapabilities = opts.outputSchema ? getModelCapabilities(opts.model) : void 0;
|
|
6112
6430
|
const responseFinalizeTool = soManagerFactory && modelCapabilities?.structuredOutput !== "native" ? soManagerFactory.getResponseTool() : void 0;
|
|
@@ -6114,12 +6432,31 @@ function createSmartAgent(opts) {
|
|
|
6114
6432
|
const ref = { toolHistory: void 0, toolHistoryArchived: void 0, todoList: void 0, planVersion: 0, adherenceScore: 0 };
|
|
6115
6433
|
const ctxTools = createContextTools(ref, { planningEnabled, includeGetToolResponse: false });
|
|
6116
6434
|
const recoveryTool = createGetToolResponseTool(ref);
|
|
6117
|
-
const
|
|
6118
|
-
if (responseFinalizeTool)
|
|
6119
|
-
if (askUserConfig)
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6435
|
+
const coreBase = [...userTools, ...ctxTools];
|
|
6436
|
+
if (responseFinalizeTool) coreBase.push(responseFinalizeTool);
|
|
6437
|
+
if (askUserConfig) coreBase.push(createAskUserQuestionTool(ref, askUserConfig));
|
|
6438
|
+
if (!skillsEnabled) {
|
|
6439
|
+
const without = coreBase;
|
|
6440
|
+
const withRec = [...without, recoveryTool];
|
|
6441
|
+
return { stateRef: ref, toolsWithoutRecovery: without, toolsWithRecovery: withRec };
|
|
6442
|
+
}
|
|
6443
|
+
const toolSet = { stateRef: ref, toolsWithoutRecovery: [], toolsWithRecovery: [] };
|
|
6444
|
+
const skillRegistryRef = createSkillRegistryRef();
|
|
6445
|
+
const skillMetaTools = createSkillTools({ registryRef: skillRegistryRef, skills, policy: skillPolicy });
|
|
6446
|
+
const baseWithMeta = [...coreBase, ...skillMetaTools];
|
|
6447
|
+
const rebuild = () => {
|
|
6448
|
+
const composed = composeToolSets({
|
|
6449
|
+
base: baseWithMeta,
|
|
6450
|
+
boundSkillTools: skillRegistryRef.boundSkillTools,
|
|
6451
|
+
recoveryTool
|
|
6452
|
+
});
|
|
6453
|
+
toolSet.toolsWithoutRecovery = composed.toolsWithoutRecovery;
|
|
6454
|
+
toolSet.toolsWithRecovery = composed.toolsWithRecovery;
|
|
6455
|
+
};
|
|
6456
|
+
skillRegistryRef.__onToolsChanged = rebuild;
|
|
6457
|
+
toolSet.skillRegistryRef = skillRegistryRef;
|
|
6458
|
+
rebuild();
|
|
6459
|
+
return toolSet;
|
|
6123
6460
|
};
|
|
6124
6461
|
const base = createAgent({ ...runtimeOpts, tools: factoryToolsWithoutRecovery });
|
|
6125
6462
|
base.__runtime.runtimeProfile = resolved.runtimeProfile;
|
|
@@ -6170,9 +6507,9 @@ function createSmartAgent(opts) {
|
|
|
6170
6507
|
planVersion: ref.planVersion || state.planVersion || 1
|
|
6171
6508
|
};
|
|
6172
6509
|
}
|
|
6173
|
-
function systemMessage2() {
|
|
6510
|
+
function systemMessage2(extraBlock) {
|
|
6174
6511
|
const sys = buildSystemPrompt(
|
|
6175
|
-
[opts.systemPrompt, runtimeHint, structuredOutputHint].filter(Boolean).join("\n"),
|
|
6512
|
+
[opts.systemPrompt, runtimeHint, structuredOutputHint, extraBlock].filter(Boolean).join("\n"),
|
|
6176
6513
|
planningEnabled,
|
|
6177
6514
|
opts.name || "Agent",
|
|
6178
6515
|
opts.todoListPrompt
|
|
@@ -6222,8 +6559,10 @@ function createSmartAgent(opts) {
|
|
|
6222
6559
|
stateRef.planVersion = input.planVersion || input.plan?.version || 0;
|
|
6223
6560
|
stateRef.adherenceScore = input.plan?.adherenceScore || 0;
|
|
6224
6561
|
const syncPlanFromRef = (state2) => syncPlanStateWith(stateRef, state2);
|
|
6562
|
+
const availableSkills = skillsEnabled ? await resolveAvailableSkills(skills, { modelTier: skillPolicy.modelTier }) : [];
|
|
6563
|
+
const skillBlock = availableSkills.length > 0 ? buildSkillHeaderBlock(availableSkills) : void 0;
|
|
6225
6564
|
const alreadyHasSystem = Array.isArray(input.messages) && input.messages[0]?.role === "system";
|
|
6226
|
-
const seedMessages = alreadyHasSystem ? [...input.messages || []] : [systemMessage2(), ...input.messages || []];
|
|
6565
|
+
const seedMessages = alreadyHasSystem ? [...input.messages || []] : [systemMessage2(skillBlock), ...input.messages || []];
|
|
6227
6566
|
let state = syncRuntimeTools(await syncMemory({ ...input, messages: seedMessages }), seedMessages, toolSet);
|
|
6228
6567
|
let lastResult = null;
|
|
6229
6568
|
let rawMessages = [...seedMessages];
|
|
@@ -6828,6 +7167,20 @@ function parseSSEBlock(block) {
|
|
|
6828
7167
|
}
|
|
6829
7168
|
|
|
6830
7169
|
// src/providers/utils/reasoning.ts
|
|
7170
|
+
var ANTHROPIC_EFFORT_BUDGET = {
|
|
7171
|
+
minimal: 1024,
|
|
7172
|
+
low: 2048,
|
|
7173
|
+
medium: 8192,
|
|
7174
|
+
high: 16384
|
|
7175
|
+
};
|
|
7176
|
+
var GEMINI_EFFORT_BUDGET = {
|
|
7177
|
+
minimal: 512,
|
|
7178
|
+
low: 1024,
|
|
7179
|
+
medium: 4096,
|
|
7180
|
+
high: 12e3
|
|
7181
|
+
};
|
|
7182
|
+
var THINKING_OUTPUT_RESERVE = 1024;
|
|
7183
|
+
var THINKING_MIN_MAX_TOKENS = 4096;
|
|
6831
7184
|
function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
6832
7185
|
if (!reasoning) return;
|
|
6833
7186
|
const effort = normalizeEffort(reasoning.effort);
|
|
@@ -6844,21 +7197,56 @@ function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
|
6844
7197
|
}
|
|
6845
7198
|
function applyAnthropicReasoning(body, reasoning) {
|
|
6846
7199
|
if (!reasoning) return;
|
|
6847
|
-
|
|
7200
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
6848
7201
|
if (!budget) return;
|
|
7202
|
+
const currentMax = typeof body.max_tokens === "number" ? body.max_tokens : 0;
|
|
7203
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
7204
|
+
if (currentMax < requiredMax) {
|
|
7205
|
+
body.max_tokens = requiredMax;
|
|
7206
|
+
}
|
|
7207
|
+
budget = clampBudget(budget, body.max_tokens);
|
|
6849
7208
|
const thinking = { type: "enabled", budget_tokens: budget };
|
|
6850
7209
|
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
6851
7210
|
body.thinking = thinking;
|
|
7211
|
+
stripSamplingParams(body, ["temperature", "top_p", "top_k"]);
|
|
7212
|
+
}
|
|
7213
|
+
function applyBedrockReasoning(body, reasoning) {
|
|
7214
|
+
if (!reasoning) return;
|
|
7215
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
7216
|
+
if (!budget) return;
|
|
7217
|
+
const inference = body.inferenceConfig ?? (body.inferenceConfig = {});
|
|
7218
|
+
const currentMax = typeof inference.maxTokens === "number" ? inference.maxTokens : 0;
|
|
7219
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
7220
|
+
if (currentMax < requiredMax) {
|
|
7221
|
+
inference.maxTokens = requiredMax;
|
|
7222
|
+
}
|
|
7223
|
+
budget = clampBudget(budget, inference.maxTokens);
|
|
7224
|
+
const extra = body.additionalModelRequestFields ?? (body.additionalModelRequestFields = {});
|
|
7225
|
+
const thinking = { type: "enabled", budget_tokens: budget };
|
|
7226
|
+
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
7227
|
+
extra.thinking = thinking;
|
|
7228
|
+
stripSamplingParams(inference, ["temperature", "topP"]);
|
|
6852
7229
|
}
|
|
6853
7230
|
function applyGeminiReasoning(generationConfig, reasoning) {
|
|
6854
7231
|
if (!reasoning) return;
|
|
6855
|
-
const budget = resolveBudget(reasoning,
|
|
7232
|
+
const budget = resolveBudget(reasoning, GEMINI_EFFORT_BUDGET);
|
|
6856
7233
|
if (budget == null) return;
|
|
6857
7234
|
const thinkingConfig = { thinkingBudget: budget };
|
|
6858
7235
|
if (reasoning.includeThoughts) thinkingConfig.includeThoughts = true;
|
|
6859
7236
|
if (reasoning.providerExtras) Object.assign(thinkingConfig, reasoning.providerExtras);
|
|
6860
7237
|
generationConfig.thinkingConfig = thinkingConfig;
|
|
6861
7238
|
}
|
|
7239
|
+
function stripSamplingParams(target, keys) {
|
|
7240
|
+
for (const k of keys) {
|
|
7241
|
+
if (k in target) delete target[k];
|
|
7242
|
+
}
|
|
7243
|
+
}
|
|
7244
|
+
function clampBudget(budget, maxTokens) {
|
|
7245
|
+
if (typeof maxTokens !== "number" || maxTokens <= 0) return budget;
|
|
7246
|
+
const ceiling = maxTokens - THINKING_OUTPUT_RESERVE;
|
|
7247
|
+
if (ceiling < 1024) return Math.max(1024, Math.floor(maxTokens / 2));
|
|
7248
|
+
return Math.min(budget, ceiling);
|
|
7249
|
+
}
|
|
6862
7250
|
function normalizeEffort(effort) {
|
|
6863
7251
|
if (!effort) return void 0;
|
|
6864
7252
|
const allowed = ["minimal", "low", "medium", "high"];
|
|
@@ -6887,13 +7275,38 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6887
7275
|
};
|
|
6888
7276
|
if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
|
|
6889
7277
|
}
|
|
7278
|
+
/** True when the request targets a reasoning model (o-series / gpt-5) so we
|
|
7279
|
+
* should route through the Responses API, which exposes `reasoning.effort`
|
|
7280
|
+
* and reasoning summaries. Chat Completions silently drops these. */
|
|
7281
|
+
useResponsesApi(request) {
|
|
7282
|
+
if (!request.reasoning) return false;
|
|
7283
|
+
return isReasoningModel(request.model || this.defaultModel);
|
|
7284
|
+
}
|
|
6890
7285
|
async complete(request) {
|
|
7286
|
+
if (this.useResponsesApi(request)) {
|
|
7287
|
+
return this.completeResponses(request);
|
|
7288
|
+
}
|
|
6891
7289
|
const body = this.buildRequestBody(request, false);
|
|
6892
7290
|
const res = await this.doFetch(body);
|
|
6893
7291
|
const json = await res.json();
|
|
6894
7292
|
return this.parseResponse(json);
|
|
6895
7293
|
}
|
|
6896
7294
|
async *completeStream(request) {
|
|
7295
|
+
if (this.useResponsesApi(request)) {
|
|
7296
|
+
const response = await this.completeResponses(request);
|
|
7297
|
+
yield {
|
|
7298
|
+
id: response.id,
|
|
7299
|
+
model: response.model,
|
|
7300
|
+
delta: {
|
|
7301
|
+
content: response.content ?? void 0,
|
|
7302
|
+
toolCalls: response.toolCalls.length > 0 ? response.toolCalls : void 0,
|
|
7303
|
+
reasoning: response.reasoning
|
|
7304
|
+
},
|
|
7305
|
+
usage: response.usage,
|
|
7306
|
+
finishReason: response.finishReason
|
|
7307
|
+
};
|
|
7308
|
+
return;
|
|
7309
|
+
}
|
|
6897
7310
|
const body = this.buildRequestBody(request, true);
|
|
6898
7311
|
const res = await this.doFetch(body);
|
|
6899
7312
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
@@ -6992,6 +7405,156 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6992
7405
|
applyOpenAIReasoning(body, request.reasoning, "legacy_effort");
|
|
6993
7406
|
return body;
|
|
6994
7407
|
}
|
|
7408
|
+
// ─── Responses API (reasoning models) ──────────────────────────────────────
|
|
7409
|
+
async completeResponses(request) {
|
|
7410
|
+
const body = this.buildResponsesBody(request);
|
|
7411
|
+
const res = await this.responsesFetch(body);
|
|
7412
|
+
const json = await res.json();
|
|
7413
|
+
return this.parseResponsesResponse(json, request.model || this.defaultModel);
|
|
7414
|
+
}
|
|
7415
|
+
buildResponsesBody(request) {
|
|
7416
|
+
const body = {
|
|
7417
|
+
model: request.model || this.defaultModel,
|
|
7418
|
+
input: request.messages.map((m) => this.toResponsesInput(m))
|
|
7419
|
+
};
|
|
7420
|
+
if (request.maxTokens != null) body.max_output_tokens = request.maxTokens;
|
|
7421
|
+
if (request.topP != null) body.top_p = request.topP;
|
|
7422
|
+
if (request.tools?.length) {
|
|
7423
|
+
body.tools = request.tools.map((t) => ({
|
|
7424
|
+
type: "function",
|
|
7425
|
+
name: t.name,
|
|
7426
|
+
description: t.description,
|
|
7427
|
+
parameters: t.parameters,
|
|
7428
|
+
...t.strict ? { strict: true } : {}
|
|
7429
|
+
}));
|
|
7430
|
+
}
|
|
7431
|
+
if (request.toolChoice != null && request.tools?.length) {
|
|
7432
|
+
if (typeof request.toolChoice === "string") {
|
|
7433
|
+
body.tool_choice = request.toolChoice;
|
|
7434
|
+
} else {
|
|
7435
|
+
body.tool_choice = { type: "function", name: request.toolChoice.name };
|
|
7436
|
+
}
|
|
7437
|
+
}
|
|
7438
|
+
if (request.responseFormat) {
|
|
7439
|
+
if (request.responseFormat.type === "json_schema") {
|
|
7440
|
+
body.text = {
|
|
7441
|
+
format: {
|
|
7442
|
+
type: "json_schema",
|
|
7443
|
+
name: request.responseFormat.name ?? "response",
|
|
7444
|
+
schema: request.responseFormat.schema,
|
|
7445
|
+
strict: true
|
|
7446
|
+
}
|
|
7447
|
+
};
|
|
7448
|
+
} else if (request.responseFormat.type === "json_object") {
|
|
7449
|
+
body.text = { format: { type: "json_object" } };
|
|
7450
|
+
}
|
|
7451
|
+
}
|
|
7452
|
+
if (request.extra) Object.assign(body, request.extra);
|
|
7453
|
+
applyOpenAIReasoning(body, request.reasoning, "responses");
|
|
7454
|
+
return body;
|
|
7455
|
+
}
|
|
7456
|
+
/** Maps a unified message to a Responses API `input` item. */
|
|
7457
|
+
toResponsesInput(m) {
|
|
7458
|
+
if (m.role === "tool" && m.toolCallId) {
|
|
7459
|
+
const output = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
|
|
7460
|
+
return { type: "function_call_output", call_id: m.toolCallId, output };
|
|
7461
|
+
}
|
|
7462
|
+
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7463
|
+
return {
|
|
7464
|
+
__assistantWithCalls: true,
|
|
7465
|
+
text: typeof m.content === "string" ? m.content : "",
|
|
7466
|
+
calls: m.toolCalls.map((tc) => ({
|
|
7467
|
+
type: "function_call",
|
|
7468
|
+
call_id: tc.id,
|
|
7469
|
+
name: tc.name,
|
|
7470
|
+
arguments: tc.arguments
|
|
7471
|
+
}))
|
|
7472
|
+
};
|
|
7473
|
+
}
|
|
7474
|
+
const role = m.role === "system" ? "system" : m.role === "assistant" ? "assistant" : "user";
|
|
7475
|
+
const textType = role === "assistant" ? "output_text" : "input_text";
|
|
7476
|
+
if (typeof m.content === "string") {
|
|
7477
|
+
return { role, content: [{ type: textType, text: m.content }] };
|
|
7478
|
+
}
|
|
7479
|
+
const content = m.content.map((part) => {
|
|
7480
|
+
if (part.type === "text") return { type: textType, text: part.text };
|
|
7481
|
+
if (part.type === "image") {
|
|
7482
|
+
const src = part.source;
|
|
7483
|
+
const url = src.type === "url" ? src.url : `data:${src.mediaType};base64,${src.data}`;
|
|
7484
|
+
return { type: "input_image", image_url: url };
|
|
7485
|
+
}
|
|
7486
|
+
return { type: textType, text: "" };
|
|
7487
|
+
});
|
|
7488
|
+
return { role, content };
|
|
7489
|
+
}
|
|
7490
|
+
async responsesFetch(body) {
|
|
7491
|
+
body.input = expandResponsesInput(body.input);
|
|
7492
|
+
const url = `${this.baseURL}/responses`;
|
|
7493
|
+
const headers = {
|
|
7494
|
+
"Content-Type": "application/json",
|
|
7495
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
7496
|
+
...this.defaultHeaders
|
|
7497
|
+
};
|
|
7498
|
+
const payload = JSON.stringify(body);
|
|
7499
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
7500
|
+
if (!res.ok) {
|
|
7501
|
+
const text = await res.text().catch(() => "");
|
|
7502
|
+
throw new ProviderError(
|
|
7503
|
+
`OpenAI Responses API error ${res.status}: ${text}`,
|
|
7504
|
+
this.providerName,
|
|
7505
|
+
res.status,
|
|
7506
|
+
text
|
|
7507
|
+
);
|
|
7508
|
+
}
|
|
7509
|
+
return res;
|
|
7510
|
+
}
|
|
7511
|
+
parseResponsesResponse(json, modelId) {
|
|
7512
|
+
const textParts = [];
|
|
7513
|
+
const toolCalls = [];
|
|
7514
|
+
const summaryParts = [];
|
|
7515
|
+
for (const item of json.output ?? []) {
|
|
7516
|
+
if (item.type === "message") {
|
|
7517
|
+
for (const c of item.content ?? []) {
|
|
7518
|
+
if (c.type === "output_text" && typeof c.text === "string") textParts.push(c.text);
|
|
7519
|
+
}
|
|
7520
|
+
} else if (item.type === "function_call") {
|
|
7521
|
+
toolCalls.push({
|
|
7522
|
+
id: item.call_id ?? item.id ?? "",
|
|
7523
|
+
name: item.name ?? "",
|
|
7524
|
+
arguments: typeof item.arguments === "string" ? item.arguments : JSON.stringify(item.arguments ?? {})
|
|
7525
|
+
});
|
|
7526
|
+
} else if (item.type === "reasoning") {
|
|
7527
|
+
for (const s of item.summary ?? []) {
|
|
7528
|
+
if (typeof s.text === "string") summaryParts.push(s.text);
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
7531
|
+
}
|
|
7532
|
+
if (textParts.length === 0 && typeof json.output_text === "string") {
|
|
7533
|
+
textParts.push(json.output_text);
|
|
7534
|
+
}
|
|
7535
|
+
const usage = json.usage ?? {};
|
|
7536
|
+
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0;
|
|
7537
|
+
const tokenUsage = {
|
|
7538
|
+
inputTokens: usage.input_tokens ?? 0,
|
|
7539
|
+
outputTokens: usage.output_tokens ?? 0,
|
|
7540
|
+
totalTokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
|
|
7541
|
+
cachedInputTokens: usage.input_tokens_details?.cached_tokens ?? 0,
|
|
7542
|
+
cachedWriteTokens: 0,
|
|
7543
|
+
cachedOutputTokens: 0,
|
|
7544
|
+
reasoningTokens
|
|
7545
|
+
};
|
|
7546
|
+
const finishReason = toolCalls.length > 0 ? "tool_calls" : json.status === "incomplete" ? "length" : "stop";
|
|
7547
|
+
return {
|
|
7548
|
+
id: json.id ?? "",
|
|
7549
|
+
model: json.model ?? modelId,
|
|
7550
|
+
content: textParts.join("") || null,
|
|
7551
|
+
toolCalls,
|
|
7552
|
+
usage: tokenUsage,
|
|
7553
|
+
finishReason,
|
|
7554
|
+
reasoning: summaryParts.length > 0 ? { summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7555
|
+
raw: json
|
|
7556
|
+
};
|
|
7557
|
+
}
|
|
6995
7558
|
toOpenAIMessage(m) {
|
|
6996
7559
|
const msg = { role: m.role };
|
|
6997
7560
|
if (typeof m.content === "string") {
|
|
@@ -7084,6 +7647,25 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
7084
7647
|
};
|
|
7085
7648
|
}
|
|
7086
7649
|
};
|
|
7650
|
+
function isReasoningModel(model) {
|
|
7651
|
+
if (!model) return false;
|
|
7652
|
+
const m = model.toLowerCase();
|
|
7653
|
+
return /(^|[/_-])o[0-9]/.test(m) || m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.includes("gpt-5") || m.includes("gpt5");
|
|
7654
|
+
}
|
|
7655
|
+
function expandResponsesInput(input) {
|
|
7656
|
+
const out = [];
|
|
7657
|
+
for (const item of input) {
|
|
7658
|
+
if (item && item.__assistantWithCalls) {
|
|
7659
|
+
if (item.text) {
|
|
7660
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
7661
|
+
}
|
|
7662
|
+
for (const call of item.calls) out.push(call);
|
|
7663
|
+
} else {
|
|
7664
|
+
out.push(item);
|
|
7665
|
+
}
|
|
7666
|
+
}
|
|
7667
|
+
return out;
|
|
7668
|
+
}
|
|
7087
7669
|
function mapFinishReason(reason) {
|
|
7088
7670
|
switch (reason) {
|
|
7089
7671
|
case "stop":
|
|
@@ -7129,6 +7711,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7129
7711
|
let cacheReadInputTokens = 0;
|
|
7130
7712
|
let cacheCreationInputTokens = 0;
|
|
7131
7713
|
const currentToolCalls = /* @__PURE__ */ new Map();
|
|
7714
|
+
const reasoningBlocks = /* @__PURE__ */ new Map();
|
|
7132
7715
|
for await (const event of parseSSEStream(res.body)) {
|
|
7133
7716
|
let data;
|
|
7134
7717
|
try {
|
|
@@ -7158,6 +7741,10 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7158
7741
|
name: block.name ?? "",
|
|
7159
7742
|
arguments: ""
|
|
7160
7743
|
});
|
|
7744
|
+
} else if (block?.type === "thinking") {
|
|
7745
|
+
reasoningBlocks.set(idx, { type: "thinking", text: block.thinking ?? "", signature: block.signature });
|
|
7746
|
+
} else if (block?.type === "redacted_thinking") {
|
|
7747
|
+
reasoningBlocks.set(idx, { type: "redacted_thinking", data: block.data });
|
|
7161
7748
|
}
|
|
7162
7749
|
break;
|
|
7163
7750
|
}
|
|
@@ -7170,6 +7757,19 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7170
7757
|
model,
|
|
7171
7758
|
delta: { content: delta.text }
|
|
7172
7759
|
};
|
|
7760
|
+
} else if (delta?.type === "thinking_delta" && delta.thinking) {
|
|
7761
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7762
|
+
blk.text = (blk.text ?? "") + delta.thinking;
|
|
7763
|
+
reasoningBlocks.set(idx, blk);
|
|
7764
|
+
yield {
|
|
7765
|
+
id,
|
|
7766
|
+
model,
|
|
7767
|
+
delta: { reasoning: { summary: delta.thinking } }
|
|
7768
|
+
};
|
|
7769
|
+
} else if (delta?.type === "signature_delta" && delta.signature) {
|
|
7770
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7771
|
+
blk.signature = (blk.signature ?? "") + delta.signature;
|
|
7772
|
+
reasoningBlocks.set(idx, blk);
|
|
7173
7773
|
} else if (delta?.type === "input_json_delta" && delta.partial_json) {
|
|
7174
7774
|
const tc = currentToolCalls.get(idx);
|
|
7175
7775
|
if (tc) {
|
|
@@ -7202,10 +7802,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7202
7802
|
cachedOutputTokens: 0,
|
|
7203
7803
|
reasoningTokens: 0
|
|
7204
7804
|
};
|
|
7805
|
+
const blocks = [...reasoningBlocks.values()].filter(
|
|
7806
|
+
(b) => b.type === "thinking" && b.signature || b.type === "redacted_thinking" && b.data
|
|
7807
|
+
);
|
|
7205
7808
|
yield {
|
|
7206
7809
|
id,
|
|
7207
7810
|
model,
|
|
7208
|
-
delta: {},
|
|
7811
|
+
delta: blocks.length > 0 ? { reasoning: { blocks } } : {},
|
|
7209
7812
|
finishReason,
|
|
7210
7813
|
usage
|
|
7211
7814
|
};
|
|
@@ -7297,6 +7900,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7297
7900
|
}
|
|
7298
7901
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7299
7902
|
const content = [];
|
|
7903
|
+
appendReasoningBlocks(content, m.reasoning?.blocks);
|
|
7300
7904
|
if (typeof m.content === "string" && m.content) {
|
|
7301
7905
|
content.push({ type: "text", text: m.content });
|
|
7302
7906
|
}
|
|
@@ -7310,6 +7914,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7310
7914
|
}
|
|
7311
7915
|
return { role: "assistant", content };
|
|
7312
7916
|
}
|
|
7917
|
+
if (m.role === "assistant" && m.reasoning?.blocks?.length) {
|
|
7918
|
+
const content = [];
|
|
7919
|
+
appendReasoningBlocks(content, m.reasoning.blocks);
|
|
7920
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
7921
|
+
if (text) content.push({ type: "text", text });
|
|
7922
|
+
return { role: "assistant", content };
|
|
7923
|
+
}
|
|
7313
7924
|
const msg = { role: m.role };
|
|
7314
7925
|
if (typeof m.content === "string") {
|
|
7315
7926
|
msg.content = m.content;
|
|
@@ -7365,9 +7976,20 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7365
7976
|
parseResponse(json) {
|
|
7366
7977
|
const textParts = [];
|
|
7367
7978
|
const toolCalls = [];
|
|
7979
|
+
const reasoningBlocks = [];
|
|
7980
|
+
const summaryParts = [];
|
|
7368
7981
|
for (const block of json.content ?? []) {
|
|
7369
7982
|
if (block.type === "text") {
|
|
7370
7983
|
textParts.push(block.text);
|
|
7984
|
+
} else if (block.type === "thinking") {
|
|
7985
|
+
reasoningBlocks.push({
|
|
7986
|
+
type: "thinking",
|
|
7987
|
+
text: block.thinking ?? "",
|
|
7988
|
+
signature: block.signature
|
|
7989
|
+
});
|
|
7990
|
+
if (block.thinking) summaryParts.push(block.thinking);
|
|
7991
|
+
} else if (block.type === "redacted_thinking") {
|
|
7992
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: block.data });
|
|
7371
7993
|
} else if (block.type === "tool_use") {
|
|
7372
7994
|
toolCalls.push({
|
|
7373
7995
|
id: block.id,
|
|
@@ -7384,6 +8006,9 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7384
8006
|
cachedInputTokens: usage.cache_read_input_tokens ?? 0,
|
|
7385
8007
|
cachedWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
7386
8008
|
cachedOutputTokens: 0,
|
|
8009
|
+
// Anthropic bills thinking tokens inside `output_tokens` and does not
|
|
8010
|
+
// expose a separate count, so reasoningTokens stays 0 here (cost is still
|
|
8011
|
+
// captured via outputTokens). See docs for the limitation.
|
|
7387
8012
|
reasoningTokens: 0
|
|
7388
8013
|
};
|
|
7389
8014
|
return {
|
|
@@ -7393,6 +8018,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7393
8018
|
toolCalls,
|
|
7394
8019
|
usage: tokenUsage,
|
|
7395
8020
|
finishReason: mapAnthropicStopReason(json.stop_reason),
|
|
8021
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7396
8022
|
raw: json
|
|
7397
8023
|
};
|
|
7398
8024
|
}
|
|
@@ -7417,6 +8043,18 @@ function safeJsonParse(str) {
|
|
|
7417
8043
|
return {};
|
|
7418
8044
|
}
|
|
7419
8045
|
}
|
|
8046
|
+
function appendReasoningBlocks(content, blocks) {
|
|
8047
|
+
if (!blocks?.length) return;
|
|
8048
|
+
for (const b of blocks) {
|
|
8049
|
+
if (b.type === "redacted_thinking") {
|
|
8050
|
+
if (b.data) content.push({ type: "redacted_thinking", data: b.data });
|
|
8051
|
+
} else if (b.type === "thinking") {
|
|
8052
|
+
if (b.signature) {
|
|
8053
|
+
content.push({ type: "thinking", thinking: b.text ?? "", signature: b.signature });
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
}
|
|
8057
|
+
}
|
|
7420
8058
|
|
|
7421
8059
|
// src/providers/azure.ts
|
|
7422
8060
|
var AzureProvider = class extends OpenAIProvider {
|
|
@@ -7460,7 +8098,52 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
7460
8098
|
}
|
|
7461
8099
|
return res;
|
|
7462
8100
|
}
|
|
8101
|
+
/** Azure exposes the Responses API at /openai/responses with api-key auth.
|
|
8102
|
+
* Reasoning summaries require a preview api-version; callers can override via
|
|
8103
|
+
* the `apiVersion` config. */
|
|
8104
|
+
async responsesFetch(body) {
|
|
8105
|
+
body.input = expandAzureResponsesInput(body.input);
|
|
8106
|
+
const deployment = this.deploymentName ?? body.model;
|
|
8107
|
+
if (!deployment) {
|
|
8108
|
+
throw new ProviderError("Azure requires a deploymentName or model", this.providerName);
|
|
8109
|
+
}
|
|
8110
|
+
const url = `${this.endpoint}/openai/responses?api-version=${this.apiVersion}`;
|
|
8111
|
+
const payload = JSON.stringify({ ...body, model: deployment });
|
|
8112
|
+
const res = await fetch(url, {
|
|
8113
|
+
method: "POST",
|
|
8114
|
+
headers: {
|
|
8115
|
+
"Content-Type": "application/json",
|
|
8116
|
+
"api-key": this.azureApiKey,
|
|
8117
|
+
...this.defaultHeaders
|
|
8118
|
+
},
|
|
8119
|
+
body: payload
|
|
8120
|
+
});
|
|
8121
|
+
if (!res.ok) {
|
|
8122
|
+
const text = await res.text().catch(() => "");
|
|
8123
|
+
throw new ProviderError(
|
|
8124
|
+
`Azure OpenAI Responses API error ${res.status}: ${text}`,
|
|
8125
|
+
this.providerName,
|
|
8126
|
+
res.status,
|
|
8127
|
+
text
|
|
8128
|
+
);
|
|
8129
|
+
}
|
|
8130
|
+
return res;
|
|
8131
|
+
}
|
|
7463
8132
|
};
|
|
8133
|
+
function expandAzureResponsesInput(input) {
|
|
8134
|
+
const out = [];
|
|
8135
|
+
for (const item of input) {
|
|
8136
|
+
if (item && item.__assistantWithCalls) {
|
|
8137
|
+
if (item.text) {
|
|
8138
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
8139
|
+
}
|
|
8140
|
+
for (const call of item.calls) out.push(call);
|
|
8141
|
+
} else {
|
|
8142
|
+
out.push(item);
|
|
8143
|
+
}
|
|
8144
|
+
}
|
|
8145
|
+
return out;
|
|
8146
|
+
}
|
|
7464
8147
|
|
|
7465
8148
|
// src/providers/openaiCompatible.ts
|
|
7466
8149
|
var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
@@ -7633,6 +8316,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7633
8316
|
if (request.extra) {
|
|
7634
8317
|
Object.assign(body, request.extra);
|
|
7635
8318
|
}
|
|
8319
|
+
applyBedrockReasoning(body, request.reasoning);
|
|
7636
8320
|
return body;
|
|
7637
8321
|
}
|
|
7638
8322
|
splitSystemMessages(messages) {
|
|
@@ -7666,6 +8350,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7666
8350
|
}
|
|
7667
8351
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7668
8352
|
const content2 = [];
|
|
8353
|
+
appendBedrockReasoning(content2, m.reasoning?.blocks);
|
|
7669
8354
|
if (typeof m.content === "string" && m.content) {
|
|
7670
8355
|
content2.push({ text: m.content });
|
|
7671
8356
|
}
|
|
@@ -7746,9 +8431,23 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7746
8431
|
const output = json.output?.message;
|
|
7747
8432
|
const textParts = [];
|
|
7748
8433
|
const toolCalls = [];
|
|
8434
|
+
const reasoningBlocks = [];
|
|
8435
|
+
const summaryParts = [];
|
|
7749
8436
|
for (const block of output?.content ?? []) {
|
|
7750
8437
|
if (block.text) {
|
|
7751
8438
|
textParts.push(block.text);
|
|
8439
|
+
} else if (block.reasoningContent) {
|
|
8440
|
+
const rc = block.reasoningContent;
|
|
8441
|
+
if (rc.reasoningText) {
|
|
8442
|
+
reasoningBlocks.push({
|
|
8443
|
+
type: "thinking",
|
|
8444
|
+
text: rc.reasoningText.text ?? "",
|
|
8445
|
+
signature: rc.reasoningText.signature
|
|
8446
|
+
});
|
|
8447
|
+
if (rc.reasoningText.text) summaryParts.push(rc.reasoningText.text);
|
|
8448
|
+
} else if (rc.redactedContent) {
|
|
8449
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: rc.redactedContent });
|
|
8450
|
+
}
|
|
7752
8451
|
} else if (block.toolUse) {
|
|
7753
8452
|
toolCalls.push({
|
|
7754
8453
|
id: block.toolUse.toolUseId,
|
|
@@ -7765,6 +8464,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7765
8464
|
cachedInputTokens: usage.cacheReadInputTokenCount ?? 0,
|
|
7766
8465
|
cachedWriteTokens: usage.cacheWriteInputTokenCount ?? 0,
|
|
7767
8466
|
cachedOutputTokens: 0,
|
|
8467
|
+
// Bedrock bills thinking tokens inside outputTokens; no separate count.
|
|
7768
8468
|
reasoningTokens: 0
|
|
7769
8469
|
};
|
|
7770
8470
|
return {
|
|
@@ -7774,10 +8474,25 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7774
8474
|
toolCalls,
|
|
7775
8475
|
usage: tokenUsage,
|
|
7776
8476
|
finishReason: mapBedrockStopReason(json.stopReason),
|
|
8477
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7777
8478
|
raw: json
|
|
7778
8479
|
};
|
|
7779
8480
|
}
|
|
7780
8481
|
};
|
|
8482
|
+
function appendBedrockReasoning(content, blocks) {
|
|
8483
|
+
if (!blocks?.length) return;
|
|
8484
|
+
for (const b of blocks) {
|
|
8485
|
+
if (b.type === "redacted_thinking") {
|
|
8486
|
+
if (b.data) content.push({ reasoningContent: { redactedContent: b.data } });
|
|
8487
|
+
} else if (b.type === "thinking") {
|
|
8488
|
+
if (b.signature) {
|
|
8489
|
+
content.push({
|
|
8490
|
+
reasoningContent: { reasoningText: { text: b.text ?? "", signature: b.signature } }
|
|
8491
|
+
});
|
|
8492
|
+
}
|
|
8493
|
+
}
|
|
8494
|
+
}
|
|
8495
|
+
}
|
|
7781
8496
|
function mapBedrockStopReason(reason) {
|
|
7782
8497
|
switch (reason) {
|
|
7783
8498
|
case "end_turn":
|
|
@@ -8100,10 +8815,15 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8100
8815
|
const parts = candidate?.content?.parts ?? [];
|
|
8101
8816
|
const textParts = [];
|
|
8102
8817
|
const toolCalls = [];
|
|
8818
|
+
const thoughtParts = [];
|
|
8103
8819
|
let toolCallIdx = 0;
|
|
8104
8820
|
for (const part of parts) {
|
|
8105
8821
|
if (part.text) {
|
|
8106
|
-
|
|
8822
|
+
if (part.thought === true) {
|
|
8823
|
+
thoughtParts.push(part.text);
|
|
8824
|
+
} else {
|
|
8825
|
+
textParts.push(part.text);
|
|
8826
|
+
}
|
|
8107
8827
|
} else if (part.functionCall) {
|
|
8108
8828
|
toolCalls.push({
|
|
8109
8829
|
id: `call_${toolCallIdx++}`,
|
|
@@ -8129,6 +8849,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8129
8849
|
toolCalls,
|
|
8130
8850
|
usage: tokenUsage,
|
|
8131
8851
|
finishReason: mapGeminiFinishReason(candidate?.finishReason),
|
|
8852
|
+
reasoning: thoughtParts.length > 0 ? { summary: thoughtParts.join("\n").trim() || void 0 } : void 0,
|
|
8132
8853
|
raw: json
|
|
8133
8854
|
};
|
|
8134
8855
|
}
|
|
@@ -8138,7 +8859,11 @@ var VertexProvider = class extends BaseProvider {
|
|
|
8138
8859
|
const delta = {};
|
|
8139
8860
|
for (const part of parts) {
|
|
8140
8861
|
if (part.text) {
|
|
8141
|
-
|
|
8862
|
+
if (part.thought === true) {
|
|
8863
|
+
delta.reasoning = { summary: (delta.reasoning?.summary ?? "") + part.text };
|
|
8864
|
+
} else {
|
|
8865
|
+
delta.content = (delta.content ?? "") + part.text;
|
|
8866
|
+
}
|
|
8142
8867
|
} else if (part.functionCall) {
|
|
8143
8868
|
if (!delta.toolCalls) delta.toolCalls = [];
|
|
8144
8869
|
delta.toolCalls.push({
|
|
@@ -8212,12 +8937,16 @@ function fromNativeProvider(provider, options) {
|
|
|
8212
8937
|
let fullContent = "";
|
|
8213
8938
|
let allToolCalls = [];
|
|
8214
8939
|
let lastUsage;
|
|
8940
|
+
let reasoningBlocks;
|
|
8215
8941
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
8216
8942
|
for await (const chunk of provider.completeStream(request)) {
|
|
8217
8943
|
if (chunk.delta.content) {
|
|
8218
8944
|
fullContent += chunk.delta.content;
|
|
8219
8945
|
yield chunk.delta.content;
|
|
8220
8946
|
}
|
|
8947
|
+
if (chunk.delta.reasoning?.blocks?.length) {
|
|
8948
|
+
reasoningBlocks = chunk.delta.reasoning.blocks;
|
|
8949
|
+
}
|
|
8221
8950
|
if (chunk.delta.toolCalls) {
|
|
8222
8951
|
for (const tc of chunk.delta.toolCalls) {
|
|
8223
8952
|
if (tc.id) {
|
|
@@ -8238,6 +8967,9 @@ function fromNativeProvider(provider, options) {
|
|
|
8238
8967
|
}
|
|
8239
8968
|
allToolCalls = [...toolCallBuffers.values()];
|
|
8240
8969
|
const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
|
|
8970
|
+
if (reasoningBlocks?.length) {
|
|
8971
|
+
finalMessage.reasoning = { blocks: reasoningBlocks };
|
|
8972
|
+
}
|
|
8241
8973
|
yield finalMessage;
|
|
8242
8974
|
},
|
|
8243
8975
|
bindTools: (tools, _bindOptions) => {
|
|
@@ -8300,6 +9032,10 @@ function toUnifiedMessage(msg) {
|
|
|
8300
9032
|
arguments: tc.function?.arguments ?? tc.arguments ?? "{}"
|
|
8301
9033
|
}));
|
|
8302
9034
|
}
|
|
9035
|
+
const reasoning = msg.reasoning;
|
|
9036
|
+
if (reasoning && (reasoning.blocks?.length || reasoning.summary)) {
|
|
9037
|
+
unified.reasoning = reasoning;
|
|
9038
|
+
}
|
|
8303
9039
|
return unified;
|
|
8304
9040
|
}
|
|
8305
9041
|
function convertContent(content) {
|
|
@@ -8508,6 +9244,9 @@ function toBaseChatMessage(response) {
|
|
|
8508
9244
|
function: { name: tc.name, arguments: tc.arguments }
|
|
8509
9245
|
}));
|
|
8510
9246
|
}
|
|
9247
|
+
if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
|
|
9248
|
+
msg.reasoning = response.reasoning;
|
|
9249
|
+
}
|
|
8511
9250
|
return msg;
|
|
8512
9251
|
}
|
|
8513
9252
|
function assembleMessage(content, toolCalls, usage) {
|
|
@@ -8609,25 +9348,32 @@ exports.AzureProvider = AzureProvider;
|
|
|
8609
9348
|
exports.BaseProvider = BaseProvider;
|
|
8610
9349
|
exports.BedrockProvider = BedrockProvider;
|
|
8611
9350
|
exports.DEFAULT_PROFILE_CONFIGS = DEFAULT_PROFILE_CONFIGS;
|
|
9351
|
+
exports.DEFAULT_SKILL_POLICY = DEFAULT_SKILL_POLICY;
|
|
8612
9352
|
exports.GuardrailPhase = GuardrailPhase;
|
|
8613
9353
|
exports.InMemoryMemoryStore = InMemoryMemoryStore;
|
|
8614
9354
|
exports.NativeJsonSchemaStrategy = NativeJsonSchemaStrategy;
|
|
8615
9355
|
exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
|
|
8616
9356
|
exports.OpenAIProvider = OpenAIProvider;
|
|
8617
9357
|
exports.ProviderError = ProviderError;
|
|
9358
|
+
exports.SMALL_TIER_SKILL_POLICY = SMALL_TIER_SKILL_POLICY;
|
|
8618
9359
|
exports.StructuredOutputManager = StructuredOutputManager;
|
|
8619
9360
|
exports.ToolBasedStrategy = ToolBasedStrategy;
|
|
8620
9361
|
exports.VertexProvider = VertexProvider;
|
|
8621
9362
|
exports.agentVerdictRule = agentVerdictRule;
|
|
9363
|
+
exports.appendBoundTools = appendBoundTools;
|
|
9364
|
+
exports.buildSkillHeaderBlock = buildSkillHeaderBlock;
|
|
8622
9365
|
exports.buildSystemPrompt = buildSystemPrompt;
|
|
9366
|
+
exports.canOpenSkill = canOpenSkill;
|
|
8623
9367
|
exports.captureSnapshot = captureSnapshot;
|
|
8624
9368
|
exports.codePresenceRule = codePresenceRule;
|
|
8625
9369
|
exports.cognipeerSink = cognipeerSink;
|
|
9370
|
+
exports.composeToolSets = composeToolSets;
|
|
8626
9371
|
exports.countApproxTokens = countApproxTokens;
|
|
8627
9372
|
exports.countMessagesTokens = countMessagesTokens;
|
|
8628
9373
|
exports.createAgent = createAgent;
|
|
8629
9374
|
exports.createAgentNode = createAgentNode;
|
|
8630
9375
|
exports.createAskUserQuestionTool = createAskUserQuestionTool;
|
|
9376
|
+
exports.createBindSkillToolsTool = createBindSkillToolsTool;
|
|
8631
9377
|
exports.createCodeGuardrail = createCodeGuardrail;
|
|
8632
9378
|
exports.createContextSummarizeNode = createContextSummarizeNode;
|
|
8633
9379
|
exports.createContextTools = createContextTools;
|
|
@@ -8635,15 +9381,19 @@ exports.createGetToolResponseTool = createGetToolResponseTool;
|
|
|
8635
9381
|
exports.createGuardrail = createGuardrail;
|
|
8636
9382
|
exports.createJsonGuardrail = createJsonGuardrail;
|
|
8637
9383
|
exports.createManageTodoTool = createManageTodoTool;
|
|
9384
|
+
exports.createOpenSkillTool = createOpenSkillTool;
|
|
8638
9385
|
exports.createProvider = createProvider;
|
|
8639
9386
|
exports.createRegexGuardrail = createRegexGuardrail;
|
|
8640
9387
|
exports.createResolverNode = createResolverNode;
|
|
9388
|
+
exports.createSkillRegistryRef = createSkillRegistryRef;
|
|
9389
|
+
exports.createSkillTools = createSkillTools;
|
|
8641
9390
|
exports.createSmartAgent = createSmartAgent;
|
|
8642
9391
|
exports.createTool = createTool;
|
|
8643
9392
|
exports.createToolLimitFinalizeNode = createToolLimitFinalizeNode;
|
|
8644
9393
|
exports.createToolsNode = createToolsNode;
|
|
8645
9394
|
exports.customCallbackRule = customCallbackRule;
|
|
8646
9395
|
exports.customSink = customSink;
|
|
9396
|
+
exports.dedupeToolsByName = dedupeToolsByName;
|
|
8647
9397
|
exports.defaultTokenCounter = defaultTokenCounter;
|
|
8648
9398
|
exports.emptyUsage = emptyUsage;
|
|
8649
9399
|
exports.evaluateGuardrails = evaluateGuardrails;
|
|
@@ -8666,7 +9416,9 @@ exports.normalizeSmartAgentOptions = normalizeSmartAgentOptions;
|
|
|
8666
9416
|
exports.otlpSink = otlpSink;
|
|
8667
9417
|
exports.readMemoryFacts = readMemoryFacts;
|
|
8668
9418
|
exports.regexRule = regexRule;
|
|
9419
|
+
exports.resolveAvailableSkills = resolveAvailableSkills;
|
|
8669
9420
|
exports.resolveMemoryStore = resolveMemoryStore;
|
|
9421
|
+
exports.resolveReasoning = resolveReasoning;
|
|
8670
9422
|
exports.resolveStrategy = resolveStrategy;
|
|
8671
9423
|
exports.resolveToolApprovalState = resolveToolApprovalState;
|
|
8672
9424
|
exports.resolveUserQuestionState = resolveUserQuestionState;
|
|
@@ -8675,6 +9427,7 @@ exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
|
|
|
8675
9427
|
exports.setTokenCounter = setTokenCounter;
|
|
8676
9428
|
exports.startStreamingSession = startStreamingSession;
|
|
8677
9429
|
exports.traceSessionToOtlp = traceSessionToOtlp;
|
|
9430
|
+
exports.validateReasoningConfig = validateReasoningConfig;
|
|
8678
9431
|
exports.withTools = withTools;
|
|
8679
9432
|
exports.writeSummaryFactsToMemory = writeSummaryFactsToMemory;
|
|
8680
9433
|
//# sourceMappingURL=index.cjs.map
|