@remnic/plugin-openclaw 1.0.31 → 1.0.33
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 +24 -1
- package/dist/{calibration-V6NBBNCD.js → calibration-JD4AU7FB.js} +7 -4
- package/dist/{causal-consolidation-3GTZFN2T.js → causal-consolidation-DSLFN64P.js} +9 -5
- package/dist/{chunk-UVQXEQBQ.js → chunk-7NMHI4IC.js} +6 -4
- package/dist/{chunk-24MGN4E3.js → chunk-7NUFIRM3.js} +153 -5
- package/dist/{chunk-HI5HX3S7.js → chunk-NDZNURDM.js} +1 -1
- package/dist/{chunk-I6B2W2IY.js → chunk-TDRJVMUP.js} +14 -1
- package/dist/{chunk-37NKFWSO.js → chunk-VRGUUHBV.js} +1 -1
- package/dist/{engine-XPEZBXIQ.js → engine-57HLTQBN.js} +2 -3
- package/dist/{fallback-llm-EGB622FE.js → fallback-llm-33SPYXQY.js} +2 -2
- package/dist/index.js +1033 -356
- package/dist/{path-5LCUBAAZ.js → path-JIEGNWFL.js} +1 -2
- package/dist/{state-store-LP5BO6SF.js → state-store-N6TFBFSP.js} +2 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
- package/dist/chunk-OEI7GLV2.js +0 -17
package/dist/index.js
CHANGED
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
parseOperatorAwareConsolidationResponse,
|
|
91
91
|
renderExtensionsFooter,
|
|
92
92
|
resolveExtensionsRoot
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-NDZNURDM.js";
|
|
94
94
|
import {
|
|
95
95
|
BoxBuilder,
|
|
96
96
|
countRecallTokenOverlap,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
CompoundingEngine,
|
|
116
116
|
SharedContextManager,
|
|
117
117
|
defaultTierMigrationCycleBudget
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-7NMHI4IC.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-7NUFIRM3.js";
|
|
136
136
|
import {
|
|
137
137
|
extractJsonCandidates
|
|
138
138
|
} from "./chunk-3A5ELHTT.js";
|
|
@@ -202,15 +202,13 @@ import {
|
|
|
202
202
|
listConnectorStates,
|
|
203
203
|
readConnectorState,
|
|
204
204
|
writeConnectorState
|
|
205
|
-
} from "./chunk-
|
|
206
|
-
import {
|
|
207
|
-
expandTildePath
|
|
208
|
-
} from "./chunk-OEI7GLV2.js";
|
|
205
|
+
} from "./chunk-VRGUUHBV.js";
|
|
209
206
|
import {
|
|
207
|
+
expandTildePath,
|
|
210
208
|
mergeEnv,
|
|
211
209
|
readEnvVar,
|
|
212
210
|
resolveHomeDir
|
|
213
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-TDRJVMUP.js";
|
|
214
212
|
import {
|
|
215
213
|
__export
|
|
216
214
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -5917,7 +5915,9 @@ var ExtractionEngine = class {
|
|
|
5917
5915
|
log.warn("no OpenAI API key \u2014 direct OpenAI client disabled; local and gateway fallback paths remain available");
|
|
5918
5916
|
}
|
|
5919
5917
|
this.localLlm = localLlm ?? new LocalLlmClient(config, modelRegistry);
|
|
5920
|
-
this.fallbackLlm = new FallbackLlmClient(gatewayConfig
|
|
5918
|
+
this.fallbackLlm = new FallbackLlmClient(gatewayConfig, {
|
|
5919
|
+
workspaceDir: config.workspaceDir
|
|
5920
|
+
});
|
|
5921
5921
|
this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);
|
|
5922
5922
|
if (config.modelSource === "gateway") {
|
|
5923
5923
|
log.debug(
|
|
@@ -14039,7 +14039,9 @@ var HourlySummarizer = class {
|
|
|
14039
14039
|
this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);
|
|
14040
14040
|
this.transcript = transcript;
|
|
14041
14041
|
this.localLlm = new LocalLlmClient(config, this.modelRegistry);
|
|
14042
|
-
this.fallbackLlm = new FallbackLlmClient(gatewayConfig
|
|
14042
|
+
this.fallbackLlm = new FallbackLlmClient(gatewayConfig, {
|
|
14043
|
+
workspaceDir: config.workspaceDir
|
|
14044
|
+
});
|
|
14043
14045
|
if (!gatewayConfig?.agents?.defaults?.model?.primary && !config.localLlmEnabled && config.modelSource !== "gateway") {
|
|
14044
14046
|
log.warn("no gateway default AI and local LLM disabled \u2014 hourly summarization disabled");
|
|
14045
14047
|
}
|
|
@@ -23513,6 +23515,7 @@ async function collectTurnReferenceEvidence(options) {
|
|
|
23513
23515
|
await collectContentLabelReferenceEvidence({
|
|
23514
23516
|
engine: options.engine,
|
|
23515
23517
|
sessionId: options.sessionId,
|
|
23518
|
+
query: options.query,
|
|
23516
23519
|
references,
|
|
23517
23520
|
evidenceItems: options.evidenceItems,
|
|
23518
23521
|
seenTurns: options.seenTurns
|
|
@@ -23565,7 +23568,9 @@ async function collectContentLabelReferenceEvidence(options) {
|
|
|
23565
23568
|
if (appendedWindows >= CONTENT_LABEL_MAX_PAIRED_WINDOWS_PER_REFERENCE) {
|
|
23566
23569
|
break;
|
|
23567
23570
|
}
|
|
23568
|
-
const { fromTurn, toTurn } = contentLabelEvidenceWindow(hit
|
|
23571
|
+
const { fromTurn, toTurn } = contentLabelEvidenceWindow(hit, {
|
|
23572
|
+
includeSuccessor: hasSuccessorTrajectoryIntent(options.query)
|
|
23573
|
+
});
|
|
23569
23574
|
const expanded = await options.engine.expandContext(
|
|
23570
23575
|
hit.session_id,
|
|
23571
23576
|
fromTurn,
|
|
@@ -23644,18 +23649,75 @@ function nearestTurnDistance(turnIndex, candidates) {
|
|
|
23644
23649
|
}
|
|
23645
23650
|
return nearest;
|
|
23646
23651
|
}
|
|
23647
|
-
function contentLabelEvidenceWindow(hit) {
|
|
23652
|
+
function contentLabelEvidenceWindow(hit, options = {}) {
|
|
23653
|
+
const successorTurns = options.includeSuccessor === true ? 2 : 0;
|
|
23648
23654
|
if (hit.labelKind === "action") {
|
|
23649
23655
|
return {
|
|
23650
23656
|
fromTurn: Math.max(0, hit.turn_index - 1),
|
|
23651
|
-
toTurn: hit.turn_index + 1
|
|
23657
|
+
toTurn: hit.turn_index + 1 + successorTurns
|
|
23652
23658
|
};
|
|
23653
23659
|
}
|
|
23654
23660
|
return {
|
|
23655
23661
|
fromTurn: Math.max(0, hit.turn_index - 1),
|
|
23656
|
-
toTurn: hit.turn_index
|
|
23662
|
+
toTurn: hit.turn_index + successorTurns
|
|
23657
23663
|
};
|
|
23658
23664
|
}
|
|
23665
|
+
function hasSuccessorTrajectoryIntent(query) {
|
|
23666
|
+
const raw = query.toLowerCase();
|
|
23667
|
+
const normalized = raw.replace(/[^a-z0-9]+/g, " ").trim();
|
|
23668
|
+
if ([
|
|
23669
|
+
/\bafter\s+(?:step|action|observation|turn)\s+\d+\b/,
|
|
23670
|
+
/\b(?:next|following|subsequent|successor)\s+(?:step|action|observation|turn)\b/,
|
|
23671
|
+
/\b(?:step|action|observation|turn)\s+\d+\s+(?:then|and then)\b/,
|
|
23672
|
+
/\bwhat\s+(?:happened|came|occurred)\s+next\b/
|
|
23673
|
+
].some((pattern) => pattern.test(normalized))) {
|
|
23674
|
+
return true;
|
|
23675
|
+
}
|
|
23676
|
+
if (!hasLoopExitIntent(normalized)) {
|
|
23677
|
+
return false;
|
|
23678
|
+
}
|
|
23679
|
+
if (!hasBoundedTrajectoryReference(raw)) {
|
|
23680
|
+
return true;
|
|
23681
|
+
}
|
|
23682
|
+
return !asksForActionInsideBoundedRange(normalized) && hasNamedTrajectoryActionCue(normalized);
|
|
23683
|
+
}
|
|
23684
|
+
function hasBoundedTrajectoryReference(query) {
|
|
23685
|
+
return hasBoundedTrajectoryRange(query) || hasSingleTrajectoryReference(query);
|
|
23686
|
+
}
|
|
23687
|
+
function hasLoopExitIntent(normalizedQuery) {
|
|
23688
|
+
const exitVerbs = "(?:breaks?|breaking|broke|ends?|ending|ended|stops?|stopping|stopped)";
|
|
23689
|
+
const loopNouns = "(?:loop|cycle|pattern|sequence)";
|
|
23690
|
+
return [
|
|
23691
|
+
new RegExp(
|
|
23692
|
+
`\\b${exitVerbs}\\s+(?:out\\s+of\\s+)?(?:this|that|the|a|an)?\\s*${loopNouns}\\b`
|
|
23693
|
+
),
|
|
23694
|
+
new RegExp(
|
|
23695
|
+
`\\b${loopNouns}\\s+(?:${exitVerbs}|is\\s+${exitVerbs}|was\\s+${exitVerbs})\\b`
|
|
23696
|
+
)
|
|
23697
|
+
].some((pattern) => pattern.test(normalizedQuery));
|
|
23698
|
+
}
|
|
23699
|
+
function hasBoundedTrajectoryRange(query) {
|
|
23700
|
+
return [
|
|
23701
|
+
/\b(?:between|from|in|during|within)\s+(?:steps?|actions?|observations?|turns?)\s+#?\d+\s*(?:-|\u2013|\u2014|\bto\b|\bthrough\b|\bthru\b|\band\b)\s*#?\d+\b/,
|
|
23702
|
+
/\b(?:steps?|actions?|observations?|turns?)\s+#?\d+\s*(?:-|\u2013|\u2014|\bto\b|\bthrough\b|\bthru\b)\s*#?\d+\b/
|
|
23703
|
+
].some((pattern) => pattern.test(query));
|
|
23704
|
+
}
|
|
23705
|
+
function hasSingleTrajectoryReference(query) {
|
|
23706
|
+
return /\b(?:in|during|within|at|on)?\s*(?:steps?|actions?|observations?|turns?)\s+#?\d+\b/.test(
|
|
23707
|
+
query
|
|
23708
|
+
);
|
|
23709
|
+
}
|
|
23710
|
+
function asksForActionInsideBoundedRange(normalizedQuery) {
|
|
23711
|
+
return /\b(?:which|what)\s+(?:single\s+)?(?:action|move|step|maneuver)\s+(?:broke|breaks|breaking|ended|ends|stopped|stops|mattered|accomplished|advanced)\b/.test(
|
|
23712
|
+
normalizedQuery
|
|
23713
|
+
);
|
|
23714
|
+
}
|
|
23715
|
+
function hasNamedTrajectoryActionCue(normalizedQuery) {
|
|
23716
|
+
const actions = "(?:up|down|left|right|wait|stay|push|pull|open|close|use|enter|exit)";
|
|
23717
|
+
return new RegExp(
|
|
23718
|
+
`\\b(?:${actions}\\s+(?:action|move|step|maneuver)|(?:action|move|step|maneuver)\\s+${actions})\\b`
|
|
23719
|
+
).test(normalizedQuery);
|
|
23720
|
+
}
|
|
23659
23721
|
function contentHasReferenceLabel(content, labelKind, referenceNumber) {
|
|
23660
23722
|
const label = labelKind === "action" ? "Action" : "Observation";
|
|
23661
23723
|
const escapedNumber = String(referenceNumber).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -25134,6 +25196,16 @@ function resolveObjectiveStateStoreDir(memoryDir, overrideDir) {
|
|
|
25134
25196
|
}
|
|
25135
25197
|
return path29.join(memoryDir, "state", "objective-state");
|
|
25136
25198
|
}
|
|
25199
|
+
function objectiveStateStoreOverrideForNamespace(options) {
|
|
25200
|
+
const configured = options.configuredStoreDir?.trim();
|
|
25201
|
+
if (!configured) return void 0;
|
|
25202
|
+
if (!options.namespacesEnabled) return configured;
|
|
25203
|
+
const defaultStoreDir = path29.join(options.memoryDir, "state", "objective-state");
|
|
25204
|
+
if (path29.resolve(configured) === path29.resolve(defaultStoreDir)) {
|
|
25205
|
+
return void 0;
|
|
25206
|
+
}
|
|
25207
|
+
return path29.join(configured, "namespaces", options.namespace);
|
|
25208
|
+
}
|
|
25137
25209
|
function validateObjectiveStateSnapshot(raw) {
|
|
25138
25210
|
if (!isRecord(raw)) throw new Error("objective-state snapshot must be an object");
|
|
25139
25211
|
if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
|
|
@@ -27468,8 +27540,12 @@ function parseOpenAiMessageParts(input, _options = {}) {
|
|
|
27468
27540
|
}
|
|
27469
27541
|
if (type === "function_call") {
|
|
27470
27542
|
const toolName = asNonEmptyString(item.name ?? item.tool_name);
|
|
27543
|
+
const callId = asNonEmptyString(item.call_id ?? item.callId);
|
|
27544
|
+
const itemId = asNonEmptyString(item.id);
|
|
27471
27545
|
const payload = {
|
|
27472
|
-
id:
|
|
27546
|
+
id: callId ?? itemId,
|
|
27547
|
+
...callId ? { call_id: callId } : {},
|
|
27548
|
+
...itemId && itemId !== callId ? { response_item_id: itemId } : {},
|
|
27473
27549
|
name: toolName,
|
|
27474
27550
|
arguments: parseMaybeJson(item.arguments)
|
|
27475
27551
|
};
|
|
@@ -27478,7 +27554,14 @@ function parseOpenAiMessageParts(input, _options = {}) {
|
|
|
27478
27554
|
}
|
|
27479
27555
|
if (type === "function_call_output") {
|
|
27480
27556
|
const output = asNonEmptyString(item.output) ?? JSON.stringify(sanitizePayload(item.output ?? item));
|
|
27481
|
-
|
|
27557
|
+
const callId = asNonEmptyString(item.call_id ?? item.callId);
|
|
27558
|
+
const itemId = asNonEmptyString(item.id);
|
|
27559
|
+
parts.push(makePart("tool_result", {
|
|
27560
|
+
id: callId ?? itemId,
|
|
27561
|
+
...callId ? { call_id: callId } : {},
|
|
27562
|
+
...itemId && itemId !== callId ? { response_item_id: itemId } : {},
|
|
27563
|
+
output
|
|
27564
|
+
}, {
|
|
27482
27565
|
filePath: firstFilePath(output)
|
|
27483
27566
|
}));
|
|
27484
27567
|
continue;
|
|
@@ -27517,7 +27600,12 @@ function parseAnthropicMessageParts(input, _options = {}) {
|
|
|
27517
27600
|
if (type === "tool_result") {
|
|
27518
27601
|
const content = block.content;
|
|
27519
27602
|
const rendered = renderUnknownContent(content);
|
|
27520
|
-
parts.push(makePart("tool_result", {
|
|
27603
|
+
parts.push(makePart("tool_result", {
|
|
27604
|
+
id: block.tool_use_id,
|
|
27605
|
+
content: sanitizePayload(content),
|
|
27606
|
+
...typeof block.is_error === "boolean" ? { is_error: block.is_error } : {},
|
|
27607
|
+
...typeof block.isError === "boolean" ? { isError: block.isError } : {}
|
|
27608
|
+
}, {
|
|
27521
27609
|
filePath: firstFilePath(rendered)
|
|
27522
27610
|
}));
|
|
27523
27611
|
continue;
|
|
@@ -27560,7 +27648,7 @@ function parseOpenClawMessageParts(input, options = {}) {
|
|
|
27560
27648
|
})
|
|
27561
27649
|
]);
|
|
27562
27650
|
}
|
|
27563
|
-
const rendered = options.renderedContent ?? asNonEmptyString(obj.content);
|
|
27651
|
+
const rendered = options.allowRenderedFallback === false ? null : options.renderedContent ?? asNonEmptyString(obj.content);
|
|
27564
27652
|
return rendered ? withOrdinals(partsFromRenderedText(rendered)) : [];
|
|
27565
27653
|
}
|
|
27566
27654
|
function partsFromRenderedText(text) {
|
|
@@ -27648,6 +27736,9 @@ function withRenderedFallback(parts, options) {
|
|
|
27648
27736
|
return parts.length > 0 ? parts : renderedFallbackParts(options);
|
|
27649
27737
|
}
|
|
27650
27738
|
function renderedFallbackParts(options) {
|
|
27739
|
+
if (options.allowRenderedFallback === false) {
|
|
27740
|
+
return [];
|
|
27741
|
+
}
|
|
27651
27742
|
const rendered = asNonEmptyString(options.renderedContent);
|
|
27652
27743
|
return rendered ? partsFromRenderedText(rendered) : [];
|
|
27653
27744
|
}
|
|
@@ -34221,7 +34312,9 @@ var Orchestrator = class _Orchestrator {
|
|
|
34221
34312
|
client.disableThinking = true;
|
|
34222
34313
|
return client;
|
|
34223
34314
|
})() : this.localLlm;
|
|
34224
|
-
this._fastGatewayLlm = config.modelSource === "gateway" ? new FallbackLlmClient(config.gatewayConfig
|
|
34315
|
+
this._fastGatewayLlm = config.modelSource === "gateway" ? new FallbackLlmClient(config.gatewayConfig, {
|
|
34316
|
+
workspaceDir: config.workspaceDir
|
|
34317
|
+
}) : null;
|
|
34225
34318
|
if (config.modelSource === "gateway") {
|
|
34226
34319
|
log.debug(
|
|
34227
34320
|
`orchestrator: gateway model source active` + (config.gatewayAgentId ? ` (primary: ${config.gatewayAgentId})` : "") + (config.fastGatewayAgentId ? ` (fast: ${config.fastGatewayAgentId})` : "")
|
|
@@ -34247,17 +34340,19 @@ var Orchestrator = class _Orchestrator {
|
|
|
34247
34340
|
const summarizeFn = async (text, targetTokens, aggressive) => {
|
|
34248
34341
|
const instructionText = aggressive ? `Compress the following into bullet points. One bullet per distinct fact or decision. Maximum ${targetTokens} tokens total. No prose.` : `Compress the following conversation segment into a dense summary. Preserve: decisions made, code artifacts mentioned, errors encountered, open questions, and any commitments or next-steps. Omit: pleasantries, restatements, and anything the agent would not need to recall later. Output a single paragraph, maximum ${targetTokens} tokens.`;
|
|
34249
34342
|
try {
|
|
34250
|
-
const
|
|
34251
|
-
|
|
34252
|
-
|
|
34253
|
-
|
|
34254
|
-
|
|
34255
|
-
|
|
34256
|
-
|
|
34257
|
-
|
|
34258
|
-
|
|
34259
|
-
|
|
34260
|
-
|
|
34343
|
+
const messages = [
|
|
34344
|
+
{ role: "system", content: instructionText },
|
|
34345
|
+
{ role: "user", content: text.slice(0, 12e3) }
|
|
34346
|
+
];
|
|
34347
|
+
const result = this.config.modelSource === "gateway" && this._fastGatewayLlm ? await this._fastGatewayLlm.chatCompletion(messages, {
|
|
34348
|
+
maxTokens: targetTokens * 2,
|
|
34349
|
+
timeoutMs: this.config.localLlmFastTimeoutMs,
|
|
34350
|
+
agentId: this.config.fastGatewayAgentId || this.config.gatewayAgentId || void 0
|
|
34351
|
+
}) : await this.localLlm.chatCompletion(messages, {
|
|
34352
|
+
maxTokens: targetTokens * 2,
|
|
34353
|
+
operation: "lcm-summarize",
|
|
34354
|
+
priority: "background"
|
|
34355
|
+
});
|
|
34261
34356
|
return result?.content ?? null;
|
|
34262
34357
|
} catch {
|
|
34263
34358
|
return null;
|
|
@@ -35195,14 +35290,16 @@ ${doc.content}` : doc.content,
|
|
|
35195
35290
|
);
|
|
35196
35291
|
return result;
|
|
35197
35292
|
}
|
|
35198
|
-
const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-
|
|
35293
|
+
const { FallbackLlmClient: FallbackLlmClient2 } = await import("./fallback-llm-33SPYXQY.js");
|
|
35199
35294
|
const useGateway = this.config.modelSource === "gateway";
|
|
35200
35295
|
const modelSetting = this.config.semanticConsolidationModel;
|
|
35201
35296
|
if (modelSetting === "fast" && this.fastLlm && !useGateway) {
|
|
35202
35297
|
log.info("[semantic-consolidation] using fast local LLM for synthesis");
|
|
35203
35298
|
}
|
|
35204
35299
|
const gatewayAgentId = useGateway ? modelSetting === "fast" && this.config.fastGatewayAgentId ? this.config.fastGatewayAgentId : this.config.gatewayAgentId || void 0 : void 0;
|
|
35205
|
-
const llm = new FallbackLlmClient2(this.config.gatewayConfig
|
|
35300
|
+
const llm = new FallbackLlmClient2(this.config.gatewayConfig, {
|
|
35301
|
+
workspaceDir: this.config.workspaceDir
|
|
35302
|
+
});
|
|
35206
35303
|
if (!llm.isAvailable(gatewayAgentId) && !(modelSetting === "fast" && this.fastLlm && !useGateway)) {
|
|
35207
35304
|
log.warn(
|
|
35208
35305
|
"[semantic-consolidation] no LLM available \u2014 skipping synthesis"
|
|
@@ -35356,7 +35453,9 @@ ${doc.content}` : doc.content,
|
|
|
35356
35453
|
if (this.config.peerProfileReasonerEnabled) {
|
|
35357
35454
|
try {
|
|
35358
35455
|
const { runPeerProfileReasoner } = await import("./peers-KRFXWRQ6.js");
|
|
35359
|
-
const llm2 = new FallbackLlmClient2(this.config.gatewayConfig
|
|
35456
|
+
const llm2 = new FallbackLlmClient2(this.config.gatewayConfig, {
|
|
35457
|
+
workspaceDir: this.config.workspaceDir
|
|
35458
|
+
});
|
|
35360
35459
|
const peerResult = await runPeerProfileReasoner({
|
|
35361
35460
|
memoryDir: targetStorage.dir,
|
|
35362
35461
|
enabled: true,
|
|
@@ -37825,13 +37924,27 @@ ${lines.join("\n\n")}`;
|
|
|
37825
37924
|
});
|
|
37826
37925
|
return null;
|
|
37827
37926
|
}
|
|
37828
|
-
const
|
|
37829
|
-
|
|
37830
|
-
|
|
37831
|
-
|
|
37832
|
-
|
|
37833
|
-
|
|
37834
|
-
|
|
37927
|
+
const objectiveStateSearches = await Promise.all(
|
|
37928
|
+
recallNamespaces.map(async (namespace) => {
|
|
37929
|
+
const storage = this.config.namespacesEnabled ? await this.getStorage(namespace) : null;
|
|
37930
|
+
return searchObjectiveStateSnapshots({
|
|
37931
|
+
memoryDir: this.config.namespacesEnabled ? storage.dir : this.config.memoryDir,
|
|
37932
|
+
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
37933
|
+
memoryDir: this.config.memoryDir,
|
|
37934
|
+
configuredStoreDir: this.config.objectiveStateStoreDir,
|
|
37935
|
+
namespacesEnabled: this.config.namespacesEnabled,
|
|
37936
|
+
namespace
|
|
37937
|
+
}),
|
|
37938
|
+
query: retrievalQuery,
|
|
37939
|
+
maxResults,
|
|
37940
|
+
sessionKey
|
|
37941
|
+
});
|
|
37942
|
+
})
|
|
37943
|
+
);
|
|
37944
|
+
const results = objectiveStateSearches.flat().sort((left, right) => {
|
|
37945
|
+
if (right.score !== left.score) return right.score - left.score;
|
|
37946
|
+
return right.snapshot.recordedAt.localeCompare(left.snapshot.recordedAt);
|
|
37947
|
+
}).slice(0, maxResults);
|
|
37835
37948
|
recordRecallSectionMetric({
|
|
37836
37949
|
section: "objectiveState",
|
|
37837
37950
|
priority: "core",
|
|
@@ -37960,7 +38073,7 @@ ${lines.join("\n\n")}`;
|
|
|
37960
38073
|
return null;
|
|
37961
38074
|
}
|
|
37962
38075
|
try {
|
|
37963
|
-
const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-
|
|
38076
|
+
const { getCalibrationRulesForRecall, buildCalibrationRecallSection } = await import("./calibration-JD4AU7FB.js");
|
|
37964
38077
|
const rules = await getCalibrationRulesForRecall(this.config.memoryDir);
|
|
37965
38078
|
if (rules.length === 0) {
|
|
37966
38079
|
recordRecallSectionMetric({
|
|
@@ -41418,7 +41531,9 @@ ${normalized}`).digest("hex");
|
|
|
41418
41531
|
judgeCandidates,
|
|
41419
41532
|
this.config,
|
|
41420
41533
|
this.localLlm,
|
|
41421
|
-
new FallbackLlmClient(this.config.gatewayConfig
|
|
41534
|
+
new FallbackLlmClient(this.config.gatewayConfig, {
|
|
41535
|
+
workspaceDir: this.config.workspaceDir
|
|
41536
|
+
}),
|
|
41422
41537
|
this.judgeVerdictCache,
|
|
41423
41538
|
this.judgeDeferCounts,
|
|
41424
41539
|
judgeTelemetryHandler
|
|
@@ -55209,6 +55324,639 @@ async function recordMemoryOutcome(storage, input) {
|
|
|
55209
55324
|
});
|
|
55210
55325
|
}
|
|
55211
55326
|
|
|
55327
|
+
// ../remnic-core/src/objective-state-writers.ts
|
|
55328
|
+
import crypto2 from "crypto";
|
|
55329
|
+
var rawProviderParts = /* @__PURE__ */ new WeakSet();
|
|
55330
|
+
function markRawProviderParts(parts) {
|
|
55331
|
+
for (const part of parts) {
|
|
55332
|
+
rawProviderParts.add(part);
|
|
55333
|
+
}
|
|
55334
|
+
return parts;
|
|
55335
|
+
}
|
|
55336
|
+
function isRawProviderPart(part) {
|
|
55337
|
+
return rawProviderParts.has(part);
|
|
55338
|
+
}
|
|
55339
|
+
function hashSha256(value) {
|
|
55340
|
+
return crypto2.createHash("sha256").update(value).digest("hex");
|
|
55341
|
+
}
|
|
55342
|
+
function isRecord4(value) {
|
|
55343
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
55344
|
+
}
|
|
55345
|
+
function optionalString2(value) {
|
|
55346
|
+
if (typeof value !== "string") return void 0;
|
|
55347
|
+
const trimmed = value.trim();
|
|
55348
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
55349
|
+
}
|
|
55350
|
+
function toolNameTokens(toolName) {
|
|
55351
|
+
if (!toolName) return [];
|
|
55352
|
+
return toolName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length > 0);
|
|
55353
|
+
}
|
|
55354
|
+
function normalizedToolName(toolName) {
|
|
55355
|
+
return toolNameTokens(toolName).join("_");
|
|
55356
|
+
}
|
|
55357
|
+
function parseToolArguments(value) {
|
|
55358
|
+
if (isRecord4(value)) return value;
|
|
55359
|
+
if (typeof value !== "string") return void 0;
|
|
55360
|
+
try {
|
|
55361
|
+
const parsed = JSON.parse(value);
|
|
55362
|
+
return isRecord4(parsed) ? parsed : void 0;
|
|
55363
|
+
} catch {
|
|
55364
|
+
return void 0;
|
|
55365
|
+
}
|
|
55366
|
+
}
|
|
55367
|
+
function stableStringify2(value) {
|
|
55368
|
+
if (Array.isArray(value)) {
|
|
55369
|
+
return `[${value.map((entry) => stableStringify2(entry)).join(",")}]`;
|
|
55370
|
+
}
|
|
55371
|
+
if (isRecord4(value)) {
|
|
55372
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify2(value[key])}`).join(",")}}`;
|
|
55373
|
+
}
|
|
55374
|
+
return JSON.stringify(value) ?? String(value);
|
|
55375
|
+
}
|
|
55376
|
+
function extractTextContent(value) {
|
|
55377
|
+
if (typeof value === "string") return value.trim();
|
|
55378
|
+
if (Array.isArray(value)) {
|
|
55379
|
+
return value.map((block) => {
|
|
55380
|
+
if (typeof block === "string") return block.trim();
|
|
55381
|
+
if (isRecord4(block) && block.type === "text" && typeof block.text === "string") {
|
|
55382
|
+
return block.text.trim();
|
|
55383
|
+
}
|
|
55384
|
+
return "";
|
|
55385
|
+
}).filter((item) => item.length > 0).join("\n");
|
|
55386
|
+
}
|
|
55387
|
+
if (isRecord4(value)) {
|
|
55388
|
+
return JSON.stringify(value);
|
|
55389
|
+
}
|
|
55390
|
+
return "";
|
|
55391
|
+
}
|
|
55392
|
+
function parseToolResultPayload(content) {
|
|
55393
|
+
const text = extractTextContent(content);
|
|
55394
|
+
if (text.length === 0) return void 0;
|
|
55395
|
+
try {
|
|
55396
|
+
return JSON.parse(text);
|
|
55397
|
+
} catch {
|
|
55398
|
+
return text;
|
|
55399
|
+
}
|
|
55400
|
+
}
|
|
55401
|
+
function resultHash(value) {
|
|
55402
|
+
if (value === void 0) return void 0;
|
|
55403
|
+
const canonical = typeof value === "string" ? value : stableStringify2(value);
|
|
55404
|
+
if (!canonical || canonical.length === 0) return void 0;
|
|
55405
|
+
return `sha256:${hashSha256(canonical)}`;
|
|
55406
|
+
}
|
|
55407
|
+
function getToolCallContexts(messages) {
|
|
55408
|
+
const contexts = /* @__PURE__ */ new Map();
|
|
55409
|
+
for (const message of messages) {
|
|
55410
|
+
if (message.role !== "assistant") continue;
|
|
55411
|
+
const toolCalls = message.tool_calls ?? message.toolCalls;
|
|
55412
|
+
if (!Array.isArray(toolCalls)) continue;
|
|
55413
|
+
for (const call of toolCalls) {
|
|
55414
|
+
if (!isRecord4(call)) continue;
|
|
55415
|
+
const toolCallId = optionalString2(call.id) ?? optionalString2(call.toolCallId);
|
|
55416
|
+
if (!toolCallId) continue;
|
|
55417
|
+
const fn = isRecord4(call.function) ? call.function : void 0;
|
|
55418
|
+
const toolName = optionalString2(fn?.name) ?? optionalString2(call.name);
|
|
55419
|
+
const args = parseToolArguments(fn?.arguments) ?? parseToolArguments(call.arguments) ?? parseToolArguments(call.args) ?? parseToolArguments(call.input);
|
|
55420
|
+
contexts.set(toolCallId, { toolCallId, toolName, args });
|
|
55421
|
+
}
|
|
55422
|
+
}
|
|
55423
|
+
return contexts;
|
|
55424
|
+
}
|
|
55425
|
+
function toolCallIdForMessage(message) {
|
|
55426
|
+
return optionalString2(message.tool_call_id) ?? optionalString2(message.toolCallId) ?? optionalString2(message.tool_use_id) ?? optionalString2(message.toolUseId);
|
|
55427
|
+
}
|
|
55428
|
+
function toolNameForMessage(message, context) {
|
|
55429
|
+
return optionalString2(message.name) ?? optionalString2(message.toolName) ?? optionalString2(message.tool) ?? context?.toolName;
|
|
55430
|
+
}
|
|
55431
|
+
function pickString(args, keys) {
|
|
55432
|
+
if (!args) return void 0;
|
|
55433
|
+
for (const key of keys) {
|
|
55434
|
+
const value = optionalString2(args[key]);
|
|
55435
|
+
if (value) return value;
|
|
55436
|
+
}
|
|
55437
|
+
return void 0;
|
|
55438
|
+
}
|
|
55439
|
+
function pickFirstStringArrayValue(args, key) {
|
|
55440
|
+
const value = args?.[key];
|
|
55441
|
+
if (!Array.isArray(value)) return void 0;
|
|
55442
|
+
for (const item of value) {
|
|
55443
|
+
const candidate = optionalString2(item);
|
|
55444
|
+
if (candidate) return candidate;
|
|
55445
|
+
}
|
|
55446
|
+
return void 0;
|
|
55447
|
+
}
|
|
55448
|
+
function fileScopeFromArgs(args) {
|
|
55449
|
+
const destinationPath = pickString(args, ["destination", "dest", "targetPath", "target", "to"]) ?? pickString(args, ["path", "filePath", "workspacePath", "projectPath"]) ?? pickFirstStringArrayValue(args, "paths");
|
|
55450
|
+
const sourcePath = pickString(args, ["source", "src", "from", "oldPath"]);
|
|
55451
|
+
const scope = destinationPath ?? sourcePath;
|
|
55452
|
+
return { scope, sourcePath, destinationPath };
|
|
55453
|
+
}
|
|
55454
|
+
function fileContentHash(args) {
|
|
55455
|
+
const content = pickString(args, ["content", "patch", "diff", "text", "value"]) ?? args?.updates;
|
|
55456
|
+
return resultHash(content);
|
|
55457
|
+
}
|
|
55458
|
+
function inferOutcome(message, parsedPayload) {
|
|
55459
|
+
if (message.isError === true) return "failure";
|
|
55460
|
+
if (isRecord4(parsedPayload)) {
|
|
55461
|
+
if (parsedPayload.partial === true || parsedPayload.status === "partial") return "partial";
|
|
55462
|
+
if (parsedPayload.success === false || parsedPayload.ok === false) return "failure";
|
|
55463
|
+
if (parsedPayload.success === true || parsedPayload.ok === true) return "success";
|
|
55464
|
+
if (typeof parsedPayload.exitCode === "number") {
|
|
55465
|
+
return parsedPayload.exitCode === 0 ? "success" : "failure";
|
|
55466
|
+
}
|
|
55467
|
+
if (optionalString2(parsedPayload.error)) return "failure";
|
|
55468
|
+
if (parsedPayload.status === "error" || parsedPayload.status === "failed") return "failure";
|
|
55469
|
+
if (parsedPayload.status === "ok" || parsedPayload.status === "success") return "success";
|
|
55470
|
+
const outputText = [
|
|
55471
|
+
optionalString2(parsedPayload.stdout),
|
|
55472
|
+
optionalString2(parsedPayload.stderr)
|
|
55473
|
+
].filter((entry) => entry !== void 0).join("\n");
|
|
55474
|
+
if (outputText) {
|
|
55475
|
+
const outputOutcome = inferOutcome({}, outputText);
|
|
55476
|
+
if (outputOutcome !== "unknown") return outputOutcome;
|
|
55477
|
+
}
|
|
55478
|
+
}
|
|
55479
|
+
if (typeof parsedPayload === "string") {
|
|
55480
|
+
const lowered = parsedPayload.toLowerCase();
|
|
55481
|
+
const loweredForFailure = lowered.replace(/\b(?:previously\s+)?failed tests?\s+now\s+pass(?:ed|es)?\b/g, "");
|
|
55482
|
+
const hasZeroCountMarker = /\b(?:0|no)\s+(?:errors?|failures?|exceptions?|timeouts?)\b/.test(lowered);
|
|
55483
|
+
const loweredForFailureCounts = loweredForFailure.replace(/\b(?:0|no)\s+errors?\b/g, "").replace(/\b(?:0|no)\s+failures?\b/g, "").replace(/\b(?:0|no)\s+exceptions?\b/g, "").replace(/\b(?:0|no)\s+timeouts?\b/g, "");
|
|
55484
|
+
const hasNonZeroErrorCounts = /\b[1-9]\d*\s+errors?\b/.test(loweredForFailureCounts);
|
|
55485
|
+
const hasNegatedSuccessMarkers = /\b(?:not|did not|didn't|doesn't|isn't|aren't|wasn't|weren't|won't|can't|couldn't|shouldn't|wouldn't)\s+(?:ok|pass|passed|passes|succeeded|success)\b/.test(loweredForFailure);
|
|
55486
|
+
const hasSuccessMarkers = /\b(success|succeeded|pass|passes|passed|ok)\b/.test(lowered) || hasZeroCountMarker;
|
|
55487
|
+
const hasFailureMarkers = hasNegatedSuccessMarkers || /\b(exceptions?|failed|failures?|fatal|timeouts?|timed out)\b/.test(loweredForFailureCounts) || hasNonZeroErrorCounts || /\berrors?\b/.test(loweredForFailureCounts) || /\b[a-z]+error\b/.test(loweredForFailureCounts) || /\b[a-z]+exception\b/.test(loweredForFailureCounts);
|
|
55488
|
+
if (hasFailureMarkers) return "failure";
|
|
55489
|
+
if (hasSuccessMarkers) return "success";
|
|
55490
|
+
}
|
|
55491
|
+
return "unknown";
|
|
55492
|
+
}
|
|
55493
|
+
function isProcessTool(toolName, args) {
|
|
55494
|
+
const tokens = toolNameTokens(toolName);
|
|
55495
|
+
const normalizedName = normalizedToolName(toolName);
|
|
55496
|
+
if (pickString(args, ["cmd", "command", "script"])) return true;
|
|
55497
|
+
return ["exec", "shell", "bash", "terminal", "run_command", "exec_command"].some(
|
|
55498
|
+
(token) => token.includes("_") ? normalizedName === token : tokens.includes(token)
|
|
55499
|
+
);
|
|
55500
|
+
}
|
|
55501
|
+
function isFileTool(toolName, args) {
|
|
55502
|
+
const tokens = toolNameTokens(toolName);
|
|
55503
|
+
const fileScope = fileScopeFromArgs(args);
|
|
55504
|
+
if (fileScope.scope) return true;
|
|
55505
|
+
return ["file", "path", "patch", "directory", "mkdir", "rename", "move"].some(
|
|
55506
|
+
(token) => tokens.includes(token)
|
|
55507
|
+
);
|
|
55508
|
+
}
|
|
55509
|
+
function inferFileChangeKind(toolName, outcome) {
|
|
55510
|
+
if (outcome === "failure") return "failed";
|
|
55511
|
+
const tokens = toolNameTokens(toolName);
|
|
55512
|
+
if (["delete", "remove", "unlink"].some((token) => tokens.includes(token))) return "deleted";
|
|
55513
|
+
if (["create", "mkdir", "new"].some((token) => tokens.includes(token))) return "created";
|
|
55514
|
+
if (["write", "edit", "patch", "update", "append", "move", "rename"].some((token) => tokens.includes(token))) {
|
|
55515
|
+
return "updated";
|
|
55516
|
+
}
|
|
55517
|
+
return "observed";
|
|
55518
|
+
}
|
|
55519
|
+
function buildFileValueRefs(args, changeKind) {
|
|
55520
|
+
const { sourcePath, destinationPath, scope } = fileScopeFromArgs(args);
|
|
55521
|
+
const contentHash = fileContentHash(args);
|
|
55522
|
+
if (changeKind === "failed") {
|
|
55523
|
+
if (sourcePath && destinationPath && sourcePath !== destinationPath) {
|
|
55524
|
+
return {
|
|
55525
|
+
before: { ref: sourcePath },
|
|
55526
|
+
after: { ref: destinationPath }
|
|
55527
|
+
};
|
|
55528
|
+
}
|
|
55529
|
+
return {
|
|
55530
|
+
before: sourcePath ? { ref: sourcePath } : void 0,
|
|
55531
|
+
after: scope ? { ref: scope } : void 0
|
|
55532
|
+
};
|
|
55533
|
+
}
|
|
55534
|
+
if (changeKind === "deleted") {
|
|
55535
|
+
return {
|
|
55536
|
+
before: scope ? { exists: true, ref: scope } : void 0,
|
|
55537
|
+
after: { exists: false }
|
|
55538
|
+
};
|
|
55539
|
+
}
|
|
55540
|
+
if (changeKind === "created") {
|
|
55541
|
+
return {
|
|
55542
|
+
after: {
|
|
55543
|
+
exists: true,
|
|
55544
|
+
ref: scope,
|
|
55545
|
+
valueHash: contentHash
|
|
55546
|
+
}
|
|
55547
|
+
};
|
|
55548
|
+
}
|
|
55549
|
+
if (sourcePath && destinationPath && sourcePath !== destinationPath) {
|
|
55550
|
+
return {
|
|
55551
|
+
before: { exists: true, ref: sourcePath },
|
|
55552
|
+
after: {
|
|
55553
|
+
exists: true,
|
|
55554
|
+
ref: destinationPath
|
|
55555
|
+
}
|
|
55556
|
+
};
|
|
55557
|
+
}
|
|
55558
|
+
return {
|
|
55559
|
+
after: {
|
|
55560
|
+
exists: true,
|
|
55561
|
+
ref: scope,
|
|
55562
|
+
valueHash: contentHash
|
|
55563
|
+
}
|
|
55564
|
+
};
|
|
55565
|
+
}
|
|
55566
|
+
function summarizeSnapshot(kind, changeKind, toolName, scope) {
|
|
55567
|
+
const action = changeKind === "executed" ? "Executed" : changeKind === "failed" ? "Failed" : changeKind === "created" ? "Created" : changeKind === "deleted" ? "Deleted" : changeKind === "updated" ? "Updated" : "Observed";
|
|
55568
|
+
if (kind === "process") return `${action} process via ${toolName}: ${scope}`;
|
|
55569
|
+
if (kind === "file") return `${action} file via ${toolName}: ${scope}`;
|
|
55570
|
+
return `${action} tool result from ${toolName}: ${scope}`;
|
|
55571
|
+
}
|
|
55572
|
+
function buildGenericToolAfterRef(outcome, parsedPayload) {
|
|
55573
|
+
const valueHash = resultHash(parsedPayload);
|
|
55574
|
+
return valueHash ? { valueHash } : { exists: outcome !== "failure" };
|
|
55575
|
+
}
|
|
55576
|
+
function snapshotIdFor(sessionKey, recordedAt, index, toolName, scope, stableKey2) {
|
|
55577
|
+
const digest = crypto2.createHash("sha256").update(
|
|
55578
|
+
stableKey2 ? `${sessionKey}|${recordedAt}|${index}|${toolName}|${scope}|stable|${stableKey2}` : `${sessionKey}|${recordedAt}|${index}|${toolName}|${scope}`
|
|
55579
|
+
).digest("hex").slice(0, 12);
|
|
55580
|
+
return `obj-${digest}`;
|
|
55581
|
+
}
|
|
55582
|
+
function objectiveStatePartsForObservedMessage(message) {
|
|
55583
|
+
if (message.role === "user") {
|
|
55584
|
+
const explicitParts2 = Array.isArray(message.parts) && message.parts.length > 0 ? sanitizeUserRoleToolResultParts(message.parts) : [];
|
|
55585
|
+
if (Array.isArray(message.parts) && message.parts.length > 0) {
|
|
55586
|
+
const rawParts2 = userRawToolResultParts(message);
|
|
55587
|
+
return mergeObservedEvidenceParts(explicitParts2, rawParts2);
|
|
55588
|
+
}
|
|
55589
|
+
return userRawToolResultParts(message);
|
|
55590
|
+
}
|
|
55591
|
+
if (message.role !== "assistant") {
|
|
55592
|
+
return [];
|
|
55593
|
+
}
|
|
55594
|
+
const explicitParts = Array.isArray(message.parts) && message.parts.length > 0 ? message.parts : [];
|
|
55595
|
+
const rawParts = assistantRawObjectiveStateParts(message);
|
|
55596
|
+
return mergeObservedEvidenceParts(explicitParts, rawParts);
|
|
55597
|
+
}
|
|
55598
|
+
function userRawToolResultParts(message) {
|
|
55599
|
+
const rawContent = message.rawContent ?? message.content;
|
|
55600
|
+
if (!containsProviderToolResultBlock(rawContent)) {
|
|
55601
|
+
return [];
|
|
55602
|
+
}
|
|
55603
|
+
return markRawProviderParts(
|
|
55604
|
+
sanitizeUserRoleToolResultParts(parseMessageParts(rawContent, {
|
|
55605
|
+
sourceFormat: message.sourceFormat,
|
|
55606
|
+
allowRenderedFallback: false
|
|
55607
|
+
}))
|
|
55608
|
+
);
|
|
55609
|
+
}
|
|
55610
|
+
function assistantRawObjectiveStateParts(message) {
|
|
55611
|
+
if (message.rawContent === void 0 || message.rawContent === null) {
|
|
55612
|
+
return [];
|
|
55613
|
+
}
|
|
55614
|
+
return markRawProviderParts(parseMessageParts(message.rawContent, {
|
|
55615
|
+
sourceFormat: message.sourceFormat,
|
|
55616
|
+
allowRenderedFallback: false
|
|
55617
|
+
}));
|
|
55618
|
+
}
|
|
55619
|
+
function mergeObservedEvidenceParts(explicitParts, rawParts) {
|
|
55620
|
+
if (explicitParts.length === 0) return rawParts;
|
|
55621
|
+
if (rawParts.length === 0) return explicitParts;
|
|
55622
|
+
const merged = [...explicitParts];
|
|
55623
|
+
const seen = new Set(
|
|
55624
|
+
explicitParts.filter(isObjectiveStateEvidencePart).map(objectiveStateEvidencePartKey)
|
|
55625
|
+
);
|
|
55626
|
+
for (const part of rawParts) {
|
|
55627
|
+
if (!isObjectiveStateEvidencePart(part)) continue;
|
|
55628
|
+
const key = objectiveStateEvidencePartKey(part);
|
|
55629
|
+
if (seen.has(key)) continue;
|
|
55630
|
+
seen.add(key);
|
|
55631
|
+
merged.push(part);
|
|
55632
|
+
}
|
|
55633
|
+
return merged;
|
|
55634
|
+
}
|
|
55635
|
+
function isObjectiveStateEvidencePart(part) {
|
|
55636
|
+
return part.kind === "tool_call" || part.kind === "tool_result" || part.kind === "file_write" || part.kind === "patch";
|
|
55637
|
+
}
|
|
55638
|
+
function objectiveStateEvidencePartKey(part) {
|
|
55639
|
+
const id = partToolCallId(part);
|
|
55640
|
+
if (id) return `${part.kind}:id:${id}`;
|
|
55641
|
+
const toolName = partToolName(part) ?? "";
|
|
55642
|
+
const filePath = partFilePath(part) ?? "";
|
|
55643
|
+
return `${part.kind}:shape:${toolName}:${filePath}:${stableStringify2(partPayload(part))}`;
|
|
55644
|
+
}
|
|
55645
|
+
function flattenObservedParts(messages) {
|
|
55646
|
+
const entries = [];
|
|
55647
|
+
messages.forEach((message, messageIndex) => {
|
|
55648
|
+
const parts = objectiveStatePartsForObservedMessage(message);
|
|
55649
|
+
parts.forEach((part, partIndex) => {
|
|
55650
|
+
entries.push({ messageIndex, partIndex, part });
|
|
55651
|
+
});
|
|
55652
|
+
});
|
|
55653
|
+
return entries.sort((a, b) => {
|
|
55654
|
+
if (a.messageIndex !== b.messageIndex) return a.messageIndex - b.messageIndex;
|
|
55655
|
+
const aOrdinal = typeof a.part.ordinal === "number" ? a.part.ordinal : a.partIndex;
|
|
55656
|
+
const bOrdinal = typeof b.part.ordinal === "number" ? b.part.ordinal : b.partIndex;
|
|
55657
|
+
if (aOrdinal !== bOrdinal) return aOrdinal - bOrdinal;
|
|
55658
|
+
return a.partIndex - b.partIndex;
|
|
55659
|
+
});
|
|
55660
|
+
}
|
|
55661
|
+
function sanitizeUserRoleToolResultParts(parts) {
|
|
55662
|
+
return parts.filter((part) => part.kind === "tool_result").map((part) => {
|
|
55663
|
+
const payload = { ...partPayload(part) };
|
|
55664
|
+
delete payload.name;
|
|
55665
|
+
delete payload.tool;
|
|
55666
|
+
delete payload.toolName;
|
|
55667
|
+
delete payload.tool_name;
|
|
55668
|
+
return {
|
|
55669
|
+
...part,
|
|
55670
|
+
toolName: null,
|
|
55671
|
+
tool_name: null,
|
|
55672
|
+
payload
|
|
55673
|
+
};
|
|
55674
|
+
});
|
|
55675
|
+
}
|
|
55676
|
+
function containsProviderToolResultBlock(value) {
|
|
55677
|
+
if (Array.isArray(value)) {
|
|
55678
|
+
return value.some(containsProviderToolResultBlock);
|
|
55679
|
+
}
|
|
55680
|
+
if (!isRecord4(value)) return false;
|
|
55681
|
+
const type = optionalString2(value.type ?? value.kind);
|
|
55682
|
+
if (type === "tool_result" || type === "function_call_output") {
|
|
55683
|
+
return true;
|
|
55684
|
+
}
|
|
55685
|
+
return containsProviderToolResultBlock(value.content) || containsProviderToolResultBlock(value.output) || containsProviderToolResultBlock(value.items);
|
|
55686
|
+
}
|
|
55687
|
+
function partPayload(part) {
|
|
55688
|
+
return isRecord4(part.payload) ? part.payload : {};
|
|
55689
|
+
}
|
|
55690
|
+
function partToolCallId(part) {
|
|
55691
|
+
const payload = partPayload(part);
|
|
55692
|
+
return optionalString2(payload.call_id) ?? optionalString2(payload.callId) ?? optionalString2(payload.id) ?? optionalString2(payload.tool_call_id) ?? optionalString2(payload.toolCallId) ?? optionalString2(payload.tool_use_id) ?? optionalString2(payload.toolUseId);
|
|
55693
|
+
}
|
|
55694
|
+
function partToolName(part) {
|
|
55695
|
+
const payload = partPayload(part);
|
|
55696
|
+
return optionalString2(part.toolName) ?? optionalString2(part.tool_name) ?? optionalString2(payload.name) ?? optionalString2(payload.toolName) ?? optionalString2(payload.tool_name) ?? (part.kind === "patch" ? "apply_patch" : void 0) ?? (part.kind === "file_write" ? "file_write" : void 0);
|
|
55697
|
+
}
|
|
55698
|
+
function partFilePath(part) {
|
|
55699
|
+
const payload = partPayload(part);
|
|
55700
|
+
return optionalString2(part.filePath) ?? optionalString2(part.file_path) ?? optionalString2(payload.path) ?? optionalString2(payload.filePath) ?? optionalString2(payload.file_path);
|
|
55701
|
+
}
|
|
55702
|
+
function syntheticPartId(options) {
|
|
55703
|
+
const digest = hashSha256(
|
|
55704
|
+
[
|
|
55705
|
+
options.sessionKey,
|
|
55706
|
+
String(options.messageIndex),
|
|
55707
|
+
String(options.part.ordinal ?? options.partIndex),
|
|
55708
|
+
options.part.kind,
|
|
55709
|
+
optionalString2(options.part.toolName) ?? "",
|
|
55710
|
+
optionalString2(options.part.tool_name) ?? "",
|
|
55711
|
+
optionalString2(options.part.filePath) ?? "",
|
|
55712
|
+
optionalString2(options.part.file_path) ?? "",
|
|
55713
|
+
stableStringify2(options.part.payload)
|
|
55714
|
+
].join("|")
|
|
55715
|
+
).slice(0, 12);
|
|
55716
|
+
return `part-${digest}`;
|
|
55717
|
+
}
|
|
55718
|
+
function toolArgumentsFromPart(part) {
|
|
55719
|
+
const payload = partPayload(part);
|
|
55720
|
+
const parsedArgs = parseToolArguments(payload.arguments) ?? parseToolArguments(payload.input) ?? parseToolArguments(payload.args) ?? parseToolArguments(payload.params) ?? payload;
|
|
55721
|
+
const args = { ...parsedArgs };
|
|
55722
|
+
const filePath = partFilePath(part);
|
|
55723
|
+
if (filePath && !pickString(args, ["path", "filePath", "file_path"])) {
|
|
55724
|
+
args.path = filePath;
|
|
55725
|
+
}
|
|
55726
|
+
if (part.kind === "patch" && !pickString(args, ["patch", "diff", "text"])) {
|
|
55727
|
+
const text = optionalString2(payload.text) ?? optionalString2(payload.patch);
|
|
55728
|
+
if (text) args.patch = text;
|
|
55729
|
+
}
|
|
55730
|
+
return args;
|
|
55731
|
+
}
|
|
55732
|
+
function toolResultContentFromPart(part) {
|
|
55733
|
+
const payload = partPayload(part);
|
|
55734
|
+
if ("output" in payload) return payload.output;
|
|
55735
|
+
if ("content" in payload) return payload.content;
|
|
55736
|
+
if ("result" in payload) return payload.result;
|
|
55737
|
+
if ("value" in payload) return payload.value;
|
|
55738
|
+
return payload;
|
|
55739
|
+
}
|
|
55740
|
+
function inlineToolResultContentFromPart(part) {
|
|
55741
|
+
const payload = partPayload(part);
|
|
55742
|
+
if (hasDefinedPayloadKey(payload, "output")) return payload.output;
|
|
55743
|
+
if (hasDefinedPayloadKey(payload, "result")) return payload.result;
|
|
55744
|
+
if (part.kind === "tool_result" && hasDefinedPayloadKey(payload, "value")) {
|
|
55745
|
+
return payload.value;
|
|
55746
|
+
}
|
|
55747
|
+
const statusPayload = {};
|
|
55748
|
+
for (const key of ["exitCode", "ok", "success", "error", "stdout", "stderr"]) {
|
|
55749
|
+
if (hasDefinedPayloadKey(payload, key)) {
|
|
55750
|
+
statusPayload[key] = payload[key];
|
|
55751
|
+
}
|
|
55752
|
+
}
|
|
55753
|
+
return Object.keys(statusPayload).length > 0 ? statusPayload : payload;
|
|
55754
|
+
}
|
|
55755
|
+
function hasDefinedPayloadKey(payload, key) {
|
|
55756
|
+
return Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== void 0;
|
|
55757
|
+
}
|
|
55758
|
+
function partHasInlineToolResult(part) {
|
|
55759
|
+
const payload = partPayload(part);
|
|
55760
|
+
return hasDefinedPayloadKey(payload, "output") || hasDefinedPayloadKey(payload, "result") || part.kind === "tool_result" && hasDefinedPayloadKey(payload, "value") || hasDefinedPayloadKey(payload, "exitCode") || hasDefinedPayloadKey(payload, "ok") || hasDefinedPayloadKey(payload, "success") || hasDefinedPayloadKey(payload, "error") || hasDefinedPayloadKey(payload, "stdout") || hasDefinedPayloadKey(payload, "stderr");
|
|
55761
|
+
}
|
|
55762
|
+
function toolResultIsError(part) {
|
|
55763
|
+
const payload = partPayload(part);
|
|
55764
|
+
return payload.isError === true || payload.is_error === true || payload.ok === false || payload.success === false || optionalString2(payload.error) !== void 0;
|
|
55765
|
+
}
|
|
55766
|
+
function buildSyntheticAssistantToolCall(id, toolName, args) {
|
|
55767
|
+
return {
|
|
55768
|
+
role: "assistant",
|
|
55769
|
+
tool_calls: [
|
|
55770
|
+
{
|
|
55771
|
+
id,
|
|
55772
|
+
function: {
|
|
55773
|
+
name: toolName,
|
|
55774
|
+
arguments: JSON.stringify(args)
|
|
55775
|
+
}
|
|
55776
|
+
}
|
|
55777
|
+
]
|
|
55778
|
+
};
|
|
55779
|
+
}
|
|
55780
|
+
function observedPartsToAgentMessages(options) {
|
|
55781
|
+
const entries = flattenObservedParts(options.messages);
|
|
55782
|
+
const resultIds = new Set(
|
|
55783
|
+
entries.filter((entry) => entry.part.kind === "tool_result").map((entry) => partToolCallId(entry.part)).filter((id) => id !== void 0)
|
|
55784
|
+
);
|
|
55785
|
+
const synthetic = [];
|
|
55786
|
+
let pendingIdlessToolCallId;
|
|
55787
|
+
for (let entryIndex = 0; entryIndex < entries.length; entryIndex += 1) {
|
|
55788
|
+
const entry = entries[entryIndex];
|
|
55789
|
+
const { part } = entry;
|
|
55790
|
+
if (part.kind === "tool_call" || part.kind === "file_write" || part.kind === "patch") {
|
|
55791
|
+
const toolName = partToolName(part);
|
|
55792
|
+
if (!toolName) continue;
|
|
55793
|
+
const observedToolCallId = partToolCallId(part);
|
|
55794
|
+
const id = observedToolCallId ?? syntheticPartId({
|
|
55795
|
+
sessionKey: options.sessionKey,
|
|
55796
|
+
messageIndex: entry.messageIndex,
|
|
55797
|
+
partIndex: entry.partIndex,
|
|
55798
|
+
part
|
|
55799
|
+
});
|
|
55800
|
+
const args = toolArgumentsFromPart(part);
|
|
55801
|
+
synthetic.push(buildSyntheticAssistantToolCall(id, toolName, args));
|
|
55802
|
+
const nextEntry = entries[entryIndex + 1];
|
|
55803
|
+
const nextIsIdlessToolResult = nextEntry?.part.kind === "tool_result" && partToolCallId(nextEntry.part) === void 0;
|
|
55804
|
+
pendingIdlessToolCallId = nextIsIdlessToolResult ? id : void 0;
|
|
55805
|
+
const hasSeparateToolResult = resultIds.has(id) || nextIsIdlessToolResult;
|
|
55806
|
+
if (partHasInlineToolResult(part) && !hasSeparateToolResult) {
|
|
55807
|
+
synthetic.push({
|
|
55808
|
+
role: "tool",
|
|
55809
|
+
tool_call_id: id,
|
|
55810
|
+
name: toolName,
|
|
55811
|
+
content: inlineToolResultContentFromPart(part),
|
|
55812
|
+
...toolResultIsError(part) ? { isError: true } : {}
|
|
55813
|
+
});
|
|
55814
|
+
pendingIdlessToolCallId = void 0;
|
|
55815
|
+
continue;
|
|
55816
|
+
}
|
|
55817
|
+
if ((part.kind === "file_write" || part.kind === "patch") && !nextIsIdlessToolResult && !resultIds.has(id) && !isRawProviderPart(part)) {
|
|
55818
|
+
synthetic.push({
|
|
55819
|
+
role: "tool",
|
|
55820
|
+
tool_call_id: id,
|
|
55821
|
+
name: toolName,
|
|
55822
|
+
content: { ok: true, source: "message_part" }
|
|
55823
|
+
});
|
|
55824
|
+
pendingIdlessToolCallId = void 0;
|
|
55825
|
+
}
|
|
55826
|
+
continue;
|
|
55827
|
+
}
|
|
55828
|
+
if (part.kind === "tool_result") {
|
|
55829
|
+
const id = partToolCallId(part) ?? pendingIdlessToolCallId;
|
|
55830
|
+
const toolName = partToolName(part);
|
|
55831
|
+
synthetic.push({
|
|
55832
|
+
role: "tool",
|
|
55833
|
+
...id ? { tool_call_id: id } : {},
|
|
55834
|
+
...toolName ? { name: toolName } : {},
|
|
55835
|
+
content: toolResultContentFromPart(part),
|
|
55836
|
+
...toolResultIsError(part) ? { isError: true } : {}
|
|
55837
|
+
});
|
|
55838
|
+
pendingIdlessToolCallId = void 0;
|
|
55839
|
+
}
|
|
55840
|
+
}
|
|
55841
|
+
return synthetic;
|
|
55842
|
+
}
|
|
55843
|
+
function deriveObjectiveStateSnapshotsFromAgentMessages(options) {
|
|
55844
|
+
const toolCallsById = getToolCallContexts(options.messages);
|
|
55845
|
+
const snapshots = [];
|
|
55846
|
+
for (const message of options.messages) {
|
|
55847
|
+
if (message.role !== "tool") continue;
|
|
55848
|
+
const toolCallId = toolCallIdForMessage(message);
|
|
55849
|
+
const context = toolCallId ? toolCallsById.get(toolCallId) : void 0;
|
|
55850
|
+
const toolName = toolNameForMessage(message, context);
|
|
55851
|
+
if (!toolName) continue;
|
|
55852
|
+
const parsedPayload = parseToolResultPayload(message.content);
|
|
55853
|
+
const outcome = inferOutcome(message, parsedPayload);
|
|
55854
|
+
const args = context?.args;
|
|
55855
|
+
const command = pickString(args, ["cmd", "command", "script"]);
|
|
55856
|
+
let kind = "tool";
|
|
55857
|
+
let changeKind = outcome === "failure" ? "failed" : "observed";
|
|
55858
|
+
let scope = toolName;
|
|
55859
|
+
let before;
|
|
55860
|
+
let after;
|
|
55861
|
+
if (isProcessTool(toolName, args)) {
|
|
55862
|
+
kind = "process";
|
|
55863
|
+
changeKind = outcome === "failure" ? "failed" : "executed";
|
|
55864
|
+
scope = command ?? toolName;
|
|
55865
|
+
after = { exists: outcome !== "failure", valueHash: resultHash(parsedPayload) };
|
|
55866
|
+
} else if (isFileTool(toolName, args)) {
|
|
55867
|
+
kind = "file";
|
|
55868
|
+
changeKind = inferFileChangeKind(toolName, outcome);
|
|
55869
|
+
const fileScope = fileScopeFromArgs(args);
|
|
55870
|
+
scope = fileScope.scope ?? toolName;
|
|
55871
|
+
const refs = buildFileValueRefs(args, changeKind);
|
|
55872
|
+
before = refs.before;
|
|
55873
|
+
after = refs.after;
|
|
55874
|
+
} else {
|
|
55875
|
+
after = buildGenericToolAfterRef(outcome, parsedPayload);
|
|
55876
|
+
}
|
|
55877
|
+
snapshots.push({
|
|
55878
|
+
schemaVersion: 1,
|
|
55879
|
+
snapshotId: snapshotIdFor(
|
|
55880
|
+
options.sessionKey,
|
|
55881
|
+
options.recordedAt,
|
|
55882
|
+
snapshots.length,
|
|
55883
|
+
toolName,
|
|
55884
|
+
scope,
|
|
55885
|
+
toolCallId
|
|
55886
|
+
),
|
|
55887
|
+
recordedAt: options.recordedAt,
|
|
55888
|
+
sessionKey: options.sessionKey,
|
|
55889
|
+
source: "tool_result",
|
|
55890
|
+
kind,
|
|
55891
|
+
changeKind,
|
|
55892
|
+
scope,
|
|
55893
|
+
summary: summarizeSnapshot(kind, changeKind, toolName, scope),
|
|
55894
|
+
toolName,
|
|
55895
|
+
command,
|
|
55896
|
+
outcome,
|
|
55897
|
+
before,
|
|
55898
|
+
after,
|
|
55899
|
+
tags: ["agent-end", `tool:${toolName}`],
|
|
55900
|
+
metadata: toolCallId ? { toolCallId } : void 0
|
|
55901
|
+
});
|
|
55902
|
+
}
|
|
55903
|
+
return snapshots;
|
|
55904
|
+
}
|
|
55905
|
+
function deriveObjectiveStateSnapshotsFromObservedMessages(options) {
|
|
55906
|
+
const syntheticMessages = observedPartsToAgentMessages({
|
|
55907
|
+
sessionKey: options.sessionKey,
|
|
55908
|
+
messages: options.messages
|
|
55909
|
+
});
|
|
55910
|
+
if (syntheticMessages.length === 0) return [];
|
|
55911
|
+
return deriveObjectiveStateSnapshotsFromAgentMessages({
|
|
55912
|
+
sessionKey: options.sessionKey,
|
|
55913
|
+
recordedAt: options.recordedAt,
|
|
55914
|
+
messages: syntheticMessages
|
|
55915
|
+
});
|
|
55916
|
+
}
|
|
55917
|
+
async function recordObjectiveStateSnapshotsFromAgentMessages(options) {
|
|
55918
|
+
if (!options.objectiveStateMemoryEnabled || !options.objectiveStateSnapshotWritesEnabled) {
|
|
55919
|
+
return { snapshots: [], filePaths: [] };
|
|
55920
|
+
}
|
|
55921
|
+
const snapshots = deriveObjectiveStateSnapshotsFromAgentMessages({
|
|
55922
|
+
sessionKey: options.sessionKey,
|
|
55923
|
+
recordedAt: options.recordedAt,
|
|
55924
|
+
messages: options.messages
|
|
55925
|
+
});
|
|
55926
|
+
const filePaths = [];
|
|
55927
|
+
for (const snapshot of snapshots) {
|
|
55928
|
+
filePaths.push(
|
|
55929
|
+
await recordObjectiveStateSnapshot({
|
|
55930
|
+
memoryDir: options.memoryDir,
|
|
55931
|
+
objectiveStateStoreDir: options.objectiveStateStoreDir,
|
|
55932
|
+
snapshot
|
|
55933
|
+
})
|
|
55934
|
+
);
|
|
55935
|
+
}
|
|
55936
|
+
return { snapshots, filePaths };
|
|
55937
|
+
}
|
|
55938
|
+
async function recordObjectiveStateSnapshotsFromObservedMessages(options) {
|
|
55939
|
+
if (!options.objectiveStateMemoryEnabled || !options.objectiveStateSnapshotWritesEnabled) {
|
|
55940
|
+
return { snapshots: [], filePaths: [] };
|
|
55941
|
+
}
|
|
55942
|
+
const snapshots = deriveObjectiveStateSnapshotsFromObservedMessages({
|
|
55943
|
+
sessionKey: options.sessionKey,
|
|
55944
|
+
recordedAt: options.recordedAt,
|
|
55945
|
+
messages: options.messages
|
|
55946
|
+
});
|
|
55947
|
+
const filePaths = [];
|
|
55948
|
+
for (const snapshot of snapshots) {
|
|
55949
|
+
filePaths.push(
|
|
55950
|
+
await recordObjectiveStateSnapshot({
|
|
55951
|
+
memoryDir: options.memoryDir,
|
|
55952
|
+
objectiveStateStoreDir: options.objectiveStateStoreDir,
|
|
55953
|
+
snapshot
|
|
55954
|
+
})
|
|
55955
|
+
);
|
|
55956
|
+
}
|
|
55957
|
+
return { snapshots, filePaths };
|
|
55958
|
+
}
|
|
55959
|
+
|
|
55212
55960
|
// ../remnic-core/src/access-service.ts
|
|
55213
55961
|
var EngramAccessInputError = class extends Error {
|
|
55214
55962
|
};
|
|
@@ -55431,6 +56179,24 @@ var EngramAccessService = class {
|
|
|
55431
56179
|
}
|
|
55432
56180
|
return resolved;
|
|
55433
56181
|
}
|
|
56182
|
+
async objectiveStateStoreLocationForNamespace(namespace) {
|
|
56183
|
+
if (!this.orchestrator.config.namespacesEnabled) {
|
|
56184
|
+
return {
|
|
56185
|
+
memoryDir: this.orchestrator.config.memoryDir,
|
|
56186
|
+
objectiveStateStoreDir: this.orchestrator.config.objectiveStateStoreDir
|
|
56187
|
+
};
|
|
56188
|
+
}
|
|
56189
|
+
const storage = await this.orchestrator.getStorage(namespace);
|
|
56190
|
+
return {
|
|
56191
|
+
memoryDir: storage.dir,
|
|
56192
|
+
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
56193
|
+
memoryDir: this.orchestrator.config.memoryDir,
|
|
56194
|
+
configuredStoreDir: this.orchestrator.config.objectiveStateStoreDir,
|
|
56195
|
+
namespacesEnabled: this.orchestrator.config.namespacesEnabled,
|
|
56196
|
+
namespace
|
|
56197
|
+
})
|
|
56198
|
+
};
|
|
56199
|
+
}
|
|
55434
56200
|
resolveReadableNamespace(namespace, principal) {
|
|
55435
56201
|
const resolved = this.resolveNamespace(namespace);
|
|
55436
56202
|
const namespacesEnabled = this.orchestrator.config.namespacesEnabled;
|
|
@@ -57160,16 +57926,54 @@ var EngramAccessService = class {
|
|
|
57160
57926
|
throw new EngramAccessInputError(`invalid message role: ${msg.role} (expected 'user' or 'assistant')`);
|
|
57161
57927
|
}
|
|
57162
57928
|
}
|
|
57929
|
+
const hasExplicitNamespace = typeof request.namespace === "string" && request.namespace.trim().length > 0;
|
|
57930
|
+
const principal = this.resolveWritePrincipal(
|
|
57931
|
+
request.sessionKey,
|
|
57932
|
+
request.authenticatedPrincipal
|
|
57933
|
+
);
|
|
57163
57934
|
const namespace = this.resolveWritableNamespace(
|
|
57164
57935
|
request.namespace,
|
|
57165
57936
|
request.sessionKey,
|
|
57166
57937
|
request.authenticatedPrincipal
|
|
57167
57938
|
);
|
|
57939
|
+
const shouldWriteObjectiveState = this.orchestrator.config.objectiveStateMemoryEnabled === true && this.orchestrator.config.objectiveStateSnapshotWritesEnabled === true;
|
|
57940
|
+
const objectiveStateBaseNamespace = hasExplicitNamespace ? namespace : defaultNamespaceForPrincipal(principal, this.orchestrator.config);
|
|
57941
|
+
if (shouldWriteObjectiveState && !hasExplicitNamespace && !canWriteNamespace(
|
|
57942
|
+
principal,
|
|
57943
|
+
objectiveStateBaseNamespace,
|
|
57944
|
+
this.orchestrator.config
|
|
57945
|
+
)) {
|
|
57946
|
+
throw new EngramAccessInputError(
|
|
57947
|
+
`namespace is not writable: ${objectiveStateBaseNamespace}`
|
|
57948
|
+
);
|
|
57949
|
+
}
|
|
57168
57950
|
await this.maybeAttachCodingContext(request.sessionKey, {
|
|
57169
57951
|
cwd: request.cwd,
|
|
57170
57952
|
projectTag: request.projectTag
|
|
57171
57953
|
});
|
|
57954
|
+
const objectiveStateNamespace = hasExplicitNamespace ? namespace : this.orchestrator.applyCodingNamespaceOverlay(
|
|
57955
|
+
request.sessionKey,
|
|
57956
|
+
objectiveStateBaseNamespace
|
|
57957
|
+
);
|
|
57172
57958
|
const lcmSessionKey = namespace !== this.orchestrator.config.defaultNamespace ? `${namespace}:${request.sessionKey}` : request.sessionKey;
|
|
57959
|
+
if (shouldWriteObjectiveState) {
|
|
57960
|
+
try {
|
|
57961
|
+
const objectiveStateLocation = await this.objectiveStateStoreLocationForNamespace(
|
|
57962
|
+
objectiveStateNamespace
|
|
57963
|
+
);
|
|
57964
|
+
await recordObjectiveStateSnapshotsFromObservedMessages({
|
|
57965
|
+
memoryDir: objectiveStateLocation.memoryDir,
|
|
57966
|
+
objectiveStateStoreDir: objectiveStateLocation.objectiveStateStoreDir,
|
|
57967
|
+
objectiveStateMemoryEnabled: this.orchestrator.config.objectiveStateMemoryEnabled,
|
|
57968
|
+
objectiveStateSnapshotWritesEnabled: this.orchestrator.config.objectiveStateSnapshotWritesEnabled,
|
|
57969
|
+
sessionKey: request.sessionKey,
|
|
57970
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57971
|
+
messages: request.messages
|
|
57972
|
+
});
|
|
57973
|
+
} catch (err) {
|
|
57974
|
+
log.error(`access-observe objective-state snapshot write failed: ${err}`);
|
|
57975
|
+
}
|
|
57976
|
+
}
|
|
57173
57977
|
let lcmArchived = false;
|
|
57174
57978
|
if (this.orchestrator.lcmEngine && this.orchestrator.lcmEngine.enabled) {
|
|
57175
57979
|
try {
|
|
@@ -64305,7 +65109,7 @@ async function runSemanticRulePromoteCliCommand(options) {
|
|
|
64305
65109
|
});
|
|
64306
65110
|
}
|
|
64307
65111
|
async function runCompoundingPromoteCliCommand(options) {
|
|
64308
|
-
const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-
|
|
65112
|
+
const { CompoundingEngine: CompoundingEngine2 } = await import("./engine-57HLTQBN.js");
|
|
64309
65113
|
const config = parseConfig({
|
|
64310
65114
|
memoryDir: options.memoryDir,
|
|
64311
65115
|
qmdEnabled: false,
|
|
@@ -67153,7 +67957,7 @@ function registerCli(api, orchestrator, registerOptions = {}) {
|
|
|
67153
67957
|
return;
|
|
67154
67958
|
}
|
|
67155
67959
|
const cfg = orchestrator.config.connectors;
|
|
67156
|
-
const { readConnectorState: readConnectorState2, writeConnectorState: writeConnectorState2 } = await import("./state-store-
|
|
67960
|
+
const { readConnectorState: readConnectorState2, writeConnectorState: writeConnectorState2 } = await import("./state-store-N6TFBFSP.js");
|
|
67157
67961
|
const sharedIngestFn = async (docs) => {
|
|
67158
67962
|
const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67159
67963
|
const turns = docs.map((doc) => ({
|
|
@@ -69690,7 +70494,7 @@ Legacy identity-anchor files are untouched. Verify the migration result`);
|
|
|
69690
70494
|
}
|
|
69691
70495
|
if (typeof options.trace === "string" && options.trace.length > 0) {
|
|
69692
70496
|
const { replayTrace, parseSpeedFlag } = await import("./trace-NJESSGH7.js");
|
|
69693
|
-
const { expandTildePath: expandTildePath2 } = await import("./path-
|
|
70497
|
+
const { expandTildePath: expandTildePath2 } = await import("./path-JIEGNWFL.js");
|
|
69694
70498
|
const tracePath = expandTildePath2(options.trace);
|
|
69695
70499
|
let speed;
|
|
69696
70500
|
try {
|
|
@@ -69721,7 +70525,7 @@ Legacy identity-anchor files are untouched. Verify the migration result`);
|
|
|
69721
70525
|
let recorder = null;
|
|
69722
70526
|
if (typeof options.recordTrace === "string" && options.recordTrace.length > 0) {
|
|
69723
70527
|
const { openTraceRecorder } = await import("./trace-NJESSGH7.js");
|
|
69724
|
-
const { expandTildePath: expandTildePath2 } = await import("./path-
|
|
70528
|
+
const { expandTildePath: expandTildePath2 } = await import("./path-JIEGNWFL.js");
|
|
69725
70529
|
recorder = await openTraceRecorder(
|
|
69726
70530
|
expandTildePath2(options.recordTrace)
|
|
69727
70531
|
);
|
|
@@ -69773,309 +70577,6 @@ function parseDuration(duration) {
|
|
|
69773
70577
|
return total || 12;
|
|
69774
70578
|
}
|
|
69775
70579
|
|
|
69776
|
-
// ../remnic-core/src/objective-state-writers.ts
|
|
69777
|
-
import crypto2 from "crypto";
|
|
69778
|
-
function hashSha256(value) {
|
|
69779
|
-
return crypto2.createHash("sha256").update(value).digest("hex");
|
|
69780
|
-
}
|
|
69781
|
-
function isRecord4(value) {
|
|
69782
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
69783
|
-
}
|
|
69784
|
-
function optionalString2(value) {
|
|
69785
|
-
if (typeof value !== "string") return void 0;
|
|
69786
|
-
const trimmed = value.trim();
|
|
69787
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
69788
|
-
}
|
|
69789
|
-
function toolNameTokens(toolName) {
|
|
69790
|
-
if (!toolName) return [];
|
|
69791
|
-
return toolName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length > 0);
|
|
69792
|
-
}
|
|
69793
|
-
function normalizedToolName(toolName) {
|
|
69794
|
-
return toolNameTokens(toolName).join("_");
|
|
69795
|
-
}
|
|
69796
|
-
function parseToolArguments(value) {
|
|
69797
|
-
if (isRecord4(value)) return value;
|
|
69798
|
-
if (typeof value !== "string") return void 0;
|
|
69799
|
-
try {
|
|
69800
|
-
const parsed = JSON.parse(value);
|
|
69801
|
-
return isRecord4(parsed) ? parsed : void 0;
|
|
69802
|
-
} catch {
|
|
69803
|
-
return void 0;
|
|
69804
|
-
}
|
|
69805
|
-
}
|
|
69806
|
-
function extractTextContent(value) {
|
|
69807
|
-
if (typeof value === "string") return value.trim();
|
|
69808
|
-
if (Array.isArray(value)) {
|
|
69809
|
-
return value.map((block) => {
|
|
69810
|
-
if (typeof block === "string") return block.trim();
|
|
69811
|
-
if (isRecord4(block) && block.type === "text" && typeof block.text === "string") {
|
|
69812
|
-
return block.text.trim();
|
|
69813
|
-
}
|
|
69814
|
-
return "";
|
|
69815
|
-
}).filter((item) => item.length > 0).join("\n");
|
|
69816
|
-
}
|
|
69817
|
-
if (isRecord4(value)) {
|
|
69818
|
-
return JSON.stringify(value);
|
|
69819
|
-
}
|
|
69820
|
-
return "";
|
|
69821
|
-
}
|
|
69822
|
-
function parseToolResultPayload(content) {
|
|
69823
|
-
const text = extractTextContent(content);
|
|
69824
|
-
if (text.length === 0) return void 0;
|
|
69825
|
-
try {
|
|
69826
|
-
return JSON.parse(text);
|
|
69827
|
-
} catch {
|
|
69828
|
-
return text;
|
|
69829
|
-
}
|
|
69830
|
-
}
|
|
69831
|
-
function resultHash(value) {
|
|
69832
|
-
if (value === void 0) return void 0;
|
|
69833
|
-
const canonical = typeof value === "string" ? value : JSON.stringify(value);
|
|
69834
|
-
if (!canonical || canonical.length === 0) return void 0;
|
|
69835
|
-
return `sha256:${hashSha256(canonical)}`;
|
|
69836
|
-
}
|
|
69837
|
-
function getToolCallContexts(messages) {
|
|
69838
|
-
const contexts = /* @__PURE__ */ new Map();
|
|
69839
|
-
for (const message of messages) {
|
|
69840
|
-
if (message.role !== "assistant") continue;
|
|
69841
|
-
const toolCalls = message.tool_calls ?? message.toolCalls;
|
|
69842
|
-
if (!Array.isArray(toolCalls)) continue;
|
|
69843
|
-
for (const call of toolCalls) {
|
|
69844
|
-
if (!isRecord4(call)) continue;
|
|
69845
|
-
const toolCallId = optionalString2(call.id) ?? optionalString2(call.toolCallId);
|
|
69846
|
-
if (!toolCallId) continue;
|
|
69847
|
-
const fn = isRecord4(call.function) ? call.function : void 0;
|
|
69848
|
-
const toolName = optionalString2(fn?.name) ?? optionalString2(call.name);
|
|
69849
|
-
const args = parseToolArguments(fn?.arguments) ?? parseToolArguments(call.arguments) ?? parseToolArguments(call.args) ?? parseToolArguments(call.input);
|
|
69850
|
-
contexts.set(toolCallId, { toolCallId, toolName, args });
|
|
69851
|
-
}
|
|
69852
|
-
}
|
|
69853
|
-
return contexts;
|
|
69854
|
-
}
|
|
69855
|
-
function toolCallIdForMessage(message) {
|
|
69856
|
-
return optionalString2(message.tool_call_id) ?? optionalString2(message.toolCallId) ?? optionalString2(message.tool_use_id) ?? optionalString2(message.toolUseId);
|
|
69857
|
-
}
|
|
69858
|
-
function toolNameForMessage(message, context) {
|
|
69859
|
-
return optionalString2(message.name) ?? optionalString2(message.toolName) ?? optionalString2(message.tool) ?? context?.toolName;
|
|
69860
|
-
}
|
|
69861
|
-
function pickString(args, keys) {
|
|
69862
|
-
if (!args) return void 0;
|
|
69863
|
-
for (const key of keys) {
|
|
69864
|
-
const value = optionalString2(args[key]);
|
|
69865
|
-
if (value) return value;
|
|
69866
|
-
}
|
|
69867
|
-
return void 0;
|
|
69868
|
-
}
|
|
69869
|
-
function pickFirstStringArrayValue(args, key) {
|
|
69870
|
-
const value = args?.[key];
|
|
69871
|
-
if (!Array.isArray(value)) return void 0;
|
|
69872
|
-
for (const item of value) {
|
|
69873
|
-
const candidate = optionalString2(item);
|
|
69874
|
-
if (candidate) return candidate;
|
|
69875
|
-
}
|
|
69876
|
-
return void 0;
|
|
69877
|
-
}
|
|
69878
|
-
function fileScopeFromArgs(args) {
|
|
69879
|
-
const destinationPath = pickString(args, ["destination", "dest", "targetPath", "target", "to"]) ?? pickString(args, ["path", "filePath", "workspacePath", "projectPath"]) ?? pickFirstStringArrayValue(args, "paths");
|
|
69880
|
-
const sourcePath = pickString(args, ["source", "src", "from", "oldPath"]);
|
|
69881
|
-
const scope = destinationPath ?? sourcePath;
|
|
69882
|
-
return { scope, sourcePath, destinationPath };
|
|
69883
|
-
}
|
|
69884
|
-
function fileContentHash(args) {
|
|
69885
|
-
const content = pickString(args, ["content", "patch", "diff", "text", "value"]) ?? args?.updates;
|
|
69886
|
-
return resultHash(content);
|
|
69887
|
-
}
|
|
69888
|
-
function inferOutcome(message, parsedPayload) {
|
|
69889
|
-
if (message.isError === true) return "failure";
|
|
69890
|
-
if (isRecord4(parsedPayload)) {
|
|
69891
|
-
if (parsedPayload.partial === true || parsedPayload.status === "partial") return "partial";
|
|
69892
|
-
if (parsedPayload.success === false || parsedPayload.ok === false) return "failure";
|
|
69893
|
-
if (parsedPayload.success === true || parsedPayload.ok === true) return "success";
|
|
69894
|
-
if (typeof parsedPayload.exitCode === "number") {
|
|
69895
|
-
return parsedPayload.exitCode === 0 ? "success" : "failure";
|
|
69896
|
-
}
|
|
69897
|
-
if (optionalString2(parsedPayload.error)) return "failure";
|
|
69898
|
-
if (parsedPayload.status === "error" || parsedPayload.status === "failed") return "failure";
|
|
69899
|
-
if (parsedPayload.status === "ok" || parsedPayload.status === "success") return "success";
|
|
69900
|
-
}
|
|
69901
|
-
if (typeof parsedPayload === "string") {
|
|
69902
|
-
const lowered = parsedPayload.toLowerCase();
|
|
69903
|
-
const loweredForFailure = lowered.replace(/\b(?:previously\s+)?failed tests?\s+now\s+pass(?:ed|es)?\b/g, "");
|
|
69904
|
-
const hasZeroCountMarker = /\b(?:0|no)\s+(?:errors?|failures?|exceptions?|timeouts?)\b/.test(lowered);
|
|
69905
|
-
const loweredForFailureCounts = loweredForFailure.replace(/\b(?:0|no)\s+errors?\b/g, "").replace(/\b(?:0|no)\s+failures?\b/g, "").replace(/\b(?:0|no)\s+exceptions?\b/g, "").replace(/\b(?:0|no)\s+timeouts?\b/g, "");
|
|
69906
|
-
const hasNonZeroErrorCounts = /\b[1-9]\d*\s+errors?\b/.test(loweredForFailureCounts);
|
|
69907
|
-
const hasNegatedSuccessMarkers = /\b(?:not|did not|didn't|doesn't|isn't|aren't|wasn't|weren't|won't|can't|couldn't|shouldn't|wouldn't)\s+(?:ok|pass|passed|passes|succeeded|success)\b/.test(loweredForFailure);
|
|
69908
|
-
const hasSuccessMarkers = /\b(success|succeeded|pass|passes|passed|ok)\b/.test(lowered) || hasZeroCountMarker;
|
|
69909
|
-
const hasFailureMarkers = hasNegatedSuccessMarkers || /\b(exceptions?|failed|failures?|fatal|timeouts?|timed out)\b/.test(loweredForFailureCounts) || hasNonZeroErrorCounts || /\berrors?\b/.test(loweredForFailureCounts) || /\b[a-z]+error\b/.test(loweredForFailureCounts) || /\b[a-z]+exception\b/.test(loweredForFailureCounts);
|
|
69910
|
-
if (hasFailureMarkers) return "failure";
|
|
69911
|
-
if (hasSuccessMarkers) return "success";
|
|
69912
|
-
}
|
|
69913
|
-
return "unknown";
|
|
69914
|
-
}
|
|
69915
|
-
function isProcessTool(toolName, args) {
|
|
69916
|
-
const tokens = toolNameTokens(toolName);
|
|
69917
|
-
const normalizedName = normalizedToolName(toolName);
|
|
69918
|
-
if (pickString(args, ["cmd", "command", "script"])) return true;
|
|
69919
|
-
return ["exec", "shell", "bash", "terminal", "run_command", "exec_command"].some(
|
|
69920
|
-
(token) => token.includes("_") ? normalizedName === token : tokens.includes(token)
|
|
69921
|
-
);
|
|
69922
|
-
}
|
|
69923
|
-
function isFileTool(toolName, args) {
|
|
69924
|
-
const tokens = toolNameTokens(toolName);
|
|
69925
|
-
const fileScope = fileScopeFromArgs(args);
|
|
69926
|
-
if (fileScope.scope) return true;
|
|
69927
|
-
return ["file", "path", "patch", "directory", "mkdir", "rename", "move"].some(
|
|
69928
|
-
(token) => tokens.includes(token)
|
|
69929
|
-
);
|
|
69930
|
-
}
|
|
69931
|
-
function inferFileChangeKind(toolName, outcome) {
|
|
69932
|
-
if (outcome === "failure") return "failed";
|
|
69933
|
-
const tokens = toolNameTokens(toolName);
|
|
69934
|
-
if (["delete", "remove", "unlink"].some((token) => tokens.includes(token))) return "deleted";
|
|
69935
|
-
if (["create", "mkdir", "new"].some((token) => tokens.includes(token))) return "created";
|
|
69936
|
-
if (["write", "edit", "patch", "update", "append", "move", "rename"].some((token) => tokens.includes(token))) {
|
|
69937
|
-
return "updated";
|
|
69938
|
-
}
|
|
69939
|
-
return "observed";
|
|
69940
|
-
}
|
|
69941
|
-
function buildFileValueRefs(args, changeKind) {
|
|
69942
|
-
const { sourcePath, destinationPath, scope } = fileScopeFromArgs(args);
|
|
69943
|
-
const contentHash = fileContentHash(args);
|
|
69944
|
-
if (changeKind === "failed") {
|
|
69945
|
-
if (sourcePath && destinationPath && sourcePath !== destinationPath) {
|
|
69946
|
-
return {
|
|
69947
|
-
before: { ref: sourcePath },
|
|
69948
|
-
after: { ref: destinationPath }
|
|
69949
|
-
};
|
|
69950
|
-
}
|
|
69951
|
-
return {
|
|
69952
|
-
before: sourcePath ? { ref: sourcePath } : void 0,
|
|
69953
|
-
after: scope ? { ref: scope } : void 0
|
|
69954
|
-
};
|
|
69955
|
-
}
|
|
69956
|
-
if (changeKind === "deleted") {
|
|
69957
|
-
return {
|
|
69958
|
-
before: scope ? { exists: true, ref: scope } : void 0,
|
|
69959
|
-
after: { exists: false }
|
|
69960
|
-
};
|
|
69961
|
-
}
|
|
69962
|
-
if (changeKind === "created") {
|
|
69963
|
-
return {
|
|
69964
|
-
after: {
|
|
69965
|
-
exists: true,
|
|
69966
|
-
ref: scope,
|
|
69967
|
-
valueHash: contentHash
|
|
69968
|
-
}
|
|
69969
|
-
};
|
|
69970
|
-
}
|
|
69971
|
-
if (sourcePath && destinationPath && sourcePath !== destinationPath) {
|
|
69972
|
-
return {
|
|
69973
|
-
before: { exists: true, ref: sourcePath },
|
|
69974
|
-
after: {
|
|
69975
|
-
exists: true,
|
|
69976
|
-
ref: destinationPath
|
|
69977
|
-
}
|
|
69978
|
-
};
|
|
69979
|
-
}
|
|
69980
|
-
return {
|
|
69981
|
-
after: {
|
|
69982
|
-
exists: true,
|
|
69983
|
-
ref: scope,
|
|
69984
|
-
valueHash: contentHash
|
|
69985
|
-
}
|
|
69986
|
-
};
|
|
69987
|
-
}
|
|
69988
|
-
function summarizeSnapshot(kind, changeKind, toolName, scope) {
|
|
69989
|
-
const action = changeKind === "executed" ? "Executed" : changeKind === "failed" ? "Failed" : changeKind === "created" ? "Created" : changeKind === "deleted" ? "Deleted" : changeKind === "updated" ? "Updated" : "Observed";
|
|
69990
|
-
if (kind === "process") return `${action} process via ${toolName}: ${scope}`;
|
|
69991
|
-
if (kind === "file") return `${action} file via ${toolName}: ${scope}`;
|
|
69992
|
-
return `${action} tool result from ${toolName}: ${scope}`;
|
|
69993
|
-
}
|
|
69994
|
-
function buildGenericToolAfterRef(outcome, parsedPayload) {
|
|
69995
|
-
const valueHash = resultHash(parsedPayload);
|
|
69996
|
-
return valueHash ? { valueHash } : { exists: outcome !== "failure" };
|
|
69997
|
-
}
|
|
69998
|
-
function snapshotIdFor(sessionKey, recordedAt, index, toolName, scope) {
|
|
69999
|
-
const digest = crypto2.createHash("sha256").update(`${sessionKey}|${recordedAt}|${index}|${toolName}|${scope}`).digest("hex").slice(0, 12);
|
|
70000
|
-
return `obj-${digest}`;
|
|
70001
|
-
}
|
|
70002
|
-
function deriveObjectiveStateSnapshotsFromAgentMessages(options) {
|
|
70003
|
-
const toolCallsById = getToolCallContexts(options.messages);
|
|
70004
|
-
const snapshots = [];
|
|
70005
|
-
for (const message of options.messages) {
|
|
70006
|
-
if (message.role !== "tool") continue;
|
|
70007
|
-
const toolCallId = toolCallIdForMessage(message);
|
|
70008
|
-
const context = toolCallId ? toolCallsById.get(toolCallId) : void 0;
|
|
70009
|
-
const toolName = toolNameForMessage(message, context);
|
|
70010
|
-
if (!toolName) continue;
|
|
70011
|
-
const parsedPayload = parseToolResultPayload(message.content);
|
|
70012
|
-
const outcome = inferOutcome(message, parsedPayload);
|
|
70013
|
-
const args = context?.args;
|
|
70014
|
-
const command = pickString(args, ["cmd", "command", "script"]);
|
|
70015
|
-
let kind = "tool";
|
|
70016
|
-
let changeKind = outcome === "failure" ? "failed" : "observed";
|
|
70017
|
-
let scope = toolName;
|
|
70018
|
-
let before;
|
|
70019
|
-
let after;
|
|
70020
|
-
if (isProcessTool(toolName, args)) {
|
|
70021
|
-
kind = "process";
|
|
70022
|
-
changeKind = outcome === "failure" ? "failed" : "executed";
|
|
70023
|
-
scope = command ?? toolName;
|
|
70024
|
-
after = { exists: outcome !== "failure", valueHash: resultHash(parsedPayload) };
|
|
70025
|
-
} else if (isFileTool(toolName, args)) {
|
|
70026
|
-
kind = "file";
|
|
70027
|
-
changeKind = inferFileChangeKind(toolName, outcome);
|
|
70028
|
-
const fileScope = fileScopeFromArgs(args);
|
|
70029
|
-
scope = fileScope.scope ?? toolName;
|
|
70030
|
-
const refs = buildFileValueRefs(args, changeKind);
|
|
70031
|
-
before = refs.before;
|
|
70032
|
-
after = refs.after;
|
|
70033
|
-
} else {
|
|
70034
|
-
after = buildGenericToolAfterRef(outcome, parsedPayload);
|
|
70035
|
-
}
|
|
70036
|
-
snapshots.push({
|
|
70037
|
-
schemaVersion: 1,
|
|
70038
|
-
snapshotId: snapshotIdFor(options.sessionKey, options.recordedAt, snapshots.length, toolName, scope),
|
|
70039
|
-
recordedAt: options.recordedAt,
|
|
70040
|
-
sessionKey: options.sessionKey,
|
|
70041
|
-
source: "tool_result",
|
|
70042
|
-
kind,
|
|
70043
|
-
changeKind,
|
|
70044
|
-
scope,
|
|
70045
|
-
summary: summarizeSnapshot(kind, changeKind, toolName, scope),
|
|
70046
|
-
toolName,
|
|
70047
|
-
command,
|
|
70048
|
-
outcome,
|
|
70049
|
-
before,
|
|
70050
|
-
after,
|
|
70051
|
-
tags: ["agent-end", `tool:${toolName}`],
|
|
70052
|
-
metadata: toolCallId ? { toolCallId } : void 0
|
|
70053
|
-
});
|
|
70054
|
-
}
|
|
70055
|
-
return snapshots;
|
|
70056
|
-
}
|
|
70057
|
-
async function recordObjectiveStateSnapshotsFromAgentMessages(options) {
|
|
70058
|
-
if (!options.objectiveStateMemoryEnabled || !options.objectiveStateSnapshotWritesEnabled) {
|
|
70059
|
-
return { snapshots: [], filePaths: [] };
|
|
70060
|
-
}
|
|
70061
|
-
const snapshots = deriveObjectiveStateSnapshotsFromAgentMessages({
|
|
70062
|
-
sessionKey: options.sessionKey,
|
|
70063
|
-
recordedAt: options.recordedAt,
|
|
70064
|
-
messages: options.messages
|
|
70065
|
-
});
|
|
70066
|
-
const filePaths = [];
|
|
70067
|
-
for (const snapshot of snapshots) {
|
|
70068
|
-
filePaths.push(
|
|
70069
|
-
await recordObjectiveStateSnapshot({
|
|
70070
|
-
memoryDir: options.memoryDir,
|
|
70071
|
-
objectiveStateStoreDir: options.objectiveStateStoreDir,
|
|
70072
|
-
snapshot
|
|
70073
|
-
})
|
|
70074
|
-
);
|
|
70075
|
-
}
|
|
70076
|
-
return { snapshots, filePaths };
|
|
70077
|
-
}
|
|
70078
|
-
|
|
70079
70580
|
// ../../src/qmd-availability-probe.ts
|
|
70080
70581
|
async function probeQmdAvailability(host) {
|
|
70081
70582
|
const qmd = host?.qmd;
|
|
@@ -72718,6 +73219,9 @@ var NODE_FS_MODULE_ID = ["node", "fs"].join(":");
|
|
|
72718
73219
|
var NODE_FS_PROMISES_MODULE_ID = ["node", "fs/promises"].join(":");
|
|
72719
73220
|
var READ_FILE_SYNC_FIELD = ["read", "File", "Sync"].join("");
|
|
72720
73221
|
var EXISTS_SYNC_FIELD = ["exists", "Sync"].join("");
|
|
73222
|
+
function isMemoryArtifactPath(p) {
|
|
73223
|
+
return /(?:^|[\\/])artifacts(?:[\\/]|$)/i.test(p);
|
|
73224
|
+
}
|
|
72721
73225
|
function readTextFileNow(filePath) {
|
|
72722
73226
|
const nodeRequire = createRequire3(import.meta.url);
|
|
72723
73227
|
const fs19 = nodeRequire(NODE_FS_MODULE_ID);
|
|
@@ -74140,7 +74644,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
74140
74644
|
api.registerMemoryPromptSection(memoryBuildFn);
|
|
74141
74645
|
memoryPromptBuilder = memoryBuildFn;
|
|
74142
74646
|
}
|
|
74143
|
-
if (sdkCaps.hasRegisterMemoryCapability && typeof api.registerMemoryCapability === "function") {
|
|
74647
|
+
if (sdkCaps.hasRegisterMemoryCapability && typeof api.registerMemoryCapability === "function" || typeof api.registerMemoryRuntime === "function" || typeof api.registerMemoryFlushPlan === "function") {
|
|
74144
74648
|
const capabilityPromptBuilder = memoryPromptBuilder ? (params) => {
|
|
74145
74649
|
const key = params?.sessionKey ?? "default";
|
|
74146
74650
|
return consumePromptMemoryLines2(key, { destructive: false });
|
|
@@ -74249,11 +74753,10 @@ Keep the reflection grounded in the evidence below.
|
|
|
74249
74753
|
namespaces: namespace ? [namespace] : void 0,
|
|
74250
74754
|
mode: resolvedMode
|
|
74251
74755
|
});
|
|
74252
|
-
const isArtifactPath2 = (p) => /(?:^|[\\/])artifacts(?:[\\/]|$)/i.test(p);
|
|
74253
74756
|
return rawResults.filter((result) => {
|
|
74254
74757
|
const candidate = result;
|
|
74255
74758
|
const p = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : "";
|
|
74256
|
-
return !
|
|
74759
|
+
return !isMemoryArtifactPath(p);
|
|
74257
74760
|
}).map((result, index) => {
|
|
74258
74761
|
const candidate = result;
|
|
74259
74762
|
const rawPath = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : `memory-${index + 1}`;
|
|
@@ -74365,6 +74868,18 @@ Keep the reflection grounded in the evidence below.
|
|
|
74365
74868
|
async closeAllMemorySearchManagers() {
|
|
74366
74869
|
}
|
|
74367
74870
|
};
|
|
74871
|
+
const remnicMemoryFlushPlanResolver = () => {
|
|
74872
|
+
const maxTurnChars = typeof cfg.extractionMaxTurnChars === "number" && Number.isFinite(cfg.extractionMaxTurnChars) ? Math.max(1e3, Math.floor(cfg.extractionMaxTurnChars)) : 8e3;
|
|
74873
|
+
return {
|
|
74874
|
+
softThresholdTokens: 24e3,
|
|
74875
|
+
forceFlushTranscriptBytes: Math.max(16384, maxTurnChars * 4),
|
|
74876
|
+
reserveTokensFloor: 2e3,
|
|
74877
|
+
model: typeof cfg.summaryModel === "string" && cfg.summaryModel.length > 0 ? cfg.summaryModel : cfg.model,
|
|
74878
|
+
prompt: "Flush the recent OpenClaw transcript into Remnic memory. Preserve durable user preferences, project facts, decisions, corrections, and commitments. Ignore runtime metadata, credentials, and transient command noise.",
|
|
74879
|
+
systemPrompt: "You are Remnic's memory flush planner. Produce concise durable memory candidates only when the transcript contains information worth remembering.",
|
|
74880
|
+
relativePath: ["state", "plugins", serviceId, "flush-plan.md"].join("/")
|
|
74881
|
+
};
|
|
74882
|
+
};
|
|
74368
74883
|
const memoryCapability = {
|
|
74369
74884
|
// Include the promptBuilder so runtimes that treat unified capability
|
|
74370
74885
|
// registration as authoritative (SDK >=2026.4.5) continue to inject
|
|
@@ -74372,6 +74887,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
74372
74887
|
// Respect promptInjectionAllowed policy — omit promptBuilder if injection
|
|
74373
74888
|
// is disabled, so the capability only provides publicArtifacts.
|
|
74374
74889
|
...promptInjectionAllowed ? { promptBuilder: capabilityPromptBuilder } : {},
|
|
74890
|
+
flushPlanResolver: remnicMemoryFlushPlanResolver,
|
|
74375
74891
|
runtime: remnicMemoryRuntime,
|
|
74376
74892
|
publicArtifacts: {
|
|
74377
74893
|
listArtifacts: async (_params) => {
|
|
@@ -74388,9 +74904,18 @@ Keep the reflection grounded in the evidence below.
|
|
|
74388
74904
|
}
|
|
74389
74905
|
}
|
|
74390
74906
|
};
|
|
74391
|
-
api.registerMemoryCapability
|
|
74907
|
+
if (typeof api.registerMemoryCapability === "function") {
|
|
74908
|
+
api.registerMemoryCapability(memoryCapability);
|
|
74909
|
+
}
|
|
74910
|
+
if (typeof api.registerMemoryRuntime === "function") {
|
|
74911
|
+
api.registerMemoryRuntime(remnicMemoryRuntime);
|
|
74912
|
+
}
|
|
74913
|
+
if (typeof api.registerMemoryFlushPlan === "function") {
|
|
74914
|
+
api.registerMemoryFlushPlan(remnicMemoryFlushPlanResolver);
|
|
74915
|
+
}
|
|
74392
74916
|
const builderDesc = !promptInjectionAllowed ? " (promptBuilder omitted \u2014 injection disabled by policy)" : memoryPromptBuilder ? " and promptBuilder (from registerMemoryPromptSection)" : " and promptBuilder (capability-only fallback)";
|
|
74393
|
-
|
|
74917
|
+
const capabilityDesc = typeof api.registerMemoryCapability === "function" ? `memory capability with publicArtifacts provider${builderDesc}` : "split memory runtime/flush-plan surfaces";
|
|
74918
|
+
log.info(`registered ${capabilityDesc}`);
|
|
74394
74919
|
}
|
|
74395
74920
|
api.on(
|
|
74396
74921
|
"agent_end",
|
|
@@ -74444,9 +74969,16 @@ Keep the reflection grounded in the evidence below.
|
|
|
74444
74969
|
}
|
|
74445
74970
|
}
|
|
74446
74971
|
try {
|
|
74972
|
+
const objectiveStateNamespace = orchestrator.config.namespacesEnabled && typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(sessionKey) : orchestrator.config.defaultNamespace;
|
|
74973
|
+
const objectiveStateStorage = orchestrator.config.namespacesEnabled && typeof orchestrator.getStorageForNamespace === "function" ? await orchestrator.getStorageForNamespace(objectiveStateNamespace) : null;
|
|
74447
74974
|
await recordObjectiveStateSnapshotsFromAgentMessages({
|
|
74448
|
-
memoryDir: orchestrator.config.memoryDir,
|
|
74449
|
-
objectiveStateStoreDir:
|
|
74975
|
+
memoryDir: objectiveStateStorage?.dir ?? orchestrator.config.memoryDir,
|
|
74976
|
+
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
74977
|
+
memoryDir: orchestrator.config.memoryDir,
|
|
74978
|
+
configuredStoreDir: orchestrator.config.objectiveStateStoreDir,
|
|
74979
|
+
namespacesEnabled: orchestrator.config.namespacesEnabled,
|
|
74980
|
+
namespace: objectiveStateNamespace
|
|
74981
|
+
}),
|
|
74450
74982
|
objectiveStateMemoryEnabled: orchestrator.config.objectiveStateMemoryEnabled,
|
|
74451
74983
|
objectiveStateSnapshotWritesEnabled: orchestrator.config.objectiveStateSnapshotWritesEnabled,
|
|
74452
74984
|
sessionKey,
|
|
@@ -74992,6 +75524,151 @@ Keep the reflection grounded in the evidence below.
|
|
|
74992
75524
|
log.error("failed to auto-register hourly summary cron job:", err);
|
|
74993
75525
|
}
|
|
74994
75526
|
}
|
|
75527
|
+
if (typeof api.registerMemoryCorpusSupplement === "function") {
|
|
75528
|
+
const normalizeCorpusLookup = (lookup) => typeof lookup === "string" && lookup.trim().length > 0 ? lookup.trim() : null;
|
|
75529
|
+
const resolveCorpusStorage = async (agentSessionKey) => {
|
|
75530
|
+
const namespace = typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(agentSessionKey) : void 0;
|
|
75531
|
+
return typeof orchestrator.getStorageForNamespace === "function" ? await orchestrator.getStorageForNamespace(namespace) : orchestrator.storage;
|
|
75532
|
+
};
|
|
75533
|
+
const normalizeCorpusPath = (value) => value.trim().replace(/\\/g, "/").replace(/^\.\//, "");
|
|
75534
|
+
const pathIsInside = (root, candidate) => {
|
|
75535
|
+
const relative = path99.relative(root, candidate);
|
|
75536
|
+
return relative === "" || !relative.startsWith("..") && !path99.isAbsolute(relative);
|
|
75537
|
+
};
|
|
75538
|
+
const corpusPathCandidates = (rawPath, storageDir) => {
|
|
75539
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
75540
|
+
const trimmed = rawPath.trim();
|
|
75541
|
+
if (!trimmed) return [];
|
|
75542
|
+
candidates.add(normalizeCorpusPath(trimmed));
|
|
75543
|
+
if (path99.isAbsolute(trimmed)) {
|
|
75544
|
+
const absolutePath = path99.resolve(trimmed);
|
|
75545
|
+
const absoluteStorageDir = path99.resolve(storageDir);
|
|
75546
|
+
if (pathIsInside(absoluteStorageDir, absolutePath)) {
|
|
75547
|
+
candidates.add(normalizeCorpusPath(path99.relative(absoluteStorageDir, absolutePath)));
|
|
75548
|
+
}
|
|
75549
|
+
}
|
|
75550
|
+
candidates.add(path99.basename(trimmed));
|
|
75551
|
+
return [...candidates].filter((candidate) => candidate.length > 0);
|
|
75552
|
+
};
|
|
75553
|
+
const displayCorpusPath = (rawPath, storageDir) => {
|
|
75554
|
+
const trimmed = rawPath.trim();
|
|
75555
|
+
if (!trimmed) return "";
|
|
75556
|
+
if (path99.isAbsolute(trimmed)) {
|
|
75557
|
+
const absolutePath = path99.resolve(trimmed);
|
|
75558
|
+
const absoluteStorageDir = path99.resolve(storageDir);
|
|
75559
|
+
if (pathIsInside(absoluteStorageDir, absolutePath)) {
|
|
75560
|
+
return normalizeCorpusPath(path99.relative(absoluteStorageDir, absolutePath));
|
|
75561
|
+
}
|
|
75562
|
+
}
|
|
75563
|
+
return normalizeCorpusPath(trimmed);
|
|
75564
|
+
};
|
|
75565
|
+
const readMemoryByLookup = async (lookup, agentSessionKey) => {
|
|
75566
|
+
const storage = await resolveCorpusStorage(agentSessionKey);
|
|
75567
|
+
const storageDir = typeof storage.dir === "string" && storage.dir.length > 0 ? storage.dir : orchestrator.config.memoryDir;
|
|
75568
|
+
const memories = await storage.readAllMemories();
|
|
75569
|
+
const normalizedLookup = normalizeCorpusPath(lookup);
|
|
75570
|
+
const matched = memories.find((memory) => memory.frontmatter.id === lookup) ?? memories.find(
|
|
75571
|
+
(memory) => corpusPathCandidates(memory.path, storageDir).includes(normalizedLookup)
|
|
75572
|
+
) ?? null;
|
|
75573
|
+
if (!matched) return null;
|
|
75574
|
+
const displayPath = displayCorpusPath(matched.path, storageDir);
|
|
75575
|
+
return { memory: matched, displayPath };
|
|
75576
|
+
};
|
|
75577
|
+
const corpusBackendError = (operation, err) => {
|
|
75578
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
75579
|
+
const error = new Error(`Remnic corpus ${operation} failed: ${message}`);
|
|
75580
|
+
error.cause = err;
|
|
75581
|
+
return error;
|
|
75582
|
+
};
|
|
75583
|
+
const remnicCorpusSupplement = {
|
|
75584
|
+
id: `${serviceId}:remnic-memory-corpus`,
|
|
75585
|
+
label: "Remnic Memory Corpus",
|
|
75586
|
+
async search(params) {
|
|
75587
|
+
const query = normalizeCorpusLookup(
|
|
75588
|
+
typeof params === "string" ? params : params?.query
|
|
75589
|
+
);
|
|
75590
|
+
if (!query) return [];
|
|
75591
|
+
const maxResults = typeof params === "object" && typeof params.maxResults === "number" && Number.isFinite(params.maxResults) ? Math.max(1, Math.floor(params.maxResults)) : 8;
|
|
75592
|
+
const agentSessionKey = typeof params === "object" ? params.agentSessionKey : void 0;
|
|
75593
|
+
const namespace = typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(agentSessionKey) : void 0;
|
|
75594
|
+
try {
|
|
75595
|
+
const rawResults = await orchestrator.searchAcrossNamespaces({
|
|
75596
|
+
query,
|
|
75597
|
+
maxResults,
|
|
75598
|
+
namespaces: namespace ? [namespace] : void 0,
|
|
75599
|
+
mode: "search"
|
|
75600
|
+
});
|
|
75601
|
+
return rawResults.filter((result) => {
|
|
75602
|
+
const candidate = result;
|
|
75603
|
+
const p = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : "";
|
|
75604
|
+
return !isMemoryArtifactPath(p);
|
|
75605
|
+
}).map((result, index) => {
|
|
75606
|
+
const candidate = result;
|
|
75607
|
+
const lookupPath = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : `remnic-memory-${index + 1}`;
|
|
75608
|
+
const startLine = typeof candidate.startLine === "number" && Number.isFinite(candidate.startLine) ? Math.max(1, Math.floor(candidate.startLine)) : 1;
|
|
75609
|
+
const endLine = typeof candidate.endLine === "number" && Number.isFinite(candidate.endLine) ? Math.max(startLine, Math.floor(candidate.endLine)) : startLine;
|
|
75610
|
+
return {
|
|
75611
|
+
corpus: "remnic",
|
|
75612
|
+
path: lookupPath,
|
|
75613
|
+
title: typeof candidate.id === "string" && candidate.id.length > 0 ? candidate.id : lookupPath,
|
|
75614
|
+
kind: "memory",
|
|
75615
|
+
score: typeof candidate.score === "number" && Number.isFinite(candidate.score) ? candidate.score : 0,
|
|
75616
|
+
snippet: typeof candidate.snippet === "string" ? candidate.snippet : typeof candidate.text === "string" ? candidate.text : "",
|
|
75617
|
+
id: typeof candidate.id === "string" ? candidate.id : lookupPath,
|
|
75618
|
+
startLine,
|
|
75619
|
+
endLine,
|
|
75620
|
+
citation: lookupPath,
|
|
75621
|
+
source: "remnic",
|
|
75622
|
+
provenanceLabel: "Remnic",
|
|
75623
|
+
sourceType: "memory",
|
|
75624
|
+
sourcePath: lookupPath,
|
|
75625
|
+
updatedAt: typeof candidate.metadata?.updatedAt === "string" ? candidate.metadata.updatedAt : void 0
|
|
75626
|
+
};
|
|
75627
|
+
});
|
|
75628
|
+
} catch (err) {
|
|
75629
|
+
log.warn(`memory corpus search failed: ${err}`);
|
|
75630
|
+
throw corpusBackendError("search", err);
|
|
75631
|
+
}
|
|
75632
|
+
},
|
|
75633
|
+
async get(params) {
|
|
75634
|
+
const lookup = normalizeCorpusLookup(
|
|
75635
|
+
typeof params === "string" ? params : params?.lookup
|
|
75636
|
+
);
|
|
75637
|
+
if (!lookup || isMemoryArtifactPath(lookup)) return null;
|
|
75638
|
+
const agentSessionKey = typeof params === "object" ? params.agentSessionKey : void 0;
|
|
75639
|
+
try {
|
|
75640
|
+
const resolved = await readMemoryByLookup(lookup, agentSessionKey);
|
|
75641
|
+
if (!resolved) return null;
|
|
75642
|
+
const { memory, displayPath } = resolved;
|
|
75643
|
+
if (isMemoryArtifactPath(displayPath) || isMemoryArtifactPath(memory.path)) {
|
|
75644
|
+
return null;
|
|
75645
|
+
}
|
|
75646
|
+
const allLines = memory.content.split(/\r?\n/);
|
|
75647
|
+
const fromLine = typeof params === "object" && typeof params.fromLine === "number" && Number.isFinite(params.fromLine) ? Math.max(1, Math.floor(params.fromLine)) : 1;
|
|
75648
|
+
const lineCount = typeof params === "object" && typeof params.lineCount === "number" && Number.isFinite(params.lineCount) ? Math.max(1, Math.floor(params.lineCount)) : allLines.length;
|
|
75649
|
+
const selected = allLines.slice(fromLine - 1, fromLine - 1 + lineCount);
|
|
75650
|
+
return {
|
|
75651
|
+
corpus: "remnic",
|
|
75652
|
+
path: displayPath,
|
|
75653
|
+
title: memory.frontmatter.id,
|
|
75654
|
+
kind: memory.frontmatter.category,
|
|
75655
|
+
content: selected.join("\n"),
|
|
75656
|
+
fromLine,
|
|
75657
|
+
lineCount: selected.length,
|
|
75658
|
+
id: memory.frontmatter.id,
|
|
75659
|
+
provenanceLabel: "Remnic",
|
|
75660
|
+
sourceType: "memory",
|
|
75661
|
+
sourcePath: displayPath,
|
|
75662
|
+
updatedAt: memory.frontmatter.updated
|
|
75663
|
+
};
|
|
75664
|
+
} catch (err) {
|
|
75665
|
+
log.warn(`memory corpus get failed: ${err}`);
|
|
75666
|
+
throw corpusBackendError("get", err);
|
|
75667
|
+
}
|
|
75668
|
+
}
|
|
75669
|
+
};
|
|
75670
|
+
api.registerMemoryCorpusSupplement(remnicCorpusSupplement);
|
|
75671
|
+
}
|
|
74995
75672
|
if (cfg.openclawToolsEnabled !== false && typeof api.registerTool === "function") {
|
|
74996
75673
|
api.registerTool(
|
|
74997
75674
|
buildMemorySearchTool(orchestrator, {
|