@remnic/plugin-openclaw 1.0.6 → 1.0.8
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 +36 -0
- package/dist/{calibration-3JHF25QT.js → calibration-BAC7KNKR.js} +2 -1
- package/dist/{causal-consolidation-EBLROS42.js → causal-consolidation-33R5JTPX.js} +7 -5
- package/dist/chunk-3A5ELHTT.js +61 -0
- package/dist/chunk-5ZW5XJQ6.js +125 -0
- package/dist/chunk-6OJAU466.js +148 -0
- package/dist/{chunk-QHMR3D7U.js → chunk-BQLPVRIU.js} +109 -2
- package/dist/chunk-DIZW6H5J.js +136 -0
- package/dist/{chunk-KPMXWORS.js → chunk-JJSNPSCD.js} +608 -354
- package/dist/{chunk-3SA5F4WT.js → chunk-NXLHSCLU.js} +125 -69
- package/dist/{chunk-GUKYM4XZ.js → chunk-PFH73PN6.js} +3 -3
- package/dist/consolidation-undo-5ZSX4MWO.js +426 -0
- package/dist/contradiction-review-SVGBS3V5.js +21 -0
- package/dist/contradiction-scan-U3QKHWQN.js +412 -0
- package/dist/{engine-BU6GNUJ5.js → engine-M5G6ZJU7.js} +3 -2
- package/dist/extraction-judge-telemetry-GHOTVYMP.js +14 -0
- package/dist/{fallback-llm-HJRCHKSA.js → fallback-llm-QEAPMDW7.js} +2 -1
- package/dist/index.js +6467 -1285
- package/dist/resolution-YITUVUTH.js +100 -0
- package/dist/{storage-BA6OBLMK.js → storage-DM4ZGOCN.js} +2 -1
- package/openclaw.plugin.json +280 -9
- package/package.json +2 -2
|
@@ -1,65 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractJsonCandidates
|
|
3
|
+
} from "./chunk-3A5ELHTT.js";
|
|
1
4
|
import {
|
|
2
5
|
log
|
|
3
6
|
} from "./chunk-UFU5GGGA.js";
|
|
4
7
|
|
|
5
|
-
// ../remnic-core/src/json-extract.ts
|
|
6
|
-
function stripCodeFences(text) {
|
|
7
|
-
return text.replace(/```(?:json)?\s*([\s\S]*?)```/gi, (_m, inner) => String(inner).trim());
|
|
8
|
-
}
|
|
9
|
-
function extractJsonCandidates(text) {
|
|
10
|
-
const trimmed = text.trim();
|
|
11
|
-
const cleaned = stripCodeFences(trimmed);
|
|
12
|
-
const candidates = [];
|
|
13
|
-
if (cleaned.length > 0) candidates.push(cleaned);
|
|
14
|
-
candidates.push(...scanBalancedJsonBlocks(cleaned));
|
|
15
|
-
const objMatch = cleaned.match(/\{[\s\S]*\}/);
|
|
16
|
-
if (objMatch) candidates.push(objMatch[0]);
|
|
17
|
-
const seen = /* @__PURE__ */ new Set();
|
|
18
|
-
return candidates.map((c) => c.trim()).filter((c) => c.length > 0).filter((c) => {
|
|
19
|
-
if (seen.has(c)) return false;
|
|
20
|
-
seen.add(c);
|
|
21
|
-
return true;
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function scanBalancedJsonBlocks(text) {
|
|
25
|
-
const out = [];
|
|
26
|
-
const opens = /* @__PURE__ */ new Set(["{", "["]);
|
|
27
|
-
const closes = { "{": "}", "[": "]" };
|
|
28
|
-
for (let i = 0; i < text.length; i++) {
|
|
29
|
-
const start = text[i];
|
|
30
|
-
if (!opens.has(start)) continue;
|
|
31
|
-
const expectedClose = closes[start];
|
|
32
|
-
let depth = 0;
|
|
33
|
-
let inString = false;
|
|
34
|
-
let escape = false;
|
|
35
|
-
for (let j = i; j < text.length; j++) {
|
|
36
|
-
const ch = text[j];
|
|
37
|
-
if (inString) {
|
|
38
|
-
if (escape) {
|
|
39
|
-
escape = false;
|
|
40
|
-
} else if (ch === "\\") {
|
|
41
|
-
escape = true;
|
|
42
|
-
} else if (ch === '"') {
|
|
43
|
-
inString = false;
|
|
44
|
-
}
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (ch === '"') {
|
|
48
|
-
inString = true;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (ch === start) depth++;
|
|
52
|
-
if (ch === expectedClose) depth--;
|
|
53
|
-
if (depth === 0) {
|
|
54
|
-
out.push(text.slice(i, j + 1).trim());
|
|
55
|
-
i = j;
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return out;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
8
|
// ../remnic-core/src/openai-chat-compat.ts
|
|
64
9
|
function normalizedModel(model) {
|
|
65
10
|
return model.trim().toLowerCase();
|
|
@@ -183,13 +128,25 @@ async function getGatewayResolver() {
|
|
|
183
128
|
async function findRuntimeModules() {
|
|
184
129
|
const { readdirSync } = await import("fs");
|
|
185
130
|
const { createRequire } = await import("module");
|
|
131
|
+
const { execFileSync } = await import("child_process");
|
|
186
132
|
const candidates = [];
|
|
187
133
|
const distDirs = [];
|
|
134
|
+
const pushDistDirs = (entryPath) => {
|
|
135
|
+
const resolvedEntryDir = path.dirname(entryPath);
|
|
136
|
+
const packageRoot = path.basename(resolvedEntryDir) === "dist" ? path.resolve(resolvedEntryDir, "..") : resolvedEntryDir;
|
|
137
|
+
const candidateDistDirs = [
|
|
138
|
+
path.join(packageRoot, "dist"),
|
|
139
|
+
path.join(packageRoot, "..", "dist")
|
|
140
|
+
];
|
|
141
|
+
for (const candidate of candidateDistDirs) {
|
|
142
|
+
const resolved = path.resolve(candidate);
|
|
143
|
+
if (!distDirs.includes(resolved)) distDirs.push(resolved);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
188
146
|
try {
|
|
189
147
|
const req = createRequire(import.meta.url);
|
|
190
148
|
const openclawMain = req.resolve("openclaw");
|
|
191
|
-
|
|
192
|
-
if (openclawDist) distDirs.push(path.resolve(openclawDist));
|
|
149
|
+
pushDistDirs(openclawMain);
|
|
193
150
|
} catch {
|
|
194
151
|
}
|
|
195
152
|
try {
|
|
@@ -198,12 +155,22 @@ async function findRuntimeModules() {
|
|
|
198
155
|
if (mainScript) {
|
|
199
156
|
const realScript = realpathSync(mainScript);
|
|
200
157
|
if (realScript.includes("openclaw")) {
|
|
201
|
-
|
|
202
|
-
if (!distDirs.includes(distDir)) distDirs.push(distDir);
|
|
158
|
+
pushDistDirs(realScript);
|
|
203
159
|
}
|
|
204
160
|
}
|
|
205
161
|
} catch {
|
|
206
162
|
}
|
|
163
|
+
try {
|
|
164
|
+
const openclawBin = execFileSync("which", ["openclaw"], {
|
|
165
|
+
encoding: "utf8",
|
|
166
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
167
|
+
}).trim();
|
|
168
|
+
if (openclawBin) {
|
|
169
|
+
const { realpathSync } = await import("fs");
|
|
170
|
+
pushDistDirs(realpathSync(openclawBin));
|
|
171
|
+
}
|
|
172
|
+
} catch {
|
|
173
|
+
}
|
|
207
174
|
for (const dir of distDirs) {
|
|
208
175
|
try {
|
|
209
176
|
const files = readdirSync(dir);
|
|
@@ -218,7 +185,10 @@ async function findRuntimeModules() {
|
|
|
218
185
|
return candidates;
|
|
219
186
|
}
|
|
220
187
|
async function resolveProviderApiKey(providerId, apiKeyValue, gatewayConfig, agentDir) {
|
|
221
|
-
const
|
|
188
|
+
const resolvedAgentDir = path.resolve(
|
|
189
|
+
agentDir ?? path.join(os2.homedir(), ".openclaw", "agents", "main", "agent")
|
|
190
|
+
);
|
|
191
|
+
const cacheKey = `provider:${providerId}:agentDir:${resolvedAgentDir}`;
|
|
222
192
|
if (resolvedCache.has(cacheKey)) {
|
|
223
193
|
return resolvedCache.get(cacheKey);
|
|
224
194
|
}
|
|
@@ -234,7 +204,6 @@ async function resolveProviderApiKey(providerId, apiKeyValue, gatewayConfig, age
|
|
|
234
204
|
const resolver = await getGatewayResolver();
|
|
235
205
|
if (resolver) {
|
|
236
206
|
try {
|
|
237
|
-
const resolvedAgentDir = agentDir ?? path.join(os2.homedir(), ".openclaw", "agents", "main", "agent");
|
|
238
207
|
const auth = await resolver({ provider: providerId, cfg: gatewayConfig, agentDir: resolvedAgentDir });
|
|
239
208
|
if (auth?.apiKey) {
|
|
240
209
|
resolved = auth.apiKey;
|
|
@@ -310,8 +279,10 @@ function loadModelsJsonProviders() {
|
|
|
310
279
|
// ../remnic-core/src/fallback-llm.ts
|
|
311
280
|
var FallbackLlmClient = class {
|
|
312
281
|
gatewayConfig;
|
|
313
|
-
|
|
282
|
+
runtimeContext;
|
|
283
|
+
constructor(gatewayConfig, runtimeContext = {}) {
|
|
314
284
|
this.gatewayConfig = gatewayConfig;
|
|
285
|
+
this.runtimeContext = runtimeContext;
|
|
315
286
|
}
|
|
316
287
|
/**
|
|
317
288
|
* Check if fallback is available (gateway config has at least one model).
|
|
@@ -513,6 +484,14 @@ var FallbackLlmClient = class {
|
|
|
513
484
|
if (model.providerConfig.api === "anthropic-messages") {
|
|
514
485
|
return await this.callAnthropic(effectiveConfig, model.modelId, messages, options);
|
|
515
486
|
}
|
|
487
|
+
if (model.providerConfig.api === "openai-responses" || model.providerConfig.api === "openai-codex-responses" || model.providerConfig.api === "azure-openai-responses") {
|
|
488
|
+
return await this.callOpenAIResponses(
|
|
489
|
+
effectiveConfig,
|
|
490
|
+
model.modelId,
|
|
491
|
+
messages,
|
|
492
|
+
options
|
|
493
|
+
);
|
|
494
|
+
}
|
|
516
495
|
return await this.callOpenAI(
|
|
517
496
|
effectiveConfig,
|
|
518
497
|
model.modelId,
|
|
@@ -537,7 +516,8 @@ var FallbackLlmClient = class {
|
|
|
537
516
|
api: model.providerConfig.api,
|
|
538
517
|
baseUrl: model.providerConfig.baseUrl
|
|
539
518
|
},
|
|
540
|
-
cfg: this.gatewayConfig
|
|
519
|
+
cfg: this.gatewayConfig,
|
|
520
|
+
workspaceDir: this.runtimeContext.workspaceDir
|
|
541
521
|
});
|
|
542
522
|
if (result?.apiKey || result?.baseUrl) {
|
|
543
523
|
log.debug(
|
|
@@ -557,7 +537,12 @@ var FallbackLlmClient = class {
|
|
|
557
537
|
* secret refs, etc.). Used as fallback when gateway runtime auth isn't available.
|
|
558
538
|
*/
|
|
559
539
|
async resolveFallbackApiKey(model) {
|
|
560
|
-
return resolveProviderApiKey(
|
|
540
|
+
return resolveProviderApiKey(
|
|
541
|
+
model.providerId,
|
|
542
|
+
model.providerConfig.apiKey,
|
|
543
|
+
this.gatewayConfig,
|
|
544
|
+
this.runtimeContext.agentDir
|
|
545
|
+
);
|
|
561
546
|
}
|
|
562
547
|
/**
|
|
563
548
|
* Call OpenAI-compatible API.
|
|
@@ -605,11 +590,65 @@ var FallbackLlmClient = class {
|
|
|
605
590
|
} : void 0
|
|
606
591
|
};
|
|
607
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* Call an OpenAI-compatible Responses API.
|
|
595
|
+
*/
|
|
596
|
+
async callOpenAIResponses(config, modelId, messages, options) {
|
|
597
|
+
const base = config.baseUrl.replace(/\/$/, "");
|
|
598
|
+
const url = base.endsWith("/v1") ? `${base}/responses` : `${base}/v1/responses`;
|
|
599
|
+
const headers = {
|
|
600
|
+
"Content-Type": "application/json",
|
|
601
|
+
...config.headers
|
|
602
|
+
};
|
|
603
|
+
if (config.apiKey && typeof config.apiKey === "string" && config.authHeader !== false) {
|
|
604
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
605
|
+
}
|
|
606
|
+
const instructions = messages.filter((message) => message.role === "system").map((message) => message.content).join("\n\n").trim();
|
|
607
|
+
const input = messages.filter((message) => message.role !== "system").map((message) => ({
|
|
608
|
+
role: message.role,
|
|
609
|
+
content: [{
|
|
610
|
+
type: message.role === "assistant" ? "output_text" : "input_text",
|
|
611
|
+
text: message.content
|
|
612
|
+
}]
|
|
613
|
+
}));
|
|
614
|
+
const body = {
|
|
615
|
+
model: modelId,
|
|
616
|
+
input,
|
|
617
|
+
max_output_tokens: Math.max(0, Math.floor(options.maxTokens ?? 4096)),
|
|
618
|
+
temperature: options.temperature ?? 0.3
|
|
619
|
+
};
|
|
620
|
+
if (instructions.length > 0) {
|
|
621
|
+
body.instructions = instructions;
|
|
622
|
+
}
|
|
623
|
+
const response = await fetch(url, {
|
|
624
|
+
method: "POST",
|
|
625
|
+
headers,
|
|
626
|
+
body: JSON.stringify(body)
|
|
627
|
+
});
|
|
628
|
+
if (!response.ok) {
|
|
629
|
+
const error = await response.text();
|
|
630
|
+
throw new Error(`OpenAI Responses API error: ${response.status} ${error}`);
|
|
631
|
+
}
|
|
632
|
+
const data = await response.json();
|
|
633
|
+
const outputText = extractResponsesOutputText(data);
|
|
634
|
+
if (!outputText) {
|
|
635
|
+
throw new Error("Empty response from OpenAI Responses API");
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
content: outputText,
|
|
639
|
+
usage: data.usage ? {
|
|
640
|
+
inputTokens: data.usage.input_tokens,
|
|
641
|
+
outputTokens: data.usage.output_tokens,
|
|
642
|
+
totalTokens: data.usage.total_tokens
|
|
643
|
+
} : void 0
|
|
644
|
+
};
|
|
645
|
+
}
|
|
608
646
|
/**
|
|
609
647
|
* Call Anthropic Messages API.
|
|
610
648
|
*/
|
|
611
649
|
async callAnthropic(config, modelId, messages, options) {
|
|
612
|
-
const
|
|
650
|
+
const base = config.baseUrl.replace(/\/$/, "");
|
|
651
|
+
const url = base.endsWith("/v1") ? `${base}/messages` : `${base}/v1/messages`;
|
|
613
652
|
const headers = {
|
|
614
653
|
"Content-Type": "application/json",
|
|
615
654
|
"anthropic-version": "2023-06-01",
|
|
@@ -657,12 +696,29 @@ var FallbackLlmClient = class {
|
|
|
657
696
|
};
|
|
658
697
|
}
|
|
659
698
|
};
|
|
699
|
+
function extractResponsesOutputText(data) {
|
|
700
|
+
if (typeof data.output_text === "string" && data.output_text.trim().length > 0) {
|
|
701
|
+
return data.output_text;
|
|
702
|
+
}
|
|
703
|
+
const chunks = [];
|
|
704
|
+
for (const item of data.output ?? []) {
|
|
705
|
+
if (typeof item.text === "string" && item.text.trim().length > 0) {
|
|
706
|
+
chunks.push(item.text);
|
|
707
|
+
}
|
|
708
|
+
for (const part of item.content ?? []) {
|
|
709
|
+
if ((part.type === "output_text" || part.type === "text") && typeof part.text === "string" && part.text.trim().length > 0) {
|
|
710
|
+
chunks.push(part.text);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const joined = chunks.join("\n").trim();
|
|
715
|
+
return joined.length > 0 ? joined : null;
|
|
716
|
+
}
|
|
660
717
|
|
|
661
718
|
export {
|
|
662
719
|
readEnvVar,
|
|
663
720
|
resolveHomeDir,
|
|
664
721
|
mergeEnv,
|
|
665
|
-
extractJsonCandidates,
|
|
666
722
|
shouldAssumeOpenAiChatCompletions,
|
|
667
723
|
buildChatCompletionTokenLimit,
|
|
668
724
|
FallbackLlmClient
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
parseContinuityImprovementLoops,
|
|
4
4
|
parseContinuityIncident,
|
|
5
5
|
sanitizeMemoryContent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JJSNPSCD.js";
|
|
7
7
|
import {
|
|
8
8
|
log
|
|
9
9
|
} from "./chunk-UFU5GGGA.js";
|
|
@@ -4881,7 +4881,7 @@ var CompoundingEngine = class {
|
|
|
4881
4881
|
let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
|
|
4882
4882
|
if (this.config.cmcConsolidationEnabled) {
|
|
4883
4883
|
try {
|
|
4884
|
-
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-
|
|
4884
|
+
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-33R5JTPX.js");
|
|
4885
4885
|
const causalCandidates = await deriveCausalPromotionCandidates({
|
|
4886
4886
|
memoryDir: this.config.memoryDir,
|
|
4887
4887
|
causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
|
|
@@ -4913,7 +4913,7 @@ var CompoundingEngine = class {
|
|
|
4913
4913
|
}
|
|
4914
4914
|
if (this.config.calibrationEnabled) {
|
|
4915
4915
|
try {
|
|
4916
|
-
const { runCalibrationConsolidation } = await import("./calibration-
|
|
4916
|
+
const { runCalibrationConsolidation } = await import("./calibration-BAC7KNKR.js");
|
|
4917
4917
|
const calRules = await runCalibrationConsolidation({
|
|
4918
4918
|
memoryDir: this.config.memoryDir,
|
|
4919
4919
|
gatewayConfig: this.config.gatewayConfig,
|