recallnest 1.4.1
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/.claude-plugin/CLAUDE.md +29 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/.env.example +3 -0
- package/.github/workflows/ci.yml +28 -0
- package/.mcp.json +9 -0
- package/CHANGELOG.md +51 -0
- package/CLAUDE.md +42 -0
- package/DEMO.md +94 -0
- package/EVAL.md +89 -0
- package/FAILURES.md +75 -0
- package/LICENSE +21 -0
- package/OPERATIONS.md +59 -0
- package/README.md +427 -0
- package/README_CN.md +425 -0
- package/ROADMAP.md +198 -0
- package/assets/recallnest-workbench.png +0 -0
- package/assets/ui/app.js +807 -0
- package/assets/ui/index.html +154 -0
- package/assets/ui/styles.css +605 -0
- package/assets/wechat-qr.jpg +0 -0
- package/config.json.example +38 -0
- package/daily-recall.sh +87 -0
- package/daily-reflections/2026-03-05.md +15 -0
- package/daily-reflections/2026-03-06.md +15 -0
- package/daily-reflections/2026-03-07.md +7 -0
- package/daily-reflections/2026-03-08.md +34 -0
- package/daily-reflections/2026-03-09.md +35 -0
- package/daily-reflections/2026-03-10.md +36 -0
- package/daily-reflections/2026-03-11.md +35 -0
- package/daily-reflections/2026-03-12.md +36 -0
- package/daily-reflections/2026-03-13.md +35 -0
- package/daily-reflections/2026-03-14.md +35 -0
- package/daily-reflections/2026-03-15.md +35 -0
- package/daily-reflections/2026-03-16.md +41 -0
- package/daily-reflections/2026-03-17.md +10 -0
- package/daily-reflections/2026-03-18.md +10 -0
- package/daily-reflections/2026-03-19.md +10 -0
- package/daily-reflections/2026-03-20.md +10 -0
- package/daily-reflections/2026-03-21.md +10 -0
- package/daily-reflections/2026-03-22.md +10 -0
- package/daily-reflections/2026-03-23.md +10 -0
- package/daily-reflections/2026-03-24.md +10 -0
- package/daily-reflections/2026-03-25.md +32 -0
- package/daily-reflections/2026-03-26.md +37 -0
- package/daily-reflections/2026-03-27.md +35 -0
- package/daily-reflections/2026-03-28.md +35 -0
- package/daily-reflections/2026-03-29.md +35 -0
- package/daily-reflections/2026-03-30.md +36 -0
- package/daily-reflections/2026-03-31.md +35 -0
- package/daily-reflections/2026-04-01.md +35 -0
- package/docs/api-reference.md +1291 -0
- package/docs/architecture.md +168 -0
- package/docs/memory-boundary-contract.md +226 -0
- package/docs/memory-categories.md +119 -0
- package/docs/pipeline-audit-ultramemory.md +177 -0
- package/docs/plans/2026-03-08-query-expansion.md +270 -0
- package/docs/plans/2026-03-16-continuity-layer.md +196 -0
- package/docs/plans/mcp-tiering-plan.md +126 -0
- package/docs/research/recall-quality-audit-2026-03-22.md +153 -0
- package/docs/self-evolution.md +198 -0
- package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +782 -0
- package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +77 -0
- package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +95 -0
- package/eval/cases.json +85 -0
- package/eval/continuity/case-seeds.json +90 -0
- package/eval/continuity/cases.json +302 -0
- package/eval/continuity/memory-seeds.json +26 -0
- package/eval/continuity/pattern-seeds.json +100 -0
- package/eval/continuity/results-2026-03-16.md +117 -0
- package/eval/continuity/results-2026-03-19.md +453 -0
- package/eval/continuity/runbook.md +110 -0
- package/eval/continuity/seed-cases.md +54 -0
- package/eval/reports/2026-03-06-abstract-query-baseline.md +96 -0
- package/eval/reports/2026-03-06-aws-ssh-baseline.md +82 -0
- package/eval/reports/2026-03-06-baseline.md +82 -0
- package/eval/reports/query-expansion.md +138 -0
- package/integrations/README.md +57 -0
- package/integrations/claude-code/README.md +133 -0
- package/integrations/claude-code/claude-md-snippet.md +31 -0
- package/integrations/claude-code/setup.sh +66 -0
- package/integrations/claude-code/smoke-continuity.sh +452 -0
- package/integrations/codex/README.md +49 -0
- package/integrations/codex/agents-md-snippet.md +31 -0
- package/integrations/codex/setup.sh +58 -0
- package/integrations/examples/claude-agent-sdk/memory-agent.ts +182 -0
- package/integrations/examples/langchain/memory-chain.py +111 -0
- package/integrations/examples/openai-agents-sdk/memory-agent.py +109 -0
- package/integrations/gemini-cli/README.md +57 -0
- package/integrations/gemini-cli/gemini-md-snippet.md +31 -0
- package/integrations/gemini-cli/setup.sh +64 -0
- package/integrations/shared/install-managed-block.sh +51 -0
- package/lm +19 -0
- package/package.json +50 -0
- package/plan-v1.2-distributable.md +105 -0
- package/scripts/archive-distilled-junk.ts +116 -0
- package/scripts/backfill-l0l1l2.ts +98 -0
- package/scripts/blind-scan.ts +588 -0
- package/scripts/cleanup-step1-exact-dups.ts +117 -0
- package/scripts/cleanup-step2-template-dups.ts +113 -0
- package/scripts/cleanup-step3-stale-content.ts +149 -0
- package/scripts/cleanup-step4-orphan-scopes.ts +131 -0
- package/scripts/delete-distilled-junk.ts +88 -0
- package/scripts/distill-facts.ts +305 -0
- package/scripts/health-check.ts +343 -0
- package/scripts/incremental-ingest.sh +71 -0
- package/scripts/mlp-health-check.ts +382 -0
- package/scripts/pull-claude-desktop.ts +515 -0
- package/scripts/re-ingest-cc.sh +66 -0
- package/scripts/rebalance-memory-health.ts +181 -0
- package/scripts/run-desktop-ingest.sh +11 -0
- package/scripts/start-server.sh +12 -0
- package/scripts/viz-dashboard.html +423 -0
- package/scripts/viz-export.ts +703 -0
- package/src/__tests__/access-tracker-novelty.test.ts +228 -0
- package/src/__tests__/auto-consolidation.test.ts +168 -0
- package/src/__tests__/auto-recall.test.ts +131 -0
- package/src/__tests__/batch-dedup.test.ts +65 -0
- package/src/__tests__/capture-engine.test.ts +1142 -0
- package/src/__tests__/capture-heuristic.test.ts +171 -0
- package/src/__tests__/cascade-forget.test.ts +210 -0
- package/src/__tests__/category-min-scores.test.ts +33 -0
- package/src/__tests__/confidence-tracker.test.ts +196 -0
- package/src/__tests__/conflict-advisor.test.ts +206 -0
- package/src/__tests__/conflict-escalation.test.ts +149 -0
- package/src/__tests__/conflict-lifecycle.test.ts +83 -0
- package/src/__tests__/conflict-output.test.ts +85 -0
- package/src/__tests__/conflict-store.test.ts +374 -0
- package/src/__tests__/consolidation-engine.test.ts +181 -0
- package/src/__tests__/context-composer-pins.test.ts +64 -0
- package/src/__tests__/context-composer-task-selection.test.ts +24 -0
- package/src/__tests__/context-renderer.test.ts +91 -0
- package/src/__tests__/continuity-eval.test.ts +275 -0
- package/src/__tests__/continuity-schema.test.ts +97 -0
- package/src/__tests__/core-recall-eval.test.ts +235 -0
- package/src/__tests__/core-summary.test.ts +109 -0
- package/src/__tests__/dedup-actions.test.ts +58 -0
- package/src/__tests__/deterministic-id.test.ts +39 -0
- package/src/__tests__/doctor.test.ts +303 -0
- package/src/__tests__/drill-down.test.ts +108 -0
- package/src/__tests__/embedder.test.ts +122 -0
- package/src/__tests__/entity-resolver.test.ts +58 -0
- package/src/__tests__/event-segmenter.test.ts +153 -0
- package/src/__tests__/hotness-blend.test.ts +76 -0
- package/src/__tests__/ingest.test.ts +360 -0
- package/src/__tests__/kg-extractor.test.ts +184 -0
- package/src/__tests__/kg-store.test.ts +198 -0
- package/src/__tests__/llm-consolidation.test.ts +226 -0
- package/src/__tests__/memory-boundaries.test.ts +237 -0
- package/src/__tests__/memory-health-rebalance.test.ts +144 -0
- package/src/__tests__/memory-output.test.ts +215 -0
- package/src/__tests__/multi-vector.test.ts +242 -0
- package/src/__tests__/ppr-traversal.test.ts +256 -0
- package/src/__tests__/preference-guard-smoke.test.ts +211 -0
- package/src/__tests__/preference-matcher.test.ts +230 -0
- package/src/__tests__/preference-slots.test.ts +106 -0
- package/src/__tests__/prospective-memory.test.ts +283 -0
- package/src/__tests__/query-entity-detector.test.ts +171 -0
- package/src/__tests__/query-expander.test.ts +34 -0
- package/src/__tests__/recall-mode.test.ts +64 -0
- package/src/__tests__/result-synthesizer.test.ts +198 -0
- package/src/__tests__/resume-context.test.ts +4743 -0
- package/src/__tests__/retrieval-trace.test.ts +213 -0
- package/src/__tests__/retriever-boundary-weight.test.ts +136 -0
- package/src/__tests__/retroactive-boost.test.ts +223 -0
- package/src/__tests__/scope-inventory.test.ts +200 -0
- package/src/__tests__/scope-policy.test.ts +69 -0
- package/src/__tests__/session-checkpoint.test.ts +259 -0
- package/src/__tests__/session-gc.test.ts +215 -0
- package/src/__tests__/store-scope-audit.test.ts +81 -0
- package/src/__tests__/temporal-parser.test.ts +241 -0
- package/src/__tests__/term-registry.test.ts +121 -0
- package/src/__tests__/tool-output-compressor.test.ts +133 -0
- package/src/__tests__/version-manager.test.ts +213 -0
- package/src/__tests__/workflow-observation.test.ts +400 -0
- package/src/access-tracker.ts +316 -0
- package/src/adaptive-retrieval.ts +64 -0
- package/src/api-server.ts +667 -0
- package/src/asset-sync.ts +79 -0
- package/src/auto-consolidation.ts +133 -0
- package/src/auto-gc.ts +124 -0
- package/src/auto-recall.ts +95 -0
- package/src/capture-engine.ts +931 -0
- package/src/capture-heuristic.ts +177 -0
- package/src/cascade-forget.ts +135 -0
- package/src/chunker.ts +253 -0
- package/src/cli.ts +1917 -0
- package/src/confidence-tracker.ts +166 -0
- package/src/conflict-advisor.ts +433 -0
- package/src/conflict-engine.ts +181 -0
- package/src/conflict-escalation.ts +138 -0
- package/src/conflict-lifecycle.ts +67 -0
- package/src/conflict-output.ts +218 -0
- package/src/conflict-schema.ts +130 -0
- package/src/conflict-store.ts +127 -0
- package/src/consolidation-engine.ts +256 -0
- package/src/context-composer-pins.ts +183 -0
- package/src/context-composer-queries.ts +121 -0
- package/src/context-composer-scope.ts +56 -0
- package/src/context-composer-stable-selection.ts +200 -0
- package/src/context-composer-stable.ts +217 -0
- package/src/context-composer-task-fallbacks.ts +36 -0
- package/src/context-composer-task-ranking.ts +197 -0
- package/src/context-composer-task-results.ts +137 -0
- package/src/context-composer-task-selection.ts +342 -0
- package/src/context-composer-text.ts +57 -0
- package/src/context-composer.ts +300 -0
- package/src/context-renderer.ts +179 -0
- package/src/decay-engine.ts +189 -0
- package/src/doctor.ts +543 -0
- package/src/embedder.ts +557 -0
- package/src/entity-resolver.ts +131 -0
- package/src/eval.ts +632 -0
- package/src/event-segmenter.ts +216 -0
- package/src/ingest.ts +1822 -0
- package/src/kg-extractor.ts +217 -0
- package/src/kg-store.ts +353 -0
- package/src/legacy-scope-review.ts +53 -0
- package/src/llm-client.ts +629 -0
- package/src/llm-consolidation.ts +168 -0
- package/src/mcp-server.ts +1337 -0
- package/src/memory-assets.ts +475 -0
- package/src/memory-boundaries.ts +354 -0
- package/src/memory-health-rebalance.ts +220 -0
- package/src/memory-output.ts +474 -0
- package/src/memory-schema.ts +184 -0
- package/src/multi-vector.ts +234 -0
- package/src/noise-filter.ts +155 -0
- package/src/ppr-traversal.ts +279 -0
- package/src/preference-matcher.ts +174 -0
- package/src/preference-slots.ts +259 -0
- package/src/prospective-memory.ts +198 -0
- package/src/query-entity-detector.ts +207 -0
- package/src/query-expander.ts +98 -0
- package/src/result-synthesizer.ts +114 -0
- package/src/retrieval-profiles.ts +101 -0
- package/src/retrieval-trace.ts +94 -0
- package/src/retriever.ts +1338 -0
- package/src/retroactive-boost.ts +154 -0
- package/src/rif.ts +73 -0
- package/src/runtime-config.ts +172 -0
- package/src/schema-utils.ts +56 -0
- package/src/scope-inventory.ts +310 -0
- package/src/scope-policy.ts +142 -0
- package/src/session-engine.ts +168 -0
- package/src/session-output.ts +96 -0
- package/src/session-schema.ts +60 -0
- package/src/session-store.ts +293 -0
- package/src/stderr-log.ts +16 -0
- package/src/store.ts +903 -0
- package/src/temporal-parser.ts +318 -0
- package/src/term-registry.ts +791 -0
- package/src/tool-output-compressor.ts +115 -0
- package/src/tracker.ts +57 -0
- package/src/ui-server.ts +430 -0
- package/src/version-manager.ts +172 -0
- package/src/workflow-observation-engine.ts +316 -0
- package/src/workflow-observation-managed.ts +83 -0
- package/src/workflow-observation-output.ts +86 -0
- package/src/workflow-observation-schema.ts +87 -0
- package/src/workflow-observation-scope-review.ts +409 -0
- package/src/workflow-observation-store.ts +69 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import type { MemoryEntry } from "./store.js";
|
|
2
|
+
import type { RetrievalResult } from "./retriever.js";
|
|
3
|
+
import type { RetrievalProfileName } from "./retrieval-profiles.js";
|
|
4
|
+
import { extractMemoryProvenance } from "./memory-boundaries.js";
|
|
5
|
+
|
|
6
|
+
interface MemoryMetadata {
|
|
7
|
+
source?: string;
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
file?: string;
|
|
10
|
+
heading?: string;
|
|
11
|
+
preferenceSlot?: {
|
|
12
|
+
type?: string;
|
|
13
|
+
brand?: string;
|
|
14
|
+
item?: string;
|
|
15
|
+
traits?: string[];
|
|
16
|
+
preferredTool?: string;
|
|
17
|
+
avoidedTool?: string;
|
|
18
|
+
};
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface RenderContext {
|
|
23
|
+
query: string;
|
|
24
|
+
profile: RetrievalProfileName;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface DistilledSourceSummary {
|
|
28
|
+
source: string;
|
|
29
|
+
hits: number;
|
|
30
|
+
newest: string;
|
|
31
|
+
files: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface DistilledEvidence {
|
|
35
|
+
memoryId: string;
|
|
36
|
+
source: string;
|
|
37
|
+
scope: string;
|
|
38
|
+
date: string;
|
|
39
|
+
retrievalPath: string;
|
|
40
|
+
snippet: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface DistilledSummary {
|
|
44
|
+
query: string;
|
|
45
|
+
profile: RetrievalProfileName;
|
|
46
|
+
hits: number;
|
|
47
|
+
sources: DistilledSourceSummary[];
|
|
48
|
+
takeaways: string[];
|
|
49
|
+
evidence: DistilledEvidence[];
|
|
50
|
+
reusableCandidates: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseMetadata(entry: MemoryEntry): MemoryMetadata {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(entry.metadata || "{}") as MemoryMetadata;
|
|
56
|
+
} catch {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getDateLabel(timestamp: number): string {
|
|
62
|
+
if (!timestamp) return "unknown";
|
|
63
|
+
return new Date(timestamp).toISOString().split("T")[0] || "unknown";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getSourceLabel(result: RetrievalResult): string {
|
|
67
|
+
const meta = parseMetadata(result.entry);
|
|
68
|
+
return String(meta.source || result.entry.scope || "?");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getCategoryLabel(result: RetrievalResult): string {
|
|
72
|
+
return result.entry.category || "other";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getTierLabel(result: RetrievalResult): string {
|
|
76
|
+
const meta = parseMetadata(result.entry);
|
|
77
|
+
return String(meta.tier || "peripheral");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getProvenanceSummary(result: RetrievalResult): string {
|
|
81
|
+
const provenance = extractMemoryProvenance({
|
|
82
|
+
scope: result.entry.scope,
|
|
83
|
+
metadata: result.entry.metadata,
|
|
84
|
+
});
|
|
85
|
+
const boundary = provenance.boundary;
|
|
86
|
+
const meta = parseMetadata(result.entry);
|
|
87
|
+
const parts = [
|
|
88
|
+
boundary
|
|
89
|
+
? `${boundary.layer}/${boundary.authority}`
|
|
90
|
+
: result.entry.scope.startsWith("memory:") || result.entry.scope.startsWith("asset:")
|
|
91
|
+
? "durable/?"
|
|
92
|
+
: result.entry.scope.startsWith("cc:") || result.entry.scope.startsWith("codex:") || result.entry.scope.startsWith("gemini:")
|
|
93
|
+
? "evidence/?"
|
|
94
|
+
: "-",
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
if (boundary?.downgradedFrom) {
|
|
98
|
+
parts.push(`downgraded:${boundary.downgradedFrom}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (provenance.canonicalKey) {
|
|
102
|
+
parts.push(`key:${provenance.canonicalKey}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (provenance.promotedFrom) {
|
|
106
|
+
const promotedBoundary = provenance.promotedFrom.boundary;
|
|
107
|
+
const promotedLabel = promotedBoundary
|
|
108
|
+
? `${promotedBoundary.layer}/${promotedBoundary.authority}`
|
|
109
|
+
: "-";
|
|
110
|
+
parts.push(`promoted:${provenance.promotedFrom.memoryId.slice(0, 8)}<-${promotedLabel}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const hasObservationHistory =
|
|
114
|
+
provenance.provenanceHistoryCount > 1 ||
|
|
115
|
+
provenance.provenanceHistory.some((item) => typeof item.observedAt === "string");
|
|
116
|
+
if (hasObservationHistory) {
|
|
117
|
+
parts.push(`history:${provenance.provenanceHistoryCount}`);
|
|
118
|
+
const latestObservation = [...provenance.provenanceHistory]
|
|
119
|
+
.reverse()
|
|
120
|
+
.find((item) => typeof item.observedAt === "string");
|
|
121
|
+
if (latestObservation?.observedAt) {
|
|
122
|
+
parts.push(`observed:${latestObservation.memoryId.slice(0, 8)}@${latestObservation.observedAt.slice(0, 10)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const preferenceSlot = meta.preferenceSlot;
|
|
127
|
+
if (
|
|
128
|
+
preferenceSlot?.type === "brand-item" &&
|
|
129
|
+
typeof preferenceSlot.brand === "string" &&
|
|
130
|
+
typeof preferenceSlot.item === "string"
|
|
131
|
+
) {
|
|
132
|
+
parts.push(`slot:${preferenceSlot.type}:${preferenceSlot.brand}:${preferenceSlot.item}`);
|
|
133
|
+
} else if (
|
|
134
|
+
preferenceSlot?.type === "reply-style" &&
|
|
135
|
+
Array.isArray(preferenceSlot.traits) &&
|
|
136
|
+
preferenceSlot.traits.length > 0
|
|
137
|
+
) {
|
|
138
|
+
parts.push(`slot:${preferenceSlot.type}:${preferenceSlot.traits.join(":")}`);
|
|
139
|
+
} else if (
|
|
140
|
+
preferenceSlot?.type === "tool-choice" &&
|
|
141
|
+
typeof preferenceSlot.preferredTool === "string" &&
|
|
142
|
+
typeof preferenceSlot.avoidedTool === "string"
|
|
143
|
+
) {
|
|
144
|
+
parts.push(`slot:${preferenceSlot.type}:${preferenceSlot.preferredTool}:over:${preferenceSlot.avoidedTool}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return parts.join(" | ");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function selectBriefSeedResults(results: RetrievalResult[]): RetrievalResult[] {
|
|
151
|
+
const directResults = results.filter((result) => getSourceLabel(result) !== "asset");
|
|
152
|
+
return directResults.length > 0 ? directResults : results;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function getFileLabel(result: RetrievalResult): string {
|
|
156
|
+
const meta = parseMetadata(result.entry);
|
|
157
|
+
return String(meta.file || meta.heading || "-");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getSessionLabel(result: RetrievalResult): string {
|
|
161
|
+
const meta = parseMetadata(result.entry);
|
|
162
|
+
return String(meta.sessionId || result.entry.scope || "-");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getRetrievalPath(result: RetrievalResult): string {
|
|
166
|
+
const parts: string[] = [];
|
|
167
|
+
if (result.sources.vector) parts.push("vector");
|
|
168
|
+
if (result.sources.bm25) parts.push("bm25");
|
|
169
|
+
if (result.sources.reranked) parts.push("reranked");
|
|
170
|
+
return parts.join("+") || "direct";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function cleanSnippet(text: string, maxLen = 180): string {
|
|
174
|
+
const compact = text.replace(/\s+/g, " ").trim();
|
|
175
|
+
if (compact.length <= maxLen) return compact;
|
|
176
|
+
return `${compact.slice(0, maxLen - 3)}...`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function extractTerms(query: string): string[] {
|
|
180
|
+
const matches = query.match(/[\p{Script=Han}]{2,}|[a-z0-9._/-]{3,}/giu) || [];
|
|
181
|
+
return Array.from(new Set(matches.map(term => term.toLowerCase()))).slice(0, 8);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function findMatchedTerms(query: string, text: string): string[] {
|
|
185
|
+
const haystack = text.toLowerCase();
|
|
186
|
+
return extractTerms(query).filter(term => haystack.includes(term));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function splitSentences(text: string): string[] {
|
|
190
|
+
return text
|
|
191
|
+
.split(/(?<=[。!?.!?])\s+|\n+/)
|
|
192
|
+
.map(part => part.trim())
|
|
193
|
+
.filter(Boolean);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function pickBestSnippet(query: string, text: string): string {
|
|
197
|
+
const terms = extractTerms(query);
|
|
198
|
+
const sentences = splitSentences(text);
|
|
199
|
+
if (sentences.length === 0) return cleanSnippet(text);
|
|
200
|
+
|
|
201
|
+
let bestSentence = sentences[0] || text;
|
|
202
|
+
let bestScore = -1;
|
|
203
|
+
|
|
204
|
+
for (const sentence of sentences) {
|
|
205
|
+
const lower = sentence.toLowerCase();
|
|
206
|
+
const score = terms.reduce((sum, term) => sum + (lower.includes(term) ? 1 : 0), 0);
|
|
207
|
+
if (score > bestScore) {
|
|
208
|
+
bestSentence = sentence;
|
|
209
|
+
bestScore = score;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return cleanSnippet(bestSentence);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function normalizeRecallText(result: RetrievalResult): string {
|
|
217
|
+
const source = getSourceLabel(result);
|
|
218
|
+
if (source !== "asset") return result.entry.text;
|
|
219
|
+
|
|
220
|
+
return result.entry.text
|
|
221
|
+
.replace(/^\[(Pinned Asset|Memory Brief)\]\s*/i, "")
|
|
222
|
+
.replace(/\bSummary:\s*/gi, "")
|
|
223
|
+
.replace(/\bSnippet:\s*/gi, "")
|
|
224
|
+
.replace(/\bOriginal Scope:.*$/gim, "")
|
|
225
|
+
.replace(/\bTags:.*$/gim, "")
|
|
226
|
+
.replace(/\bSources:\s*/gi, "")
|
|
227
|
+
.replace(/\bReusable:\s*/gi, "")
|
|
228
|
+
.replace(/\bTakeaways:\s*/gi, "")
|
|
229
|
+
.replace(/\bProfile:\s*/gi, "")
|
|
230
|
+
.replace(/\bQuery:\s*/gi, "")
|
|
231
|
+
.replace(/\n{2,}/g, "\n")
|
|
232
|
+
.trim();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function ageDays(timestamp: number): number | null {
|
|
236
|
+
if (!timestamp) return null;
|
|
237
|
+
return Math.max(0, (Date.now() - timestamp) / 86_400_000);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function buildWhyMatched(query: string, result: RetrievalResult): string {
|
|
241
|
+
const reasons: string[] = [];
|
|
242
|
+
const matchedTerms = findMatchedTerms(query, result.entry.text);
|
|
243
|
+
const meta = parseMetadata(result.entry);
|
|
244
|
+
|
|
245
|
+
if (result.sources.vector && result.sources.bm25) {
|
|
246
|
+
reasons.push("semantic+keyword");
|
|
247
|
+
} else if (result.sources.vector) {
|
|
248
|
+
reasons.push("semantic");
|
|
249
|
+
} else if (result.sources.bm25) {
|
|
250
|
+
reasons.push("keyword");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (result.sources.reranked) {
|
|
254
|
+
reasons.push("reranked");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (matchedTerms.length > 0) {
|
|
258
|
+
reasons.push(`terms:${matchedTerms.slice(0, 3).join(",")}`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const days = ageDays(result.entry.timestamp);
|
|
262
|
+
if (days !== null && days <= 14) {
|
|
263
|
+
reasons.push(`fresh:${Math.round(days)}d`);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if ((result.entry.importance || 0) >= 0.7) {
|
|
267
|
+
reasons.push("important");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (meta.heading) {
|
|
271
|
+
reasons.push(`heading:${String(meta.heading).slice(0, 24)}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return reasons.join(" | ") || "retrieved";
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function buildSearchRow(index: number, query: string, result: RetrievalResult): string[] {
|
|
278
|
+
return [
|
|
279
|
+
String(index + 1).padEnd(2),
|
|
280
|
+
result.entry.id.slice(0, 8).padEnd(8),
|
|
281
|
+
`${(result.score * 100).toFixed(0)}%`.padEnd(5),
|
|
282
|
+
getCategoryLabel(result).padEnd(12),
|
|
283
|
+
getTierLabel(result).padEnd(10),
|
|
284
|
+
getSourceLabel(result).padEnd(7),
|
|
285
|
+
getDateLabel(result.entry.timestamp),
|
|
286
|
+
getRetrievalPath(result).padEnd(20),
|
|
287
|
+
getFileLabel(result),
|
|
288
|
+
cleanSnippet(pickBestSnippet(query, result.entry.text), 120),
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function formatSearchResults(
|
|
293
|
+
results: RetrievalResult[],
|
|
294
|
+
context: RenderContext,
|
|
295
|
+
): string {
|
|
296
|
+
if (results.length === 0) return "No results found.";
|
|
297
|
+
|
|
298
|
+
const lines = [
|
|
299
|
+
`Query : ${context.query}`,
|
|
300
|
+
`Profile : ${context.profile}`,
|
|
301
|
+
`Hits : ${results.length}`,
|
|
302
|
+
"",
|
|
303
|
+
"# ID Score Category Tier Source Date Retrieval Path File / Snippet",
|
|
304
|
+
"-- -------- ----- ------------ ---------- ------- ---------- -------------------- --------------",
|
|
305
|
+
];
|
|
306
|
+
|
|
307
|
+
for (let i = 0; i < results.length; i++) {
|
|
308
|
+
const row = buildSearchRow(i, context.query, results[i]);
|
|
309
|
+
lines.push(`${row[0]} ${row[1]} ${row[2]} ${row[3]} ${row[4]} ${row[5]} ${row[6]} ${row[7]} ${row[8]} | ${row[9]}`);
|
|
310
|
+
lines.push(` prov : ${getProvenanceSummary(results[i])}`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return lines.join("\n");
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function formatExplainResults(
|
|
317
|
+
results: RetrievalResult[],
|
|
318
|
+
context: RenderContext,
|
|
319
|
+
): string {
|
|
320
|
+
if (results.length === 0) return "No results found.";
|
|
321
|
+
|
|
322
|
+
const lines = [
|
|
323
|
+
`Query : ${context.query}`,
|
|
324
|
+
`Profile : ${context.profile}`,
|
|
325
|
+
`Hits : ${results.length}`,
|
|
326
|
+
"",
|
|
327
|
+
"# Explain",
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
for (let i = 0; i < results.length; i++) {
|
|
331
|
+
const result = results[i];
|
|
332
|
+
const score = `${(result.score * 100).toFixed(0)}%`;
|
|
333
|
+
const retrieval = getRetrievalPath(result);
|
|
334
|
+
const file = getFileLabel(result);
|
|
335
|
+
const session = getSessionLabel(result);
|
|
336
|
+
const why = buildWhyMatched(context.query, result);
|
|
337
|
+
|
|
338
|
+
lines.push(`${i + 1}. ${result.entry.id.slice(0, 8)} | ${score} | ${getSourceLabel(result)} | ${getDateLabel(result.entry.timestamp)}`);
|
|
339
|
+
lines.push(` category: ${getCategoryLabel(result)}`);
|
|
340
|
+
lines.push(` tier : ${getTierLabel(result)}`);
|
|
341
|
+
lines.push(` path : ${retrieval}`);
|
|
342
|
+
lines.push(` session : ${session}`);
|
|
343
|
+
lines.push(` file : ${file}`);
|
|
344
|
+
lines.push(` prov : ${getProvenanceSummary(result)}`);
|
|
345
|
+
lines.push(` why : ${why}`);
|
|
346
|
+
lines.push(` snippet : ${pickBestSnippet(context.query, result.entry.text)}`);
|
|
347
|
+
lines.push("");
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return lines.join("\n").trimEnd();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export function summarizeResults(
|
|
354
|
+
results: RetrievalResult[],
|
|
355
|
+
context: RenderContext,
|
|
356
|
+
): DistilledSummary {
|
|
357
|
+
if (results.length === 0) {
|
|
358
|
+
return {
|
|
359
|
+
query: context.query,
|
|
360
|
+
profile: context.profile,
|
|
361
|
+
hits: 0,
|
|
362
|
+
sources: [],
|
|
363
|
+
takeaways: [],
|
|
364
|
+
evidence: [],
|
|
365
|
+
reusableCandidates: [],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const sourceMap = new Map<string, { hits: number; newest: number; files: Set<string> }>();
|
|
370
|
+
const topTakeaways: string[] = [];
|
|
371
|
+
const evidence: DistilledEvidence[] = [];
|
|
372
|
+
const reusable: string[] = [];
|
|
373
|
+
const seenTakeaways = new Set<string>();
|
|
374
|
+
const seenReusable = new Set<string>();
|
|
375
|
+
|
|
376
|
+
for (const result of results) {
|
|
377
|
+
const source = getSourceLabel(result);
|
|
378
|
+
const file = getFileLabel(result);
|
|
379
|
+
const bucket = sourceMap.get(source) || { hits: 0, newest: 0, files: new Set<string>() };
|
|
380
|
+
bucket.hits += 1;
|
|
381
|
+
bucket.newest = Math.max(bucket.newest, result.entry.timestamp || 0);
|
|
382
|
+
if (file !== "-") bucket.files.add(file);
|
|
383
|
+
sourceMap.set(source, bucket);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
for (const result of results) {
|
|
387
|
+
const takeaway = `${getSourceLabel(result)}: ${pickBestSnippet(context.query, normalizeRecallText(result))}`;
|
|
388
|
+
if (!seenTakeaways.has(takeaway)) {
|
|
389
|
+
topTakeaways.push(takeaway);
|
|
390
|
+
seenTakeaways.add(takeaway);
|
|
391
|
+
}
|
|
392
|
+
if (topTakeaways.length >= 4) break;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
for (const result of results.slice(0, 5)) {
|
|
396
|
+
evidence.push({
|
|
397
|
+
memoryId: result.entry.id,
|
|
398
|
+
source: getSourceLabel(result),
|
|
399
|
+
scope: result.entry.scope,
|
|
400
|
+
date: getDateLabel(result.entry.timestamp),
|
|
401
|
+
retrievalPath: getRetrievalPath(result),
|
|
402
|
+
snippet: pickBestSnippet(context.query, normalizeRecallText(result)),
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
for (const result of results) {
|
|
407
|
+
const candidate = pickBestSnippet(context.query, normalizeRecallText(result));
|
|
408
|
+
if (candidate.length < 20) continue;
|
|
409
|
+
if (seenReusable.has(candidate)) continue;
|
|
410
|
+
reusable.push(candidate);
|
|
411
|
+
seenReusable.add(candidate);
|
|
412
|
+
if (reusable.length >= 3) break;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const sources = Array.from(sourceMap.entries())
|
|
416
|
+
.sort((a, b) => b[1].hits - a[1].hits)
|
|
417
|
+
.map(([source, stats]) => ({
|
|
418
|
+
source,
|
|
419
|
+
hits: stats.hits,
|
|
420
|
+
newest: getDateLabel(stats.newest),
|
|
421
|
+
files: Array.from(stats.files).slice(0, 3),
|
|
422
|
+
}));
|
|
423
|
+
|
|
424
|
+
return {
|
|
425
|
+
query: context.query,
|
|
426
|
+
profile: context.profile,
|
|
427
|
+
hits: results.length,
|
|
428
|
+
sources,
|
|
429
|
+
takeaways: topTakeaways,
|
|
430
|
+
evidence,
|
|
431
|
+
reusableCandidates: reusable,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function distillResults(
|
|
436
|
+
results: RetrievalResult[],
|
|
437
|
+
context: RenderContext,
|
|
438
|
+
): string {
|
|
439
|
+
const summary = summarizeResults(results, context);
|
|
440
|
+
if (summary.hits === 0) return "No results found.";
|
|
441
|
+
|
|
442
|
+
const lines = [
|
|
443
|
+
`Query : ${context.query}`,
|
|
444
|
+
`Profile : ${context.profile}`,
|
|
445
|
+
`Hits : ${summary.hits}`,
|
|
446
|
+
"",
|
|
447
|
+
"Source Map",
|
|
448
|
+
"Source Hits Newest Files",
|
|
449
|
+
"---------- ----- ---------- ------------------------------",
|
|
450
|
+
];
|
|
451
|
+
|
|
452
|
+
for (const item of summary.sources) {
|
|
453
|
+
lines.push(
|
|
454
|
+
`${item.source.padEnd(10)} ${String(item.hits).padEnd(5)} ${item.newest.padEnd(10)} ${item.files.join(", ") || "-"}`,
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
lines.push("", "Core Takeaways");
|
|
459
|
+
summary.takeaways.forEach((item, index) => lines.push(`${index + 1}. ${item}`));
|
|
460
|
+
|
|
461
|
+
lines.push("", "Evidence");
|
|
462
|
+
summary.evidence.forEach((item, index) => {
|
|
463
|
+
lines.push(`${index + 1}. ${item.source} | ${item.date} | ${item.retrievalPath} | ${item.snippet}`);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
lines.push("", "Reusable Memory Candidates");
|
|
467
|
+
if (summary.reusableCandidates.length === 0) {
|
|
468
|
+
lines.push("1. No strong reusable memory candidate yet. Expand the query or use a broader profile.");
|
|
469
|
+
} else {
|
|
470
|
+
summary.reusableCandidates.forEach((item, index) => lines.push(`${index + 1}. ${item}`));
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return lines.join("\n");
|
|
474
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { boundedStringSchema, identifierSchema, normalizedStringListSchema, optionalBoundedStringSchema } from "./schema-utils.js";
|
|
4
|
+
|
|
5
|
+
export const DURABLE_MEMORY_CATEGORIES = [
|
|
6
|
+
"profile",
|
|
7
|
+
"preferences",
|
|
8
|
+
"entities",
|
|
9
|
+
"events",
|
|
10
|
+
"cases",
|
|
11
|
+
"patterns",
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export const LEGACY_MEMORY_CATEGORIES = [
|
|
15
|
+
"preference",
|
|
16
|
+
"fact",
|
|
17
|
+
"decision",
|
|
18
|
+
"entity",
|
|
19
|
+
"other",
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
export const ALL_MEMORY_CATEGORIES = [
|
|
23
|
+
...DURABLE_MEMORY_CATEGORIES,
|
|
24
|
+
...LEGACY_MEMORY_CATEGORIES,
|
|
25
|
+
] as const;
|
|
26
|
+
|
|
27
|
+
export const STORE_MEMORY_SOURCES = ["manual", "agent", "api"] as const;
|
|
28
|
+
|
|
29
|
+
export const DurableMemoryCategorySchema = z.enum(DURABLE_MEMORY_CATEGORIES);
|
|
30
|
+
export const MemoryCategorySchema = z.enum(ALL_MEMORY_CATEGORIES);
|
|
31
|
+
export const StoreMemorySourceSchema = z.enum(STORE_MEMORY_SOURCES);
|
|
32
|
+
export const WriteDispositionSchema = z.enum(["stored", "updated", "deduped", "promoted", "conflict"]);
|
|
33
|
+
|
|
34
|
+
export type DurableMemoryCategory = z.infer<typeof DurableMemoryCategorySchema>;
|
|
35
|
+
export type MemoryCategoryValue = z.infer<typeof MemoryCategorySchema>;
|
|
36
|
+
export type StoreMemorySource = z.infer<typeof StoreMemorySourceSchema>;
|
|
37
|
+
export type WriteDisposition = z.infer<typeof WriteDispositionSchema>;
|
|
38
|
+
|
|
39
|
+
export const MemoryTextSchema = boundedStringSchema("text", 4000);
|
|
40
|
+
export const MemoryScopeSchema = optionalBoundedStringSchema(160);
|
|
41
|
+
export const RequiredMemoryScopeSchema = boundedStringSchema("scope", 160);
|
|
42
|
+
export const MemoryImportanceSchema = z.number().min(0).max(1);
|
|
43
|
+
export const CanonicalKeySchema = optionalBoundedStringSchema(120);
|
|
44
|
+
export const MemoryTagsSchema = normalizedStringListSchema("tags", 8, 40);
|
|
45
|
+
export const WorkflowPatternTitleSchema = boundedStringSchema("title", 120);
|
|
46
|
+
export const WorkflowPatternTriggerSchema = boundedStringSchema("trigger", 240);
|
|
47
|
+
export const WorkflowPatternStepsSchema = normalizedStringListSchema("steps", 8, 220)
|
|
48
|
+
.pipe(z.array(z.string()).min(1, "steps must contain at least 1 item"));
|
|
49
|
+
export const WorkflowPatternOutcomeSchema = optionalBoundedStringSchema(240);
|
|
50
|
+
export const WorkflowPatternToolsSchema = normalizedStringListSchema("tools", 6, 60);
|
|
51
|
+
export const CaseMemoryTitleSchema = boundedStringSchema("title", 120);
|
|
52
|
+
export const CaseMemoryProblemSchema = boundedStringSchema("problem", 320);
|
|
53
|
+
export const CaseMemoryContextSchema = optionalBoundedStringSchema(240);
|
|
54
|
+
export const CaseMemorySolutionStepsSchema = normalizedStringListSchema("solutionSteps", 8, 220)
|
|
55
|
+
.pipe(z.array(z.string()).min(1, "solutionSteps must contain at least 1 item"));
|
|
56
|
+
export const CaseMemoryOutcomeSchema = optionalBoundedStringSchema(240);
|
|
57
|
+
export const CaseMemoryToolsSchema = normalizedStringListSchema("tools", 6, 60);
|
|
58
|
+
|
|
59
|
+
export const StoreMemoryInputSchema = z.object({
|
|
60
|
+
text: MemoryTextSchema,
|
|
61
|
+
category: DurableMemoryCategorySchema.default("events"),
|
|
62
|
+
importance: MemoryImportanceSchema.default(0.7),
|
|
63
|
+
scope: RequiredMemoryScopeSchema,
|
|
64
|
+
source: StoreMemorySourceSchema.default("manual"),
|
|
65
|
+
tags: MemoryTagsSchema,
|
|
66
|
+
canonicalKey: CanonicalKeySchema,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export const StoredMemoryRecordSchema = StoreMemoryInputSchema.extend({
|
|
70
|
+
id: identifierSchema("id", 128),
|
|
71
|
+
resolvedScope: identifierSchema("resolvedScope", 160),
|
|
72
|
+
storedAt: z.string().datetime(),
|
|
73
|
+
disposition: WriteDispositionSchema.default("stored"),
|
|
74
|
+
conflictId: identifierSchema("conflictId", 128).optional(),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const CaptureMemoryItemSchema = z.object({
|
|
78
|
+
text: MemoryTextSchema,
|
|
79
|
+
category: DurableMemoryCategorySchema.default("events"),
|
|
80
|
+
importance: MemoryImportanceSchema.optional(),
|
|
81
|
+
scope: MemoryScopeSchema,
|
|
82
|
+
source: StoreMemorySourceSchema.optional(),
|
|
83
|
+
tags: MemoryTagsSchema.optional(),
|
|
84
|
+
canonicalKey: CanonicalKeySchema,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
export const CaptureMemoryInputSchema = z.object({
|
|
88
|
+
scope: MemoryScopeSchema,
|
|
89
|
+
source: StoreMemorySourceSchema.default("agent"),
|
|
90
|
+
defaultImportance: MemoryImportanceSchema.default(0.7),
|
|
91
|
+
memories: z.array(CaptureMemoryItemSchema)
|
|
92
|
+
.min(1, "memories must contain at least 1 item")
|
|
93
|
+
.max(20, "memories must contain at most 20 items"),
|
|
94
|
+
}).superRefine((input, ctx) => {
|
|
95
|
+
if (input.scope) return;
|
|
96
|
+
input.memories.forEach((memory, index) => {
|
|
97
|
+
if (!memory.scope) {
|
|
98
|
+
ctx.addIssue({
|
|
99
|
+
code: z.ZodIssueCode.custom,
|
|
100
|
+
path: ["memories", index, "scope"],
|
|
101
|
+
message: "scope is required for each memory when capture scope is not provided",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const WorkflowPatternInputSchema = z.object({
|
|
108
|
+
title: WorkflowPatternTitleSchema,
|
|
109
|
+
trigger: WorkflowPatternTriggerSchema,
|
|
110
|
+
steps: WorkflowPatternStepsSchema,
|
|
111
|
+
outcome: WorkflowPatternOutcomeSchema,
|
|
112
|
+
tools: WorkflowPatternToolsSchema,
|
|
113
|
+
importance: MemoryImportanceSchema.default(0.82),
|
|
114
|
+
scope: RequiredMemoryScopeSchema,
|
|
115
|
+
source: StoreMemorySourceSchema.default("agent"),
|
|
116
|
+
tags: MemoryTagsSchema,
|
|
117
|
+
canonicalKey: CanonicalKeySchema,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const CaseMemoryInputSchema = z.object({
|
|
121
|
+
title: CaseMemoryTitleSchema,
|
|
122
|
+
problem: CaseMemoryProblemSchema,
|
|
123
|
+
context: CaseMemoryContextSchema,
|
|
124
|
+
solutionSteps: CaseMemorySolutionStepsSchema,
|
|
125
|
+
outcome: CaseMemoryOutcomeSchema,
|
|
126
|
+
tools: CaseMemoryToolsSchema,
|
|
127
|
+
importance: MemoryImportanceSchema.default(0.84),
|
|
128
|
+
scope: RequiredMemoryScopeSchema,
|
|
129
|
+
source: StoreMemorySourceSchema.default("agent"),
|
|
130
|
+
tags: MemoryTagsSchema,
|
|
131
|
+
canonicalKey: CanonicalKeySchema,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
export const PromoteMemoryInputSchema = z.object({
|
|
135
|
+
memoryId: identifierSchema("memoryId", 128),
|
|
136
|
+
text: MemoryTextSchema.optional(),
|
|
137
|
+
category: DurableMemoryCategorySchema.optional(),
|
|
138
|
+
importance: MemoryImportanceSchema.default(0.78),
|
|
139
|
+
scope: RequiredMemoryScopeSchema,
|
|
140
|
+
source: StoreMemorySourceSchema.default("agent"),
|
|
141
|
+
tags: MemoryTagsSchema,
|
|
142
|
+
canonicalKey: CanonicalKeySchema,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export const StoredWorkflowPatternRecordSchema = WorkflowPatternInputSchema.extend({
|
|
146
|
+
category: z.literal("patterns"),
|
|
147
|
+
text: MemoryTextSchema,
|
|
148
|
+
id: identifierSchema("id", 128),
|
|
149
|
+
resolvedScope: identifierSchema("resolvedScope", 160),
|
|
150
|
+
storedAt: z.string().datetime(),
|
|
151
|
+
disposition: WriteDispositionSchema.default("stored"),
|
|
152
|
+
conflictId: identifierSchema("conflictId", 128).optional(),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
export const StoredCaseMemoryRecordSchema = CaseMemoryInputSchema.extend({
|
|
156
|
+
category: z.literal("cases"),
|
|
157
|
+
text: MemoryTextSchema,
|
|
158
|
+
id: identifierSchema("id", 128),
|
|
159
|
+
resolvedScope: identifierSchema("resolvedScope", 160),
|
|
160
|
+
storedAt: z.string().datetime(),
|
|
161
|
+
disposition: WriteDispositionSchema.default("stored"),
|
|
162
|
+
conflictId: identifierSchema("conflictId", 128).optional(),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
export const StoredPromotedMemoryRecordSchema = StoreMemoryInputSchema.extend({
|
|
166
|
+
id: identifierSchema("id", 128),
|
|
167
|
+
resolvedScope: identifierSchema("resolvedScope", 160),
|
|
168
|
+
storedAt: z.string().datetime(),
|
|
169
|
+
disposition: WriteDispositionSchema.default("promoted"),
|
|
170
|
+
sourceMemoryId: identifierSchema("sourceMemoryId", 128),
|
|
171
|
+
sourceCategory: MemoryCategorySchema,
|
|
172
|
+
conflictId: identifierSchema("conflictId", 128).optional(),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export type StoreMemoryInput = z.infer<typeof StoreMemoryInputSchema>;
|
|
176
|
+
export type StoredMemoryRecord = z.infer<typeof StoredMemoryRecordSchema>;
|
|
177
|
+
export type CaptureMemoryItem = z.infer<typeof CaptureMemoryItemSchema>;
|
|
178
|
+
export type CaptureMemoryInput = z.infer<typeof CaptureMemoryInputSchema>;
|
|
179
|
+
export type WorkflowPatternInput = z.infer<typeof WorkflowPatternInputSchema>;
|
|
180
|
+
export type StoredWorkflowPatternRecord = z.infer<typeof StoredWorkflowPatternRecordSchema>;
|
|
181
|
+
export type CaseMemoryInput = z.infer<typeof CaseMemoryInputSchema>;
|
|
182
|
+
export type StoredCaseMemoryRecord = z.infer<typeof StoredCaseMemoryRecordSchema>;
|
|
183
|
+
export type PromoteMemoryInput = z.infer<typeof PromoteMemoryInputSchema>;
|
|
184
|
+
export type StoredPromotedMemoryRecord = z.infer<typeof StoredPromotedMemoryRecordSchema>;
|