@anuma/sdk 3.6.3 → 3.7.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-J5PHQKKY.mjs} +1 -1
- package/dist/expo/index.cjs +39 -19
- package/dist/expo/index.d.mts +9 -0
- package/dist/expo/index.d.ts +9 -0
- package/dist/expo/index.mjs +8 -20
- 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-PWJCAPZA.mjs} +1 -1
- package/dist/react/index.cjs +39 -19
- package/dist/react/index.d.mts +9 -0
- package/dist/react/index.d.ts +9 -0
- package/dist/react/index.mjs +8 -20
- 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-PCHO3D3G.mjs} +1 -1
- package/dist/server/index.cjs +39 -19
- package/dist/server/index.d.mts +36 -0
- package/dist/server/index.d.ts +36 -0
- package/dist/server/index.mjs +8 -20
- package/dist/server/{recall-UTVH2XPK.mjs → recall-XEOLXA6P.mjs} +2 -2
- package/package.json +1 -1
|
@@ -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,
|
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"]);
|
|
@@ -8027,6 +8059,7 @@ init_serverSentEvents_gen();
|
|
|
8027
8059
|
init_clientConfig();
|
|
8028
8060
|
init_embeddings();
|
|
8029
8061
|
init_redactor();
|
|
8062
|
+
init_endpointOverride();
|
|
8030
8063
|
|
|
8031
8064
|
// src/lib/chat/runHooks.ts
|
|
8032
8065
|
function composeHooks(hooks) {
|
|
@@ -10206,22 +10239,6 @@ function linkAbortSignals(a, b) {
|
|
|
10206
10239
|
}
|
|
10207
10240
|
};
|
|
10208
10241
|
}
|
|
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
10242
|
async function runToolLoop(options) {
|
|
10226
10243
|
const {
|
|
10227
10244
|
model,
|
|
@@ -15991,6 +16008,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
15991
16008
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
15992
16009
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
15993
16010
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
16011
|
+
...options.endpointOverride !== void 0 && {
|
|
16012
|
+
endpointOverride: options.endpointOverride
|
|
16013
|
+
},
|
|
15994
16014
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
15995
16015
|
systemPrompt: SYSTEM_PROMPT6,
|
|
15996
16016
|
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,
|
|
@@ -6430,7 +6415,7 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
6430
6415
|
content: m.content,
|
|
6431
6416
|
similarity: m.similarity
|
|
6432
6417
|
}));
|
|
6433
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
6418
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-J5PHQKKY.mjs");
|
|
6434
6419
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
6435
6420
|
if (decision.action === "create") return null;
|
|
6436
6421
|
if (decision.action === "supersede" && decision.targetId && decision.content) {
|
|
@@ -8173,6 +8158,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
8173
8158
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
8174
8159
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
8175
8160
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
8161
|
+
...options.endpointOverride !== void 0 && {
|
|
8162
|
+
endpointOverride: options.endpointOverride
|
|
8163
|
+
},
|
|
8176
8164
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
8177
8165
|
systemPrompt: SYSTEM_PROMPT4,
|
|
8178
8166
|
userMessage: `${vocabularyNote}Memories:
|
|
@@ -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,
|
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"]);
|
|
@@ -8378,6 +8410,7 @@ init_serverSentEvents_gen();
|
|
|
8378
8410
|
init_clientConfig();
|
|
8379
8411
|
init_embeddings();
|
|
8380
8412
|
init_redactor();
|
|
8413
|
+
init_endpointOverride();
|
|
8381
8414
|
|
|
8382
8415
|
// src/lib/chat/runHooks.ts
|
|
8383
8416
|
function composeHooks(hooks) {
|
|
@@ -10557,22 +10590,6 @@ function linkAbortSignals(a, b) {
|
|
|
10557
10590
|
}
|
|
10558
10591
|
};
|
|
10559
10592
|
}
|
|
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
10593
|
async function runToolLoop(options) {
|
|
10577
10594
|
const {
|
|
10578
10595
|
model,
|
|
@@ -17281,6 +17298,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
17281
17298
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
17282
17299
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
17283
17300
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
17301
|
+
...options.endpointOverride !== void 0 && {
|
|
17302
|
+
endpointOverride: options.endpointOverride
|
|
17303
|
+
},
|
|
17284
17304
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
17285
17305
|
systemPrompt: SYSTEM_PROMPT6,
|
|
17286
17306
|
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,
|
|
@@ -7243,7 +7228,7 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
7243
7228
|
content: m.content,
|
|
7244
7229
|
similarity: m.similarity
|
|
7245
7230
|
}));
|
|
7246
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
7231
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-PWJCAPZA.mjs");
|
|
7247
7232
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
7248
7233
|
if (decision.action === "create") return null;
|
|
7249
7234
|
if (decision.action === "supersede" && decision.targetId && decision.content) {
|
|
@@ -8986,6 +8971,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
8986
8971
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
8987
8972
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
8988
8973
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
8974
|
+
...options.endpointOverride !== void 0 && {
|
|
8975
|
+
endpointOverride: options.endpointOverride
|
|
8976
|
+
},
|
|
8989
8977
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
8990
8978
|
systemPrompt: SYSTEM_PROMPT4,
|
|
8991
8979
|
userMessage: `${vocabularyNote}Memories:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callPortalJsonCompletion,
|
|
3
3
|
getLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MIXEASUP.mjs";
|
|
5
5
|
import {
|
|
6
6
|
BASE_URL,
|
|
7
7
|
__commonJS,
|
|
@@ -19554,7 +19554,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
19554
19554
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
19555
19555
|
);
|
|
19556
19556
|
}
|
|
19557
|
-
const { recall: recall2 } = await import("./recall-
|
|
19557
|
+
const { recall: recall2 } = await import("./recall-XEOLXA6P.mjs");
|
|
19558
19558
|
const result = await recall2(
|
|
19559
19559
|
query,
|
|
19560
19560
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
|
@@ -14,6 +14,24 @@ function getLogger() {
|
|
|
14
14
|
return currentLogger;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// src/lib/chat/endpointOverride.ts
|
|
18
|
+
function validateEndpointOverride(override) {
|
|
19
|
+
const trimmed = override.trim();
|
|
20
|
+
if (trimmed === "") {
|
|
21
|
+
return {
|
|
22
|
+
valid: false,
|
|
23
|
+
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
27
|
+
return {
|
|
28
|
+
valid: false,
|
|
29
|
+
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
// src/lib/memory/portalLlm.ts
|
|
18
36
|
function defaultBaseUrl() {
|
|
19
37
|
return typeof process !== "undefined" && process.env?.ANUMA_PORTAL_BASE_URL || BASE_URL;
|
|
@@ -65,6 +83,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
65
83
|
}
|
|
66
84
|
async function callPortalJsonCompletion(req) {
|
|
67
85
|
const log = getLogger();
|
|
86
|
+
let endpoint = "/api/v1/chat/completions";
|
|
87
|
+
if (req.endpointOverride !== void 0) {
|
|
88
|
+
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
89
|
+
if (!overrideValidation.valid) {
|
|
90
|
+
throw new Error(overrideValidation.message);
|
|
91
|
+
}
|
|
92
|
+
endpoint = overrideValidation.endpoint;
|
|
93
|
+
}
|
|
68
94
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
69
95
|
const startedAt = Date.now();
|
|
70
96
|
const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
|
|
@@ -80,7 +106,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
80
106
|
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
81
107
|
)
|
|
82
108
|
} : req;
|
|
83
|
-
const outcome = await attemptPortalJson(attemptReq);
|
|
109
|
+
const outcome = await attemptPortalJson(attemptReq, endpoint);
|
|
84
110
|
if (outcome.kind === "ok") return outcome.value;
|
|
85
111
|
if (outcome.kind === "terminal") {
|
|
86
112
|
log.warn(`[${req.tag}] ${outcome.reason}`);
|
|
@@ -103,7 +129,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
103
129
|
}
|
|
104
130
|
return null;
|
|
105
131
|
}
|
|
106
|
-
async function attemptPortalJson(req) {
|
|
132
|
+
async function attemptPortalJson(req, endpoint) {
|
|
107
133
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
108
134
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
109
135
|
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
@@ -128,7 +154,7 @@ async function attemptPortalJson(req) {
|
|
|
128
154
|
if (!supportsJsonObjectFormat) delete requestBody.response_format;
|
|
129
155
|
let response;
|
|
130
156
|
try {
|
|
131
|
-
response = await fetchImpl(`${baseUrl}
|
|
157
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
132
158
|
method: "POST",
|
|
133
159
|
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
134
160
|
body: JSON.stringify(requestBody),
|
|
@@ -223,6 +249,7 @@ function extractCompletionContent(body) {
|
|
|
223
249
|
|
|
224
250
|
export {
|
|
225
251
|
getLogger,
|
|
252
|
+
validateEndpointOverride,
|
|
226
253
|
supportsResponseFormat,
|
|
227
254
|
resolvePortalAuthHeaders,
|
|
228
255
|
callPortalJsonCompletion,
|
package/dist/server/index.cjs
CHANGED
|
@@ -19549,6 +19549,29 @@ var init_bm25 = __esm({
|
|
|
19549
19549
|
}
|
|
19550
19550
|
});
|
|
19551
19551
|
|
|
19552
|
+
// src/lib/chat/endpointOverride.ts
|
|
19553
|
+
function validateEndpointOverride(override) {
|
|
19554
|
+
const trimmed = override.trim();
|
|
19555
|
+
if (trimmed === "") {
|
|
19556
|
+
return {
|
|
19557
|
+
valid: false,
|
|
19558
|
+
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
19559
|
+
};
|
|
19560
|
+
}
|
|
19561
|
+
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
19562
|
+
return {
|
|
19563
|
+
valid: false,
|
|
19564
|
+
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
19565
|
+
};
|
|
19566
|
+
}
|
|
19567
|
+
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
19568
|
+
}
|
|
19569
|
+
var init_endpointOverride = __esm({
|
|
19570
|
+
"src/lib/chat/endpointOverride.ts"() {
|
|
19571
|
+
"use strict";
|
|
19572
|
+
}
|
|
19573
|
+
});
|
|
19574
|
+
|
|
19552
19575
|
// src/lib/memory/portalLlm.ts
|
|
19553
19576
|
function defaultBaseUrl() {
|
|
19554
19577
|
return typeof process !== "undefined" && process.env?.ANUMA_PORTAL_BASE_URL || BASE_URL;
|
|
@@ -19597,6 +19620,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
|
|
|
19597
19620
|
}
|
|
19598
19621
|
async function callPortalJsonCompletion(req) {
|
|
19599
19622
|
const log = getLogger();
|
|
19623
|
+
let endpoint = "/api/v1/chat/completions";
|
|
19624
|
+
if (req.endpointOverride !== void 0) {
|
|
19625
|
+
const overrideValidation = validateEndpointOverride(req.endpointOverride);
|
|
19626
|
+
if (!overrideValidation.valid) {
|
|
19627
|
+
throw new Error(overrideValidation.message);
|
|
19628
|
+
}
|
|
19629
|
+
endpoint = overrideValidation.endpoint;
|
|
19630
|
+
}
|
|
19600
19631
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
19601
19632
|
const startedAt = Date.now();
|
|
19602
19633
|
const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
|
|
@@ -19612,7 +19643,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
19612
19643
|
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
19613
19644
|
)
|
|
19614
19645
|
} : req;
|
|
19615
|
-
const outcome = await attemptPortalJson(attemptReq);
|
|
19646
|
+
const outcome = await attemptPortalJson(attemptReq, endpoint);
|
|
19616
19647
|
if (outcome.kind === "ok") return outcome.value;
|
|
19617
19648
|
if (outcome.kind === "terminal") {
|
|
19618
19649
|
log.warn(`[${req.tag}] ${outcome.reason}`);
|
|
@@ -19635,7 +19666,7 @@ async function callPortalJsonCompletion(req) {
|
|
|
19635
19666
|
}
|
|
19636
19667
|
return null;
|
|
19637
19668
|
}
|
|
19638
|
-
async function attemptPortalJson(req) {
|
|
19669
|
+
async function attemptPortalJson(req, endpoint) {
|
|
19639
19670
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
19640
19671
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
19641
19672
|
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
@@ -19660,7 +19691,7 @@ async function attemptPortalJson(req) {
|
|
|
19660
19691
|
if (!supportsJsonObjectFormat) delete requestBody.response_format;
|
|
19661
19692
|
let response;
|
|
19662
19693
|
try {
|
|
19663
|
-
response = await fetchImpl(`${baseUrl}
|
|
19694
|
+
response = await fetchImpl(`${baseUrl}${endpoint}`, {
|
|
19664
19695
|
method: "POST",
|
|
19665
19696
|
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
19666
19697
|
body: JSON.stringify(requestBody),
|
|
@@ -19757,6 +19788,7 @@ var init_portalLlm = __esm({
|
|
|
19757
19788
|
"src/lib/memory/portalLlm.ts"() {
|
|
19758
19789
|
"use strict";
|
|
19759
19790
|
init_clientConfig();
|
|
19791
|
+
init_endpointOverride();
|
|
19760
19792
|
init_logger();
|
|
19761
19793
|
RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
|
|
19762
19794
|
RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
|
|
@@ -29132,6 +29164,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
29132
29164
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
29133
29165
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
29134
29166
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
29167
|
+
...options.endpointOverride !== void 0 && {
|
|
29168
|
+
endpointOverride: options.endpointOverride
|
|
29169
|
+
},
|
|
29135
29170
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
29136
29171
|
systemPrompt: SYSTEM_PROMPT6,
|
|
29137
29172
|
userMessage: `${vocabularyNote}Memories:
|
|
@@ -31283,6 +31318,7 @@ init_serverSentEvents_gen();
|
|
|
31283
31318
|
init_clientConfig();
|
|
31284
31319
|
init_embeddings();
|
|
31285
31320
|
init_redactor();
|
|
31321
|
+
init_endpointOverride();
|
|
31286
31322
|
|
|
31287
31323
|
// src/lib/chat/runHooks.ts
|
|
31288
31324
|
function composeHooks(hooks) {
|
|
@@ -33433,22 +33469,6 @@ function linkAbortSignals(a, b) {
|
|
|
33433
33469
|
}
|
|
33434
33470
|
};
|
|
33435
33471
|
}
|
|
33436
|
-
function validateEndpointOverride(override) {
|
|
33437
|
-
const trimmed = override.trim();
|
|
33438
|
-
if (trimmed === "") {
|
|
33439
|
-
return {
|
|
33440
|
-
valid: false,
|
|
33441
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
33442
|
-
};
|
|
33443
|
-
}
|
|
33444
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
33445
|
-
return {
|
|
33446
|
-
valid: false,
|
|
33447
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
33448
|
-
};
|
|
33449
|
-
}
|
|
33450
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
33451
|
-
}
|
|
33452
33472
|
async function runToolLoop(options) {
|
|
33453
33473
|
const {
|
|
33454
33474
|
model,
|
package/dist/server/index.d.mts
CHANGED
|
@@ -2516,6 +2516,33 @@ type StreamingTransportResult = {
|
|
|
2516
2516
|
* transport both honor this contract.
|
|
2517
2517
|
*/
|
|
2518
2518
|
type StreamingTransport = (options: StreamingTransportOptions) => StreamingTransportResult;
|
|
2519
|
+
/**
|
|
2520
|
+
* Framework-agnostic tool execution loop.
|
|
2521
|
+
*
|
|
2522
|
+
* Sends a streaming completion request, auto-executes tools that have executors,
|
|
2523
|
+
* feeds results back to the model, and repeats until the model stops emitting
|
|
2524
|
+
* tool calls or hits the iteration limit.
|
|
2525
|
+
*
|
|
2526
|
+
* This is the same loop that powers `useChat` in the React SDK, extracted so
|
|
2527
|
+
* it can be used from Node.js servers, CLI tools, and background workers.
|
|
2528
|
+
*
|
|
2529
|
+
* @example
|
|
2530
|
+
* ```ts
|
|
2531
|
+
* import { runToolLoop } from "@anuma/sdk/server";
|
|
2532
|
+
*
|
|
2533
|
+
* const result = await runToolLoop({
|
|
2534
|
+
* messages: [{ role: "user", content: [{ type: "text", text: "What's the weather?" }] }],
|
|
2535
|
+
* model: "fireworks/accounts/fireworks/models/kimi-k2p5",
|
|
2536
|
+
* token: "my-api-token",
|
|
2537
|
+
* tools: [{
|
|
2538
|
+
* type: "function",
|
|
2539
|
+
* function: { name: "get_weather", parameters: { type: "object", properties: { city: { type: "string" } } } },
|
|
2540
|
+
* executor: async ({ city }) => fetchWeather(city),
|
|
2541
|
+
* }],
|
|
2542
|
+
* onData: (chunk) => process.stdout.write(chunk),
|
|
2543
|
+
* });
|
|
2544
|
+
* ```
|
|
2545
|
+
*/
|
|
2519
2546
|
declare function runToolLoop(options: RunToolLoopOptions): Promise<RunToolLoopResult>;
|
|
2520
2547
|
|
|
2521
2548
|
/**
|
|
@@ -8146,6 +8173,15 @@ interface TopicExtractionInput {
|
|
|
8146
8173
|
*/
|
|
8147
8174
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
8148
8175
|
baseUrl?: string;
|
|
8176
|
+
/**
|
|
8177
|
+
* Optional per-call request path override, forwarded to
|
|
8178
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
8179
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
8180
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
8181
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
8182
|
+
* call time (see {@link validateEndpointOverride}).
|
|
8183
|
+
*/
|
|
8184
|
+
endpointOverride?: string;
|
|
8149
8185
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
8150
8186
|
* model. Don't point this at a second model without an eval. */
|
|
8151
8187
|
model?: string;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -2516,6 +2516,33 @@ type StreamingTransportResult = {
|
|
|
2516
2516
|
* transport both honor this contract.
|
|
2517
2517
|
*/
|
|
2518
2518
|
type StreamingTransport = (options: StreamingTransportOptions) => StreamingTransportResult;
|
|
2519
|
+
/**
|
|
2520
|
+
* Framework-agnostic tool execution loop.
|
|
2521
|
+
*
|
|
2522
|
+
* Sends a streaming completion request, auto-executes tools that have executors,
|
|
2523
|
+
* feeds results back to the model, and repeats until the model stops emitting
|
|
2524
|
+
* tool calls or hits the iteration limit.
|
|
2525
|
+
*
|
|
2526
|
+
* This is the same loop that powers `useChat` in the React SDK, extracted so
|
|
2527
|
+
* it can be used from Node.js servers, CLI tools, and background workers.
|
|
2528
|
+
*
|
|
2529
|
+
* @example
|
|
2530
|
+
* ```ts
|
|
2531
|
+
* import { runToolLoop } from "@anuma/sdk/server";
|
|
2532
|
+
*
|
|
2533
|
+
* const result = await runToolLoop({
|
|
2534
|
+
* messages: [{ role: "user", content: [{ type: "text", text: "What's the weather?" }] }],
|
|
2535
|
+
* model: "fireworks/accounts/fireworks/models/kimi-k2p5",
|
|
2536
|
+
* token: "my-api-token",
|
|
2537
|
+
* tools: [{
|
|
2538
|
+
* type: "function",
|
|
2539
|
+
* function: { name: "get_weather", parameters: { type: "object", properties: { city: { type: "string" } } } },
|
|
2540
|
+
* executor: async ({ city }) => fetchWeather(city),
|
|
2541
|
+
* }],
|
|
2542
|
+
* onData: (chunk) => process.stdout.write(chunk),
|
|
2543
|
+
* });
|
|
2544
|
+
* ```
|
|
2545
|
+
*/
|
|
2519
2546
|
declare function runToolLoop(options: RunToolLoopOptions): Promise<RunToolLoopResult>;
|
|
2520
2547
|
|
|
2521
2548
|
/**
|
|
@@ -8146,6 +8173,15 @@ interface TopicExtractionInput {
|
|
|
8146
8173
|
*/
|
|
8147
8174
|
interface TopicExtractOptions extends PortalLlmAuth {
|
|
8148
8175
|
baseUrl?: string;
|
|
8176
|
+
/**
|
|
8177
|
+
* Optional per-call request path override, forwarded to
|
|
8178
|
+
* {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
|
|
8179
|
+
* `baseUrl + endpointOverride` instead of the default
|
|
8180
|
+
* `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
|
|
8181
|
+
* this internal-utility pass to a dedicated endpoint. Invalid values throw at
|
|
8182
|
+
* call time (see {@link validateEndpointOverride}).
|
|
8183
|
+
*/
|
|
8184
|
+
endpointOverride?: string;
|
|
8149
8185
|
/** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
|
|
8150
8186
|
* model. Don't point this at a second model without an eval. */
|
|
8151
8187
|
model?: string;
|
package/dist/server/index.mjs
CHANGED
|
@@ -125,7 +125,7 @@ import {
|
|
|
125
125
|
updateVaultMemoryOp,
|
|
126
126
|
upsertMessageOp,
|
|
127
127
|
vaultMemoryToStored
|
|
128
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-LSKFJNLF.mjs";
|
|
129
129
|
import {
|
|
130
130
|
createStreamingDeAnonymizer,
|
|
131
131
|
resolvePiiRedactor
|
|
@@ -135,8 +135,9 @@ import {
|
|
|
135
135
|
extractJsonCandidate,
|
|
136
136
|
getLogger,
|
|
137
137
|
resolvePortalAuthHeaders,
|
|
138
|
-
supportsResponseFormat
|
|
139
|
-
|
|
138
|
+
supportsResponseFormat,
|
|
139
|
+
validateEndpointOverride
|
|
140
|
+
} from "./chunk-MIXEASUP.mjs";
|
|
140
141
|
import {
|
|
141
142
|
BASE_URL,
|
|
142
143
|
__commonJS,
|
|
@@ -5315,7 +5316,7 @@ async function tryConsolidate(trimmed, ctx, options) {
|
|
|
5315
5316
|
content: m.content,
|
|
5316
5317
|
similarity: m.similarity
|
|
5317
5318
|
}));
|
|
5318
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
5319
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-PCHO3D3G.mjs");
|
|
5319
5320
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
5320
5321
|
if (decision.action === "create") return null;
|
|
5321
5322
|
if (decision.action === "supersede" && decision.targetId && decision.content) {
|
|
@@ -7058,6 +7059,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
|
|
|
7058
7059
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
7059
7060
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
7060
7061
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
7062
|
+
...options.endpointOverride !== void 0 && {
|
|
7063
|
+
endpointOverride: options.endpointOverride
|
|
7064
|
+
},
|
|
7061
7065
|
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
7062
7066
|
systemPrompt: SYSTEM_PROMPT4,
|
|
7063
7067
|
userMessage: `${vocabularyNote}Memories:
|
|
@@ -11326,22 +11330,6 @@ function linkAbortSignals(a, b) {
|
|
|
11326
11330
|
}
|
|
11327
11331
|
};
|
|
11328
11332
|
}
|
|
11329
|
-
function validateEndpointOverride(override) {
|
|
11330
|
-
const trimmed = override.trim();
|
|
11331
|
-
if (trimmed === "") {
|
|
11332
|
-
return {
|
|
11333
|
-
valid: false,
|
|
11334
|
-
message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
|
|
11335
|
-
};
|
|
11336
|
-
}
|
|
11337
|
-
if (trimmed.startsWith("//") || trimmed.includes("://")) {
|
|
11338
|
-
return {
|
|
11339
|
-
valid: false,
|
|
11340
|
-
message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
|
|
11341
|
-
};
|
|
11342
|
-
}
|
|
11343
|
-
return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
|
|
11344
|
-
}
|
|
11345
11333
|
async function runToolLoop(options) {
|
|
11346
11334
|
const {
|
|
11347
11335
|
model,
|