@remnic/plugin-openclaw 1.0.34 → 1.0.36
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/README.md +59 -10
- package/dist/{calibration-JD4AU7FB.js → calibration-RKL2LRW4.js} +4 -4
- package/dist/{capsule-cli-GBM3WPAM.js → capsule-cli-EHZPMXBC.js} +2 -2
- package/dist/{capsule-crypto-K3IRTKRH.js → capsule-crypto-JS67OSWM.js} +3 -3
- package/dist/capsule-export-YPDWRB3C.js +17 -0
- package/dist/capsule-import-SWPOFG6F.js +16 -0
- package/dist/{capsule-merge-IWOQ34KL.js → capsule-merge-YXAF7ZJW.js} +7 -7
- package/dist/{causal-chain-WYN5QOPS.js → causal-chain-BVTOWZKC.js} +4 -4
- package/dist/{causal-consolidation-DSLFN64P.js → causal-consolidation-DRPM2KOE.js} +13 -10
- package/dist/{causal-retrieval-NZHQOZOE.js → causal-retrieval-XAP6QKHZ.js} +4 -5
- package/dist/{causal-trajectory-graph-VBPE2WPM.js → causal-trajectory-graph-ZWQWZ7N5.js} +2 -2
- package/dist/{chunk-5LE4HTVL.js → chunk-25J4PXDH.js} +0 -18
- package/dist/{chunk-FGTYFLL5.js → chunk-3IHGISUN.js} +29 -32
- package/dist/{chunk-6UFI73TJ.js → chunk-3IKMUNW5.js} +53 -46
- package/dist/{chunk-EXDYWXMB.js → chunk-4XDQ3KEC.js} +1 -2
- package/dist/{chunk-4UA6KMRO.js → chunk-6O3H3DPL.js} +2 -2
- package/dist/{chunk-7NMHI4IC.js → chunk-BLC3RQNV.js} +5 -555
- package/dist/{chunk-4G2XCSD2.js → chunk-BZ4EYURA.js} +0 -5
- package/dist/{chunk-4LYQ4ONL.js → chunk-E4RM7637.js} +1 -1
- package/dist/{chunk-TDRJVMUP.js → chunk-EH4AXGRO.js} +0 -12
- package/dist/{chunk-ZXLYEVOP.js → chunk-G3CZA4SD.js} +60 -362
- package/dist/chunk-I2KLQ2HA.js +22 -0
- package/dist/chunk-IO5WWY6A.js +156 -0
- package/dist/{contradiction-scan-U3QKHWQN.js → chunk-JC3FCKYL.js} +191 -87
- package/dist/{chunk-SVSQAG6M.js → chunk-KC7KSQR4.js} +47 -28
- package/dist/chunk-LZCGPRHS.js +228 -0
- package/dist/{chunk-CXM7EBAO.js → chunk-MXFJXUHC.js} +1 -1
- package/dist/{chunk-L6I4MQKO.js → chunk-NNAN63QK.js} +6 -6
- package/dist/{chunk-VRGUUHBV.js → chunk-NUWDSTP7.js} +1 -1
- package/dist/{chunk-6OJAU466.js → chunk-QMUQV5NP.js} +0 -1
- package/dist/{chunk-LLUROTZJ.js → chunk-QQXJODFL.js} +9 -9
- package/dist/{chunk-6F6EKSVP.js → chunk-QXXEF7VI.js} +1 -1
- package/dist/{chunk-NDZNURDM.js → chunk-SEGEX7W4.js} +73 -241
- package/dist/{chunk-7NUFIRM3.js → chunk-SWOYEQN2.js} +97 -21
- package/dist/chunk-TH5FF5SC.js +16 -0
- package/dist/chunk-UZJ7EERS.js +272 -0
- package/dist/chunk-YJYZMLD5.js +360 -0
- package/dist/{chunk-NKVIN6RD.js → chunk-YKV4EFUI.js} +84 -2
- package/dist/{chunk-SSFTU6LP.js → chunk-ZS6VABML.js} +4 -4
- package/dist/{cipher-VHAFCG7Z.js → cipher-E23BHBSO.js} +1 -1
- package/dist/{consolidation-undo-5ZSX4MWO.js → consolidation-undo-FKJZCJHS.js} +2 -2
- package/dist/contradiction-review-WJRWNQ5N.js +29 -0
- package/dist/contradiction-scan-5X423QGT.js +12 -0
- package/dist/{dreams-ledger-3I52ISYR.js → dreams-ledger-KDX44I7R.js} +1 -1
- package/dist/{engine-57HLTQBN.js → engine-5P774HTZ.js} +6 -6
- package/dist/{extraction-judge-telemetry-GHOTVYMP.js → extraction-judge-telemetry-O4ZVGLTU.js} +1 -1
- package/dist/{fallback-llm-33SPYXQY.js → fallback-llm-43UMEXNJ.js} +3 -3
- package/dist/{first-start-migration-I24M2JEE.js → first-start-migration-H2SAXAGR.js} +4 -4
- package/dist/{forget-NI4RBDPB.js → forget-ZECIDNL5.js} +1 -1
- package/dist/{fs-utils-PZRI2HDZ.js → fs-utils-OYXSZSVV.js} +12 -2
- package/dist/{graph-edge-decay-5CVKWBYH.js → graph-edge-decay-24ZKD5QL.js} +5 -5
- package/dist/index.js +7187 -71983
- package/dist/{kdf-H5B23ZM2.js → kdf-RXKIWHRU.js} +1 -1
- package/dist/legacy-hook-compat-QHHKF4GK.js +2 -0
- package/dist/{logger-TNOKCH7X.js → logger-XG7JKLPS.js} +1 -1
- package/dist/{memory-governance-FEQCA35V.js → memory-governance-6K4M4YXD.js} +5 -5
- package/dist/{metadata-JAGIWHEA.js → metadata-WK2TRPYZ.js} +1 -1
- package/dist/{migrate-from-identity-anchor-7MMSPEUM.js → migrate-from-identity-anchor-SNDNKHZD.js} +1 -1
- package/dist/path-ZKO74XXC.js +7 -0
- package/dist/{peers-KRFXWRQ6.js → peers-W53WSDXG.js} +1 -1
- package/dist/{purge-XN2VSPZ2.js → purge-IKJISXEQ.js} +1 -1
- package/dist/resolution-BN35OXDS.js +11 -0
- package/dist/{secure-store-A4NGCNXV.js → secure-store-F75I54O5.js} +3 -3
- package/dist/{state-PVISYXRH.js → state-4ITLYMAU.js} +1 -1
- package/dist/{state-store-N6TFBFSP.js → state-store-ET3ADVY5.js} +3 -3
- package/dist/{storage-R3V6ZFQT.js → storage-5EY6T7ON.js} +3 -3
- package/dist/{tier-stats-IZNW66NC.js → tier-stats-ZRQBV6G2.js} +4 -4
- package/dist/{trace-NJESSGH7.js → trace-IL2Y34EH.js} +1 -1
- package/dist/{tui-MGK2LYJY.js → tui-7KRDCMYK.js} +1 -1
- package/dist/{types-R4DO7AKM.js → types-7L34HYDW.js} +3 -3
- package/openclaw.plugin.json +153 -20
- package/package.json +18 -9
- package/scripts/faiss_index.py +756 -0
- package/scripts/faiss_requirements.txt +3 -0
- package/dist/capsule-export-IXVERCQG.js +0 -17
- package/dist/capsule-import-IA6VIOPQ.js +0 -16
- package/dist/chunk-3GUF7RQI.js +0 -559
- package/dist/chunk-7OQEPGQF.js +0 -533
- package/dist/chunk-DIZW6H5J.js +0 -136
- package/dist/chunk-FQRSVYY4.js +0 -110
- package/dist/chunk-GUSMRW4H.js +0 -12
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-WPINX4MF.js +0 -380
- package/dist/contradiction-review-SVGBS3V5.js +0 -21
- package/dist/legacy-hook-compat-XQ7FP6FV.js +0 -35
- package/dist/path-JIEGNWFL.js +0 -7
- package/dist/resolution-YITUVUTH.js +0 -100
|
@@ -1,29 +1,42 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./chunk-WPINX4MF.js";
|
|
2
|
+
isSafeRouteNamespace
|
|
3
|
+
} from "./chunk-TH5FF5SC.js";
|
|
5
4
|
import {
|
|
6
|
-
StorageManager
|
|
7
|
-
|
|
8
|
-
} from "./chunk-ZXLYEVOP.js";
|
|
5
|
+
StorageManager
|
|
6
|
+
} from "./chunk-G3CZA4SD.js";
|
|
9
7
|
import {
|
|
10
8
|
log
|
|
11
9
|
} from "./chunk-UFU5GGGA.js";
|
|
12
10
|
import {
|
|
13
11
|
readEnvVar,
|
|
14
12
|
resolveHomeDir
|
|
15
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EH4AXGRO.js";
|
|
16
14
|
|
|
17
15
|
// ../remnic-core/src/connectors/codex-materialize-runner.ts
|
|
18
|
-
import path2 from "path";
|
|
19
16
|
import { existsSync } from "fs";
|
|
20
17
|
|
|
18
|
+
// ../remnic-core/src/namespaces/path.ts
|
|
19
|
+
import path from "path";
|
|
20
|
+
function assertNamespacePathInsideRoot(root, candidate, namespace, label = "namespace path") {
|
|
21
|
+
const relative = path.relative(root, candidate);
|
|
22
|
+
if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`invalid ${label}: ${namespace}`);
|
|
26
|
+
}
|
|
27
|
+
function resolveNamespaceChildRoot(memoryDir, namespace, label = "namespace path") {
|
|
28
|
+
const namespaceRoot = path.resolve(memoryDir, "namespaces");
|
|
29
|
+
const candidate = path.resolve(namespaceRoot, namespace);
|
|
30
|
+
assertNamespacePathInsideRoot(namespaceRoot, candidate, namespace, label);
|
|
31
|
+
return candidate;
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
// ../remnic-core/src/connectors/codex-materialize.ts
|
|
22
35
|
import {
|
|
23
36
|
createHash
|
|
24
37
|
} from "crypto";
|
|
25
38
|
import fs from "fs";
|
|
26
|
-
import
|
|
39
|
+
import path2 from "path";
|
|
27
40
|
var MATERIALIZE_VERSION = 1;
|
|
28
41
|
var SENTINEL_FILE = ".remnic-managed";
|
|
29
42
|
var TMP_DIR = ".remnic-tmp";
|
|
@@ -34,12 +47,11 @@ function materializeForNamespace(namespace, options) {
|
|
|
34
47
|
warn: (msg) => log.warn(`[codex-materialize] ${msg}`),
|
|
35
48
|
debug: (msg) => log.debug(`[codex-materialize] ${msg}`)
|
|
36
49
|
};
|
|
37
|
-
const
|
|
38
|
-
const memoriesDir = path.join(codexHome, "memories");
|
|
50
|
+
const memoriesDir = resolveCodexMemoriesDir(options.codexHome);
|
|
39
51
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
40
52
|
const maxSummaryTokens = typeof options.maxSummaryTokens === "number" && options.maxSummaryTokens >= 0 ? options.maxSummaryTokens : 4500;
|
|
41
53
|
const rolloutRetentionDays = typeof options.rolloutRetentionDays === "number" && options.rolloutRetentionDays >= 0 ? options.rolloutRetentionDays : 30;
|
|
42
|
-
const sentinelPath =
|
|
54
|
+
const sentinelPath = path2.join(memoriesDir, SENTINEL_FILE);
|
|
43
55
|
const existingSentinel = readSentinel(sentinelPath);
|
|
44
56
|
if (!existingSentinel) {
|
|
45
57
|
if (fs.existsSync(memoriesDir)) {
|
|
@@ -117,10 +129,10 @@ function materializeForNamespace(namespace, options) {
|
|
|
117
129
|
});
|
|
118
130
|
if (existingSentinel.content_hash === hash) {
|
|
119
131
|
const requiredFiles = [
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
...rolloutFiles.map((r) =>
|
|
132
|
+
path2.join(memoriesDir, "memory_summary.md"),
|
|
133
|
+
path2.join(memoriesDir, "MEMORY.md"),
|
|
134
|
+
path2.join(memoriesDir, "raw_memories.md"),
|
|
135
|
+
...rolloutFiles.map((r) => path2.join(memoriesDir, ROLLOUT_SUBDIR, r.name))
|
|
124
136
|
];
|
|
125
137
|
const allPresent = requiredFiles.every((f) => fs.existsSync(f));
|
|
126
138
|
if (allPresent) {
|
|
@@ -140,14 +152,14 @@ function materializeForNamespace(namespace, options) {
|
|
|
140
152
|
);
|
|
141
153
|
}
|
|
142
154
|
const runTag = `${process.pid}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
143
|
-
const tmpDir =
|
|
155
|
+
const tmpDir = path2.join(memoriesDir, `${TMP_DIR}-${runTag}`);
|
|
144
156
|
const TMP_STALE_MS = 60 * 60 * 1e3;
|
|
145
157
|
const wallClockMs = Date.now();
|
|
146
158
|
try {
|
|
147
159
|
for (const entry of fs.readdirSync(memoriesDir, { withFileTypes: true })) {
|
|
148
160
|
if (!entry.isDirectory()) continue;
|
|
149
161
|
if (!entry.name.startsWith(TMP_DIR)) continue;
|
|
150
|
-
const stalePath =
|
|
162
|
+
const stalePath = path2.join(memoriesDir, entry.name);
|
|
151
163
|
try {
|
|
152
164
|
const stat = fs.statSync(stalePath);
|
|
153
165
|
if (wallClockMs - stat.mtimeMs < TMP_STALE_MS) continue;
|
|
@@ -158,24 +170,24 @@ function materializeForNamespace(namespace, options) {
|
|
|
158
170
|
} catch {
|
|
159
171
|
}
|
|
160
172
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
161
|
-
fs.mkdirSync(
|
|
173
|
+
fs.mkdirSync(path2.join(tmpDir, ROLLOUT_SUBDIR), { recursive: true });
|
|
162
174
|
const filesWritten = [];
|
|
163
|
-
fs.writeFileSync(
|
|
175
|
+
fs.writeFileSync(path2.join(tmpDir, "memory_summary.md"), memorySummary);
|
|
164
176
|
filesWritten.push("memory_summary.md");
|
|
165
|
-
fs.writeFileSync(
|
|
177
|
+
fs.writeFileSync(path2.join(tmpDir, "MEMORY.md"), memoryMd);
|
|
166
178
|
filesWritten.push("MEMORY.md");
|
|
167
|
-
fs.writeFileSync(
|
|
179
|
+
fs.writeFileSync(path2.join(tmpDir, "raw_memories.md"), rawMemories);
|
|
168
180
|
filesWritten.push("raw_memories.md");
|
|
169
181
|
for (const rollout of rolloutFiles) {
|
|
170
|
-
fs.writeFileSync(
|
|
171
|
-
filesWritten.push(
|
|
182
|
+
fs.writeFileSync(path2.join(tmpDir, ROLLOUT_SUBDIR, rollout.name), rollout.body);
|
|
183
|
+
filesWritten.push(path2.join(ROLLOUT_SUBDIR, rollout.name));
|
|
172
184
|
}
|
|
173
185
|
for (const rel of ["memory_summary.md", "MEMORY.md", "raw_memories.md"]) {
|
|
174
|
-
const src =
|
|
175
|
-
const dest =
|
|
186
|
+
const src = path2.join(tmpDir, rel);
|
|
187
|
+
const dest = path2.join(memoriesDir, rel);
|
|
176
188
|
fs.renameSync(src, dest);
|
|
177
189
|
}
|
|
178
|
-
const destRolloutsDir =
|
|
190
|
+
const destRolloutsDir = path2.join(memoriesDir, ROLLOUT_SUBDIR);
|
|
179
191
|
fs.mkdirSync(destRolloutsDir, { recursive: true });
|
|
180
192
|
if (rolloutsSupplied) {
|
|
181
193
|
const retainedRolloutNames = new Set(rolloutFiles.map((r) => r.name));
|
|
@@ -185,7 +197,7 @@ function materializeForNamespace(namespace, options) {
|
|
|
185
197
|
if (!entry.name.endsWith(".md")) continue;
|
|
186
198
|
if (retainedRolloutNames.has(entry.name)) continue;
|
|
187
199
|
try {
|
|
188
|
-
fs.unlinkSync(
|
|
200
|
+
fs.unlinkSync(path2.join(destRolloutsDir, entry.name));
|
|
189
201
|
} catch {
|
|
190
202
|
}
|
|
191
203
|
}
|
|
@@ -193,8 +205,8 @@ function materializeForNamespace(namespace, options) {
|
|
|
193
205
|
}
|
|
194
206
|
}
|
|
195
207
|
for (const rollout of rolloutFiles) {
|
|
196
|
-
const src =
|
|
197
|
-
const dest =
|
|
208
|
+
const src = path2.join(tmpDir, ROLLOUT_SUBDIR, rollout.name);
|
|
209
|
+
const dest = path2.join(destRolloutsDir, rollout.name);
|
|
198
210
|
fs.renameSync(src, dest);
|
|
199
211
|
}
|
|
200
212
|
const sentinel = {
|
|
@@ -419,7 +431,13 @@ function resolveCodexHome(override) {
|
|
|
419
431
|
if (override && override.trim().length > 0) return override;
|
|
420
432
|
const fromEnv = readEnvVar("CODEX_HOME");
|
|
421
433
|
if (fromEnv && fromEnv.trim().length > 0) return fromEnv;
|
|
422
|
-
return
|
|
434
|
+
return path2.join(resolveHomeDir(), ".codex");
|
|
435
|
+
}
|
|
436
|
+
function resolveCodexMemoriesDir(codexHome) {
|
|
437
|
+
return path2.join(resolveCodexHome(codexHome), "memories");
|
|
438
|
+
}
|
|
439
|
+
function hasCodexMaterializeSentinel(codexHome) {
|
|
440
|
+
return readSentinel(path2.join(resolveCodexMemoriesDir(codexHome), SENTINEL_FILE)) !== null;
|
|
423
441
|
}
|
|
424
442
|
function readSentinel(sentinelPath) {
|
|
425
443
|
if (!fs.existsSync(sentinelPath)) return null;
|
|
@@ -567,16 +585,19 @@ async function runCodexMaterialize(options) {
|
|
|
567
585
|
if (options.memories) {
|
|
568
586
|
memories = options.memories;
|
|
569
587
|
} else {
|
|
588
|
+
if (!hasCodexMaterializeSentinel(options.codexHome)) {
|
|
589
|
+
return materializeForNamespace(namespace, {
|
|
590
|
+
memories: [],
|
|
591
|
+
codexHome: options.codexHome,
|
|
592
|
+
maxSummaryTokens: cfg.codexMaterializeMaxSummaryTokens,
|
|
593
|
+
rolloutRetentionDays: cfg.codexMaterializeRolloutRetentionDays,
|
|
594
|
+
rolloutSummaries: options.rolloutSummaries,
|
|
595
|
+
now: options.now
|
|
596
|
+
});
|
|
597
|
+
}
|
|
570
598
|
const nsDir = resolveNamespaceDir(memoryDir, namespace, cfg);
|
|
571
599
|
const storage = new StorageManager(nsDir);
|
|
572
|
-
|
|
573
|
-
memories = await storage.readAllMemories();
|
|
574
|
-
} catch (error) {
|
|
575
|
-
log.warn(
|
|
576
|
-
`[codex-materialize] skipped \u2014 failed to read memories from ${nsDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
577
|
-
);
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
600
|
+
memories = await storage.readAllMemories();
|
|
580
601
|
}
|
|
581
602
|
const result = materializeForNamespace(namespace, {
|
|
582
603
|
memories,
|
|
@@ -616,16 +637,22 @@ async function runPostConsolidationMaterialize(logPrefix, options) {
|
|
|
616
637
|
}
|
|
617
638
|
function resolveNamespace(override, cfg) {
|
|
618
639
|
const requested = (override ?? cfg.codexMaterializeNamespace ?? "auto").trim();
|
|
619
|
-
|
|
620
|
-
|
|
640
|
+
const defaultNamespace = (cfg.defaultNamespace ?? "").trim();
|
|
641
|
+
const namespace = requested.length === 0 || requested === "auto" ? defaultNamespace.length > 0 ? defaultNamespace : "default" : requested;
|
|
642
|
+
if (!isSafeRouteNamespace(namespace)) {
|
|
643
|
+
throw new Error(`invalid materialize namespace: ${namespace}`);
|
|
621
644
|
}
|
|
622
|
-
return
|
|
645
|
+
return namespace;
|
|
623
646
|
}
|
|
624
647
|
function resolveNamespaceDir(memoryDir, namespace, cfg) {
|
|
625
648
|
if (!cfg.namespacesEnabled) return memoryDir;
|
|
626
|
-
const
|
|
627
|
-
const
|
|
628
|
-
if (ns
|
|
649
|
+
const defaultNamespace = (cfg.defaultNamespace ?? "").trim();
|
|
650
|
+
const ns = (namespace || defaultNamespace || "default").trim();
|
|
651
|
+
if (!isSafeRouteNamespace(ns)) {
|
|
652
|
+
throw new Error(`invalid materialize namespace: ${ns}`);
|
|
653
|
+
}
|
|
654
|
+
const namespacedRoot = resolveNamespaceChildRoot(memoryDir, ns, "materialize namespace path");
|
|
655
|
+
if (ns === defaultNamespace) {
|
|
629
656
|
return existsSync(namespacedRoot) ? namespacedRoot : memoryDir;
|
|
630
657
|
}
|
|
631
658
|
return namespacedRoot;
|
|
@@ -853,190 +880,8 @@ ${ext.instructions}
|
|
|
853
880
|
}
|
|
854
881
|
return result;
|
|
855
882
|
}
|
|
856
|
-
function renderExtensionsFooter(extensions) {
|
|
857
|
-
if (extensions.length === 0) return "";
|
|
858
|
-
const names = extensions.map((ext) => ext.name).join(", ");
|
|
859
|
-
return `Active extensions: ${names}`;
|
|
860
|
-
}
|
|
861
883
|
|
|
862
884
|
// ../remnic-core/src/semantic-consolidation.ts
|
|
863
|
-
function findSimilarClusters(memories, config) {
|
|
864
|
-
const excluded = new Set(config.excludeCategories);
|
|
865
|
-
const byCategory = /* @__PURE__ */ new Map();
|
|
866
|
-
for (const m of memories) {
|
|
867
|
-
const cat = m.frontmatter.category;
|
|
868
|
-
if (excluded.has(cat)) continue;
|
|
869
|
-
if (m.frontmatter.status && m.frontmatter.status !== "active") continue;
|
|
870
|
-
const list = byCategory.get(cat) ?? [];
|
|
871
|
-
list.push(m);
|
|
872
|
-
byCategory.set(cat, list);
|
|
873
|
-
}
|
|
874
|
-
const clusters = [];
|
|
875
|
-
let totalCandidates = 0;
|
|
876
|
-
for (const [category, mems] of byCategory) {
|
|
877
|
-
if (totalCandidates >= config.maxPerRun) break;
|
|
878
|
-
const tokenized = mems.map((m) => ({
|
|
879
|
-
memory: m,
|
|
880
|
-
tokens: new Set(normalizeRecallTokens(m.content, []))
|
|
881
|
-
}));
|
|
882
|
-
const clustered = /* @__PURE__ */ new Set();
|
|
883
|
-
for (let i = 0; i < tokenized.length && totalCandidates < config.maxPerRun; i++) {
|
|
884
|
-
if (clustered.has(tokenized[i].memory.frontmatter.id)) continue;
|
|
885
|
-
const cluster = [tokenized[i].memory];
|
|
886
|
-
let totalOverlap = 0;
|
|
887
|
-
let comparisons = 0;
|
|
888
|
-
for (let j = i + 1; j < tokenized.length; j++) {
|
|
889
|
-
if (clustered.has(tokenized[j].memory.frontmatter.id)) continue;
|
|
890
|
-
const aTokens = tokenized[i].tokens;
|
|
891
|
-
const bTokens = tokenized[j].tokens;
|
|
892
|
-
if (aTokens.size === 0 || bTokens.size === 0) continue;
|
|
893
|
-
const overlap = countRecallTokenOverlap(aTokens, [...bTokens].join(" "));
|
|
894
|
-
const maxTokens = Math.max(aTokens.size, bTokens.size);
|
|
895
|
-
const score = maxTokens > 0 ? overlap / maxTokens : 0;
|
|
896
|
-
if (score >= config.threshold) {
|
|
897
|
-
cluster.push(tokenized[j].memory);
|
|
898
|
-
totalOverlap += score;
|
|
899
|
-
comparisons++;
|
|
900
|
-
if (totalCandidates + cluster.length >= config.maxPerRun) break;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
if (cluster.length >= config.minClusterSize) {
|
|
904
|
-
for (const m of cluster) clustered.add(m.frontmatter.id);
|
|
905
|
-
clusters.push({
|
|
906
|
-
category,
|
|
907
|
-
memories: cluster,
|
|
908
|
-
overlapScore: comparisons > 0 ? totalOverlap / comparisons : 0
|
|
909
|
-
});
|
|
910
|
-
totalCandidates += cluster.length;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
return clusters;
|
|
915
|
-
}
|
|
916
|
-
function buildConsolidationPrompt(cluster) {
|
|
917
|
-
const memoryTexts = cluster.memories.map(
|
|
918
|
-
(m, i) => `Memory ${i + 1} (${m.frontmatter.id}, created ${m.frontmatter.created}):
|
|
919
|
-
${m.content}`
|
|
920
|
-
).join("\n\n");
|
|
921
|
-
return `You are a memory consolidation system. The following ${cluster.memories.length} memories in the "${cluster.category}" category contain overlapping information.
|
|
922
|
-
|
|
923
|
-
Synthesize them into ONE canonical memory that:
|
|
924
|
-
1. Preserves ALL unique information from every source memory
|
|
925
|
-
2. Removes redundancy and repetition
|
|
926
|
-
3. Uses clear, concise language
|
|
927
|
-
4. Maintains the same category and tone
|
|
928
|
-
5. Does NOT add information that isn't in the sources
|
|
929
|
-
|
|
930
|
-
${memoryTexts}
|
|
931
|
-
|
|
932
|
-
Write ONLY the consolidated memory content (no metadata, no explanation, no preamble):`;
|
|
933
|
-
}
|
|
934
|
-
function parseConsolidationResponse(response) {
|
|
935
|
-
return response.trim();
|
|
936
|
-
}
|
|
937
|
-
function chooseConsolidationOperator(cluster) {
|
|
938
|
-
if (cluster.memories.length <= 1) return "update";
|
|
939
|
-
return "merge";
|
|
940
|
-
}
|
|
941
|
-
function buildOperatorAwareConsolidationPrompt(cluster) {
|
|
942
|
-
const memoryTexts = cluster.memories.map(
|
|
943
|
-
(m, i) => `Memory ${i + 1} (${m.frontmatter.id}, created ${m.frontmatter.created}):
|
|
944
|
-
${m.content}`
|
|
945
|
-
).join("\n\n");
|
|
946
|
-
return `You are a memory consolidation system. The following ${cluster.memories.length} memories in the "${cluster.category}" category contain overlapping information.
|
|
947
|
-
|
|
948
|
-
Pick exactly ONE consolidation operator for this cluster and return a JSON object.
|
|
949
|
-
|
|
950
|
-
Operator vocabulary:
|
|
951
|
-
- "merge" \u2014 multiple distinct source memories overlap and should be collapsed into one canonical memory (most common).
|
|
952
|
-
- "update" \u2014 one source memory carries a stale value that a newer source supersedes within the same logical fact.
|
|
953
|
-
- "split" \u2014 a single logical source really encodes multiple distinct facts that should be separated (rare; if you pick split, still emit ONE canonical body \u2014 the write path will chunk it later).
|
|
954
|
-
|
|
955
|
-
Output JSON ONLY, no prose before or after. The "operator" key MUST be set to exactly one of the three strings "merge", "update", or "split" \u2014 never a pipe-separated placeholder like "merge|update|split". Example shape:
|
|
956
|
-
{
|
|
957
|
-
"operator": "merge",
|
|
958
|
-
"output": "<the canonical memory text>"
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
The "output" value must:
|
|
962
|
-
1. Preserve ALL unique information from every source memory
|
|
963
|
-
2. Remove redundancy and repetition
|
|
964
|
-
3. Use clear, concise language
|
|
965
|
-
4. Match the "${cluster.category}" category and tone
|
|
966
|
-
5. NOT add information that isn't in the sources
|
|
967
|
-
|
|
968
|
-
${memoryTexts}
|
|
969
|
-
|
|
970
|
-
Return ONLY the JSON object:`;
|
|
971
|
-
}
|
|
972
|
-
function parseOperatorAwareConsolidationResponse(response, cluster) {
|
|
973
|
-
const fallback = {
|
|
974
|
-
operator: chooseConsolidationOperator(cluster),
|
|
975
|
-
output: response.trim()
|
|
976
|
-
};
|
|
977
|
-
const trimmed = response.trim();
|
|
978
|
-
if (trimmed.length === 0) return fallback;
|
|
979
|
-
const fenced = /^```(?:json)?\s*([\s\S]*?)```\s*$/u.exec(trimmed);
|
|
980
|
-
const payload = fenced ? fenced[1].trim() : trimmed;
|
|
981
|
-
const parsed = findLastJsonObjectWithOperator(payload);
|
|
982
|
-
if (parsed === void 0) return fallback;
|
|
983
|
-
if (typeof parsed !== "object" || parsed === null) return fallback;
|
|
984
|
-
const obj = parsed;
|
|
985
|
-
const rawOperator = typeof obj.operator === "string" ? obj.operator.trim().toLowerCase() : "";
|
|
986
|
-
const rawOutput = typeof obj.output === "string" ? obj.output : "";
|
|
987
|
-
const operator = isSemanticConsolidationLlmOperator(rawOperator) ? rawOperator : chooseConsolidationOperator(cluster);
|
|
988
|
-
const output = rawOutput.trim().length > 0 ? rawOutput.trim() : response.trim();
|
|
989
|
-
return { operator, output };
|
|
990
|
-
}
|
|
991
|
-
function findLastJsonObjectWithOperator(text) {
|
|
992
|
-
let searchFrom = 0;
|
|
993
|
-
let last = void 0;
|
|
994
|
-
while (searchFrom < text.length) {
|
|
995
|
-
const start = text.indexOf("{", searchFrom);
|
|
996
|
-
if (start < 0) return last;
|
|
997
|
-
let depth = 0;
|
|
998
|
-
let inString = false;
|
|
999
|
-
let escape = false;
|
|
1000
|
-
let closed = false;
|
|
1001
|
-
let endIdx = -1;
|
|
1002
|
-
for (let i = start; i < text.length; i++) {
|
|
1003
|
-
const ch = text[i];
|
|
1004
|
-
if (inString) {
|
|
1005
|
-
if (escape) {
|
|
1006
|
-
escape = false;
|
|
1007
|
-
} else if (ch === "\\") {
|
|
1008
|
-
escape = true;
|
|
1009
|
-
} else if (ch === '"') {
|
|
1010
|
-
inString = false;
|
|
1011
|
-
}
|
|
1012
|
-
continue;
|
|
1013
|
-
}
|
|
1014
|
-
if (ch === '"') {
|
|
1015
|
-
inString = true;
|
|
1016
|
-
} else if (ch === "{") {
|
|
1017
|
-
depth += 1;
|
|
1018
|
-
} else if (ch === "}") {
|
|
1019
|
-
depth -= 1;
|
|
1020
|
-
if (depth === 0) {
|
|
1021
|
-
closed = true;
|
|
1022
|
-
endIdx = i;
|
|
1023
|
-
break;
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
if (!closed) return last;
|
|
1028
|
-
const slice = text.slice(start, endIdx + 1);
|
|
1029
|
-
try {
|
|
1030
|
-
const parsed = JSON.parse(slice);
|
|
1031
|
-
if (typeof parsed === "object" && parsed !== null && "operator" in parsed) {
|
|
1032
|
-
last = parsed;
|
|
1033
|
-
}
|
|
1034
|
-
} catch {
|
|
1035
|
-
}
|
|
1036
|
-
searchFrom = endIdx + 1;
|
|
1037
|
-
}
|
|
1038
|
-
return last;
|
|
1039
|
-
}
|
|
1040
885
|
async function buildExtensionsBlockForConsolidation(config) {
|
|
1041
886
|
if (!config.memoryExtensionsEnabled) return "";
|
|
1042
887
|
const root = resolveExtensionsRoot(config);
|
|
@@ -1044,21 +889,8 @@ async function buildExtensionsBlockForConsolidation(config) {
|
|
|
1044
889
|
if (extensions.length === 0) return "";
|
|
1045
890
|
return renderExtensionsBlock(extensions);
|
|
1046
891
|
}
|
|
1047
|
-
async function materializeAfterSemanticConsolidation(options) {
|
|
1048
|
-
return runPostConsolidationMaterialize("[semantic-consolidation]", options);
|
|
1049
|
-
}
|
|
1050
892
|
|
|
1051
893
|
export {
|
|
1052
|
-
discoverMemoryExtensions,
|
|
1053
|
-
resolveExtensionsRoot,
|
|
1054
|
-
renderExtensionsFooter,
|
|
1055
894
|
runPostConsolidationMaterialize,
|
|
1056
|
-
|
|
1057
|
-
buildConsolidationPrompt,
|
|
1058
|
-
parseConsolidationResponse,
|
|
1059
|
-
chooseConsolidationOperator,
|
|
1060
|
-
buildOperatorAwareConsolidationPrompt,
|
|
1061
|
-
parseOperatorAwareConsolidationResponse,
|
|
1062
|
-
buildExtensionsBlockForConsolidation,
|
|
1063
|
-
materializeAfterSemanticConsolidation
|
|
895
|
+
buildExtensionsBlockForConsolidation
|
|
1064
896
|
};
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
expandTildePath,
|
|
9
9
|
readEnvVar,
|
|
10
10
|
resolveHomeDir
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EH4AXGRO.js";
|
|
12
12
|
|
|
13
13
|
// ../remnic-core/src/fallback-llm.ts
|
|
14
14
|
import path2 from "path";
|
|
@@ -66,6 +66,13 @@ var _resolverLoaded = false;
|
|
|
66
66
|
var _resolverNextRetryAt = 0;
|
|
67
67
|
var RESOLVER_RETRY_BACKOFF_MS = 6e4;
|
|
68
68
|
var resolvedCache = /* @__PURE__ */ new Map();
|
|
69
|
+
var cacheObjectIds = /* @__PURE__ */ new WeakMap();
|
|
70
|
+
var nextCacheObjectId = 1;
|
|
71
|
+
var NON_LITERAL_AUTH_MARKERS = /* @__PURE__ */ new Set([
|
|
72
|
+
"secretref-managed",
|
|
73
|
+
"lm-studio"
|
|
74
|
+
]);
|
|
75
|
+
var ENV_VAR_MARKER_RE = /^[A-Z][A-Z0-9_]*(?:_API_KEY|_ACCESS_TOKEN|_TOKEN|_SECRET|_CREDENTIALS|_CREDENTIALS_JSON)$/;
|
|
69
76
|
async function getGatewayResolver() {
|
|
70
77
|
if (_resolverLoaded) {
|
|
71
78
|
return _resolveCredentialForProvider;
|
|
@@ -178,23 +185,59 @@ function findExecutableOnPath(executableName, access, stat, executableMode) {
|
|
|
178
185
|
}
|
|
179
186
|
return void 0;
|
|
180
187
|
}
|
|
188
|
+
function isNonLiteralAuthMarker(value) {
|
|
189
|
+
return NON_LITERAL_AUTH_MARKERS.has(value) || value.endsWith("-oauth") || value.endsWith("-local") || value.startsWith("gcp-") || ENV_VAR_MARKER_RE.test(value);
|
|
190
|
+
}
|
|
191
|
+
function resolveFromNamedEnvVar(marker) {
|
|
192
|
+
if (!ENV_VAR_MARKER_RE.test(marker)) return void 0;
|
|
193
|
+
const value = readEnvVar(marker);
|
|
194
|
+
return value && value.trim().length > 0 ? value.trim() : void 0;
|
|
195
|
+
}
|
|
196
|
+
function cacheIdentity(value) {
|
|
197
|
+
if (value === null) return "null";
|
|
198
|
+
if (value === void 0) return "undefined";
|
|
199
|
+
if (typeof value === "string") return `string:${value}`;
|
|
200
|
+
if (typeof value === "number") return `number:${String(value)}`;
|
|
201
|
+
if (typeof value === "boolean") return `boolean:${String(value)}`;
|
|
202
|
+
if (typeof value === "bigint") return `bigint:${String(value)}`;
|
|
203
|
+
if (typeof value === "symbol" || typeof value === "function") return typeof value;
|
|
204
|
+
if (typeof value === "object") {
|
|
205
|
+
const existingId = cacheObjectIds.get(value);
|
|
206
|
+
if (existingId !== void 0) return `object:${existingId}`;
|
|
207
|
+
const newId = nextCacheObjectId++;
|
|
208
|
+
cacheObjectIds.set(value, newId);
|
|
209
|
+
return `object:${newId}`;
|
|
210
|
+
}
|
|
211
|
+
return String(value);
|
|
212
|
+
}
|
|
213
|
+
function providerSecretCacheKey(providerId, resolvedAgentDir, credentialValue, gatewayConfig) {
|
|
214
|
+
return [
|
|
215
|
+
`provider:${providerId}`,
|
|
216
|
+
`agentDir:${resolvedAgentDir}`,
|
|
217
|
+
`apiKey:${cacheIdentity(credentialValue)}`,
|
|
218
|
+
`cfg:${cacheIdentity(gatewayConfig)}`
|
|
219
|
+
].join(":");
|
|
220
|
+
}
|
|
181
221
|
async function resolveProviderCredential(providerId, credentialValue, gatewayConfig, agentDir) {
|
|
182
222
|
const resolvedAgentDir = path.resolve(
|
|
183
223
|
agentDir ?? path.join(os.homedir(), ".openclaw", "agents", "main", "agent")
|
|
184
224
|
);
|
|
185
|
-
const cacheKey = `provider:${providerId}:agentDir:${resolvedAgentDir}`;
|
|
186
|
-
if (resolvedCache.has(cacheKey)) {
|
|
187
|
-
return resolvedCache.get(cacheKey);
|
|
188
|
-
}
|
|
189
225
|
let resolved;
|
|
190
226
|
if (typeof credentialValue === "string" && credentialValue.trim().length > 0) {
|
|
191
|
-
|
|
227
|
+
const trimmedCredentialValue = credentialValue.trim();
|
|
228
|
+
if (isNonLiteralAuthMarker(trimmedCredentialValue)) {
|
|
229
|
+
const markerEnvValue = resolveFromNamedEnvVar(trimmedCredentialValue);
|
|
230
|
+
if (markerEnvValue) {
|
|
231
|
+
return markerEnvValue;
|
|
232
|
+
}
|
|
192
233
|
} else {
|
|
193
|
-
|
|
194
|
-
resolvedCache.set(cacheKey, resolved);
|
|
195
|
-
return resolved;
|
|
234
|
+
return trimmedCredentialValue;
|
|
196
235
|
}
|
|
197
236
|
}
|
|
237
|
+
const cacheKey = providerSecretCacheKey(providerId, resolvedAgentDir, credentialValue, gatewayConfig);
|
|
238
|
+
if (resolvedCache.has(cacheKey)) {
|
|
239
|
+
return resolvedCache.get(cacheKey);
|
|
240
|
+
}
|
|
198
241
|
const resolver = await getGatewayResolver();
|
|
199
242
|
if (resolver) {
|
|
200
243
|
try {
|
|
@@ -307,7 +350,8 @@ function normalizeCodexCliFallbackConfig(config) {
|
|
|
307
350
|
}
|
|
308
351
|
function normalizeCodexCliFallbackOptions(options) {
|
|
309
352
|
return {
|
|
310
|
-
...options.timeoutMs !== void 0 ? { timeoutMs: normalizeCodexCliTimeoutMs(options.timeoutMs) } : {}
|
|
353
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: normalizeCodexCliTimeoutMs(options.timeoutMs) } : {},
|
|
354
|
+
...options.signal ? { signal: options.signal } : {}
|
|
311
355
|
};
|
|
312
356
|
}
|
|
313
357
|
function normalizeOptionalString(value, label) {
|
|
@@ -381,17 +425,20 @@ var FallbackLlmClient = class {
|
|
|
381
425
|
* When agentId is provided, uses that agent persona's model chain instead of defaults.
|
|
382
426
|
*/
|
|
383
427
|
async chatCompletion(messages, options = {}) {
|
|
384
|
-
const models = this.getModelChain(options.agentId);
|
|
428
|
+
const models = this.getModelChain(options.agentId, options.model);
|
|
385
429
|
if (models.length === 0) {
|
|
386
430
|
log.warn("fallback LLM: no models configured in gateway");
|
|
387
431
|
return null;
|
|
388
432
|
}
|
|
389
|
-
const runChain = async () => {
|
|
433
|
+
const runChain = async (runOptions) => {
|
|
390
434
|
for (let i = 0; i < models.length; i++) {
|
|
435
|
+
if (runOptions.signal?.aborted) {
|
|
436
|
+
throw abortReason(runOptions.signal);
|
|
437
|
+
}
|
|
391
438
|
const model = models[i];
|
|
392
439
|
const isFallback = i > 0;
|
|
393
440
|
try {
|
|
394
|
-
const result = await this.tryModel(model, messages,
|
|
441
|
+
const result = await this.tryModel(model, messages, runOptions);
|
|
395
442
|
if (result) {
|
|
396
443
|
if (isFallback) {
|
|
397
444
|
log.debug(`fallback LLM: succeeded using ${model.modelString} (fallback ${i})`);
|
|
@@ -403,6 +450,9 @@ var FallbackLlmClient = class {
|
|
|
403
450
|
};
|
|
404
451
|
}
|
|
405
452
|
} catch (err) {
|
|
453
|
+
if (runOptions.signal?.aborted) {
|
|
454
|
+
throw abortReason(runOptions.signal);
|
|
455
|
+
}
|
|
406
456
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
407
457
|
log.debug(`fallback LLM: ${model.modelString} failed (${errorMsg}), trying next...`);
|
|
408
458
|
}
|
|
@@ -416,21 +466,37 @@ var FallbackLlmClient = class {
|
|
|
416
466
|
return null;
|
|
417
467
|
}
|
|
418
468
|
let timeoutHandle;
|
|
469
|
+
const controller = new AbortController();
|
|
470
|
+
const onCallerAbort = () => {
|
|
471
|
+
controller.abort(abortReason(options.signal));
|
|
472
|
+
};
|
|
473
|
+
options.signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
474
|
+
if (options.signal?.aborted) {
|
|
475
|
+
onCallerAbort();
|
|
476
|
+
}
|
|
477
|
+
const timedOptions = { ...options, signal: controller.signal };
|
|
478
|
+
const chain = runChain(timedOptions);
|
|
479
|
+
chain.catch(() => {
|
|
480
|
+
});
|
|
419
481
|
try {
|
|
420
482
|
return await Promise.race([
|
|
421
|
-
|
|
483
|
+
chain,
|
|
422
484
|
new Promise((resolve) => {
|
|
423
485
|
timeoutHandle = setTimeout(() => {
|
|
424
486
|
log.warn(`fallback LLM: timed out after ${options.timeoutMs}ms`);
|
|
487
|
+
controller.abort(
|
|
488
|
+
new Error(`fallback LLM timed out after ${options.timeoutMs}ms`)
|
|
489
|
+
);
|
|
425
490
|
resolve(null);
|
|
426
491
|
}, options.timeoutMs);
|
|
427
492
|
})
|
|
428
493
|
]);
|
|
429
494
|
} finally {
|
|
430
495
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
496
|
+
options.signal?.removeEventListener("abort", onCallerAbort);
|
|
431
497
|
}
|
|
432
498
|
}
|
|
433
|
-
return await runChain();
|
|
499
|
+
return await runChain(options);
|
|
434
500
|
}
|
|
435
501
|
/**
|
|
436
502
|
* Make a request with structured output (Zod schema).
|
|
@@ -470,7 +536,7 @@ var FallbackLlmClient = class {
|
|
|
470
536
|
* and uses that persona's model chain. Falls back to agents.defaults.model
|
|
471
537
|
* if agentId is not found or not provided.
|
|
472
538
|
*/
|
|
473
|
-
getModelChain(agentId) {
|
|
539
|
+
getModelChain(agentId, modelOverride) {
|
|
474
540
|
const chain = [];
|
|
475
541
|
const providers = this.gatewayConfig?.models?.providers ?? {};
|
|
476
542
|
let modelConfig;
|
|
@@ -491,8 +557,13 @@ var FallbackLlmClient = class {
|
|
|
491
557
|
modelConfig = this.gatewayConfig?.agents?.defaults?.model;
|
|
492
558
|
}
|
|
493
559
|
const modelStrings = [];
|
|
560
|
+
if (typeof modelOverride === "string" && modelOverride.trim().length > 0) {
|
|
561
|
+
modelStrings.push(modelOverride.trim());
|
|
562
|
+
}
|
|
494
563
|
if (modelConfig?.primary) {
|
|
495
|
-
modelStrings.
|
|
564
|
+
if (!modelStrings.includes(modelConfig.primary)) {
|
|
565
|
+
modelStrings.push(modelConfig.primary);
|
|
566
|
+
}
|
|
496
567
|
}
|
|
497
568
|
if (Array.isArray(modelConfig?.fallbacks)) {
|
|
498
569
|
for (const fb of modelConfig.fallbacks) {
|
|
@@ -618,7 +689,7 @@ var FallbackLlmClient = class {
|
|
|
618
689
|
effectiveConfig,
|
|
619
690
|
model.modelId,
|
|
620
691
|
messages,
|
|
621
|
-
{ timeoutMs: options.timeoutMs }
|
|
692
|
+
{ timeoutMs: options.timeoutMs, signal: options.signal }
|
|
622
693
|
);
|
|
623
694
|
}
|
|
624
695
|
if (model.providerConfig.api === "ollama-chat") {
|
|
@@ -712,6 +783,7 @@ var FallbackLlmClient = class {
|
|
|
712
783
|
const response = await fetch(url, {
|
|
713
784
|
method: "POST",
|
|
714
785
|
headers,
|
|
786
|
+
signal: options.signal,
|
|
715
787
|
body: JSON.stringify(body)
|
|
716
788
|
});
|
|
717
789
|
if (!response.ok) {
|
|
@@ -750,6 +822,7 @@ var FallbackLlmClient = class {
|
|
|
750
822
|
const response = await fetch(url, {
|
|
751
823
|
method: "POST",
|
|
752
824
|
headers,
|
|
825
|
+
signal: options.signal,
|
|
753
826
|
body: JSON.stringify({
|
|
754
827
|
model: modelId,
|
|
755
828
|
messages,
|
|
@@ -816,6 +889,7 @@ var FallbackLlmClient = class {
|
|
|
816
889
|
const response = await fetch(url, {
|
|
817
890
|
method: "POST",
|
|
818
891
|
headers,
|
|
892
|
+
signal: options.signal,
|
|
819
893
|
body: JSON.stringify(body)
|
|
820
894
|
});
|
|
821
895
|
if (!response.ok) {
|
|
@@ -868,6 +942,7 @@ var FallbackLlmClient = class {
|
|
|
868
942
|
const response = await fetch(url, {
|
|
869
943
|
method: "POST",
|
|
870
944
|
headers,
|
|
945
|
+
signal: options.signal,
|
|
871
946
|
body: JSON.stringify(body)
|
|
872
947
|
});
|
|
873
948
|
if (!response.ok) {
|
|
@@ -889,6 +964,10 @@ var FallbackLlmClient = class {
|
|
|
889
964
|
};
|
|
890
965
|
}
|
|
891
966
|
};
|
|
967
|
+
function abortReason(signal) {
|
|
968
|
+
const reason = signal?.reason;
|
|
969
|
+
return reason instanceof Error ? reason : new Error("fallback LLM request aborted");
|
|
970
|
+
}
|
|
892
971
|
function normalizeRuntimePath(value) {
|
|
893
972
|
if (typeof value !== "string") return void 0;
|
|
894
973
|
const trimmed = value.trim();
|
|
@@ -922,8 +1001,5 @@ function extractResponsesOutputText(data) {
|
|
|
922
1001
|
}
|
|
923
1002
|
|
|
924
1003
|
export {
|
|
925
|
-
shouldAssumeOpenAiChatCompletions,
|
|
926
|
-
buildChatCompletionTokenLimit,
|
|
927
|
-
findGatewayRuntimeModules,
|
|
928
1004
|
FallbackLlmClient
|
|
929
1005
|
};
|