@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.
- package/dist/expo/{chunk-3V3BBJLH.mjs → chunk-4Z2X4UYQ.mjs} +7 -1
- package/dist/expo/{chunk-DIUQLXEH.mjs → chunk-A2G6TRUK.mjs} +1 -1
- package/dist/expo/{chunk-LUSKQQDD.mjs → chunk-TNMPAE3V.mjs} +2 -2
- package/dist/{react/consolidate-Y2XWEZRQ.mjs → expo/consolidate-ZM5JNULQ.mjs} +2 -2
- package/dist/expo/index.cjs +117 -74
- package/dist/expo/index.mjs +118 -77
- package/dist/expo/{recall-GKYVPD2B.mjs → recall-FJQTIMYT.mjs} +2 -2
- package/dist/react/{chunk-3V3BBJLH.mjs → chunk-4Z2X4UYQ.mjs} +7 -1
- package/dist/react/{chunk-2GNOTRG4.mjs → chunk-7X7BNMGS.mjs} +1 -1
- package/dist/react/{chunk-PDKKPAXP.mjs → chunk-YSL3J4K4.mjs} +2 -2
- package/dist/{expo/consolidate-GTMXZZ4C.mjs → react/consolidate-7NMKF7UC.mjs} +2 -2
- package/dist/react/index.cjs +117 -74
- package/dist/react/index.mjs +118 -77
- package/dist/react/{recall-5HNAFHLL.mjs → recall-UVVZGRVF.mjs} +2 -2
- package/dist/server/{chunk-JPLFOSB2.mjs → chunk-4LPSEROP.mjs} +1 -1
- package/dist/server/{chunk-2QFK4L7Y.mjs → chunk-ARYSRI4Z.mjs} +2 -2
- package/dist/server/{chunk-H4G3DLDJ.mjs → chunk-BSCEZOIW.mjs} +7 -1
- package/dist/server/{consolidate-CMMDTZ37.mjs → consolidate-MSAXASHL.mjs} +2 -2
- package/dist/server/index.cjs +117 -74
- package/dist/server/index.mjs +118 -77
- package/dist/server/{recall-EODNEKIA.mjs → recall-OVSSDRYU.mjs} +2 -2
- package/package.json +1 -1
|
@@ -70,6 +70,10 @@ function supportsResponseFormat(model, variant = "json_object") {
|
|
|
70
70
|
const allow = variant === "json_schema" ? RESPONSE_SCHEMA_OK : RESPONSE_FORMAT_OK;
|
|
71
71
|
return model.split("/").some((seg) => allow.has(seg));
|
|
72
72
|
}
|
|
73
|
+
var RESPONSES_ONLY_MODEL_PREFIXES = ["gpt-5.6"];
|
|
74
|
+
function requiresResponsesTransport(model) {
|
|
75
|
+
return model.split("/").some((seg) => RESPONSES_ONLY_MODEL_PREFIXES.some((prefix) => seg.startsWith(prefix)));
|
|
76
|
+
}
|
|
73
77
|
var CHAT_TO_RESPONSES_FIELDS = {
|
|
74
78
|
max_completion_tokens: "max_output_tokens"
|
|
75
79
|
};
|
|
@@ -424,7 +428,9 @@ export {
|
|
|
424
428
|
withInternalFlowMarker,
|
|
425
429
|
taskTypeHeader,
|
|
426
430
|
supportsResponseFormat,
|
|
431
|
+
requiresResponsesTransport,
|
|
427
432
|
resolvePortalAuthHeaders,
|
|
428
433
|
callPortalJsonCompletion,
|
|
429
|
-
extractJsonCandidate
|
|
434
|
+
extractJsonCandidate,
|
|
435
|
+
extractCompletionContent
|
|
430
436
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callPortalJsonCompletion,
|
|
3
3
|
getLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4Z2X4UYQ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
BASE_URL,
|
|
7
7
|
createClientConfig
|
|
@@ -6885,7 +6885,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
6885
6885
|
subQueries = decomp.subQueries;
|
|
6886
6886
|
}
|
|
6887
6887
|
}
|
|
6888
|
-
const { recall: recall2 } = await import("./recall-
|
|
6888
|
+
const { recall: recall2 } = await import("./recall-FJQTIMYT.mjs");
|
|
6889
6889
|
let recallDegraded = [];
|
|
6890
6890
|
const result = await recall2(
|
|
6891
6891
|
query,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
notifyConsolidationFallback,
|
|
3
3
|
resolvePiiRedactor
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-A2G6TRUK.mjs";
|
|
5
5
|
import {
|
|
6
6
|
callPortalJsonCompletion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4Z2X4UYQ.mjs";
|
|
8
8
|
import "./chunk-GYKJOWEO.mjs";
|
|
9
9
|
|
|
10
10
|
// src/lib/memory/consolidate.ts
|
package/dist/expo/index.cjs
CHANGED
|
@@ -6145,6 +6145,9 @@ function supportsResponseFormat(model, variant = "json_object") {
|
|
|
6145
6145
|
const allow = variant === "json_schema" ? RESPONSE_SCHEMA_OK : RESPONSE_FORMAT_OK;
|
|
6146
6146
|
return model.split("/").some((seg) => allow.has(seg));
|
|
6147
6147
|
}
|
|
6148
|
+
function requiresResponsesTransport(model) {
|
|
6149
|
+
return model.split("/").some((seg) => RESPONSES_ONLY_MODEL_PREFIXES.some((prefix) => seg.startsWith(prefix)));
|
|
6150
|
+
}
|
|
6148
6151
|
function responsesExtra(extra) {
|
|
6149
6152
|
if (!extra) return {};
|
|
6150
6153
|
const out = {};
|
|
@@ -6480,7 +6483,7 @@ function extractResponsesContent(body) {
|
|
|
6480
6483
|
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("");
|
|
6481
6484
|
return text12;
|
|
6482
6485
|
}
|
|
6483
|
-
var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
|
|
6486
|
+
var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, RESPONSES_ONLY_MODEL_PREFIXES, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
|
|
6484
6487
|
var init_portalLlm = __esm({
|
|
6485
6488
|
"src/lib/memory/portalLlm.ts"() {
|
|
6486
6489
|
"use strict";
|
|
@@ -6492,6 +6495,7 @@ var init_portalLlm = __esm({
|
|
|
6492
6495
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
6493
6496
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
6494
6497
|
JSON_CONTRACT_REMINDER = "Output ONLY the strict JSON object requested. No prose, no explanation, no markdown.";
|
|
6498
|
+
RESPONSES_ONLY_MODEL_PREFIXES = ["gpt-5.6"];
|
|
6495
6499
|
CHAT_TO_RESPONSES_FIELDS = {
|
|
6496
6500
|
max_completion_tokens: "max_output_tokens"
|
|
6497
6501
|
};
|
|
@@ -17817,6 +17821,9 @@ var DEFAULT_BASE_URL2 = BASE_URL;
|
|
|
17817
17821
|
var DEFAULT_MODEL4 = "anthropic/claude-sonnet-4-6";
|
|
17818
17822
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
17819
17823
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
17824
|
+
var MIN_RETRY_BUDGET_MS = 2e3;
|
|
17825
|
+
var MIN_RESPONSES_OUTPUT_TOKENS = 2048;
|
|
17826
|
+
var SCHEMA_FALLBACK_SKIP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 408, 409, 413, 425, 429]);
|
|
17820
17827
|
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.
|
|
17821
17828
|
|
|
17822
17829
|
Rules:
|
|
@@ -17848,14 +17855,9 @@ ${m.content}`).join("\n\n");
|
|
|
17848
17855
|
const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL2;
|
|
17849
17856
|
const model = options.llmModel ?? DEFAULT_MODEL4;
|
|
17850
17857
|
const wantsStructured = !!options.responseSchema;
|
|
17851
|
-
const
|
|
17858
|
+
const useResponsesTransport = requiresResponsesTransport(model);
|
|
17859
|
+
const sendResponseFormat = wantsStructured && !useResponsesTransport && supportsResponseFormat(model, "json_schema");
|
|
17852
17860
|
const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
17853
|
-
const systemPrompt = wantsStructured && !sendResponseFormat ? `${basePrompt}
|
|
17854
|
-
|
|
17855
|
-
Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
|
|
17856
|
-
${JSON.stringify(
|
|
17857
|
-
options.responseSchema
|
|
17858
|
-
)}` : basePrompt;
|
|
17859
17861
|
const userMessage = [
|
|
17860
17862
|
`Question:
|
|
17861
17863
|
${trimmed}`,
|
|
@@ -17865,85 +17867,121 @@ ${evidence}`
|
|
|
17865
17867
|
].join("\n\n");
|
|
17866
17868
|
const maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
17867
17869
|
const fetchImpl = options.fetchFn ?? fetch;
|
|
17870
|
+
const buildBody = (useResponseFormat) => {
|
|
17871
|
+
const systemPrompt = wantsStructured && !useResponseFormat ? `${basePrompt}
|
|
17872
|
+
|
|
17873
|
+
Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
|
|
17874
|
+
${JSON.stringify(
|
|
17875
|
+
options.responseSchema
|
|
17876
|
+
)}` : basePrompt;
|
|
17877
|
+
const messages = [
|
|
17878
|
+
{ role: "system", content: systemPrompt },
|
|
17879
|
+
{ role: "user", content: userMessage }
|
|
17880
|
+
];
|
|
17881
|
+
if (useResponsesTransport) {
|
|
17882
|
+
return JSON.stringify({
|
|
17883
|
+
model,
|
|
17884
|
+
// Same system+user pair under the Responses-API field names: `input`
|
|
17885
|
+
// for the turns, `max_output_tokens` for the cap. Sending the
|
|
17886
|
+
// chat-completions spelling here is silently ignored, which caps the
|
|
17887
|
+
// answer at the portal default.
|
|
17888
|
+
input: messages,
|
|
17889
|
+
max_output_tokens: Math.max(maxTokens, MIN_RESPONSES_OUTPUT_TOKENS)
|
|
17890
|
+
});
|
|
17891
|
+
}
|
|
17892
|
+
return JSON.stringify({
|
|
17893
|
+
model,
|
|
17894
|
+
// Modern OpenAI field; the portal reads only `max_completion_tokens`
|
|
17895
|
+
// (the deprecated `max_tokens` is silently ignored → falls back to the
|
|
17896
|
+
// portal's default output cap and truncates the answer).
|
|
17897
|
+
max_completion_tokens: maxTokens,
|
|
17898
|
+
messages,
|
|
17899
|
+
...useResponseFormat && {
|
|
17900
|
+
response_format: {
|
|
17901
|
+
type: "json_schema",
|
|
17902
|
+
json_schema: { name: "reflect_output", schema: options.responseSchema }
|
|
17903
|
+
}
|
|
17904
|
+
}
|
|
17905
|
+
});
|
|
17906
|
+
};
|
|
17868
17907
|
const log = getLogger();
|
|
17869
17908
|
const authHeaders = await resolvePortalAuthHeaders(options, "memory/reflect");
|
|
17870
17909
|
if (authHeaders === null) return baseResult;
|
|
17871
|
-
const controller = new AbortController();
|
|
17872
17910
|
const deadline = Date.now() + REQUEST_TIMEOUT_MS;
|
|
17873
17911
|
const remaining = () => Math.max(0, deadline - Date.now());
|
|
17874
|
-
const
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17886
|
-
|
|
17887
|
-
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
}
|
|
17901
|
-
}
|
|
17902
|
-
}),
|
|
17903
|
-
signal: controller.signal
|
|
17904
|
-
});
|
|
17905
|
-
} catch (err) {
|
|
17912
|
+
const endpoint = useResponsesTransport ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
17913
|
+
const sendOnce = async (useResponseFormat) => {
|
|
17914
|
+
const controller = new AbortController();
|
|
17915
|
+
const timer = setTimeout(() => controller.abort(), remaining());
|
|
17916
|
+
let response;
|
|
17917
|
+
try {
|
|
17918
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
17919
|
+
method: "POST",
|
|
17920
|
+
// No task type unless the caller named one — an undeclared task adds no
|
|
17921
|
+
// header at all, which is what keeps user-facing reflect() unlabelled.
|
|
17922
|
+
headers: {
|
|
17923
|
+
...authHeaders,
|
|
17924
|
+
...taskTypeHeader(options.taskType),
|
|
17925
|
+
"Content-Type": "application/json"
|
|
17926
|
+
},
|
|
17927
|
+
body: buildBody(useResponseFormat),
|
|
17928
|
+
signal: controller.signal
|
|
17929
|
+
});
|
|
17930
|
+
} catch (err) {
|
|
17931
|
+
clearTimeout(timer);
|
|
17932
|
+
log.warn("[memory/reflect] portal request failed", {
|
|
17933
|
+
err: err instanceof Error ? err.message : String(err),
|
|
17934
|
+
baseUrl
|
|
17935
|
+
});
|
|
17936
|
+
return { kind: "error" };
|
|
17937
|
+
}
|
|
17906
17938
|
clearTimeout(timer);
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17939
|
+
if (!response.ok) {
|
|
17940
|
+
return { kind: "http", status: response.status, statusText: response.statusText };
|
|
17941
|
+
}
|
|
17942
|
+
const bodyTimer = setTimeout(() => controller.abort(), remaining());
|
|
17943
|
+
try {
|
|
17944
|
+
const body = await response.json();
|
|
17945
|
+
clearTimeout(bodyTimer);
|
|
17946
|
+
return { kind: "ok", body };
|
|
17947
|
+
} catch (err) {
|
|
17948
|
+
clearTimeout(bodyTimer);
|
|
17949
|
+
log.warn("[memory/reflect] failed to parse portal response body", {
|
|
17950
|
+
err: err instanceof Error ? err.message : String(err)
|
|
17951
|
+
});
|
|
17952
|
+
return { kind: "error" };
|
|
17953
|
+
}
|
|
17954
|
+
};
|
|
17955
|
+
let attempt = await sendOnce(sendResponseFormat);
|
|
17956
|
+
let schemaFallbackUsed = false;
|
|
17957
|
+
const budgetLeftMs = remaining();
|
|
17958
|
+
if (attempt.kind === "http" && sendResponseFormat && !SCHEMA_FALLBACK_SKIP_STATUSES.has(attempt.status) && budgetLeftMs >= MIN_RETRY_BUDGET_MS) {
|
|
17959
|
+
log.warn("[memory/reflect] response_format json_schema rejected; retrying schema-in-prompt", {
|
|
17960
|
+
status: attempt.status,
|
|
17961
|
+
statusText: attempt.statusText,
|
|
17962
|
+
model,
|
|
17963
|
+
taskType: options.taskType,
|
|
17964
|
+
budgetLeftMs
|
|
17910
17965
|
});
|
|
17911
|
-
|
|
17966
|
+
schemaFallbackUsed = true;
|
|
17967
|
+
attempt = await sendOnce(false);
|
|
17912
17968
|
}
|
|
17913
|
-
|
|
17914
|
-
if (
|
|
17969
|
+
if (attempt.kind === "error") return baseResult;
|
|
17970
|
+
if (attempt.kind === "http") {
|
|
17915
17971
|
log.warn("[memory/reflect] portal returned non-OK", {
|
|
17916
|
-
status:
|
|
17917
|
-
statusText:
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
}
|
|
17921
|
-
const bodyTimer = setTimeout(() => controller.abort(), remaining());
|
|
17922
|
-
let body;
|
|
17923
|
-
try {
|
|
17924
|
-
body = await response.json();
|
|
17925
|
-
} catch (err) {
|
|
17926
|
-
clearTimeout(bodyTimer);
|
|
17927
|
-
log.warn("[memory/reflect] failed to parse portal response body", {
|
|
17928
|
-
err: err instanceof Error ? err.message : String(err)
|
|
17972
|
+
status: attempt.status,
|
|
17973
|
+
statusText: attempt.statusText,
|
|
17974
|
+
// Distinguishes "the fallback ran and still failed" from "never tried".
|
|
17975
|
+
schemaFallbackUsed
|
|
17929
17976
|
});
|
|
17930
17977
|
return baseResult;
|
|
17931
17978
|
}
|
|
17932
|
-
|
|
17933
|
-
return parseAnswer(body, baseResult, !!options.responseSchema);
|
|
17979
|
+
return parseAnswer(attempt.body, baseResult, !!options.responseSchema);
|
|
17934
17980
|
}
|
|
17935
17981
|
function parseAnswer(body, base, parseSchema) {
|
|
17936
17982
|
if (typeof body !== "object" || body === null) return base;
|
|
17937
17983
|
const obj = body;
|
|
17938
|
-
const
|
|
17939
|
-
let text12 = "";
|
|
17940
|
-
if (Array.isArray(choices) && choices.length > 0) {
|
|
17941
|
-
const message = choices[0].message;
|
|
17942
|
-
if (typeof message === "object" && message !== null) {
|
|
17943
|
-
const content = message.content;
|
|
17944
|
-
if (typeof content === "string") text12 = content;
|
|
17945
|
-
}
|
|
17946
|
-
}
|
|
17984
|
+
const text12 = extractCompletionContent(obj) ?? "";
|
|
17947
17985
|
const usage = obj.usage;
|
|
17948
17986
|
let structuredOutput;
|
|
17949
17987
|
if (parseSchema && text12) {
|
|
@@ -17955,14 +17993,19 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
17955
17993
|
});
|
|
17956
17994
|
}
|
|
17957
17995
|
}
|
|
17996
|
+
const promptTokens = usage?.prompt_tokens ?? usage?.input_tokens ?? 0;
|
|
17997
|
+
const completionTokens = usage?.completion_tokens ?? usage?.output_tokens ?? 0;
|
|
17958
17998
|
return {
|
|
17959
17999
|
text: text12,
|
|
17960
18000
|
...structuredOutput !== void 0 && { structuredOutput },
|
|
17961
18001
|
basedOn: base.basedOn,
|
|
17962
18002
|
usage: {
|
|
17963
|
-
promptTokens
|
|
17964
|
-
completionTokens
|
|
17965
|
-
|
|
18003
|
+
promptTokens,
|
|
18004
|
+
completionTokens,
|
|
18005
|
+
// Derived when absent: the Responses API reports the two component counts
|
|
18006
|
+
// and does not always send a total, which would otherwise report zero
|
|
18007
|
+
// spend for a call that plainly cost something.
|
|
18008
|
+
totalTokens: usage?.total_tokens ?? promptTokens + completionTokens
|
|
17966
18009
|
}
|
|
17967
18010
|
};
|
|
17968
18011
|
}
|
package/dist/expo/index.mjs
CHANGED
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
upsertMessageOp,
|
|
133
133
|
useEncryption,
|
|
134
134
|
vaultMemoryToStored
|
|
135
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-TNMPAE3V.mjs";
|
|
136
136
|
import {
|
|
137
137
|
PII_PATTERNS,
|
|
138
138
|
PiiRedactor,
|
|
@@ -140,21 +140,23 @@ import {
|
|
|
140
140
|
isPiiRedactor,
|
|
141
141
|
notifyConsolidationFallback,
|
|
142
142
|
resolvePiiRedactor
|
|
143
|
-
} from "./chunk-
|
|
143
|
+
} from "./chunk-A2G6TRUK.mjs";
|
|
144
144
|
import {
|
|
145
145
|
INTERNAL_FLOW_MARKER,
|
|
146
146
|
callPortalJsonCompletion,
|
|
147
147
|
consoleLogger,
|
|
148
|
+
extractCompletionContent,
|
|
148
149
|
extractJsonCandidate,
|
|
149
150
|
getLogger,
|
|
150
151
|
noopLogger,
|
|
152
|
+
requiresResponsesTransport,
|
|
151
153
|
resolvePortalAuthHeaders,
|
|
152
154
|
setLogger,
|
|
153
155
|
supportsResponseFormat,
|
|
154
156
|
taskTypeHeader,
|
|
155
157
|
validateEndpointOverride,
|
|
156
158
|
withInternalFlowMarker
|
|
157
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-4Z2X4UYQ.mjs";
|
|
158
160
|
import {
|
|
159
161
|
BASE_URL,
|
|
160
162
|
MCP_R2_DOMAIN,
|
|
@@ -6868,7 +6870,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
6868
6870
|
content: m.content,
|
|
6869
6871
|
similarity: m.similarity
|
|
6870
6872
|
}));
|
|
6871
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
6873
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-ZM5JNULQ.mjs");
|
|
6872
6874
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
6873
6875
|
if (decision.action === "create") return null;
|
|
6874
6876
|
if (decision.action === "supersede" && decision.content) {
|
|
@@ -8092,6 +8094,9 @@ var DEFAULT_BASE_URL = BASE_URL;
|
|
|
8092
8094
|
var DEFAULT_MODEL3 = "anthropic/claude-sonnet-4-6";
|
|
8093
8095
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
8094
8096
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
8097
|
+
var MIN_RETRY_BUDGET_MS = 2e3;
|
|
8098
|
+
var MIN_RESPONSES_OUTPUT_TOKENS = 2048;
|
|
8099
|
+
var SCHEMA_FALLBACK_SKIP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 408, 409, 413, 425, 429]);
|
|
8095
8100
|
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.
|
|
8096
8101
|
|
|
8097
8102
|
Rules:
|
|
@@ -8123,14 +8128,9 @@ ${m.content}`).join("\n\n");
|
|
|
8123
8128
|
const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
|
|
8124
8129
|
const model = options.llmModel ?? DEFAULT_MODEL3;
|
|
8125
8130
|
const wantsStructured = !!options.responseSchema;
|
|
8126
|
-
const
|
|
8131
|
+
const useResponsesTransport = requiresResponsesTransport(model);
|
|
8132
|
+
const sendResponseFormat = wantsStructured && !useResponsesTransport && supportsResponseFormat(model, "json_schema");
|
|
8127
8133
|
const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
8128
|
-
const systemPrompt = wantsStructured && !sendResponseFormat ? `${basePrompt}
|
|
8129
|
-
|
|
8130
|
-
Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
|
|
8131
|
-
${JSON.stringify(
|
|
8132
|
-
options.responseSchema
|
|
8133
|
-
)}` : basePrompt;
|
|
8134
8134
|
const userMessage = [
|
|
8135
8135
|
`Question:
|
|
8136
8136
|
${trimmed}`,
|
|
@@ -8140,85 +8140,121 @@ ${evidence}`
|
|
|
8140
8140
|
].join("\n\n");
|
|
8141
8141
|
const maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
8142
8142
|
const fetchImpl = options.fetchFn ?? fetch;
|
|
8143
|
+
const buildBody = (useResponseFormat) => {
|
|
8144
|
+
const systemPrompt = wantsStructured && !useResponseFormat ? `${basePrompt}
|
|
8145
|
+
|
|
8146
|
+
Respond with ONLY a single JSON object conforming to this JSON Schema, with no prose, comments, or code fences:
|
|
8147
|
+
${JSON.stringify(
|
|
8148
|
+
options.responseSchema
|
|
8149
|
+
)}` : basePrompt;
|
|
8150
|
+
const messages = [
|
|
8151
|
+
{ role: "system", content: systemPrompt },
|
|
8152
|
+
{ role: "user", content: userMessage }
|
|
8153
|
+
];
|
|
8154
|
+
if (useResponsesTransport) {
|
|
8155
|
+
return JSON.stringify({
|
|
8156
|
+
model,
|
|
8157
|
+
// Same system+user pair under the Responses-API field names: `input`
|
|
8158
|
+
// for the turns, `max_output_tokens` for the cap. Sending the
|
|
8159
|
+
// chat-completions spelling here is silently ignored, which caps the
|
|
8160
|
+
// answer at the portal default.
|
|
8161
|
+
input: messages,
|
|
8162
|
+
max_output_tokens: Math.max(maxTokens, MIN_RESPONSES_OUTPUT_TOKENS)
|
|
8163
|
+
});
|
|
8164
|
+
}
|
|
8165
|
+
return JSON.stringify({
|
|
8166
|
+
model,
|
|
8167
|
+
// Modern OpenAI field; the portal reads only `max_completion_tokens`
|
|
8168
|
+
// (the deprecated `max_tokens` is silently ignored → falls back to the
|
|
8169
|
+
// portal's default output cap and truncates the answer).
|
|
8170
|
+
max_completion_tokens: maxTokens,
|
|
8171
|
+
messages,
|
|
8172
|
+
...useResponseFormat && {
|
|
8173
|
+
response_format: {
|
|
8174
|
+
type: "json_schema",
|
|
8175
|
+
json_schema: { name: "reflect_output", schema: options.responseSchema }
|
|
8176
|
+
}
|
|
8177
|
+
}
|
|
8178
|
+
});
|
|
8179
|
+
};
|
|
8143
8180
|
const log = getLogger();
|
|
8144
8181
|
const authHeaders = await resolvePortalAuthHeaders(options, "memory/reflect");
|
|
8145
8182
|
if (authHeaders === null) return baseResult;
|
|
8146
|
-
const controller = new AbortController();
|
|
8147
8183
|
const deadline = Date.now() + REQUEST_TIMEOUT_MS;
|
|
8148
8184
|
const remaining = () => Math.max(0, deadline - Date.now());
|
|
8149
|
-
const
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
}
|
|
8176
|
-
}
|
|
8177
|
-
}),
|
|
8178
|
-
signal: controller.signal
|
|
8179
|
-
});
|
|
8180
|
-
} catch (err) {
|
|
8185
|
+
const endpoint = useResponsesTransport ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
8186
|
+
const sendOnce = async (useResponseFormat) => {
|
|
8187
|
+
const controller = new AbortController();
|
|
8188
|
+
const timer = setTimeout(() => controller.abort(), remaining());
|
|
8189
|
+
let response;
|
|
8190
|
+
try {
|
|
8191
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
8192
|
+
method: "POST",
|
|
8193
|
+
// No task type unless the caller named one — an undeclared task adds no
|
|
8194
|
+
// header at all, which is what keeps user-facing reflect() unlabelled.
|
|
8195
|
+
headers: {
|
|
8196
|
+
...authHeaders,
|
|
8197
|
+
...taskTypeHeader(options.taskType),
|
|
8198
|
+
"Content-Type": "application/json"
|
|
8199
|
+
},
|
|
8200
|
+
body: buildBody(useResponseFormat),
|
|
8201
|
+
signal: controller.signal
|
|
8202
|
+
});
|
|
8203
|
+
} catch (err) {
|
|
8204
|
+
clearTimeout(timer);
|
|
8205
|
+
log.warn("[memory/reflect] portal request failed", {
|
|
8206
|
+
err: err instanceof Error ? err.message : String(err),
|
|
8207
|
+
baseUrl
|
|
8208
|
+
});
|
|
8209
|
+
return { kind: "error" };
|
|
8210
|
+
}
|
|
8181
8211
|
clearTimeout(timer);
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8212
|
+
if (!response.ok) {
|
|
8213
|
+
return { kind: "http", status: response.status, statusText: response.statusText };
|
|
8214
|
+
}
|
|
8215
|
+
const bodyTimer = setTimeout(() => controller.abort(), remaining());
|
|
8216
|
+
try {
|
|
8217
|
+
const body = await response.json();
|
|
8218
|
+
clearTimeout(bodyTimer);
|
|
8219
|
+
return { kind: "ok", body };
|
|
8220
|
+
} catch (err) {
|
|
8221
|
+
clearTimeout(bodyTimer);
|
|
8222
|
+
log.warn("[memory/reflect] failed to parse portal response body", {
|
|
8223
|
+
err: err instanceof Error ? err.message : String(err)
|
|
8224
|
+
});
|
|
8225
|
+
return { kind: "error" };
|
|
8226
|
+
}
|
|
8227
|
+
};
|
|
8228
|
+
let attempt = await sendOnce(sendResponseFormat);
|
|
8229
|
+
let schemaFallbackUsed = false;
|
|
8230
|
+
const budgetLeftMs = remaining();
|
|
8231
|
+
if (attempt.kind === "http" && sendResponseFormat && !SCHEMA_FALLBACK_SKIP_STATUSES.has(attempt.status) && budgetLeftMs >= MIN_RETRY_BUDGET_MS) {
|
|
8232
|
+
log.warn("[memory/reflect] response_format json_schema rejected; retrying schema-in-prompt", {
|
|
8233
|
+
status: attempt.status,
|
|
8234
|
+
statusText: attempt.statusText,
|
|
8235
|
+
model,
|
|
8236
|
+
taskType: options.taskType,
|
|
8237
|
+
budgetLeftMs
|
|
8185
8238
|
});
|
|
8186
|
-
|
|
8239
|
+
schemaFallbackUsed = true;
|
|
8240
|
+
attempt = await sendOnce(false);
|
|
8187
8241
|
}
|
|
8188
|
-
|
|
8189
|
-
if (
|
|
8242
|
+
if (attempt.kind === "error") return baseResult;
|
|
8243
|
+
if (attempt.kind === "http") {
|
|
8190
8244
|
log.warn("[memory/reflect] portal returned non-OK", {
|
|
8191
|
-
status:
|
|
8192
|
-
statusText:
|
|
8245
|
+
status: attempt.status,
|
|
8246
|
+
statusText: attempt.statusText,
|
|
8247
|
+
// Distinguishes "the fallback ran and still failed" from "never tried".
|
|
8248
|
+
schemaFallbackUsed
|
|
8193
8249
|
});
|
|
8194
8250
|
return baseResult;
|
|
8195
8251
|
}
|
|
8196
|
-
|
|
8197
|
-
let body;
|
|
8198
|
-
try {
|
|
8199
|
-
body = await response.json();
|
|
8200
|
-
} catch (err) {
|
|
8201
|
-
clearTimeout(bodyTimer);
|
|
8202
|
-
log.warn("[memory/reflect] failed to parse portal response body", {
|
|
8203
|
-
err: err instanceof Error ? err.message : String(err)
|
|
8204
|
-
});
|
|
8205
|
-
return baseResult;
|
|
8206
|
-
}
|
|
8207
|
-
clearTimeout(bodyTimer);
|
|
8208
|
-
return parseAnswer(body, baseResult, !!options.responseSchema);
|
|
8252
|
+
return parseAnswer(attempt.body, baseResult, !!options.responseSchema);
|
|
8209
8253
|
}
|
|
8210
8254
|
function parseAnswer(body, base, parseSchema) {
|
|
8211
8255
|
if (typeof body !== "object" || body === null) return base;
|
|
8212
8256
|
const obj = body;
|
|
8213
|
-
const
|
|
8214
|
-
let text12 = "";
|
|
8215
|
-
if (Array.isArray(choices) && choices.length > 0) {
|
|
8216
|
-
const message = choices[0].message;
|
|
8217
|
-
if (typeof message === "object" && message !== null) {
|
|
8218
|
-
const content = message.content;
|
|
8219
|
-
if (typeof content === "string") text12 = content;
|
|
8220
|
-
}
|
|
8221
|
-
}
|
|
8257
|
+
const text12 = extractCompletionContent(obj) ?? "";
|
|
8222
8258
|
const usage = obj.usage;
|
|
8223
8259
|
let structuredOutput;
|
|
8224
8260
|
if (parseSchema && text12) {
|
|
@@ -8230,14 +8266,19 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
8230
8266
|
});
|
|
8231
8267
|
}
|
|
8232
8268
|
}
|
|
8269
|
+
const promptTokens = usage?.prompt_tokens ?? usage?.input_tokens ?? 0;
|
|
8270
|
+
const completionTokens = usage?.completion_tokens ?? usage?.output_tokens ?? 0;
|
|
8233
8271
|
return {
|
|
8234
8272
|
text: text12,
|
|
8235
8273
|
...structuredOutput !== void 0 && { structuredOutput },
|
|
8236
8274
|
basedOn: base.basedOn,
|
|
8237
8275
|
usage: {
|
|
8238
|
-
promptTokens
|
|
8239
|
-
completionTokens
|
|
8240
|
-
|
|
8276
|
+
promptTokens,
|
|
8277
|
+
completionTokens,
|
|
8278
|
+
// Derived when absent: the Responses API reports the two component counts
|
|
8279
|
+
// and does not always send a total, which would otherwise report zero
|
|
8280
|
+
// spend for a call that plainly cost something.
|
|
8281
|
+
totalTokens: usage?.total_tokens ?? promptTokens + completionTokens
|
|
8241
8282
|
}
|
|
8242
8283
|
};
|
|
8243
8284
|
}
|
|
@@ -70,6 +70,10 @@ function supportsResponseFormat(model, variant = "json_object") {
|
|
|
70
70
|
const allow = variant === "json_schema" ? RESPONSE_SCHEMA_OK : RESPONSE_FORMAT_OK;
|
|
71
71
|
return model.split("/").some((seg) => allow.has(seg));
|
|
72
72
|
}
|
|
73
|
+
var RESPONSES_ONLY_MODEL_PREFIXES = ["gpt-5.6"];
|
|
74
|
+
function requiresResponsesTransport(model) {
|
|
75
|
+
return model.split("/").some((seg) => RESPONSES_ONLY_MODEL_PREFIXES.some((prefix) => seg.startsWith(prefix)));
|
|
76
|
+
}
|
|
73
77
|
var CHAT_TO_RESPONSES_FIELDS = {
|
|
74
78
|
max_completion_tokens: "max_output_tokens"
|
|
75
79
|
};
|
|
@@ -424,7 +428,9 @@ export {
|
|
|
424
428
|
withInternalFlowMarker,
|
|
425
429
|
taskTypeHeader,
|
|
426
430
|
supportsResponseFormat,
|
|
431
|
+
requiresResponsesTransport,
|
|
427
432
|
resolvePortalAuthHeaders,
|
|
428
433
|
callPortalJsonCompletion,
|
|
429
|
-
extractJsonCandidate
|
|
434
|
+
extractJsonCandidate,
|
|
435
|
+
extractCompletionContent
|
|
430
436
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callPortalJsonCompletion,
|
|
3
3
|
getLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4Z2X4UYQ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
BASE_URL,
|
|
7
7
|
createClientConfig
|
|
@@ -7169,7 +7169,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
7169
7169
|
subQueries = decomp.subQueries;
|
|
7170
7170
|
}
|
|
7171
7171
|
}
|
|
7172
|
-
const { recall: recall2 } = await import("./recall-
|
|
7172
|
+
const { recall: recall2 } = await import("./recall-UVVZGRVF.mjs");
|
|
7173
7173
|
let recallDegraded = [];
|
|
7174
7174
|
const result = await recall2(
|
|
7175
7175
|
query,
|