@pentatonic-ai/ai-agent-sdk 0.6.0 → 0.7.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 (94) hide show
  1. package/README.md +170 -69
  2. package/bin/__tests__/callback-server.test.js +4 -1
  3. package/bin/cli.js +41 -164
  4. package/bin/commands/config.js +251 -0
  5. package/package.json +2 -1
  6. package/packages/doctor/__tests__/detect.test.js +2 -6
  7. package/packages/doctor/src/checks/local-memory.js +164 -196
  8. package/packages/doctor/src/detect.js +11 -3
  9. package/packages/memory/src/corpus/adapters.js +104 -0
  10. package/packages/memory/src/corpus/cli.js +72 -7
  11. package/packages/memory/src/corpus/index.js +1 -1
  12. package/packages/memory-engine/.env.example +13 -0
  13. package/packages/memory-engine/README.md +131 -0
  14. package/packages/memory-engine/bench/README.md +99 -0
  15. package/packages/memory-engine/bench/scorecards-engine/agent-coding__pentatonic-baseline__20260427-142523.json +1115 -0
  16. package/packages/memory-engine/bench/scorecards-engine/chat-recall__pentatonic-baseline__20260427-142648.json +819 -0
  17. package/packages/memory-engine/bench/scorecards-engine/circular-economy__pentatonic-baseline__20260427-142757.json +1278 -0
  18. package/packages/memory-engine/bench/scorecards-engine/customer-support__pentatonic-baseline__20260427-142900.json +1018 -0
  19. package/packages/memory-engine/bench/scorecards-engine/marketplace-ops__pentatonic-baseline__20260427-142957.json +1038 -0
  20. package/packages/memory-engine/bench/scorecards-engine/product-catalogue__pentatonic-baseline__20260427-143122.json +961 -0
  21. package/packages/memory-engine/bench/scorecards-engine-via-docker/agent-coding__pentatonic-memory__20260427-161812.json +1115 -0
  22. package/packages/memory-engine/bench/scorecards-engine-via-docker/chat-recall__pentatonic-memory__20260427-161701.json +819 -0
  23. package/packages/memory-engine/bench/scorecards-engine-via-docker/circular-economy__pentatonic-memory__20260427-161713.json +1278 -0
  24. package/packages/memory-engine/bench/scorecards-engine-via-docker/customer-support__pentatonic-memory__20260427-161723.json +1018 -0
  25. package/packages/memory-engine/bench/scorecards-engine-via-docker/marketplace-ops__pentatonic-memory__20260427-161732.json +1038 -0
  26. package/packages/memory-engine/bench/scorecards-engine-via-docker/product-catalogue__pentatonic-memory__20260427-161741.json +937 -0
  27. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/agent-coding__pentatonic-memory__20260427-184718.json +1115 -0
  28. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/chat-recall__pentatonic-memory__20260427-184614.json +819 -0
  29. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/circular-economy__pentatonic-memory__20260427-184809.json +1278 -0
  30. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/customer-support__pentatonic-memory__20260427-184854.json +1018 -0
  31. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/marketplace-ops__pentatonic-memory__20260427-184929.json +1038 -0
  32. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/product-catalogue__pentatonic-memory__20260427-185015.json +961 -0
  33. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/agent-coding__pentatonic-memory__20260427-175252.json +1115 -0
  34. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/chat-recall__pentatonic-memory__20260427-175312.json +819 -0
  35. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/circular-economy__pentatonic-memory__20260427-175335.json +1278 -0
  36. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/customer-support__pentatonic-memory__20260427-175355.json +1018 -0
  37. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/marketplace-ops__pentatonic-memory__20260427-175413.json +1038 -0
  38. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/product-catalogue__pentatonic-memory__20260427-175430.json +883 -0
  39. package/packages/memory-engine/bench/scorecards-engine-via-shim/agent-coding__pentatonic-memory__20260427-155409.json +1115 -0
  40. package/packages/memory-engine/bench/scorecards-engine-via-shim/chat-recall__pentatonic-memory__20260427-155421.json +819 -0
  41. package/packages/memory-engine/bench/scorecards-engine-via-shim/circular-economy__pentatonic-memory__20260427-155433.json +1278 -0
  42. package/packages/memory-engine/bench/scorecards-engine-via-shim/customer-support__pentatonic-memory__20260427-155443.json +1018 -0
  43. package/packages/memory-engine/bench/scorecards-engine-via-shim/marketplace-ops__pentatonic-memory__20260427-155453.json +1038 -0
  44. package/packages/memory-engine/bench/scorecards-engine-via-shim/product-catalogue__pentatonic-memory__20260427-155503.json +937 -0
  45. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/agent-coding__pentatonic-memory-latest__20260427-145103.json +1115 -0
  46. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/agent-coding__pentatonic-memory__20260427-144909.json +1115 -0
  47. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/chat-recall__pentatonic-memory-latest__20260427-145153.json +819 -0
  48. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/chat-recall__pentatonic-memory__20260427-145120.json +542 -0
  49. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/circular-economy__pentatonic-memory-latest__20260427-145313.json +1278 -0
  50. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/circular-economy__pentatonic-memory__20260427-145207.json +894 -0
  51. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/customer-support__pentatonic-memory-latest__20260427-145412.json +1018 -0
  52. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/customer-support__pentatonic-memory__20260427-145327.json +680 -0
  53. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/marketplace-ops__pentatonic-memory-latest__20260427-145517.json +1038 -0
  54. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/marketplace-ops__pentatonic-memory__20260427-145422.json +693 -0
  55. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/product-catalogue__pentatonic-memory-latest__20260427-145616.json +961 -0
  56. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/product-catalogue__pentatonic-memory__20260427-145528.json +727 -0
  57. package/packages/memory-engine/compat/Dockerfile +11 -0
  58. package/packages/memory-engine/compat/server.py +680 -0
  59. package/packages/memory-engine/docker-compose.yml +243 -0
  60. package/packages/memory-engine/docs/MIGRATION.md +178 -0
  61. package/packages/memory-engine/docs/RUNBOOK-AWS.md +375 -0
  62. package/packages/memory-engine/docs/why-v05-underperforms.md +138 -0
  63. package/packages/memory-engine/engine/README.md +52 -0
  64. package/packages/memory-engine/engine/l2-hybridrag-proxy.py +1543 -0
  65. package/packages/memory-engine/engine/l5-comms-layer.py +663 -0
  66. package/packages/memory-engine/engine/l6-document-store.py +1018 -0
  67. package/packages/memory-engine/engine/services/l2/Dockerfile +41 -0
  68. package/packages/memory-engine/engine/services/l2/init_databases.py +81 -0
  69. package/packages/memory-engine/engine/services/l2/l2-hybridrag-proxy.py +1543 -0
  70. package/packages/memory-engine/engine/services/l4/Dockerfile +15 -0
  71. package/packages/memory-engine/engine/services/l4/server.py +235 -0
  72. package/packages/memory-engine/engine/services/l5/Dockerfile +9 -0
  73. package/packages/memory-engine/engine/services/l5/l5-comms-layer.py +678 -0
  74. package/packages/memory-engine/engine/services/l6/Dockerfile +11 -0
  75. package/packages/memory-engine/engine/services/l6/l6-document-store.py +1016 -0
  76. package/packages/memory-engine/engine/services/nv-embed/Dockerfile +28 -0
  77. package/packages/memory-engine/engine/services/nv-embed/server.py +152 -0
  78. package/packages/memory-engine/pme_memory/__init__.py +0 -0
  79. package/packages/memory-engine/pme_memory/__main__.py +129 -0
  80. package/packages/memory-engine/pme_memory/artifacts.py +95 -0
  81. package/packages/memory-engine/pme_memory/embed.py +74 -0
  82. package/packages/memory-engine/pme_memory/health.py +36 -0
  83. package/packages/memory-engine/pme_memory/hygiene.py +159 -0
  84. package/packages/memory-engine/pme_memory/indexer.py +200 -0
  85. package/packages/memory-engine/pme_memory/needs.py +55 -0
  86. package/packages/memory-engine/pme_memory/provenance.py +80 -0
  87. package/packages/memory-engine/pme_memory/scoring.py +168 -0
  88. package/packages/memory-engine/pme_memory/search.py +52 -0
  89. package/packages/memory-engine/pme_memory/store.py +86 -0
  90. package/packages/memory-engine/pme_memory/synthesis.py +114 -0
  91. package/packages/memory-engine/pyproject.toml +65 -0
  92. package/packages/memory-engine/scripts/kg-extractor.py +557 -0
  93. package/packages/memory-engine/scripts/kg-preflexor-v2.py +738 -0
  94. package/packages/memory-engine/tests/test_api_contract.sh +57 -0
@@ -0,0 +1,251 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+
5
+ const DEFAULT_ENGINE_URL = "http://localhost:8099";
6
+
7
+ /**
8
+ * Top-level dispatcher for `tes config <sub>`.
9
+ *
10
+ * Subcommands:
11
+ * local — write `mode: local` + memory_url to the plugin config; print
12
+ * bring-up instructions for the engine docker stack.
13
+ * hosted — run the SDK login flow (writes ~/.config/tes/credentials.json
14
+ * and updates the plugin config to hosted mode).
15
+ * show — read the plugin config + credentials and print what's
16
+ * currently configured.
17
+ *
18
+ * Future:
19
+ * set <key> <value> — tweak engine env vars (EMBED_MODEL, EMBED_DIM, …)
20
+ * and reload docker-compose.
21
+ *
22
+ * @param {object} opts
23
+ * @param {string} opts.sub - subcommand name
24
+ * @param {string} [opts.endpoint] - default TES endpoint (forwarded to login)
25
+ * @param {string} [opts.engineUrl] - override for `local`
26
+ * @param {string} [opts.configDir] - override config-file dir (test hook)
27
+ * @param {Function} [opts.log]
28
+ * @param {Function} [opts.errLog]
29
+ */
30
+ export async function runConfigCommand(opts = {}) {
31
+ const log = opts.log || ((m) => process.stdout.write(m + "\n"));
32
+ const errLog = opts.errLog || ((m) => process.stderr.write(m + "\n"));
33
+ const sub = opts.sub;
34
+
35
+ switch (sub) {
36
+ case "local":
37
+ return runConfigLocal(opts);
38
+ case "hosted":
39
+ return runConfigHosted(opts);
40
+ case "show":
41
+ return runConfigShow(opts);
42
+ case undefined:
43
+ case "":
44
+ case "help":
45
+ case "--help":
46
+ case "-h":
47
+ printHelp(log);
48
+ return { exitCode: sub === undefined ? 1 : 0 };
49
+ default:
50
+ errLog(`Unknown subcommand: ${sub}`);
51
+ printHelp(errLog);
52
+ return { exitCode: 2 };
53
+ }
54
+ }
55
+
56
+ function printHelp(out) {
57
+ out("Usage: tes config <subcommand>");
58
+ out("");
59
+ out("Subcommands:");
60
+ out(" local Point Claude Code's plugin at a local memory engine");
61
+ out(" hosted Sign in with TES (browser flow); writes credentials");
62
+ out(" show Print the current plugin config + memory backend");
63
+ out("");
64
+ out("Flags (subcommand-specific):");
65
+ out(" --engine-url <url> For 'local'; default http://localhost:8099");
66
+ }
67
+
68
+ // ----------------------------------------------------------------------
69
+ // `tes config local`
70
+ // ----------------------------------------------------------------------
71
+
72
+ async function runConfigLocal(opts) {
73
+ const log = opts.log || ((m) => process.stdout.write(m + "\n"));
74
+ const errLog = opts.errLog || ((m) => process.stderr.write(m + "\n"));
75
+ const engineUrl = opts.engineUrl || DEFAULT_ENGINE_URL;
76
+
77
+ const configDir = opts.configDir || resolveConfigDir();
78
+ const configPath = join(configDir, "tes-memory.local.md");
79
+
80
+ try {
81
+ mkdirSync(configDir, { recursive: true });
82
+ } catch (err) {
83
+ errLog(`Error: cannot create config dir ${configDir}: ${err.message}`);
84
+ return { exitCode: 1 };
85
+ }
86
+
87
+ // Preserve any existing hosted config as comments so the user can
88
+ // flip back without re-running login.
89
+ let preserved = "";
90
+ if (existsSync(configPath)) {
91
+ try {
92
+ const fm = parseFrontmatter(readFileSync(configPath, "utf-8"));
93
+ if (fm && fm.tes_endpoint) {
94
+ copyFileSync(configPath, configPath + ".bak");
95
+ preserved = formatPreservedHosted(fm);
96
+ log(` Existing hosted config backed up to ${configPath}.bak`);
97
+ }
98
+ } catch {
99
+ // best-effort
100
+ }
101
+ }
102
+
103
+ const body =
104
+ `---\n` +
105
+ `mode: local\n` +
106
+ `memory_url: ${engineUrl}\n` +
107
+ preserved +
108
+ `---\n`;
109
+
110
+ try {
111
+ writeFileSync(configPath, body, { mode: 0o600 });
112
+ } catch (err) {
113
+ errLog(`Error: cannot write config ${configPath}: ${err.message}`);
114
+ return { exitCode: 1 };
115
+ }
116
+
117
+ log("");
118
+ log(`✓ Plugin config written: ${configPath}`);
119
+ log(` → Claude Code's tes-memory plugin now points at ${engineUrl}`);
120
+ log("");
121
+ log("Next steps to bring up the engine:");
122
+ log("");
123
+ log(" 1. Make sure Ollama is running and bound to all interfaces");
124
+ log(" (so docker containers can reach it via host.docker.internal):");
125
+ log("");
126
+ log(" sudo mkdir -p /etc/systemd/system/ollama.service.d");
127
+ log(" echo -e '[Service]\\nEnvironment=\"OLLAMA_HOST=0.0.0.0:11434\"' \\");
128
+ log(" | sudo tee /etc/systemd/system/ollama.service.d/override.conf");
129
+ log(" sudo systemctl daemon-reload && sudo systemctl restart ollama");
130
+ log(" ollama pull nomic-embed-text # if not already pulled");
131
+ log("");
132
+ log(" 2. Bring up the engine docker stack:");
133
+ log("");
134
+ log(" cd packages/memory-engine");
135
+ log(" cp .env.example .env # if no .env yet");
136
+ log(" # edit .env if you want a different embedding model/dim");
137
+ log(" docker compose up -d --scale nv-embed=0");
138
+ log("");
139
+ log(" 3. Verify it's healthy:");
140
+ log("");
141
+ log(` curl -s ${engineUrl}/health | jq`);
142
+ log("");
143
+ log(" 4. Reload Claude Code (close + reopen, or /reload-plugins).");
144
+ log("");
145
+ log(" Verify with /tes-memory:tes-status — should report:");
146
+ log(" ✓ Connected to local memory engine");
147
+ log("");
148
+ return { exitCode: 0, configPath };
149
+ }
150
+
151
+ // ----------------------------------------------------------------------
152
+ // `tes config hosted`
153
+ // ----------------------------------------------------------------------
154
+
155
+ async function runConfigHosted(opts) {
156
+ const { runLoginCommand } = await import("./login.js");
157
+ return runLoginCommand({ endpoint: opts.endpoint });
158
+ }
159
+
160
+ // ----------------------------------------------------------------------
161
+ // `tes config show`
162
+ // ----------------------------------------------------------------------
163
+
164
+ function runConfigShow(opts) {
165
+ const log = opts.log || ((m) => process.stdout.write(m + "\n"));
166
+ const configDir = opts.configDir || resolveConfigDir();
167
+ const configPath = join(configDir, "tes-memory.local.md");
168
+
169
+ log("");
170
+ log(`Plugin config: ${configPath}`);
171
+ if (!existsSync(configPath)) {
172
+ log(" (file does not exist — run `tes config local` or `tes config hosted`)");
173
+ return { exitCode: 1 };
174
+ }
175
+
176
+ const fm = parseFrontmatter(readFileSync(configPath, "utf-8"));
177
+ if (!fm) {
178
+ log(" (file exists but couldn't parse frontmatter)");
179
+ return { exitCode: 1 };
180
+ }
181
+
182
+ const mode = fm.mode || (fm.tes_endpoint ? "hosted" : "?");
183
+ log(` Mode: ${mode}`);
184
+ if (mode === "local") {
185
+ log(` memory_url: ${fm.memory_url || "(missing)"}`);
186
+ } else if (mode === "hosted") {
187
+ log(` endpoint: ${fm.tes_endpoint}`);
188
+ log(` client_id: ${fm.tes_client_id}`);
189
+ log(` user_id: ${fm.tes_user_id || "(unset)"}`);
190
+ }
191
+
192
+ // Also surface ~/.config/tes/credentials.json if present
193
+ const credPath = join(
194
+ process.env.XDG_CONFIG_HOME || join(homedir(), ".config"),
195
+ "tes",
196
+ "credentials.json"
197
+ );
198
+ if (existsSync(credPath)) {
199
+ try {
200
+ const c = JSON.parse(readFileSync(credPath, "utf-8"));
201
+ log("");
202
+ log(`Credentials: ${credPath}`);
203
+ log(` endpoint: ${c.endpoint}`);
204
+ log(` clientId: ${c.clientId}`);
205
+ } catch {
206
+ log(` (${credPath} unreadable)`);
207
+ }
208
+ }
209
+
210
+ log("");
211
+ return { exitCode: 0 };
212
+ }
213
+
214
+ // ----------------------------------------------------------------------
215
+ // Helpers
216
+ // ----------------------------------------------------------------------
217
+
218
+ function resolveConfigDir() {
219
+ const candidates = [
220
+ process.env.CLAUDE_CONFIG_DIR,
221
+ join(homedir(), ".claude-pentatonic"),
222
+ join(homedir(), ".claude"),
223
+ ].filter(Boolean);
224
+ for (const c of candidates) {
225
+ if (existsSync(c)) return c;
226
+ }
227
+ return candidates[candidates.length - 1];
228
+ }
229
+
230
+ function parseFrontmatter(content) {
231
+ const m = content.match(/^---\n([\s\S]*?)\n---/);
232
+ if (!m) return null;
233
+ const out = {};
234
+ for (const line of m[1].split("\n")) {
235
+ const kv = line.match(/^(\w+):\s*(.+)$/);
236
+ if (kv) out[kv[1]] = kv[2].trim();
237
+ }
238
+ return out;
239
+ }
240
+
241
+ function formatPreservedHosted(fm) {
242
+ const keys = ["tes_endpoint", "tes_client_id", "tes_api_key", "tes_user_id"];
243
+ const present = keys.filter((k) => fm[k]);
244
+ if (!present.length) return "";
245
+ return (
246
+ `# Hosted config preserved — uncomment + remove the local block above\n` +
247
+ `# to switch back. Original saved as <this-file>.bak.\n` +
248
+ present.map((k) => `# ${k}: ${fm[k]}`).join("\n") +
249
+ `\n`
250
+ );
251
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pentatonic-ai/ai-agent-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "TES SDK — LLM observability and lifecycle tracking via Pentatonic Thing Event System. Track token usage, tool calls, and conversations. Manage things through event-sourced lifecycle stages with AI enrichment and vector search.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -25,6 +25,7 @@
25
25
  "src",
26
26
  "bin",
27
27
  "packages/memory",
28
+ "packages/memory-engine",
28
29
  "packages/doctor",
29
30
  "build.js",
30
31
  "README.md",
@@ -39,13 +39,9 @@ describe("detectPaths", () => {
39
39
  expect(paths.has(PATHS.PLATFORM)).toBe(true);
40
40
  });
41
41
 
42
- it("detects local from full DSN trio", () => {
42
+ it("detects local from MEMORY_ENGINE_URL", () => {
43
43
  const paths = detectPaths({
44
- env: {
45
- DATABASE_URL: "postgres://x",
46
- EMBEDDING_URL: "http://x/v1",
47
- LLM_URL: "http://x/v1",
48
- },
44
+ env: { MEMORY_ENGINE_URL: "http://localhost:8099" },
49
45
  });
50
46
  expect(paths.has(PATHS.LOCAL)).toBe(true);
51
47
  });