@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
|
|
@@ -5641,7 +5641,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
5641
5641
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
5642
5642
|
);
|
|
5643
5643
|
}
|
|
5644
|
-
const { recall: recall2 } = await import("./recall-
|
|
5644
|
+
const { recall: recall2 } = await import("./recall-Z7BWJ67X.mjs");
|
|
5645
5645
|
const result = await recall2(
|
|
5646
5646
|
query,
|
|
5647
5647
|
{ 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/react/index.cjs
CHANGED
|
@@ -4175,6 +4175,29 @@ var init_redactor = __esm({
|
|
|
4175
4175
|
}
|
|
4176
4176
|
});
|
|
4177
4177
|
|
|
4178
|
+
// src/lib/chat/endpointOverride.ts
|
|
4179
|
+
function validateEndpointOverride(override) {
|
|
4180
|
+
const trimmed = override.trim();
|
|
4181
|
+
if (trimmed === "") {
|
|
4182
|
+
return {
|
|
4183
|
+
valid: false,
|
|
4184
|
+
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
4188
|
+
return {
|
|
4189
|
+
valid: false,
|
|
4190
|
+
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
4191
|
+
};
|
|
4192
|
+
}
|
|
4193
|
+
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
4194
|
+
}
|
|
4195
|
+
var init_endpointOverride = __esm({
|
|
4196
|
+
"src/lib/chat/endpointOverride.ts"() {
|
|
4197
|
+
"use strict";
|
|
4198
|
+
}
|
|
4199
|
+
});
|
|
4200
|
+
|
|
4178
4201
|
// src/lib/db/entities/types.ts
|
|
4179
4202
|
function normalizeEntityName(name) {
|
|
4180
4203
|
return name.trim().toLowerCase();
|
|
@@ -5304,6 +5327,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
5304
5327
|
}
|
|
5305
5328
|
async function callPortalJsonCompletion(req) {
|
|
5306
5329
|
const log = getLogger();
|
|
5330
|
+
let endpoint = "/api/v1/chat/completions";
|
|
5331
|
+
if (req.endpointOverride !== void 0) {
|
|
5332
|
+
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
5333
|
+
if (!overrideValidation.valid) {
|
|
5334
|
+
throw new Error(overrideValidation.message);
|
|
5335
|
+
}
|
|
5336
|
+
endpoint = overrideValidation.endpoint;
|
|
5337
|
+
}
|
|
5307
5338
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
5308
5339
|
const startedAt = Date.now();
|
|
5309
5340
|
const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
|
|
@@ -5319,7 +5350,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
5319
5350
|
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
5320
5351
|
)
|
|
5321
5352
|
} : req;
|
|
5322
|
-
const outcome = await attemptPortalJson(attemptReq);
|
|
5353
|
+
const outcome = await attemptPortalJson(attemptReq, endpoint);
|
|
5323
5354
|
if (outcome.kind === "ok") return outcome.value;
|
|
5324
5355
|
if (outcome.kind === "terminal") {
|
|
5325
5356
|
log.warn(`[${req.tag}] ${outcome.reason}`);
|
|
@@ -5342,7 +5373,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
5342
5373
|
}
|
|
5343
5374
|
return null;
|
|
5344
5375
|
}
|
|
5345
|
-
async function attemptPortalJson(req) {
|
|
5376
|
+
async function attemptPortalJson(req, endpoint) {
|
|
5346
5377
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
5347
5378
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
5348
5379
|
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
@@ -5367,7 +5398,7 @@ async function attemptPortalJson(req) {
|
|
|
5367
5398
|
if (!supportsJsonObjectFormat) delete requestBody.response_format;
|
|
5368
5399
|
let response;
|
|
5369
5400
|
try {
|
|
5370
|
-
response = await fetchImpl(`${baseUrl}
|
|
5401
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
5371
5402
|
method: "POST",
|
|
5372
5403
|
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
5373
5404
|
body: JSON.stringify(requestBody),
|
|
@@ -5464,6 +5495,7 @@ var init_portalLlm = __esm({
|
|
|
5464
5495
|
"src/lib/memory/portalLlm.ts"() {
|
|
5465
5496
|
"use strict";
|
|
5466
5497
|
init_clientConfig();
|
|
5498
|
+
init_endpointOverride();
|
|
5467
5499
|
init_logger();
|
|
5468
5500
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
5469
5501
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
@@ -7879,14 +7911,27 @@ function validate2(parsed, newContent, validIds) {
|
|
|
7879
7911
|
const c2 = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
7880
7912
|
return { action: "create", content: c2.length > 0 ? c2 : newContent };
|
|
7881
7913
|
}
|
|
7882
|
-
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7883
|
-
if (!targetId || !validIds.has(targetId)) return null;
|
|
7884
7914
|
if (action === "noop") {
|
|
7885
|
-
|
|
7915
|
+
const targetId2 = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7916
|
+
if (!targetId2 || !validIds.has(targetId2)) return null;
|
|
7917
|
+
return { action: "noop", targetId: targetId2 };
|
|
7886
7918
|
}
|
|
7887
7919
|
const c = typeof obj.content === "string" ? obj.content.trim() : "";
|
|
7888
7920
|
if (c.length === 0) return null;
|
|
7889
|
-
|
|
7921
|
+
if (action === "supersede") {
|
|
7922
|
+
const rawIds = [
|
|
7923
|
+
...Array.isArray(obj.targetIds) ? obj.targetIds : [],
|
|
7924
|
+
...typeof obj.targetId === "string" ? [obj.targetId] : []
|
|
7925
|
+
];
|
|
7926
|
+
const targetIds = [
|
|
7927
|
+
...new Set(rawIds.filter((id) => typeof id === "string" && validIds.has(id)))
|
|
7928
|
+
];
|
|
7929
|
+
if (targetIds.length === 0) return null;
|
|
7930
|
+
return { action: "supersede", targetId: targetIds[0], targetIds, content: c };
|
|
7931
|
+
}
|
|
7932
|
+
const targetId = typeof obj.targetId === "string" ? obj.targetId : null;
|
|
7933
|
+
if (!targetId || !validIds.has(targetId)) return null;
|
|
7934
|
+
return { action: "update", targetId, content: c };
|
|
7890
7935
|
}
|
|
7891
7936
|
var DEFAULT_MODEL3, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
|
|
7892
7937
|
var init_consolidate = __esm({
|
|
@@ -7906,7 +7951,7 @@ Decide one of four actions:
|
|
|
7906
7951
|
|
|
7907
7952
|
- "create": the new memory describes a distinct fact not covered by any existing memory. Write it as new.
|
|
7908
7953
|
- "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).
|
|
7909
|
-
- "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
|
|
7954
|
+
- "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.
|
|
7910
7955
|
- "noop": the new memory is already fully captured by an existing memory \u2014 same facet, no new information. Skip the write.
|
|
7911
7956
|
|
|
7912
7957
|
RULES (carry these strictly):
|
|
@@ -7922,14 +7967,15 @@ RULES (carry these strictly):
|
|
|
7922
7967
|
OUTPUT \u2014 strict JSON, no prose:
|
|
7923
7968
|
{
|
|
7924
7969
|
"action": "create" | "update" | "supersede" | "noop",
|
|
7925
|
-
"targetId": "<existing memory id \u2014 required for update/
|
|
7970
|
+
"targetId": "<existing memory id \u2014 required for update/noop, omit for create/supersede>",
|
|
7971
|
+
"targetIds": ["<id>", ...],
|
|
7926
7972
|
"content": "<content \u2014 required for create/update/supersede, omit for noop>"
|
|
7927
7973
|
}
|
|
7928
7974
|
|
|
7929
|
-
For "create": content is the new memory verbatim (or a slight refinement).
|
|
7930
|
-
For "update": content is the merged richest-version, \u226480 words.
|
|
7931
|
-
For "supersede": content is the NEW fact only (\u226480 words);
|
|
7932
|
-
For "noop": no content (existing memory is already correct).`;
|
|
7975
|
+
For "create": content is the new memory verbatim (or a slight refinement); omit targetId/targetIds.
|
|
7976
|
+
For "update": content is the merged richest-version, \u226480 words; targetId is the single memory to update.
|
|
7977
|
+
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).
|
|
7978
|
+
For "noop": no content (existing memory is already correct); targetId is that memory.`;
|
|
7933
7979
|
}
|
|
7934
7980
|
});
|
|
7935
7981
|
|
|
@@ -8378,6 +8424,7 @@ init_serverSentEvents_gen();
|
|
|
8378
8424
|
init_clientConfig();
|
|
8379
8425
|
init_embeddings();
|
|
8380
8426
|
init_redactor();
|
|
8427
|
+
init_endpointOverride();
|
|
8381
8428
|
|
|
8382
8429
|
// src/lib/chat/runHooks.ts
|
|
8383
8430
|
function composeHooks(hooks) {
|
|
@@ -10557,22 +10604,6 @@ function linkAbortSignals(a, b) {
|
|
|
10557
10604
|
}
|
|
10558
10605
|
};
|
|
10559
10606
|
}
|
|
10560
|
-
function validateEndpointOverride(override) {
|
|
10561
|
-
const trimmed = override.trim();
|
|
10562
|
-
if (trimmed === "") {
|
|
10563
|
-
return {
|
|
10564
|
-
valid: false,
|
|
10565
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
10566
|
-
};
|
|
10567
|
-
}
|
|
10568
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
10569
|
-
return {
|
|
10570
|
-
valid: false,
|
|
10571
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
10572
|
-
};
|
|
10573
|
-
}
|
|
10574
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
10575
|
-
}
|
|
10576
10607
|
async function runToolLoop(options) {
|
|
10577
10608
|
const {
|
|
10578
10609
|
model,
|
|
@@ -15274,14 +15305,15 @@ init_portalLlm();
|
|
|
15274
15305
|
|
|
15275
15306
|
// src/lib/memory/retain.ts
|
|
15276
15307
|
init_operations3();
|
|
15308
|
+
init_logger();
|
|
15277
15309
|
init_constants();
|
|
15278
15310
|
init_embeddings();
|
|
15279
15311
|
init_vector();
|
|
15280
15312
|
init_searchTool();
|
|
15281
|
-
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.
|
|
15313
|
+
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
15282
15314
|
var DEFAULT_SCOPE = "private";
|
|
15283
|
-
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.
|
|
15284
|
-
var DEFAULT_CONSOLIDATE_TOP_K =
|
|
15315
|
+
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
15316
|
+
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
15285
15317
|
async function retain(content, ctx, options = {}) {
|
|
15286
15318
|
const trimmed = content.trim();
|
|
15287
15319
|
if (trimmed.length === 0) {
|
|
@@ -15290,18 +15322,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
15290
15322
|
const enableAutoMerge = options.enableAutoMerge ?? true;
|
|
15291
15323
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
15292
15324
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
15293
|
-
let
|
|
15325
|
+
let supersedeTargetIds = [];
|
|
15294
15326
|
let supersedeContent;
|
|
15295
15327
|
if (enableAutoMerge) {
|
|
15296
15328
|
if (options.consolidateOptions) {
|
|
15297
15329
|
const outcome = await tryConsolidate(trimmed, ctx, options);
|
|
15298
15330
|
if (outcome) {
|
|
15299
15331
|
if ("done" in outcome) return outcome.done;
|
|
15300
|
-
|
|
15332
|
+
supersedeTargetIds = outcome.supersede;
|
|
15301
15333
|
supersedeContent = outcome.content;
|
|
15302
15334
|
}
|
|
15303
15335
|
}
|
|
15304
|
-
if (
|
|
15336
|
+
if (supersedeTargetIds.length === 0) {
|
|
15305
15337
|
const matches = await searchVaultMemories(
|
|
15306
15338
|
trimmed,
|
|
15307
15339
|
ctx.vaultCtx,
|
|
@@ -15405,18 +15437,42 @@ async function retain(content, ctx, options = {}) {
|
|
|
15405
15437
|
// memory's tier. The DB op re-validates against the known set.
|
|
15406
15438
|
...options.trustTier !== void 0 && { trustTier: options.trustTier }
|
|
15407
15439
|
};
|
|
15408
|
-
if (
|
|
15440
|
+
if (supersedeTargetIds.length > 0) {
|
|
15441
|
+
const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
|
|
15409
15442
|
const { created: created2, retired } = await createSupersedingMemoryOp(
|
|
15410
15443
|
ctx.vaultCtx,
|
|
15411
15444
|
createOpts,
|
|
15412
|
-
|
|
15445
|
+
primaryTargetId
|
|
15413
15446
|
);
|
|
15414
15447
|
if (created2 && retired) {
|
|
15415
15448
|
ctx.vaultCache.set(created2.uniqueId, Float32Array.from(embedding));
|
|
15449
|
+
const liveLeftovers = [];
|
|
15450
|
+
for (const staleId of restTargetIds) {
|
|
15451
|
+
let ok = false;
|
|
15452
|
+
try {
|
|
15453
|
+
ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
|
|
15454
|
+
} catch {
|
|
15455
|
+
}
|
|
15456
|
+
if (ok) continue;
|
|
15457
|
+
const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
|
|
15458
|
+
if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
|
|
15459
|
+
}
|
|
15460
|
+
if (liveLeftovers.length > 0) {
|
|
15461
|
+
getLogger().warn(
|
|
15462
|
+
"[memory/retain] supersede left duplicate row(s) live \u2014 will reconcile at next consolidation",
|
|
15463
|
+
{
|
|
15464
|
+
newMemoryId: created2.uniqueId,
|
|
15465
|
+
leftover: liveLeftovers.length,
|
|
15466
|
+
// Log the specific ids (opaque record ids, not content) so an
|
|
15467
|
+
// operator can identify exactly which rows are still active.
|
|
15468
|
+
leftoverIds: liveLeftovers
|
|
15469
|
+
}
|
|
15470
|
+
);
|
|
15471
|
+
}
|
|
15416
15472
|
return {
|
|
15417
15473
|
action: "supersede",
|
|
15418
15474
|
memoryId: created2.uniqueId,
|
|
15419
|
-
targetId:
|
|
15475
|
+
targetId: primaryTargetId,
|
|
15420
15476
|
proofCount: 1
|
|
15421
15477
|
};
|
|
15422
15478
|
}
|
|
@@ -15502,10 +15558,16 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
15502
15558
|
const { consolidateMemory: doConsolidate } = await Promise.resolve().then(() => (init_consolidate(), consolidate_exports));
|
|
15503
15559
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
15504
15560
|
if (decision.action === "create") return null;
|
|
15505
|
-
if (decision.action === "supersede" && decision.
|
|
15506
|
-
const
|
|
15507
|
-
if (
|
|
15508
|
-
|
|
15561
|
+
if (decision.action === "supersede" && decision.content) {
|
|
15562
|
+
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
15563
|
+
if (requestedIds.length === 0) return null;
|
|
15564
|
+
const valid = [];
|
|
15565
|
+
for (const id of requestedIds) {
|
|
15566
|
+
const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
|
|
15567
|
+
if (existing && !existing.supersededBy) valid.push(id);
|
|
15568
|
+
}
|
|
15569
|
+
if (valid.length === 0) return null;
|
|
15570
|
+
return { supersede: valid, content: decision.content };
|
|
15509
15571
|
}
|
|
15510
15572
|
if (decision.action === "noop" && decision.targetId) {
|
|
15511
15573
|
const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
|
|
@@ -17281,6 +17343,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
17281
17343
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
17282
17344
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
17283
17345
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
17346
|
+
...options.endpointOverride !== void 0 && {
|
|
17347
|
+
endpointOverride: options.endpointOverride
|
|
17348
|
+
},
|
|
17284
17349
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
17285
17350
|
systemPrompt: SYSTEM_PROMPT6,
|
|
17286
17351
|
userMessage: `${vocabularyNote}Memories:
|
package/dist/react/index.d.mts
CHANGED
|
@@ -8607,6 +8607,15 @@ interface TopicExtractionInput {
|
|
|
8607
8607
|
*/
|
|
8608
8608
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
8609
8609
|
baseUrl?: string;
|
|
8610
|
+
/**
|
|
8611
|
+
* Optional per-call request path override, forwarded to
|
|
8612
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
8613
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
8614
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
8615
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
8616
|
+
* call time (see {@link validateEndpointOverride}).
|
|
8617
|
+
*/
|
|
8618
|
+
endpointOverride?: string;
|
|
8610
8619
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
8611
8620
|
* model. Don't point this at a second model without an eval. */
|
|
8612
8621
|
model?: string;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -8607,6 +8607,15 @@ interface TopicExtractionInput {
|
|
|
8607
8607
|
*/
|
|
8608
8608
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
8609
8609
|
baseUrl?: string;
|
|
8610
|
+
/**
|
|
8611
|
+
* Optional per-call request path override, forwarded to
|
|
8612
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
8613
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
8614
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
8615
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
8616
|
+
* call time (see {@link validateEndpointOverride}).
|
|
8617
|
+
*/
|
|
8618
|
+
endpointOverride?: string;
|
|
8610
8619
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
8611
8620
|
* model. Don't point this at a second model without an eval. */
|
|
8612
8621
|
model?: string;
|
package/dist/react/index.mjs
CHANGED
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
updateVaultMemoryOp,
|
|
150
150
|
useEncryption,
|
|
151
151
|
vaultMemoryToStored
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-3VPEZDYL.mjs";
|
|
153
153
|
import {
|
|
154
154
|
PiiRedactor,
|
|
155
155
|
createStreamingDeAnonymizer,
|
|
@@ -164,8 +164,9 @@ import {
|
|
|
164
164
|
noopLogger,
|
|
165
165
|
resolvePortalAuthHeaders,
|
|
166
166
|
setLogger,
|
|
167
|
-
supportsResponseFormat
|
|
168
|
-
|
|
167
|
+
supportsResponseFormat,
|
|
168
|
+
validateEndpointOverride
|
|
169
|
+
} from "./chunk-BOY27A2C.mjs";
|
|
169
170
|
import {
|
|
170
171
|
BASE_URL,
|
|
171
172
|
MCP_R2_DOMAIN,
|
|
@@ -2346,22 +2347,6 @@ function linkAbortSignals(a, b) {
|
|
|
2346
2347
|
}
|
|
2347
2348
|
};
|
|
2348
2349
|
}
|
|
2349
|
-
function validateEndpointOverride(override) {
|
|
2350
|
-
const trimmed = override.trim();
|
|
2351
|
-
if (trimmed === "") {
|
|
2352
|
-
return {
|
|
2353
|
-
valid: false,
|
|
2354
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
2355
|
-
};
|
|
2356
|
-
}
|
|
2357
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
2358
|
-
return {
|
|
2359
|
-
valid: false,
|
|
2360
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
2361
|
-
};
|
|
2362
|
-
}
|
|
2363
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
2364
|
-
}
|
|
2365
2350
|
async function runToolLoop(options) {
|
|
2366
2351
|
const {
|
|
2367
2352
|
model,
|
|
@@ -7022,10 +7007,10 @@ function injectionSignatureCatalog() {
|
|
|
7022
7007
|
}
|
|
7023
7008
|
|
|
7024
7009
|
// src/lib/memory/retain.ts
|
|
7025
|
-
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.
|
|
7010
|
+
var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
7026
7011
|
var DEFAULT_SCOPE = "private";
|
|
7027
|
-
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.
|
|
7028
|
-
var DEFAULT_CONSOLIDATE_TOP_K =
|
|
7012
|
+
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
7013
|
+
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
7029
7014
|
async function retain(content, ctx, options = {}) {
|
|
7030
7015
|
const trimmed = content.trim();
|
|
7031
7016
|
if (trimmed.length === 0) {
|
|
@@ -7034,18 +7019,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
7034
7019
|
const enableAutoMerge = options.enableAutoMerge ?? true;
|
|
7035
7020
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
7036
7021
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
7037
|
-
let
|
|
7022
|
+
let supersedeTargetIds = [];
|
|
7038
7023
|
let supersedeContent;
|
|
7039
7024
|
if (enableAutoMerge) {
|
|
7040
7025
|
if (options.consolidateOptions) {
|
|
7041
7026
|
const outcome = await tryConsolidate(trimmed, ctx, options);
|
|
7042
7027
|
if (outcome) {
|
|
7043
7028
|
if ("done" in outcome) return outcome.done;
|
|
7044
|
-
|
|
7029
|
+
supersedeTargetIds = outcome.supersede;
|
|
7045
7030
|
supersedeContent = outcome.content;
|
|
7046
7031
|
}
|
|
7047
7032
|
}
|
|
7048
|
-
if (
|
|
7033
|
+
if (supersedeTargetIds.length === 0) {
|
|
7049
7034
|
const matches = await searchVaultMemories(
|
|
7050
7035
|
trimmed,
|
|
7051
7036
|
ctx.vaultCtx,
|
|
@@ -7149,18 +7134,42 @@ async function retain(content, ctx, options = {}) {
|
|
|
7149
7134
|
// memory's tier. The DB op re-validates against the known set.
|
|
7150
7135
|
...options.trustTier !== void 0 && { trustTier: options.trustTier }
|
|
7151
7136
|
};
|
|
7152
|
-
if (
|
|
7137
|
+
if (supersedeTargetIds.length > 0) {
|
|
7138
|
+
const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
|
|
7153
7139
|
const { created: created2, retired } = await createSupersedingMemoryOp(
|
|
7154
7140
|
ctx.vaultCtx,
|
|
7155
7141
|
createOpts,
|
|
7156
|
-
|
|
7142
|
+
primaryTargetId
|
|
7157
7143
|
);
|
|
7158
7144
|
if (created2 && retired) {
|
|
7159
7145
|
ctx.vaultCache.set(created2.uniqueId, Float32Array.from(embedding));
|
|
7146
|
+
const liveLeftovers = [];
|
|
7147
|
+
for (const staleId of restTargetIds) {
|
|
7148
|
+
let ok = false;
|
|
7149
|
+
try {
|
|
7150
|
+
ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
|
|
7151
|
+
} catch {
|
|
7152
|
+
}
|
|
7153
|
+
if (ok) continue;
|
|
7154
|
+
const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
|
|
7155
|
+
if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
|
|
7156
|
+
}
|
|
7157
|
+
if (liveLeftovers.length > 0) {
|
|
7158
|
+
getLogger().warn(
|
|
7159
|
+
"[memory/retain] supersede left duplicate row(s) live \u2014 will reconcile at next consolidation",
|
|
7160
|
+
{
|
|
7161
|
+
newMemoryId: created2.uniqueId,
|
|
7162
|
+
leftover: liveLeftovers.length,
|
|
7163
|
+
// Log the specific ids (opaque record ids, not content) so an
|
|
7164
|
+
// operator can identify exactly which rows are still active.
|
|
7165
|
+
leftoverIds: liveLeftovers
|
|
7166
|
+
}
|
|
7167
|
+
);
|
|
7168
|
+
}
|
|
7160
7169
|
return {
|
|
7161
7170
|
action: "supersede",
|
|
7162
7171
|
memoryId: created2.uniqueId,
|
|
7163
|
-
targetId:
|
|
7172
|
+
targetId: primaryTargetId,
|
|
7164
7173
|
proofCount: 1
|
|
7165
7174
|
};
|
|
7166
7175
|
}
|
|
@@ -7243,13 +7252,19 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
7243
7252
|
content: m.content,
|
|
7244
7253
|
similarity: m.similarity
|
|
7245
7254
|
}));
|
|
7246
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
7255
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-7UUX56GM.mjs");
|
|
7247
7256
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
7248
7257
|
if (decision.action === "create") return null;
|
|
7249
|
-
if (decision.action === "supersede" && decision.
|
|
7250
|
-
const
|
|
7251
|
-
if (
|
|
7252
|
-
|
|
7258
|
+
if (decision.action === "supersede" && decision.content) {
|
|
7259
|
+
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
7260
|
+
if (requestedIds.length === 0) return null;
|
|
7261
|
+
const valid = [];
|
|
7262
|
+
for (const id of requestedIds) {
|
|
7263
|
+
const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
|
|
7264
|
+
if (existing && !existing.supersededBy) valid.push(id);
|
|
7265
|
+
}
|
|
7266
|
+
if (valid.length === 0) return null;
|
|
7267
|
+
return { supersede: valid, content: decision.content };
|
|
7253
7268
|
}
|
|
7254
7269
|
if (decision.action === "noop" && decision.targetId) {
|
|
7255
7270
|
const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
|
|
@@ -8986,6 +9001,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
8986
9001
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
8987
9002
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
8988
9003
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
9004
|
+
...options.endpointOverride !== void 0 && {
|
|
9005
|
+
endpointOverride: options.endpointOverride
|
|
9006
|
+
},
|
|
8989
9007
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
8990
9008
|
systemPrompt: SYSTEM_PROMPT4,
|
|
8991
9009
|
userMessage: `${vocabularyNote}Memories:
|