@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
|
@@ -57,6 +57,30 @@ function supportsResponseFormat(model, variant = "json_object") {
|
|
|
57
57
|
const allow = variant === "json_schema" ? RESPONSE_SCHEMA_OK : RESPONSE_FORMAT_OK;
|
|
58
58
|
return model.split("/").some((seg) => allow.has(seg));
|
|
59
59
|
}
|
|
60
|
+
var CHAT_TO_RESPONSES_FIELDS = {
|
|
61
|
+
max_completion_tokens: "max_output_tokens"
|
|
62
|
+
};
|
|
63
|
+
function responsesExtra(extra) {
|
|
64
|
+
if (!extra) return {};
|
|
65
|
+
const out = {};
|
|
66
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
67
|
+
const target = CHAT_TO_RESPONSES_FIELDS[key] ?? key;
|
|
68
|
+
if (target !== key && target in extra) continue;
|
|
69
|
+
out[target] = value;
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
var FOREIGN_ENDPOINT_SUFFIX = {
|
|
74
|
+
chat: "/responses",
|
|
75
|
+
responses: "/chat/completions"
|
|
76
|
+
};
|
|
77
|
+
function assertTransportMatchesEndpoint(transport, endpoint) {
|
|
78
|
+
const foreign = FOREIGN_ENDPOINT_SUFFIX[transport];
|
|
79
|
+
if (!endpoint.endsWith(foreign)) return;
|
|
80
|
+
throw new Error(
|
|
81
|
+
`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.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
60
84
|
var RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
61
85
|
function isRetryableStatus(status) {
|
|
62
86
|
return status >= 500 || RETRYABLE_HTTP.has(status);
|
|
@@ -98,13 +122,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
98
122
|
}
|
|
99
123
|
async function callPortalJsonCompletion(req) {
|
|
100
124
|
const log = getLogger();
|
|
101
|
-
let endpoint = "/api/v1/chat/completions";
|
|
125
|
+
let endpoint = req.transport === "responses" ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
102
126
|
if (req.endpointOverride !== void 0) {
|
|
103
127
|
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
104
128
|
if (!overrideValidation.valid) {
|
|
105
129
|
throw new Error(overrideValidation.message);
|
|
106
130
|
}
|
|
107
131
|
endpoint = overrideValidation.endpoint;
|
|
132
|
+
assertTransportMatchesEndpoint(req.transport ?? "chat", endpoint);
|
|
108
133
|
}
|
|
109
134
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
110
135
|
const startedAt = Date.now();
|
|
@@ -166,8 +191,8 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
166
191
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
167
192
|
if (authHeaders === null)
|
|
168
193
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
169
|
-
const
|
|
170
|
-
const prefill =
|
|
194
|
+
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
195
|
+
const prefill = usesPrefill ? "{" : "";
|
|
171
196
|
const messages = [
|
|
172
197
|
// Every caller of this helper is a first-party BACKGROUND op (fact extraction,
|
|
173
198
|
// topic sweep, consolidation, classifiers, graph traversal, query
|
|
@@ -186,13 +211,34 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
186
211
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
187
212
|
const controller = new AbortController();
|
|
188
213
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
189
|
-
const requestBody = {
|
|
214
|
+
const requestBody = req.transport === "responses" ? {
|
|
215
|
+
model: req.model,
|
|
216
|
+
// Same system+user pair under the Responses-API field name. No prefill
|
|
217
|
+
// entry to strip: `usesPrefill` is false on this transport, so it was
|
|
218
|
+
// never pushed and the response-side restore is disarmed with it. An
|
|
219
|
+
// earlier version pushed it and sliced it back off here, which left
|
|
220
|
+
// `prefill` truthy and the restore still armed — the fix belonged at
|
|
221
|
+
// the decision, not at the two symptoms.
|
|
222
|
+
input: messages,
|
|
223
|
+
...req.reasoning && { reasoning: req.reasoning },
|
|
224
|
+
// NO response_format. The Responses API spells structured output
|
|
225
|
+
// differently (`text.format`), and it is unverified against this
|
|
226
|
+
// portal — so this transport relies on the same strict-JSON system
|
|
227
|
+
// prompt plus `extractJsonCandidate` that every response_format-
|
|
228
|
+
// rejecting model already relies on. Verified end to end on dev:
|
|
229
|
+
// luna returns clean parseable JSON here without it. Add the field
|
|
230
|
+
// only with a per-provider check, exactly as RESPONSE_FORMAT_OK was
|
|
231
|
+
// earned.
|
|
232
|
+
...responsesExtra(req.extra)
|
|
233
|
+
} : {
|
|
190
234
|
model: req.model,
|
|
191
235
|
messages,
|
|
192
236
|
...supportsJsonObjectFormat && { response_format: { type: "json_object" } },
|
|
193
237
|
...req.extra
|
|
194
238
|
};
|
|
195
|
-
if (!supportsJsonObjectFormat)
|
|
239
|
+
if (req.transport === "responses" || !supportsJsonObjectFormat) {
|
|
240
|
+
delete requestBody.response_format;
|
|
241
|
+
}
|
|
196
242
|
let response;
|
|
197
243
|
try {
|
|
198
244
|
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
@@ -322,13 +368,15 @@ function logPortalUsage(body, tag) {
|
|
|
322
368
|
const root = asRecord(body);
|
|
323
369
|
if (!root) return;
|
|
324
370
|
const usage = asRecord(root.usage);
|
|
325
|
-
const promptTokens = asCount(usage?.prompt_tokens);
|
|
326
|
-
const completionTokens = asCount(usage?.completion_tokens);
|
|
371
|
+
const promptTokens = asCount(usage?.prompt_tokens) ?? asCount(usage?.input_tokens);
|
|
372
|
+
const completionTokens = asCount(usage?.completion_tokens) ?? asCount(usage?.output_tokens);
|
|
327
373
|
if (promptTokens === void 0 && completionTokens === void 0) return;
|
|
328
|
-
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? 0;
|
|
374
|
+
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;
|
|
375
|
+
const reasoningTokens = asCount(asRecord(usage?.output_tokens_details)?.reasoning_tokens) ?? asCount(asRecord(usage?.completion_tokens_details)?.reasoning_tokens);
|
|
329
376
|
const parts = [];
|
|
330
377
|
if (promptTokens !== void 0) parts.push(`prompt=${promptTokens}`);
|
|
331
378
|
if (completionTokens !== void 0) parts.push(`completion=${completionTokens}`);
|
|
379
|
+
if (reasoningTokens !== void 0) parts.push(`reasoning=${reasoningTokens}`);
|
|
332
380
|
parts.push(`cached=${cachedTokens}`);
|
|
333
381
|
getLogger().debug(`[${tag}] usage ${parts.join(" ")}`);
|
|
334
382
|
} catch {
|
|
@@ -336,12 +384,22 @@ function logPortalUsage(body, tag) {
|
|
|
336
384
|
}
|
|
337
385
|
function extractCompletionContent(body) {
|
|
338
386
|
if (typeof body !== "object" || body === null) return null;
|
|
387
|
+
const responsesText = extractResponsesContent(body);
|
|
388
|
+
if (responsesText !== null) return responsesText;
|
|
339
389
|
const choices = body.choices;
|
|
340
390
|
if (!Array.isArray(choices) || choices.length === 0) return null;
|
|
341
391
|
const first = choices[0];
|
|
342
392
|
const content = first?.message?.content;
|
|
343
393
|
return typeof content === "string" ? content : null;
|
|
344
394
|
}
|
|
395
|
+
function extractResponsesContent(body) {
|
|
396
|
+
const root = asRecord(body);
|
|
397
|
+
if (!root) return null;
|
|
398
|
+
if (typeof root.output_text === "string" && root.output_text !== "") return root.output_text;
|
|
399
|
+
if (!Array.isArray(root.output)) return null;
|
|
400
|
+
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("");
|
|
401
|
+
return text;
|
|
402
|
+
}
|
|
345
403
|
|
|
346
404
|
export {
|
|
347
405
|
getLogger,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
notifyConsolidationFallback,
|
|
3
3
|
resolvePiiRedactor
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-JPLFOSB2.mjs";
|
|
5
5
|
import {
|
|
6
6
|
callPortalJsonCompletion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-H4G3DLDJ.mjs";
|
|
8
8
|
import "./chunk-3RPGXXPZ.mjs";
|
|
9
9
|
|
|
10
10
|
// src/lib/memory/consolidate.ts
|
package/dist/server/index.cjs
CHANGED
|
@@ -20611,6 +20611,23 @@ 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 responsesExtra(extra) {
|
|
20615
|
+
if (!extra) return {};
|
|
20616
|
+
const out = {};
|
|
20617
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
20618
|
+
const target = CHAT_TO_RESPONSES_FIELDS[key] ?? key;
|
|
20619
|
+
if (target !== key && target in extra) continue;
|
|
20620
|
+
out[target] = value;
|
|
20621
|
+
}
|
|
20622
|
+
return out;
|
|
20623
|
+
}
|
|
20624
|
+
function assertTransportMatchesEndpoint(transport, endpoint) {
|
|
20625
|
+
const foreign = FOREIGN_ENDPOINT_SUFFIX[transport];
|
|
20626
|
+
if (!endpoint.endsWith(foreign)) return;
|
|
20627
|
+
throw new Error(
|
|
20628
|
+
`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.`
|
|
20629
|
+
);
|
|
20630
|
+
}
|
|
20614
20631
|
function isRetryableStatus(status) {
|
|
20615
20632
|
return status >= 500 || RETRYABLE_HTTP.has(status);
|
|
20616
20633
|
}
|
|
@@ -20651,13 +20668,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
20651
20668
|
}
|
|
20652
20669
|
async function callPortalJsonCompletion(req) {
|
|
20653
20670
|
const log = getLogger();
|
|
20654
|
-
let endpoint = "/api/v1/chat/completions";
|
|
20671
|
+
let endpoint = req.transport === "responses" ? "/api/v1/responses" : "/api/v1/chat/completions";
|
|
20655
20672
|
if (req.endpointOverride !== void 0) {
|
|
20656
20673
|
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
20657
20674
|
if (!overrideValidation.valid) {
|
|
20658
20675
|
throw new Error(overrideValidation.message);
|
|
20659
20676
|
}
|
|
20660
20677
|
endpoint = overrideValidation.endpoint;
|
|
20678
|
+
assertTransportMatchesEndpoint(req.transport ?? "chat", endpoint);
|
|
20661
20679
|
}
|
|
20662
20680
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
20663
20681
|
const startedAt = Date.now();
|
|
@@ -20719,8 +20737,8 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
20719
20737
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
20720
20738
|
if (authHeaders === null)
|
|
20721
20739
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
20722
|
-
const
|
|
20723
|
-
const prefill =
|
|
20740
|
+
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
20741
|
+
const prefill = usesPrefill ? "{" : "";
|
|
20724
20742
|
const messages = [
|
|
20725
20743
|
// Every caller of this helper is a first-party BACKGROUND op (fact extraction,
|
|
20726
20744
|
// topic sweep, consolidation, classifiers, graph traversal, query
|
|
@@ -20739,13 +20757,34 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
20739
20757
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
20740
20758
|
const controller = new AbortController();
|
|
20741
20759
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
20742
|
-
const requestBody = {
|
|
20760
|
+
const requestBody = req.transport === "responses" ? {
|
|
20761
|
+
model: req.model,
|
|
20762
|
+
// Same system+user pair under the Responses-API field name. No prefill
|
|
20763
|
+
// entry to strip: `usesPrefill` is false on this transport, so it was
|
|
20764
|
+
// never pushed and the response-side restore is disarmed with it. An
|
|
20765
|
+
// earlier version pushed it and sliced it back off here, which left
|
|
20766
|
+
// `prefill` truthy and the restore still armed — the fix belonged at
|
|
20767
|
+
// the decision, not at the two symptoms.
|
|
20768
|
+
input: messages,
|
|
20769
|
+
...req.reasoning && { reasoning: req.reasoning },
|
|
20770
|
+
// NO response_format. The Responses API spells structured output
|
|
20771
|
+
// differently (`text.format`), and it is unverified against this
|
|
20772
|
+
// portal — so this transport relies on the same strict-JSON system
|
|
20773
|
+
// prompt plus `extractJsonCandidate` that every response_format-
|
|
20774
|
+
// rejecting model already relies on. Verified end to end on dev:
|
|
20775
|
+
// luna returns clean parseable JSON here without it. Add the field
|
|
20776
|
+
// only with a per-provider check, exactly as RESPONSE_FORMAT_OK was
|
|
20777
|
+
// earned.
|
|
20778
|
+
...responsesExtra(req.extra)
|
|
20779
|
+
} : {
|
|
20743
20780
|
model: req.model,
|
|
20744
20781
|
messages,
|
|
20745
20782
|
...supportsJsonObjectFormat && { response_format: { type: "json_object" } },
|
|
20746
20783
|
...req.extra
|
|
20747
20784
|
};
|
|
20748
|
-
if (!supportsJsonObjectFormat)
|
|
20785
|
+
if (req.transport === "responses" || !supportsJsonObjectFormat) {
|
|
20786
|
+
delete requestBody.response_format;
|
|
20787
|
+
}
|
|
20749
20788
|
let response;
|
|
20750
20789
|
try {
|
|
20751
20790
|
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
@@ -20875,13 +20914,15 @@ function logPortalUsage(body, tag) {
|
|
|
20875
20914
|
const root = asRecord(body);
|
|
20876
20915
|
if (!root) return;
|
|
20877
20916
|
const usage = asRecord(root.usage);
|
|
20878
|
-
const promptTokens = asCount(usage?.prompt_tokens);
|
|
20879
|
-
const completionTokens = asCount(usage?.completion_tokens);
|
|
20917
|
+
const promptTokens = asCount(usage?.prompt_tokens) ?? asCount(usage?.input_tokens);
|
|
20918
|
+
const completionTokens = asCount(usage?.completion_tokens) ?? asCount(usage?.output_tokens);
|
|
20880
20919
|
if (promptTokens === void 0 && completionTokens === void 0) return;
|
|
20881
|
-
const cachedTokens = asCount(asRecord(root.portal)?.cached_tokens) ?? asCount(asRecord(usage?.prompt_tokens_details)?.cached_tokens) ?? 0;
|
|
20920
|
+
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;
|
|
20921
|
+
const reasoningTokens = asCount(asRecord(usage?.output_tokens_details)?.reasoning_tokens) ?? asCount(asRecord(usage?.completion_tokens_details)?.reasoning_tokens);
|
|
20882
20922
|
const parts = [];
|
|
20883
20923
|
if (promptTokens !== void 0) parts.push(`prompt=${promptTokens}`);
|
|
20884
20924
|
if (completionTokens !== void 0) parts.push(`completion=${completionTokens}`);
|
|
20925
|
+
if (reasoningTokens !== void 0) parts.push(`reasoning=${reasoningTokens}`);
|
|
20885
20926
|
parts.push(`cached=${cachedTokens}`);
|
|
20886
20927
|
getLogger().debug(`[${tag}] usage ${parts.join(" ")}`);
|
|
20887
20928
|
} catch {
|
|
@@ -20889,13 +20930,23 @@ function logPortalUsage(body, tag) {
|
|
|
20889
20930
|
}
|
|
20890
20931
|
function extractCompletionContent(body) {
|
|
20891
20932
|
if (typeof body !== "object" || body === null) return null;
|
|
20933
|
+
const responsesText = extractResponsesContent(body);
|
|
20934
|
+
if (responsesText !== null) return responsesText;
|
|
20892
20935
|
const choices = body.choices;
|
|
20893
20936
|
if (!Array.isArray(choices) || choices.length === 0) return null;
|
|
20894
20937
|
const first = choices[0];
|
|
20895
20938
|
const content = first?.message?.content;
|
|
20896
20939
|
return typeof content === "string" ? content : null;
|
|
20897
20940
|
}
|
|
20898
|
-
|
|
20941
|
+
function extractResponsesContent(body) {
|
|
20942
|
+
const root = asRecord(body);
|
|
20943
|
+
if (!root) return null;
|
|
20944
|
+
if (typeof root.output_text === "string" && root.output_text !== "") return root.output_text;
|
|
20945
|
+
if (!Array.isArray(root.output)) return null;
|
|
20946
|
+
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
|
+
return text12;
|
|
20948
|
+
}
|
|
20949
|
+
var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
|
|
20899
20950
|
var init_portalLlm = __esm({
|
|
20900
20951
|
"src/lib/memory/portalLlm.ts"() {
|
|
20901
20952
|
"use strict";
|
|
@@ -20907,6 +20958,13 @@ var init_portalLlm = __esm({
|
|
|
20907
20958
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
20908
20959
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
20909
20960
|
JSON_CONTRACT_REMINDER = "Output ONLY the strict JSON object requested. No prose, no explanation, no markdown.";
|
|
20961
|
+
CHAT_TO_RESPONSES_FIELDS = {
|
|
20962
|
+
max_completion_tokens: "max_output_tokens"
|
|
20963
|
+
};
|
|
20964
|
+
FOREIGN_ENDPOINT_SUFFIX = {
|
|
20965
|
+
chat: "/responses",
|
|
20966
|
+
responses: "/chat/completions"
|
|
20967
|
+
};
|
|
20910
20968
|
RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
20911
20969
|
}
|
|
20912
20970
|
});
|
|
@@ -27426,7 +27484,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
27426
27484
|
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
|
|
27427
27485
|
record._raw.id = row.memoryId;
|
|
27428
27486
|
record._setRaw("content", content);
|
|
27429
|
-
record._setRaw("scope", "
|
|
27487
|
+
record._setRaw("scope", "shared");
|
|
27430
27488
|
record._setRaw("folder_id", null);
|
|
27431
27489
|
record._setRaw("user_id", ctx.userId ?? null);
|
|
27432
27490
|
record._setRaw("is_deleted", false);
|
package/dist/server/index.d.mts
CHANGED
|
@@ -6253,15 +6253,26 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
6253
6253
|
}>;
|
|
6254
6254
|
|
|
6255
6255
|
/**
|
|
6256
|
-
*
|
|
6257
|
-
*
|
|
6258
|
-
*
|
|
6259
|
-
*
|
|
6256
|
+
* LEGACY. This column no longer decides anything.
|
|
6257
|
+
*
|
|
6258
|
+
* `scope === 'shared'` is now the single publication axis: it means the memory
|
|
6259
|
+
* is on the People Nearby profile, its text goes to the nearby server, and it
|
|
6260
|
+
* may inform what strangers see. `scope: 'private'` means it is not. There is
|
|
6261
|
+
* no second control, and scope no longer gates model access either — every
|
|
6262
|
+
* model tier reads every memory. Do NOT reason about publication from this
|
|
6263
|
+
* type; read `scope`.
|
|
6264
|
+
*
|
|
6265
|
+
* The column survives in the schema and is still stamped on writes so that
|
|
6266
|
+
* stored rows stay readable by builds that predate the change. Nothing on a
|
|
6267
|
+
* current build reads it to make a decision.
|
|
6268
|
+
*
|
|
6269
|
+
* Values, kept for tolerance of already-stored data:
|
|
6270
|
+
* - `private`: local-only (a null column reads as private)
|
|
6271
|
+
* - `public`: the row was published
|
|
6260
6272
|
*
|
|
6261
6273
|
* TWO TIERS ONLY (decided 2026-07-27). An earlier design had a middle
|
|
6262
6274
|
* `matchable` tier that published a memory's embedding while keeping its text
|
|
6263
|
-
* on-device; it was dropped
|
|
6264
|
-
* published with its content. Any unrecognised stored value — including a
|
|
6275
|
+
* on-device; it was dropped. Any unrecognised stored value — including a
|
|
6265
6276
|
* `matchable` row written by a pre-release build — reads as `private`, which is
|
|
6266
6277
|
* the fail-safe direction: it un-publishes rather than exposes.
|
|
6267
6278
|
*/
|
|
@@ -6853,12 +6864,16 @@ declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext,
|
|
|
6853
6864
|
* candidate to be reconciled against the vault — it is an already-decided
|
|
6854
6865
|
* fact the server has published.
|
|
6855
6866
|
*
|
|
6856
|
-
* The rows are written `
|
|
6857
|
-
*
|
|
6858
|
-
*
|
|
6859
|
-
*
|
|
6860
|
-
*
|
|
6861
|
-
*
|
|
6867
|
+
* The rows are written `scope: "shared"` because they genuinely ARE published.
|
|
6868
|
+
* `scope === 'shared'` is the publication axis — the single one. The reconciler
|
|
6869
|
+
* reads local scope as the user's intent, and it builds its `local` set from a
|
|
6870
|
+
* vault read narrowed to `{scopes: ['shared']}`. A row stamped anything else
|
|
6871
|
+
* never enters that read, so it is never adopted into the publish ledger, and
|
|
6872
|
+
* `toRevoke` is computed only over ids the ledger holds. The user's off-toggle
|
|
6873
|
+
* would then do nothing server-side while nearby kept serving the memory. The
|
|
6874
|
+
* `visibility` column is legacy: nothing reads it any more. They carry
|
|
6875
|
+
* `source: SOURCE_PHOTO`, which is what exempts them from decay's auto-archive;
|
|
6876
|
+
* see the note there for why archiving one would silently unpublish it.
|
|
6862
6877
|
*
|
|
6863
6878
|
* No embedding is computed here. `searchTool`'s un-embedded lane embeds any row
|
|
6864
6879
|
* lacking a vector at search time, uses it in that same search and persists it
|
|
@@ -6906,6 +6921,29 @@ interface PhotoIngestResult {
|
|
|
6906
6921
|
* class of bug as publishing a version the user has since changed. Re-ingesting
|
|
6907
6922
|
* changed text is a follow-up that needs a merge decision, not a clobber.
|
|
6908
6923
|
*
|
|
6924
|
+
* That skip is also why this op does NOT repair a row an older build stamped
|
|
6925
|
+
* `scope: "private"`. Such a row is present, so ingest leaves it alone, and it
|
|
6926
|
+
* stays outside the published-set read. The user's switch cannot revoke it.
|
|
6927
|
+
* Repair belongs in a one-time pass at upgrade. Do not add it here, for two
|
|
6928
|
+
* reasons:
|
|
6929
|
+
*
|
|
6930
|
+
* - **The two states are indistinguishable from this op.** After this build a
|
|
6931
|
+
* `photo:` row with `scope: "private"` is also exactly what the user's own
|
|
6932
|
+
* off-toggle produces. The toggle calls `updateVaultMemoryOp`, which writes
|
|
6933
|
+
* `scope` and never touches `visibility`, so the mis-stamped row and the
|
|
6934
|
+
* turned-off row carry identical columns. No test here can tell them apart.
|
|
6935
|
+
*
|
|
6936
|
+
* - **A re-stamp here would revert the off-toggle.** The pass runs ingest
|
|
6937
|
+
* BEFORE it reads the vault, so a row re-stamped `shared` re-enters the
|
|
6938
|
+
* desired set on that same pass and never reaches `toRevoke`. The switch
|
|
6939
|
+
* would spring back to "on" and nearby would keep serving the memory. That
|
|
6940
|
+
* is worse than the bug it repairs.
|
|
6941
|
+
*
|
|
6942
|
+
* A one-time pass does not have the ambiguity. Before this build the switch
|
|
6943
|
+
* already read "off" for these rows, because it reads `scope`, so no user can
|
|
6944
|
+
* have turned one off. Every `private` photo row at that instant came from the
|
|
6945
|
+
* old stamp.
|
|
6946
|
+
*
|
|
6909
6947
|
* Non-`photo:` ids are ignored: everything else in the published set is a
|
|
6910
6948
|
* client-published memory that by definition already lives in this vault (or in
|
|
6911
6949
|
* another device's, which is not ours to recreate).
|
package/dist/server/index.d.ts
CHANGED
|
@@ -6253,15 +6253,26 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
6253
6253
|
}>;
|
|
6254
6254
|
|
|
6255
6255
|
/**
|
|
6256
|
-
*
|
|
6257
|
-
*
|
|
6258
|
-
*
|
|
6259
|
-
*
|
|
6256
|
+
* LEGACY. This column no longer decides anything.
|
|
6257
|
+
*
|
|
6258
|
+
* `scope === 'shared'` is now the single publication axis: it means the memory
|
|
6259
|
+
* is on the People Nearby profile, its text goes to the nearby server, and it
|
|
6260
|
+
* may inform what strangers see. `scope: 'private'` means it is not. There is
|
|
6261
|
+
* no second control, and scope no longer gates model access either — every
|
|
6262
|
+
* model tier reads every memory. Do NOT reason about publication from this
|
|
6263
|
+
* type; read `scope`.
|
|
6264
|
+
*
|
|
6265
|
+
* The column survives in the schema and is still stamped on writes so that
|
|
6266
|
+
* stored rows stay readable by builds that predate the change. Nothing on a
|
|
6267
|
+
* current build reads it to make a decision.
|
|
6268
|
+
*
|
|
6269
|
+
* Values, kept for tolerance of already-stored data:
|
|
6270
|
+
* - `private`: local-only (a null column reads as private)
|
|
6271
|
+
* - `public`: the row was published
|
|
6260
6272
|
*
|
|
6261
6273
|
* TWO TIERS ONLY (decided 2026-07-27). An earlier design had a middle
|
|
6262
6274
|
* `matchable` tier that published a memory's embedding while keeping its text
|
|
6263
|
-
* on-device; it was dropped
|
|
6264
|
-
* published with its content. Any unrecognised stored value — including a
|
|
6275
|
+
* on-device; it was dropped. Any unrecognised stored value — including a
|
|
6265
6276
|
* `matchable` row written by a pre-release build — reads as `private`, which is
|
|
6266
6277
|
* the fail-safe direction: it un-publishes rather than exposes.
|
|
6267
6278
|
*/
|
|
@@ -6853,12 +6864,16 @@ declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext,
|
|
|
6853
6864
|
* candidate to be reconciled against the vault — it is an already-decided
|
|
6854
6865
|
* fact the server has published.
|
|
6855
6866
|
*
|
|
6856
|
-
* The rows are written `
|
|
6857
|
-
*
|
|
6858
|
-
*
|
|
6859
|
-
*
|
|
6860
|
-
*
|
|
6861
|
-
*
|
|
6867
|
+
* The rows are written `scope: "shared"` because they genuinely ARE published.
|
|
6868
|
+
* `scope === 'shared'` is the publication axis — the single one. The reconciler
|
|
6869
|
+
* reads local scope as the user's intent, and it builds its `local` set from a
|
|
6870
|
+
* vault read narrowed to `{scopes: ['shared']}`. A row stamped anything else
|
|
6871
|
+
* never enters that read, so it is never adopted into the publish ledger, and
|
|
6872
|
+
* `toRevoke` is computed only over ids the ledger holds. The user's off-toggle
|
|
6873
|
+
* would then do nothing server-side while nearby kept serving the memory. The
|
|
6874
|
+
* `visibility` column is legacy: nothing reads it any more. They carry
|
|
6875
|
+
* `source: SOURCE_PHOTO`, which is what exempts them from decay's auto-archive;
|
|
6876
|
+
* see the note there for why archiving one would silently unpublish it.
|
|
6862
6877
|
*
|
|
6863
6878
|
* No embedding is computed here. `searchTool`'s un-embedded lane embeds any row
|
|
6864
6879
|
* lacking a vector at search time, uses it in that same search and persists it
|
|
@@ -6906,6 +6921,29 @@ interface PhotoIngestResult {
|
|
|
6906
6921
|
* class of bug as publishing a version the user has since changed. Re-ingesting
|
|
6907
6922
|
* changed text is a follow-up that needs a merge decision, not a clobber.
|
|
6908
6923
|
*
|
|
6924
|
+
* That skip is also why this op does NOT repair a row an older build stamped
|
|
6925
|
+
* `scope: "private"`. Such a row is present, so ingest leaves it alone, and it
|
|
6926
|
+
* stays outside the published-set read. The user's switch cannot revoke it.
|
|
6927
|
+
* Repair belongs in a one-time pass at upgrade. Do not add it here, for two
|
|
6928
|
+
* reasons:
|
|
6929
|
+
*
|
|
6930
|
+
* - **The two states are indistinguishable from this op.** After this build a
|
|
6931
|
+
* `photo:` row with `scope: "private"` is also exactly what the user's own
|
|
6932
|
+
* off-toggle produces. The toggle calls `updateVaultMemoryOp`, which writes
|
|
6933
|
+
* `scope` and never touches `visibility`, so the mis-stamped row and the
|
|
6934
|
+
* turned-off row carry identical columns. No test here can tell them apart.
|
|
6935
|
+
*
|
|
6936
|
+
* - **A re-stamp here would revert the off-toggle.** The pass runs ingest
|
|
6937
|
+
* BEFORE it reads the vault, so a row re-stamped `shared` re-enters the
|
|
6938
|
+
* desired set on that same pass and never reaches `toRevoke`. The switch
|
|
6939
|
+
* would spring back to "on" and nearby would keep serving the memory. That
|
|
6940
|
+
* is worse than the bug it repairs.
|
|
6941
|
+
*
|
|
6942
|
+
* A one-time pass does not have the ambiguity. Before this build the switch
|
|
6943
|
+
* already read "off" for these rows, because it reads `scope`, so no user can
|
|
6944
|
+
* have turned one off. Every `private` photo row at that instant came from the
|
|
6945
|
+
* old stamp.
|
|
6946
|
+
*
|
|
6909
6947
|
* Non-`photo:` ids are ignored: everything else in the published set is a
|
|
6910
6948
|
* client-published memory that by definition already lives in this vault (or in
|
|
6911
6949
|
* another device's, which is not ours to recreate).
|
package/dist/server/index.mjs
CHANGED
|
@@ -141,12 +141,12 @@ import {
|
|
|
141
141
|
updateVaultMemoryOp,
|
|
142
142
|
upsertMessageOp,
|
|
143
143
|
vaultMemoryToStored
|
|
144
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-2QFK4L7Y.mjs";
|
|
145
145
|
import {
|
|
146
146
|
createStreamingDeAnonymizer,
|
|
147
147
|
notifyConsolidationFallback,
|
|
148
148
|
resolvePiiRedactor
|
|
149
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-JPLFOSB2.mjs";
|
|
150
150
|
import {
|
|
151
151
|
INTERNAL_FLOW_MARKER,
|
|
152
152
|
callPortalJsonCompletion,
|
|
@@ -157,7 +157,7 @@ import {
|
|
|
157
157
|
taskTypeHeader,
|
|
158
158
|
validateEndpointOverride,
|
|
159
159
|
withInternalFlowMarker
|
|
160
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-H4G3DLDJ.mjs";
|
|
161
161
|
import {
|
|
162
162
|
BASE_URL,
|
|
163
163
|
__commonJS,
|
|
@@ -3736,7 +3736,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
3736
3736
|
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
|
|
3737
3737
|
record._raw.id = row.memoryId;
|
|
3738
3738
|
record._setRaw("content", content);
|
|
3739
|
-
record._setRaw("scope", "
|
|
3739
|
+
record._setRaw("scope", "shared");
|
|
3740
3740
|
record._setRaw("folder_id", null);
|
|
3741
3741
|
record._setRaw("user_id", ctx.userId ?? null);
|
|
3742
3742
|
record._setRaw("is_deleted", false);
|
|
@@ -5700,7 +5700,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
5700
5700
|
content: m.content,
|
|
5701
5701
|
similarity: m.similarity
|
|
5702
5702
|
}));
|
|
5703
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
5703
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-CMMDTZ37.mjs");
|
|
5704
5704
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
5705
5705
|
if (decision.action === "create") return null;
|
|
5706
5706
|
if (decision.action === "supersede" && decision.content) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anuma/sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.15.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"homepage": "https://github.com/anuma-ai/sdk#readme",
|
|
161
161
|
"packageManager": "pnpm@10.23.0",
|
|
162
162
|
"dependencies": {
|
|
163
|
-
"@anuma/portal": "1.0.0-next.
|
|
163
|
+
"@anuma/portal": "1.0.0-next.20260815023541",
|
|
164
164
|
"@babel/parser": "^7.29.2",
|
|
165
165
|
"@babel/types": "^7.29.0",
|
|
166
166
|
"ai": "6.0.202",
|