@anuma/sdk 6.14.1 → 6.15.0
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/client/index.cjs +13 -0
- package/dist/client/index.d.mts +187 -1
- package/dist/client/index.d.ts +187 -1
- package/dist/client/index.mjs +11 -0
- package/dist/expo/{chunk-O25LUKBK.mjs → chunk-3V3BBJLH.mjs} +66 -8
- package/dist/expo/{chunk-M4JSLFTQ.mjs → chunk-DIUQLXEH.mjs} +1 -1
- package/dist/expo/{chunk-JA7CDJCA.mjs → chunk-LUSKQQDD.mjs} +2 -2
- package/dist/{react/consolidate-LSDBMQDW.mjs → expo/consolidate-GTMXZZ4C.mjs} +2 -2
- package/dist/expo/index.cjs +68 -10
- package/dist/expo/index.d.mts +50 -12
- package/dist/expo/index.d.ts +50 -12
- package/dist/expo/index.mjs +5 -5
- package/dist/expo/{recall-JYVHWU6N.mjs → recall-GKYVPD2B.mjs} +2 -2
- package/dist/react/{chunk-2XLHV2XW.mjs → chunk-2GNOTRG4.mjs} +1 -1
- package/dist/react/{chunk-O25LUKBK.mjs → chunk-3V3BBJLH.mjs} +66 -8
- package/dist/react/{chunk-DNSPMVBY.mjs → chunk-PDKKPAXP.mjs} +2 -2
- package/dist/{expo/consolidate-S3KFA2WT.mjs → react/consolidate-Y2XWEZRQ.mjs} +2 -2
- package/dist/react/index.cjs +68 -10
- package/dist/react/index.d.mts +50 -12
- package/dist/react/index.d.ts +50 -12
- package/dist/react/index.mjs +5 -5
- package/dist/react/{recall-2BWBJWGG.mjs → recall-5HNAFHLL.mjs} +2 -2
- package/dist/server/{chunk-O7TB36P3.mjs → chunk-2QFK4L7Y.mjs} +2 -2
- package/dist/server/{chunk-7D3RI25K.mjs → chunk-H4G3DLDJ.mjs} +66 -8
- package/dist/server/{chunk-GP6YY6H5.mjs → chunk-JPLFOSB2.mjs} +1 -1
- package/dist/server/{consolidate-Z2JJP7LW.mjs → consolidate-CMMDTZ37.mjs} +2 -2
- package/dist/server/index.cjs +68 -10
- package/dist/server/index.d.mts +50 -12
- package/dist/server/index.d.ts +50 -12
- package/dist/server/index.mjs +5 -5
- package/dist/server/{recall-VHU372MK.mjs → recall-EODNEKIA.mjs} +2 -2
- package/package.json +2 -2
|
@@ -70,6 +70,30 @@ 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 CHAT_TO_RESPONSES_FIELDS = {
|
|
74
|
+
max_completion_tokens: "max_output_tokens"
|
|
75
|
+
};
|
|
76
|
+
function responsesExtra(extra) {
|
|
77
|
+
if (!extra) return {};
|
|
78
|
+
const out = {};
|
|
79
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
80
|
+
const target = CHAT_TO_RESPONSES_FIELDS[key] ?? key;
|
|
81
|
+
if (target !== key && target in extra) continue;
|
|
82
|
+
out[target] = value;
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
var FOREIGN_ENDPOINT_SUFFIX = {
|
|
87
|
+
chat: "/responses",
|
|
88
|
+
responses: "/chat/completions"
|
|
89
|
+
};
|
|
90
|
+
function assertTransportMatchesEndpoint(transport, endpoint) {
|
|
91
|
+
const foreign = FOREIGN_ENDPOINT_SUFFIX[transport];
|
|
92
|
+
if (!endpoint.endsWith(foreign)) return;
|
|
93
|
+
throw new Error(
|
|
94
|
+
`endpointOverride "${endpoint}" is the other transport's endpoint, but transport is "${transport}". The request body is built for the transport, so this sends the wrong shape and 400s without retry.`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
73
97
|
var RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
74
98
|
function isRetryableStatus(status) {
|
|
75
99
|
return status >= 500 || RETRYABLE_HTTP.has(status);
|
|
@@ -111,13 +135,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
111
135
|
}
|
|
112
136
|
async function callPortalJsonCompletion(req) {
|
|
113
137
|
const log = getLogger();
|
|
114
|
-
let endpoint = "/api/v1/chat/completions";
|
|
138
|
+
let endpoint = req.transport === "responses" ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
115
139
|
if (req.endpointOverride !== void 0) {
|
|
116
140
|
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
117
141
|
if (!overrideValidation.valid) {
|
|
118
142
|
throw new Error(overrideValidation.message);
|
|
119
143
|
}
|
|
120
144
|
endpoint = overrideValidation.endpoint;
|
|
145
|
+
assertTransportMatchesEndpoint(req.transport ?? "chat", endpoint);
|
|
121
146
|
}
|
|
122
147
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
123
148
|
const startedAt = Date.now();
|
|
@@ -179,8 +204,8 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
179
204
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
180
205
|
if (authHeaders === null)
|
|
181
206
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
182
|
-
const
|
|
183
|
-
const prefill =
|
|
207
|
+
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
208
|
+
const prefill = usesPrefill ? "{" : "";
|
|
184
209
|
const messages = [
|
|
185
210
|
// Every caller of this helper is a first-party BACKGROUND op (fact extraction,
|
|
186
211
|
// topic sweep, consolidation, classifiers, graph traversal, query
|
|
@@ -199,13 +224,34 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
199
224
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
200
225
|
const controller = new AbortController();
|
|
201
226
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
202
|
-
const requestBody = {
|
|
227
|
+
const requestBody = req.transport === "responses" ? {
|
|
228
|
+
model: req.model,
|
|
229
|
+
// Same system+user pair under the Responses-API field name. No prefill
|
|
230
|
+
// entry to strip: `usesPrefill` is false on this transport, so it was
|
|
231
|
+
// never pushed and the response-side restore is disarmed with it. An
|
|
232
|
+
// earlier version pushed it and sliced it back off here, which left
|
|
233
|
+
// `prefill` truthy and the restore still armed — the fix belonged at
|
|
234
|
+
// the decision, not at the two symptoms.
|
|
235
|
+
input: messages,
|
|
236
|
+
...req.reasoning && { reasoning: req.reasoning },
|
|
237
|
+
// NO response_format. The Responses API spells structured output
|
|
238
|
+
// differently (`text.format`), and it is unverified against this
|
|
239
|
+
// portal — so this transport relies on the same strict-JSON system
|
|
240
|
+
// prompt plus `extractJsonCandidate` that every response_format-
|
|
241
|
+
// rejecting model already relies on. Verified end to end on dev:
|
|
242
|
+
// luna returns clean parseable JSON here without it. Add the field
|
|
243
|
+
// only with a per-provider check, exactly as RESPONSE_FORMAT_OK was
|
|
244
|
+
// earned.
|
|
245
|
+
...responsesExtra(req.extra)
|
|
246
|
+
} : {
|
|
203
247
|
model: req.model,
|
|
204
248
|
messages,
|
|
205
249
|
...supportsJsonObjectFormat && { response_format: { type: "json_object" } },
|
|
206
250
|
...req.extra
|
|
207
251
|
};
|
|
208
|
-
if (!supportsJsonObjectFormat)
|
|
252
|
+
if (req.transport === "responses" || !supportsJsonObjectFormat) {
|
|
253
|
+
delete requestBody.response_format;
|
|
254
|
+
}
|
|
209
255
|
let response;
|
|
210
256
|
try {
|
|
211
257
|
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
@@ -335,13 +381,15 @@ function logPortalUsage(body, tag) {
|
|
|
335
381
|
const root = asRecord(body);
|
|
336
382
|
if (!root) return;
|
|
337
383
|
const usage = asRecord(root.usage);
|
|
338
|
-
const promptTokens = asCount(usage?.prompt_tokens);
|
|
339
|
-
const completionTokens = asCount(usage?.completion_tokens);
|
|
384
|
+
const promptTokens = asCount(usage?.prompt_tokens) ?? asCount(usage?.input_tokens);
|
|
385
|
+
const completionTokens = asCount(usage?.completion_tokens) ?? asCount(usage?.output_tokens);
|
|
340
386
|
if (promptTokens === void 0 && completionTokens === void 0) return;
|
|
341
|
-
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? 0;
|
|
387
|
+
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? asCount(asRecord(usage?.input_tokens_details)?.cached_tokens) ?? 0;
|
|
388
|
+
const reasoningTokens = asCount(asRecord(usage?.output_tokens_details)?.reasoning_tokens) ?? asCount(asRecord(usage?.completion_tokens_details)?.reasoning_tokens);
|
|
342
389
|
const parts = [];
|
|
343
390
|
if (promptTokens !== void 0) parts.push(`prompt=${promptTokens}`);
|
|
344
391
|
if (completionTokens !== void 0) parts.push(`completion=${completionTokens}`);
|
|
392
|
+
if (reasoningTokens !== void 0) parts.push(`reasoning=${reasoningTokens}`);
|
|
345
393
|
parts.push(`cached=${cachedTokens}`);
|
|
346
394
|
getLogger().debug(`[${tag}] usage ${parts.join(" ")}`);
|
|
347
395
|
} catch {
|
|
@@ -349,12 +397,22 @@ function logPortalUsage(body, tag) {
|
|
|
349
397
|
}
|
|
350
398
|
function extractCompletionContent(body) {
|
|
351
399
|
if (typeof body !== "object" || body === null) return null;
|
|
400
|
+
const responsesText = extractResponsesContent(body);
|
|
401
|
+
if (responsesText !== null) return responsesText;
|
|
352
402
|
const choices = body.choices;
|
|
353
403
|
if (!Array.isArray(choices) || choices.length === 0) return null;
|
|
354
404
|
const first = choices[0];
|
|
355
405
|
const content = first?.message?.content;
|
|
356
406
|
return typeof content === "string" ? content : null;
|
|
357
407
|
}
|
|
408
|
+
function extractResponsesContent(body) {
|
|
409
|
+
const root = asRecord(body);
|
|
410
|
+
if (!root) return null;
|
|
411
|
+
if (typeof root.output_text === "string" && root.output_text !== "") return root.output_text;
|
|
412
|
+
if (!Array.isArray(root.output)) return null;
|
|
413
|
+
const text = 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("");
|
|
414
|
+
return text;
|
|
415
|
+
}
|
|
358
416
|
|
|
359
417
|
export {
|
|
360
418
|
consoleLogger,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callPortalJsonCompletion,
|
|
3
3
|
getLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3V3BBJLH.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-GKYVPD2B.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-DIUQLXEH.mjs";
|
|
5
5
|
import {
|
|
6
6
|
callPortalJsonCompletion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3V3BBJLH.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,23 @@ 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 responsesExtra(extra) {
|
|
6149
|
+
if (!extra) return {};
|
|
6150
|
+
const out = {};
|
|
6151
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
6152
|
+
const target = CHAT_TO_RESPONSES_FIELDS[key] ?? key;
|
|
6153
|
+
if (target !== key && target in extra) continue;
|
|
6154
|
+
out[target] = value;
|
|
6155
|
+
}
|
|
6156
|
+
return out;
|
|
6157
|
+
}
|
|
6158
|
+
function assertTransportMatchesEndpoint(transport, endpoint) {
|
|
6159
|
+
const foreign = FOREIGN_ENDPOINT_SUFFIX[transport];
|
|
6160
|
+
if (!endpoint.endsWith(foreign)) return;
|
|
6161
|
+
throw new Error(
|
|
6162
|
+
`endpointOverride "${endpoint}" is the other transport's endpoint, but transport is "${transport}". The request body is built for the transport, so this sends the wrong shape and 400s without retry.`
|
|
6163
|
+
);
|
|
6164
|
+
}
|
|
6148
6165
|
function isRetryableStatus(status) {
|
|
6149
6166
|
return status >= 500 || RETRYABLE_HTTP.has(status);
|
|
6150
6167
|
}
|
|
@@ -6185,13 +6202,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
6185
6202
|
}
|
|
6186
6203
|
async function callPortalJsonCompletion(req) {
|
|
6187
6204
|
const log = getLogger();
|
|
6188
|
-
let endpoint = "/api/v1/chat/completions";
|
|
6205
|
+
let endpoint = req.transport === "responses" ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
6189
6206
|
if (req.endpointOverride !== void 0) {
|
|
6190
6207
|
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
6191
6208
|
if (!overrideValidation.valid) {
|
|
6192
6209
|
throw new Error(overrideValidation.message);
|
|
6193
6210
|
}
|
|
6194
6211
|
endpoint = overrideValidation.endpoint;
|
|
6212
|
+
assertTransportMatchesEndpoint(req.transport ?? "chat", endpoint);
|
|
6195
6213
|
}
|
|
6196
6214
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
6197
6215
|
const startedAt = Date.now();
|
|
@@ -6253,8 +6271,8 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
6253
6271
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
6254
6272
|
if (authHeaders === null)
|
|
6255
6273
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
6256
|
-
const
|
|
6257
|
-
const prefill =
|
|
6274
|
+
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
6275
|
+
const prefill = usesPrefill ? "{" : "";
|
|
6258
6276
|
const messages = [
|
|
6259
6277
|
// Every caller of this helper is a first-party BACKGROUND op (fact extraction,
|
|
6260
6278
|
// topic sweep, consolidation, classifiers, graph traversal, query
|
|
@@ -6273,13 +6291,34 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
6273
6291
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
6274
6292
|
const controller = new AbortController();
|
|
6275
6293
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
6276
|
-
const requestBody = {
|
|
6294
|
+
const requestBody = req.transport === "responses" ? {
|
|
6295
|
+
model: req.model,
|
|
6296
|
+
// Same system+user pair under the Responses-API field name. No prefill
|
|
6297
|
+
// entry to strip: `usesPrefill` is false on this transport, so it was
|
|
6298
|
+
// never pushed and the response-side restore is disarmed with it. An
|
|
6299
|
+
// earlier version pushed it and sliced it back off here, which left
|
|
6300
|
+
// `prefill` truthy and the restore still armed — the fix belonged at
|
|
6301
|
+
// the decision, not at the two symptoms.
|
|
6302
|
+
input: messages,
|
|
6303
|
+
...req.reasoning && { reasoning: req.reasoning },
|
|
6304
|
+
// NO response_format. The Responses API spells structured output
|
|
6305
|
+
// differently (`text.format`), and it is unverified against this
|
|
6306
|
+
// portal — so this transport relies on the same strict-JSON system
|
|
6307
|
+
// prompt plus `extractJsonCandidate` that every response_format-
|
|
6308
|
+
// rejecting model already relies on. Verified end to end on dev:
|
|
6309
|
+
// luna returns clean parseable JSON here without it. Add the field
|
|
6310
|
+
// only with a per-provider check, exactly as RESPONSE_FORMAT_OK was
|
|
6311
|
+
// earned.
|
|
6312
|
+
...responsesExtra(req.extra)
|
|
6313
|
+
} : {
|
|
6277
6314
|
model: req.model,
|
|
6278
6315
|
messages,
|
|
6279
6316
|
...supportsJsonObjectFormat && { response_format: { type: "json_object" } },
|
|
6280
6317
|
...req.extra
|
|
6281
6318
|
};
|
|
6282
|
-
if (!supportsJsonObjectFormat)
|
|
6319
|
+
if (req.transport === "responses" || !supportsJsonObjectFormat) {
|
|
6320
|
+
delete requestBody.response_format;
|
|
6321
|
+
}
|
|
6283
6322
|
let response;
|
|
6284
6323
|
try {
|
|
6285
6324
|
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
@@ -6409,13 +6448,15 @@ function logPortalUsage(body, tag) {
|
|
|
6409
6448
|
const root = asRecord(body);
|
|
6410
6449
|
if (!root) return;
|
|
6411
6450
|
const usage = asRecord(root.usage);
|
|
6412
|
-
const promptTokens = asCount(usage?.prompt_tokens);
|
|
6413
|
-
const completionTokens = asCount(usage?.completion_tokens);
|
|
6451
|
+
const promptTokens = asCount(usage?.prompt_tokens) ?? asCount(usage?.input_tokens);
|
|
6452
|
+
const completionTokens = asCount(usage?.completion_tokens) ?? asCount(usage?.output_tokens);
|
|
6414
6453
|
if (promptTokens === void 0 && completionTokens === void 0) return;
|
|
6415
|
-
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? 0;
|
|
6454
|
+
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? asCount(asRecord(usage?.input_tokens_details)?.cached_tokens) ?? 0;
|
|
6455
|
+
const reasoningTokens = asCount(asRecord(usage?.output_tokens_details)?.reasoning_tokens) ?? asCount(asRecord(usage?.completion_tokens_details)?.reasoning_tokens);
|
|
6416
6456
|
const parts = [];
|
|
6417
6457
|
if (promptTokens !== void 0) parts.push(`prompt=${promptTokens}`);
|
|
6418
6458
|
if (completionTokens !== void 0) parts.push(`completion=${completionTokens}`);
|
|
6459
|
+
if (reasoningTokens !== void 0) parts.push(`reasoning=${reasoningTokens}`);
|
|
6419
6460
|
parts.push(`cached=${cachedTokens}`);
|
|
6420
6461
|
getLogger().debug(`[${tag}] usage ${parts.join(" ")}`);
|
|
6421
6462
|
} catch {
|
|
@@ -6423,13 +6464,23 @@ function logPortalUsage(body, tag) {
|
|
|
6423
6464
|
}
|
|
6424
6465
|
function extractCompletionContent(body) {
|
|
6425
6466
|
if (typeof body !== "object" || body === null) return null;
|
|
6467
|
+
const responsesText = extractResponsesContent(body);
|
|
6468
|
+
if (responsesText !== null) return responsesText;
|
|
6426
6469
|
const choices = body.choices;
|
|
6427
6470
|
if (!Array.isArray(choices) || choices.length === 0) return null;
|
|
6428
6471
|
const first = choices[0];
|
|
6429
6472
|
const content = first?.message?.content;
|
|
6430
6473
|
return typeof content === "string" ? content : null;
|
|
6431
6474
|
}
|
|
6432
|
-
|
|
6475
|
+
function extractResponsesContent(body) {
|
|
6476
|
+
const root = asRecord(body);
|
|
6477
|
+
if (!root) return null;
|
|
6478
|
+
if (typeof root.output_text === "string" && root.output_text !== "") return root.output_text;
|
|
6479
|
+
if (!Array.isArray(root.output)) return null;
|
|
6480
|
+
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
|
+
return text12;
|
|
6482
|
+
}
|
|
6483
|
+
var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
|
|
6433
6484
|
var init_portalLlm = __esm({
|
|
6434
6485
|
"src/lib/memory/portalLlm.ts"() {
|
|
6435
6486
|
"use strict";
|
|
@@ -6441,6 +6492,13 @@ var init_portalLlm = __esm({
|
|
|
6441
6492
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
6442
6493
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
6443
6494
|
JSON_CONTRACT_REMINDER = "Output ONLY the strict JSON object requested. No prose, no explanation, no markdown.";
|
|
6495
|
+
CHAT_TO_RESPONSES_FIELDS = {
|
|
6496
|
+
max_completion_tokens: "max_output_tokens"
|
|
6497
|
+
};
|
|
6498
|
+
FOREIGN_ENDPOINT_SUFFIX = {
|
|
6499
|
+
chat: "/responses",
|
|
6500
|
+
responses: "/chat/completions"
|
|
6501
|
+
};
|
|
6444
6502
|
RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
6445
6503
|
}
|
|
6446
6504
|
});
|
|
@@ -15438,7 +15496,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
15438
15496
|
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
|
|
15439
15497
|
record._raw.id = row.memoryId;
|
|
15440
15498
|
record._setRaw("content", content);
|
|
15441
|
-
record._setRaw("scope", "
|
|
15499
|
+
record._setRaw("scope", "shared");
|
|
15442
15500
|
record._setRaw("folder_id", null);
|
|
15443
15501
|
record._setRaw("user_id", ctx.userId ?? null);
|
|
15444
15502
|
record._setRaw("is_deleted", false);
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -6335,15 +6335,26 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
6335
6335
|
}>;
|
|
6336
6336
|
|
|
6337
6337
|
/**
|
|
6338
|
-
*
|
|
6339
|
-
*
|
|
6340
|
-
*
|
|
6341
|
-
*
|
|
6338
|
+
* LEGACY. This column no longer decides anything.
|
|
6339
|
+
*
|
|
6340
|
+
* `scope === 'shared'` is now the single publication axis: it means the memory
|
|
6341
|
+
* is on the People Nearby profile, its text goes to the nearby server, and it
|
|
6342
|
+
* may inform what strangers see. `scope: 'private'` means it is not. There is
|
|
6343
|
+
* no second control, and scope no longer gates model access either — every
|
|
6344
|
+
* model tier reads every memory. Do NOT reason about publication from this
|
|
6345
|
+
* type; read `scope`.
|
|
6346
|
+
*
|
|
6347
|
+
* The column survives in the schema and is still stamped on writes so that
|
|
6348
|
+
* stored rows stay readable by builds that predate the change. Nothing on a
|
|
6349
|
+
* current build reads it to make a decision.
|
|
6350
|
+
*
|
|
6351
|
+
* Values, kept for tolerance of already-stored data:
|
|
6352
|
+
* - `private`: local-only (a null column reads as private)
|
|
6353
|
+
* - `public`: the row was published
|
|
6342
6354
|
*
|
|
6343
6355
|
* TWO TIERS ONLY (decided 2026-07-27). An earlier design had a middle
|
|
6344
6356
|
* `matchable` tier that published a memory's embedding while keeping its text
|
|
6345
|
-
* on-device; it was dropped
|
|
6346
|
-
* published with its content. Any unrecognised stored value — including a
|
|
6357
|
+
* on-device; it was dropped. Any unrecognised stored value — including a
|
|
6347
6358
|
* `matchable` row written by a pre-release build — reads as `private`, which is
|
|
6348
6359
|
* the fail-safe direction: it un-publishes rather than exposes.
|
|
6349
6360
|
*/
|
|
@@ -6997,12 +7008,16 @@ declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext,
|
|
|
6997
7008
|
* candidate to be reconciled against the vault — it is an already-decided
|
|
6998
7009
|
* fact the server has published.
|
|
6999
7010
|
*
|
|
7000
|
-
* The rows are written `
|
|
7001
|
-
*
|
|
7002
|
-
*
|
|
7003
|
-
*
|
|
7004
|
-
*
|
|
7005
|
-
*
|
|
7011
|
+
* The rows are written `scope: "shared"` because they genuinely ARE published.
|
|
7012
|
+
* `scope === 'shared'` is the publication axis — the single one. The reconciler
|
|
7013
|
+
* reads local scope as the user's intent, and it builds its `local` set from a
|
|
7014
|
+
* vault read narrowed to `{scopes: ['shared']}`. A row stamped anything else
|
|
7015
|
+
* never enters that read, so it is never adopted into the publish ledger, and
|
|
7016
|
+
* `toRevoke` is computed only over ids the ledger holds. The user's off-toggle
|
|
7017
|
+
* would then do nothing server-side while nearby kept serving the memory. The
|
|
7018
|
+
* `visibility` column is legacy: nothing reads it any more. They carry
|
|
7019
|
+
* `source: SOURCE_PHOTO`, which is what exempts them from decay's auto-archive;
|
|
7020
|
+
* see the note there for why archiving one would silently unpublish it.
|
|
7006
7021
|
*
|
|
7007
7022
|
* No embedding is computed here. `searchTool`'s un-embedded lane embeds any row
|
|
7008
7023
|
* lacking a vector at search time, uses it in that same search and persists it
|
|
@@ -7050,6 +7065,29 @@ interface PhotoIngestResult {
|
|
|
7050
7065
|
* class of bug as publishing a version the user has since changed. Re-ingesting
|
|
7051
7066
|
* changed text is a follow-up that needs a merge decision, not a clobber.
|
|
7052
7067
|
*
|
|
7068
|
+
* That skip is also why this op does NOT repair a row an older build stamped
|
|
7069
|
+
* `scope: "private"`. Such a row is present, so ingest leaves it alone, and it
|
|
7070
|
+
* stays outside the published-set read. The user's switch cannot revoke it.
|
|
7071
|
+
* Repair belongs in a one-time pass at upgrade. Do not add it here, for two
|
|
7072
|
+
* reasons:
|
|
7073
|
+
*
|
|
7074
|
+
* - **The two states are indistinguishable from this op.** After this build a
|
|
7075
|
+
* `photo:` row with `scope: "private"` is also exactly what the user's own
|
|
7076
|
+
* off-toggle produces. The toggle calls `updateVaultMemoryOp`, which writes
|
|
7077
|
+
* `scope` and never touches `visibility`, so the mis-stamped row and the
|
|
7078
|
+
* turned-off row carry identical columns. No test here can tell them apart.
|
|
7079
|
+
*
|
|
7080
|
+
* - **A re-stamp here would revert the off-toggle.** The pass runs ingest
|
|
7081
|
+
* BEFORE it reads the vault, so a row re-stamped `shared` re-enters the
|
|
7082
|
+
* desired set on that same pass and never reaches `toRevoke`. The switch
|
|
7083
|
+
* would spring back to "on" and nearby would keep serving the memory. That
|
|
7084
|
+
* is worse than the bug it repairs.
|
|
7085
|
+
*
|
|
7086
|
+
* A one-time pass does not have the ambiguity. Before this build the switch
|
|
7087
|
+
* already read "off" for these rows, because it reads `scope`, so no user can
|
|
7088
|
+
* have turned one off. Every `private` photo row at that instant came from the
|
|
7089
|
+
* old stamp.
|
|
7090
|
+
*
|
|
7053
7091
|
* Non-`photo:` ids are ignored: everything else in the published set is a
|
|
7054
7092
|
* client-published memory that by definition already lives in this vault (or in
|
|
7055
7093
|
* another device's, which is not ours to recreate).
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -6335,15 +6335,26 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
6335
6335
|
}>;
|
|
6336
6336
|
|
|
6337
6337
|
/**
|
|
6338
|
-
*
|
|
6339
|
-
*
|
|
6340
|
-
*
|
|
6341
|
-
*
|
|
6338
|
+
* LEGACY. This column no longer decides anything.
|
|
6339
|
+
*
|
|
6340
|
+
* `scope === 'shared'` is now the single publication axis: it means the memory
|
|
6341
|
+
* is on the People Nearby profile, its text goes to the nearby server, and it
|
|
6342
|
+
* may inform what strangers see. `scope: 'private'` means it is not. There is
|
|
6343
|
+
* no second control, and scope no longer gates model access either — every
|
|
6344
|
+
* model tier reads every memory. Do NOT reason about publication from this
|
|
6345
|
+
* type; read `scope`.
|
|
6346
|
+
*
|
|
6347
|
+
* The column survives in the schema and is still stamped on writes so that
|
|
6348
|
+
* stored rows stay readable by builds that predate the change. Nothing on a
|
|
6349
|
+
* current build reads it to make a decision.
|
|
6350
|
+
*
|
|
6351
|
+
* Values, kept for tolerance of already-stored data:
|
|
6352
|
+
* - `private`: local-only (a null column reads as private)
|
|
6353
|
+
* - `public`: the row was published
|
|
6342
6354
|
*
|
|
6343
6355
|
* TWO TIERS ONLY (decided 2026-07-27). An earlier design had a middle
|
|
6344
6356
|
* `matchable` tier that published a memory's embedding while keeping its text
|
|
6345
|
-
* on-device; it was dropped
|
|
6346
|
-
* published with its content. Any unrecognised stored value — including a
|
|
6357
|
+
* on-device; it was dropped. Any unrecognised stored value — including a
|
|
6347
6358
|
* `matchable` row written by a pre-release build — reads as `private`, which is
|
|
6348
6359
|
* the fail-safe direction: it un-publishes rather than exposes.
|
|
6349
6360
|
*/
|
|
@@ -6997,12 +7008,16 @@ declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext,
|
|
|
6997
7008
|
* candidate to be reconciled against the vault — it is an already-decided
|
|
6998
7009
|
* fact the server has published.
|
|
6999
7010
|
*
|
|
7000
|
-
* The rows are written `
|
|
7001
|
-
*
|
|
7002
|
-
*
|
|
7003
|
-
*
|
|
7004
|
-
*
|
|
7005
|
-
*
|
|
7011
|
+
* The rows are written `scope: "shared"` because they genuinely ARE published.
|
|
7012
|
+
* `scope === 'shared'` is the publication axis — the single one. The reconciler
|
|
7013
|
+
* reads local scope as the user's intent, and it builds its `local` set from a
|
|
7014
|
+
* vault read narrowed to `{scopes: ['shared']}`. A row stamped anything else
|
|
7015
|
+
* never enters that read, so it is never adopted into the publish ledger, and
|
|
7016
|
+
* `toRevoke` is computed only over ids the ledger holds. The user's off-toggle
|
|
7017
|
+
* would then do nothing server-side while nearby kept serving the memory. The
|
|
7018
|
+
* `visibility` column is legacy: nothing reads it any more. They carry
|
|
7019
|
+
* `source: SOURCE_PHOTO`, which is what exempts them from decay's auto-archive;
|
|
7020
|
+
* see the note there for why archiving one would silently unpublish it.
|
|
7006
7021
|
*
|
|
7007
7022
|
* No embedding is computed here. `searchTool`'s un-embedded lane embeds any row
|
|
7008
7023
|
* lacking a vector at search time, uses it in that same search and persists it
|
|
@@ -7050,6 +7065,29 @@ interface PhotoIngestResult {
|
|
|
7050
7065
|
* class of bug as publishing a version the user has since changed. Re-ingesting
|
|
7051
7066
|
* changed text is a follow-up that needs a merge decision, not a clobber.
|
|
7052
7067
|
*
|
|
7068
|
+
* That skip is also why this op does NOT repair a row an older build stamped
|
|
7069
|
+
* `scope: "private"`. Such a row is present, so ingest leaves it alone, and it
|
|
7070
|
+
* stays outside the published-set read. The user's switch cannot revoke it.
|
|
7071
|
+
* Repair belongs in a one-time pass at upgrade. Do not add it here, for two
|
|
7072
|
+
* reasons:
|
|
7073
|
+
*
|
|
7074
|
+
* - **The two states are indistinguishable from this op.** After this build a
|
|
7075
|
+
* `photo:` row with `scope: "private"` is also exactly what the user's own
|
|
7076
|
+
* off-toggle produces. The toggle calls `updateVaultMemoryOp`, which writes
|
|
7077
|
+
* `scope` and never touches `visibility`, so the mis-stamped row and the
|
|
7078
|
+
* turned-off row carry identical columns. No test here can tell them apart.
|
|
7079
|
+
*
|
|
7080
|
+
* - **A re-stamp here would revert the off-toggle.** The pass runs ingest
|
|
7081
|
+
* BEFORE it reads the vault, so a row re-stamped `shared` re-enters the
|
|
7082
|
+
* desired set on that same pass and never reaches `toRevoke`. The switch
|
|
7083
|
+
* would spring back to "on" and nearby would keep serving the memory. That
|
|
7084
|
+
* is worse than the bug it repairs.
|
|
7085
|
+
*
|
|
7086
|
+
* A one-time pass does not have the ambiguity. Before this build the switch
|
|
7087
|
+
* already read "off" for these rows, because it reads `scope`, so no user can
|
|
7088
|
+
* have turned one off. Every `private` photo row at that instant came from the
|
|
7089
|
+
* old stamp.
|
|
7090
|
+
*
|
|
7053
7091
|
* Non-`photo:` ids are ignored: everything else in the published set is a
|
|
7054
7092
|
* client-published memory that by definition already lives in this vault (or in
|
|
7055
7093
|
* another device's, which is not ours to recreate).
|
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-LUSKQQDD.mjs";
|
|
136
136
|
import {
|
|
137
137
|
PII_PATTERNS,
|
|
138
138
|
PiiRedactor,
|
|
@@ -140,7 +140,7 @@ import {
|
|
|
140
140
|
isPiiRedactor,
|
|
141
141
|
notifyConsolidationFallback,
|
|
142
142
|
resolvePiiRedactor
|
|
143
|
-
} from "./chunk-
|
|
143
|
+
} from "./chunk-DIUQLXEH.mjs";
|
|
144
144
|
import {
|
|
145
145
|
INTERNAL_FLOW_MARKER,
|
|
146
146
|
callPortalJsonCompletion,
|
|
@@ -154,7 +154,7 @@ import {
|
|
|
154
154
|
taskTypeHeader,
|
|
155
155
|
validateEndpointOverride,
|
|
156
156
|
withInternalFlowMarker
|
|
157
|
-
} from "./chunk-
|
|
157
|
+
} from "./chunk-3V3BBJLH.mjs";
|
|
158
158
|
import {
|
|
159
159
|
BASE_URL,
|
|
160
160
|
MCP_R2_DOMAIN,
|
|
@@ -5819,7 +5819,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
5819
5819
|
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
|
|
5820
5820
|
record._raw.id = row.memoryId;
|
|
5821
5821
|
record._setRaw("content", content);
|
|
5822
|
-
record._setRaw("scope", "
|
|
5822
|
+
record._setRaw("scope", "shared");
|
|
5823
5823
|
record._setRaw("folder_id", null);
|
|
5824
5824
|
record._setRaw("user_id", ctx.userId ?? null);
|
|
5825
5825
|
record._setRaw("is_deleted", false);
|
|
@@ -6868,7 +6868,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
6868
6868
|
content: m.content,
|
|
6869
6869
|
similarity: m.similarity
|
|
6870
6870
|
}));
|
|
6871
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
6871
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-GTMXZZ4C.mjs");
|
|
6872
6872
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
6873
6873
|
if (decision.action === "create") return null;
|
|
6874
6874
|
if (decision.action === "supersede" && decision.content) {
|