@cognipeer/agent-sdk 0.6.0 → 0.6.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 +58 -8
- package/dist/index.cjs +324 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -5
- package/dist/index.d.ts +117 -5
- package/dist/index.mjs +325 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import fs from 'fs';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
7
7
|
import { nanoid } from 'nanoid';
|
|
8
|
-
import crypto, { createHash, createHmac } from 'crypto';
|
|
8
|
+
import crypto, { randomUUID, createHash, createHmac } from 'crypto';
|
|
9
9
|
import AjvModule from 'ajv';
|
|
10
10
|
|
|
11
11
|
// src/adapters/langchain.ts
|
|
@@ -1968,7 +1968,9 @@ function createAgentCoreNode(opts) {
|
|
|
1968
1968
|
const cancellationToken = state.ctx?.__cancellationToken;
|
|
1969
1969
|
const abortSignal = state.ctx?.__abortSignal;
|
|
1970
1970
|
const responseFormat = runtime.responseFormat;
|
|
1971
|
-
const
|
|
1971
|
+
const reasoningForCall = state.ctx?.__reasoning;
|
|
1972
|
+
const reasoningInvokeOpts = reasoningForCall ? { reasoning: reasoningForCall } : void 0;
|
|
1973
|
+
const extractText2 = (chunk) => {
|
|
1972
1974
|
if (chunk == null) return "";
|
|
1973
1975
|
if (typeof chunk === "string") return chunk;
|
|
1974
1976
|
if (typeof chunk?.content === "string") return chunk.content;
|
|
@@ -1986,7 +1988,7 @@ function createAgentCoreNode(opts) {
|
|
|
1986
1988
|
if (streamingEnabled && typeof modelWithTools.stream === "function") {
|
|
1987
1989
|
let streamedText = "";
|
|
1988
1990
|
let streamedMessage;
|
|
1989
|
-
const streamOptions = { signal: abortSignal, cancellationToken, ...responseFormat };
|
|
1991
|
+
const streamOptions = { signal: abortSignal, cancellationToken, ...responseFormat, ...reasoningInvokeOpts };
|
|
1990
1992
|
for await (const chunk of modelWithTools.stream(normalizedMessages, streamOptions)) {
|
|
1991
1993
|
if (cancellationToken && cancellationToken.isCancellationRequested || abortSignal?.aborted) {
|
|
1992
1994
|
break;
|
|
@@ -1994,7 +1996,7 @@ function createAgentCoreNode(opts) {
|
|
|
1994
1996
|
if (chunk && typeof chunk === "object" && chunk.role) {
|
|
1995
1997
|
streamedMessage = chunk;
|
|
1996
1998
|
}
|
|
1997
|
-
const text =
|
|
1999
|
+
const text = extractText2(chunk);
|
|
1998
2000
|
if (text) {
|
|
1999
2001
|
streamedText += text;
|
|
2000
2002
|
onStream?.({ text });
|
|
@@ -2010,7 +2012,7 @@ function createAgentCoreNode(opts) {
|
|
|
2010
2012
|
response = { role: "assistant", content: streamedText };
|
|
2011
2013
|
}
|
|
2012
2014
|
} else {
|
|
2013
|
-
response = await modelWithTools.invoke(normalizedMessages, { signal: abortSignal, cancellationToken, ...responseFormat });
|
|
2015
|
+
response = await modelWithTools.invoke(normalizedMessages, { signal: abortSignal, cancellationToken, ...responseFormat, ...reasoningInvokeOpts });
|
|
2014
2016
|
}
|
|
2015
2017
|
} catch (err) {
|
|
2016
2018
|
const durationMs2 = Date.now() - start;
|
|
@@ -2097,8 +2099,6 @@ var BASE_DEFAULTS = {
|
|
|
2097
2099
|
policy: "hybrid",
|
|
2098
2100
|
lastTurnsToKeep: 8,
|
|
2099
2101
|
toolResponsePolicy: "summarize_archive",
|
|
2100
|
-
archiveLargeToolResponses: true,
|
|
2101
|
-
retrieveArchivedToolResponseOnDemand: true,
|
|
2102
2102
|
budget: {
|
|
2103
2103
|
systemReserveTokens: 1200,
|
|
2104
2104
|
goalsReserveTokens: 1200,
|
|
@@ -2131,8 +2131,7 @@ var BASE_DEFAULTS = {
|
|
|
2131
2131
|
defaultPolicy: "summarize_archive",
|
|
2132
2132
|
toolResponseRetentionByTool: {},
|
|
2133
2133
|
criticalTools: [...DEFAULT_CRITICAL_TOOLS],
|
|
2134
|
-
schemaValidation: "strict"
|
|
2135
|
-
retryOnSchemaError: true
|
|
2134
|
+
schemaValidation: "strict"
|
|
2136
2135
|
}
|
|
2137
2136
|
};
|
|
2138
2137
|
function buildProfile(overrides) {
|
|
@@ -2929,6 +2928,246 @@ function createToolLimitFinalizeNode(_opts) {
|
|
|
2929
2928
|
return { messages: [...state.messages, notice], ctx };
|
|
2930
2929
|
};
|
|
2931
2930
|
}
|
|
2931
|
+
var REFLECTION_SYSTEM_NAME = "agent_reflection";
|
|
2932
|
+
var REFLECTION_ASK_NAME = "agent_reflection_ask";
|
|
2933
|
+
var DEFAULT_REFLECT_PROMPT = `Reflect briefly \u2014 plain text, no JSON, no tool calls.
|
|
2934
|
+
Structure your note (1\u20132 sentences each):
|
|
2935
|
+
1) What the latest tool results actually tell us (facts, surprises).
|
|
2936
|
+
2) What is still missing or uncertain before we can finish the user's task.
|
|
2937
|
+
3) The single next step you plan to take, and why that step over alternatives.
|
|
2938
|
+
Be concrete. Do not repeat the task description. Do not apologize. Max ${"${maxChars}"} characters total.`;
|
|
2939
|
+
function trimToChars(text, maxChars) {
|
|
2940
|
+
if (text.length <= maxChars) return text;
|
|
2941
|
+
return text.slice(0, maxChars - 1).trimEnd() + "\u2026";
|
|
2942
|
+
}
|
|
2943
|
+
function countToolCallsInLastTurn(state) {
|
|
2944
|
+
const ids = [];
|
|
2945
|
+
const names = [];
|
|
2946
|
+
for (let i = state.messages.length - 1; i >= 0; i--) {
|
|
2947
|
+
const m = state.messages[i];
|
|
2948
|
+
if (m?.role === "tool") {
|
|
2949
|
+
if (m.tool_call_id) ids.push(m.tool_call_id);
|
|
2950
|
+
if (m.name) names.push(m.name);
|
|
2951
|
+
} else if (m?.role === "assistant") {
|
|
2952
|
+
break;
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
return { ids, names };
|
|
2956
|
+
}
|
|
2957
|
+
function stripReflectionAskMessages(messages) {
|
|
2958
|
+
return messages.filter((m) => !(m?.role === "user" && m?.name === REFLECTION_ASK_NAME));
|
|
2959
|
+
}
|
|
2960
|
+
function shouldRunReflection(cadence, state, ranToolsThisTurn) {
|
|
2961
|
+
if (cadence === "off") return false;
|
|
2962
|
+
if (cadence === "every_turn") return true;
|
|
2963
|
+
if (cadence === "after_tool") return ranToolsThisTurn;
|
|
2964
|
+
if (cadence === "on_branch") {
|
|
2965
|
+
const reflections = state.reflections || [];
|
|
2966
|
+
const lastReflectionTurn = reflections[reflections.length - 1]?.turn ?? -1;
|
|
2967
|
+
const currentTurnId = state.toolCallCount ?? 0;
|
|
2968
|
+
return currentTurnId - lastReflectionTurn >= 2;
|
|
2969
|
+
}
|
|
2970
|
+
return false;
|
|
2971
|
+
}
|
|
2972
|
+
function createReflectionNode(opts, resolved) {
|
|
2973
|
+
return async function reflectNode(state, trigger) {
|
|
2974
|
+
if (!resolved.enabled) return {};
|
|
2975
|
+
const runtime = state.agent || {
|
|
2976
|
+
model: opts.model,
|
|
2977
|
+
name: opts.name,
|
|
2978
|
+
version: opts.version
|
|
2979
|
+
};
|
|
2980
|
+
const model = runtime.model;
|
|
2981
|
+
if (!model?.invoke && !model?.stream) return {};
|
|
2982
|
+
const onEvent = state.ctx?.__onEvent;
|
|
2983
|
+
const traceSession = state.ctx?.__traceSession;
|
|
2984
|
+
const maxChars = resolved.maxChars;
|
|
2985
|
+
const promptBody = (resolved.promptTemplate || DEFAULT_REFLECT_PROMPT).replace(/\$\{maxChars\}/g, String(maxChars));
|
|
2986
|
+
const baseMessages = stripReflectionAskMessages([...state.messages]);
|
|
2987
|
+
const askMessage = {
|
|
2988
|
+
role: "user",
|
|
2989
|
+
name: REFLECTION_ASK_NAME,
|
|
2990
|
+
content: promptBody
|
|
2991
|
+
};
|
|
2992
|
+
const messagesForCall = resolved.mode === "piggyback" ? [...baseMessages, askMessage] : buildSeparateCallMessages(baseMessages, promptBody);
|
|
2993
|
+
const start = Date.now();
|
|
2994
|
+
let response;
|
|
2995
|
+
try {
|
|
2996
|
+
response = await model.invoke(messagesForCall, {
|
|
2997
|
+
// tool_choice:"none" so the model won't try to call tools during reflection
|
|
2998
|
+
tool_choice: "none",
|
|
2999
|
+
toolChoice: "none",
|
|
3000
|
+
// Override max_tokens for the reflection call. BaseChatModel passes this through
|
|
3001
|
+
// to the adapter which forwards into the provider body.
|
|
3002
|
+
max_tokens: resolved.maxTokens,
|
|
3003
|
+
maxTokens: resolved.maxTokens
|
|
3004
|
+
});
|
|
3005
|
+
} catch (err) {
|
|
3006
|
+
recordTraceEvent(traceSession, {
|
|
3007
|
+
type: "reflection",
|
|
3008
|
+
label: "Reflection error",
|
|
3009
|
+
actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
|
|
3010
|
+
status: "error",
|
|
3011
|
+
error: { message: err?.message || String(err) }
|
|
3012
|
+
});
|
|
3013
|
+
return {};
|
|
3014
|
+
}
|
|
3015
|
+
const durationMs = Date.now() - start;
|
|
3016
|
+
const rawText = extractText(response);
|
|
3017
|
+
const text = trimToChars(String(rawText ?? "").trim(), maxChars);
|
|
3018
|
+
if (!text) return {};
|
|
3019
|
+
const rawUsage = response?.usage_metadata || response?.response_metadata?.usage || response?.usage || response?.additional_kwargs?.usage;
|
|
3020
|
+
const usage = normalizeUsage(rawUsage);
|
|
3021
|
+
const { ids, names } = countToolCallsInLastTurn(state);
|
|
3022
|
+
const turn = state.toolCallCount ?? 0;
|
|
3023
|
+
const record = {
|
|
3024
|
+
id: safeRandomId(),
|
|
3025
|
+
turn,
|
|
3026
|
+
text,
|
|
3027
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3028
|
+
durationMs,
|
|
3029
|
+
anchorMessageIndex: state.messages.length,
|
|
3030
|
+
trigger,
|
|
3031
|
+
usage: usage ? {
|
|
3032
|
+
inputTokens: usage.prompt_tokens,
|
|
3033
|
+
outputTokens: usage.completion_tokens,
|
|
3034
|
+
cachedInputTokens: usage.prompt_tokens_details?.cached_tokens,
|
|
3035
|
+
totalTokens: usage.total_tokens,
|
|
3036
|
+
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens
|
|
3037
|
+
} : void 0,
|
|
3038
|
+
toolCallIds: ids.length > 0 ? ids : void 0
|
|
3039
|
+
};
|
|
3040
|
+
recordTraceEvent(traceSession, {
|
|
3041
|
+
type: "reflection",
|
|
3042
|
+
label: `Reflection turn ${turn}`,
|
|
3043
|
+
actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
|
|
3044
|
+
status: "success",
|
|
3045
|
+
durationMs,
|
|
3046
|
+
inputTokens: record.usage?.inputTokens,
|
|
3047
|
+
outputTokens: record.usage?.outputTokens,
|
|
3048
|
+
cachedInputTokens: record.usage?.cachedInputTokens,
|
|
3049
|
+
totalTokens: record.usage?.totalTokens,
|
|
3050
|
+
debug: { text, toolNames: names }
|
|
3051
|
+
});
|
|
3052
|
+
if (resolved.emitEvents) {
|
|
3053
|
+
try {
|
|
3054
|
+
onEvent?.({
|
|
3055
|
+
type: "reflection",
|
|
3056
|
+
id: record.id,
|
|
3057
|
+
turn,
|
|
3058
|
+
text,
|
|
3059
|
+
trigger,
|
|
3060
|
+
durationMs,
|
|
3061
|
+
usage: record.usage,
|
|
3062
|
+
toolCallIds: record.toolCallIds
|
|
3063
|
+
});
|
|
3064
|
+
} catch (e) {
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
const nextMessages = stripReflectionAskMessages([...state.messages]);
|
|
3068
|
+
const reflections = [...state.reflections || [], record];
|
|
3069
|
+
const kept = reflections.slice(-Math.max(1, resolved.keepLast));
|
|
3070
|
+
const prunedMessages = nextMessages.filter(
|
|
3071
|
+
(m) => !(m?.role === "system" && m?.name === REFLECTION_SYSTEM_NAME)
|
|
3072
|
+
);
|
|
3073
|
+
for (const r of kept) {
|
|
3074
|
+
prunedMessages.push({
|
|
3075
|
+
role: "system",
|
|
3076
|
+
name: REFLECTION_SYSTEM_NAME,
|
|
3077
|
+
content: `<agent_reflection turn=${r.turn} at=${r.createdAt}>
|
|
3078
|
+
${r.text}
|
|
3079
|
+
</agent_reflection>`,
|
|
3080
|
+
metadata: { reflectionId: r.id, reflectionTurn: r.turn, reflectionTrigger: r.trigger }
|
|
3081
|
+
});
|
|
3082
|
+
}
|
|
3083
|
+
return { messages: prunedMessages, reflections };
|
|
3084
|
+
};
|
|
3085
|
+
}
|
|
3086
|
+
function extractText(chunk) {
|
|
3087
|
+
if (chunk == null) return "";
|
|
3088
|
+
if (typeof chunk === "string") return chunk;
|
|
3089
|
+
if (typeof chunk?.content === "string") return chunk.content;
|
|
3090
|
+
if (Array.isArray(chunk?.content)) {
|
|
3091
|
+
return chunk.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("");
|
|
3092
|
+
}
|
|
3093
|
+
if (typeof chunk?.text === "string") return chunk.text;
|
|
3094
|
+
return "";
|
|
3095
|
+
}
|
|
3096
|
+
function buildSeparateCallMessages(base, promptBody) {
|
|
3097
|
+
const systemMessages = base.filter((m) => m?.role === "system");
|
|
3098
|
+
const tail = base.slice(-8);
|
|
3099
|
+
return [
|
|
3100
|
+
...systemMessages,
|
|
3101
|
+
...tail,
|
|
3102
|
+
{ role: "user", name: REFLECTION_ASK_NAME, content: promptBody }
|
|
3103
|
+
];
|
|
3104
|
+
}
|
|
3105
|
+
function safeRandomId() {
|
|
3106
|
+
try {
|
|
3107
|
+
return randomUUID();
|
|
3108
|
+
} catch {
|
|
3109
|
+
return `r_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`;
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3113
|
+
// src/smart/reasoning.ts
|
|
3114
|
+
var LEVEL_DEFAULTS = {
|
|
3115
|
+
low: {
|
|
3116
|
+
native: { effort: "low" },
|
|
3117
|
+
reflection: { maxTokens: 200, maxChars: 600, cadence: "on_branch" }
|
|
3118
|
+
},
|
|
3119
|
+
medium: {
|
|
3120
|
+
native: { effort: "medium" },
|
|
3121
|
+
reflection: { maxTokens: 350, maxChars: 1200, cadence: "after_tool" }
|
|
3122
|
+
},
|
|
3123
|
+
high: {
|
|
3124
|
+
native: { effort: "high" },
|
|
3125
|
+
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "after_tool" }
|
|
3126
|
+
}
|
|
3127
|
+
};
|
|
3128
|
+
function resolveReasoning(input) {
|
|
3129
|
+
if (!input || input.enabled === false) return void 0;
|
|
3130
|
+
const enabled = input.enabled ?? (input.native !== void 0 || input.reflection !== void 0 || input.level !== void 0);
|
|
3131
|
+
if (!enabled) return void 0;
|
|
3132
|
+
const level = input.level ?? "medium";
|
|
3133
|
+
const presets = LEVEL_DEFAULTS[level];
|
|
3134
|
+
let native;
|
|
3135
|
+
if (input.native === false) {
|
|
3136
|
+
native = void 0;
|
|
3137
|
+
} else {
|
|
3138
|
+
native = { ...presets.native, ...input.native ?? {} };
|
|
3139
|
+
}
|
|
3140
|
+
const reflection = resolveReflection(input.reflection, presets.reflection);
|
|
3141
|
+
return { enabled: true, level, native, reflection };
|
|
3142
|
+
}
|
|
3143
|
+
function resolveReflection(input, preset) {
|
|
3144
|
+
if (input === false) {
|
|
3145
|
+
return {
|
|
3146
|
+
enabled: false,
|
|
3147
|
+
cadence: "off",
|
|
3148
|
+
mode: "piggyback",
|
|
3149
|
+
maxTokens: preset.maxTokens,
|
|
3150
|
+
maxChars: preset.maxChars,
|
|
3151
|
+
keepLast: 3,
|
|
3152
|
+
summarize: false,
|
|
3153
|
+
emitEvents: true
|
|
3154
|
+
};
|
|
3155
|
+
}
|
|
3156
|
+
const cfg = input ?? {};
|
|
3157
|
+
const enabled = cfg.enabled ?? true;
|
|
3158
|
+
const cadence = cfg.cadence ?? preset.cadence;
|
|
3159
|
+
return {
|
|
3160
|
+
enabled: enabled && cadence !== "off",
|
|
3161
|
+
cadence: enabled ? cadence : "off",
|
|
3162
|
+
mode: cfg.mode ?? "piggyback",
|
|
3163
|
+
maxTokens: cfg.maxTokens ?? preset.maxTokens,
|
|
3164
|
+
maxChars: cfg.maxChars ?? preset.maxChars,
|
|
3165
|
+
keepLast: cfg.keepLast ?? 3,
|
|
3166
|
+
summarize: cfg.summarize ?? false,
|
|
3167
|
+
promptTemplate: cfg.promptTemplate,
|
|
3168
|
+
emitEvents: cfg.emitEvents ?? true
|
|
3169
|
+
};
|
|
3170
|
+
}
|
|
2932
3171
|
function ensureArray(value) {
|
|
2933
3172
|
return Array.isArray(value) ? value : [];
|
|
2934
3173
|
}
|
|
@@ -3342,6 +3581,8 @@ function createAgent(opts) {
|
|
|
3342
3581
|
}
|
|
3343
3582
|
const toolsNode = createToolsNode(toolsBase, opts);
|
|
3344
3583
|
const finalizeNode = createToolLimitFinalizeNode();
|
|
3584
|
+
const resolvedReasoning = resolveReasoning(opts.reasoning);
|
|
3585
|
+
const reflectNode = resolvedReasoning?.reflection.enabled ? createReflectionNode(opts, resolvedReasoning.reflection) : void 0;
|
|
3345
3586
|
const mergeGuardrailOutcomes = (prev, next) => {
|
|
3346
3587
|
if (!prev) return next;
|
|
3347
3588
|
return {
|
|
@@ -3396,6 +3637,13 @@ function createAgent(opts) {
|
|
|
3396
3637
|
if (summarizationThreshold === void 0) {
|
|
3397
3638
|
state = clearNeedsSummarization(state);
|
|
3398
3639
|
}
|
|
3640
|
+
if (resolvedReasoning?.native) {
|
|
3641
|
+
const ctx = { ...state.ctx || {} };
|
|
3642
|
+
if (!ctx.__reasoning) {
|
|
3643
|
+
ctx.__reasoning = resolvedReasoning.native;
|
|
3644
|
+
state = { ...state, ctx };
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3399
3647
|
const mergedLimits = {
|
|
3400
3648
|
...opts.limits || {},
|
|
3401
3649
|
...config?.limits || {}
|
|
@@ -3624,6 +3872,18 @@ function createAgent(opts) {
|
|
|
3624
3872
|
if (state.ctx?.__awaitingApproval) break;
|
|
3625
3873
|
if (checkpointIfRequested("after_tools")) break;
|
|
3626
3874
|
if (state.ctx?.__finalizedDueToStructuredOutput) break;
|
|
3875
|
+
if (reflectNode && resolvedReasoning?.reflection.enabled) {
|
|
3876
|
+
const cadence = resolvedReasoning.reflection.cadence;
|
|
3877
|
+
if (shouldRunReflection(cadence, state, true)) {
|
|
3878
|
+
try {
|
|
3879
|
+
const patch = await reflectNode(state, cadence);
|
|
3880
|
+
if (patch && Object.keys(patch).length > 0) {
|
|
3881
|
+
state = { ...state, ...patch };
|
|
3882
|
+
}
|
|
3883
|
+
} catch {
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3627
3887
|
}
|
|
3628
3888
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
|
|
3629
3889
|
const lastForParse = state.messages[state.messages.length - 1];
|
|
@@ -5633,6 +5893,52 @@ function parseSSEBlock(block) {
|
|
|
5633
5893
|
return { event, data: dataLines.join("\n"), id, retry };
|
|
5634
5894
|
}
|
|
5635
5895
|
|
|
5896
|
+
// src/providers/utils/reasoning.ts
|
|
5897
|
+
function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
5898
|
+
if (!reasoning) return;
|
|
5899
|
+
const effort = normalizeEffort(reasoning.effort);
|
|
5900
|
+
if (mode === "responses") {
|
|
5901
|
+
const obj = {};
|
|
5902
|
+
if (effort) obj.effort = effort;
|
|
5903
|
+
if (reasoning.includeThoughts) obj.summary = "auto";
|
|
5904
|
+
if (reasoning.providerExtras) Object.assign(obj, reasoning.providerExtras);
|
|
5905
|
+
if (Object.keys(obj).length > 0) body.reasoning = obj;
|
|
5906
|
+
} else {
|
|
5907
|
+
if (effort) body.reasoning_effort = effort;
|
|
5908
|
+
if (reasoning.providerExtras) Object.assign(body, reasoning.providerExtras);
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
function applyAnthropicReasoning(body, reasoning) {
|
|
5912
|
+
if (!reasoning) return;
|
|
5913
|
+
const budget = resolveBudget(reasoning, { low: 2048, medium: 8192, high: 16384, minimal: 1024 });
|
|
5914
|
+
if (!budget) return;
|
|
5915
|
+
const thinking = { type: "enabled", budget_tokens: budget };
|
|
5916
|
+
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
5917
|
+
body.thinking = thinking;
|
|
5918
|
+
}
|
|
5919
|
+
function applyGeminiReasoning(generationConfig, reasoning) {
|
|
5920
|
+
if (!reasoning) return;
|
|
5921
|
+
const budget = resolveBudget(reasoning, { low: 1024, medium: 4096, high: 12e3, minimal: 512 });
|
|
5922
|
+
if (budget == null) return;
|
|
5923
|
+
const thinkingConfig = { thinkingBudget: budget };
|
|
5924
|
+
if (reasoning.includeThoughts) thinkingConfig.includeThoughts = true;
|
|
5925
|
+
if (reasoning.providerExtras) Object.assign(thinkingConfig, reasoning.providerExtras);
|
|
5926
|
+
generationConfig.thinkingConfig = thinkingConfig;
|
|
5927
|
+
}
|
|
5928
|
+
function normalizeEffort(effort) {
|
|
5929
|
+
if (!effort) return void 0;
|
|
5930
|
+
const allowed = ["minimal", "low", "medium", "high"];
|
|
5931
|
+
return allowed.includes(effort) ? effort : void 0;
|
|
5932
|
+
}
|
|
5933
|
+
function resolveBudget(reasoning, effortBudget) {
|
|
5934
|
+
if (typeof reasoning.budgetTokens === "number" && reasoning.budgetTokens > 0) {
|
|
5935
|
+
return Math.floor(reasoning.budgetTokens);
|
|
5936
|
+
}
|
|
5937
|
+
const effort = normalizeEffort(reasoning.effort);
|
|
5938
|
+
if (effort && effortBudget[effort]) return effortBudget[effort];
|
|
5939
|
+
return void 0;
|
|
5940
|
+
}
|
|
5941
|
+
|
|
5636
5942
|
// src/providers/openai.ts
|
|
5637
5943
|
var OpenAIProvider = class extends BaseProvider {
|
|
5638
5944
|
constructor(config) {
|
|
@@ -5748,6 +6054,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
5748
6054
|
if (request.extra) {
|
|
5749
6055
|
Object.assign(body, request.extra);
|
|
5750
6056
|
}
|
|
6057
|
+
applyOpenAIReasoning(body, request.reasoning, "legacy_effort");
|
|
5751
6058
|
return body;
|
|
5752
6059
|
}
|
|
5753
6060
|
toOpenAIMessage(m) {
|
|
@@ -6006,6 +6313,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
6006
6313
|
if (request.extra) {
|
|
6007
6314
|
Object.assign(body, request.extra);
|
|
6008
6315
|
}
|
|
6316
|
+
applyAnthropicReasoning(body, request.reasoning);
|
|
6009
6317
|
return body;
|
|
6010
6318
|
}
|
|
6011
6319
|
splitSystemMessages(messages) {
|
|
@@ -6660,6 +6968,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
6660
6968
|
}
|
|
6661
6969
|
}
|
|
6662
6970
|
}
|
|
6971
|
+
applyGeminiReasoning(generationConfig, request.reasoning);
|
|
6663
6972
|
if (Object.keys(generationConfig).length > 0) body.generationConfig = generationConfig;
|
|
6664
6973
|
if (request.tools?.length) {
|
|
6665
6974
|
body.tools = [
|
|
@@ -6998,6 +7307,13 @@ function fromNativeProvider(provider, options) {
|
|
|
6998
7307
|
if (opts?.maxTokens != null) req.maxTokens = opts.maxTokens;
|
|
6999
7308
|
if (tools?.length) req.tools = tools;
|
|
7000
7309
|
if (opts?.extra) req.extra = opts.extra;
|
|
7310
|
+
const reasoningOverride = invokeOptions?.reasoning;
|
|
7311
|
+
const reasoningCfg = reasoningOverride ?? opts?.reasoning;
|
|
7312
|
+
if (reasoningCfg) req.reasoning = reasoningCfg;
|
|
7313
|
+
const tc = invokeOptions?.tool_choice ?? invokeOptions?.toolChoice;
|
|
7314
|
+
if (tc) {
|
|
7315
|
+
req.toolChoice = tc;
|
|
7316
|
+
}
|
|
7001
7317
|
const rf = invokeOptions?.response_format;
|
|
7002
7318
|
if (rf && typeof rf === "object" && rf.type) {
|
|
7003
7319
|
if (rf.type === "json_schema" && rf.json_schema) {
|