@joshuaswarren/openclaw-engram 9.0.11 → 9.0.13
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 +2 -2
- package/dist/index.js +135 -85
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +39 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -138,13 +138,13 @@ openclaw engram policy-status # Lifecycle policy snapshot
|
|
|
138
138
|
|
|
139
139
|
## Configuration
|
|
140
140
|
|
|
141
|
-
All settings live in `openclaw.json` under `plugins.entries.openclaw-engram.config`.
|
|
141
|
+
All settings live in `openclaw.json` under `plugins.entries.openclaw-engram.config`. `openaiApiKey` is optional when local LLM or gateway fallback paths are available.
|
|
142
142
|
|
|
143
143
|
Key settings:
|
|
144
144
|
|
|
145
145
|
| Setting | Default | Description |
|
|
146
146
|
|---------|---------|-------------|
|
|
147
|
-
| `openaiApiKey` | `(env fallback)` | OpenAI API key or `${ENV_VAR}` reference |
|
|
147
|
+
| `openaiApiKey` | `(env fallback)` | Optional OpenAI API key or `${ENV_VAR}` reference for direct-client paths |
|
|
148
148
|
| `model` | `gpt-5.2` | LLM model for extraction |
|
|
149
149
|
| `searchBackend` | `"qmd"` | Search engine: `qmd`, `orama`, `lancedb`, `meilisearch`, `remote`, `noop` |
|
|
150
150
|
| `qmdEnabled` | `true` | Enable QMD hybrid search |
|
package/dist/index.js
CHANGED
|
@@ -325,6 +325,11 @@ function parseConfig(raw) {
|
|
|
325
325
|
localLlmRetryBackoffMs: typeof cfg.localLlmRetryBackoffMs === "number" ? cfg.localLlmRetryBackoffMs : 400,
|
|
326
326
|
localLlm400TripThreshold: typeof cfg.localLlm400TripThreshold === "number" ? cfg.localLlm400TripThreshold : 5,
|
|
327
327
|
localLlm400CooldownMs: typeof cfg.localLlm400CooldownMs === "number" ? cfg.localLlm400CooldownMs : 12e4,
|
|
328
|
+
// Local LLM fast tier (v9.1)
|
|
329
|
+
localLlmFastEnabled: cfg.localLlmFastEnabled === true,
|
|
330
|
+
localLlmFastModel: typeof cfg.localLlmFastModel === "string" && cfg.localLlmFastModel.length > 0 ? cfg.localLlmFastModel : "",
|
|
331
|
+
localLlmFastUrl: typeof cfg.localLlmFastUrl === "string" && cfg.localLlmFastUrl.length > 0 ? cfg.localLlmFastUrl : typeof cfg.localLlmUrl === "string" && cfg.localLlmUrl.length > 0 ? cfg.localLlmUrl : "http://localhost:1234/v1",
|
|
332
|
+
localLlmFastTimeoutMs: typeof cfg.localLlmFastTimeoutMs === "number" ? cfg.localLlmFastTimeoutMs : 15e3,
|
|
328
333
|
// Gateway config (passed from index.ts for fallback AI)
|
|
329
334
|
gatewayConfig: cfg.gatewayConfig,
|
|
330
335
|
// v3.0 namespaces (default off)
|
|
@@ -2401,7 +2406,7 @@ var ExtractionEngine = class {
|
|
|
2401
2406
|
});
|
|
2402
2407
|
} else {
|
|
2403
2408
|
this.client = null;
|
|
2404
|
-
log.warn("no OpenAI API key \u2014
|
|
2409
|
+
log.warn("no OpenAI API key \u2014 direct OpenAI client disabled; local and gateway fallback paths remain available");
|
|
2405
2410
|
}
|
|
2406
2411
|
this.localLlm = localLlm ?? new LocalLlmClient(config, modelRegistry);
|
|
2407
2412
|
this.fallbackLlm = new FallbackLlmClient(gatewayConfig);
|
|
@@ -2465,6 +2470,52 @@ var ExtractionEngine = class {
|
|
|
2465
2470
|
) : void 0
|
|
2466
2471
|
};
|
|
2467
2472
|
}
|
|
2473
|
+
parseJsonObject(content) {
|
|
2474
|
+
const trimmed = content?.trim();
|
|
2475
|
+
if (!trimmed) return null;
|
|
2476
|
+
for (const candidate of extractJsonCandidates(trimmed)) {
|
|
2477
|
+
try {
|
|
2478
|
+
return JSON.parse(candidate);
|
|
2479
|
+
} catch {
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
return null;
|
|
2483
|
+
}
|
|
2484
|
+
normalizeContradictionVerificationResult(parsed) {
|
|
2485
|
+
if (!parsed || typeof parsed.isContradiction !== "boolean") return null;
|
|
2486
|
+
const rawWhich = parsed.whichIsNewer ?? parsed.winner;
|
|
2487
|
+
const normalizedWhich = rawWhich === "first" || rawWhich === "existing" ? "first" : rawWhich === "second" || rawWhich === "new" ? "second" : "unclear";
|
|
2488
|
+
return {
|
|
2489
|
+
isContradiction: Boolean(parsed.isContradiction),
|
|
2490
|
+
confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0.5,
|
|
2491
|
+
reasoning: typeof parsed.reasoning === "string" ? parsed.reasoning : typeof parsed.explanation === "string" ? parsed.explanation : "",
|
|
2492
|
+
whichIsNewer: normalizedWhich
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
normalizeSuggestedLinksResult(parsed) {
|
|
2496
|
+
if (!parsed || !Array.isArray(parsed.links)) {
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
const normalizedLinks = parsed.links.map((link) => {
|
|
2500
|
+
const rawLinkType = link?.linkType ?? link?.type;
|
|
2501
|
+
return {
|
|
2502
|
+
targetId: typeof link?.targetId === "string" ? link.targetId : "",
|
|
2503
|
+
linkType: rawLinkType === "follows" || rawLinkType === "references" || rawLinkType === "contradicts" || rawLinkType === "supports" || rawLinkType === "related" ? rawLinkType : "related",
|
|
2504
|
+
strength: typeof link?.strength === "number" ? Math.max(0, Math.min(1, link.strength)) : 0.5,
|
|
2505
|
+
reason: typeof link?.reason === "string" ? link.reason : void 0
|
|
2506
|
+
};
|
|
2507
|
+
}).filter((link) => link.targetId.length > 0);
|
|
2508
|
+
return { links: normalizedLinks };
|
|
2509
|
+
}
|
|
2510
|
+
normalizeMemorySummaryResult(parsed) {
|
|
2511
|
+
if (!parsed) return null;
|
|
2512
|
+
const normalized = {
|
|
2513
|
+
summaryText: typeof parsed.summaryText === "string" ? parsed.summaryText : typeof parsed.summary === "string" ? parsed.summary : "",
|
|
2514
|
+
keyFacts: Array.isArray(parsed.keyFacts) ? parsed.keyFacts.filter((f) => typeof f === "string") : [],
|
|
2515
|
+
keyEntities: Array.isArray(parsed.keyEntities) ? parsed.keyEntities.filter((e) => typeof e === "string") : Array.isArray(parsed.entities) ? parsed.entities.filter((e) => typeof e === "string") : []
|
|
2516
|
+
};
|
|
2517
|
+
return normalized.summaryText.length > 0 ? normalized : null;
|
|
2518
|
+
}
|
|
2468
2519
|
sanitizeConsolidationResult(result) {
|
|
2469
2520
|
const items = result.items.map((item) => {
|
|
2470
2521
|
if (!item.updatedContent) return item;
|
|
@@ -3650,10 +3701,6 @@ Respond with valid JSON matching this schema:
|
|
|
3650
3701
|
* Called when QMD finds semantically similar memories (Phase 2B).
|
|
3651
3702
|
*/
|
|
3652
3703
|
async verifyContradiction(newMemory, existingMemory) {
|
|
3653
|
-
if (!this.client) {
|
|
3654
|
-
log.warn("contradiction verification skipped \u2014 no OpenAI API key");
|
|
3655
|
-
return null;
|
|
3656
|
-
}
|
|
3657
3704
|
const input = `Memory 1 (existing, created ${existingMemory.created}):
|
|
3658
3705
|
Category: ${existingMemory.category}
|
|
3659
3706
|
Content: ${existingMemory.content}
|
|
@@ -3684,6 +3731,26 @@ Respond with valid JSON matching this schema:
|
|
|
3684
3731
|
"reasoning": "why they contradict or don't",
|
|
3685
3732
|
"whichIsNewer": "first"
|
|
3686
3733
|
}`;
|
|
3734
|
+
if (!this.client) {
|
|
3735
|
+
const fallbackResponse = await this.fallbackLlm.chatCompletion(
|
|
3736
|
+
[
|
|
3737
|
+
{ role: "system", content: systemPrompt },
|
|
3738
|
+
{ role: "user", content: input }
|
|
3739
|
+
],
|
|
3740
|
+
{ temperature: 0.3, maxTokens: 2048 }
|
|
3741
|
+
);
|
|
3742
|
+
const normalized2 = this.normalizeContradictionVerificationResult(
|
|
3743
|
+
this.parseJsonObject(fallbackResponse?.content)
|
|
3744
|
+
);
|
|
3745
|
+
if (normalized2) {
|
|
3746
|
+
log.debug(
|
|
3747
|
+
`contradiction check via fallback: ${normalized2.isContradiction ? "YES" : "NO"} (confidence: ${normalized2.confidence})`
|
|
3748
|
+
);
|
|
3749
|
+
return normalized2;
|
|
3750
|
+
}
|
|
3751
|
+
log.warn("contradiction verification skipped \u2014 no OpenAI API key and fallback unavailable");
|
|
3752
|
+
return null;
|
|
3753
|
+
}
|
|
3687
3754
|
const response = await this.client.chat.completions.create({
|
|
3688
3755
|
model: this.config.model,
|
|
3689
3756
|
messages: [
|
|
@@ -3693,26 +3760,10 @@ Respond with valid JSON matching this schema:
|
|
|
3693
3760
|
temperature: 0.3,
|
|
3694
3761
|
max_tokens: 2048
|
|
3695
3762
|
});
|
|
3696
|
-
const
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
try {
|
|
3701
|
-
parsed = JSON.parse(candidate);
|
|
3702
|
-
break;
|
|
3703
|
-
} catch {
|
|
3704
|
-
}
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
if (parsed && typeof parsed.isContradiction === "boolean") {
|
|
3708
|
-
const rawWhich = parsed.whichIsNewer ?? parsed.winner;
|
|
3709
|
-
const normalizedWhich = rawWhich === "first" || rawWhich === "existing" ? "first" : rawWhich === "second" || rawWhich === "new" ? "second" : "unclear";
|
|
3710
|
-
const normalized = {
|
|
3711
|
-
isContradiction: Boolean(parsed.isContradiction),
|
|
3712
|
-
confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0.5,
|
|
3713
|
-
reasoning: typeof parsed.reasoning === "string" ? parsed.reasoning : typeof parsed.explanation === "string" ? parsed.explanation : "",
|
|
3714
|
-
whichIsNewer: normalizedWhich
|
|
3715
|
-
};
|
|
3763
|
+
const normalized = this.normalizeContradictionVerificationResult(
|
|
3764
|
+
this.parseJsonObject(response.choices?.[0]?.message?.content)
|
|
3765
|
+
);
|
|
3766
|
+
if (normalized) {
|
|
3716
3767
|
log.debug(
|
|
3717
3768
|
`contradiction check: ${normalized.isContradiction ? "YES" : "NO"} (confidence: ${normalized.confidence})`
|
|
3718
3769
|
);
|
|
@@ -3729,10 +3780,6 @@ Respond with valid JSON matching this schema:
|
|
|
3729
3780
|
* Called during extraction to build the knowledge graph.
|
|
3730
3781
|
*/
|
|
3731
3782
|
async suggestLinks(newMemory, candidateMemories) {
|
|
3732
|
-
if (!this.client) {
|
|
3733
|
-
log.warn("link suggestion skipped \u2014 no OpenAI API key");
|
|
3734
|
-
return null;
|
|
3735
|
-
}
|
|
3736
3783
|
if (candidateMemories.length === 0) {
|
|
3737
3784
|
return { links: [] };
|
|
3738
3785
|
}
|
|
@@ -3765,6 +3812,22 @@ Respond with valid JSON matching this schema:
|
|
|
3765
3812
|
{
|
|
3766
3813
|
"links": [{"targetId": "memory-id", "linkType": "follows|references|contradicts|supports|related", "strength": 0.8, "reason": "why"}]
|
|
3767
3814
|
}`;
|
|
3815
|
+
if (!this.client) {
|
|
3816
|
+
const fallbackResponse = await this.fallbackLlm.chatCompletion(
|
|
3817
|
+
[
|
|
3818
|
+
{ role: "system", content: systemPrompt },
|
|
3819
|
+
{ role: "user", content: input }
|
|
3820
|
+
],
|
|
3821
|
+
{ temperature: 0.3, maxTokens: 2048 }
|
|
3822
|
+
);
|
|
3823
|
+
const normalized2 = this.normalizeSuggestedLinksResult(this.parseJsonObject(fallbackResponse?.content));
|
|
3824
|
+
if (normalized2) {
|
|
3825
|
+
log.debug(`suggested ${normalized2.links.length} links via fallback`);
|
|
3826
|
+
return normalized2;
|
|
3827
|
+
}
|
|
3828
|
+
log.warn("link suggestion skipped \u2014 no OpenAI API key and fallback unavailable");
|
|
3829
|
+
return null;
|
|
3830
|
+
}
|
|
3768
3831
|
const response = await this.client.chat.completions.create({
|
|
3769
3832
|
model: this.config.model,
|
|
3770
3833
|
messages: [
|
|
@@ -3774,44 +3837,23 @@ Respond with valid JSON matching this schema:
|
|
|
3774
3837
|
temperature: 0.3,
|
|
3775
3838
|
max_tokens: 2048
|
|
3776
3839
|
});
|
|
3777
|
-
const
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
break;
|
|
3784
|
-
} catch {
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
}
|
|
3788
|
-
if (parsed && Array.isArray(parsed.links)) {
|
|
3789
|
-
const normalizedLinks = parsed.links.map((link) => {
|
|
3790
|
-
const rawLinkType = link?.linkType ?? link?.type;
|
|
3791
|
-
return {
|
|
3792
|
-
targetId: typeof link?.targetId === "string" ? link.targetId : "",
|
|
3793
|
-
linkType: rawLinkType === "follows" || rawLinkType === "references" || rawLinkType === "contradicts" || rawLinkType === "supports" || rawLinkType === "related" ? rawLinkType : "related",
|
|
3794
|
-
strength: typeof link?.strength === "number" ? Math.max(0, Math.min(1, link.strength)) : 0.5,
|
|
3795
|
-
reason: typeof link?.reason === "string" ? link.reason : void 0
|
|
3796
|
-
};
|
|
3797
|
-
}).filter((link) => link.targetId.length > 0);
|
|
3798
|
-
log.debug(`suggested ${normalizedLinks.length} links`);
|
|
3799
|
-
return { links: normalizedLinks };
|
|
3840
|
+
const normalized = this.normalizeSuggestedLinksResult(
|
|
3841
|
+
this.parseJsonObject(response.choices?.[0]?.message?.content)
|
|
3842
|
+
);
|
|
3843
|
+
if (normalized) {
|
|
3844
|
+
log.debug(`suggested ${normalized.links.length} links`);
|
|
3845
|
+
return normalized;
|
|
3800
3846
|
}
|
|
3801
|
-
return
|
|
3847
|
+
return null;
|
|
3802
3848
|
} catch (err) {
|
|
3803
3849
|
log.error("link suggestion failed", err);
|
|
3804
|
-
return
|
|
3850
|
+
return null;
|
|
3805
3851
|
}
|
|
3806
3852
|
}
|
|
3807
3853
|
/**
|
|
3808
3854
|
* Summarize a batch of old memories into a compact summary (Phase 4A).
|
|
3809
3855
|
*/
|
|
3810
3856
|
async summarizeMemories(memories) {
|
|
3811
|
-
if (!this.client) {
|
|
3812
|
-
log.warn("summarization skipped \u2014 no OpenAI API key");
|
|
3813
|
-
return null;
|
|
3814
|
-
}
|
|
3815
3857
|
if (memories.length === 0) return null;
|
|
3816
3858
|
const memoryList = memories.map((m) => `[${m.id}] (${m.category}, ${m.created.slice(0, 10)})
|
|
3817
3859
|
${m.content}`).join("\n\n");
|
|
@@ -3835,6 +3877,24 @@ Respond with valid JSON matching this schema:
|
|
|
3835
3877
|
"keyFacts": ["fact 1", "fact 2"],
|
|
3836
3878
|
"keyEntities": ["entity-1", "entity-2"]
|
|
3837
3879
|
}`;
|
|
3880
|
+
if (!this.client) {
|
|
3881
|
+
const fallbackResponse = await this.fallbackLlm.chatCompletion(
|
|
3882
|
+
[
|
|
3883
|
+
{ role: "system", content: systemPrompt },
|
|
3884
|
+
{ role: "user", content: `Summarize these ${memories.length} memories:
|
|
3885
|
+
|
|
3886
|
+
${memoryList}` }
|
|
3887
|
+
],
|
|
3888
|
+
{ temperature: 0.3, maxTokens: 4096 }
|
|
3889
|
+
);
|
|
3890
|
+
const normalized2 = this.normalizeMemorySummaryResult(this.parseJsonObject(fallbackResponse?.content));
|
|
3891
|
+
if (normalized2) {
|
|
3892
|
+
log.debug(`summarized ${memories.length} memories into ${normalized2.keyFacts.length} key facts via fallback`);
|
|
3893
|
+
return normalized2;
|
|
3894
|
+
}
|
|
3895
|
+
log.warn("summarization skipped \u2014 no OpenAI API key and fallback unavailable");
|
|
3896
|
+
return null;
|
|
3897
|
+
}
|
|
3838
3898
|
const response = await this.client.chat.completions.create({
|
|
3839
3899
|
model: this.config.model,
|
|
3840
3900
|
messages: [
|
|
@@ -3846,27 +3906,12 @@ ${memoryList}` }
|
|
|
3846
3906
|
temperature: 0.3,
|
|
3847
3907
|
max_tokens: 4096
|
|
3848
3908
|
});
|
|
3849
|
-
const
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
break;
|
|
3856
|
-
} catch {
|
|
3857
|
-
}
|
|
3858
|
-
}
|
|
3859
|
-
}
|
|
3860
|
-
if (parsed) {
|
|
3861
|
-
const normalized = {
|
|
3862
|
-
summaryText: typeof parsed.summaryText === "string" ? parsed.summaryText : typeof parsed.summary === "string" ? parsed.summary : "",
|
|
3863
|
-
keyFacts: Array.isArray(parsed.keyFacts) ? parsed.keyFacts.filter((f) => typeof f === "string") : [],
|
|
3864
|
-
keyEntities: Array.isArray(parsed.keyEntities) ? parsed.keyEntities.filter((e) => typeof e === "string") : Array.isArray(parsed.entities) ? parsed.entities.filter((e) => typeof e === "string") : []
|
|
3865
|
-
};
|
|
3866
|
-
if (normalized.summaryText.length > 0) {
|
|
3867
|
-
log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts`);
|
|
3868
|
-
return normalized;
|
|
3869
|
-
}
|
|
3909
|
+
const normalized = this.normalizeMemorySummaryResult(
|
|
3910
|
+
this.parseJsonObject(response.choices?.[0]?.message?.content)
|
|
3911
|
+
);
|
|
3912
|
+
if (normalized) {
|
|
3913
|
+
log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts`);
|
|
3914
|
+
return normalized;
|
|
3870
3915
|
}
|
|
3871
3916
|
return null;
|
|
3872
3917
|
} catch (err) {
|
|
@@ -16348,6 +16393,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
16348
16393
|
sessionObserver;
|
|
16349
16394
|
summarizer;
|
|
16350
16395
|
localLlm;
|
|
16396
|
+
fastLlm;
|
|
16351
16397
|
modelRegistry;
|
|
16352
16398
|
relevance;
|
|
16353
16399
|
negatives;
|
|
@@ -16449,6 +16495,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
16449
16495
|
this.policyRuntime = new PolicyRuntimeManager(config.memoryDir, config);
|
|
16450
16496
|
this.summarizer = new HourlySummarizer(config, config.gatewayConfig, this.modelRegistry, this.transcript);
|
|
16451
16497
|
this.localLlm = new LocalLlmClient(config, this.modelRegistry);
|
|
16498
|
+
this.fastLlm = config.localLlmFastEnabled ? new LocalLlmClient(
|
|
16499
|
+
{ ...config, localLlmModel: config.localLlmFastModel || config.localLlmModel, localLlmUrl: config.localLlmFastUrl, localLlmTimeoutMs: config.localLlmFastTimeoutMs },
|
|
16500
|
+
this.modelRegistry
|
|
16501
|
+
) : this.localLlm;
|
|
16452
16502
|
this.extraction = new ExtractionEngine(config, this.localLlm, config.gatewayConfig, this.modelRegistry);
|
|
16453
16503
|
this.threading = new ThreadingManager(
|
|
16454
16504
|
path30.join(config.memoryDir, "threads"),
|
|
@@ -17852,7 +17902,7 @@ ${tmtNode.summary}`);
|
|
|
17852
17902
|
id: r.path,
|
|
17853
17903
|
snippet: r.snippet || r.path
|
|
17854
17904
|
})),
|
|
17855
|
-
local: this.
|
|
17905
|
+
local: this.fastLlm,
|
|
17856
17906
|
enabled: true,
|
|
17857
17907
|
timeoutMs: this.config.rerankTimeoutMs,
|
|
17858
17908
|
maxCandidates: this.config.rerankMaxCandidates,
|
|
@@ -19343,7 +19393,7 @@ _Context: ${topQuestion.context}_`
|
|
|
19343
19393
|
try {
|
|
19344
19394
|
const factsText = entity.facts.slice(0, 10).join("; ");
|
|
19345
19395
|
const prompt = `Summarize this entity in one sentence. Entity: ${entity.name} (${entity.type}). Facts: ${factsText}`;
|
|
19346
|
-
const response = await this.
|
|
19396
|
+
const response = await this.fastLlm.chatCompletion(
|
|
19347
19397
|
[
|
|
19348
19398
|
{ role: "system", content: "Respond with a single concise sentence summarizing the entity. No JSON, just plain text." },
|
|
19349
19399
|
{ role: "user", content: prompt }
|
|
@@ -19445,7 +19495,7 @@ _Context: ${topQuestion.context}_`
|
|
|
19445
19495
|
const prompt = `You are a memory archivist. Summarize the following ${level}-level memories into 3\u20135 sentences, preserving key facts, decisions, and preferences.
|
|
19446
19496
|
|
|
19447
19497
|
${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
19448
|
-
const response = await this.
|
|
19498
|
+
const response = await this.fastLlm.chatCompletion(
|
|
19449
19499
|
[
|
|
19450
19500
|
{ role: "system", content: "Respond with a 3\u20135 sentence narrative summary. No JSON, just plain prose." },
|
|
19451
19501
|
{ role: "user", content: prompt }
|
|
@@ -19502,7 +19552,7 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
19502
19552
|
"Input candidate:",
|
|
19503
19553
|
JSON.stringify(baseline)
|
|
19504
19554
|
].join("\n");
|
|
19505
|
-
const response = await this.
|
|
19555
|
+
const response = await this.fastLlm.chatCompletion(
|
|
19506
19556
|
[
|
|
19507
19557
|
{ role: "system", content: "Respond with strict JSON only. No markdown." },
|
|
19508
19558
|
{ role: "user", content: prompt }
|
|
@@ -20114,7 +20164,7 @@ ${lines.join("\n\n")}`;
|
|
|
20114
20164
|
id: r.path,
|
|
20115
20165
|
snippet: r.snippet || r.path
|
|
20116
20166
|
})),
|
|
20117
|
-
local: this.
|
|
20167
|
+
local: this.fastLlm,
|
|
20118
20168
|
enabled: true,
|
|
20119
20169
|
timeoutMs: this.config.rerankTimeoutMs,
|
|
20120
20170
|
maxCandidates: this.config.rerankMaxCandidates,
|
|
@@ -27686,7 +27736,7 @@ var index_default = {
|
|
|
27686
27736
|
});
|
|
27687
27737
|
initLogger(api.logger, cfg.debug);
|
|
27688
27738
|
log.info(
|
|
27689
|
-
`initialized (debug=${cfg.debug}, qmdEnabled=${cfg.qmdEnabled}, transcriptEnabled=${cfg.transcriptEnabled}, hourlySummariesEnabled=${cfg.hourlySummariesEnabled}, localLlmEnabled=${cfg.localLlmEnabled})`
|
|
27739
|
+
`initialized (debug=${cfg.debug}, qmdEnabled=${cfg.qmdEnabled}, transcriptEnabled=${cfg.transcriptEnabled}, hourlySummariesEnabled=${cfg.hourlySummariesEnabled}, localLlmEnabled=${cfg.localLlmEnabled}${cfg.localLlmFastEnabled ? `, fastLlm=${cfg.localLlmFastModel || "(primary)"}` : ""})`
|
|
27690
27740
|
);
|
|
27691
27741
|
const existing = globalThis.__openclawEngramOrchestrator;
|
|
27692
27742
|
const orchestrator = existing?.recall ? existing : new Orchestrator(cfg);
|