@cognipeer/agent-sdk 0.8.8 → 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 CHANGED
@@ -4299,7 +4299,7 @@ var LEVEL_DEFAULTS = {
4299
4299
  };
4300
4300
  var VALID_LEVELS = ["minimal", "low", "medium", "high"];
4301
4301
  var VALID_CADENCES = ["off", "every_turn", "after_tool", "on_branch", "initial_then_after_tool"];
4302
- var VALID_EFFORTS = ["minimal", "low", "medium", "high"];
4302
+ var VALID_EFFORTS = ["none", "minimal", "low", "medium", "high"];
4303
4303
  function validateReasoningConfig(input) {
4304
4304
  if (!input) return;
4305
4305
  if (input.level !== void 0 && !VALID_LEVELS.includes(input.level)) {
@@ -4885,11 +4885,13 @@ var StructuredOutputManager = class {
4885
4885
  /**
4886
4886
  * Build a nudge message for when the model didn't produce structured output.
4887
4887
  * Used by the agent loop when it needs to retry.
4888
+ * User role is intentional: OpenAI-compatible chat templates such as Qwen
4889
+ * reject system messages anywhere except the beginning of the conversation.
4888
4890
  */
4889
4891
  buildNudgeMessage(isLastAttempt) {
4890
4892
  if (this.strategy.kind === "native") {
4891
4893
  return {
4892
- role: "system",
4894
+ role: "user",
4893
4895
  content: [
4894
4896
  "A structured output schema is active.",
4895
4897
  "You MUST respond with valid JSON matching the schema.",
@@ -4899,7 +4901,7 @@ var StructuredOutputManager = class {
4899
4901
  };
4900
4902
  }
4901
4903
  return {
4902
- role: "system",
4904
+ role: "user",
4903
4905
  content: [
4904
4906
  "A structured output schema is active.",
4905
4907
  "You MUST now call tool `response` with the final JSON object that matches the schema.",
@@ -4917,7 +4919,7 @@ var StructuredOutputManager = class {
4917
4919
  const fieldIssues = error.fieldErrors.map((f) => `- "${f.path}": ${f.message} (received: ${JSON.stringify(f.received)})`).join("\n");
4918
4920
  const action = this.strategy.kind === "native" ? "Please output corrected JSON matching the schema." : "Please call `response` again with corrected values matching the schema.";
4919
4921
  return {
4920
- role: "system",
4922
+ role: "user",
4921
4923
  content: [
4922
4924
  "Your previous structured output had validation errors:",
4923
4925
  fieldIssues,
@@ -8791,12 +8793,19 @@ function parseSSEBlock(block) {
8791
8793
 
8792
8794
  // src/providers/utils/reasoning.ts
8793
8795
  var ANTHROPIC_EFFORT_BUDGET = {
8796
+ // 0 = off. `applyAnthropicReasoning` bails on a falsy budget and emits no
8797
+ // thinking block, which on Anthropic IS off — thinking there is opt-in.
8798
+ none: 0,
8794
8799
  minimal: 1024,
8795
8800
  low: 2048,
8796
8801
  medium: 8192,
8797
8802
  high: 16384
8798
8803
  };
8799
8804
  var GEMINI_EFFORT_BUDGET = {
8805
+ // 0 is Gemini's own documented spelling for "do not think", and unlike
8806
+ // Anthropic it has to be SENT — hence `applyGeminiReasoning` testing for null
8807
+ // rather than falsiness.
8808
+ none: 0,
8800
8809
  minimal: 512,
8801
8810
  low: 1024,
8802
8811
  medium: 4096,
@@ -8872,14 +8881,15 @@ function clampBudget(budget, maxTokens) {
8872
8881
  }
8873
8882
  function normalizeEffort(effort) {
8874
8883
  if (!effort) return void 0;
8875
- const allowed = ["minimal", "low", "medium", "high"];
8884
+ const allowed = ["none", "minimal", "low", "medium", "high"];
8876
8885
  return allowed.includes(effort) ? effort : void 0;
8877
8886
  }
8878
8887
  function resolveBudget(reasoning, effortBudget) {
8888
+ const effort = normalizeEffort(reasoning.effort);
8889
+ if (effort === "none") return 0;
8879
8890
  if (typeof reasoning.budgetTokens === "number" && reasoning.budgetTokens > 0) {
8880
8891
  return Math.floor(reasoning.budgetTokens);
8881
8892
  }
8882
- const effort = normalizeEffort(reasoning.effort);
8883
8893
  if (effort && effortBudget[effort]) return effortBudget[effort];
8884
8894
  return void 0;
8885
8895
  }
@@ -8968,12 +8978,21 @@ var OpenAIProvider = class extends BaseProvider {
8968
8978
  ...config.defaultHeaders,
8969
8979
  ...config.organization ? { "OpenAI-Organization": config.organization } : {}
8970
8980
  };
8981
+ this.responsesApi = config.responsesApi ?? "auto";
8971
8982
  if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
8972
8983
  }
8973
- /** True when the request targets a reasoning model (o-series / gpt-5) so we
8974
- * should route through the Responses API, which exposes `reasoning.effort`
8975
- * and reasoning summaries. Chat Completions silently drops these. */
8984
+ /** True when this request should go to the Responses API rather than Chat
8985
+ * Completions — which exposes `reasoning.effort` and reasoning summaries that
8986
+ * Chat Completions silently drops.
8987
+ *
8988
+ * `auto` (the default) keeps the historical rule: only when the request
8989
+ * carries a reasoning config AND the model name looks like an o-series/gpt-5
8990
+ * model. `never`/`always` let a caller state the answer instead, because the
8991
+ * name check is a guess and the two APIs differ in far more than reasoning —
8992
+ * see `responsesApi` in OpenAIProviderConfig. */
8976
8993
  useResponsesApi(request) {
8994
+ if (this.responsesApi === "never") return false;
8995
+ if (this.responsesApi === "always") return true;
8977
8996
  if (!request.reasoning) return false;
8978
8997
  return isReasoningModel(request.model || this.defaultModel);
8979
8998
  }
@@ -10836,7 +10855,7 @@ function fromNativeProvider(provider, options) {
10836
10855
  if (tools?.length) req.tools = tools;
10837
10856
  if (opts?.extra) req.extra = opts.extra;
10838
10857
  const reasoningOverride = invokeOptions?.reasoning;
10839
- const reasoningCfg = reasoningOverride ?? opts?.reasoning;
10858
+ const reasoningCfg = mergeReasoning(opts?.reasoning, reasoningOverride);
10840
10859
  if (reasoningCfg) req.reasoning = reasoningCfg;
10841
10860
  const tc = invokeOptions?.tool_choice ?? invokeOptions?.toolChoice;
10842
10861
  if (tc && tools?.length) {
@@ -10865,6 +10884,15 @@ function fromNativeProvider(provider, options) {
10865
10884
  return req;
10866
10885
  }
10867
10886
  }
10887
+ function mergeReasoning(base, override) {
10888
+ if (!base) return override;
10889
+ if (!override) return base;
10890
+ const merged = { ...base, ...override };
10891
+ if (base.providerExtras || override.providerExtras) {
10892
+ merged.providerExtras = { ...base.providerExtras, ...override.providerExtras };
10893
+ }
10894
+ return merged;
10895
+ }
10868
10896
  function toUnifiedMessage(msg) {
10869
10897
  const unified = {
10870
10898
  role: msg.role,