@anuma/sdk 3.6.3 → 3.8.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/expo/{chunk-FKACNV6X.mjs → chunk-AAB7OG7Q.mjs} +2 -2
- package/dist/expo/{chunk-DFVCS3QQ.mjs → chunk-BOY27A2C.mjs} +30 -3
- package/dist/expo/{consolidate-3QQPUWD6.mjs → consolidate-HKN32P5W.mjs} +25 -11
- package/dist/expo/index.cjs +107 -42
- package/dist/expo/index.d.mts +9 -0
- package/dist/expo/index.d.ts +9 -0
- package/dist/expo/index.mjs +51 -33
- package/dist/{react/recall-JOLS3V4B.mjs → expo/recall-YVU7OSSJ.mjs} +2 -2
- package/dist/react/{chunk-ZGMHRWOR.mjs → chunk-3VPEZDYL.mjs} +2 -2
- package/dist/react/{chunk-DFVCS3QQ.mjs → chunk-BOY27A2C.mjs} +30 -3
- package/dist/react/{consolidate-3MXZV3G7.mjs → consolidate-7UUX56GM.mjs} +25 -11
- package/dist/react/index.cjs +107 -42
- package/dist/react/index.d.mts +9 -0
- package/dist/react/index.d.ts +9 -0
- package/dist/react/index.mjs +51 -33
- package/dist/{expo/recall-VZHV7ILE.mjs → react/recall-Z7BWJ67X.mjs} +2 -2
- package/dist/server/{chunk-66UWDXS3.mjs → chunk-LSKFJNLF.mjs} +2 -2
- package/dist/server/{chunk-AHJT66EO.mjs → chunk-MIXEASUP.mjs} +30 -3
- package/dist/server/{consolidate-CN2GQV4D.mjs → consolidate-BKLNVH5Y.mjs} +25 -11
- package/dist/server/index.cjs +107 -42
- package/dist/server/index.d.mts +36 -0
- package/dist/server/index.d.ts +36 -0
- package/dist/server/index.mjs +51 -33
- package/dist/server/{recall-UTVH2XPK.mjs → recall-XEOLXA6P.mjs} +2 -2
- package/package.json +3 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callPortalJsonCompletion,
|
|
3
3
|
getLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BOY27A2C.mjs";
|
|
5
5
|
import {
|
|
6
6
|
BASE_URL,
|
|
7
7
|
createClientConfig
|
|
@@ -5363,7 +5363,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
5363
5363
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
5364
5364
|
);
|
|
5365
5365
|
}
|
|
5366
|
-
const { recall: recall2 } = await import("./recall-
|
|
5366
|
+
const { recall: recall2 } = await import("./recall-YVU7OSSJ.mjs");
|
|
5367
5367
|
const result = await recall2(
|
|
5368
5368
|
query,
|
|
5369
5369
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
|
@@ -27,6 +27,24 @@ function getLogger() {
|
|
|
27
27
|
return currentLogger;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// src/lib/chat/endpointOverride.ts
|
|
31
|
+
function validateEndpointOverride(override) {
|
|
32
|
+
const trimmed = override.trim();
|
|
33
|
+
if (trimmed === "") {
|
|
34
|
+
return {
|
|
35
|
+
valid: false,
|
|
36
|
+
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
40
|
+
return {
|
|
41
|
+
valid: false,
|
|
42
|
+
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
46
|
+
}
|
|
47
|
+
|
|
30
48
|
// src/lib/memory/portalLlm.ts
|
|
31
49
|
function defaultBaseUrl() {
|
|
32
50
|
return typeof process !== "undefined" && process.env?.ANUMA_PORTAL_BASE_URL || BASE_URL;
|
|
@@ -78,6 +96,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
78
96
|
}
|
|
79
97
|
async function callPortalJsonCompletion(req) {
|
|
80
98
|
const log = getLogger();
|
|
99
|
+
let endpoint = "/api/v1/chat/completions";
|
|
100
|
+
if (req.endpointOverride !== void 0) {
|
|
101
|
+
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
102
|
+
if (!overrideValidation.valid) {
|
|
103
|
+
throw new Error(overrideValidation.message);
|
|
104
|
+
}
|
|
105
|
+
endpoint = overrideValidation.endpoint;
|
|
106
|
+
}
|
|
81
107
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
82
108
|
const startedAt = Date.now();
|
|
83
109
|
const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
|
|
@@ -93,7 +119,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
93
119
|
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
94
120
|
)
|
|
95
121
|
} : req;
|
|
96
|
-
const outcome = await attemptPortalJson(attemptReq);
|
|
122
|
+
const outcome = await attemptPortalJson(attemptReq, endpoint);
|
|
97
123
|
if (outcome.kind === "ok") return outcome.value;
|
|
98
124
|
if (outcome.kind === "terminal") {
|
|
99
125
|
log.warn(`[${req.tag}] ${outcome.reason}`);
|
|
@@ -116,7 +142,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
116
142
|
}
|
|
117
143
|
return null;
|
|
118
144
|
}
|
|
119
|
-
async function attemptPortalJson(req) {
|
|
145
|
+
async function attemptPortalJson(req, endpoint) {
|
|
120
146
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
121
147
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
122
148
|
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
@@ -141,7 +167,7 @@ async function attemptPortalJson(req) {
|
|
|
141
167
|
if (!supportsJsonObjectFormat) delete requestBody.response_format;
|
|
142
168
|
let response;
|
|
143
169
|
try {
|
|
144
|
-
response = await fetchImpl(`${baseUrl}
|
|
170
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
145
171
|
method: "POST",
|
|
146
172
|
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
147
173
|
body: JSON.stringify(requestBody),
|
|
@@ -239,6 +265,7 @@ export {
|
|
|
239
265
|
noopLogger,
|
|
240
266
|
setLogger,
|
|
241
267
|
getLogger,
|
|
268
|
+
validateEndpointOverride,
|
|
242
269
|
supportsResponseFormat,
|
|
243
270
|
resolvePortalAuthHeaders,
|
|
244
271
|
callPortalJsonCompletion,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
callPortalJsonCompletion,
|
|
6
6
|
getLogger
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BOY27A2C.mjs";
|
|
8
8
|
import "./chunk-GYKJOWEO.mjs";
|
|
9
9
|
|
|
10
10
|
// src/lib/memory/consolidate.ts
|
|
@@ -19,7 +19,7 @@ Decide one of four actions:
|
|
|
19
19
|
|
|
20
20
|
- "create": the new memory describes a distinct fact not covered by any existing memory. Write it as new.
|
|
21
21
|
- "update": the new memory describes the SAME FACET as exactly one existing memory and is COMPATIBLE with it \u2014 it adds detail, fixes an incomplete value, or rephrases the same still-true fact. Return targetId of that existing memory + the consolidated content (richest version of the two).
|
|
22
|
-
- "supersede": the new memory REPLACES a standing fact whose value has CHANGED and is now INCOMPATIBLE with an existing memory \u2014 the old fact was true before but is false now (a state change). Return
|
|
22
|
+
- "supersede": the new memory REPLACES a standing fact whose value has CHANGED and is now INCOMPATIBLE with an existing memory \u2014 the old fact was true before but is false now (a state change). Return "targetIds": an array of the ids of EVERY existing candidate that describes the SAME standing attribute now being changed \u2014 retire ALL stale duplicates of the old value, not just one (the candidate list may contain several paraphrases of the same old fact) + content = the NEW fact. The old memories are kept as history, not overwritten or deleted; do not re-state them.
|
|
23
23
|
- "noop": the new memory is already fully captured by an existing memory \u2014 same facet, no new information. Skip the write.
|
|
24
24
|
|
|
25
25
|
RULES (carry these strictly):
|
|
@@ -35,14 +35,15 @@ RULES (carry these strictly):
|
|
|
35
35
|
OUTPUT \u2014 strict JSON, no prose:
|
|
36
36
|
{
|
|
37
37
|
"action": "create" | "update" | "supersede" | "noop",
|
|
38
|
-
"targetId": "<existing memory id \u2014 required for update/
|
|
38
|
+
"targetId": "<existing memory id \u2014 required for update/noop, omit for create/supersede>",
|
|
39
|
+
"targetIds": ["<id>", ...],
|
|
39
40
|
"content": "<content \u2014 required for create/update/supersede, omit for noop>"
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
For "create": content is the new memory verbatim (or a slight refinement).
|
|
43
|
-
For "update": content is the merged richest-version, \u226480 words.
|
|
44
|
-
For "supersede": content is the NEW fact only (\u226480 words);
|
|
45
|
-
For "noop": no content (existing memory is already correct).`;
|
|
43
|
+
For "create": content is the new memory verbatim (or a slight refinement); omit targetId/targetIds.
|
|
44
|
+
For "update": content is the merged richest-version, \u226480 words; targetId is the single memory to update.
|
|
45
|
+
For "supersede": content is the NEW fact only (\u226480 words); "targetIds" lists EVERY stale memory being retired (all candidates describing the same now-changed attribute).
|
|
46
|
+
For "noop": no content (existing memory is already correct); targetId is that memory.`;
|
|
46
47
|
async function consolidateMemory(newContent, candidates, options) {
|
|
47
48
|
const fallback = {
|
|
48
49
|
action: "create",
|
|
@@ -123,14 +124,27 @@ function validate(parsed, newContent, validIds) {
|
|
|
123
124
|
const c2 = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
124
125
|
return { action: "create", content: c2.length > 0 ? c2 : newContent };
|
|
125
126
|
}
|
|
126
|
-
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
127
|
-
if (!targetId || !validIds.has(targetId)) return null;
|
|
128
127
|
if (action === "noop") {
|
|
129
|
-
|
|
128
|
+
const targetId2 = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
129
|
+
if (!targetId2 || !validIds.has(targetId2)) return null;
|
|
130
|
+
return { action: "noop", targetId: targetId2 };
|
|
130
131
|
}
|
|
131
132
|
const c = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
132
133
|
if (c.length === 0) return null;
|
|
133
|
-
|
|
134
|
+
if (action === "supersede") {
|
|
135
|
+
const rawIds = [
|
|
136
|
+
...Array.isArray(obj.targetIds) ? obj.targetIds : [],
|
|
137
|
+
...typeof obj.targetId === "string" ? [obj.targetId] : []
|
|
138
|
+
];
|
|
139
|
+
const targetIds = [
|
|
140
|
+
...new Set(rawIds.filter((id) => typeof id === "string" && validIds.has(id)))
|
|
141
|
+
];
|
|
142
|
+
if (targetIds.length === 0) return null;
|
|
143
|
+
return { action: "supersede", targetId: targetIds[0], targetIds, content: c };
|
|
144
|
+
}
|
|
145
|
+
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
146
|
+
if (!targetId || !validIds.has(targetId)) return null;
|
|
147
|
+
return { action: "update", targetId, content: c };
|
|
134
148
|
}
|
|
135
149
|
export {
|
|
136
150
|
consolidateMemory
|
package/dist/expo/index.cjs
CHANGED
|
@@ -3976,6 +3976,29 @@ var init_redactor = __esm({
|
|
|
3976
3976
|
}
|
|
3977
3977
|
});
|
|
3978
3978
|
|
|
3979
|
+
// src/lib/chat/endpointOverride.ts
|
|
3980
|
+
function validateEndpointOverride(override) {
|
|
3981
|
+
const trimmed = override.trim();
|
|
3982
|
+
if (trimmed === "") {
|
|
3983
|
+
return {
|
|
3984
|
+
valid: false,
|
|
3985
|
+
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
3986
|
+
};
|
|
3987
|
+
}
|
|
3988
|
+
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
3989
|
+
return {
|
|
3990
|
+
valid: false,
|
|
3991
|
+
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
3995
|
+
}
|
|
3996
|
+
var init_endpointOverride = __esm({
|
|
3997
|
+
"src/lib/chat/endpointOverride.ts"() {
|
|
3998
|
+
"use strict";
|
|
3999
|
+
}
|
|
4000
|
+
});
|
|
4001
|
+
|
|
3979
4002
|
// src/lib/db/entities/types.ts
|
|
3980
4003
|
function normalizeEntityName(name) {
|
|
3981
4004
|
return name.trim().toLowerCase();
|
|
@@ -5026,6 +5049,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
5026
5049
|
}
|
|
5027
5050
|
async function callPortalJsonCompletion(req) {
|
|
5028
5051
|
const log = getLogger();
|
|
5052
|
+
let endpoint = "/api/v1/chat/completions";
|
|
5053
|
+
if (req.endpointOverride !== void 0) {
|
|
5054
|
+
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
5055
|
+
if (!overrideValidation.valid) {
|
|
5056
|
+
throw new Error(overrideValidation.message);
|
|
5057
|
+
}
|
|
5058
|
+
endpoint = overrideValidation.endpoint;
|
|
5059
|
+
}
|
|
5029
5060
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
5030
5061
|
const startedAt = Date.now();
|
|
5031
5062
|
const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
|
|
@@ -5041,7 +5072,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
5041
5072
|
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
5042
5073
|
)
|
|
5043
5074
|
} : req;
|
|
5044
|
-
const outcome = await attemptPortalJson(attemptReq);
|
|
5075
|
+
const outcome = await attemptPortalJson(attemptReq, endpoint);
|
|
5045
5076
|
if (outcome.kind === "ok") return outcome.value;
|
|
5046
5077
|
if (outcome.kind === "terminal") {
|
|
5047
5078
|
log.warn(`[${req.tag}] ${outcome.reason}`);
|
|
@@ -5064,7 +5095,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
5064
5095
|
}
|
|
5065
5096
|
return null;
|
|
5066
5097
|
}
|
|
5067
|
-
async function attemptPortalJson(req) {
|
|
5098
|
+
async function attemptPortalJson(req, endpoint) {
|
|
5068
5099
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
5069
5100
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
5070
5101
|
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
@@ -5089,7 +5120,7 @@ async function attemptPortalJson(req) {
|
|
|
5089
5120
|
if (!supportsJsonObjectFormat) delete requestBody.response_format;
|
|
5090
5121
|
let response;
|
|
5091
5122
|
try {
|
|
5092
|
-
response = await fetchImpl(`${baseUrl}
|
|
5123
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
5093
5124
|
method: "POST",
|
|
5094
5125
|
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
5095
5126
|
body: JSON.stringify(requestBody),
|
|
@@ -5186,6 +5217,7 @@ var init_portalLlm = __esm({
|
|
|
5186
5217
|
"src/lib/memory/portalLlm.ts"() {
|
|
5187
5218
|
"use strict";
|
|
5188
5219
|
init_clientConfig();
|
|
5220
|
+
init_endpointOverride();
|
|
5189
5221
|
init_logger();
|
|
5190
5222
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
5191
5223
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
@@ -7601,14 +7633,27 @@ function validate2(parsed, newContent, validIds) {
|
|
|
7601
7633
|
const c2 = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
7602
7634
|
return { action: "create", content: c2.length > 0 ? c2 : newContent };
|
|
7603
7635
|
}
|
|
7604
|
-
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7605
|
-
if (!targetId || !validIds.has(targetId)) return null;
|
|
7606
7636
|
if (action === "noop") {
|
|
7607
|
-
|
|
7637
|
+
const targetId2 = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7638
|
+
if (!targetId2 || !validIds.has(targetId2)) return null;
|
|
7639
|
+
return { action: "noop", targetId: targetId2 };
|
|
7608
7640
|
}
|
|
7609
7641
|
const c = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
7610
7642
|
if (c.length === 0) return null;
|
|
7611
|
-
|
|
7643
|
+
if (action === "supersede") {
|
|
7644
|
+
const rawIds = [
|
|
7645
|
+
...Array.isArray(obj.targetIds) ? obj.targetIds : [],
|
|
7646
|
+
...typeof obj.targetId === "string" ? [obj.targetId] : []
|
|
7647
|
+
];
|
|
7648
|
+
const targetIds = [
|
|
7649
|
+
...new Set(rawIds.filter((id) => typeof id === "string" && validIds.has(id)))
|
|
7650
|
+
];
|
|
7651
|
+
if (targetIds.length === 0) return null;
|
|
7652
|
+
return { action: "supersede", targetId: targetIds[0], targetIds, content: c };
|
|
7653
|
+
}
|
|
7654
|
+
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7655
|
+
if (!targetId || !validIds.has(targetId)) return null;
|
|
7656
|
+
return { action: "update", targetId, content: c };
|
|
7612
7657
|
}
|
|
7613
7658
|
var DEFAULT_MODEL3, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
|
|
7614
7659
|
var init_consolidate = __esm({
|
|
@@ -7628,7 +7673,7 @@ Decide one of four actions:
|
|
|
7628
7673
|
|
|
7629
7674
|
- "create": the new memory describes a distinct fact not covered by any existing memory. Write it as new.
|
|
7630
7675
|
- "update": the new memory describes the SAME FACET as exactly one existing memory and is COMPATIBLE with it \u2014 it adds detail, fixes an incomplete value, or rephrases the same still-true fact. Return targetId of that existing memory + the consolidated content (richest version of the two).
|
|
7631
|
-
- "supersede": the new memory REPLACES a standing fact whose value has CHANGED and is now INCOMPATIBLE with an existing memory \u2014 the old fact was true before but is false now (a state change). Return
|
|
7676
|
+
- "supersede": the new memory REPLACES a standing fact whose value has CHANGED and is now INCOMPATIBLE with an existing memory \u2014 the old fact was true before but is false now (a state change). Return "targetIds": an array of the ids of EVERY existing candidate that describes the SAME standing attribute now being changed \u2014 retire ALL stale duplicates of the old value, not just one (the candidate list may contain several paraphrases of the same old fact) + content = the NEW fact. The old memories are kept as history, not overwritten or deleted; do not re-state them.
|
|
7632
7677
|
- "noop": the new memory is already fully captured by an existing memory \u2014 same facet, no new information. Skip the write.
|
|
7633
7678
|
|
|
7634
7679
|
RULES (carry these strictly):
|
|
@@ -7644,14 +7689,15 @@ RULES (carry these strictly):
|
|
|
7644
7689
|
OUTPUT \u2014 strict JSON, no prose:
|
|
7645
7690
|
{
|
|
7646
7691
|
"action": "create" | "update" | "supersede" | "noop",
|
|
7647
|
-
"targetId": "<existing memory id \u2014 required for update/
|
|
7692
|
+
"targetId": "<existing memory id \u2014 required for update/noop, omit for create/supersede>",
|
|
7693
|
+
"targetIds": ["<id>", ...],
|
|
7648
7694
|
"content": "<content \u2014 required for create/update/supersede, omit for noop>"
|
|
7649
7695
|
}
|
|
7650
7696
|
|
|
7651
|
-
For "create": content is the new memory verbatim (or a slight refinement).
|
|
7652
|
-
For "update": content is the merged richest-version, \u226480 words.
|
|
7653
|
-
For "supersede": content is the NEW fact only (\u226480 words);
|
|
7654
|
-
For "noop": no content (existing memory is already correct).`;
|
|
7697
|
+
For "create": content is the new memory verbatim (or a slight refinement); omit targetId/targetIds.
|
|
7698
|
+
For "update": content is the merged richest-version, \u226480 words; targetId is the single memory to update.
|
|
7699
|
+
For "supersede": content is the NEW fact only (\u226480 words); "targetIds" lists EVERY stale memory being retired (all candidates describing the same now-changed attribute).
|
|
7700
|
+
For "noop": no content (existing memory is already correct); targetId is that memory.`;
|
|
7655
7701
|
}
|
|
7656
7702
|
});
|
|
7657
7703
|
|
|
@@ -8027,6 +8073,7 @@ init_serverSentEvents_gen();
|
|
|
8027
8073
|
init_clientConfig();
|
|
8028
8074
|
init_embeddings();
|
|
8029
8075
|
init_redactor();
|
|
8076
|
+
init_endpointOverride();
|
|
8030
8077
|
|
|
8031
8078
|
// src/lib/chat/runHooks.ts
|
|
8032
8079
|
function composeHooks(hooks) {
|
|
@@ -10206,22 +10253,6 @@ function linkAbortSignals(a, b) {
|
|
|
10206
10253
|
}
|
|
10207
10254
|
};
|
|
10208
10255
|
}
|
|
10209
|
-
function validateEndpointOverride(override) {
|
|
10210
|
-
const trimmed = override.trim();
|
|
10211
|
-
if (trimmed === "") {
|
|
10212
|
-
return {
|
|
10213
|
-
valid: false,
|
|
10214
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
10215
|
-
};
|
|
10216
|
-
}
|
|
10217
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
10218
|
-
return {
|
|
10219
|
-
valid: false,
|
|
10220
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
10221
|
-
};
|
|
10222
|
-
}
|
|
10223
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
10224
|
-
}
|
|
10225
10256
|
async function runToolLoop(options) {
|
|
10226
10257
|
const {
|
|
10227
10258
|
model,
|
|
@@ -13984,14 +14015,15 @@ init_portalLlm();
|
|
|
13984
14015
|
|
|
13985
14016
|
// src/lib/memory/retain.ts
|
|
13986
14017
|
init_operations3();
|
|
14018
|
+
init_logger();
|
|
13987
14019
|
init_constants();
|
|
13988
14020
|
init_embeddings();
|
|
13989
14021
|
init_vector();
|
|
13990
14022
|
init_searchTool();
|
|
13991
|
-
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.
|
|
14023
|
+
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
13992
14024
|
var DEFAULT_SCOPE = "private";
|
|
13993
|
-
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.
|
|
13994
|
-
var DEFAULT_CONSOLIDATE_TOP_K =
|
|
14025
|
+
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
14026
|
+
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
13995
14027
|
async function retain(content, ctx, options = {}) {
|
|
13996
14028
|
const trimmed = content.trim();
|
|
13997
14029
|
if (trimmed.length === 0) {
|
|
@@ -14000,18 +14032,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
14000
14032
|
const enableAutoMerge = options.enableAutoMerge ?? true;
|
|
14001
14033
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
14002
14034
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
14003
|
-
let
|
|
14035
|
+
let supersedeTargetIds = [];
|
|
14004
14036
|
let supersedeContent;
|
|
14005
14037
|
if (enableAutoMerge) {
|
|
14006
14038
|
if (options.consolidateOptions) {
|
|
14007
14039
|
const outcome = await tryConsolidate(trimmed, ctx, options);
|
|
14008
14040
|
if (outcome) {
|
|
14009
14041
|
if ("done" in outcome) return outcome.done;
|
|
14010
|
-
|
|
14042
|
+
supersedeTargetIds = outcome.supersede;
|
|
14011
14043
|
supersedeContent = outcome.content;
|
|
14012
14044
|
}
|
|
14013
14045
|
}
|
|
14014
|
-
if (
|
|
14046
|
+
if (supersedeTargetIds.length === 0) {
|
|
14015
14047
|
const matches = await searchVaultMemories(
|
|
14016
14048
|
trimmed,
|
|
14017
14049
|
ctx.vaultCtx,
|
|
@@ -14115,18 +14147,42 @@ async function retain(content, ctx, options = {}) {
|
|
|
14115
14147
|
// memory's tier. The DB op re-validates against the known set.
|
|
14116
14148
|
...options.trustTier !== void 0 && { trustTier: options.trustTier }
|
|
14117
14149
|
};
|
|
14118
|
-
if (
|
|
14150
|
+
if (supersedeTargetIds.length > 0) {
|
|
14151
|
+
const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
|
|
14119
14152
|
const { created: created2, retired } = await createSupersedingMemoryOp(
|
|
14120
14153
|
ctx.vaultCtx,
|
|
14121
14154
|
createOpts,
|
|
14122
|
-
|
|
14155
|
+
primaryTargetId
|
|
14123
14156
|
);
|
|
14124
14157
|
if (created2 && retired) {
|
|
14125
14158
|
ctx.vaultCache.set(created2.uniqueId, Float32Array.from(embedding));
|
|
14159
|
+
const liveLeftovers = [];
|
|
14160
|
+
for (const staleId of restTargetIds) {
|
|
14161
|
+
let ok = false;
|
|
14162
|
+
try {
|
|
14163
|
+
ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
|
|
14164
|
+
} catch {
|
|
14165
|
+
}
|
|
14166
|
+
if (ok) continue;
|
|
14167
|
+
const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
|
|
14168
|
+
if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
|
|
14169
|
+
}
|
|
14170
|
+
if (liveLeftovers.length > 0) {
|
|
14171
|
+
getLogger().warn(
|
|
14172
|
+
"[memory/retain] supersede left duplicate row(s) live \u2014 will reconcile at next consolidation",
|
|
14173
|
+
{
|
|
14174
|
+
newMemoryId: created2.uniqueId,
|
|
14175
|
+
leftover: liveLeftovers.length,
|
|
14176
|
+
// Log the specific ids (opaque record ids, not content) so an
|
|
14177
|
+
// operator can identify exactly which rows are still active.
|
|
14178
|
+
leftoverIds: liveLeftovers
|
|
14179
|
+
}
|
|
14180
|
+
);
|
|
14181
|
+
}
|
|
14126
14182
|
return {
|
|
14127
14183
|
action: "supersede",
|
|
14128
14184
|
memoryId: created2.uniqueId,
|
|
14129
|
-
targetId:
|
|
14185
|
+
targetId: primaryTargetId,
|
|
14130
14186
|
proofCount: 1
|
|
14131
14187
|
};
|
|
14132
14188
|
}
|
|
@@ -14212,10 +14268,16 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
14212
14268
|
const { consolidateMemory: doConsolidate } = await Promise.resolve().then(() => (init_consolidate(), consolidate_exports));
|
|
14213
14269
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
14214
14270
|
if (decision.action === "create") return null;
|
|
14215
|
-
if (decision.action === "supersede" && decision.
|
|
14216
|
-
const
|
|
14217
|
-
if (
|
|
14218
|
-
|
|
14271
|
+
if (decision.action === "supersede" && decision.content) {
|
|
14272
|
+
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
14273
|
+
if (requestedIds.length === 0) return null;
|
|
14274
|
+
const valid = [];
|
|
14275
|
+
for (const id of requestedIds) {
|
|
14276
|
+
const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
|
|
14277
|
+
if (existing && !existing.supersededBy) valid.push(id);
|
|
14278
|
+
}
|
|
14279
|
+
if (valid.length === 0) return null;
|
|
14280
|
+
return { supersede: valid, content: decision.content };
|
|
14219
14281
|
}
|
|
14220
14282
|
if (decision.action === "noop" && decision.targetId) {
|
|
14221
14283
|
const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
|
|
@@ -15991,6 +16053,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
15991
16053
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
15992
16054
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
15993
16055
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
16056
|
+
...options.endpointOverride !== void 0 && {
|
|
16057
|
+
endpointOverride: options.endpointOverride
|
|
16058
|
+
},
|
|
15994
16059
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
15995
16060
|
systemPrompt: SYSTEM_PROMPT6,
|
|
15996
16061
|
userMessage: `${vocabularyNote}Memories:
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -7456,6 +7456,15 @@ interface TopicExtractionInput {
|
|
|
7456
7456
|
*/
|
|
7457
7457
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
7458
7458
|
baseUrl?: string;
|
|
7459
|
+
/**
|
|
7460
|
+
* Optional per-call request path override, forwarded to
|
|
7461
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
7462
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
7463
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
7464
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
7465
|
+
* call time (see {@link validateEndpointOverride}).
|
|
7466
|
+
*/
|
|
7467
|
+
endpointOverride?: string;
|
|
7459
7468
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
7460
7469
|
* model. Don't point this at a second model without an eval. */
|
|
7461
7470
|
model?: string;
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -7456,6 +7456,15 @@ interface TopicExtractionInput {
|
|
|
7456
7456
|
*/
|
|
7457
7457
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
7458
7458
|
baseUrl?: string;
|
|
7459
|
+
/**
|
|
7460
|
+
* Optional per-call request path override, forwarded to
|
|
7461
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
7462
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
7463
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
7464
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
7465
|
+
* call time (see {@link validateEndpointOverride}).
|
|
7466
|
+
*/
|
|
7467
|
+
endpointOverride?: string;
|
|
7459
7468
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
7460
7469
|
* model. Don't point this at a second model without an eval. */
|
|
7461
7470
|
model?: string;
|
package/dist/expo/index.mjs
CHANGED
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
upsertMessageOp,
|
|
109
109
|
useEncryption,
|
|
110
110
|
vaultMemoryToStored
|
|
111
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-AAB7OG7Q.mjs";
|
|
112
112
|
import {
|
|
113
113
|
PII_PATTERNS,
|
|
114
114
|
PiiRedactor,
|
|
@@ -124,8 +124,9 @@ import {
|
|
|
124
124
|
noopLogger,
|
|
125
125
|
resolvePortalAuthHeaders,
|
|
126
126
|
setLogger,
|
|
127
|
-
supportsResponseFormat
|
|
128
|
-
|
|
127
|
+
supportsResponseFormat,
|
|
128
|
+
validateEndpointOverride
|
|
129
|
+
} from "./chunk-BOY27A2C.mjs";
|
|
129
130
|
import {
|
|
130
131
|
BASE_URL,
|
|
131
132
|
MCP_R2_DOMAIN,
|
|
@@ -2473,22 +2474,6 @@ function linkAbortSignals(a, b) {
|
|
|
2473
2474
|
}
|
|
2474
2475
|
};
|
|
2475
2476
|
}
|
|
2476
|
-
function validateEndpointOverride(override) {
|
|
2477
|
-
const trimmed = override.trim();
|
|
2478
|
-
if (trimmed === "") {
|
|
2479
|
-
return {
|
|
2480
|
-
valid: false,
|
|
2481
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
2482
|
-
};
|
|
2483
|
-
}
|
|
2484
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
2485
|
-
return {
|
|
2486
|
-
valid: false,
|
|
2487
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
2488
|
-
};
|
|
2489
|
-
}
|
|
2490
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
2491
|
-
}
|
|
2492
2477
|
async function runToolLoop(options) {
|
|
2493
2478
|
const {
|
|
2494
2479
|
model,
|
|
@@ -6209,10 +6194,10 @@ function injectionSignatureCatalog() {
|
|
|
6209
6194
|
}
|
|
6210
6195
|
|
|
6211
6196
|
// src/lib/memory/retain.ts
|
|
6212
|
-
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.
|
|
6197
|
+
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
6213
6198
|
var DEFAULT_SCOPE = "private";
|
|
6214
|
-
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.
|
|
6215
|
-
var DEFAULT_CONSOLIDATE_TOP_K =
|
|
6199
|
+
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
6200
|
+
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
6216
6201
|
async function retain(content, ctx, options = {}) {
|
|
6217
6202
|
const trimmed = content.trim();
|
|
6218
6203
|
if (trimmed.length === 0) {
|
|
@@ -6221,18 +6206,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
6221
6206
|
const enableAutoMerge = options.enableAutoMerge ?? true;
|
|
6222
6207
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
6223
6208
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
6224
|
-
let
|
|
6209
|
+
let supersedeTargetIds = [];
|
|
6225
6210
|
let supersedeContent;
|
|
6226
6211
|
if (enableAutoMerge) {
|
|
6227
6212
|
if (options.consolidateOptions) {
|
|
6228
6213
|
const outcome = await tryConsolidate(trimmed, ctx, options);
|
|
6229
6214
|
if (outcome) {
|
|
6230
6215
|
if ("done" in outcome) return outcome.done;
|
|
6231
|
-
|
|
6216
|
+
supersedeTargetIds = outcome.supersede;
|
|
6232
6217
|
supersedeContent = outcome.content;
|
|
6233
6218
|
}
|
|
6234
6219
|
}
|
|
6235
|
-
if (
|
|
6220
|
+
if (supersedeTargetIds.length === 0) {
|
|
6236
6221
|
const matches = await searchVaultMemories(
|
|
6237
6222
|
trimmed,
|
|
6238
6223
|
ctx.vaultCtx,
|
|
@@ -6336,18 +6321,42 @@ async function retain(content, ctx, options = {}) {
|
|
|
6336
6321
|
// memory's tier. The DB op re-validates against the known set.
|
|
6337
6322
|
...options.trustTier !== void 0 && { trustTier: options.trustTier }
|
|
6338
6323
|
};
|
|
6339
|
-
if (
|
|
6324
|
+
if (supersedeTargetIds.length > 0) {
|
|
6325
|
+
const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
|
|
6340
6326
|
const { created: created2, retired } = await createSupersedingMemoryOp(
|
|
6341
6327
|
ctx.vaultCtx,
|
|
6342
6328
|
createOpts,
|
|
6343
|
-
|
|
6329
|
+
primaryTargetId
|
|
6344
6330
|
);
|
|
6345
6331
|
if (created2 && retired) {
|
|
6346
6332
|
ctx.vaultCache.set(created2.uniqueId, Float32Array.from(embedding));
|
|
6333
|
+
const liveLeftovers = [];
|
|
6334
|
+
for (const staleId of restTargetIds) {
|
|
6335
|
+
let ok = false;
|
|
6336
|
+
try {
|
|
6337
|
+
ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
|
|
6338
|
+
} catch {
|
|
6339
|
+
}
|
|
6340
|
+
if (ok) continue;
|
|
6341
|
+
const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
|
|
6342
|
+
if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
|
|
6343
|
+
}
|
|
6344
|
+
if (liveLeftovers.length > 0) {
|
|
6345
|
+
getLogger().warn(
|
|
6346
|
+
"[memory/retain] supersede left duplicate row(s) live \u2014 will reconcile at next consolidation",
|
|
6347
|
+
{
|
|
6348
|
+
newMemoryId: created2.uniqueId,
|
|
6349
|
+
leftover: liveLeftovers.length,
|
|
6350
|
+
// Log the specific ids (opaque record ids, not content) so an
|
|
6351
|
+
// operator can identify exactly which rows are still active.
|
|
6352
|
+
leftoverIds: liveLeftovers
|
|
6353
|
+
}
|
|
6354
|
+
);
|
|
6355
|
+
}
|
|
6347
6356
|
return {
|
|
6348
6357
|
action: "supersede",
|
|
6349
6358
|
memoryId: created2.uniqueId,
|
|
6350
|
-
targetId:
|
|
6359
|
+
targetId: primaryTargetId,
|
|
6351
6360
|
proofCount: 1
|
|
6352
6361
|
};
|
|
6353
6362
|
}
|
|
@@ -6430,13 +6439,19 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
6430
6439
|
content: m.content,
|
|
6431
6440
|
similarity: m.similarity
|
|
6432
6441
|
}));
|
|
6433
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
6442
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-HKN32P5W.mjs");
|
|
6434
6443
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
6435
6444
|
if (decision.action === "create") return null;
|
|
6436
|
-
if (decision.action === "supersede" && decision.
|
|
6437
|
-
const
|
|
6438
|
-
if (
|
|
6439
|
-
|
|
6445
|
+
if (decision.action === "supersede" && decision.content) {
|
|
6446
|
+
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
6447
|
+
if (requestedIds.length === 0) return null;
|
|
6448
|
+
const valid = [];
|
|
6449
|
+
for (const id of requestedIds) {
|
|
6450
|
+
const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
|
|
6451
|
+
if (existing && !existing.supersededBy) valid.push(id);
|
|
6452
|
+
}
|
|
6453
|
+
if (valid.length === 0) return null;
|
|
6454
|
+
return { supersede: valid, content: decision.content };
|
|
6440
6455
|
}
|
|
6441
6456
|
if (decision.action === "noop" && decision.targetId) {
|
|
6442
6457
|
const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
|
|
@@ -8173,6 +8188,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
8173
8188
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
8174
8189
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
8175
8190
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
8191
|
+
...options.endpointOverride !== void 0 && {
|
|
8192
|
+
endpointOverride: options.endpointOverride
|
|
8193
|
+
},
|
|
8176
8194
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
8177
8195
|
systemPrompt: SYSTEM_PROMPT4,
|
|
8178
8196
|
userMessage: `${vocabularyNote}Memories:
|