@duetso/agent 0.2.6 → 0.3.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/README.md +29 -16
- package/dist/package.json +8 -3
- package/dist/src/cli/auto-upgrade.d.ts.map +1 -1
- package/dist/src/cli/auto-upgrade.js +7 -54
- package/dist/src/cli/auto-upgrade.js.map +1 -1
- package/dist/src/cli/connect.d.ts +45 -0
- package/dist/src/cli/connect.d.ts.map +1 -0
- package/dist/src/cli/connect.js +265 -0
- package/dist/src/cli/connect.js.map +1 -0
- package/dist/src/cli/help.d.ts +1 -0
- package/dist/src/cli/help.d.ts.map +1 -1
- package/dist/src/cli/help.js +66 -32
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/memory-add.d.ts +18 -13
- package/dist/src/cli/memory-add.d.ts.map +1 -1
- package/dist/src/cli/memory-add.js +91 -32
- package/dist/src/cli/memory-add.js.map +1 -1
- package/dist/src/cli/memory-recall.d.ts.map +1 -1
- package/dist/src/cli/memory-recall.js +3 -0
- package/dist/src/cli/memory-recall.js.map +1 -1
- package/dist/src/cli/memory-sources.d.ts +20 -0
- package/dist/src/cli/memory-sources.d.ts.map +1 -0
- package/dist/src/cli/memory-sources.js +40 -0
- package/dist/src/cli/memory-sources.js.map +1 -0
- package/dist/src/cli/model.d.ts +5 -0
- package/dist/src/cli/model.d.ts.map +1 -1
- package/dist/src/cli/model.js +43 -0
- package/dist/src/cli/model.js.map +1 -1
- package/dist/src/cli/route.d.ts +12 -0
- package/dist/src/cli/route.d.ts.map +1 -1
- package/dist/src/cli/route.js +39 -9
- package/dist/src/cli/route.js.map +1 -1
- package/dist/src/cli/rpc.d.ts +3 -2
- package/dist/src/cli/rpc.d.ts.map +1 -1
- package/dist/src/cli/rpc.js +3 -2
- package/dist/src/cli/rpc.js.map +1 -1
- package/dist/src/cli/run.d.ts +1 -0
- package/dist/src/cli/run.d.ts.map +1 -1
- package/dist/src/cli/run.js +1 -0
- package/dist/src/cli/run.js.map +1 -1
- package/dist/src/cli/shared.d.ts +11 -0
- package/dist/src/cli/shared.d.ts.map +1 -1
- package/dist/src/cli/shared.js +31 -0
- package/dist/src/cli/shared.js.map +1 -1
- package/dist/src/cli/train.d.ts +31 -7
- package/dist/src/cli/train.d.ts.map +1 -1
- package/dist/src/cli/train.js +233 -79
- package/dist/src/cli/train.js.map +1 -1
- package/dist/src/cli.d.ts +3 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +9 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/connected-providers/billing.d.ts +6 -0
- package/dist/src/connected-providers/billing.d.ts.map +1 -0
- package/dist/src/connected-providers/billing.js +11 -0
- package/dist/src/connected-providers/billing.js.map +1 -0
- package/dist/src/connected-providers/capability-probe.d.ts +17 -0
- package/dist/src/connected-providers/capability-probe.d.ts.map +1 -0
- package/dist/src/connected-providers/capability-probe.js +92 -0
- package/dist/src/connected-providers/capability-probe.js.map +1 -0
- package/dist/src/connected-providers/fake-issuer.d.ts +61 -0
- package/dist/src/connected-providers/fake-issuer.d.ts.map +1 -0
- package/dist/src/connected-providers/fake-issuer.js +161 -0
- package/dist/src/connected-providers/fake-issuer.js.map +1 -0
- package/dist/src/connected-providers/fallback-notice.d.ts +11 -0
- package/dist/src/connected-providers/fallback-notice.d.ts.map +1 -0
- package/dist/src/connected-providers/fallback-notice.js +20 -0
- package/dist/src/connected-providers/fallback-notice.js.map +1 -0
- package/dist/src/connected-providers/fallback.d.ts +11 -0
- package/dist/src/connected-providers/fallback.d.ts.map +1 -0
- package/dist/src/connected-providers/fallback.js +37 -0
- package/dist/src/connected-providers/fallback.js.map +1 -0
- package/dist/src/connected-providers/refresh.d.ts +12 -0
- package/dist/src/connected-providers/refresh.d.ts.map +1 -0
- package/dist/src/connected-providers/refresh.js +72 -0
- package/dist/src/connected-providers/refresh.js.map +1 -0
- package/dist/src/connected-providers/registry.d.ts +17 -0
- package/dist/src/connected-providers/registry.d.ts.map +1 -0
- package/dist/src/connected-providers/registry.js +30 -0
- package/dist/src/connected-providers/registry.js.map +1 -0
- package/dist/src/connected-providers/store.d.ts +41 -0
- package/dist/src/connected-providers/store.d.ts.map +1 -0
- package/dist/src/connected-providers/store.js +145 -0
- package/dist/src/connected-providers/store.js.map +1 -0
- package/dist/src/connected-providers/tokens.d.ts +42 -0
- package/dist/src/connected-providers/tokens.d.ts.map +1 -0
- package/dist/src/connected-providers/tokens.js +148 -0
- package/dist/src/connected-providers/tokens.js.map +1 -0
- package/dist/src/connected-providers/transport-preference.d.ts +26 -0
- package/dist/src/connected-providers/transport-preference.d.ts.map +1 -0
- package/dist/src/connected-providers/transport-preference.js +42 -0
- package/dist/src/connected-providers/transport-preference.js.map +1 -0
- package/dist/src/core/structured-output.d.ts.map +1 -1
- package/dist/src/core/structured-output.js +2 -1
- package/dist/src/core/structured-output.js.map +1 -1
- package/dist/src/file-lock.d.ts +22 -0
- package/dist/src/file-lock.d.ts.map +1 -0
- package/dist/src/file-lock.js +69 -0
- package/dist/src/file-lock.js.map +1 -0
- package/dist/src/memory/context-pack.d.ts +5 -0
- package/dist/src/memory/context-pack.d.ts.map +1 -1
- package/dist/src/memory/context-pack.js +6 -0
- package/dist/src/memory/context-pack.js.map +1 -1
- package/dist/src/memory/id.d.ts +3 -0
- package/dist/src/memory/id.d.ts.map +1 -0
- package/dist/src/memory/id.js +6 -0
- package/dist/src/memory/id.js.map +1 -0
- package/dist/src/memory/observational-prompts.d.ts +2 -0
- package/dist/src/memory/observational-prompts.d.ts.map +1 -1
- package/dist/src/memory/observational-prompts.js +4 -2
- package/dist/src/memory/observational-prompts.js.map +1 -1
- package/dist/src/memory/observational.d.ts +22 -0
- package/dist/src/memory/observational.d.ts.map +1 -1
- package/dist/src/memory/observational.js +65 -22
- package/dist/src/memory/observational.js.map +1 -1
- package/dist/src/memory/paths.d.ts +9 -0
- package/dist/src/memory/paths.d.ts.map +1 -0
- package/dist/src/memory/paths.js +11 -0
- package/dist/src/memory/paths.js.map +1 -0
- package/dist/src/memory/storage.d.ts.map +1 -1
- package/dist/src/memory/storage.js +1 -4
- package/dist/src/memory/storage.js.map +1 -1
- package/dist/src/memory/store/discovery.d.ts +7 -0
- package/dist/src/memory/store/discovery.d.ts.map +1 -0
- package/dist/src/memory/store/discovery.js +34 -0
- package/dist/src/memory/store/discovery.js.map +1 -0
- package/dist/src/memory/store/file.d.ts +52 -0
- package/dist/src/memory/store/file.d.ts.map +1 -0
- package/dist/src/memory/store/file.js +287 -0
- package/dist/src/memory/store/file.js.map +1 -0
- package/dist/src/memory/store/index.d.ts +5 -0
- package/dist/src/memory/store/index.d.ts.map +1 -0
- package/dist/src/memory/store/index.js +5 -0
- package/dist/src/memory/store/index.js.map +1 -0
- package/dist/src/memory/store/pack.d.ts +25 -0
- package/dist/src/memory/store/pack.d.ts.map +1 -0
- package/dist/src/memory/store/pack.js +71 -0
- package/dist/src/memory/store/pack.js.map +1 -0
- package/dist/src/memory/store/sources.d.ts +55 -0
- package/dist/src/memory/store/sources.d.ts.map +1 -0
- package/dist/src/memory/store/sources.js +85 -0
- package/dist/src/memory/store/sources.js.map +1 -0
- package/dist/src/memory/store/store.d.ts +46 -0
- package/dist/src/memory/store/store.d.ts.map +1 -0
- package/dist/src/memory/store/store.js +171 -0
- package/dist/src/memory/store/store.js.map +1 -0
- package/dist/src/memory/store.d.ts +19 -16
- package/dist/src/memory/store.d.ts.map +1 -1
- package/dist/src/memory/store.js +14 -11
- package/dist/src/memory/store.js.map +1 -1
- package/dist/src/memory-store.js +554 -0
- package/dist/src/model-resolution/catalog.d.ts +24 -10
- package/dist/src/model-resolution/catalog.d.ts.map +1 -1
- package/dist/src/model-resolution/catalog.js +61 -36
- package/dist/src/model-resolution/catalog.js.map +1 -1
- package/dist/src/model-resolution/duet-gateway.d.ts +2 -0
- package/dist/src/model-resolution/duet-gateway.d.ts.map +1 -1
- package/dist/src/model-resolution/duet-gateway.js +57 -4
- package/dist/src/model-resolution/duet-gateway.js.map +1 -1
- package/dist/src/model-resolution/resolver.d.ts +17 -0
- package/dist/src/model-resolution/resolver.d.ts.map +1 -1
- package/dist/src/model-resolution/resolver.js +49 -4
- package/dist/src/model-resolution/resolver.js.map +1 -1
- package/dist/src/model-routing/advisor-context.d.ts +31 -5
- package/dist/src/model-routing/advisor-context.d.ts.map +1 -1
- package/dist/src/model-routing/advisor-context.js +87 -10
- package/dist/src/model-routing/advisor-context.js.map +1 -1
- package/dist/src/model-routing/advisor-lifecycle.d.ts +14 -5
- package/dist/src/model-routing/advisor-lifecycle.d.ts.map +1 -1
- package/dist/src/model-routing/advisor-lifecycle.js +24 -7
- package/dist/src/model-routing/advisor-lifecycle.js.map +1 -1
- package/dist/src/model-routing/prompts.d.ts.map +1 -1
- package/dist/src/model-routing/prompts.js +18 -10
- package/dist/src/model-routing/prompts.js.map +1 -1
- package/dist/src/model-routing/table.js +18 -18
- package/dist/src/model-routing/table.js.map +1 -1
- package/dist/src/session/session-manager.d.ts +1 -4
- package/dist/src/session/session-manager.d.ts.map +1 -1
- package/dist/src/session/session-manager.js +2 -5
- package/dist/src/session/session-manager.js.map +1 -1
- package/dist/src/session/session.d.ts +2 -2
- package/dist/src/session/session.d.ts.map +1 -1
- package/dist/src/session/session.js +10 -7
- package/dist/src/session/session.js.map +1 -1
- package/dist/src/train/archive.d.ts.map +1 -1
- package/dist/src/train/archive.js +5 -0
- package/dist/src/train/archive.js.map +1 -1
- package/dist/src/train/types.d.ts +8 -7
- package/dist/src/train/types.d.ts.map +1 -1
- package/dist/src/tui/sidebar.d.ts.map +1 -1
- package/dist/src/tui/sidebar.js +40 -1
- package/dist/src/tui/sidebar.js.map +1 -1
- package/dist/src/turn-runner/agent-events.d.ts +2 -0
- package/dist/src/turn-runner/agent-events.d.ts.map +1 -1
- package/dist/src/turn-runner/agent-events.js +11 -0
- package/dist/src/turn-runner/agent-events.js.map +1 -1
- package/dist/src/turn-runner/subagent.d.ts +4 -1
- package/dist/src/turn-runner/subagent.d.ts.map +1 -1
- package/dist/src/turn-runner/subagent.js +11 -3
- package/dist/src/turn-runner/subagent.js.map +1 -1
- package/dist/src/turn-runner/tools.d.ts +3 -3
- package/dist/src/turn-runner/tools.d.ts.map +1 -1
- package/dist/src/turn-runner/tools.js +1 -1
- package/dist/src/turn-runner/tools.js.map +1 -1
- package/dist/src/turn-runner/turn-runner.d.ts +19 -3
- package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
- package/dist/src/turn-runner/turn-runner.js +162 -33
- package/dist/src/turn-runner/turn-runner.js.map +1 -1
- package/dist/src/turn-runner/usage-accounting.d.ts +5 -2
- package/dist/src/turn-runner/usage-accounting.d.ts.map +1 -1
- package/dist/src/turn-runner/usage-accounting.js +18 -6
- package/dist/src/turn-runner/usage-accounting.js.map +1 -1
- package/dist/src/turn-runner/wire-shaping.d.ts +3 -1
- package/dist/src/turn-runner/wire-shaping.d.ts.map +1 -1
- package/dist/src/turn-runner/wire-shaping.js +5 -1
- package/dist/src/turn-runner/wire-shaping.js.map +1 -1
- package/dist/src/types/config.d.ts +7 -0
- package/dist/src/types/config.d.ts.map +1 -1
- package/dist/src/types/protocol.d.ts +13 -5
- package/dist/src/types/protocol.d.ts.map +1 -1
- package/package.json +8 -3
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
/** The established Train API ceiling, applied to UTF-8 body bytes. */
|
|
4
|
+
export const MAX_TRAIN_RECORD_CONTENT_BYTES = 10 * 1024 * 1024;
|
|
5
|
+
const SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
6
|
+
// Identifiers become path segments under the private archive root, so they
|
|
7
|
+
// must never be able to traverse (`..`, separators) out of it. nanoid's
|
|
8
|
+
// alphabet plus the `mem_` prefix always satisfies this.
|
|
9
|
+
const ID_SEGMENT_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
10
|
+
const KEY_PATTERN = /^[A-Za-z][A-Za-z0-9]*$/;
|
|
11
|
+
const NUMBER_PATTERN = /^-?(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
12
|
+
const KNOWN_KEYS = [
|
|
13
|
+
"version",
|
|
14
|
+
"id",
|
|
15
|
+
"kind",
|
|
16
|
+
"createdAt",
|
|
17
|
+
"headline",
|
|
18
|
+
"model",
|
|
19
|
+
"fileCount",
|
|
20
|
+
"archiveId",
|
|
21
|
+
"priority",
|
|
22
|
+
"source",
|
|
23
|
+
"tags",
|
|
24
|
+
];
|
|
25
|
+
const KNOWN_KEY_ORDER = new Map(KNOWN_KEYS.map((key, index) => [key, index]));
|
|
26
|
+
// Line endings are byte-format state, not record metadata. Keeping them on the
|
|
27
|
+
// parsed object preserves CRLF without exposing a formatting field to callers.
|
|
28
|
+
const parsedLineEndings = new WeakMap();
|
|
29
|
+
/**
|
|
30
|
+
* Parse the canonical YAML-compatible subset used by memory files.
|
|
31
|
+
*
|
|
32
|
+
* Values are canonical JSON strings, finite decimal numbers, or inline
|
|
33
|
+
* arrays of canonical JSON strings. Known keys stay in the order emitted by
|
|
34
|
+
* {@link serializeMemoryFile}; unknown keys may follow them and use the same
|
|
35
|
+
* scalar grammar.
|
|
36
|
+
*/
|
|
37
|
+
export function parseMemoryFile(text) {
|
|
38
|
+
const lineEnding = text.startsWith("---\r\n")
|
|
39
|
+
? "\r\n"
|
|
40
|
+
: text.startsWith("---\n")
|
|
41
|
+
? "\n"
|
|
42
|
+
: undefined;
|
|
43
|
+
if (!lineEnding)
|
|
44
|
+
throw new Error("Memory file must start with a frontmatter delimiter");
|
|
45
|
+
const closingDelimiter = `${lineEnding}---${lineEnding}`;
|
|
46
|
+
const closingIndex = text.indexOf(closingDelimiter, 3 + lineEnding.length);
|
|
47
|
+
if (closingIndex === -1)
|
|
48
|
+
throw new Error("Memory file is missing its closing delimiter");
|
|
49
|
+
const header = text.slice(3 + lineEnding.length, closingIndex);
|
|
50
|
+
const content = text.slice(closingIndex + closingDelimiter.length);
|
|
51
|
+
assertContent(content);
|
|
52
|
+
const values = new Map();
|
|
53
|
+
let lastKnownIndex = -1;
|
|
54
|
+
let sawUnknown = false;
|
|
55
|
+
for (const line of header.split(lineEnding)) {
|
|
56
|
+
const separator = line.indexOf(": ");
|
|
57
|
+
if (separator <= 0)
|
|
58
|
+
throw new Error(`Invalid frontmatter line: ${line}`);
|
|
59
|
+
const key = line.slice(0, separator);
|
|
60
|
+
const rawValue = line.slice(separator + 2);
|
|
61
|
+
if (!KEY_PATTERN.test(key))
|
|
62
|
+
throw new Error(`Invalid frontmatter key: ${key}`);
|
|
63
|
+
if (values.has(key))
|
|
64
|
+
throw new Error(`Duplicate frontmatter key: ${key}`);
|
|
65
|
+
if (key === "sourceFolder") {
|
|
66
|
+
throw new Error("sourceFolder is private archive metadata and cannot enter a memory file");
|
|
67
|
+
}
|
|
68
|
+
const knownIndex = KNOWN_KEY_ORDER.get(key);
|
|
69
|
+
if (knownIndex === undefined) {
|
|
70
|
+
sawUnknown = true;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
if (sawUnknown || knownIndex <= lastKnownIndex) {
|
|
74
|
+
throw new Error(`Frontmatter key is out of canonical order: ${key}`);
|
|
75
|
+
}
|
|
76
|
+
lastKnownIndex = knownIndex;
|
|
77
|
+
}
|
|
78
|
+
values.set(key, parseScalar(rawValue));
|
|
79
|
+
}
|
|
80
|
+
const version = requireNumber(values, "version");
|
|
81
|
+
if (version !== 1)
|
|
82
|
+
throw new Error(`Unsupported memory file version: ${version}`);
|
|
83
|
+
const kind = requireString(values, "kind");
|
|
84
|
+
if (kind !== "train" && kind !== "note")
|
|
85
|
+
throw new Error(`Invalid memory kind: ${kind}`);
|
|
86
|
+
const createdAt = requireNumber(values, "createdAt");
|
|
87
|
+
if (!Number.isSafeInteger(createdAt) || createdAt < 0) {
|
|
88
|
+
throw new Error("createdAt must be a non-negative integer");
|
|
89
|
+
}
|
|
90
|
+
const fileCount = optionalNumber(values, "fileCount");
|
|
91
|
+
if (fileCount !== undefined && (!Number.isSafeInteger(fileCount) || fileCount < 0)) {
|
|
92
|
+
throw new Error("fileCount must be a non-negative integer");
|
|
93
|
+
}
|
|
94
|
+
const record = {
|
|
95
|
+
version: 1,
|
|
96
|
+
id: requireIdSegment(values, "id"),
|
|
97
|
+
kind,
|
|
98
|
+
createdAt,
|
|
99
|
+
...optionalStringProperty(values, "headline"),
|
|
100
|
+
...optionalStringProperty(values, "model"),
|
|
101
|
+
...(fileCount === undefined ? {} : { fileCount }),
|
|
102
|
+
...optionalIdSegmentProperty(values, "archiveId"),
|
|
103
|
+
...optionalStringProperty(values, "priority"),
|
|
104
|
+
...optionalStringProperty(values, "source"),
|
|
105
|
+
...optionalStringArrayProperty(values, "tags"),
|
|
106
|
+
...extraProperties(values),
|
|
107
|
+
content,
|
|
108
|
+
};
|
|
109
|
+
parsedLineEndings.set(record, lineEnding);
|
|
110
|
+
return record;
|
|
111
|
+
}
|
|
112
|
+
/** Serialize a memory record into the one canonical byte representation. */
|
|
113
|
+
export function serializeMemoryFile(record) {
|
|
114
|
+
validateRecord(record);
|
|
115
|
+
const lineEnding = parsedLineEndings.get(record) ?? "\n";
|
|
116
|
+
const fields = [
|
|
117
|
+
["version", record.version],
|
|
118
|
+
["id", record.id],
|
|
119
|
+
["kind", record.kind],
|
|
120
|
+
["createdAt", record.createdAt],
|
|
121
|
+
];
|
|
122
|
+
appendOptional(fields, "headline", record.headline);
|
|
123
|
+
appendOptional(fields, "model", record.model);
|
|
124
|
+
appendOptional(fields, "fileCount", record.fileCount);
|
|
125
|
+
appendOptional(fields, "archiveId", record.archiveId);
|
|
126
|
+
appendOptional(fields, "priority", record.priority);
|
|
127
|
+
appendOptional(fields, "source", record.source);
|
|
128
|
+
appendOptional(fields, "tags", record.tags);
|
|
129
|
+
for (const [key, value] of Object.entries(record.extra ?? {})) {
|
|
130
|
+
if (!KEY_PATTERN.test(key) || KNOWN_KEY_ORDER.has(key) || key === "sourceFolder") {
|
|
131
|
+
throw new Error(`Invalid extra frontmatter key: ${key}`);
|
|
132
|
+
}
|
|
133
|
+
fields.push([key, value]);
|
|
134
|
+
}
|
|
135
|
+
const header = fields.map(([key, value]) => `${key}: ${serializeScalar(value)}`).join(lineEnding);
|
|
136
|
+
return `---${lineEnding}${header}${lineEnding}---${lineEnding}${record.content}`;
|
|
137
|
+
}
|
|
138
|
+
/** Return the safe slug owned by a bare `<slug>.md` filename. */
|
|
139
|
+
export function slugFromFilename(name) {
|
|
140
|
+
if (basename(name) !== name || !name.endsWith(".md")) {
|
|
141
|
+
throw new Error(`Memory filename must be a bare .md filename: ${name}`);
|
|
142
|
+
}
|
|
143
|
+
const slug = name.slice(0, -3);
|
|
144
|
+
if (!SLUG_PATTERN.test(slug))
|
|
145
|
+
throw new Error(`Unsafe memory slug: ${slug}`);
|
|
146
|
+
return slug;
|
|
147
|
+
}
|
|
148
|
+
function parseScalar(rawValue) {
|
|
149
|
+
if (NUMBER_PATTERN.test(rawValue)) {
|
|
150
|
+
const value = Number(rawValue);
|
|
151
|
+
if (Number.isFinite(value) && String(value) === rawValue)
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const value = JSON.parse(rawValue);
|
|
156
|
+
if (typeof value === "string" && JSON.stringify(value) === rawValue)
|
|
157
|
+
return value;
|
|
158
|
+
if (Array.isArray(value) &&
|
|
159
|
+
value.every((item) => typeof item === "string") &&
|
|
160
|
+
`[${value.map((item) => JSON.stringify(item)).join(", ")}]` === rawValue) {
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// The grammar error below is more useful than JSON's parser diagnostic.
|
|
166
|
+
}
|
|
167
|
+
throw new Error(`Unsupported frontmatter scalar: ${rawValue}`);
|
|
168
|
+
}
|
|
169
|
+
function serializeScalar(value) {
|
|
170
|
+
if (typeof value === "number") {
|
|
171
|
+
if (!Number.isFinite(value) || /[eE]/.test(String(value))) {
|
|
172
|
+
throw new Error(`Frontmatter numbers must be finite decimals: ${value}`);
|
|
173
|
+
}
|
|
174
|
+
return String(value);
|
|
175
|
+
}
|
|
176
|
+
if (typeof value === "string")
|
|
177
|
+
return JSON.stringify(value);
|
|
178
|
+
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
|
|
179
|
+
return `[${value.map((item) => JSON.stringify(item)).join(", ")}]`;
|
|
180
|
+
}
|
|
181
|
+
throw new Error("Frontmatter values must be strings, numbers, or string arrays");
|
|
182
|
+
}
|
|
183
|
+
function requireNumber(values, key) {
|
|
184
|
+
const value = values.get(key);
|
|
185
|
+
if (typeof value !== "number")
|
|
186
|
+
throw new Error(`Frontmatter ${key} must be a number`);
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
function optionalNumber(values, key) {
|
|
190
|
+
const value = values.get(key);
|
|
191
|
+
if (value === undefined)
|
|
192
|
+
return undefined;
|
|
193
|
+
if (typeof value !== "number")
|
|
194
|
+
throw new Error(`Frontmatter ${key} must be a number`);
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
function requireString(values, key) {
|
|
198
|
+
const value = values.get(key);
|
|
199
|
+
if (typeof value !== "string")
|
|
200
|
+
throw new Error(`Frontmatter ${key} must be a string`);
|
|
201
|
+
return value;
|
|
202
|
+
}
|
|
203
|
+
function requireNonBlankString(values, key) {
|
|
204
|
+
const value = requireString(values, key);
|
|
205
|
+
if (value.trim().length === 0)
|
|
206
|
+
throw new Error(`Frontmatter ${key} cannot be blank`);
|
|
207
|
+
return value;
|
|
208
|
+
}
|
|
209
|
+
function requireIdSegment(values, key) {
|
|
210
|
+
return assertIdSegment(key, requireNonBlankString(values, key));
|
|
211
|
+
}
|
|
212
|
+
function optionalIdSegmentProperty(values, key) {
|
|
213
|
+
if (!values.has(key))
|
|
214
|
+
return {};
|
|
215
|
+
return { [key]: requireIdSegment(values, key) };
|
|
216
|
+
}
|
|
217
|
+
function assertIdSegment(key, value) {
|
|
218
|
+
if (!ID_SEGMENT_PATTERN.test(value)) {
|
|
219
|
+
throw new Error(`Frontmatter ${key} must be a safe path segment: ${value}`);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
function optionalStringProperty(values, key) {
|
|
224
|
+
if (!values.has(key))
|
|
225
|
+
return {};
|
|
226
|
+
return { [key]: requireNonBlankString(values, key) };
|
|
227
|
+
}
|
|
228
|
+
function optionalStringArrayProperty(values, key) {
|
|
229
|
+
const value = values.get(key);
|
|
230
|
+
if (value === undefined)
|
|
231
|
+
return {};
|
|
232
|
+
if (!Array.isArray(value) || value.some((item) => item.trim().length === 0)) {
|
|
233
|
+
throw new Error(`Frontmatter ${key} must be a string array without blank items`);
|
|
234
|
+
}
|
|
235
|
+
return { tags: value };
|
|
236
|
+
}
|
|
237
|
+
function extraProperties(values) {
|
|
238
|
+
const extra = Object.fromEntries(Array.from(values).filter(([key]) => !KNOWN_KEY_ORDER.has(key)));
|
|
239
|
+
return Object.keys(extra).length === 0 ? {} : { extra };
|
|
240
|
+
}
|
|
241
|
+
function appendOptional(fields, key, value) {
|
|
242
|
+
if (value !== undefined)
|
|
243
|
+
fields.push([key, value]);
|
|
244
|
+
}
|
|
245
|
+
function validateRecord(record) {
|
|
246
|
+
if (record.version !== 1)
|
|
247
|
+
throw new Error(`Unsupported memory file version: ${record.version}`);
|
|
248
|
+
if (record.id.trim().length === 0)
|
|
249
|
+
throw new Error("Frontmatter id cannot be blank");
|
|
250
|
+
assertIdSegment("id", record.id);
|
|
251
|
+
if (record.archiveId !== undefined)
|
|
252
|
+
assertIdSegment("archiveId", record.archiveId);
|
|
253
|
+
if (record.kind !== "train" && record.kind !== "note") {
|
|
254
|
+
throw new Error(`Invalid memory kind: ${String(record.kind)}`);
|
|
255
|
+
}
|
|
256
|
+
if (!Number.isSafeInteger(record.createdAt) || record.createdAt < 0) {
|
|
257
|
+
throw new Error("createdAt must be a non-negative integer");
|
|
258
|
+
}
|
|
259
|
+
if (record.fileCount !== undefined &&
|
|
260
|
+
(!Number.isSafeInteger(record.fileCount) || record.fileCount < 0)) {
|
|
261
|
+
throw new Error("fileCount must be a non-negative integer");
|
|
262
|
+
}
|
|
263
|
+
for (const [key, value] of Object.entries({
|
|
264
|
+
headline: record.headline,
|
|
265
|
+
model: record.model,
|
|
266
|
+
archiveId: record.archiveId,
|
|
267
|
+
priority: record.priority,
|
|
268
|
+
source: record.source,
|
|
269
|
+
})) {
|
|
270
|
+
if (value !== undefined && value.trim().length === 0) {
|
|
271
|
+
throw new Error(`Frontmatter ${key} cannot be blank`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (record.tags?.some((tag) => tag.trim().length === 0)) {
|
|
275
|
+
throw new Error("Frontmatter tags cannot contain blank items");
|
|
276
|
+
}
|
|
277
|
+
assertContent(record.content);
|
|
278
|
+
}
|
|
279
|
+
function assertContent(content) {
|
|
280
|
+
if (content.trim().length === 0)
|
|
281
|
+
throw new Error("Memory content cannot be blank");
|
|
282
|
+
const bytes = Buffer.byteLength(content, "utf8");
|
|
283
|
+
if (bytes > MAX_TRAIN_RECORD_CONTENT_BYTES) {
|
|
284
|
+
throw new Error(`Memory content exceeds ${MAX_TRAIN_RECORD_CONTENT_BYTES} UTF-8 bytes`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../../src/memory/store/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MAX_TRAIN_RECORD_CONTENT_BYTES, parseMemoryFile, serializeMemoryFile, slugFromFilename, type MemoryFileRecord, type MemoryFrontmatterValue, type MemoryKind, } from "./file.js";
|
|
2
|
+
export { discoverMemoryStores } from "./discovery.js";
|
|
3
|
+
export { mergeListings, resolveSources, type MemorySourceFlags, type MemorySources, type MemoryWriteTarget, type SourceListing, } from "./sources.js";
|
|
4
|
+
export { deleteEntry, listStore, readEntry, updateEntry, writeEntry, type MemoryEntryInput, type StoredMemory, } from "./store.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,aAAa,EACb,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MAX_TRAIN_RECORD_CONTENT_BYTES, parseMemoryFile, serializeMemoryFile, slugFromFilename, } from "./file.js";
|
|
2
|
+
export { discoverMemoryStores } from "./discovery.js";
|
|
3
|
+
export { mergeListings, resolveSources, } from "./sources.js";
|
|
4
|
+
export { deleteEntry, listStore, readEntry, updateEntry, writeEntry, } from "./store.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/memory/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GAIjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,aAAa,EACb,cAAc,GAKf,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,GAGX,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type StoredMemory } from "./store.js";
|
|
2
|
+
/** Standalone ceiling for curated file memory pinned into an agent prompt. */
|
|
3
|
+
export declare const PINNED_STORE_TOKEN_BUDGET = 15000;
|
|
4
|
+
export interface LoadPinnedStorePackOptions {
|
|
5
|
+
/** Store directories in collision precedence order, nearest first. */
|
|
6
|
+
stores: readonly string[];
|
|
7
|
+
/** Independent ceiling for file-backed content; defaults to 15,000 tokens. */
|
|
8
|
+
tokenBudget?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PinnedStorePack {
|
|
11
|
+
/** Newest-first entries retained after collision resolution and budget fitting. */
|
|
12
|
+
entries: StoredMemory[];
|
|
13
|
+
/** Number of complete older entries removed to satisfy the cap. */
|
|
14
|
+
dropped: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Load a frozen, newest-first view of curated file memories.
|
|
18
|
+
*
|
|
19
|
+
* Malformed entries are isolated to their own file and warned about instead
|
|
20
|
+
* of making agent startup fail. When the complete set exceeds the independent
|
|
21
|
+
* cap, whole entries leave oldest-first; the newest entry is retained and
|
|
22
|
+
* deterministically tail-truncated when it alone is too large.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadPinnedStorePack(options: LoadPinnedStorePackOptions): Promise<PinnedStorePack>;
|
|
25
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../../../src/memory/store/pack.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,MAAM,WAAW,0BAA0B;IACzC,sEAAsE;IACtE,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,eAAe,CAAC,CAwC1B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { estimateTokens } from "../observational.js";
|
|
2
|
+
import { mergeListings } from "./sources.js";
|
|
3
|
+
import { listStoreTolerant } from "./store.js";
|
|
4
|
+
/** Standalone ceiling for curated file memory pinned into an agent prompt. */
|
|
5
|
+
export const PINNED_STORE_TOKEN_BUDGET = 15_000;
|
|
6
|
+
/**
|
|
7
|
+
* Load a frozen, newest-first view of curated file memories.
|
|
8
|
+
*
|
|
9
|
+
* Malformed entries are isolated to their own file and warned about instead
|
|
10
|
+
* of making agent startup fail. When the complete set exceeds the independent
|
|
11
|
+
* cap, whole entries leave oldest-first; the newest entry is retained and
|
|
12
|
+
* deterministically tail-truncated when it alone is too large.
|
|
13
|
+
*/
|
|
14
|
+
export async function loadPinnedStorePack(options) {
|
|
15
|
+
const tokenBudget = options.tokenBudget ?? PINNED_STORE_TOKEN_BUDGET;
|
|
16
|
+
if (!Number.isFinite(tokenBudget) || tokenBudget < 0) {
|
|
17
|
+
throw new Error(`Pinned store token budget must be a non-negative number: ${tokenBudget}`);
|
|
18
|
+
}
|
|
19
|
+
const listings = await Promise.all(options.stores.map(async (store) => ({
|
|
20
|
+
source: store,
|
|
21
|
+
entries: await loadStoreEntries(store),
|
|
22
|
+
})));
|
|
23
|
+
const entries = mergeListings(listings, []);
|
|
24
|
+
let totalTokens = entries.reduce((total, entry) => total + estimateTokens(entry.content), 0);
|
|
25
|
+
let dropped = 0;
|
|
26
|
+
let truncated = false;
|
|
27
|
+
while (entries.length > 1 && totalTokens > tokenBudget) {
|
|
28
|
+
const removed = entries.pop();
|
|
29
|
+
totalTokens -= estimateTokens(removed.content);
|
|
30
|
+
dropped += 1;
|
|
31
|
+
}
|
|
32
|
+
if (entries.length === 1 && totalTokens > tokenBudget) {
|
|
33
|
+
entries[0] = {
|
|
34
|
+
...entries[0],
|
|
35
|
+
content: truncateToTokenBudget(entries[0].content, tokenBudget),
|
|
36
|
+
};
|
|
37
|
+
truncated = true;
|
|
38
|
+
}
|
|
39
|
+
if (dropped > 0 || truncated) {
|
|
40
|
+
const truncation = truncated ? " and truncated the newest entry" : "";
|
|
41
|
+
const formattedBudget = tokenBudget.toLocaleString("en-US");
|
|
42
|
+
console.warn(`[duet-agent] pinned memory store context exceeded ${formattedBudget}-token cap; dropped ${dropped} older memory ${dropped === 1 ? "entry" : "entries"}${truncation}.`);
|
|
43
|
+
}
|
|
44
|
+
return { entries, dropped };
|
|
45
|
+
}
|
|
46
|
+
async function loadStoreEntries(store) {
|
|
47
|
+
try {
|
|
48
|
+
return await listStoreTolerant(store, warnSkippedStore);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
warnSkippedStore(store, error);
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function truncateToTokenBudget(content, tokenBudget) {
|
|
56
|
+
let low = 0;
|
|
57
|
+
let high = content.length;
|
|
58
|
+
while (low < high) {
|
|
59
|
+
const midpoint = Math.ceil((low + high) / 2);
|
|
60
|
+
if (estimateTokens(content.slice(0, midpoint)) <= tokenBudget)
|
|
61
|
+
low = midpoint;
|
|
62
|
+
else
|
|
63
|
+
high = midpoint - 1;
|
|
64
|
+
}
|
|
65
|
+
return content.slice(0, low);
|
|
66
|
+
}
|
|
67
|
+
function warnSkippedStore(path, error) {
|
|
68
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
69
|
+
console.warn(`[duet-agent] skipped malformed memory store entry ${path}: ${reason}`);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../../../../src/memory/store/pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Ordered source paths collected from repeatable CLI backend flags. */
|
|
2
|
+
export interface MemorySourceFlags {
|
|
3
|
+
/** Explicit memory-file directories, in command-line order. */
|
|
4
|
+
stores: string[];
|
|
5
|
+
/** Explicit PGlite files, in command-line order. */
|
|
6
|
+
dbs: string[];
|
|
7
|
+
}
|
|
8
|
+
/** The single backend selected for a create operation. */
|
|
9
|
+
export interface MemoryWriteTarget {
|
|
10
|
+
/** Selects the file-store or legacy PGlite persistence path. */
|
|
11
|
+
kind: "store" | "db";
|
|
12
|
+
/** Absolute store directory or PGlite data path. */
|
|
13
|
+
path: string;
|
|
14
|
+
}
|
|
15
|
+
/** Effective read sources plus the create-operation target implied by them. */
|
|
16
|
+
export interface MemorySources {
|
|
17
|
+
/** File stores in collision-precedence order. */
|
|
18
|
+
stores: string[];
|
|
19
|
+
/** PGlite paths in collision-precedence order after every file store. */
|
|
20
|
+
dbs: string[];
|
|
21
|
+
/** Present only when the invocation selects exactly one write backend. */
|
|
22
|
+
writeTarget?: MemoryWriteTarget;
|
|
23
|
+
}
|
|
24
|
+
/** One backend's already-projected listing rows. */
|
|
25
|
+
export interface SourceListing<T> {
|
|
26
|
+
/** Absolute backend path; file-store groups stamp it as row provenance. */
|
|
27
|
+
source: string;
|
|
28
|
+
/** Rows returned by this backend before collision resolution. */
|
|
29
|
+
entries: readonly T[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve explicit flags or the skills-style flagless source set.
|
|
33
|
+
*
|
|
34
|
+
* Any explicit backend flag replaces discovery. Without flags, reads inherit
|
|
35
|
+
* every existing memory store from cwd toward the filesystem root and then
|
|
36
|
+
* consult the default DB. Writes target the nearest ancestor that owns an
|
|
37
|
+
* `.agents` directory, falling back to cwd when no agent marker exists; the
|
|
38
|
+
* `memories` child itself is allowed to be absent because writers create it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveSources(flags: MemorySourceFlags, cwd: string): Promise<MemorySources>;
|
|
41
|
+
/**
|
|
42
|
+
* Merge projected rows under the one canonical ordering policy.
|
|
43
|
+
*
|
|
44
|
+
* File-store groups precede DB groups; within each family the caller supplies
|
|
45
|
+
* nearest-to-root or explicit flag order. The first row for a slug wins that
|
|
46
|
+
* collision. Only after shadowed copies are removed are all winners sorted
|
|
47
|
+
* newest-first, with the precedence order retained for timestamp ties.
|
|
48
|
+
*/
|
|
49
|
+
export declare function mergeListings<T extends {
|
|
50
|
+
slug: string;
|
|
51
|
+
createdAt: number;
|
|
52
|
+
}>(storeEntries: readonly SourceListing<T>[], dbEntries: readonly SourceListing<T>[]): Array<T & {
|
|
53
|
+
store?: string;
|
|
54
|
+
}>;
|
|
55
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../../../src/memory/store/sources.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oDAAoD;IACpD,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yEAAyE;IACzE,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,0EAA0E;IAC1E,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,CAuBxB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACzE,YAAY,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,EACzC,SAAS,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,GACrC,KAAK,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as fileSystem from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { walkAncestors } from "../../lib/walk-ancestors.js";
|
|
4
|
+
import { DEFAULT_MEMORY_DB_PATH } from "../paths.js";
|
|
5
|
+
import { discoverMemoryStores } from "./discovery.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve explicit flags or the skills-style flagless source set.
|
|
8
|
+
*
|
|
9
|
+
* Any explicit backend flag replaces discovery. Without flags, reads inherit
|
|
10
|
+
* every existing memory store from cwd toward the filesystem root and then
|
|
11
|
+
* consult the default DB. Writes target the nearest ancestor that owns an
|
|
12
|
+
* `.agents` directory, falling back to cwd when no agent marker exists; the
|
|
13
|
+
* `memories` child itself is allowed to be absent because writers create it.
|
|
14
|
+
*/
|
|
15
|
+
export async function resolveSources(flags, cwd) {
|
|
16
|
+
const explicitCount = flags.stores.length + flags.dbs.length;
|
|
17
|
+
if (explicitCount > 0) {
|
|
18
|
+
const stores = unique(flags.stores);
|
|
19
|
+
const dbs = unique(flags.dbs);
|
|
20
|
+
const selected = flags.stores[0] ?? flags.dbs[0];
|
|
21
|
+
const writeTarget = explicitCount === 1 && selected
|
|
22
|
+
? { kind: flags.stores.length === 1 ? "store" : "db", path: selected }
|
|
23
|
+
: undefined;
|
|
24
|
+
return {
|
|
25
|
+
stores,
|
|
26
|
+
dbs,
|
|
27
|
+
...(writeTarget ? { writeTarget } : {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const stores = await discoverMemoryStores(cwd);
|
|
31
|
+
return {
|
|
32
|
+
stores,
|
|
33
|
+
dbs: [DEFAULT_MEMORY_DB_PATH],
|
|
34
|
+
writeTarget: { kind: "store", path: await nearestAgentMemoryStore(cwd) },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Merge projected rows under the one canonical ordering policy.
|
|
39
|
+
*
|
|
40
|
+
* File-store groups precede DB groups; within each family the caller supplies
|
|
41
|
+
* nearest-to-root or explicit flag order. The first row for a slug wins that
|
|
42
|
+
* collision. Only after shadowed copies are removed are all winners sorted
|
|
43
|
+
* newest-first, with the precedence order retained for timestamp ties.
|
|
44
|
+
*/
|
|
45
|
+
export function mergeListings(storeEntries, dbEntries) {
|
|
46
|
+
const winners = new Map();
|
|
47
|
+
for (const listing of storeEntries) {
|
|
48
|
+
for (const entry of listing.entries) {
|
|
49
|
+
if (!winners.has(entry.slug))
|
|
50
|
+
winners.set(entry.slug, { ...entry, store: listing.source });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const listing of dbEntries) {
|
|
54
|
+
for (const entry of listing.entries) {
|
|
55
|
+
if (!winners.has(entry.slug))
|
|
56
|
+
winners.set(entry.slug, { ...entry });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return Array.from(winners.values()).sort((left, right) => right.createdAt - left.createdAt);
|
|
60
|
+
}
|
|
61
|
+
async function nearestAgentMemoryStore(cwd) {
|
|
62
|
+
for (const ancestor of walkAncestors(cwd)) {
|
|
63
|
+
const agentRoot = join(ancestor, ".agents");
|
|
64
|
+
const status = await fileSystem.lstat(agentRoot).catch((error) => {
|
|
65
|
+
if (isNodeError(error, "ENOENT") || isNodeError(error, "ENOTDIR"))
|
|
66
|
+
return undefined;
|
|
67
|
+
throw error;
|
|
68
|
+
});
|
|
69
|
+
if (!status)
|
|
70
|
+
continue;
|
|
71
|
+
if (status.isSymbolicLink())
|
|
72
|
+
throw new Error(`Agent directories cannot be symlinks: ${agentRoot}`);
|
|
73
|
+
if (!status.isDirectory())
|
|
74
|
+
throw new Error(`Agent path is not a directory: ${agentRoot}`);
|
|
75
|
+
return join(agentRoot, "memories");
|
|
76
|
+
}
|
|
77
|
+
return join(resolve(cwd), ".agents", "memories");
|
|
78
|
+
}
|
|
79
|
+
function unique(paths) {
|
|
80
|
+
return Array.from(new Set(paths));
|
|
81
|
+
}
|
|
82
|
+
function isNodeError(error, code) {
|
|
83
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../../../../src/memory/store/sources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type MemoryFileRecord } from "./file.js";
|
|
2
|
+
/** Public view of a record read from a concrete memory-store directory. */
|
|
3
|
+
export interface StoredMemory {
|
|
4
|
+
/** Filename stem and authoritative identity within a store. */
|
|
5
|
+
slug: string;
|
|
6
|
+
/** Absolute directory containing the record, used as its provenance layer. */
|
|
7
|
+
storeDir: string;
|
|
8
|
+
/** Stable record identity shared with APIs and private archive metadata. */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Whether the content is synthesized training or a directly curated note. */
|
|
11
|
+
kind: MemoryFileRecord["kind"];
|
|
12
|
+
/** Unix epoch milliseconds used for observed dates and newest-first ordering. */
|
|
13
|
+
createdAt: number;
|
|
14
|
+
/** Short display label for the curated content. */
|
|
15
|
+
headline?: string;
|
|
16
|
+
/** Model identifier that produced synthesized content, when applicable. */
|
|
17
|
+
model?: string;
|
|
18
|
+
/** Number of source files represented by synthesized content. */
|
|
19
|
+
fileCount?: number;
|
|
20
|
+
/** Private archive manifest identifier; never an absolute archive path. */
|
|
21
|
+
archiveId?: string;
|
|
22
|
+
/** Exact curated markdown body. */
|
|
23
|
+
content: string;
|
|
24
|
+
}
|
|
25
|
+
/** Input for a new file; the slug selects its filename and is never serialized. */
|
|
26
|
+
export interface MemoryEntryInput extends MemoryFileRecord {
|
|
27
|
+
/** Safe filename stem used for `<slug>.md`. */
|
|
28
|
+
slug: string;
|
|
29
|
+
}
|
|
30
|
+
/** List valid markdown records in lexical slug order. */
|
|
31
|
+
export declare function listStore(dir: string): Promise<StoredMemory[]>;
|
|
32
|
+
/**
|
|
33
|
+
* List valid records while isolating malformed files. Runtime prompt loading
|
|
34
|
+
* uses this best-effort form so one hand-edited file cannot block startup;
|
|
35
|
+
* management commands retain {@link listStore}'s strict failure behavior.
|
|
36
|
+
*/
|
|
37
|
+
export declare function listStoreTolerant(dir: string, onInvalidEntry: (path: string, error: unknown) => void): Promise<StoredMemory[]>;
|
|
38
|
+
/** Read one record by its safe filename stem. */
|
|
39
|
+
export declare function readEntry(dir: string, slug: string): Promise<StoredMemory>;
|
|
40
|
+
/** Atomically create or replace one memory file. */
|
|
41
|
+
export declare function writeEntry(dir: string, record: MemoryEntryInput): Promise<StoredMemory>;
|
|
42
|
+
/** Replace only a record's curated body while preserving all frontmatter. */
|
|
43
|
+
export declare function updateEntry(dir: string, slug: string, content: string): Promise<StoredMemory>;
|
|
44
|
+
/** Delete one record and return the bytes' parsed public view. */
|
|
45
|
+
export declare function deleteEntry(dir: string, slug: string): Promise<StoredMemory>;
|
|
46
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/memory/store/store.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAEnB,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yDAAyD;AACzD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAEpE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GACrD,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzB;AA8BD,iDAAiD;AACjD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAKhF;AAED,oDAAoD;AACpD,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuB7F;AAED,6EAA6E;AAC7E,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CASvB;AAED,kEAAkE;AAClE,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CASlF"}
|