ahok-skill 1.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.
Files changed (141) hide show
  1. package/.prettierrc +8 -0
  2. package/Dockerfile +59 -0
  3. package/RAW_SKILL.md +219 -0
  4. package/README.md +277 -0
  5. package/SKILL.md +58 -0
  6. package/bin/opm.js +268 -0
  7. package/data/openmemory.sqlite +0 -0
  8. package/data/openmemory.sqlite-shm +0 -0
  9. package/data/openmemory.sqlite-wal +0 -0
  10. package/dist/ai/graph.js +293 -0
  11. package/dist/ai/mcp.js +397 -0
  12. package/dist/cli.js +78 -0
  13. package/dist/core/cfg.js +87 -0
  14. package/dist/core/db.js +636 -0
  15. package/dist/core/memory.js +116 -0
  16. package/dist/core/migrate.js +227 -0
  17. package/dist/core/models.js +105 -0
  18. package/dist/core/telemetry.js +57 -0
  19. package/dist/core/types.js +2 -0
  20. package/dist/core/vector/postgres.js +52 -0
  21. package/dist/core/vector/valkey.js +246 -0
  22. package/dist/core/vector_store.js +2 -0
  23. package/dist/index.js +44 -0
  24. package/dist/memory/decay.js +301 -0
  25. package/dist/memory/embed.js +675 -0
  26. package/dist/memory/hsg.js +959 -0
  27. package/dist/memory/reflect.js +131 -0
  28. package/dist/memory/user_summary.js +99 -0
  29. package/dist/migrate.js +9 -0
  30. package/dist/ops/compress.js +255 -0
  31. package/dist/ops/dynamics.js +189 -0
  32. package/dist/ops/extract.js +333 -0
  33. package/dist/ops/ingest.js +214 -0
  34. package/dist/server/index.js +109 -0
  35. package/dist/server/middleware/auth.js +137 -0
  36. package/dist/server/routes/auth.js +186 -0
  37. package/dist/server/routes/compression.js +108 -0
  38. package/dist/server/routes/dashboard.js +399 -0
  39. package/dist/server/routes/docs.js +241 -0
  40. package/dist/server/routes/dynamics.js +312 -0
  41. package/dist/server/routes/ide.js +280 -0
  42. package/dist/server/routes/index.js +33 -0
  43. package/dist/server/routes/keys.js +132 -0
  44. package/dist/server/routes/langgraph.js +61 -0
  45. package/dist/server/routes/memory.js +213 -0
  46. package/dist/server/routes/sources.js +140 -0
  47. package/dist/server/routes/system.js +63 -0
  48. package/dist/server/routes/temporal.js +293 -0
  49. package/dist/server/routes/users.js +101 -0
  50. package/dist/server/routes/vercel.js +57 -0
  51. package/dist/server/server.js +211 -0
  52. package/dist/server.js +3 -0
  53. package/dist/sources/base.js +223 -0
  54. package/dist/sources/github.js +171 -0
  55. package/dist/sources/google_drive.js +166 -0
  56. package/dist/sources/google_sheets.js +112 -0
  57. package/dist/sources/google_slides.js +139 -0
  58. package/dist/sources/index.js +34 -0
  59. package/dist/sources/notion.js +165 -0
  60. package/dist/sources/onedrive.js +143 -0
  61. package/dist/sources/web_crawler.js +166 -0
  62. package/dist/temporal_graph/index.js +20 -0
  63. package/dist/temporal_graph/query.js +240 -0
  64. package/dist/temporal_graph/store.js +116 -0
  65. package/dist/temporal_graph/timeline.js +241 -0
  66. package/dist/temporal_graph/types.js +2 -0
  67. package/dist/utils/chunking.js +60 -0
  68. package/dist/utils/index.js +31 -0
  69. package/dist/utils/keyword.js +94 -0
  70. package/dist/utils/text.js +120 -0
  71. package/nodemon.json +7 -0
  72. package/package.json +50 -0
  73. package/references/api_reference.md +66 -0
  74. package/references/examples.md +45 -0
  75. package/src/ai/graph.ts +363 -0
  76. package/src/ai/mcp.ts +494 -0
  77. package/src/cli.ts +94 -0
  78. package/src/core/cfg.ts +110 -0
  79. package/src/core/db.ts +1052 -0
  80. package/src/core/memory.ts +99 -0
  81. package/src/core/migrate.ts +302 -0
  82. package/src/core/models.ts +107 -0
  83. package/src/core/telemetry.ts +47 -0
  84. package/src/core/types.ts +130 -0
  85. package/src/core/vector/postgres.ts +61 -0
  86. package/src/core/vector/valkey.ts +261 -0
  87. package/src/core/vector_store.ts +9 -0
  88. package/src/index.ts +5 -0
  89. package/src/memory/decay.ts +427 -0
  90. package/src/memory/embed.ts +707 -0
  91. package/src/memory/hsg.ts +1245 -0
  92. package/src/memory/reflect.ts +158 -0
  93. package/src/memory/user_summary.ts +110 -0
  94. package/src/migrate.ts +8 -0
  95. package/src/ops/compress.ts +296 -0
  96. package/src/ops/dynamics.ts +272 -0
  97. package/src/ops/extract.ts +360 -0
  98. package/src/ops/ingest.ts +286 -0
  99. package/src/server/index.ts +159 -0
  100. package/src/server/middleware/auth.ts +156 -0
  101. package/src/server/routes/auth.ts +223 -0
  102. package/src/server/routes/compression.ts +106 -0
  103. package/src/server/routes/dashboard.ts +420 -0
  104. package/src/server/routes/docs.ts +380 -0
  105. package/src/server/routes/dynamics.ts +516 -0
  106. package/src/server/routes/ide.ts +283 -0
  107. package/src/server/routes/index.ts +32 -0
  108. package/src/server/routes/keys.ts +131 -0
  109. package/src/server/routes/langgraph.ts +71 -0
  110. package/src/server/routes/memory.ts +440 -0
  111. package/src/server/routes/sources.ts +111 -0
  112. package/src/server/routes/system.ts +68 -0
  113. package/src/server/routes/temporal.ts +335 -0
  114. package/src/server/routes/users.ts +111 -0
  115. package/src/server/routes/vercel.ts +55 -0
  116. package/src/server/server.js +215 -0
  117. package/src/server.ts +1 -0
  118. package/src/sources/base.ts +257 -0
  119. package/src/sources/github.ts +156 -0
  120. package/src/sources/google_drive.ts +144 -0
  121. package/src/sources/google_sheets.ts +85 -0
  122. package/src/sources/google_slides.ts +115 -0
  123. package/src/sources/index.ts +19 -0
  124. package/src/sources/notion.ts +148 -0
  125. package/src/sources/onedrive.ts +131 -0
  126. package/src/sources/web_crawler.ts +161 -0
  127. package/src/temporal_graph/index.ts +4 -0
  128. package/src/temporal_graph/query.ts +299 -0
  129. package/src/temporal_graph/store.ts +156 -0
  130. package/src/temporal_graph/timeline.ts +319 -0
  131. package/src/temporal_graph/types.ts +41 -0
  132. package/src/utils/chunking.ts +66 -0
  133. package/src/utils/index.ts +25 -0
  134. package/src/utils/keyword.ts +137 -0
  135. package/src/utils/text.ts +115 -0
  136. package/tests/test_api_workspace_management.ts +413 -0
  137. package/tests/test_bulk_delete.ts +267 -0
  138. package/tests/test_omnibus.ts +166 -0
  139. package/tests/test_workspace_management.ts +278 -0
  140. package/tests/verify.ts +104 -0
  141. package/tsconfig.json +15 -0
@@ -0,0 +1,363 @@
1
+ import { env } from "../core/cfg";
2
+ import { add_hsg_memory, hsg_query } from "../memory/hsg";
3
+ import { q, vector_store } from "../core/db";
4
+ import { now, j } from "../utils";
5
+ import type {
6
+ lgm_store_req,
7
+ lgm_retrieve_req,
8
+ lgm_context_req,
9
+ lgm_reflection_req,
10
+ sector_type,
11
+ mem_row,
12
+ } from "../core/types";
13
+
14
+ type hydrated_mem = {
15
+ id: string;
16
+ node: string;
17
+ content: string;
18
+ primary_sector: string;
19
+ sectors: string[];
20
+ tags: string[];
21
+ created_at: number;
22
+ updated_at: number;
23
+ last_seen_at: number;
24
+ salience: number;
25
+ decay_lambda: number;
26
+ version: number;
27
+ score?: number;
28
+ path?: string[];
29
+ metadata?: Record<string, unknown>;
30
+ };
31
+
32
+ export const node_sector_map: Record<string, sector_type> = {
33
+ observe: "episodic",
34
+ plan: "semantic",
35
+ reflect: "reflective",
36
+ act: "procedural",
37
+ emotion: "emotional",
38
+ };
39
+
40
+ const default_sector: sector_type = "semantic";
41
+ const summary_line_limit = 160;
42
+
43
+ const trunc = (txt: string, max = 320) =>
44
+ txt.length <= max ? txt : `${txt.slice(0, max).trimEnd()}...`;
45
+
46
+ const safe_parse = <T>(val: string | null, fb: T): T => {
47
+ if (!val) return fb;
48
+ try {
49
+ return JSON.parse(val) as T;
50
+ } catch {
51
+ return fb;
52
+ }
53
+ };
54
+
55
+ const resolve_sector = (node: string): sector_type =>
56
+ node_sector_map[node.toLowerCase()] ?? default_sector;
57
+
58
+ const resolve_ns = (ns?: string) => ns || env.lg_namespace;
59
+
60
+ const build_tags = (
61
+ tags: string[] | undefined,
62
+ node: string,
63
+ ns: string,
64
+ gid?: string,
65
+ ) => {
66
+ const ts = new Set<string>(tags || []);
67
+ ts.add(`lgm:node:${node.toLowerCase()}`);
68
+ ts.add(`lgm:namespace:${ns}`);
69
+ if (gid) ts.add(`lgm:graph:${gid}`);
70
+ return Array.from(ts);
71
+ };
72
+
73
+ const build_meta = (
74
+ p: lgm_store_req,
75
+ sec: sector_type,
76
+ ns: string,
77
+ ext?: Record<string, unknown>,
78
+ ) => {
79
+ const base = { ...(p.metadata || {}) } as Record<string, unknown>;
80
+ const ex_lgm =
81
+ typeof base.lgm === "object" && base.lgm !== null
82
+ ? (base.lgm as Record<string, unknown>)
83
+ : {};
84
+ base.lgm = {
85
+ ...ex_lgm,
86
+ node: p.node.toLowerCase(),
87
+ sector: sec,
88
+ namespace: ns,
89
+ graph_id: p.graph_id ?? null,
90
+ stored_at: now(),
91
+ mode: "langgraph",
92
+ ...ext,
93
+ };
94
+ return base;
95
+ };
96
+
97
+ const matches_ns = (
98
+ meta: Record<string, unknown>,
99
+ ns: string,
100
+ gid?: string,
101
+ ) => {
102
+ const lgm = meta?.lgm as Record<string, unknown> | undefined;
103
+ if (!lgm) return false;
104
+ if (lgm.namespace !== ns) return false;
105
+ if (gid && lgm.graph_id !== gid) return false;
106
+ return true;
107
+ };
108
+
109
+ const hydrate_mem_row = async (
110
+ row: mem_row,
111
+ meta: Record<string, unknown>,
112
+ inc_meta: boolean,
113
+ score?: number,
114
+ path?: string[],
115
+ ): Promise<hydrated_mem> => {
116
+ const tags = safe_parse<string[]>(row.tags, []);
117
+ const vecs = await vector_store.getVectorsById(row.id);
118
+ const secs = vecs.map((v) => v.sector);
119
+ const mem: hydrated_mem = {
120
+ id: row.id,
121
+ node:
122
+ ((meta?.lgm as Record<string, unknown> | undefined)
123
+ ?.node as string) || row.primary_sector,
124
+ content: row.content,
125
+ primary_sector: row.primary_sector,
126
+ sectors: secs,
127
+ tags,
128
+ created_at: row.created_at,
129
+ updated_at: row.updated_at,
130
+ last_seen_at: row.last_seen_at,
131
+ salience: row.salience,
132
+ decay_lambda: row.decay_lambda,
133
+ version: row.version,
134
+ };
135
+ if (typeof score === "number") mem.score = score;
136
+ if (path) mem.path = path;
137
+ if (inc_meta) mem.metadata = meta;
138
+ return mem;
139
+ };
140
+
141
+ const build_refl_content = (p: lgm_store_req, ns: string) => {
142
+ const parts = [
143
+ `LangGraph reflection for node "${p.node}"`,
144
+ `namespace=${ns}`,
145
+ ];
146
+ if (p.graph_id) parts.push(`graph=${p.graph_id}`);
147
+ return `${parts.join(" | ")}\n\n${trunc(p.content, 480)}`;
148
+ };
149
+
150
+ const create_auto_refl = async (
151
+ p: lgm_store_req,
152
+ stored: { id: string; namespace: string; graph_id: string | null },
153
+ ) => {
154
+ const refl_tags = build_tags(
155
+ [`lgm:auto:reflection`, `lgm:source:${stored.id}`],
156
+ "reflect",
157
+ stored.namespace,
158
+ stored.graph_id ?? undefined,
159
+ );
160
+ const refl_meta = {
161
+ lgm: {
162
+ node: "reflect",
163
+ sector: "reflective",
164
+ namespace: stored.namespace,
165
+ graph_id: stored.graph_id,
166
+ stored_at: now(),
167
+ mode: "langgraph",
168
+ source_memory: stored.id,
169
+ source_node: p.node.toLowerCase(),
170
+ },
171
+ };
172
+ const res = await add_hsg_memory(
173
+ build_refl_content(p, stored.namespace),
174
+ j(refl_tags),
175
+ refl_meta,
176
+ p.user_id,
177
+ );
178
+ return {
179
+ id: res.id,
180
+ node: "reflect",
181
+ primary_sector: res.primary_sector,
182
+ sectors: res.sectors,
183
+ namespace: stored.namespace,
184
+ graph_id: stored.graph_id,
185
+ tags: refl_tags,
186
+ chunks: res.chunks ?? 1,
187
+ metadata: refl_meta,
188
+ };
189
+ };
190
+
191
+ export async function store_node_mem(p: lgm_store_req) {
192
+ if (!p?.node || !p?.content)
193
+ throw new Error("node and content are required");
194
+ const ns = resolve_ns(p.namespace);
195
+ const node = p.node.toLowerCase();
196
+ const sec = resolve_sector(node);
197
+ const tag_list = build_tags(p.tags, node, ns, p.graph_id);
198
+ const meta = build_meta(p, sec, ns);
199
+ const res = await add_hsg_memory(p.content, j(tag_list), meta, p.user_id);
200
+ const stored = {
201
+ id: res.id,
202
+ node,
203
+ primary_sector: res.primary_sector,
204
+ sectors: res.sectors,
205
+ namespace: ns,
206
+ graph_id: p.graph_id ?? null,
207
+ tags: tag_list,
208
+ chunks: res.chunks ?? 1,
209
+ metadata: meta,
210
+ };
211
+ const refl_set = p.reflective ?? env.lg_reflective;
212
+ const refl =
213
+ refl_set && node !== "reflect"
214
+ ? await create_auto_refl(p, stored)
215
+ : null;
216
+ return { memory: stored, reflection: refl };
217
+ }
218
+
219
+ export async function retrieve_node_mems(p: lgm_retrieve_req) {
220
+ if (!p?.node) throw new Error("node is required");
221
+ const ns = resolve_ns(p.namespace);
222
+ const node = p.node.toLowerCase();
223
+ const sec = resolve_sector(node);
224
+ const lim = p.limit || env.lg_max_context;
225
+ const inc_meta = p.include_metadata ?? false;
226
+ const gid = p.graph_id;
227
+ const items: hydrated_mem[] = [];
228
+ if (p.query) {
229
+ const matches = await hsg_query(p.query, Math.max(lim * 2, lim), {
230
+ sectors: [sec],
231
+ });
232
+ for (const match of matches) {
233
+ const row = (await q.get_mem.get(match.id)) as mem_row | undefined;
234
+ if (!row) continue;
235
+ const meta = safe_parse<Record<string, unknown>>(row.meta, {});
236
+ if (!matches_ns(meta, ns, gid)) continue;
237
+ const hyd = await hydrate_mem_row(
238
+ row,
239
+ meta,
240
+ inc_meta,
241
+ match.score,
242
+ match.path,
243
+ );
244
+ items.push(hyd);
245
+ if (items.length >= lim) break;
246
+ }
247
+ } else {
248
+ const raw_rows = (await q.all_mem_by_sector.all(
249
+ sec,
250
+ lim * 4,
251
+ 0,
252
+ )) as mem_row[];
253
+ for (const row of raw_rows) {
254
+ const meta = safe_parse<Record<string, unknown>>(row.meta, {});
255
+ if (!matches_ns(meta, ns, gid)) continue;
256
+ const hyd = await hydrate_mem_row(row, meta, inc_meta);
257
+ items.push(hyd);
258
+ if (items.length >= lim) break;
259
+ }
260
+ items.sort((a, b) => b.last_seen_at - a.last_seen_at);
261
+ }
262
+ return {
263
+ node,
264
+ sector: sec,
265
+ namespace: ns,
266
+ graph_id: gid ?? null,
267
+ query: p.query || null,
268
+ count: items.length,
269
+ items,
270
+ };
271
+ }
272
+
273
+ export async function get_graph_ctx(p: lgm_context_req) {
274
+ const ns = resolve_ns(p.namespace);
275
+ const gid = p.graph_id;
276
+ const lim = p.limit || env.lg_max_context;
277
+ const nodes = Object.keys(node_sector_map);
278
+ const per_node_lim = Math.max(1, Math.floor(lim / nodes.length) || 1);
279
+ const node_ctxs = [];
280
+ for (const node of nodes) {
281
+ const res = await retrieve_node_mems({
282
+ node,
283
+ namespace: ns,
284
+ graph_id: gid,
285
+ limit: per_node_lim,
286
+ include_metadata: true,
287
+ });
288
+ node_ctxs.push({ node, sector: res.sector, items: res.items });
289
+ }
290
+ const flat = node_ctxs.flatMap((e) =>
291
+ e.items.map((i) => ({
292
+ node: e.node,
293
+ content: trunc(i.content, summary_line_limit),
294
+ })),
295
+ );
296
+ const summ = flat.length
297
+ ? flat
298
+ .slice(0, lim)
299
+ .map((ln) => `- [${ln.node}] ${ln.content}`)
300
+ .join("\n")
301
+ : "";
302
+ return {
303
+ namespace: ns,
304
+ graph_id: gid ?? null,
305
+ limit: lim,
306
+ nodes: node_ctxs,
307
+ summary: summ,
308
+ };
309
+ }
310
+
311
+ const build_ctx_refl = async (ns: string, gid?: string) => {
312
+ const ctx = await get_graph_ctx({
313
+ namespace: ns,
314
+ graph_id: gid,
315
+ limit: env.lg_max_context,
316
+ });
317
+ const lns = ctx.nodes.flatMap((e) =>
318
+ e.items.map((i) => ({
319
+ node: e.node,
320
+ content: trunc(i.content, summary_line_limit),
321
+ })),
322
+ );
323
+ if (!lns.length) return null;
324
+ const hdr = `Reflection synthesized from LangGraph context (namespace=${ns}${gid ? `, graph=${gid}` : ""})`;
325
+ const body = lns
326
+ .slice(0, env.lg_max_context)
327
+ .map((ln, idx) => `${idx + 1}. [${ln.node}] ${ln.content}`)
328
+ .join("\n");
329
+ return `${hdr}\n\n${body}`;
330
+ };
331
+
332
+ export async function create_refl(p: lgm_reflection_req) {
333
+ const ns = resolve_ns(p.namespace);
334
+ const node = (p.node || "reflect").toLowerCase();
335
+ const base_content = p.content || (await build_ctx_refl(ns, p.graph_id));
336
+ if (!base_content)
337
+ throw new Error("reflection content could not be derived");
338
+ const tags = [
339
+ `lgm:manual:reflection`,
340
+ ...(p.context_ids?.map((id) => `lgm:context:${id}`) || []),
341
+ ];
342
+ const meta: Record<string, unknown> = {
343
+ lgm_context_ids: p.context_ids || [],
344
+ };
345
+ const res = await store_node_mem({
346
+ node,
347
+ content: base_content,
348
+ namespace: ns,
349
+ graph_id: p.graph_id,
350
+ tags,
351
+ metadata: meta,
352
+ reflective: false,
353
+ });
354
+ return res;
355
+ }
356
+
357
+ export const get_lg_cfg = () => ({
358
+ mode: env.mode,
359
+ namespace_default: env.lg_namespace,
360
+ max_context: env.lg_max_context,
361
+ reflective: env.lg_reflective,
362
+ node_sector_map,
363
+ });