@cognipeer/agent-sdk 0.8.9 → 0.8.10
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 +33 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -5
- package/dist/index.d.ts +46 -5
- package/dist/index.mjs +33 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -719,7 +719,8 @@ type ReflectionConfig = {
|
|
|
719
719
|
onReflection?: (record: ReflectionRecord, ctx: ReflectionHookContext) => void;
|
|
720
720
|
};
|
|
721
721
|
type NativeReasoningConfig = {
|
|
722
|
-
|
|
722
|
+
/** `none` is OFF — a value that gets SENT. See ReasoningEffort in providers/types.ts. */
|
|
723
|
+
effort?: "none" | "minimal" | "low" | "medium" | "high";
|
|
723
724
|
budgetTokens?: number;
|
|
724
725
|
includeThoughts?: boolean;
|
|
725
726
|
providerExtras?: Record<string, any>;
|
|
@@ -2918,7 +2919,18 @@ type ChatCompletionRequest = {
|
|
|
2918
2919
|
*/
|
|
2919
2920
|
reasoning?: ReasoningRequestConfig;
|
|
2920
2921
|
};
|
|
2921
|
-
|
|
2922
|
+
/**
|
|
2923
|
+
* `none` is OFF, and it is a value rather than the absence of one.
|
|
2924
|
+
*
|
|
2925
|
+
* On a thinking-by-default model — every Qwen3 under vLLM, gpt-5.1 and newer on
|
|
2926
|
+
* OpenAI — sending no reasoning field leaves the model thinking. So "do not
|
|
2927
|
+
* think" is an instruction that has to travel: `reasoning_effort:"none"` on
|
|
2928
|
+
* OpenAI, `thinkingBudget:0` on Gemini, and no thinking block at all on
|
|
2929
|
+
* Anthropic (where thinking is opt-in and the absence IS off). Omitting
|
|
2930
|
+
* `effort` still means "say nothing about reasoning", which is the different
|
|
2931
|
+
* and equally necessary state.
|
|
2932
|
+
*/
|
|
2933
|
+
type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high";
|
|
2922
2934
|
type ReasoningRequestConfig = {
|
|
2923
2935
|
/** Qualitative effort hint (mapped per-provider). */
|
|
2924
2936
|
effort?: ReasoningEffort;
|
|
@@ -2981,6 +2993,28 @@ type OpenAIProviderConfig = {
|
|
|
2981
2993
|
defaultModel?: string;
|
|
2982
2994
|
defaultHeaders?: Record<string, string>;
|
|
2983
2995
|
retry?: ProviderRetryConfig;
|
|
2996
|
+
/**
|
|
2997
|
+
* WHICH API a reasoning-carrying request is addressed to.
|
|
2998
|
+
*
|
|
2999
|
+
* auto (default, and today's behaviour) route to the Responses API when
|
|
3000
|
+
* the request carries `reasoning` AND the model name looks like an
|
|
3001
|
+
* o-series/gpt-5 reasoning model.
|
|
3002
|
+
* never always Chat Completions. `reasoning` is still mapped, as
|
|
3003
|
+
* `reasoning_effort` plus any `providerExtras`.
|
|
3004
|
+
* always always Responses, whatever the model is called.
|
|
3005
|
+
*
|
|
3006
|
+
* `auto` is a name-based guess, and it decides far more than where reasoning
|
|
3007
|
+
* goes: Responses is a different request shape (`input` not `messages`,
|
|
3008
|
+
* `text.format` not `response_format`, flat tool objects) and a different
|
|
3009
|
+
* response parse. A caller with its own measurements of the Chat Completions
|
|
3010
|
+
* body — a gateway, a proxy, an on-prem server that serves one and not the
|
|
3011
|
+
* other, or anything that has tuned `extra` — must be able to say so, rather
|
|
3012
|
+
* than discover that asking for less thinking silently changed the transport.
|
|
3013
|
+
*
|
|
3014
|
+
* Applies to any OpenAI-shaped endpoint, which is also why the guess is weak
|
|
3015
|
+
* where it matters most: a self-hosted model is named by whoever served it.
|
|
3016
|
+
*/
|
|
3017
|
+
responsesApi?: "auto" | "never" | "always";
|
|
2984
3018
|
};
|
|
2985
3019
|
type AnthropicProviderConfig = {
|
|
2986
3020
|
provider: "anthropic";
|
|
@@ -3085,10 +3119,17 @@ declare class OpenAIProvider extends BaseProvider {
|
|
|
3085
3119
|
protected readonly baseURL: string;
|
|
3086
3120
|
protected readonly defaultModel: string;
|
|
3087
3121
|
protected readonly defaultHeaders: Record<string, string>;
|
|
3122
|
+
protected readonly responsesApi: "auto" | "never" | "always";
|
|
3088
3123
|
constructor(config: OpenAIProviderConfig);
|
|
3089
|
-
/** True when
|
|
3090
|
-
*
|
|
3091
|
-
*
|
|
3124
|
+
/** True when this request should go to the Responses API rather than Chat
|
|
3125
|
+
* Completions — which exposes `reasoning.effort` and reasoning summaries that
|
|
3126
|
+
* Chat Completions silently drops.
|
|
3127
|
+
*
|
|
3128
|
+
* `auto` (the default) keeps the historical rule: only when the request
|
|
3129
|
+
* carries a reasoning config AND the model name looks like an o-series/gpt-5
|
|
3130
|
+
* model. `never`/`always` let a caller state the answer instead, because the
|
|
3131
|
+
* name check is a guess and the two APIs differ in far more than reasoning —
|
|
3132
|
+
* see `responsesApi` in OpenAIProviderConfig. */
|
|
3092
3133
|
protected useResponsesApi(request: ChatCompletionRequest): boolean;
|
|
3093
3134
|
complete(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
3094
3135
|
completeStream(request: ChatCompletionRequest): AsyncGenerator<ChatCompletionChunk, void, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -719,7 +719,8 @@ type ReflectionConfig = {
|
|
|
719
719
|
onReflection?: (record: ReflectionRecord, ctx: ReflectionHookContext) => void;
|
|
720
720
|
};
|
|
721
721
|
type NativeReasoningConfig = {
|
|
722
|
-
|
|
722
|
+
/** `none` is OFF — a value that gets SENT. See ReasoningEffort in providers/types.ts. */
|
|
723
|
+
effort?: "none" | "minimal" | "low" | "medium" | "high";
|
|
723
724
|
budgetTokens?: number;
|
|
724
725
|
includeThoughts?: boolean;
|
|
725
726
|
providerExtras?: Record<string, any>;
|
|
@@ -2918,7 +2919,18 @@ type ChatCompletionRequest = {
|
|
|
2918
2919
|
*/
|
|
2919
2920
|
reasoning?: ReasoningRequestConfig;
|
|
2920
2921
|
};
|
|
2921
|
-
|
|
2922
|
+
/**
|
|
2923
|
+
* `none` is OFF, and it is a value rather than the absence of one.
|
|
2924
|
+
*
|
|
2925
|
+
* On a thinking-by-default model — every Qwen3 under vLLM, gpt-5.1 and newer on
|
|
2926
|
+
* OpenAI — sending no reasoning field leaves the model thinking. So "do not
|
|
2927
|
+
* think" is an instruction that has to travel: `reasoning_effort:"none"` on
|
|
2928
|
+
* OpenAI, `thinkingBudget:0` on Gemini, and no thinking block at all on
|
|
2929
|
+
* Anthropic (where thinking is opt-in and the absence IS off). Omitting
|
|
2930
|
+
* `effort` still means "say nothing about reasoning", which is the different
|
|
2931
|
+
* and equally necessary state.
|
|
2932
|
+
*/
|
|
2933
|
+
type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high";
|
|
2922
2934
|
type ReasoningRequestConfig = {
|
|
2923
2935
|
/** Qualitative effort hint (mapped per-provider). */
|
|
2924
2936
|
effort?: ReasoningEffort;
|
|
@@ -2981,6 +2993,28 @@ type OpenAIProviderConfig = {
|
|
|
2981
2993
|
defaultModel?: string;
|
|
2982
2994
|
defaultHeaders?: Record<string, string>;
|
|
2983
2995
|
retry?: ProviderRetryConfig;
|
|
2996
|
+
/**
|
|
2997
|
+
* WHICH API a reasoning-carrying request is addressed to.
|
|
2998
|
+
*
|
|
2999
|
+
* auto (default, and today's behaviour) route to the Responses API when
|
|
3000
|
+
* the request carries `reasoning` AND the model name looks like an
|
|
3001
|
+
* o-series/gpt-5 reasoning model.
|
|
3002
|
+
* never always Chat Completions. `reasoning` is still mapped, as
|
|
3003
|
+
* `reasoning_effort` plus any `providerExtras`.
|
|
3004
|
+
* always always Responses, whatever the model is called.
|
|
3005
|
+
*
|
|
3006
|
+
* `auto` is a name-based guess, and it decides far more than where reasoning
|
|
3007
|
+
* goes: Responses is a different request shape (`input` not `messages`,
|
|
3008
|
+
* `text.format` not `response_format`, flat tool objects) and a different
|
|
3009
|
+
* response parse. A caller with its own measurements of the Chat Completions
|
|
3010
|
+
* body — a gateway, a proxy, an on-prem server that serves one and not the
|
|
3011
|
+
* other, or anything that has tuned `extra` — must be able to say so, rather
|
|
3012
|
+
* than discover that asking for less thinking silently changed the transport.
|
|
3013
|
+
*
|
|
3014
|
+
* Applies to any OpenAI-shaped endpoint, which is also why the guess is weak
|
|
3015
|
+
* where it matters most: a self-hosted model is named by whoever served it.
|
|
3016
|
+
*/
|
|
3017
|
+
responsesApi?: "auto" | "never" | "always";
|
|
2984
3018
|
};
|
|
2985
3019
|
type AnthropicProviderConfig = {
|
|
2986
3020
|
provider: "anthropic";
|
|
@@ -3085,10 +3119,17 @@ declare class OpenAIProvider extends BaseProvider {
|
|
|
3085
3119
|
protected readonly baseURL: string;
|
|
3086
3120
|
protected readonly defaultModel: string;
|
|
3087
3121
|
protected readonly defaultHeaders: Record<string, string>;
|
|
3122
|
+
protected readonly responsesApi: "auto" | "never" | "always";
|
|
3088
3123
|
constructor(config: OpenAIProviderConfig);
|
|
3089
|
-
/** True when
|
|
3090
|
-
*
|
|
3091
|
-
*
|
|
3124
|
+
/** True when this request should go to the Responses API rather than Chat
|
|
3125
|
+
* Completions — which exposes `reasoning.effort` and reasoning summaries that
|
|
3126
|
+
* Chat Completions silently drops.
|
|
3127
|
+
*
|
|
3128
|
+
* `auto` (the default) keeps the historical rule: only when the request
|
|
3129
|
+
* carries a reasoning config AND the model name looks like an o-series/gpt-5
|
|
3130
|
+
* model. `never`/`always` let a caller state the answer instead, because the
|
|
3131
|
+
* name check is a guess and the two APIs differ in far more than reasoning —
|
|
3132
|
+
* see `responsesApi` in OpenAIProviderConfig. */
|
|
3092
3133
|
protected useResponsesApi(request: ChatCompletionRequest): boolean;
|
|
3093
3134
|
complete(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
3094
3135
|
completeStream(request: ChatCompletionRequest): AsyncGenerator<ChatCompletionChunk, void, unknown>;
|
package/dist/index.mjs
CHANGED
|
@@ -4289,7 +4289,7 @@ var LEVEL_DEFAULTS = {
|
|
|
4289
4289
|
};
|
|
4290
4290
|
var VALID_LEVELS = ["minimal", "low", "medium", "high"];
|
|
4291
4291
|
var VALID_CADENCES = ["off", "every_turn", "after_tool", "on_branch", "initial_then_after_tool"];
|
|
4292
|
-
var VALID_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
4292
|
+
var VALID_EFFORTS = ["none", "minimal", "low", "medium", "high"];
|
|
4293
4293
|
function validateReasoningConfig(input) {
|
|
4294
4294
|
if (!input) return;
|
|
4295
4295
|
if (input.level !== void 0 && !VALID_LEVELS.includes(input.level)) {
|
|
@@ -8783,12 +8783,19 @@ function parseSSEBlock(block) {
|
|
|
8783
8783
|
|
|
8784
8784
|
// src/providers/utils/reasoning.ts
|
|
8785
8785
|
var ANTHROPIC_EFFORT_BUDGET = {
|
|
8786
|
+
// 0 = off. `applyAnthropicReasoning` bails on a falsy budget and emits no
|
|
8787
|
+
// thinking block, which on Anthropic IS off — thinking there is opt-in.
|
|
8788
|
+
none: 0,
|
|
8786
8789
|
minimal: 1024,
|
|
8787
8790
|
low: 2048,
|
|
8788
8791
|
medium: 8192,
|
|
8789
8792
|
high: 16384
|
|
8790
8793
|
};
|
|
8791
8794
|
var GEMINI_EFFORT_BUDGET = {
|
|
8795
|
+
// 0 is Gemini's own documented spelling for "do not think", and unlike
|
|
8796
|
+
// Anthropic it has to be SENT — hence `applyGeminiReasoning` testing for null
|
|
8797
|
+
// rather than falsiness.
|
|
8798
|
+
none: 0,
|
|
8792
8799
|
minimal: 512,
|
|
8793
8800
|
low: 1024,
|
|
8794
8801
|
medium: 4096,
|
|
@@ -8864,14 +8871,15 @@ function clampBudget(budget, maxTokens) {
|
|
|
8864
8871
|
}
|
|
8865
8872
|
function normalizeEffort(effort) {
|
|
8866
8873
|
if (!effort) return void 0;
|
|
8867
|
-
const allowed = ["minimal", "low", "medium", "high"];
|
|
8874
|
+
const allowed = ["none", "minimal", "low", "medium", "high"];
|
|
8868
8875
|
return allowed.includes(effort) ? effort : void 0;
|
|
8869
8876
|
}
|
|
8870
8877
|
function resolveBudget(reasoning, effortBudget) {
|
|
8878
|
+
const effort = normalizeEffort(reasoning.effort);
|
|
8879
|
+
if (effort === "none") return 0;
|
|
8871
8880
|
if (typeof reasoning.budgetTokens === "number" && reasoning.budgetTokens > 0) {
|
|
8872
8881
|
return Math.floor(reasoning.budgetTokens);
|
|
8873
8882
|
}
|
|
8874
|
-
const effort = normalizeEffort(reasoning.effort);
|
|
8875
8883
|
if (effort && effortBudget[effort]) return effortBudget[effort];
|
|
8876
8884
|
return void 0;
|
|
8877
8885
|
}
|
|
@@ -8960,12 +8968,21 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
8960
8968
|
...config.defaultHeaders,
|
|
8961
8969
|
...config.organization ? { "OpenAI-Organization": config.organization } : {}
|
|
8962
8970
|
};
|
|
8971
|
+
this.responsesApi = config.responsesApi ?? "auto";
|
|
8963
8972
|
if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
|
|
8964
8973
|
}
|
|
8965
|
-
/** True when
|
|
8966
|
-
*
|
|
8967
|
-
*
|
|
8974
|
+
/** True when this request should go to the Responses API rather than Chat
|
|
8975
|
+
* Completions — which exposes `reasoning.effort` and reasoning summaries that
|
|
8976
|
+
* Chat Completions silently drops.
|
|
8977
|
+
*
|
|
8978
|
+
* `auto` (the default) keeps the historical rule: only when the request
|
|
8979
|
+
* carries a reasoning config AND the model name looks like an o-series/gpt-5
|
|
8980
|
+
* model. `never`/`always` let a caller state the answer instead, because the
|
|
8981
|
+
* name check is a guess and the two APIs differ in far more than reasoning —
|
|
8982
|
+
* see `responsesApi` in OpenAIProviderConfig. */
|
|
8968
8983
|
useResponsesApi(request) {
|
|
8984
|
+
if (this.responsesApi === "never") return false;
|
|
8985
|
+
if (this.responsesApi === "always") return true;
|
|
8969
8986
|
if (!request.reasoning) return false;
|
|
8970
8987
|
return isReasoningModel(request.model || this.defaultModel);
|
|
8971
8988
|
}
|
|
@@ -10828,7 +10845,7 @@ function fromNativeProvider(provider, options) {
|
|
|
10828
10845
|
if (tools?.length) req.tools = tools;
|
|
10829
10846
|
if (opts?.extra) req.extra = opts.extra;
|
|
10830
10847
|
const reasoningOverride = invokeOptions?.reasoning;
|
|
10831
|
-
const reasoningCfg =
|
|
10848
|
+
const reasoningCfg = mergeReasoning(opts?.reasoning, reasoningOverride);
|
|
10832
10849
|
if (reasoningCfg) req.reasoning = reasoningCfg;
|
|
10833
10850
|
const tc = invokeOptions?.tool_choice ?? invokeOptions?.toolChoice;
|
|
10834
10851
|
if (tc && tools?.length) {
|
|
@@ -10857,6 +10874,15 @@ function fromNativeProvider(provider, options) {
|
|
|
10857
10874
|
return req;
|
|
10858
10875
|
}
|
|
10859
10876
|
}
|
|
10877
|
+
function mergeReasoning(base, override) {
|
|
10878
|
+
if (!base) return override;
|
|
10879
|
+
if (!override) return base;
|
|
10880
|
+
const merged = { ...base, ...override };
|
|
10881
|
+
if (base.providerExtras || override.providerExtras) {
|
|
10882
|
+
merged.providerExtras = { ...base.providerExtras, ...override.providerExtras };
|
|
10883
|
+
}
|
|
10884
|
+
return merged;
|
|
10885
|
+
}
|
|
10860
10886
|
function toUnifiedMessage(msg) {
|
|
10861
10887
|
const unified = {
|
|
10862
10888
|
role: msg.role,
|