@lapis-notes/ai 0.1.2 → 0.1.5

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.
Files changed (69) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE.md +3 -7
  3. package/README.md +1 -1
  4. package/dist/ai-plugin.d.ts +2 -2
  5. package/dist/ai-plugin.js +28 -11
  6. package/dist/catalog/ai-catalog-panel.svelte +20 -3
  7. package/dist/chat/ai-chat-panel.svelte +187 -87
  8. package/dist/chat/ai-chat-panel.svelte.d.ts +2 -0
  9. package/dist/chat/ai-view-bootstrap.d.ts +1 -0
  10. package/dist/chat/ai-view-bootstrap.js +32 -12
  11. package/dist/chat/ai-view-panel.svelte +14 -0
  12. package/dist/chat/ai-view.d.ts +1 -1
  13. package/dist/chat/chat-controller.svelte.d.ts +1 -1
  14. package/dist/chat/chat-controller.svelte.js +94 -29
  15. package/dist/chat/chat-tool-display.d.ts +2 -12
  16. package/dist/chat/chat-tool-display.js +2 -206
  17. package/dist/chat/composer-model-catalog.d.ts +20 -0
  18. package/dist/chat/composer-model-catalog.js +44 -0
  19. package/dist/commands/agent.d.ts +1 -1
  20. package/dist/commands/agent.js +6 -1
  21. package/dist/conversations/context-handoff.d.ts +1 -25
  22. package/dist/conversations/context-handoff.js +1 -207
  23. package/dist/conversations/hashes.d.ts +1 -5
  24. package/dist/conversations/hashes.js +1 -40
  25. package/dist/core/types.d.ts +1 -241
  26. package/dist/core/types.js +1 -50
  27. package/dist/history/ai-history-panel.svelte +4 -1
  28. package/dist/host/controller-connection.d.ts +14 -0
  29. package/dist/host/controller-connection.js +62 -0
  30. package/dist/host/controller-runtime.d.ts +13 -0
  31. package/dist/host/controller-runtime.js +112 -0
  32. package/dist/host/create-host-runtimes.d.ts +2 -1
  33. package/dist/host/create-host-runtimes.js +5 -7
  34. package/dist/index.d.ts +1 -1
  35. package/dist/memory/candidate-extractor.d.ts +2 -25
  36. package/dist/memory/candidate-extractor.js +1 -191
  37. package/dist/memory/hashes.d.ts +1 -5
  38. package/dist/memory/hashes.js +1 -37
  39. package/dist/memory/memory-record-store.d.ts +3 -48
  40. package/dist/memory/memory-record-store.js +16 -220
  41. package/dist/memory/memory-scheduler.d.ts +1 -21
  42. package/dist/memory/memory-scheduler.js +1 -143
  43. package/dist/memory/native-memory-service.d.ts +1 -72
  44. package/dist/memory/native-memory-service.js +1 -1256
  45. package/dist/memory/paths.d.ts +1 -13
  46. package/dist/memory/paths.js +1 -60
  47. package/dist/memory/runtime-consolidation-provider.d.ts +2 -18
  48. package/dist/memory/runtime-consolidation-provider.js +1 -154
  49. package/dist/memory/types.d.ts +1 -139
  50. package/dist/providers/acp-model-provider.d.ts +8 -3
  51. package/dist/providers/acp-model-provider.js +21 -49
  52. package/dist/providers/model-provider.d.ts +3 -2
  53. package/dist/providers/model-provider.js +15 -2
  54. package/dist/runtime-adapters.d.ts +3 -0
  55. package/dist/runtime-adapters.js +2 -0
  56. package/dist/settings/acp-agents.d.ts +4 -1
  57. package/dist/settings/acp-agents.js +5 -1
  58. package/dist/settings/ai-settings-tab.js +8 -6
  59. package/dist/settings/ai-settings.d.ts +4 -4
  60. package/dist/settings/ai-settings.js +5 -3
  61. package/dist/settings/register-ai-settings.js +27 -14
  62. package/dist/tools/app-tool-host.d.ts +22 -2
  63. package/dist/tools/app-tool-host.js +51 -4
  64. package/dist/tools/desktop-app-tool-bridge.d.ts +4 -1
  65. package/dist/tools/desktop-app-tool-bridge.js +94 -157
  66. package/manifest.json +20 -2
  67. package/package.json +17 -7
  68. package/registry-content/overview.md +10 -0
  69. package/registry.json +211 -2
@@ -1,14 +1,13 @@
1
1
  import { TFile, TFolder } from "@lapis-notes/api/vault";
2
- import { parse, stringify } from "yaml";
3
- import { canonicalJson, sha256Text } from "./hashes";
4
- import { hasHiddenApplicationSegment, normalizeConversationScope, } from "../conversations/paths";
5
- const MEMORY_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,127}$/u;
6
- const MAX_MEMORY_FILE_BYTES = 512 * 1024;
7
- export class MemoryRecordConflictError extends Error {
8
- constructor(message) {
9
- super(message);
10
- this.name = "MemoryRecordConflictError";
11
- }
2
+ import { stringify } from "yaml";
3
+ import { MemoryRecordConflictError, serializeMemoryRecord, validateMemoryRecord, recordPath, recordDirectory, memoryRoot, sha256Text, __memoryRecordStoreInternals, } from "@lapismd/ai-controller/memory/lapis";
4
+ export { InMemoryMemoryRecordStore, MemoryRecordConflictError, serializeMemoryRecord, validateMemoryRecord, recordPath, recordDirectory, memoryRoot, __memoryRecordStoreInternals, } from "@lapismd/ai-controller/memory/lapis";
5
+ const { parseStoredRecord, revisionDirectory, scopeKey } = __memoryRecordStoreInternals;
6
+ function sameScope(left, right) {
7
+ return scopeKey(left) === scopeKey(right);
8
+ }
9
+ function assertMemoryId(id) {
10
+ recordPath({ kind: "workspace" }, id);
12
11
  }
13
12
  export class VaultMemoryRecordStore {
14
13
  vault;
@@ -60,7 +59,8 @@ export class VaultMemoryRecordStore {
60
59
  throw new MemoryRecordConflictError(`Memory ${record.id} changed after consolidation preview`);
61
60
  }
62
61
  if (current) {
63
- if (current.record.id !== record.id || !sameScope(current.record.scope, record.scope)) {
62
+ if (current.record.id !== record.id ||
63
+ !sameScope(current.record.scope, record.scope)) {
64
64
  throw new MemoryRecordConflictError("Memory identity or scope changed externally");
65
65
  }
66
66
  if (record.revision !== current.record.revision + 1) {
@@ -71,7 +71,8 @@ export class VaultMemoryRecordStore {
71
71
  }
72
72
  await this.writeImmutablePreimage(current);
73
73
  }
74
- else if (record.revision !== 1 || record.previousRevisionHash !== undefined) {
74
+ else if (record.revision !== 1 ||
75
+ record.previousRevisionHash !== undefined) {
75
76
  throw new MemoryRecordConflictError("A new memory must begin at revision 1 without a previous hash");
76
77
  }
77
78
  const content = serializeMemoryRecord(record);
@@ -95,7 +96,8 @@ export class VaultMemoryRecordStore {
95
96
  const records = [];
96
97
  for (const file of files) {
97
98
  try {
98
- records.push((await parseStoredRecord(file.path, await this.vault.read(file))).record);
99
+ records.push((await parseStoredRecord(file.path, await this.vault.read(file)))
100
+ .record);
99
101
  }
100
102
  catch {
101
103
  // Corrupt external revision files stay visible in the vault but not active data.
@@ -119,9 +121,7 @@ export class VaultMemoryRecordStore {
119
121
  ...this.vault.getFilesByGlob(".lapis/agents/memory/exclusions/*.yaml"),
120
122
  ...this.vault.getFilesByGlob("**/.lapis/agents/memory/exclusions/*.yaml"),
121
123
  ];
122
- return new Set(files
123
- .map((file) => file.name.replace(/\.yaml$/u, ""))
124
- .filter(Boolean));
124
+ return new Set(files.map((file) => file.name.replace(/\.yaml$/u, "")).filter(Boolean));
125
125
  }
126
126
  async writeConversationExclusion(location) {
127
127
  const scope = location.scopeDir
@@ -163,207 +163,3 @@ export class VaultMemoryRecordStore {
163
163
  await this.vault.create(path, content);
164
164
  }
165
165
  }
166
- export class InMemoryMemoryRecordStore {
167
- #records = new Map();
168
- #history = new Map();
169
- #reviews = new Map();
170
- #exclusions = new Map();
171
- async list(scope) {
172
- return [...this.#records.values()]
173
- .filter((stored) => !scope || sameScope(scope, stored.record.scope))
174
- .map((stored) => structuredClone(stored));
175
- }
176
- async find(id) {
177
- return (await this.list()).filter((stored) => stored.record.id === id);
178
- }
179
- async write(record, options = {}) {
180
- validateMemoryRecord(record);
181
- const key = `${scopeKey(record.scope)}\u0000${record.id}`;
182
- const current = this.#records.get(key);
183
- if (!current &&
184
- [...this.#records.values()].some((stored) => stored.record.id === record.id)) {
185
- throw new MemoryRecordConflictError(`Memory ${record.id} already exists in another scope`);
186
- }
187
- if (options.expectedCurrentHash !== undefined &&
188
- current?.hash !== options.expectedCurrentHash) {
189
- throw new MemoryRecordConflictError("Memory changed after preview");
190
- }
191
- if (current) {
192
- if (record.revision !== current.record.revision + 1 ||
193
- record.previousRevisionHash !== current.hash) {
194
- throw new MemoryRecordConflictError("Invalid memory revision preimage");
195
- }
196
- const history = this.#history.get(key) ?? [];
197
- history.push(structuredClone(current.record));
198
- this.#history.set(key, history);
199
- }
200
- else if (record.revision !== 1 || record.previousRevisionHash) {
201
- throw new MemoryRecordConflictError("Invalid first memory revision");
202
- }
203
- const content = serializeMemoryRecord(record);
204
- const stored = {
205
- record: structuredClone(record),
206
- path: recordPath(record.scope, record.id),
207
- hash: await sha256Text(content),
208
- content,
209
- };
210
- this.#records.set(key, stored);
211
- return structuredClone(stored);
212
- }
213
- async listHistory(id, scope) {
214
- return structuredClone(this.#history.get(`${scopeKey(scope)}\u0000${id}`) ?? []);
215
- }
216
- async writeReview(scope, jobId, markdown) {
217
- const path = `${memoryRoot(scope)}/reviews/${jobId}.md`;
218
- if (this.#reviews.has(path))
219
- throw new MemoryRecordConflictError("Review exists");
220
- this.#reviews.set(path, markdown);
221
- return path;
222
- }
223
- async listExcludedConversationIds() {
224
- return new Set(this.#exclusions.keys());
225
- }
226
- async writeConversationExclusion(location) {
227
- const scope = location.scopeDir
228
- ? { kind: "project", projectDir: location.scopeDir }
229
- : { kind: "workspace" };
230
- const path = `${memoryRoot(scope)}/exclusions/${location.conversationId}.yaml`;
231
- this.#exclusions.set(location.conversationId, path);
232
- return path;
233
- }
234
- }
235
- export function memoryRoot(scope) {
236
- return [
237
- scope.kind === "project" ? scope.projectDir : "",
238
- ".lapis",
239
- "agents",
240
- "memory",
241
- ]
242
- .filter(Boolean)
243
- .join("/");
244
- }
245
- export function recordDirectory(scope) {
246
- return `${memoryRoot(scope)}/${scope.kind}/records`;
247
- }
248
- export function recordPath(scope, id) {
249
- assertMemoryId(id);
250
- return `${recordDirectory(scope)}/${id}.md`;
251
- }
252
- function revisionDirectory(scope, id) {
253
- return `${memoryRoot(scope)}/revisions/${id}`;
254
- }
255
- export function serializeMemoryRecord(record) {
256
- validateMemoryRecord(record);
257
- const { summary, ...frontmatter } = record;
258
- return `---\n${stringify(frontmatter, { lineWidth: 0 })}---\n\n${summary.trim()}\n`;
259
- }
260
- async function parseStoredRecord(path, content) {
261
- if (new TextEncoder().encode(content).byteLength > MAX_MEMORY_FILE_BYTES) {
262
- throw new Error("Memory record exceeds the maximum supported size");
263
- }
264
- const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n(?:\r?\n)?([\s\S]*)$/u.exec(content);
265
- if (!match)
266
- throw new Error("Memory record requires YAML frontmatter");
267
- const metadata = parse(match[1], { maxAliasCount: 10 });
268
- const record = validateMemoryRecord({
269
- ...metadata,
270
- summary: match[2].trim(),
271
- });
272
- const expectedPath = recordPath(record.scope, record.id);
273
- const isRevision = path.startsWith(`${revisionDirectory(record.scope, record.id)}/`);
274
- if (path !== expectedPath && !isRevision) {
275
- throw new Error("Memory record path does not match its scope and identity");
276
- }
277
- return { record, path, hash: await sha256Text(content), content };
278
- }
279
- export function validateMemoryRecord(value) {
280
- if (!value || typeof value !== "object" || Array.isArray(value)) {
281
- throw new Error("Memory record must be an object");
282
- }
283
- const record = value;
284
- if (record.schemaVersion !== 1)
285
- throw new Error("Unsupported memory schema");
286
- assertMemoryId(record.id);
287
- if (!Number.isSafeInteger(record.revision) || record.revision < 1) {
288
- throw new Error("Memory revision is invalid");
289
- }
290
- if (!["preference", "fact", "decision", "procedure", "constraint"].includes(record.kind)) {
291
- throw new Error("Memory kind is invalid");
292
- }
293
- validateScope(record.scope);
294
- if (record.status !== "active" && record.status !== "retracted") {
295
- throw new Error("Memory status is invalid");
296
- }
297
- if (![1, 2, 3, 4, 5].includes(record.importance)) {
298
- throw new Error("Memory importance is invalid");
299
- }
300
- if (!Array.isArray(record.triggers) || record.triggers.some((item) => typeof item !== "string")) {
301
- throw new Error("Memory triggers are invalid");
302
- }
303
- if (typeof record.summary !== "string" || !record.summary.trim()) {
304
- throw new Error("Memory summary is required");
305
- }
306
- if (!Array.isArray(record.evidence))
307
- throw new Error("Memory evidence is invalid");
308
- for (const evidence of record.evidence)
309
- validateEvidence(evidence);
310
- if (record.createdBy !== "owner-ui" && record.evidence.length === 0) {
311
- throw new Error("Automatically generated memory requires evidence");
312
- }
313
- if (!["owner-ui", "deterministic-promotion", "consolidator"].includes(record.createdBy)) {
314
- throw new Error("Memory creator is invalid");
315
- }
316
- for (const timestamp of [record.createdAt, record.updatedAt]) {
317
- if (!Number.isFinite(Date.parse(timestamp)))
318
- throw new Error("Memory timestamp is invalid");
319
- }
320
- if (record.previousRevisionHash !== undefined &&
321
- !/^[0-9a-f]{64}$/u.test(record.previousRevisionHash)) {
322
- throw new Error("Memory previous revision hash is invalid");
323
- }
324
- return structuredClone(record);
325
- }
326
- function validateEvidence(evidence) {
327
- if (!evidence ||
328
- typeof evidence.conversationId !== "string" ||
329
- typeof evidence.entryId !== "string" ||
330
- !/^[0-9a-f]{64}$/u.test(evidence.entryHash) ||
331
- !Number.isFinite(Date.parse(evidence.observedAt)) ||
332
- typeof evidence.scopeDirAtObservation !== "string") {
333
- throw new Error("Memory evidence reference is invalid");
334
- }
335
- }
336
- function validateScope(scope) {
337
- if (!scope || !["user", "workspace", "project"].includes(scope.kind)) {
338
- throw new Error("Memory scope is invalid");
339
- }
340
- if (scope.kind === "project") {
341
- let normalized;
342
- try {
343
- normalized = normalizeConversationScope(scope.projectDir);
344
- }
345
- catch {
346
- throw new Error("Project memory scope is invalid");
347
- }
348
- if (normalized !== scope.projectDir ||
349
- hasHiddenApplicationSegment(normalized)) {
350
- throw new Error("Project memory scope is invalid");
351
- }
352
- }
353
- }
354
- function assertMemoryId(id) {
355
- if (!MEMORY_ID_PATTERN.test(id))
356
- throw new Error("Memory ID is invalid");
357
- }
358
- function sameScope(left, right) {
359
- return scopeKey(left) === scopeKey(right);
360
- }
361
- function scopeKey(scope) {
362
- return scope.kind === "project" ? `project:${scope.projectDir}` : `${scope.kind}:`;
363
- }
364
- export const __memoryRecordStoreInternals = {
365
- parseStoredRecord,
366
- revisionDirectory,
367
- scopeKey,
368
- canonicalJson,
369
- };
@@ -1,21 +1 @@
1
- import type { AppDatabase } from "@lapis-notes/api";
2
- import type { ConsolidationResult, MemoryScope, MemoryService } from "./types";
3
- export type MemorySchedulerOptions = {
4
- ownerId?: string;
5
- idleMs?: number;
6
- dailyMs?: number;
7
- leaseMs?: number;
8
- now?: () => number;
9
- onError?: (operation: "consolidate", scope: MemoryScope, error: unknown) => void;
10
- };
11
- export declare class MemoryMaintenanceScheduler {
12
- #private;
13
- private readonly database;
14
- private readonly memory;
15
- constructor(database: AppDatabase, memory: MemoryService, options?: MemorySchedulerOptions);
16
- start(): void;
17
- noteActivity(scope: MemoryScope): void;
18
- run(scope: MemoryScope): Promise<ConsolidationResult | null>;
19
- dispose(): void;
20
- private runDaily;
21
- }
1
+ export { MemoryMaintenanceScheduler, type MemorySchedulerOptions, } from "@lapismd/ai-controller/memory/lapis";
@@ -1,143 +1 @@
1
- import { sha256Text } from "./hashes";
2
- import { memoryScopeKey } from "./paths";
3
- const DEFAULT_IDLE_MS = 30 * 60 * 1_000;
4
- const DEFAULT_DAILY_MS = 24 * 60 * 60 * 1_000;
5
- const DEFAULT_LEASE_MS = 5 * 60 * 1_000;
6
- export class MemoryMaintenanceScheduler {
7
- database;
8
- memory;
9
- #ownerId;
10
- #idleMs;
11
- #dailyMs;
12
- #leaseMs;
13
- #now;
14
- #onError;
15
- #idleTimers = new Map();
16
- #scopes = new Map();
17
- #dailyTimer;
18
- #disposed = false;
19
- constructor(database, memory, options = {}) {
20
- this.database = database;
21
- this.memory = memory;
22
- this.#ownerId = options.ownerId ?? crypto.randomUUID();
23
- this.#idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
24
- this.#dailyMs = options.dailyMs ?? DEFAULT_DAILY_MS;
25
- this.#leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;
26
- this.#now = options.now ?? (() => Date.now());
27
- this.#onError = options.onError ?? (() => { });
28
- }
29
- start() {
30
- if (this.#disposed || this.#dailyTimer)
31
- return;
32
- this.#dailyTimer = setTimeout(() => void this.runDaily(), this.#dailyMs);
33
- }
34
- noteActivity(scope) {
35
- if (this.#disposed)
36
- return;
37
- const key = memoryScopeKey(scope);
38
- this.#scopes.set(key, scope);
39
- const current = this.#idleTimers.get(key);
40
- if (current)
41
- clearTimeout(current);
42
- this.#idleTimers.set(key, setTimeout(() => {
43
- this.#idleTimers.delete(key);
44
- void this.run(scope);
45
- }, this.#idleMs));
46
- }
47
- async run(scope) {
48
- if (this.#disposed)
49
- return null;
50
- const preview = await this.memory.previewConsolidation(scope);
51
- if (preview.proposals === 0)
52
- return null;
53
- const now = this.#now();
54
- const scopeKey = memoryScopeKey(scope);
55
- const candidateFingerprint = (await sha256Text([...preview.candidateIds].sort().join("\n"))).slice(0, 16);
56
- const job = {
57
- id: `consolidate:${scopeKey}:${new Date(now).toISOString().slice(0, 10)}:${candidateFingerprint}`,
58
- kind: "consolidate",
59
- scopeKey,
60
- status: "queued",
61
- attempts: 0,
62
- maxAttempts: 3,
63
- createdAt: now,
64
- };
65
- const claimed = await this.database.claimMemoryJob({
66
- job,
67
- ownerId: this.#ownerId,
68
- now,
69
- leaseMs: this.#leaseMs,
70
- });
71
- if (!claimed)
72
- return null;
73
- const renew = setInterval(() => {
74
- const renewedAt = this.#now();
75
- void this.database.updateMemoryJob({
76
- jobId: job.id,
77
- ownerId: this.#ownerId,
78
- now: renewedAt,
79
- patch: {
80
- status: "running",
81
- leaseUntil: renewedAt + this.#leaseMs,
82
- },
83
- });
84
- }, Math.max(1_000, Math.floor(this.#leaseMs / 2)));
85
- try {
86
- const result = await this.memory.consolidate(scope);
87
- await this.database.updateMemoryJob({
88
- jobId: job.id,
89
- ownerId: this.#ownerId,
90
- now: this.#now(),
91
- patch: { status: "completed", finishedAt: this.#now() },
92
- });
93
- return result;
94
- }
95
- catch (error) {
96
- await this.database.updateMemoryJob({
97
- jobId: job.id,
98
- ownerId: this.#ownerId,
99
- now: this.#now(),
100
- patch: {
101
- status: "failed",
102
- finishedAt: this.#now(),
103
- errorCode: "consolidation-failed",
104
- },
105
- });
106
- this.#onError("consolidate", scope, error);
107
- return null;
108
- }
109
- finally {
110
- clearInterval(renew);
111
- }
112
- }
113
- dispose() {
114
- this.#disposed = true;
115
- if (this.#dailyTimer)
116
- clearTimeout(this.#dailyTimer);
117
- this.#dailyTimer = undefined;
118
- for (const timer of this.#idleTimers.values())
119
- clearTimeout(timer);
120
- this.#idleTimers.clear();
121
- this.#scopes.clear();
122
- }
123
- async runDaily() {
124
- this.#dailyTimer = undefined;
125
- if (this.#disposed)
126
- return;
127
- for (const candidate of await this.database.queryMemoryCandidates({
128
- states: ["staged"],
129
- limit: 10_000,
130
- })) {
131
- const scope = candidate.candidate.scopeKind === "project"
132
- ? {
133
- kind: "project",
134
- projectDir: candidate.candidate.scopePath,
135
- }
136
- : { kind: candidate.candidate.scopeKind };
137
- this.#scopes.set(memoryScopeKey(scope), scope);
138
- }
139
- for (const scope of this.#scopes.values())
140
- await this.run(scope);
141
- this.start();
142
- }
143
- }
1
+ export { MemoryMaintenanceScheduler, } from "@lapismd/ai-controller/memory/lapis";
@@ -1,72 +1 @@
1
- import type { AppDatabase } from "@lapis-notes/api";
2
- import type { ConversationRepository } from "../conversations/conversation-repository";
3
- import type { AgentContextBlock } from "../core/types";
4
- import type { ConversationLocation, ConversationSnapshot, TranscriptEntry } from "../conversations/types";
5
- import { type MemoryRecordStore } from "./memory-record-store";
6
- import type { ConsolidationPreview, ConsolidationResult, MemoryContext, MemoryDetail, MemoryOriginClass, MemoryRebuildResult, MemoryForgetPreview, MemoryForgetResult, MemoryScope, MemorySearchQuery, MemorySearchResult, MemoryService, MemoryConsolidationProvider } from "./types";
7
- type RankedEpisode = {
8
- path: string;
9
- result: MemorySearchResult;
10
- retrievalScore: number;
11
- };
12
- export type NativeMemoryServiceOptions = {
13
- now?: () => Date;
14
- yieldToApp?: () => Promise<void>;
15
- recordStore?: MemoryRecordStore;
16
- consolidationProvider?: MemoryConsolidationProvider | (() => MemoryConsolidationProvider | undefined);
17
- };
18
- export declare class NativeMemoryService implements MemoryService {
19
- #private;
20
- private readonly repository;
21
- private readonly database;
22
- constructor(repository: ConversationRepository, database: AppDatabase, options?: NativeMemoryServiceOptions);
23
- ingestConversation(location: ConversationLocation): Promise<void>;
24
- search(query: MemorySearchQuery, context: MemoryContext, signal?: AbortSignal): Promise<MemorySearchResult[]>;
25
- recall(query: string, context: MemoryContext, signal?: AbortSignal): Promise<AgentContextBlock[]>;
26
- get(ref: string, _context: MemoryContext, signal?: AbortSignal): Promise<MemoryDetail>;
27
- rebuild(scope?: MemoryScope): Promise<MemoryRebuildResult>;
28
- previewForgetConversation(location: ConversationLocation): Promise<MemoryForgetPreview>;
29
- forgetConversation(location: ConversationLocation): Promise<MemoryForgetResult>;
30
- previewConsolidation(scope: MemoryScope): Promise<ConsolidationPreview>;
31
- consolidate(scope: MemoryScope): Promise<ConsolidationResult>;
32
- private markInconsistent;
33
- private removeStaleConversationDocuments;
34
- private curatedSearchDocument;
35
- private verifyEvidence;
36
- private getCurated;
37
- private resolveCandidateEvidence;
38
- private markCandidatePromoted;
39
- private writeConsolidationReview;
40
- private recordRecallSignals;
41
- }
42
- type ProjectedEpisode = {
43
- entry: Extract<TranscriptEntry, {
44
- type: "message" | "tool";
45
- }>;
46
- entryHash: string;
47
- text: string;
48
- originClass: MemoryOriginClass;
49
- };
50
- declare function projectEpisodes(snapshot: ConversationSnapshot): Promise<ProjectedEpisode[]>;
51
- declare function episodeRef(conversationId: string, entryId: string): string;
52
- declare function curatedRef(id: string, revision: number): string;
53
- declare function parseCuratedRef(ref: string): {
54
- id: string;
55
- revision: number;
56
- } | null;
57
- declare function parseEpisodeRef(ref: string): {
58
- conversationId: string;
59
- entryId: string;
60
- } | null;
61
- declare function selectMmr(candidates: RankedEpisode[], limit: number): RankedEpisode[];
62
- declare function contradictory(current: string, proposed: string): boolean;
63
- export declare const __memoryServiceInternals: {
64
- contradictory: typeof contradictory;
65
- curatedRef: typeof curatedRef;
66
- episodeRef: typeof episodeRef;
67
- parseCuratedRef: typeof parseCuratedRef;
68
- parseEpisodeRef: typeof parseEpisodeRef;
69
- projectEpisodes: typeof projectEpisodes;
70
- selectMmr: typeof selectMmr;
71
- };
72
- export {};
1
+ export { NativeMemoryService, __memoryServiceInternals, type NativeMemoryServiceOptions, } from "@lapismd/ai-controller/memory/lapis";