UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

119 lines (118 loc) • 6.95 kB
import { t as asNonArrayRecord } from "./record-coerce-TIsquoVR.mjs"; import { _ as resolveSessionAgentIdStrict } from "./agent-scope-CG17uXFn.mjs"; import "./agent-scope-runtime-DMJYuX7c.mjs"; import { n as resolveMemorySearchIndexConfig } from "./memory-search-BKCwFNk2.mjs"; import "./memory-core-host-runtime-core-CNR3hHPL.mjs"; //#region extensions/memory-core/src/memory-tool-contract.ts const MemorySearchSchema = { type: "object", properties: { query: { type: "string" }, maxResults: { type: "integer", minimum: 1 }, minScore: { type: "number" }, corpus: { type: "string", enum: [ "memory", "wiki", "all", "sessions" ] } }, required: ["query"], additionalProperties: false }; const MemoryGetSchema = { type: "object", properties: { path: { type: "string" }, from: { type: "integer", minimum: 1 }, lines: { type: "integer", minimum: 1 }, corpus: { type: "string", enum: [ "memory", "wiki", "all" ] } }, required: ["path"], additionalProperties: false }; function resolveMemorySourceContract(settings) { const files = ["MEMORY.md, USER.md, Markdown files recursively under memory/", settings.extraPaths.length > 0 ? "configured extra paths" : ""].filter(Boolean).join(", "); return { files, search: settings.searchSources.includes("sessions") ? `${files}, indexed session transcripts` : files }; } function resolveMemoryToolContext(options) { const cfg = options.getConfig ? options.getConfig() : options.config; if (!cfg) return null; const agentId = resolveSessionAgentIdStrict({ sessionKey: options.agentSessionKey, config: cfg, agentId: options.agentId }); const settings = resolveMemorySearchIndexConfig(cfg, agentId); return settings ? { cfg, agentId, settings, sources: resolveMemorySourceContract(settings) } : null; } const SEARCH_CORPUS_OUTCOME_GUIDANCE = "Corpus outcomes cover each requested corpus; only a top-level corpus warning means results are partial and must be surfaced to the user. An optional corpus outcome of not-registered in a multi-corpus result is informational."; const GET_READ_OUTCOME_GUIDANCE = "status=ok means the requested excerpt was read; status=not_found means every requested available corpus missed; status=error means the requested read failed, not that memory is disabled."; const MEMORY_SEARCH_TOOL_CONTRACT = { label: "Memory Search", name: "memory_search", parameters: MemorySearchSchema, prepareArguments: (args) => { const params = asNonArrayRecord(args); if (!Object.hasOwn(params, "min_score") && !Object.hasOwn(params, "max_results")) return args; const normalized = { ...params }; for (const [alias, key] of [["min_score", "minScore"], ["max_results", "maxResults"]]) if (Object.hasOwn(normalized, alias)) { if (!Object.hasOwn(normalized, key)) normalized[key] = normalized[alias]; delete normalized[alias]; } return normalized; }, describe: ({ search }) => `Mandatory recall step: semantically search ${search} before answering questions about prior work, decisions, dates, people, preferences, or todos. Omit \`corpus\` to search those configured sources. Session results are transcript search references, not readable memory-file paths. Optional \`corpus=wiki\` or \`corpus=all\` also searches registered compiled-wiki supplements; use \`corpus=all\` only when compiled wiki supplements are needed. \`corpus=memory\` restricts hits to indexed memory files (excludes session transcript chunks from ranking). \`corpus=sessions\` searches indexed session transcripts under the same visibility rules as session history tools and returns unavailable when semantic session indexing is disabled. ${SEARCH_CORPUS_OUTCOME_GUIDANCE} If response has disabled=true or stale=true, tell the user and include the warning/action guidance.` }; const MEMORY_GET_TOOL_CONTRACT = { label: "Memory Get", name: "memory_get", parameters: MemoryGetSchema, describe: ({ files }) => `Safe exact excerpt read from ${files}. Session transcript paths are unsupported; use the available session-history workflow for session hits. Defaults to a bounded excerpt when lines are omitted and includes truncation/continuation info when more content exists. \`corpus=wiki\` reads registered compiled-wiki supplements. ${GET_READ_OUTCOME_GUIDANCE} ${SEARCH_CORPUS_OUTCOME_GUIDANCE}` }; function buildMemoryPromptSection({ availableTools, citationsMode }) { const hasMemorySearch = availableTools.has("memory_search"); const hasMemoryGet = availableTools.has("memory_get"); if (!hasMemorySearch && !hasMemoryGet) return []; const guidance = hasMemorySearch ? `Before answering anything about prior work, decisions, dates, people, preferences, or todos: run memory_search without corpus to search the configured sources${hasMemoryGet ? "; for memory-file hits, use memory_get to pull only the needed lines" : ""}. Use corpus=all only when compiled wiki supplements are needed. If low confidence after search, say you checked.` : "Before answering anything about prior work, decisions, dates, people, preferences, or todos that point to a specific memory file: run memory_get to pull only the needed lines. If low confidence after reading, say you checked."; const sessionGuidance = !hasMemorySearch ? [] : [availableTools.has("sessions_search") ? `For session hits, use sessions_search with distinctive snippet text (and sessionKey set to the transcript ID when known)${availableTools.has("sessions_history") ? ", then sessions_history with the returned sessionKey, messageId, and sessionId for a bounded sanitized excerpt" : "; exact session history is unavailable with the enabled tools"}.` : availableTools.has("sessions_history") ? "For session hits, use sessions_history with a known session key or transcript ID and a small limit; paginate its returned history metadata to locate the excerpt." : "Session hits are search snippets only; exact session history is unavailable with the enabled tools.", "Session search line numbers are not history offsets. Never read raw transcript files to expand session hits."]; const outcomeGuidance = "Report recall as partial, unavailable, or stale when the result includes a top-level warning or action guidance, or explicitly sets disabled=true or stale=true. In a multi-corpus result without a top-level warning or action guidance, treat an optional corpus outcome of not-registered as informational."; const citationGuidance = citationsMode === "off" ? "Citations are disabled: do not mention file paths or line numbers in replies unless the user explicitly asks." : "Citations: include Source: <path#line> when it helps the user verify memory snippets."; return [ "## Memory Recall", guidance, ...sessionGuidance, outcomeGuidance, citationGuidance, "" ]; } //#endregion export { resolveMemoryToolContext as i, MEMORY_SEARCH_TOOL_CONTRACT as n, buildMemoryPromptSection as r, MEMORY_GET_TOOL_CONTRACT as t };