@noopolis/mneme 0.1.0

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 (77) hide show
  1. package/README.md +83 -0
  2. package/dist/cli/index.d.ts +3 -0
  3. package/dist/cli/index.d.ts.map +1 -0
  4. package/dist/cli/index.js +46 -0
  5. package/dist/contract/index.d.ts +3 -0
  6. package/dist/contract/index.d.ts.map +1 -0
  7. package/dist/contract/index.js +2 -0
  8. package/dist/contract/toolDescriptors.d.ts +14 -0
  9. package/dist/contract/toolDescriptors.d.ts.map +1 -0
  10. package/dist/contract/toolDescriptors.js +98 -0
  11. package/dist/contract/types.d.ts +262 -0
  12. package/dist/contract/types.d.ts.map +1 -0
  13. package/dist/contract/types.js +1 -0
  14. package/dist/identity/ids.d.ts +9 -0
  15. package/dist/identity/ids.d.ts.map +1 -0
  16. package/dist/identity/ids.js +25 -0
  17. package/dist/identity/index.d.ts +3 -0
  18. package/dist/identity/index.d.ts.map +1 -0
  19. package/dist/identity/index.js +2 -0
  20. package/dist/identity/scope.d.ts +24 -0
  21. package/dist/identity/scope.d.ts.map +1 -0
  22. package/dist/identity/scope.js +123 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/kernel/index.d.ts +3 -0
  27. package/dist/kernel/index.d.ts.map +1 -0
  28. package/dist/kernel/index.js +2 -0
  29. package/dist/kernel/kernel.d.ts +19 -0
  30. package/dist/kernel/kernel.d.ts.map +1 -0
  31. package/dist/kernel/kernel.js +318 -0
  32. package/dist/kernel/support.d.ts +66 -0
  33. package/dist/kernel/support.d.ts.map +1 -0
  34. package/dist/kernel/support.js +207 -0
  35. package/dist/mcp/config.d.ts +23 -0
  36. package/dist/mcp/config.d.ts.map +1 -0
  37. package/dist/mcp/config.js +76 -0
  38. package/dist/mcp/index.d.ts +4 -0
  39. package/dist/mcp/index.d.ts.map +1 -0
  40. package/dist/mcp/index.js +3 -0
  41. package/dist/mcp/schemas.d.ts +150 -0
  42. package/dist/mcp/schemas.d.ts.map +1 -0
  43. package/dist/mcp/schemas.js +54 -0
  44. package/dist/mcp/server.d.ts +5 -0
  45. package/dist/mcp/server.d.ts.map +1 -0
  46. package/dist/mcp/server.js +45 -0
  47. package/dist/policy/index.d.ts +2 -0
  48. package/dist/policy/index.d.ts.map +1 -0
  49. package/dist/policy/index.js +1 -0
  50. package/dist/policy/policy.d.ts +9 -0
  51. package/dist/policy/policy.d.ts.map +1 -0
  52. package/dist/policy/policy.js +123 -0
  53. package/dist/recall/index.d.ts +2 -0
  54. package/dist/recall/index.d.ts.map +1 -0
  55. package/dist/recall/index.js +1 -0
  56. package/dist/recall/recall.d.ts +28 -0
  57. package/dist/recall/recall.d.ts.map +1 -0
  58. package/dist/recall/recall.js +178 -0
  59. package/dist/runtime/index.d.ts +3 -0
  60. package/dist/runtime/index.d.ts.map +1 -0
  61. package/dist/runtime/index.js +2 -0
  62. package/dist/runtime/runtime.d.ts +19 -0
  63. package/dist/runtime/runtime.d.ts.map +1 -0
  64. package/dist/runtime/runtime.js +129 -0
  65. package/dist/runtime/support.d.ts +52 -0
  66. package/dist/runtime/support.d.ts.map +1 -0
  67. package/dist/runtime/support.js +229 -0
  68. package/dist/store/index.d.ts +3 -0
  69. package/dist/store/index.d.ts.map +1 -0
  70. package/dist/store/index.js +2 -0
  71. package/dist/store/sqliteIndex.d.ts +38 -0
  72. package/dist/store/sqliteIndex.d.ts.map +1 -0
  73. package/dist/store/sqliteIndex.js +270 -0
  74. package/dist/store/store.d.ts +27 -0
  75. package/dist/store/store.d.ts.map +1 -0
  76. package/dist/store/store.js +114 -0
  77. package/package.json +53 -0
@@ -0,0 +1,123 @@
1
+ import { canonicalPrincipalKey, canonicalScopeKey, sanitizePrincipalQualifier } from "../identity/ids.js";
2
+ const isPairMatch = (request, source, candidateVisibility) => {
3
+ if (candidateVisibility !== "pair" && candidateVisibility !== "private") {
4
+ return false;
5
+ }
6
+ if (request.scope === "pair" && source.scope === "pair") {
7
+ return sanitizePrincipalQualifier(request.qualifier) === sanitizePrincipalQualifier(source.qualifier);
8
+ }
9
+ return request.agentId === source.agentId && request.qualifier !== undefined && source.qualifier !== undefined
10
+ ? request.qualifier.toLowerCase() === source.qualifier.toLowerCase()
11
+ : false;
12
+ };
13
+ const samePrincipal = (a, b) => a.agentId === b.agentId && a.scope === b.scope &&
14
+ sanitizePrincipalQualifier(a.qualifier) === sanitizePrincipalQualifier(b.qualifier);
15
+ const roomMatch = (a, b) => a.scope === "room" && b.scope === "room" && a.agentId === b.agentId &&
16
+ sanitizePrincipalQualifier(a.qualifier) === sanitizePrincipalQualifier(b.qualifier);
17
+ const teamMatch = (a, b) => a.scope === "team" && b.scope === "team" && a.agentId === b.agentId &&
18
+ sanitizePrincipalQualifier(a.qualifier) === sanitizePrincipalQualifier(b.qualifier);
19
+ const roleMatch = (a, b) => a.scope === "role" && b.scope === "role" && a.agentId === b.agentId &&
20
+ sanitizePrincipalQualifier(a.qualifier) === sanitizePrincipalQualifier(b.qualifier);
21
+ const eventScopeMatchesPrincipal = (candidate) => canonicalScopeKey(candidate.scope) === canonicalScopeKey(canonicalPrincipalKey(candidate.principal));
22
+ const scopePriority = (request, candidate) => {
23
+ if (samePrincipal(request, candidate)) {
24
+ return 100;
25
+ }
26
+ if (roomMatch(request, candidate) || roleMatch(request, candidate)) {
27
+ return 80;
28
+ }
29
+ if (teamMatch(request, candidate)) {
30
+ return 70;
31
+ }
32
+ if (request.scope === "pair" && candidate.scope === "pair") {
33
+ return 90;
34
+ }
35
+ return 40;
36
+ };
37
+ export const memoryPolicy = ({ request, candidate }) => {
38
+ const visible = candidate.visibility;
39
+ const sensitive = candidate.sensitivity;
40
+ if (visible === "sealed") {
41
+ return {
42
+ decision: "deny",
43
+ reason: "sealed content"
44
+ };
45
+ }
46
+ if (samePrincipal(request, candidate.principal)) {
47
+ return {
48
+ decision: "allow_raw",
49
+ reason: "same principal"
50
+ };
51
+ }
52
+ if (visible === "private") {
53
+ return isPairMatch(request, candidate.principal, visible)
54
+ ? {
55
+ decision: "allow_raw",
56
+ reason: "pair requester context"
57
+ }
58
+ : {
59
+ decision: "known_but_private",
60
+ reason: "private visibility"
61
+ };
62
+ }
63
+ if (visible === "pair") {
64
+ return isPairMatch(request, candidate.principal, visible)
65
+ ? {
66
+ decision: sensitive === "secret" ? "allow_summary" : "allow_raw",
67
+ reason: "pair scope match"
68
+ }
69
+ : {
70
+ decision: "known_but_private",
71
+ reason: "pair visibility mismatch"
72
+ };
73
+ }
74
+ if (visible === "team" &&
75
+ candidate.principal.scope === "team" &&
76
+ request.agentId === candidate.principal.agentId &&
77
+ eventScopeMatchesPrincipal(candidate)) {
78
+ if (sensitive === "secret") {
79
+ return {
80
+ decision: "allow_summary",
81
+ reason: "team scope match with sensitive visibility"
82
+ };
83
+ }
84
+ return {
85
+ decision: "allow_summary",
86
+ reason: "team scope match"
87
+ };
88
+ }
89
+ if (visible === "room" &&
90
+ candidate.principal.scope === "room" &&
91
+ request.agentId === candidate.principal.agentId &&
92
+ eventScopeMatchesPrincipal(candidate)) {
93
+ if (sensitive === "secret") {
94
+ return {
95
+ decision: "allow_redacted_summary",
96
+ reason: "room scope match with secret visibility"
97
+ };
98
+ }
99
+ return {
100
+ decision: "allow_summary",
101
+ reason: "room scope match"
102
+ };
103
+ }
104
+ if (visible === "global" && candidate.principal.scope === "global") {
105
+ return {
106
+ decision: "allow_summary",
107
+ reason: "global visibility"
108
+ };
109
+ }
110
+ if (visible === "public") {
111
+ return {
112
+ decision: "allow_summary",
113
+ reason: "public visibility"
114
+ };
115
+ }
116
+ return {
117
+ decision: "deny",
118
+ reason: "scope mismatch"
119
+ };
120
+ };
121
+ export const memoryPriority = (request, candidate) => scopePriority(request, candidate);
122
+ export const shouldRecordDecisionEvent = (decision) => decision !== "allow_summary" && decision !== "allow_raw";
123
+ export const principalKey = canonicalPrincipalKey;
@@ -0,0 +1,2 @@
1
+ export * from "./recall.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recall/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./recall.js";
@@ -0,0 +1,28 @@
1
+ import type { MemoryEvent, MemoryPrincipalRef, MemoryRecallAudit, MemoryDecision, WakeMemoryContext, MemoryPacket } from "../contract/types.js";
2
+ export interface RecallInput {
3
+ actor: MemoryPrincipalRef;
4
+ scopeIds: string[];
5
+ events: MemoryEvent[];
6
+ query: string;
7
+ maxTokens: number;
8
+ }
9
+ export interface RecallSelection {
10
+ packet: MemoryPacket;
11
+ audit: MemoryRecallAudit;
12
+ selected: Array<{
13
+ event: MemoryEvent;
14
+ decision: MemoryDecision;
15
+ representation: string;
16
+ scope: string;
17
+ }>;
18
+ }
19
+ export declare const rankCandidates: (input: RecallInput) => Array<{
20
+ event: MemoryEvent;
21
+ decision: MemoryDecision;
22
+ score: number;
23
+ representation: string;
24
+ scope: string;
25
+ }>;
26
+ export declare const runRecall: (input: RecallInput) => RecallSelection;
27
+ export declare const buildWakePacketText: (context: WakeMemoryContext, wakeText: string, packet: MemoryPacket) => string;
28
+ //# sourceMappingURL=recall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/recall/recall.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,cAAc,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1G;AAuDD,eAAO,MAAM,cAAc,GAAI,OAAO,WAAW,KAAG,KAAK,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA8D/J,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,WAAW,KAAG,eAwD9C,CAAC;AAkBF,eAAO,MAAM,mBAAmB,GAAI,SAAS,iBAAiB,EAAE,UAAU,MAAM,EAAE,QAAQ,YAAY,KAAG,MAgBxG,CAAC"}
@@ -0,0 +1,178 @@
1
+ import { canonicalPrincipalKey } from "../identity/ids.js";
2
+ import { memoryPriority, memoryPolicy } from "../policy/policy.js";
3
+ const estimateTokens = (text) => Math.max(1, Math.ceil(text.length / 4));
4
+ const textFromEvent = (event) => {
5
+ const fallback = JSON.stringify(event.content);
6
+ if (event.content.kind === "text") {
7
+ return event.content.text.trim();
8
+ }
9
+ if (event.content.kind === "decision") {
10
+ return `${event.content.decision}${event.content.rationale ? ` — ${event.content.rationale}` : ""}`;
11
+ }
12
+ if (event.content.kind === "artifact") {
13
+ return event.content.description;
14
+ }
15
+ if (event.content.kind === "relationship") {
16
+ return `${event.content.from} ${event.content.relation} ${event.content.to}`;
17
+ }
18
+ if (event.content.kind === "claim") {
19
+ return `${event.content.subject} ${event.content.predicate} ${event.content.object}`;
20
+ }
21
+ return fallback;
22
+ };
23
+ const buildRepresentation = (decision, event) => {
24
+ const base = textFromEvent(event);
25
+ if (decision === "allow_raw") {
26
+ return base;
27
+ }
28
+ if (decision === "allow_summary") {
29
+ const summary = base.slice(0, 140);
30
+ return summary.length < base.length ? `${summary}...` : summary;
31
+ }
32
+ if (decision === "allow_redacted_summary") {
33
+ return `[redacted] ${base.slice(0, 100)}...`;
34
+ }
35
+ if (decision === "known_but_private") {
36
+ return "Related private context is available behind policy.";
37
+ }
38
+ return "Memory was blocked by policy.";
39
+ };
40
+ const scoreEvent = (actor, candidateScope, event, queryText) => {
41
+ const text = textFromEvent(event).toLowerCase();
42
+ const overlap = queryText
43
+ .split(" ")
44
+ .map((value) => value.trim().toLowerCase())
45
+ .filter((value) => value.length > 2)
46
+ .reduce((total, token) => total + (text.includes(token) ? 2 : 0), 0);
47
+ const scopeScore = memoryPriority(actor, candidateScope ? { ...event.principal, scope: event.principal.scope } : event.principal);
48
+ const freshness = Date.parse(event.createdAt) / 1000_000;
49
+ return overlap + scopeScore + (freshness % 30_000) / 1000;
50
+ };
51
+ export const rankCandidates = (input) => {
52
+ const allowedScopeSet = new Set(input.scopeIds);
53
+ const query = input.query.toLowerCase();
54
+ const candidateRows = [];
55
+ for (const event of input.events) {
56
+ const policy = memoryPolicy({
57
+ request: input.actor,
58
+ activeScope: input.actor,
59
+ candidate: event
60
+ });
61
+ if (!allowedScopeSet.has(event.scope)) {
62
+ continue;
63
+ }
64
+ if (policy.decision === "deny") {
65
+ continue;
66
+ }
67
+ const representation = buildRepresentation(policy.decision, event);
68
+ candidateRows.push({
69
+ event,
70
+ decision: policy.decision,
71
+ scope: event.scope,
72
+ score: scoreEvent(input.actor, event.scope, event, query),
73
+ representation
74
+ });
75
+ }
76
+ return candidateRows
77
+ .sort((left, right) => {
78
+ const scoreDelta = right.score - left.score;
79
+ if (scoreDelta !== 0) {
80
+ return scoreDelta;
81
+ }
82
+ const timeDelta = Date.parse(right.event.createdAt) - Date.parse(left.event.createdAt);
83
+ if (timeDelta !== 0) {
84
+ return timeDelta;
85
+ }
86
+ const scopeDelta = left.scope.localeCompare(right.scope);
87
+ if (scopeDelta !== 0) {
88
+ return scopeDelta;
89
+ }
90
+ const idDelta = left.event.id.localeCompare(right.event.id);
91
+ if (idDelta !== 0) {
92
+ return idDelta;
93
+ }
94
+ return left.event.checksum.localeCompare(right.event.checksum);
95
+ })
96
+ .map((row) => ({
97
+ event: row.event,
98
+ decision: row.decision,
99
+ score: row.score,
100
+ representation: row.representation,
101
+ scope: row.scope
102
+ }));
103
+ };
104
+ export const runRecall = (input) => {
105
+ const candidates = rankCandidates(input);
106
+ const selected = [];
107
+ const auditDecisions = [];
108
+ let usedTokens = 0;
109
+ let redactions = 0;
110
+ for (const candidate of candidates) {
111
+ const tokens = estimateTokens(candidate.representation);
112
+ if (usedTokens + tokens > input.maxTokens && selected.length > 0) {
113
+ continue;
114
+ }
115
+ selected.push({
116
+ event: candidate.event,
117
+ decision: candidate.decision,
118
+ representation: candidate.representation,
119
+ scope: candidate.scope
120
+ });
121
+ usedTokens += tokens;
122
+ if (candidate.decision === "allow_redacted_summary" || candidate.decision === "known_but_private") {
123
+ redactions += 1;
124
+ }
125
+ auditDecisions.push({
126
+ eventId: candidate.event.id,
127
+ decision: candidate.decision,
128
+ reason: "policy + recall ranking"
129
+ });
130
+ }
131
+ return {
132
+ packet: {
133
+ principal: input.actor,
134
+ sections: selected.map((entry) => ({
135
+ heading: `${entry.scope}: ${entry.event.type}`,
136
+ text: entry.representation
137
+ })),
138
+ rawHint: queryHint(selected, input.actor, input.scopeIds)
139
+ },
140
+ selected,
141
+ audit: {
142
+ totalCandidates: candidates.length,
143
+ selectedEventIds: selected.map((entry) => entry.event.id),
144
+ selected: selected.map((entry) => ({
145
+ eventId: entry.event.id,
146
+ decision: entry.decision,
147
+ scope: entry.scope,
148
+ representation: entry.representation
149
+ })),
150
+ decisions: auditDecisions,
151
+ tokenBudgetUsed: usedTokens,
152
+ redactionCount: redactions
153
+ }
154
+ };
155
+ };
156
+ const queryHint = (selections, actor, scopeIds) => {
157
+ const pending = scopeIds.filter((scope) => !selections.some((selection) => selection.scope === scope));
158
+ if (pending.length > 0) {
159
+ return `Active memory principal ${canonicalPrincipalKey(actor)} has access to ${scopeIds.length} scopes. Missing active data in: ${pending.join(", ")}`;
160
+ }
161
+ return `Active memory principal ${canonicalPrincipalKey(actor)} has no known denials.`;
162
+ };
163
+ export const buildWakePacketText = (context, wakeText, packet) => {
164
+ const room = context.roomId ? `${context.networkId ?? "unknown"}/${context.roomId}` : "global";
165
+ const lines = [
166
+ "## Memory context",
167
+ `Agent: ${packet.principal.agentId}`,
168
+ `Active scope: ${packet.principal.scope}${packet.principal.qualifier ? ` (${packet.principal.qualifier})` : ""}`,
169
+ `Active room: ${room}`,
170
+ "",
171
+ ...packet.sections.map((section) => `- ${section.heading}\n${section.text}`),
172
+ packet.rawHint ? `\nHints: ${packet.rawHint}` : "",
173
+ "",
174
+ "Wake event:",
175
+ wakeText
176
+ ];
177
+ return lines.filter((line) => line.length > 0).join("\n\n");
178
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./runtime.js";
2
+ export * from "./support.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./runtime.js";
2
+ export * from "./support.js";
@@ -0,0 +1,19 @@
1
+ import type { MemoryKernel, MemoryPrepareTurnResult, MemoryRecallRequest, MemoryRuntime, MemoryTurnRecord } from "../contract/types.js";
2
+ export interface JsonlMemoryRuntimeConfig {
3
+ agentId: string;
4
+ runtimeHomePath: string;
5
+ source?: string;
6
+ tokenBudget?: number;
7
+ }
8
+ export declare class JsonlMemoryRuntime implements MemoryRuntime {
9
+ private readonly options;
10
+ private readonly store;
11
+ private readonly source;
12
+ private readonly defaultTokenBudget;
13
+ readonly kernel: MemoryKernel;
14
+ constructor(options: JsonlMemoryRuntimeConfig);
15
+ prepareTurn(request: MemoryRecallRequest): Promise<MemoryPrepareTurnResult>;
16
+ recordTurn(input: MemoryTurnRecord): Promise<void>;
17
+ }
18
+ export declare const createMemoryRuntime: (options: JsonlMemoryRuntimeConfig) => MemoryRuntime;
19
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAEV,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;AAY9B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,kBAAmB,YAAW,aAAa;IAM1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,SAAgB,MAAM,EAAE,YAAY,CAAC;gBAER,OAAO,EAAE,wBAAwB;IAUxD,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmE3E,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAuCzD;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,aACvC,CAAC"}
@@ -0,0 +1,129 @@
1
+ import { buildWakePacketText } from "../recall/recall.js";
2
+ import { JsonlMemoryStore } from "../store/store.js";
3
+ import { memoryScopeId } from "../identity/ids.js";
4
+ import { readMemoryContext, resolveScopePlan } from "../identity/scope.js";
5
+ import { createMemoryKernel } from "../kernel/kernel.js";
6
+ import { buildDecisionEvents, buildRecallInput, clampTokenBudget, defaultSource, deniedMemoryEvents, normalizeScopeIds, readByScopes, recallableEvents, selectToolSummary } from "./support.js";
7
+ const resolveContextFromRequest = (request) => {
8
+ return readMemoryContext({
9
+ kind: request.kind,
10
+ from: request.from,
11
+ text: request.text,
12
+ id: request.eventId,
13
+ context: request.context
14
+ });
15
+ };
16
+ export class JsonlMemoryRuntime {
17
+ options;
18
+ store;
19
+ source;
20
+ defaultTokenBudget;
21
+ kernel;
22
+ constructor(options) {
23
+ this.options = options;
24
+ this.store = new JsonlMemoryStore(options.runtimeHomePath);
25
+ this.source = options.source ?? defaultSource(options.agentId);
26
+ this.defaultTokenBudget = clampTokenBudget(options.tokenBudget);
27
+ this.kernel = createMemoryKernel({
28
+ runtimeHomePath: options.runtimeHomePath,
29
+ source: this.source
30
+ });
31
+ }
32
+ async prepareTurn(request) {
33
+ const context = resolveContextFromRequest(request);
34
+ const scopePlan = resolveScopePlan({
35
+ agentId: this.options.agentId,
36
+ context,
37
+ wake: {
38
+ id: request.eventId,
39
+ kind: request.kind,
40
+ from: request.from
41
+ }
42
+ });
43
+ const scopeIds = normalizeScopeIds(scopePlan.readableScopes.map(memoryScopeId));
44
+ const events = recallableEvents(await readByScopes(this.store, scopeIds));
45
+ const recall = buildRecallInput({
46
+ actor: scopePlan.activePrincipal,
47
+ scopeIds,
48
+ events,
49
+ text: request.text,
50
+ maxTokens: request.tokenBudget ?? this.defaultTokenBudget
51
+ });
52
+ const denied = deniedMemoryEvents({
53
+ requester: scopePlan.activePrincipal,
54
+ activeScope: scopePlan.activePrincipal,
55
+ events,
56
+ selectedIds: new Set(recall.audit.selectedEventIds)
57
+ });
58
+ if (denied.length > 0) {
59
+ await this.store.appendBatch(denied.map(({ event, reason }) => ({
60
+ type: "memory.denied",
61
+ principal: scopePlan.activePrincipal,
62
+ scope: memoryScopeId(scopePlan.activePrincipal),
63
+ visibility: "private",
64
+ source: this.source,
65
+ content: {
66
+ kind: "text",
67
+ text: `Denied ${event.id}: ${reason}`
68
+ },
69
+ tags: ["denied", "recall"],
70
+ entities: [event.id],
71
+ parentEventIds: [event.id],
72
+ sensitivity: "normal"
73
+ })));
74
+ }
75
+ const wakeText = [
76
+ "## Wake",
77
+ `id: ${request.eventId}`,
78
+ `kind: ${request.kind}`,
79
+ `from: ${request.from ?? "operator"}`,
80
+ `network: ${context.networkId ?? "global"}`,
81
+ `room: ${context.roomId ?? "global"}`,
82
+ "",
83
+ request.text
84
+ ].join("\n");
85
+ const promptText = buildWakePacketText(context, wakeText, recall.packet);
86
+ return {
87
+ principal: scopePlan.activePrincipal,
88
+ packet: recall.packet,
89
+ promptText,
90
+ recall: recall.audit
91
+ };
92
+ }
93
+ async recordTurn(input) {
94
+ const scope = memoryScopeId(input.principal);
95
+ const parentEventIds = (await this.store.read({
96
+ principalAgentId: input.principal.agentId,
97
+ principalScope: input.principal.scope
98
+ })).map((event) => event.id);
99
+ const recall = input.recall ?? {
100
+ totalCandidates: 0,
101
+ selectedEventIds: [],
102
+ selected: [],
103
+ decisions: [],
104
+ tokenBudgetUsed: 0,
105
+ redactionCount: 0
106
+ };
107
+ const events = buildDecisionEvents({
108
+ principal: input.principal,
109
+ scope,
110
+ source: this.source,
111
+ request: input.request,
112
+ packet: input.prompt,
113
+ recall,
114
+ result: input.result,
115
+ outputText: input.outputText,
116
+ error: input.error,
117
+ parentEventIds
118
+ });
119
+ const toolSummary = selectToolSummary(input.toolEvents ?? []);
120
+ if (toolSummary) {
121
+ toolSummary.parentEventIds = parentEventIds;
122
+ toolSummary.scope = scope;
123
+ toolSummary.principal = input.principal;
124
+ events.push(toolSummary);
125
+ }
126
+ await this.store.appendBatch(events);
127
+ }
128
+ }
129
+ export const createMemoryRuntime = (options) => new JsonlMemoryRuntime(options);
@@ -0,0 +1,52 @@
1
+ import { runRecall } from "../recall/recall.js";
2
+ import { JsonlMemoryStore } from "../store/store.js";
3
+ import type { MemoryDecision, MemoryEvent, MemoryEventInput, MemoryPacket, MemoryPrincipalRef, MemoryRecallAudit, MemoryRecallRequest, MemoryTurnRecord } from "../contract/types.js";
4
+ export interface MemoryRecallEntry {
5
+ event: MemoryEvent;
6
+ decision: MemoryDecision;
7
+ representation: string;
8
+ scope: string;
9
+ }
10
+ export declare const defaultSource: (agentId: string) => string;
11
+ export declare const clampTokenBudget: (value: number | undefined) => number;
12
+ export declare const normalizeScopeIds: (ids: string[]) => string[];
13
+ export declare const readByScopes: (store: JsonlMemoryStore, scopeIds: string[]) => Promise<MemoryEvent[]>;
14
+ export declare const recallableEvents: (events: MemoryEvent[]) => MemoryEvent[];
15
+ export declare const deniedMemoryEvents: (input: {
16
+ requester: MemoryPrincipalRef;
17
+ activeScope: MemoryPrincipalRef;
18
+ events: MemoryEvent[];
19
+ selectedIds: Set<string>;
20
+ }) => Array<{
21
+ event: MemoryEvent;
22
+ reason: string;
23
+ }>;
24
+ export declare const buildRecallInput: (input: {
25
+ actor: MemoryPrincipalRef;
26
+ scopeIds: string[];
27
+ events: MemoryEvent[];
28
+ text: string;
29
+ maxTokens?: number;
30
+ }) => ReturnType<typeof runRecall>;
31
+ export declare const buildDecisionEvents: (input: {
32
+ principal: MemoryPrincipalRef;
33
+ scope: string;
34
+ source: string;
35
+ request: MemoryRecallRequest;
36
+ packet: MemoryPacket;
37
+ recall: MemoryRecallAudit;
38
+ result: MemoryTurnRecord["result"];
39
+ outputText: string;
40
+ error?: string;
41
+ parentEventIds: string[];
42
+ }) => MemoryEventInput[];
43
+ export declare const selectToolSummary: (toolEvents: unknown[]) => MemoryEventInput | undefined;
44
+ export declare const runMemorySelection: (input: {
45
+ requester: MemoryPrincipalRef;
46
+ scopeIds: string[];
47
+ events: MemoryEvent[];
48
+ query: string;
49
+ maxResults?: number;
50
+ }) => MemoryRecallEntry[];
51
+ export { runRecall };
52
+ //# sourceMappingURL=support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../src/runtime/support.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,YAAY,EAEZ,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,MAA6C,CAAC;AAE9F,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAK5D,CAAC;AAOF,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,EAAE,KAAG,MAAM,EAEvD,CAAC;AAWF,eAAO,MAAM,YAAY,GACvB,OAAO,gBAAgB,EACvB,UAAU,MAAM,EAAE,KACjB,OAAO,CAAC,WAAW,EAAE,CAcvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,WAAW,EAAE,KAAG,WAAW,EAanE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO;IACxC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B,KAAG,KAAK,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAa5C,CAAC;AAEL,eAAO,MAAM,gBAAgB,GAAI,OAAO;IACtC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,KAAG,UAAU,CAAC,OAAO,SAAS,CAQ9B,CAAC;AAiEF,eAAO,MAAM,mBAAmB,GAAI,OAAO;IACzC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,KAAG,gBAAgB,EAqFnB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,OAAO,EAAE,KAAG,gBAAgB,GAAG,SAsB5E,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO;IACxC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,KAAG,iBAAiB,EAgBpB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}