@anuma/sdk 6.15.0 → 6.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20611,6 +20611,9 @@ function supportsResponseFormat(model, variant = "json_object") {
20611
20611
  const allow = variant === "json_schema" ? RESPONSE_SCHEMA_OK : RESPONSE_FORMAT_OK;
20612
20612
  return model.split("/").some((seg) => allow.has(seg));
20613
20613
  }
20614
+ function requiresResponsesTransport(model) {
20615
+ return model.split("/").some((seg) => RESPONSES_ONLY_MODEL_PREFIXES.some((prefix) => seg.startsWith(prefix)));
20616
+ }
20614
20617
  function responsesExtra(extra) {
20615
20618
  if (!extra) return {};
20616
20619
  const out = {};
@@ -20946,7 +20949,7 @@ function extractResponsesContent(body) {
20946
20949
  const text12 = root.output.filter((item) => asRecord(item)?.type === "message").flatMap((item) => Array.isArray(item.content) ? item.content : []).map((part) => asRecord(part)?.text).filter((t) => typeof t === "string").join("");
20947
20950
  return text12;
20948
20951
  }
20949
- var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
20952
+ var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, RESPONSES_ONLY_MODEL_PREFIXES, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
20950
20953
  var init_portalLlm = __esm({
20951
20954
  "src/lib/memory/portalLlm.ts"() {
20952
20955
  "use strict";
@@ -20958,6 +20961,7 @@ var init_portalLlm = __esm({
20958
20961
  RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
20959
20962
  RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
20960
20963
  JSON_CONTRACT_REMINDER = "Output ONLY the strict JSON object requested. No prose, no explanation, no markdown.";
20964
+ RESPONSES_ONLY_MODEL_PREFIXES = ["gpt-5.6"];
20961
20965
  CHAT_TO_RESPONSES_FIELDS = {
20962
20966
  max_completion_tokens: "max_output_tokens"
20963
20967
  };
@@ -30733,6 +30737,9 @@ var DEFAULT_BASE_URL2 = BASE_URL;
30733
30737
  var DEFAULT_MODEL4 = "anthropic/claude-sonnet-4-6";
30734
30738
  var DEFAULT_MAX_TOKENS = 4096;
30735
30739
  var REQUEST_TIMEOUT_MS = 6e4;
30740
+ var MIN_RETRY_BUDGET_MS = 2e3;
30741
+ var MIN_RESPONSES_OUTPUT_TOKENS = 2048;
30742
+ var SCHEMA_FALLBACK_SKIP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 408, 409, 413, 425, 429]);
30736
30743
  var DEFAULT_SYSTEM_PROMPT = `You are a personal assistant with access to the user's memory. Answer the user's question using the supplied memories as evidence.
30737
30744
 
30738
30745
  Rules:
@@ -30764,14 +30771,9 @@ ${m.content}`).join("\n\n");
30764
30771
  const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL2;
30765
30772
  const model = options.llmModel ?? DEFAULT_MODEL4;
30766
30773
  const wantsStructured = !!options.responseSchema;
30767
- const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
30774
+ const useResponsesTransport = requiresResponsesTransport(model);
30775
+ const sendResponseFormat = wantsStructured && !useResponsesTransport && supportsResponseFormat(model, "json_schema");
30768
30776
  const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
30769
- const systemPrompt = wantsStructured && !sendResponseFormat ? `${basePrompt}
30770
-
30771
- Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
30772
- ${JSON.stringify(
30773
- options.responseSchema
30774
- )}` : basePrompt;
30775
30777
  const userMessage = [
30776
30778
  `Question:
30777
30779
  ${trimmed}`,
@@ -30781,85 +30783,121 @@ ${evidence}`
30781
30783
  ].join("\n\n");
30782
30784
  const maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
30783
30785
  const fetchImpl = options.fetchFn ?? fetch;
30786
+ const buildBody = (useResponseFormat) => {
30787
+ const systemPrompt = wantsStructured && !useResponseFormat ? `${basePrompt}
30788
+
30789
+ Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
30790
+ ${JSON.stringify(
30791
+ options.responseSchema
30792
+ )}` : basePrompt;
30793
+ const messages = [
30794
+ { role: "system", content: systemPrompt },
30795
+ { role: "user", content: userMessage }
30796
+ ];
30797
+ if (useResponsesTransport) {
30798
+ return JSON.stringify({
30799
+ model,
30800
+ // Same system+user pair under the Responses-API field names: `input`
30801
+ // for the turns, `max_output_tokens` for the cap. Sending the
30802
+ // chat-completions spelling here is silently ignored, which caps the
30803
+ // answer at the portal default.
30804
+ input: messages,
30805
+ max_output_tokens: Math.max(maxTokens, MIN_RESPONSES_OUTPUT_TOKENS)
30806
+ });
30807
+ }
30808
+ return JSON.stringify({
30809
+ model,
30810
+ // Modern OpenAI field; the portal reads only `max_completion_tokens`
30811
+ // (the deprecated `max_tokens` is silently ignored → falls back to the
30812
+ // portal's default output cap and truncates the answer).
30813
+ max_completion_tokens: maxTokens,
30814
+ messages,
30815
+ ...useResponseFormat && {
30816
+ response_format: {
30817
+ type: "json_schema",
30818
+ json_schema: { name: "reflect_output", schema: options.responseSchema }
30819
+ }
30820
+ }
30821
+ });
30822
+ };
30784
30823
  const log = getLogger();
30785
30824
  const authHeaders = await resolvePortalAuthHeaders(options, "memory/reflect");
30786
30825
  if (authHeaders === null) return baseResult;
30787
- const controller = new AbortController();
30788
30826
  const deadline = Date.now() + REQUEST_TIMEOUT_MS;
30789
30827
  const remaining = () => Math.max(0, deadline - Date.now());
30790
- const timer = setTimeout(() => controller.abort(), remaining());
30791
- let response;
30792
- try {
30793
- response = await fetchImpl(`${baseUrl}/api/v1/chat/completions`, {
30794
- method: "POST",
30795
- // No task type unless the caller named one — an undeclared task adds no
30796
- // header at all, which is what keeps user-facing reflect() unlabelled.
30797
- headers: {
30798
- ...authHeaders,
30799
- ...taskTypeHeader(options.taskType),
30800
- "Content-Type": "application/json"
30801
- },
30802
- body: JSON.stringify({
30803
- model,
30804
- // Modern OpenAI field; the portal reads only `max_completion_tokens`
30805
- // (the deprecated `max_tokens` is silently ignored → falls back to the
30806
- // portal's default output cap and truncates the answer).
30807
- max_completion_tokens: maxTokens,
30808
- messages: [
30809
- { role: "system", content: systemPrompt },
30810
- { role: "user", content: userMessage }
30811
- ],
30812
- ...sendResponseFormat && {
30813
- response_format: {
30814
- type: "json_schema",
30815
- json_schema: { name: "reflect_output", schema: options.responseSchema }
30816
- }
30817
- }
30818
- }),
30819
- signal: controller.signal
30820
- });
30821
- } catch (err) {
30828
+ const endpoint = useResponsesTransport ? "/api/v1/responses" : "/api/v1/chat/completions";
30829
+ const sendOnce = async (useResponseFormat) => {
30830
+ const controller = new AbortController();
30831
+ const timer = setTimeout(() => controller.abort(), remaining());
30832
+ let response;
30833
+ try {
30834
+ response = await fetchImpl(`${baseUrl}${endpoint}`, {
30835
+ method: "POST",
30836
+ // No task type unless the caller named one — an undeclared task adds no
30837
+ // header at all, which is what keeps user-facing reflect() unlabelled.
30838
+ headers: {
30839
+ ...authHeaders,
30840
+ ...taskTypeHeader(options.taskType),
30841
+ "Content-Type": "application/json"
30842
+ },
30843
+ body: buildBody(useResponseFormat),
30844
+ signal: controller.signal
30845
+ });
30846
+ } catch (err) {
30847
+ clearTimeout(timer);
30848
+ log.warn("[memory/reflect] portal request failed", {
30849
+ err: err instanceof Error ? err.message : String(err),
30850
+ baseUrl
30851
+ });
30852
+ return { kind: "error" };
30853
+ }
30822
30854
  clearTimeout(timer);
30823
- log.warn("[memory/reflect] portal request failed", {
30824
- err: err instanceof Error ? err.message : String(err),
30825
- baseUrl
30855
+ if (!response.ok) {
30856
+ return { kind: "http", status: response.status, statusText: response.statusText };
30857
+ }
30858
+ const bodyTimer = setTimeout(() => controller.abort(), remaining());
30859
+ try {
30860
+ const body = await response.json();
30861
+ clearTimeout(bodyTimer);
30862
+ return { kind: "ok", body };
30863
+ } catch (err) {
30864
+ clearTimeout(bodyTimer);
30865
+ log.warn("[memory/reflect] failed to parse portal response body", {
30866
+ err: err instanceof Error ? err.message : String(err)
30867
+ });
30868
+ return { kind: "error" };
30869
+ }
30870
+ };
30871
+ let attempt = await sendOnce(sendResponseFormat);
30872
+ let schemaFallbackUsed = false;
30873
+ const budgetLeftMs = remaining();
30874
+ if (attempt.kind === "http" && sendResponseFormat && !SCHEMA_FALLBACK_SKIP_STATUSES.has(attempt.status) && budgetLeftMs >= MIN_RETRY_BUDGET_MS) {
30875
+ log.warn("[memory/reflect] response_format json_schema rejected; retrying schema-in-prompt", {
30876
+ status: attempt.status,
30877
+ statusText: attempt.statusText,
30878
+ model,
30879
+ taskType: options.taskType,
30880
+ budgetLeftMs
30826
30881
  });
30827
- return baseResult;
30882
+ schemaFallbackUsed = true;
30883
+ attempt = await sendOnce(false);
30828
30884
  }
30829
- clearTimeout(timer);
30830
- if (!response.ok) {
30885
+ if (attempt.kind === "error") return baseResult;
30886
+ if (attempt.kind === "http") {
30831
30887
  log.warn("[memory/reflect] portal returned non-OK", {
30832
- status: response.status,
30833
- statusText: response.statusText
30834
- });
30835
- return baseResult;
30836
- }
30837
- const bodyTimer = setTimeout(() => controller.abort(), remaining());
30838
- let body;
30839
- try {
30840
- body = await response.json();
30841
- } catch (err) {
30842
- clearTimeout(bodyTimer);
30843
- log.warn("[memory/reflect] failed to parse portal response body", {
30844
- err: err instanceof Error ? err.message : String(err)
30888
+ status: attempt.status,
30889
+ statusText: attempt.statusText,
30890
+ // Distinguishes "the fallback ran and still failed" from "never tried".
30891
+ schemaFallbackUsed
30845
30892
  });
30846
30893
  return baseResult;
30847
30894
  }
30848
- clearTimeout(bodyTimer);
30849
- return parseAnswer(body, baseResult, !!options.responseSchema);
30895
+ return parseAnswer(attempt.body, baseResult, !!options.responseSchema);
30850
30896
  }
30851
30897
  function parseAnswer(body, base, parseSchema) {
30852
30898
  if (typeof body !== "object" || body === null) return base;
30853
30899
  const obj = body;
30854
- const choices = obj.choices;
30855
- let text12 = "";
30856
- if (Array.isArray(choices) && choices.length > 0) {
30857
- const message = choices[0].message;
30858
- if (typeof message === "object" && message !== null) {
30859
- const content = message.content;
30860
- if (typeof content === "string") text12 = content;
30861
- }
30862
- }
30900
+ const text12 = extractCompletionContent(obj) ?? "";
30863
30901
  const usage = obj.usage;
30864
30902
  let structuredOutput;
30865
30903
  if (parseSchema && text12) {
@@ -30871,14 +30909,19 @@ function parseAnswer(body, base, parseSchema) {
30871
30909
  });
30872
30910
  }
30873
30911
  }
30912
+ const promptTokens = usage?.prompt_tokens ?? usage?.input_tokens ?? 0;
30913
+ const completionTokens = usage?.completion_tokens ?? usage?.output_tokens ?? 0;
30874
30914
  return {
30875
30915
  text: text12,
30876
30916
  ...structuredOutput !== void 0 && { structuredOutput },
30877
30917
  basedOn: base.basedOn,
30878
30918
  usage: {
30879
- promptTokens: usage?.prompt_tokens ?? 0,
30880
- completionTokens: usage?.completion_tokens ?? 0,
30881
- totalTokens: usage?.total_tokens ?? 0
30919
+ promptTokens,
30920
+ completionTokens,
30921
+ // Derived when absent: the Responses API reports the two component counts
30922
+ // and does not always send a total, which would otherwise report zero
30923
+ // spend for a call that plainly cost something.
30924
+ totalTokens: usage?.total_tokens ?? promptTokens + completionTokens
30882
30925
  }
30883
30926
  };
30884
30927
  }
@@ -141,23 +141,25 @@ import {
141
141
  updateVaultMemoryOp,
142
142
  upsertMessageOp,
143
143
  vaultMemoryToStored
144
- } from "./chunk-2QFK4L7Y.mjs";
144
+ } from "./chunk-ARYSRI4Z.mjs";
145
145
  import {
146
146
  createStreamingDeAnonymizer,
147
147
  notifyConsolidationFallback,
148
148
  resolvePiiRedactor
149
- } from "./chunk-JPLFOSB2.mjs";
149
+ } from "./chunk-4LPSEROP.mjs";
150
150
  import {
151
151
  INTERNAL_FLOW_MARKER,
152
152
  callPortalJsonCompletion,
153
+ extractCompletionContent,
153
154
  extractJsonCandidate,
154
155
  getLogger,
156
+ requiresResponsesTransport,
155
157
  resolvePortalAuthHeaders,
156
158
  supportsResponseFormat,
157
159
  taskTypeHeader,
158
160
  validateEndpointOverride,
159
161
  withInternalFlowMarker
160
- } from "./chunk-H4G3DLDJ.mjs";
162
+ } from "./chunk-BSCEZOIW.mjs";
161
163
  import {
162
164
  BASE_URL,
163
165
  __commonJS,
@@ -5700,7 +5702,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
5700
5702
  content: m.content,
5701
5703
  similarity: m.similarity
5702
5704
  }));
5703
- const { consolidateMemory: doConsolidate } = await import("./consolidate-CMMDTZ37.mjs");
5705
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-MSAXASHL.mjs");
5704
5706
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
5705
5707
  if (decision.action === "create") return null;
5706
5708
  if (decision.action === "supersede" && decision.content) {
@@ -6924,6 +6926,9 @@ var DEFAULT_BASE_URL = BASE_URL;
6924
6926
  var DEFAULT_MODEL3 = "anthropic/claude-sonnet-4-6";
6925
6927
  var DEFAULT_MAX_TOKENS = 4096;
6926
6928
  var REQUEST_TIMEOUT_MS = 6e4;
6929
+ var MIN_RETRY_BUDGET_MS = 2e3;
6930
+ var MIN_RESPONSES_OUTPUT_TOKENS = 2048;
6931
+ var SCHEMA_FALLBACK_SKIP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 408, 409, 413, 425, 429]);
6927
6932
  var DEFAULT_SYSTEM_PROMPT = `You are a personal assistant with access to the user's memory. Answer the user's question using the supplied memories as evidence.
6928
6933
 
6929
6934
  Rules:
@@ -6955,14 +6960,9 @@ ${m.content}`).join("\n\n");
6955
6960
  const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
6956
6961
  const model = options.llmModel ?? DEFAULT_MODEL3;
6957
6962
  const wantsStructured = !!options.responseSchema;
6958
- const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
6963
+ const useResponsesTransport = requiresResponsesTransport(model);
6964
+ const sendResponseFormat = wantsStructured && !useResponsesTransport && supportsResponseFormat(model, "json_schema");
6959
6965
  const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
6960
- const systemPrompt = wantsStructured && !sendResponseFormat ? `${basePrompt}
6961
-
6962
- Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
6963
- ${JSON.stringify(
6964
- options.responseSchema
6965
- )}` : basePrompt;
6966
6966
  const userMessage = [
6967
6967
  `Question:
6968
6968
  ${trimmed}`,
@@ -6972,85 +6972,121 @@ ${evidence}`
6972
6972
  ].join("\n\n");
6973
6973
  const maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
6974
6974
  const fetchImpl = options.fetchFn ?? fetch;
6975
+ const buildBody = (useResponseFormat) => {
6976
+ const systemPrompt = wantsStructured && !useResponseFormat ? `${basePrompt}
6977
+
6978
+ Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
6979
+ ${JSON.stringify(
6980
+ options.responseSchema
6981
+ )}` : basePrompt;
6982
+ const messages = [
6983
+ { role: "system", content: systemPrompt },
6984
+ { role: "user", content: userMessage }
6985
+ ];
6986
+ if (useResponsesTransport) {
6987
+ return JSON.stringify({
6988
+ model,
6989
+ // Same system+user pair under the Responses-API field names: `input`
6990
+ // for the turns, `max_output_tokens` for the cap. Sending the
6991
+ // chat-completions spelling here is silently ignored, which caps the
6992
+ // answer at the portal default.
6993
+ input: messages,
6994
+ max_output_tokens: Math.max(maxTokens, MIN_RESPONSES_OUTPUT_TOKENS)
6995
+ });
6996
+ }
6997
+ return JSON.stringify({
6998
+ model,
6999
+ // Modern OpenAI field; the portal reads only `max_completion_tokens`
7000
+ // (the deprecated `max_tokens` is silently ignored → falls back to the
7001
+ // portal's default output cap and truncates the answer).
7002
+ max_completion_tokens: maxTokens,
7003
+ messages,
7004
+ ...useResponseFormat && {
7005
+ response_format: {
7006
+ type: "json_schema",
7007
+ json_schema: { name: "reflect_output", schema: options.responseSchema }
7008
+ }
7009
+ }
7010
+ });
7011
+ };
6975
7012
  const log = getLogger();
6976
7013
  const authHeaders = await resolvePortalAuthHeaders(options, "memory/reflect");
6977
7014
  if (authHeaders === null) return baseResult;
6978
- const controller = new AbortController();
6979
7015
  const deadline = Date.now() + REQUEST_TIMEOUT_MS;
6980
7016
  const remaining = () => Math.max(0, deadline - Date.now());
6981
- const timer = setTimeout(() => controller.abort(), remaining());
6982
- let response;
6983
- try {
6984
- response = await fetchImpl(`${baseUrl}/api/v1/chat/completions`, {
6985
- method: "POST",
6986
- // No task type unless the caller named one — an undeclared task adds no
6987
- // header at all, which is what keeps user-facing reflect() unlabelled.
6988
- headers: {
6989
- ...authHeaders,
6990
- ...taskTypeHeader(options.taskType),
6991
- "Content-Type": "application/json"
6992
- },
6993
- body: JSON.stringify({
6994
- model,
6995
- // Modern OpenAI field; the portal reads only `max_completion_tokens`
6996
- // (the deprecated `max_tokens` is silently ignored → falls back to the
6997
- // portal's default output cap and truncates the answer).
6998
- max_completion_tokens: maxTokens,
6999
- messages: [
7000
- { role: "system", content: systemPrompt },
7001
- { role: "user", content: userMessage }
7002
- ],
7003
- ...sendResponseFormat && {
7004
- response_format: {
7005
- type: "json_schema",
7006
- json_schema: { name: "reflect_output", schema: options.responseSchema }
7007
- }
7008
- }
7009
- }),
7010
- signal: controller.signal
7011
- });
7012
- } catch (err) {
7017
+ const endpoint = useResponsesTransport ? "/api/v1/responses" : "/api/v1/chat/completions";
7018
+ const sendOnce = async (useResponseFormat) => {
7019
+ const controller = new AbortController();
7020
+ const timer = setTimeout(() => controller.abort(), remaining());
7021
+ let response;
7022
+ try {
7023
+ response = await fetchImpl(`${baseUrl}${endpoint}`, {
7024
+ method: "POST",
7025
+ // No task type unless the caller named one — an undeclared task adds no
7026
+ // header at all, which is what keeps user-facing reflect() unlabelled.
7027
+ headers: {
7028
+ ...authHeaders,
7029
+ ...taskTypeHeader(options.taskType),
7030
+ "Content-Type": "application/json"
7031
+ },
7032
+ body: buildBody(useResponseFormat),
7033
+ signal: controller.signal
7034
+ });
7035
+ } catch (err) {
7036
+ clearTimeout(timer);
7037
+ log.warn("[memory/reflect] portal request failed", {
7038
+ err: err instanceof Error ? err.message : String(err),
7039
+ baseUrl
7040
+ });
7041
+ return { kind: "error" };
7042
+ }
7013
7043
  clearTimeout(timer);
7014
- log.warn("[memory/reflect] portal request failed", {
7015
- err: err instanceof Error ? err.message : String(err),
7016
- baseUrl
7044
+ if (!response.ok) {
7045
+ return { kind: "http", status: response.status, statusText: response.statusText };
7046
+ }
7047
+ const bodyTimer = setTimeout(() => controller.abort(), remaining());
7048
+ try {
7049
+ const body = await response.json();
7050
+ clearTimeout(bodyTimer);
7051
+ return { kind: "ok", body };
7052
+ } catch (err) {
7053
+ clearTimeout(bodyTimer);
7054
+ log.warn("[memory/reflect] failed to parse portal response body", {
7055
+ err: err instanceof Error ? err.message : String(err)
7056
+ });
7057
+ return { kind: "error" };
7058
+ }
7059
+ };
7060
+ let attempt = await sendOnce(sendResponseFormat);
7061
+ let schemaFallbackUsed = false;
7062
+ const budgetLeftMs = remaining();
7063
+ if (attempt.kind === "http" && sendResponseFormat && !SCHEMA_FALLBACK_SKIP_STATUSES.has(attempt.status) && budgetLeftMs >= MIN_RETRY_BUDGET_MS) {
7064
+ log.warn("[memory/reflect] response_format json_schema rejected; retrying schema-in-prompt", {
7065
+ status: attempt.status,
7066
+ statusText: attempt.statusText,
7067
+ model,
7068
+ taskType: options.taskType,
7069
+ budgetLeftMs
7017
7070
  });
7018
- return baseResult;
7071
+ schemaFallbackUsed = true;
7072
+ attempt = await sendOnce(false);
7019
7073
  }
7020
- clearTimeout(timer);
7021
- if (!response.ok) {
7074
+ if (attempt.kind === "error") return baseResult;
7075
+ if (attempt.kind === "http") {
7022
7076
  log.warn("[memory/reflect] portal returned non-OK", {
7023
- status: response.status,
7024
- statusText: response.statusText
7077
+ status: attempt.status,
7078
+ statusText: attempt.statusText,
7079
+ // Distinguishes "the fallback ran and still failed" from "never tried".
7080
+ schemaFallbackUsed
7025
7081
  });
7026
7082
  return baseResult;
7027
7083
  }
7028
- const bodyTimer = setTimeout(() => controller.abort(), remaining());
7029
- let body;
7030
- try {
7031
- body = await response.json();
7032
- } catch (err) {
7033
- clearTimeout(bodyTimer);
7034
- log.warn("[memory/reflect] failed to parse portal response body", {
7035
- err: err instanceof Error ? err.message : String(err)
7036
- });
7037
- return baseResult;
7038
- }
7039
- clearTimeout(bodyTimer);
7040
- return parseAnswer(body, baseResult, !!options.responseSchema);
7084
+ return parseAnswer(attempt.body, baseResult, !!options.responseSchema);
7041
7085
  }
7042
7086
  function parseAnswer(body, base, parseSchema) {
7043
7087
  if (typeof body !== "object" || body === null) return base;
7044
7088
  const obj = body;
7045
- const choices = obj.choices;
7046
- let text12 = "";
7047
- if (Array.isArray(choices) && choices.length > 0) {
7048
- const message = choices[0].message;
7049
- if (typeof message === "object" && message !== null) {
7050
- const content = message.content;
7051
- if (typeof content === "string") text12 = content;
7052
- }
7053
- }
7089
+ const text12 = extractCompletionContent(obj) ?? "";
7054
7090
  const usage = obj.usage;
7055
7091
  let structuredOutput;
7056
7092
  if (parseSchema && text12) {
@@ -7062,14 +7098,19 @@ function parseAnswer(body, base, parseSchema) {
7062
7098
  });
7063
7099
  }
7064
7100
  }
7101
+ const promptTokens = usage?.prompt_tokens ?? usage?.input_tokens ?? 0;
7102
+ const completionTokens = usage?.completion_tokens ?? usage?.output_tokens ?? 0;
7065
7103
  return {
7066
7104
  text: text12,
7067
7105
  ...structuredOutput !== void 0 && { structuredOutput },
7068
7106
  basedOn: base.basedOn,
7069
7107
  usage: {
7070
- promptTokens: usage?.prompt_tokens ?? 0,
7071
- completionTokens: usage?.completion_tokens ?? 0,
7072
- totalTokens: usage?.total_tokens ?? 0
7108
+ promptTokens,
7109
+ completionTokens,
7110
+ // Derived when absent: the Responses API reports the two component counts
7111
+ // and does not always send a total, which would otherwise report zero
7112
+ // spend for a call that plainly cost something.
7113
+ totalTokens: usage?.total_tokens ?? promptTokens + completionTokens
7073
7114
  }
7074
7115
  };
7075
7116
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-2QFK4L7Y.mjs";
4
- import "./chunk-H4G3DLDJ.mjs";
3
+ } from "./chunk-ARYSRI4Z.mjs";
4
+ import "./chunk-BSCEZOIW.mjs";
5
5
  import "./chunk-3RPGXXPZ.mjs";
6
6
  export {
7
7
  recall
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "6.15.0",
3
+ "version": "6.15.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",