@remnic/plugin-openclaw 1.0.13 → 1.0.15
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/{calibration-WCHOK6DX.js → calibration-WBEDZUR3.js} +1 -1
- package/dist/{causal-consolidation-YI53C2AO.js → causal-consolidation-K65BZXWS.js} +1 -1
- package/dist/{chunk-RQCTMECT.js → chunk-BCKAR3OK.js} +80 -6
- package/dist/{chunk-OAE7AQ6R.js → chunk-URJUGPZW.js} +2 -2
- package/dist/{engine-BIYI3P4J.js → engine-KJWHWWLM.js} +1 -1
- package/dist/{fallback-llm-WCWNGIQ3.js → fallback-llm-7PHTDZ4M.js} +1 -1
- package/dist/index.js +872 -8
- package/openclaw.plugin.json +17 -0
- package/package.json +2 -2
|
@@ -40,6 +40,17 @@ function buildChatCompletionTokenLimit(model, maxTokens, options) {
|
|
|
40
40
|
}
|
|
41
41
|
return { max_tokens: safeMaxTokens };
|
|
42
42
|
}
|
|
43
|
+
function supportsTemperature(model, options) {
|
|
44
|
+
const normalized = normalizedModel(model);
|
|
45
|
+
if (options?.assumeOpenAI === true && matchesModelFamily(normalized, /^gpt-5(?:$|[-.])/)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
function buildChatCompletionTemperature(model, temperature, options) {
|
|
51
|
+
if (!supportsTemperature(model, options)) return {};
|
|
52
|
+
return { temperature };
|
|
53
|
+
}
|
|
43
54
|
|
|
44
55
|
// ../remnic-core/src/resolve-provider-secret.ts
|
|
45
56
|
import path from "path";
|
|
@@ -255,6 +266,20 @@ function loadModelsJsonProviders() {
|
|
|
255
266
|
}
|
|
256
267
|
|
|
257
268
|
// ../remnic-core/src/fallback-llm.ts
|
|
269
|
+
var PROVIDER_ALIASES = {
|
|
270
|
+
"openai-codex": ["codex"],
|
|
271
|
+
codex: ["openai-codex"],
|
|
272
|
+
"claude-cli": ["anthropic"]
|
|
273
|
+
};
|
|
274
|
+
var LEGACY_PROVIDER_IDS = /* @__PURE__ */ new Set(["openai-codex", "claude-cli"]);
|
|
275
|
+
var BUILT_IN_PROVIDER_FALLBACKS = {
|
|
276
|
+
anthropic: {
|
|
277
|
+
baseUrl: "https://api.anthropic.com/v1",
|
|
278
|
+
api: "anthropic-messages",
|
|
279
|
+
apiKey: "secretref-managed",
|
|
280
|
+
models: []
|
|
281
|
+
}
|
|
282
|
+
};
|
|
258
283
|
var FallbackLlmClient = class {
|
|
259
284
|
gatewayConfig;
|
|
260
285
|
runtimeContext;
|
|
@@ -412,14 +437,59 @@ var FallbackLlmClient = class {
|
|
|
412
437
|
log.warn(`fallback LLM: invalid model format: ${modelString}`);
|
|
413
438
|
return null;
|
|
414
439
|
}
|
|
415
|
-
const
|
|
440
|
+
const requestedProviderId = parts[0];
|
|
416
441
|
const modelId = parts.slice(1).join("/");
|
|
417
|
-
const
|
|
442
|
+
const resolvedProvider = this.resolveProviderConfig(requestedProviderId, providers);
|
|
443
|
+
const providerConfig = resolvedProvider?.config;
|
|
418
444
|
if (!providerConfig) {
|
|
419
|
-
log.warn(
|
|
445
|
+
log.warn(
|
|
446
|
+
`fallback LLM: provider not found: ${requestedProviderId} (tried: ${this.providerResolutionCandidates(requestedProviderId).join(", ")})`
|
|
447
|
+
);
|
|
420
448
|
return null;
|
|
421
449
|
}
|
|
422
|
-
return {
|
|
450
|
+
return {
|
|
451
|
+
providerId: resolvedProvider.providerId,
|
|
452
|
+
modelId,
|
|
453
|
+
providerConfig,
|
|
454
|
+
modelString
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
resolveProviderConfig(providerId, providers) {
|
|
458
|
+
const candidates = this.providerResolutionCandidates(providerId);
|
|
459
|
+
const aliasCandidates = candidates.filter((candidate) => candidate !== providerId);
|
|
460
|
+
const fallbackCandidates = LEGACY_PROVIDER_IDS.has(providerId) ? [...aliasCandidates, providerId] : [providerId, ...aliasCandidates];
|
|
461
|
+
for (const candidate of candidates) {
|
|
462
|
+
const config = providers[candidate];
|
|
463
|
+
if (config) {
|
|
464
|
+
if (candidate !== providerId) {
|
|
465
|
+
log.debug(`fallback LLM: provider "${providerId}" resolved via alias "${candidate}"`);
|
|
466
|
+
}
|
|
467
|
+
return { providerId: candidate, config };
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (const candidate of fallbackCandidates) {
|
|
471
|
+
const config = this.resolveFromModelsJson(candidate);
|
|
472
|
+
if (config) {
|
|
473
|
+
if (candidate !== providerId) {
|
|
474
|
+
log.debug(`fallback LLM: provider "${providerId}" resolved via models.json alias "${candidate}"`);
|
|
475
|
+
}
|
|
476
|
+
return { providerId: candidate, config };
|
|
477
|
+
}
|
|
478
|
+
const builtInConfig = BUILT_IN_PROVIDER_FALLBACKS[candidate];
|
|
479
|
+
if (builtInConfig) {
|
|
480
|
+
if (candidate === providerId) {
|
|
481
|
+
log.debug(`fallback LLM: provider "${providerId}" resolved from built-in defaults`);
|
|
482
|
+
return { providerId, config: builtInConfig };
|
|
483
|
+
}
|
|
484
|
+
log.debug(`fallback LLM: provider "${providerId}" resolved via built-in alias "${candidate}"`);
|
|
485
|
+
return { providerId: candidate, config: builtInConfig };
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
providerResolutionCandidates(providerId) {
|
|
491
|
+
const candidates = [providerId, ...PROVIDER_ALIASES[providerId] ?? []];
|
|
492
|
+
return [...new Set(candidates)];
|
|
423
493
|
}
|
|
424
494
|
/**
|
|
425
495
|
* Look up a provider from the gateway's materialized models.json, which
|
|
@@ -540,7 +610,9 @@ var FallbackLlmClient = class {
|
|
|
540
610
|
const body = {
|
|
541
611
|
model: modelId,
|
|
542
612
|
messages,
|
|
543
|
-
|
|
613
|
+
...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {
|
|
614
|
+
assumeOpenAI
|
|
615
|
+
}),
|
|
544
616
|
...buildChatCompletionTokenLimit(modelId, options.maxTokens ?? 4096, {
|
|
545
617
|
assumeOpenAI
|
|
546
618
|
})
|
|
@@ -593,7 +665,9 @@ var FallbackLlmClient = class {
|
|
|
593
665
|
model: modelId,
|
|
594
666
|
input,
|
|
595
667
|
max_output_tokens: Math.max(0, Math.floor(options.maxTokens ?? 4096)),
|
|
596
|
-
|
|
668
|
+
...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {
|
|
669
|
+
assumeOpenAI: shouldAssumeOpenAiChatCompletions(config.baseUrl)
|
|
670
|
+
})
|
|
597
671
|
};
|
|
598
672
|
if (instructions.length > 0) {
|
|
599
673
|
body.instructions = instructions;
|
|
@@ -831,7 +831,7 @@ var CompoundingEngine = class {
|
|
|
831
831
|
let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
|
|
832
832
|
if (this.config.cmcConsolidationEnabled) {
|
|
833
833
|
try {
|
|
834
|
-
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-
|
|
834
|
+
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-K65BZXWS.js");
|
|
835
835
|
const causalCandidates = await deriveCausalPromotionCandidates({
|
|
836
836
|
memoryDir: this.config.memoryDir,
|
|
837
837
|
causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
|
|
@@ -863,7 +863,7 @@ var CompoundingEngine = class {
|
|
|
863
863
|
}
|
|
864
864
|
if (this.config.calibrationEnabled) {
|
|
865
865
|
try {
|
|
866
|
-
const { runCalibrationConsolidation } = await import("./calibration-
|
|
866
|
+
const { runCalibrationConsolidation } = await import("./calibration-WBEDZUR3.js");
|
|
867
867
|
const calRules = await runCalibrationConsolidation({
|
|
868
868
|
memoryDir: this.config.memoryDir,
|
|
869
869
|
gatewayConfig: this.config.gatewayConfig,
|
package/dist/index.js
CHANGED
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
CompoundingEngine,
|
|
116
116
|
SharedContextManager,
|
|
117
117
|
defaultTierMigrationCycleBudget
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-URJUGPZW.js";
|
|
119
119
|
import {
|
|
120
120
|
ZodError,
|
|
121
121
|
external_exports
|
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
buildChatCompletionTokenLimit,
|
|
133
133
|
findGatewayRuntimeModules,
|
|
134
134
|
shouldAssumeOpenAiChatCompletions
|
|
135
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-BCKAR3OK.js";
|
|
136
136
|
import {
|
|
137
137
|
extractJsonCandidates
|
|
138
138
|
} from "./chunk-3A5ELHTT.js";
|
|
@@ -601,6 +601,9 @@ var MEMORY_OS_PRESETS = {
|
|
|
601
601
|
contextCompressionActionsEnabled: true,
|
|
602
602
|
compressionGuidelineLearningEnabled: true,
|
|
603
603
|
compressionGuidelineSemanticRefinementEnabled: true,
|
|
604
|
+
explicitCueRecallEnabled: true,
|
|
605
|
+
explicitCueRecallMaxChars: 3200,
|
|
606
|
+
lcmEnabled: true,
|
|
604
607
|
maxProactiveQuestionsPerExtraction: 4,
|
|
605
608
|
maxCompressionTokensPerHour: 3e3,
|
|
606
609
|
behaviorLoopAutoTuneEnabled: true
|
|
@@ -1897,6 +1900,9 @@ function parseConfig(raw) {
|
|
|
1897
1900
|
temporalMemoryTreeEnabled: cfg.temporalMemoryTreeEnabled === true,
|
|
1898
1901
|
tmtHourlyMinMemories: typeof cfg.tmtHourlyMinMemories === "number" ? cfg.tmtHourlyMinMemories : 3,
|
|
1899
1902
|
tmtSummaryMaxTokens: typeof cfg.tmtSummaryMaxTokens === "number" ? cfg.tmtSummaryMaxTokens : 300,
|
|
1903
|
+
explicitCueRecallEnabled: coerceBool(cfg.explicitCueRecallEnabled) === true,
|
|
1904
|
+
explicitCueRecallMaxChars: coerceNumber(cfg.explicitCueRecallMaxChars) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxChars))) : 2400,
|
|
1905
|
+
explicitCueRecallMaxReferences: coerceNumber(cfg.explicitCueRecallMaxReferences) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxReferences))) : 24,
|
|
1900
1906
|
// Lossless Context Management (LCM)
|
|
1901
1907
|
lcmEnabled: cfg.lcmEnabled === true,
|
|
1902
1908
|
lcmLeafBatchSize: typeof cfg.lcmLeafBatchSize === "number" ? Math.max(2, Math.floor(cfg.lcmLeafBatchSize)) : 8,
|
|
@@ -2254,6 +2260,12 @@ function buildDefaultRecallPipeline(cfg) {
|
|
|
2254
2260
|
enabled: cfg.sharedContextEnabled === true,
|
|
2255
2261
|
maxChars: typeof cfg.sharedContextMaxInjectChars === "number" ? Math.max(0, Math.floor(cfg.sharedContextMaxInjectChars)) : 4e3
|
|
2256
2262
|
},
|
|
2263
|
+
{
|
|
2264
|
+
id: "explicit-cue",
|
|
2265
|
+
enabled: coerceBool(cfg.explicitCueRecallEnabled) === true,
|
|
2266
|
+
maxChars: coerceNumber(cfg.explicitCueRecallMaxChars) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxChars))) : 2400,
|
|
2267
|
+
maxResults: coerceNumber(cfg.explicitCueRecallMaxReferences) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxReferences))) : 24
|
|
2268
|
+
},
|
|
2257
2269
|
{
|
|
2258
2270
|
id: "profile",
|
|
2259
2271
|
enabled: true,
|
|
@@ -23087,6 +23099,827 @@ async function readRecentEntityTranscriptEntries(transcriptEntriesPromise, recen
|
|
|
23087
23099
|
}
|
|
23088
23100
|
var entityRecentTranscriptLookbackHours = RECENT_TRANSCRIPT_LOOKBACK_HOURS;
|
|
23089
23101
|
|
|
23102
|
+
// ../remnic-core/src/evidence-pack.ts
|
|
23103
|
+
var DEFAULT_MAX_ITEM_CHARS = 1200;
|
|
23104
|
+
function buildEvidencePack(items, options) {
|
|
23105
|
+
const budget = normalizePositiveInteger(options.maxChars);
|
|
23106
|
+
if (budget <= 0 || items.length === 0) {
|
|
23107
|
+
return "";
|
|
23108
|
+
}
|
|
23109
|
+
const maxItemChars = normalizePositiveInteger(
|
|
23110
|
+
options.maxItemChars ?? DEFAULT_MAX_ITEM_CHARS
|
|
23111
|
+
);
|
|
23112
|
+
if (maxItemChars <= 0) {
|
|
23113
|
+
return "";
|
|
23114
|
+
}
|
|
23115
|
+
const title = options.title ?? "Evidence";
|
|
23116
|
+
const lines = [`## ${title}`];
|
|
23117
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
23118
|
+
const seenContent = /* @__PURE__ */ new Set();
|
|
23119
|
+
let used = lines[0].length;
|
|
23120
|
+
for (const item of items) {
|
|
23121
|
+
const content = item.content.trim();
|
|
23122
|
+
if (!content) continue;
|
|
23123
|
+
const id = item.id ?? evidenceItemFallbackId(item);
|
|
23124
|
+
if (id && seenIds.has(id)) continue;
|
|
23125
|
+
const contentKey = normalizeEvidenceContent(content);
|
|
23126
|
+
if (seenContent.has(contentKey)) continue;
|
|
23127
|
+
const label = formatEvidenceLabel(item);
|
|
23128
|
+
const clipped = clipText(content, maxItemChars);
|
|
23129
|
+
const block = `${label}: ${clipped}`;
|
|
23130
|
+
const separatorLength = lines.length > 0 ? 2 : 0;
|
|
23131
|
+
const remaining = budget - used - separatorLength;
|
|
23132
|
+
if (remaining <= 0) break;
|
|
23133
|
+
const finalBlock = block.length > remaining ? clipText(block, remaining) : block;
|
|
23134
|
+
if (!finalBlock.trim()) break;
|
|
23135
|
+
lines.push(finalBlock);
|
|
23136
|
+
used += separatorLength + finalBlock.length;
|
|
23137
|
+
if (id) seenIds.add(id);
|
|
23138
|
+
seenContent.add(contentKey);
|
|
23139
|
+
}
|
|
23140
|
+
return lines.length === 1 ? "" : lines.join("\n\n");
|
|
23141
|
+
}
|
|
23142
|
+
function normalizePositiveInteger(value) {
|
|
23143
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
23144
|
+
return 0;
|
|
23145
|
+
}
|
|
23146
|
+
return Math.floor(value);
|
|
23147
|
+
}
|
|
23148
|
+
function evidenceItemFallbackId(item) {
|
|
23149
|
+
if (item.sessionId && typeof item.turnIndex === "number") {
|
|
23150
|
+
return `${item.sessionId}:${item.turnIndex}`;
|
|
23151
|
+
}
|
|
23152
|
+
return void 0;
|
|
23153
|
+
}
|
|
23154
|
+
function normalizeEvidenceContent(content) {
|
|
23155
|
+
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
23156
|
+
}
|
|
23157
|
+
function formatEvidenceLabel(item) {
|
|
23158
|
+
const parts = [];
|
|
23159
|
+
if (item.sessionId) parts.push(item.sessionId);
|
|
23160
|
+
if (typeof item.turnIndex === "number") parts.push(`turn ${item.turnIndex}`);
|
|
23161
|
+
if (item.role) parts.push(item.role);
|
|
23162
|
+
if (typeof item.score === "number" && Number.isFinite(item.score)) {
|
|
23163
|
+
parts.push(`score ${item.score.toFixed(3)}`);
|
|
23164
|
+
}
|
|
23165
|
+
return parts.length > 0 ? `[${parts.join(", ")}]` : "[evidence]";
|
|
23166
|
+
}
|
|
23167
|
+
function clipText(text, maxChars) {
|
|
23168
|
+
if (text.length <= maxChars) {
|
|
23169
|
+
return text;
|
|
23170
|
+
}
|
|
23171
|
+
if (maxChars <= 1) {
|
|
23172
|
+
return text.slice(0, maxChars);
|
|
23173
|
+
}
|
|
23174
|
+
if (maxChars <= 3) {
|
|
23175
|
+
return text.slice(0, maxChars);
|
|
23176
|
+
}
|
|
23177
|
+
return `${text.slice(0, maxChars - 3).trimEnd()}...`;
|
|
23178
|
+
}
|
|
23179
|
+
|
|
23180
|
+
// ../remnic-core/src/explicit-cue-recall.ts
|
|
23181
|
+
var DEFAULT_MAX_CHARS = 2400;
|
|
23182
|
+
var DEFAULT_MAX_ITEM_CHARS2 = 1200;
|
|
23183
|
+
var DEFAULT_MAX_REFERENCES = 24;
|
|
23184
|
+
var REFERENCE_SCAN_TOKEN_FACTOR = 3;
|
|
23185
|
+
var TURN_REFERENCE_WINDOW_RADIUS = 0;
|
|
23186
|
+
var LEXICAL_CUE_WINDOW_RADIUS = 1;
|
|
23187
|
+
var LEXICAL_CUE_SEARCH_LIMIT = 3;
|
|
23188
|
+
var LEXICAL_CUE_MAX_TOKENS = 400;
|
|
23189
|
+
var LATEST_STATE_CUES = /* @__PURE__ */ new Set([
|
|
23190
|
+
"as of",
|
|
23191
|
+
"currently",
|
|
23192
|
+
"latest",
|
|
23193
|
+
"most recent",
|
|
23194
|
+
"newest",
|
|
23195
|
+
"now",
|
|
23196
|
+
"updated",
|
|
23197
|
+
"changed",
|
|
23198
|
+
"change"
|
|
23199
|
+
]);
|
|
23200
|
+
var STRUCTURED_PLAN_FIELD_CUES = /* @__PURE__ */ new Set([
|
|
23201
|
+
"accommodation",
|
|
23202
|
+
"attraction",
|
|
23203
|
+
"breakfast",
|
|
23204
|
+
"current city",
|
|
23205
|
+
"dinner",
|
|
23206
|
+
"flight",
|
|
23207
|
+
"flights",
|
|
23208
|
+
"hotel",
|
|
23209
|
+
"lunch",
|
|
23210
|
+
"restaurant",
|
|
23211
|
+
"restaurants",
|
|
23212
|
+
"transportation",
|
|
23213
|
+
"traveler",
|
|
23214
|
+
"travelers"
|
|
23215
|
+
]);
|
|
23216
|
+
var STRUCTURED_PLAN_DEPENDENCY_CUES = /* @__PURE__ */ new Set([
|
|
23217
|
+
"comparison",
|
|
23218
|
+
"constraint",
|
|
23219
|
+
"constraints",
|
|
23220
|
+
"dependency",
|
|
23221
|
+
"dependencies",
|
|
23222
|
+
"join",
|
|
23223
|
+
"same",
|
|
23224
|
+
"shared"
|
|
23225
|
+
]);
|
|
23226
|
+
var BENCHMARK_ABILITY_CUES = /* @__PURE__ */ new Map([
|
|
23227
|
+
["information extraction", "ability=information_extraction"],
|
|
23228
|
+
["knowledge update", "ability=knowledge_update"],
|
|
23229
|
+
["multi session reasoning", "ability=multi_session_reasoning"],
|
|
23230
|
+
["multi-session reasoning", "ability=multi_session_reasoning"],
|
|
23231
|
+
["instruction following", "ability=instruction_following"]
|
|
23232
|
+
]);
|
|
23233
|
+
var BENCHMARK_ANCHOR_VALUE_STOPWORDS = /* @__PURE__ */ new Set([
|
|
23234
|
+
"a",
|
|
23235
|
+
"about",
|
|
23236
|
+
"an",
|
|
23237
|
+
"for",
|
|
23238
|
+
"from",
|
|
23239
|
+
"in",
|
|
23240
|
+
"on",
|
|
23241
|
+
"the",
|
|
23242
|
+
"to",
|
|
23243
|
+
"use",
|
|
23244
|
+
"using",
|
|
23245
|
+
"with"
|
|
23246
|
+
]);
|
|
23247
|
+
var RELATIVE_TEMPORAL_CUES = [
|
|
23248
|
+
"as of",
|
|
23249
|
+
"most recent",
|
|
23250
|
+
"last time",
|
|
23251
|
+
"last week",
|
|
23252
|
+
"last month",
|
|
23253
|
+
"last year",
|
|
23254
|
+
"last session",
|
|
23255
|
+
"last conversation",
|
|
23256
|
+
"next time",
|
|
23257
|
+
"next week",
|
|
23258
|
+
"next month",
|
|
23259
|
+
"next year",
|
|
23260
|
+
"next session",
|
|
23261
|
+
"next conversation",
|
|
23262
|
+
"previous time",
|
|
23263
|
+
"previous week",
|
|
23264
|
+
"previous month",
|
|
23265
|
+
"previous year",
|
|
23266
|
+
"previous session",
|
|
23267
|
+
"previous conversation",
|
|
23268
|
+
"prior time",
|
|
23269
|
+
"prior week",
|
|
23270
|
+
"prior month",
|
|
23271
|
+
"prior year",
|
|
23272
|
+
"prior session",
|
|
23273
|
+
"prior conversation",
|
|
23274
|
+
"today",
|
|
23275
|
+
"yesterday",
|
|
23276
|
+
"tomorrow",
|
|
23277
|
+
"tonight",
|
|
23278
|
+
"earlier",
|
|
23279
|
+
"later",
|
|
23280
|
+
"recently",
|
|
23281
|
+
"previously",
|
|
23282
|
+
"currently",
|
|
23283
|
+
"now",
|
|
23284
|
+
"latest",
|
|
23285
|
+
"newest",
|
|
23286
|
+
"oldest",
|
|
23287
|
+
"earliest",
|
|
23288
|
+
"before",
|
|
23289
|
+
"after",
|
|
23290
|
+
"since",
|
|
23291
|
+
"updated",
|
|
23292
|
+
"changed",
|
|
23293
|
+
"change"
|
|
23294
|
+
];
|
|
23295
|
+
var SPEAKER_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
23296
|
+
"A",
|
|
23297
|
+
"According",
|
|
23298
|
+
"An",
|
|
23299
|
+
"And",
|
|
23300
|
+
"Are",
|
|
23301
|
+
"As",
|
|
23302
|
+
"At",
|
|
23303
|
+
"Before",
|
|
23304
|
+
"Can",
|
|
23305
|
+
"Compare",
|
|
23306
|
+
"Could",
|
|
23307
|
+
"Did",
|
|
23308
|
+
"Do",
|
|
23309
|
+
"Does",
|
|
23310
|
+
"For",
|
|
23311
|
+
"From",
|
|
23312
|
+
"Had",
|
|
23313
|
+
"Has",
|
|
23314
|
+
"Have",
|
|
23315
|
+
"How",
|
|
23316
|
+
"In",
|
|
23317
|
+
"Is",
|
|
23318
|
+
"It",
|
|
23319
|
+
"Join",
|
|
23320
|
+
"Of",
|
|
23321
|
+
"On",
|
|
23322
|
+
"Or",
|
|
23323
|
+
"Please",
|
|
23324
|
+
"Review",
|
|
23325
|
+
"Step",
|
|
23326
|
+
"Tell",
|
|
23327
|
+
"The",
|
|
23328
|
+
"To",
|
|
23329
|
+
"Turn",
|
|
23330
|
+
"Use",
|
|
23331
|
+
"Was",
|
|
23332
|
+
"Were",
|
|
23333
|
+
"What",
|
|
23334
|
+
"When",
|
|
23335
|
+
"Where",
|
|
23336
|
+
"Which",
|
|
23337
|
+
"Who",
|
|
23338
|
+
"Why",
|
|
23339
|
+
"Will",
|
|
23340
|
+
"Would"
|
|
23341
|
+
]);
|
|
23342
|
+
var QUESTION_SLOT_STOPWORDS = /* @__PURE__ */ new Set([
|
|
23343
|
+
"answer",
|
|
23344
|
+
"choice",
|
|
23345
|
+
"did",
|
|
23346
|
+
"does",
|
|
23347
|
+
"do",
|
|
23348
|
+
"is",
|
|
23349
|
+
"should",
|
|
23350
|
+
"single",
|
|
23351
|
+
"the",
|
|
23352
|
+
"user",
|
|
23353
|
+
"was",
|
|
23354
|
+
"were"
|
|
23355
|
+
]);
|
|
23356
|
+
async function buildExplicitCueRecallSection(options) {
|
|
23357
|
+
const engine = options.engine;
|
|
23358
|
+
const query = options.query.trim();
|
|
23359
|
+
const maxChars = normalizePositiveInteger2(options.maxChars, DEFAULT_MAX_CHARS);
|
|
23360
|
+
if (!engine || query.length === 0 || maxChars <= 0) {
|
|
23361
|
+
return "";
|
|
23362
|
+
}
|
|
23363
|
+
const maxReferences = normalizePositiveInteger2(
|
|
23364
|
+
options.maxReferences,
|
|
23365
|
+
DEFAULT_MAX_REFERENCES
|
|
23366
|
+
);
|
|
23367
|
+
if (maxReferences <= 0) {
|
|
23368
|
+
return "";
|
|
23369
|
+
}
|
|
23370
|
+
const evidenceItems = [];
|
|
23371
|
+
const seenTurns = /* @__PURE__ */ new Set();
|
|
23372
|
+
await collectTurnReferenceEvidence({
|
|
23373
|
+
engine,
|
|
23374
|
+
sessionId: options.sessionId,
|
|
23375
|
+
query,
|
|
23376
|
+
maxReferences,
|
|
23377
|
+
evidenceItems,
|
|
23378
|
+
seenTurns
|
|
23379
|
+
});
|
|
23380
|
+
await collectLexicalCueEvidence({
|
|
23381
|
+
engine,
|
|
23382
|
+
sessionId: options.sessionId,
|
|
23383
|
+
query,
|
|
23384
|
+
maxReferences,
|
|
23385
|
+
includeBenchmarkAnchorCues: options.includeBenchmarkAnchorCues,
|
|
23386
|
+
includeStructuredPlanCues: options.includeStructuredPlanCues,
|
|
23387
|
+
evidenceItems,
|
|
23388
|
+
seenTurns
|
|
23389
|
+
});
|
|
23390
|
+
return buildEvidencePack(evidenceItems, {
|
|
23391
|
+
title: "Explicit Cue Evidence",
|
|
23392
|
+
maxChars,
|
|
23393
|
+
maxItemChars: normalizePositiveInteger2(
|
|
23394
|
+
options.maxItemChars,
|
|
23395
|
+
DEFAULT_MAX_ITEM_CHARS2
|
|
23396
|
+
)
|
|
23397
|
+
});
|
|
23398
|
+
}
|
|
23399
|
+
async function collectTurnReferenceEvidence(options) {
|
|
23400
|
+
if (!options.sessionId) {
|
|
23401
|
+
return;
|
|
23402
|
+
}
|
|
23403
|
+
const references = collectExplicitTurnReferences(options.query).slice(
|
|
23404
|
+
0,
|
|
23405
|
+
options.maxReferences
|
|
23406
|
+
);
|
|
23407
|
+
if (references.length === 0) {
|
|
23408
|
+
return;
|
|
23409
|
+
}
|
|
23410
|
+
const windows = /* @__PURE__ */ new Map();
|
|
23411
|
+
for (const reference of references) {
|
|
23412
|
+
for (const center of candidateTurnIndexesForReference(reference)) {
|
|
23413
|
+
if (center < 0) {
|
|
23414
|
+
continue;
|
|
23415
|
+
}
|
|
23416
|
+
const fromTurn = Math.max(0, center - TURN_REFERENCE_WINDOW_RADIUS);
|
|
23417
|
+
const toTurn = center + TURN_REFERENCE_WINDOW_RADIUS;
|
|
23418
|
+
windows.set(`${fromTurn}:${toTurn}`, { fromTurn, toTurn });
|
|
23419
|
+
}
|
|
23420
|
+
}
|
|
23421
|
+
for (const window of [...windows.values()].sort(
|
|
23422
|
+
(left, right) => left.fromTurn - right.fromTurn || left.toTurn - right.toTurn
|
|
23423
|
+
)) {
|
|
23424
|
+
const expanded = await options.engine.expandContext(
|
|
23425
|
+
options.sessionId,
|
|
23426
|
+
window.fromTurn,
|
|
23427
|
+
window.toTurn,
|
|
23428
|
+
2e3
|
|
23429
|
+
);
|
|
23430
|
+
appendExpandedEvidence(
|
|
23431
|
+
options.evidenceItems,
|
|
23432
|
+
options.seenTurns,
|
|
23433
|
+
options.sessionId,
|
|
23434
|
+
expanded
|
|
23435
|
+
);
|
|
23436
|
+
}
|
|
23437
|
+
}
|
|
23438
|
+
async function collectLexicalCueEvidence(options) {
|
|
23439
|
+
const cues = collectLexicalCues(options.query, {
|
|
23440
|
+
includeBenchmarkAnchorCues: options.includeBenchmarkAnchorCues,
|
|
23441
|
+
includeStructuredPlanCues: options.includeStructuredPlanCues
|
|
23442
|
+
}).slice(0, options.maxReferences);
|
|
23443
|
+
const preferLatest = hasLatestStateIntent(options.query);
|
|
23444
|
+
for (const cue of cues) {
|
|
23445
|
+
const results = sortLexicalCueResults(
|
|
23446
|
+
await options.engine.searchContextFull(
|
|
23447
|
+
cue,
|
|
23448
|
+
LEXICAL_CUE_SEARCH_LIMIT,
|
|
23449
|
+
options.sessionId
|
|
23450
|
+
),
|
|
23451
|
+
preferLatest
|
|
23452
|
+
);
|
|
23453
|
+
for (const result of results) {
|
|
23454
|
+
const windowRadius = preferLatest ? 0 : LEXICAL_CUE_WINDOW_RADIUS;
|
|
23455
|
+
const fromTurn = Math.max(0, result.turn_index - windowRadius);
|
|
23456
|
+
const toTurn = result.turn_index + windowRadius;
|
|
23457
|
+
const expanded = await options.engine.expandContext(
|
|
23458
|
+
result.session_id,
|
|
23459
|
+
fromTurn,
|
|
23460
|
+
toTurn,
|
|
23461
|
+
LEXICAL_CUE_MAX_TOKENS
|
|
23462
|
+
);
|
|
23463
|
+
if (expanded.length === 0) {
|
|
23464
|
+
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
23465
|
+
id: `${result.session_id}:${result.turn_index}`,
|
|
23466
|
+
sessionId: result.session_id,
|
|
23467
|
+
turnIndex: result.turn_index,
|
|
23468
|
+
role: result.role,
|
|
23469
|
+
content: result.content,
|
|
23470
|
+
...typeof result.score === "number" ? { score: result.score } : {}
|
|
23471
|
+
});
|
|
23472
|
+
continue;
|
|
23473
|
+
}
|
|
23474
|
+
appendExpandedEvidence(
|
|
23475
|
+
options.evidenceItems,
|
|
23476
|
+
options.seenTurns,
|
|
23477
|
+
result.session_id,
|
|
23478
|
+
expanded
|
|
23479
|
+
);
|
|
23480
|
+
}
|
|
23481
|
+
}
|
|
23482
|
+
}
|
|
23483
|
+
function appendExpandedEvidence(evidenceItems, seenTurns, sessionId, expanded) {
|
|
23484
|
+
for (const message of expanded) {
|
|
23485
|
+
appendEvidenceItem(evidenceItems, seenTurns, {
|
|
23486
|
+
id: `${sessionId}:${message.turn_index}`,
|
|
23487
|
+
sessionId,
|
|
23488
|
+
turnIndex: message.turn_index,
|
|
23489
|
+
role: message.role,
|
|
23490
|
+
content: message.content
|
|
23491
|
+
});
|
|
23492
|
+
}
|
|
23493
|
+
}
|
|
23494
|
+
function appendEvidenceItem(evidenceItems, seenTurns, item) {
|
|
23495
|
+
if (seenTurns.has(item.id)) {
|
|
23496
|
+
return;
|
|
23497
|
+
}
|
|
23498
|
+
seenTurns.add(item.id);
|
|
23499
|
+
evidenceItems.push(item);
|
|
23500
|
+
}
|
|
23501
|
+
function collectExplicitTurnReferences(query) {
|
|
23502
|
+
const references = /* @__PURE__ */ new Map();
|
|
23503
|
+
const addReference = (value, label) => {
|
|
23504
|
+
const existing = references.get(String(value));
|
|
23505
|
+
references.set(String(value), {
|
|
23506
|
+
number: value,
|
|
23507
|
+
includeDirectTurn: (existing?.includeDirectTurn ?? false) || label === "turn"
|
|
23508
|
+
});
|
|
23509
|
+
};
|
|
23510
|
+
const tokens = tokenizeReferenceQuery(query);
|
|
23511
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
23512
|
+
const label = normalizeReferenceLabel(tokens[index]);
|
|
23513
|
+
if (!label) {
|
|
23514
|
+
continue;
|
|
23515
|
+
}
|
|
23516
|
+
const parsed = parseReferenceNumbers(tokens, index + 1);
|
|
23517
|
+
for (const number of parsed.numbers) {
|
|
23518
|
+
addReference(number, label);
|
|
23519
|
+
}
|
|
23520
|
+
index = Math.max(index, parsed.nextIndex - 1);
|
|
23521
|
+
}
|
|
23522
|
+
return [...references.values()].sort((left, right) => left.number - right.number);
|
|
23523
|
+
}
|
|
23524
|
+
function collectLexicalCues(query, options = {}) {
|
|
23525
|
+
const cues = /* @__PURE__ */ new Set();
|
|
23526
|
+
for (const match of query.matchAll(/\b[A-Za-z][A-Za-z0-9]{0,12}\d+:\d+\b/g)) {
|
|
23527
|
+
cues.add(match[0]);
|
|
23528
|
+
}
|
|
23529
|
+
for (const match of query.matchAll(/\b\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2})?Z?)?\b/g)) {
|
|
23530
|
+
cues.add(match[0]);
|
|
23531
|
+
}
|
|
23532
|
+
for (const cue of collectTemporalLexicalCues(query)) {
|
|
23533
|
+
cues.add(cue);
|
|
23534
|
+
}
|
|
23535
|
+
for (const cue of collectQuestionSlotCues(query)) {
|
|
23536
|
+
cues.add(cue);
|
|
23537
|
+
}
|
|
23538
|
+
if (options.includeBenchmarkAnchorCues) {
|
|
23539
|
+
for (const cue of collectBenchmarkAnchorCues(query)) {
|
|
23540
|
+
cues.add(cue);
|
|
23541
|
+
}
|
|
23542
|
+
}
|
|
23543
|
+
if (options.includeStructuredPlanCues) {
|
|
23544
|
+
for (const cue of collectStructuredPlanCues(query)) {
|
|
23545
|
+
cues.add(cue);
|
|
23546
|
+
}
|
|
23547
|
+
}
|
|
23548
|
+
for (const match of query.matchAll(/\b(?:session|source|chat|plan|task|event|file|tool)[_-][A-Za-z0-9][A-Za-z0-9_.:-]{0,80}\b/gi)) {
|
|
23549
|
+
cues.add(match[0]);
|
|
23550
|
+
}
|
|
23551
|
+
for (const match of query.matchAll(/\b[A-Z][a-z]{1,30}(?:\s+[A-Z][a-z]{1,30}){0,2}\b/g)) {
|
|
23552
|
+
const value = normalizeSpeakerNameCue(match[0]);
|
|
23553
|
+
if (value) {
|
|
23554
|
+
cues.add(value);
|
|
23555
|
+
}
|
|
23556
|
+
}
|
|
23557
|
+
for (const match of query.matchAll(/\[([A-Za-z0-9][A-Za-z0-9_.:/ -]{1,80})\]/g)) {
|
|
23558
|
+
const value = match[1]?.trim();
|
|
23559
|
+
if (value) {
|
|
23560
|
+
cues.add(value);
|
|
23561
|
+
}
|
|
23562
|
+
}
|
|
23563
|
+
return [...cues].sort((left, right) => left.localeCompare(right));
|
|
23564
|
+
}
|
|
23565
|
+
function collectQuestionSlotCues(query) {
|
|
23566
|
+
const cues = /* @__PURE__ */ new Set();
|
|
23567
|
+
for (const match of query.matchAll(
|
|
23568
|
+
/\b(?:what|which)\s+([a-z][a-z0-9_-]{2,30})\s+(?:does|do|did|is|are|was|were|should|would|could|can|will)\b/gi
|
|
23569
|
+
)) {
|
|
23570
|
+
const value = match[1]?.toLowerCase();
|
|
23571
|
+
if (value && !QUESTION_SLOT_STOPWORDS.has(value)) {
|
|
23572
|
+
cues.add(value);
|
|
23573
|
+
}
|
|
23574
|
+
}
|
|
23575
|
+
return [...cues].sort((left, right) => left.localeCompare(right));
|
|
23576
|
+
}
|
|
23577
|
+
function collectBenchmarkAnchorCues(query) {
|
|
23578
|
+
const cues = /* @__PURE__ */ new Set();
|
|
23579
|
+
const normalizedQuery = query.toLowerCase().replace(/\s+/g, " ");
|
|
23580
|
+
for (const [phrase, cue] of BENCHMARK_ABILITY_CUES) {
|
|
23581
|
+
if (containsBoundedPhrase(normalizedQuery, phrase)) {
|
|
23582
|
+
cues.add(cue);
|
|
23583
|
+
}
|
|
23584
|
+
}
|
|
23585
|
+
const tokens = tokenizeAnchorQuery(query);
|
|
23586
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
23587
|
+
let prefix = normalizeBenchmarkAnchorPrefix(tokens[index]);
|
|
23588
|
+
if (!prefix) {
|
|
23589
|
+
continue;
|
|
23590
|
+
}
|
|
23591
|
+
let valueIndex = index + 1;
|
|
23592
|
+
if (prefix === "source" && tokens[valueIndex]?.toLowerCase() === "chat") {
|
|
23593
|
+
prefix = "source_chat";
|
|
23594
|
+
valueIndex += 1;
|
|
23595
|
+
}
|
|
23596
|
+
const maybeIdLabel = tokens[valueIndex]?.toLowerCase();
|
|
23597
|
+
if (maybeIdLabel === "id" || maybeIdLabel === "ids") {
|
|
23598
|
+
valueIndex += 1;
|
|
23599
|
+
}
|
|
23600
|
+
let consumedValue = false;
|
|
23601
|
+
for (let currentValueIndex = valueIndex; currentValueIndex < tokens.length; currentValueIndex += 1) {
|
|
23602
|
+
const rawValue = tokens[currentValueIndex];
|
|
23603
|
+
const normalizedValue = rawValue?.toLowerCase();
|
|
23604
|
+
if (!rawValue || normalizeBenchmarkAnchorPrefix(rawValue)) {
|
|
23605
|
+
break;
|
|
23606
|
+
}
|
|
23607
|
+
if (normalizedValue === "and" || normalizedValue === "or") {
|
|
23608
|
+
continue;
|
|
23609
|
+
}
|
|
23610
|
+
if (BENCHMARK_ANCHOR_VALUE_STOPWORDS.has(normalizedValue)) {
|
|
23611
|
+
break;
|
|
23612
|
+
}
|
|
23613
|
+
if (!isBenchmarkAnchorValue(rawValue)) {
|
|
23614
|
+
break;
|
|
23615
|
+
}
|
|
23616
|
+
addBenchmarkAnchorCues(cues, prefix, rawValue);
|
|
23617
|
+
consumedValue = true;
|
|
23618
|
+
index = currentValueIndex;
|
|
23619
|
+
}
|
|
23620
|
+
if (!consumedValue) {
|
|
23621
|
+
continue;
|
|
23622
|
+
}
|
|
23623
|
+
}
|
|
23624
|
+
return [...cues].sort((left, right) => left.localeCompare(right));
|
|
23625
|
+
}
|
|
23626
|
+
function addBenchmarkAnchorCues(cues, prefix, rawValue) {
|
|
23627
|
+
cues.add(`${prefix}_id=${rawValue}`);
|
|
23628
|
+
cues.add(`${prefix}-${rawValue}`);
|
|
23629
|
+
if (prefix === "source_chat") {
|
|
23630
|
+
cues.add(`chat_id=${rawValue}`);
|
|
23631
|
+
}
|
|
23632
|
+
}
|
|
23633
|
+
function isBenchmarkAnchorValue(token) {
|
|
23634
|
+
for (const char of token) {
|
|
23635
|
+
if (isAsciiDigitChar(char)) {
|
|
23636
|
+
return true;
|
|
23637
|
+
}
|
|
23638
|
+
}
|
|
23639
|
+
return false;
|
|
23640
|
+
}
|
|
23641
|
+
function isAsciiDigitChar(char) {
|
|
23642
|
+
const code = char.charCodeAt(0);
|
|
23643
|
+
return code >= 48 && code <= 57;
|
|
23644
|
+
}
|
|
23645
|
+
function normalizeBenchmarkAnchorPrefix(token) {
|
|
23646
|
+
switch (token?.toLowerCase()) {
|
|
23647
|
+
case "ability":
|
|
23648
|
+
case "chat":
|
|
23649
|
+
case "plan":
|
|
23650
|
+
case "rubric":
|
|
23651
|
+
case "source":
|
|
23652
|
+
return token.toLowerCase();
|
|
23653
|
+
default:
|
|
23654
|
+
return void 0;
|
|
23655
|
+
}
|
|
23656
|
+
}
|
|
23657
|
+
function tokenizeAnchorQuery(query) {
|
|
23658
|
+
const tokens = [];
|
|
23659
|
+
let current = "";
|
|
23660
|
+
const push = () => {
|
|
23661
|
+
const token = trimTrailingAnchorTokenPunctuation(current);
|
|
23662
|
+
if (token.length > 0) {
|
|
23663
|
+
tokens.push(token);
|
|
23664
|
+
}
|
|
23665
|
+
current = "";
|
|
23666
|
+
};
|
|
23667
|
+
for (const char of query) {
|
|
23668
|
+
if (isAsciiLetterOrDigit(char) || char === "_" || char === "-" || char === "." || char === ":") {
|
|
23669
|
+
current += char;
|
|
23670
|
+
continue;
|
|
23671
|
+
}
|
|
23672
|
+
push();
|
|
23673
|
+
}
|
|
23674
|
+
push();
|
|
23675
|
+
return tokens;
|
|
23676
|
+
}
|
|
23677
|
+
function trimTrailingAnchorTokenPunctuation(token) {
|
|
23678
|
+
let end = token.length;
|
|
23679
|
+
while (end > 0) {
|
|
23680
|
+
const char = token[end - 1];
|
|
23681
|
+
if (char !== "." && char !== ":" && char !== ";" && char !== "!" && char !== "?") {
|
|
23682
|
+
break;
|
|
23683
|
+
}
|
|
23684
|
+
end -= 1;
|
|
23685
|
+
}
|
|
23686
|
+
return token.slice(0, end);
|
|
23687
|
+
}
|
|
23688
|
+
function collectStructuredPlanCues(query) {
|
|
23689
|
+
const cues = /* @__PURE__ */ new Set();
|
|
23690
|
+
const normalizedQuery = query.toLowerCase().replace(/\s+/g, " ");
|
|
23691
|
+
for (const cue of STRUCTURED_PLAN_FIELD_CUES) {
|
|
23692
|
+
if (containsBoundedPhrase(normalizedQuery, cue)) {
|
|
23693
|
+
cues.add(cue);
|
|
23694
|
+
}
|
|
23695
|
+
}
|
|
23696
|
+
if (cues.size === 0) {
|
|
23697
|
+
return [];
|
|
23698
|
+
}
|
|
23699
|
+
for (const cue of STRUCTURED_PLAN_DEPENDENCY_CUES) {
|
|
23700
|
+
if (containsBoundedPhrase(normalizedQuery, cue)) {
|
|
23701
|
+
cues.add(cue);
|
|
23702
|
+
}
|
|
23703
|
+
}
|
|
23704
|
+
return [...cues].sort((left, right) => left.localeCompare(right));
|
|
23705
|
+
}
|
|
23706
|
+
function containsBoundedPhrase(normalizedHaystack, phrase) {
|
|
23707
|
+
let searchFrom = 0;
|
|
23708
|
+
while (searchFrom < normalizedHaystack.length) {
|
|
23709
|
+
const index = normalizedHaystack.indexOf(phrase, searchFrom);
|
|
23710
|
+
if (index < 0) {
|
|
23711
|
+
return false;
|
|
23712
|
+
}
|
|
23713
|
+
const afterIndex = index + phrase.length;
|
|
23714
|
+
if (isTemporalCueBoundary(normalizedHaystack[index - 1]) && isTemporalCueBoundary(normalizedHaystack[afterIndex])) {
|
|
23715
|
+
return true;
|
|
23716
|
+
}
|
|
23717
|
+
searchFrom = afterIndex;
|
|
23718
|
+
}
|
|
23719
|
+
return false;
|
|
23720
|
+
}
|
|
23721
|
+
function collectTemporalLexicalCues(query) {
|
|
23722
|
+
const cues = /* @__PURE__ */ new Set();
|
|
23723
|
+
const normalizedQuery = query.toLowerCase().replace(/\s+/g, " ");
|
|
23724
|
+
for (const cue of RELATIVE_TEMPORAL_CUES) {
|
|
23725
|
+
if (containsBoundedPhrase(normalizedQuery, cue)) {
|
|
23726
|
+
cues.add(cue);
|
|
23727
|
+
}
|
|
23728
|
+
}
|
|
23729
|
+
return [...cues].sort((left, right) => left.localeCompare(right));
|
|
23730
|
+
}
|
|
23731
|
+
function hasLatestStateIntent(query) {
|
|
23732
|
+
return collectTemporalLexicalCues(query).some(
|
|
23733
|
+
(cue) => LATEST_STATE_CUES.has(cue)
|
|
23734
|
+
);
|
|
23735
|
+
}
|
|
23736
|
+
function sortLexicalCueResults(results, preferLatest) {
|
|
23737
|
+
return [...results].sort((left, right) => {
|
|
23738
|
+
if (preferLatest) {
|
|
23739
|
+
const sessionOrder2 = left.session_id.localeCompare(right.session_id);
|
|
23740
|
+
if (sessionOrder2 !== 0) {
|
|
23741
|
+
return sessionOrder2;
|
|
23742
|
+
}
|
|
23743
|
+
const turnOrder = right.turn_index - left.turn_index;
|
|
23744
|
+
if (turnOrder !== 0) {
|
|
23745
|
+
return turnOrder;
|
|
23746
|
+
}
|
|
23747
|
+
return (right.score ?? 0) - (left.score ?? 0);
|
|
23748
|
+
}
|
|
23749
|
+
const scoreDelta = (right.score ?? 0) - (left.score ?? 0);
|
|
23750
|
+
if (scoreDelta !== 0) {
|
|
23751
|
+
return scoreDelta;
|
|
23752
|
+
}
|
|
23753
|
+
const sessionOrder = left.session_id.localeCompare(right.session_id);
|
|
23754
|
+
if (sessionOrder !== 0) {
|
|
23755
|
+
return sessionOrder;
|
|
23756
|
+
}
|
|
23757
|
+
return left.turn_index - right.turn_index;
|
|
23758
|
+
});
|
|
23759
|
+
}
|
|
23760
|
+
function normalizeSpeakerNameCue(value) {
|
|
23761
|
+
const words = value.trim().split(/\s+/).filter(Boolean);
|
|
23762
|
+
while (words.length > 0 && SPEAKER_NAME_STOPWORDS.has(words[0])) {
|
|
23763
|
+
words.shift();
|
|
23764
|
+
}
|
|
23765
|
+
while (words.length > 0 && SPEAKER_NAME_STOPWORDS.has(words[words.length - 1])) {
|
|
23766
|
+
words.pop();
|
|
23767
|
+
}
|
|
23768
|
+
return words.length > 0 ? words.join(" ") : void 0;
|
|
23769
|
+
}
|
|
23770
|
+
function isTemporalCueBoundary(char) {
|
|
23771
|
+
if (!char) {
|
|
23772
|
+
return true;
|
|
23773
|
+
}
|
|
23774
|
+
return !isAsciiLetterOrDigit(char);
|
|
23775
|
+
}
|
|
23776
|
+
function tokenizeReferenceQuery(query) {
|
|
23777
|
+
const tokens = [];
|
|
23778
|
+
let current = "";
|
|
23779
|
+
const flushCurrent = () => {
|
|
23780
|
+
if (current) {
|
|
23781
|
+
tokens.push(current);
|
|
23782
|
+
current = "";
|
|
23783
|
+
}
|
|
23784
|
+
};
|
|
23785
|
+
for (const char of query) {
|
|
23786
|
+
if (isAsciiLetterOrDigit(char)) {
|
|
23787
|
+
current += char;
|
|
23788
|
+
continue;
|
|
23789
|
+
}
|
|
23790
|
+
flushCurrent();
|
|
23791
|
+
if (char === "#" || char === ",") {
|
|
23792
|
+
tokens.push(char);
|
|
23793
|
+
} else if (isReferenceDash(char)) {
|
|
23794
|
+
tokens.push("-");
|
|
23795
|
+
}
|
|
23796
|
+
}
|
|
23797
|
+
flushCurrent();
|
|
23798
|
+
return tokens;
|
|
23799
|
+
}
|
|
23800
|
+
function parseReferenceNumbers(tokens, startIndex) {
|
|
23801
|
+
const numbers = [];
|
|
23802
|
+
let lastNumber;
|
|
23803
|
+
let pendingRangeStart;
|
|
23804
|
+
let index = startIndex;
|
|
23805
|
+
const scanEnd = Math.min(
|
|
23806
|
+
tokens.length,
|
|
23807
|
+
startIndex + DEFAULT_MAX_REFERENCES * REFERENCE_SCAN_TOKEN_FACTOR
|
|
23808
|
+
);
|
|
23809
|
+
for (; index < scanEnd; index += 1) {
|
|
23810
|
+
const token = tokens[index];
|
|
23811
|
+
const normalized = token.toLowerCase();
|
|
23812
|
+
const value = parseNonNegativeIntegerToken(token);
|
|
23813
|
+
if (value !== void 0) {
|
|
23814
|
+
if (pendingRangeStart !== void 0) {
|
|
23815
|
+
numbers.push(...expandReferenceRange(pendingRangeStart, value));
|
|
23816
|
+
pendingRangeStart = void 0;
|
|
23817
|
+
} else {
|
|
23818
|
+
numbers.push(value);
|
|
23819
|
+
}
|
|
23820
|
+
lastNumber = value;
|
|
23821
|
+
continue;
|
|
23822
|
+
}
|
|
23823
|
+
if (normalized === "#" || normalized === "number" || normalized === ",") {
|
|
23824
|
+
continue;
|
|
23825
|
+
}
|
|
23826
|
+
if (normalized === "-" || normalized === "to" || normalized === "through" || normalized === "thru") {
|
|
23827
|
+
if (lastNumber !== void 0) {
|
|
23828
|
+
if (numbers[numbers.length - 1] === lastNumber) {
|
|
23829
|
+
numbers.pop();
|
|
23830
|
+
}
|
|
23831
|
+
pendingRangeStart = lastNumber;
|
|
23832
|
+
}
|
|
23833
|
+
continue;
|
|
23834
|
+
}
|
|
23835
|
+
if (normalized === "and" && numbers.length > 0) {
|
|
23836
|
+
continue;
|
|
23837
|
+
}
|
|
23838
|
+
if (normalizeReferenceLabel(token)) {
|
|
23839
|
+
break;
|
|
23840
|
+
}
|
|
23841
|
+
break;
|
|
23842
|
+
}
|
|
23843
|
+
if (pendingRangeStart !== void 0) {
|
|
23844
|
+
numbers.push(pendingRangeStart);
|
|
23845
|
+
}
|
|
23846
|
+
return {
|
|
23847
|
+
numbers: [...new Set(numbers)],
|
|
23848
|
+
nextIndex: index
|
|
23849
|
+
};
|
|
23850
|
+
}
|
|
23851
|
+
function expandReferenceRange(start, end) {
|
|
23852
|
+
const low = Math.min(start, end);
|
|
23853
|
+
const high = Math.max(start, end);
|
|
23854
|
+
if (high - low + 1 > DEFAULT_MAX_REFERENCES) {
|
|
23855
|
+
return [start, end];
|
|
23856
|
+
}
|
|
23857
|
+
const values = [];
|
|
23858
|
+
for (let value = low; value <= high; value += 1) {
|
|
23859
|
+
values.push(value);
|
|
23860
|
+
}
|
|
23861
|
+
return values;
|
|
23862
|
+
}
|
|
23863
|
+
function normalizeReferenceLabel(token) {
|
|
23864
|
+
const normalized = token?.toLowerCase();
|
|
23865
|
+
switch (normalized) {
|
|
23866
|
+
case "step":
|
|
23867
|
+
case "steps":
|
|
23868
|
+
return "step";
|
|
23869
|
+
case "turn":
|
|
23870
|
+
case "turns":
|
|
23871
|
+
return "turn";
|
|
23872
|
+
case "action":
|
|
23873
|
+
case "actions":
|
|
23874
|
+
return "action";
|
|
23875
|
+
case "observation":
|
|
23876
|
+
case "observations":
|
|
23877
|
+
return "observation";
|
|
23878
|
+
default:
|
|
23879
|
+
return void 0;
|
|
23880
|
+
}
|
|
23881
|
+
}
|
|
23882
|
+
function candidateTurnIndexesForReference(reference) {
|
|
23883
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
23884
|
+
if (reference.includeDirectTurn) {
|
|
23885
|
+
for (let offset = -1; offset <= 1; offset += 1) {
|
|
23886
|
+
candidates.add(reference.number + offset);
|
|
23887
|
+
}
|
|
23888
|
+
}
|
|
23889
|
+
const pairedBase = reference.number * 2;
|
|
23890
|
+
for (let offset = -2; offset <= 3; offset += 1) {
|
|
23891
|
+
candidates.add(pairedBase + offset);
|
|
23892
|
+
}
|
|
23893
|
+
return [...candidates].sort((left, right) => left - right);
|
|
23894
|
+
}
|
|
23895
|
+
function parseNonNegativeIntegerToken(token) {
|
|
23896
|
+
if (token.length === 0) {
|
|
23897
|
+
return void 0;
|
|
23898
|
+
}
|
|
23899
|
+
let value = 0;
|
|
23900
|
+
for (const char of token) {
|
|
23901
|
+
const code = char.charCodeAt(0);
|
|
23902
|
+
if (code < 48 || code > 57) {
|
|
23903
|
+
return void 0;
|
|
23904
|
+
}
|
|
23905
|
+
value = value * 10 + (code - 48);
|
|
23906
|
+
}
|
|
23907
|
+
return value;
|
|
23908
|
+
}
|
|
23909
|
+
function normalizePositiveInteger2(value, fallback) {
|
|
23910
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
23911
|
+
return fallback;
|
|
23912
|
+
}
|
|
23913
|
+
return Math.max(0, Math.floor(value));
|
|
23914
|
+
}
|
|
23915
|
+
function isAsciiLetterOrDigit(char) {
|
|
23916
|
+
const code = char.charCodeAt(0);
|
|
23917
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
23918
|
+
}
|
|
23919
|
+
function isReferenceDash(char) {
|
|
23920
|
+
return char === "-" || char === "\u2010" || char === "\u2011" || char === "\u2012" || char === "\u2013" || char === "\u2014" || char === "\u2015";
|
|
23921
|
+
}
|
|
23922
|
+
|
|
23090
23923
|
// ../remnic-core/src/recall-query-policy.ts
|
|
23091
23924
|
var DEFAULT_STOPWORDS = /* @__PURE__ */ new Set([
|
|
23092
23925
|
"the",
|
|
@@ -34089,7 +34922,7 @@ ${doc.content}` : doc.content,
|
|
|
34089
34922
|
);
|
|
34090
34923
|
return result;
|
|
34091
34924
|
}
|
|
34092
|
-
const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-
|
|
34925
|
+
const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-7PHTDZ4M.js");
|
|
34093
34926
|
const useGateway = this.config.modelSource === "gateway";
|
|
34094
34927
|
const modelSetting = this.config.semanticConsolidationModel;
|
|
34095
34928
|
if (modelSetting === "fast" && this.fastLlm && !useGateway) {
|
|
@@ -36852,7 +37685,7 @@ ${lines.join("\n\n")}`;
|
|
|
36852
37685
|
return null;
|
|
36853
37686
|
}
|
|
36854
37687
|
try {
|
|
36855
|
-
const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-
|
|
37688
|
+
const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-WBEDZUR3.js");
|
|
36856
37689
|
const rules = await getCalibrationRulesForRecall(this.config.memoryDir);
|
|
36857
37690
|
if (rules.length === 0) {
|
|
36858
37691
|
recordRecallSectionMetric({
|
|
@@ -37930,6 +38763,27 @@ ${formatted}`;
|
|
|
37930
38763
|
this.profiler.startSpan("assembly", profileTraceId);
|
|
37931
38764
|
if (sharedCtx)
|
|
37932
38765
|
this.appendRecallSection(sectionBuckets, "shared-context", sharedCtx);
|
|
38766
|
+
const explicitCueMaxChars = this.getRecallSectionMaxChars("explicit-cue") ?? this.config.explicitCueRecallMaxChars;
|
|
38767
|
+
if (this.config.explicitCueRecallEnabled && this.isRecallSectionEnabled("explicit-cue") && explicitCueMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall") {
|
|
38768
|
+
try {
|
|
38769
|
+
const explicitCueSection = await buildExplicitCueRecallSection({
|
|
38770
|
+
engine: this.lcmEngine,
|
|
38771
|
+
sessionId: sessionKey,
|
|
38772
|
+
query: retrievalQuery,
|
|
38773
|
+
maxChars: explicitCueMaxChars,
|
|
38774
|
+
maxReferences: this.getRecallSectionNumber("explicit-cue", "maxResults") ?? this.config.explicitCueRecallMaxReferences
|
|
38775
|
+
});
|
|
38776
|
+
if (explicitCueSection) {
|
|
38777
|
+
this.appendRecallSection(
|
|
38778
|
+
sectionBuckets,
|
|
38779
|
+
"explicit-cue",
|
|
38780
|
+
explicitCueSection
|
|
38781
|
+
);
|
|
38782
|
+
}
|
|
38783
|
+
} catch (err) {
|
|
38784
|
+
log.debug(`Explicit cue recall assembly error: ${err}`);
|
|
38785
|
+
}
|
|
38786
|
+
}
|
|
37933
38787
|
if (profile)
|
|
37934
38788
|
this.appendRecallSection(
|
|
37935
38789
|
sectionBuckets,
|
|
@@ -63117,7 +63971,7 @@ async function runSemanticRulePromoteCliCommand(options) {
|
|
|
63117
63971
|
});
|
|
63118
63972
|
}
|
|
63119
63973
|
async function runCompoundingPromoteCliCommand(options) {
|
|
63120
|
-
const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-
|
|
63974
|
+
const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-KJWHWWLM.js");
|
|
63121
63975
|
const config = parseConfig({
|
|
63122
63976
|
memoryDir: options.memoryDir,
|
|
63123
63977
|
qmdEnabled: false,
|
|
@@ -70914,8 +71768,7 @@ function buildTurnFingerprint(input) {
|
|
|
70914
71768
|
// ../../src/index.ts
|
|
70915
71769
|
import {
|
|
70916
71770
|
resolvePrincipal as resolvePrincipal2,
|
|
70917
|
-
resolveAgentAccessAuthToken as resolveAgentAccessAuthToken2
|
|
70918
|
-
hasEnabledLiveConnector as hasEnabledLiveConnector2
|
|
71771
|
+
resolveAgentAccessAuthToken as resolveAgentAccessAuthToken2
|
|
70919
71772
|
} from "@remnic/core";
|
|
70920
71773
|
|
|
70921
71774
|
// ../remnic-core/src/surfaces/dreams.ts
|
|
@@ -71494,6 +72347,17 @@ function liveConnectorCronExprForConfig(connectors) {
|
|
|
71494
72347
|
return hasEnabledConnector ? ENABLED_LIVE_CONNECTOR_CRON_EXPR : DEFAULT_LIVE_CONNECTOR_CRON_EXPR;
|
|
71495
72348
|
}
|
|
71496
72349
|
|
|
72350
|
+
// ../../src/openclaw-live-connector-config.ts
|
|
72351
|
+
function hasEnabledLiveConnectorConfig(config) {
|
|
72352
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) return false;
|
|
72353
|
+
return Object.values(config).some((connector) => {
|
|
72354
|
+
if (!connector || typeof connector !== "object" || Array.isArray(connector)) {
|
|
72355
|
+
return false;
|
|
72356
|
+
}
|
|
72357
|
+
return connector.enabled === true;
|
|
72358
|
+
});
|
|
72359
|
+
}
|
|
72360
|
+
|
|
71497
72361
|
// ../../src/index.ts
|
|
71498
72362
|
var ENGRAM_MIGRATION_PROMISE = "__openclawEngramMigrationPromise";
|
|
71499
72363
|
var CLI_REGISTERED_GUARD = "__openclawEngramCliRegistered";
|
|
@@ -71605,7 +72469,7 @@ function readPluginHooksPolicy(apiConfig, pluginId) {
|
|
|
71605
72469
|
return loadPluginEntryFromFile(pluginId)?.["hooks"];
|
|
71606
72470
|
}
|
|
71607
72471
|
async function maybeRegisterLiveConnectorCron(orchestrator) {
|
|
71608
|
-
if (!
|
|
72472
|
+
if (!hasEnabledLiveConnectorConfig(orchestrator.config.connectors)) return;
|
|
71609
72473
|
const jobsPath = path99.join(resolveHomeDir(), ".openclaw", "cron", "jobs.json");
|
|
71610
72474
|
try {
|
|
71611
72475
|
if (!existsSync12(jobsPath)) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -2192,6 +2192,23 @@
|
|
|
2192
2192
|
"default": 300,
|
|
2193
2193
|
"description": "Max tokens for each TMT summary node. Default: 300."
|
|
2194
2194
|
},
|
|
2195
|
+
"explicitCueRecallEnabled": {
|
|
2196
|
+
"type": "boolean",
|
|
2197
|
+
"default": false,
|
|
2198
|
+
"description": "Front-load exact LCM evidence for query-visible cues such as turns, dates, ids, files, and tools."
|
|
2199
|
+
},
|
|
2200
|
+
"explicitCueRecallMaxChars": {
|
|
2201
|
+
"type": "number",
|
|
2202
|
+
"default": 2400,
|
|
2203
|
+
"minimum": 0,
|
|
2204
|
+
"description": "Character budget for the explicit cue evidence recall section."
|
|
2205
|
+
},
|
|
2206
|
+
"explicitCueRecallMaxReferences": {
|
|
2207
|
+
"type": "number",
|
|
2208
|
+
"default": 24,
|
|
2209
|
+
"minimum": 0,
|
|
2210
|
+
"description": "Maximum query-visible cues expanded by explicit cue recall."
|
|
2211
|
+
},
|
|
2195
2212
|
"queryExpansionEnabled": {
|
|
2196
2213
|
"type": "boolean",
|
|
2197
2214
|
"default": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/plugin-openclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "OpenClaw adapter for Remnic memory — thin wrapper delegating to @remnic/core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"openai": "^6.0.0",
|
|
28
|
-
"@remnic/core": "^1.1.
|
|
28
|
+
"@remnic/core": "^1.1.7"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"openclaw": ">=2026.4.8"
|