mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 11:21:07 +00:00
91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
import {
|
|
parseAgentSessionKey,
|
|
type MemoryCitationsMode,
|
|
type OpenClawConfig,
|
|
} from "openclaw/plugin-sdk/memory-core-host-runtime-core";
|
|
import type { MemorySearchResult } from "openclaw/plugin-sdk/memory-core-host-runtime-files";
|
|
|
|
export function resolveMemoryCitationsMode(cfg: OpenClawConfig): MemoryCitationsMode {
|
|
const mode = cfg.memory?.citations;
|
|
if (mode === "on" || mode === "off" || mode === "auto") {
|
|
return mode;
|
|
}
|
|
return "auto";
|
|
}
|
|
|
|
export function decorateCitations(
|
|
results: MemorySearchResult[],
|
|
include: boolean,
|
|
): MemorySearchResult[] {
|
|
if (!include) {
|
|
return results.map((entry) => ({ ...entry, citation: undefined }));
|
|
}
|
|
return results.map((entry) => {
|
|
const citation = formatCitation(entry);
|
|
const snippet = `${entry.snippet.trim()}\n\nSource: ${citation}`;
|
|
return { ...entry, citation, snippet };
|
|
});
|
|
}
|
|
|
|
function formatCitation(entry: MemorySearchResult): string {
|
|
const lineRange =
|
|
entry.startLine === entry.endLine
|
|
? `#L${entry.startLine}`
|
|
: `#L${entry.startLine}-L${entry.endLine}`;
|
|
return `${entry.path}${lineRange}`;
|
|
}
|
|
|
|
export function clampResultsByInjectedChars(
|
|
results: MemorySearchResult[],
|
|
budget?: number,
|
|
): MemorySearchResult[] {
|
|
if (!budget || budget <= 0) {
|
|
return results;
|
|
}
|
|
let remaining = budget;
|
|
const clamped: MemorySearchResult[] = [];
|
|
for (const entry of results) {
|
|
if (remaining <= 0) {
|
|
break;
|
|
}
|
|
const snippet = entry.snippet ?? "";
|
|
if (snippet.length <= remaining) {
|
|
clamped.push(entry);
|
|
remaining -= snippet.length;
|
|
} else {
|
|
const trimmed = snippet.slice(0, Math.max(0, remaining));
|
|
clamped.push({ ...entry, snippet: trimmed });
|
|
break;
|
|
}
|
|
}
|
|
return clamped;
|
|
}
|
|
|
|
export function shouldIncludeCitations(params: {
|
|
mode: MemoryCitationsMode;
|
|
sessionKey?: string;
|
|
}): boolean {
|
|
if (params.mode === "on") {
|
|
return true;
|
|
}
|
|
if (params.mode === "off") {
|
|
return false;
|
|
}
|
|
return deriveChatTypeFromSessionKey(params.sessionKey) === "direct";
|
|
}
|
|
|
|
function deriveChatTypeFromSessionKey(sessionKey?: string): "direct" | "group" | "channel" {
|
|
const parsed = parseAgentSessionKey(sessionKey);
|
|
if (!parsed?.rest) {
|
|
return "direct";
|
|
}
|
|
const tokens = new Set(parsed.rest.toLowerCase().split(":").filter(Boolean));
|
|
if (tokens.has("channel")) {
|
|
return "channel";
|
|
}
|
|
if (tokens.has("group")) {
|
|
return "group";
|
|
}
|
|
return "direct";
|
|
}
|