@mnemom/mnemom 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 (47) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +123 -0
  3. package/dist/commands/agents.d.ts +15 -0
  4. package/dist/commands/agents.js +303 -0
  5. package/dist/commands/auth.d.ts +5 -0
  6. package/dist/commands/auth.js +60 -0
  7. package/dist/commands/card.d.ts +23 -0
  8. package/dist/commands/card.js +460 -0
  9. package/dist/commands/claim.d.ts +1 -0
  10. package/dist/commands/claim.js +72 -0
  11. package/dist/commands/init.d.ts +7 -0
  12. package/dist/commands/init.js +763 -0
  13. package/dist/commands/integrity.d.ts +1 -0
  14. package/dist/commands/integrity.js +49 -0
  15. package/dist/commands/license.d.ts +3 -0
  16. package/dist/commands/license.js +163 -0
  17. package/dist/commands/logs.d.ts +5 -0
  18. package/dist/commands/logs.js +73 -0
  19. package/dist/commands/migrate-config.d.ts +2 -0
  20. package/dist/commands/migrate-config.js +72 -0
  21. package/dist/commands/policy.d.ts +31 -0
  22. package/dist/commands/policy.js +543 -0
  23. package/dist/commands/register.d.ts +6 -0
  24. package/dist/commands/register.js +362 -0
  25. package/dist/commands/status.d.ts +1 -0
  26. package/dist/commands/status.js +383 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +381 -0
  29. package/dist/lib/api.d.ts +133 -0
  30. package/dist/lib/api.js +207 -0
  31. package/dist/lib/auth.d.ts +60 -0
  32. package/dist/lib/auth.js +281 -0
  33. package/dist/lib/config.d.ts +105 -0
  34. package/dist/lib/config.js +253 -0
  35. package/dist/lib/format.d.ts +35 -0
  36. package/dist/lib/format.js +60 -0
  37. package/dist/lib/model-cache.d.ts +16 -0
  38. package/dist/lib/model-cache.js +138 -0
  39. package/dist/lib/models.d.ts +41 -0
  40. package/dist/lib/models.js +357 -0
  41. package/dist/lib/openclaw.d.ts +221 -0
  42. package/dist/lib/openclaw.js +474 -0
  43. package/dist/lib/prompt.d.ts +26 -0
  44. package/dist/lib/prompt.js +150 -0
  45. package/dist/smoltbot-shim.d.ts +2 -0
  46. package/dist/smoltbot-shim.js +7 -0
  47. package/package.json +61 -0
@@ -0,0 +1,383 @@
1
+ import { configExists, loadConfig, requireAgent } from "../lib/config.js";
2
+ import { getAgent, getIntegrity, getTraces } from "../lib/api.js";
3
+ import { detectOpenClaw, detectProviders, getCurrentModel, getSmoltbotConfiguredProviders, PROVIDER_CONFIG_KEYS, } from "../lib/openclaw.js";
4
+ import { formatModelName, detectProvider } from "../lib/models.js";
5
+ import { refreshModelCache } from "../lib/model-cache.js";
6
+ import { fmt } from "../lib/format.js";
7
+ const GATEWAY_URL = "https://gateway.mnemom.ai";
8
+ const DASHBOARD_URL = "https://mnemom.ai";
9
+ const PROVIDER_LABELS = {
10
+ anthropic: "Anthropic",
11
+ openai: "OpenAI",
12
+ gemini: "Gemini",
13
+ };
14
+ const AIP_SUPPORT = {
15
+ anthropic: "Full (thinking blocks)",
16
+ openai: "Via reasoning summaries",
17
+ gemini: "Full (thought parts)",
18
+ };
19
+ export async function statusCommand(agentName) {
20
+ console.log(fmt.header("smoltbot status"));
21
+ console.log();
22
+ const checks = [];
23
+ // 1. Check smoltbot config
24
+ const configCheck = checkSmoltbotConfig();
25
+ checks.push(configCheck);
26
+ if (configCheck.status === "error") {
27
+ printChecks(checks);
28
+ console.log("\nRun `smoltbot init` to get started.\n");
29
+ process.exit(1);
30
+ }
31
+ const config = loadConfig();
32
+ const agent = await requireAgent(agentName);
33
+ // 2. Check OpenClaw configuration
34
+ const openclawCheck = checkOpenClawConfig();
35
+ checks.push(openclawCheck);
36
+ // 3. Check configured providers
37
+ const providerChecks = checkConfiguredProviders();
38
+ checks.push(...providerChecks);
39
+ // 4. Check current model
40
+ const modelCheck = checkCurrentModel();
41
+ checks.push(modelCheck);
42
+ // 5. Test gateway connectivity
43
+ const gatewayCheck = await checkGatewayConnectivity();
44
+ checks.push(gatewayCheck);
45
+ // 6. Test API connectivity
46
+ const apiCheck = await checkApiConnectivity(agent.agentId);
47
+ checks.push(apiCheck);
48
+ // Print all checks
49
+ printChecks(checks);
50
+ // Show configuration details
51
+ console.log(fmt.section("Configuration"));
52
+ console.log();
53
+ console.log(fmt.label("Agent ID: ", agent.agentId));
54
+ console.log(fmt.label("Gateway: ", config.gateway || GATEWAY_URL));
55
+ console.log(fmt.label("Dashboard:", ` ${DASHBOARD_URL}/agents/${agent.agentId}`));
56
+ if (config.mnemomApiKey) {
57
+ console.log(`Mnemom Key: [CONFIGURED] (billing enabled)`);
58
+ }
59
+ else {
60
+ console.log(`Mnemom Key: Not configured (free tier)`);
61
+ }
62
+ if (agent.openclawConfigured) {
63
+ console.log(`Configured: ${agent.configuredAt || "yes"}`);
64
+ }
65
+ // Show current model info
66
+ const { fullPath, provider, modelId } = getCurrentModel();
67
+ if (fullPath) {
68
+ console.log(`\nCurrent Model: ${fullPath}`);
69
+ if (modelId) {
70
+ console.log(` (${formatModelName(modelId)})`);
71
+ }
72
+ if (provider && (provider === "smoltbot" || provider.startsWith("smoltbot"))) {
73
+ console.log(" Status: Traced mode ACTIVE");
74
+ }
75
+ else {
76
+ console.log(" Status: Traced mode NOT ACTIVE");
77
+ if (modelId) {
78
+ const detectedProvider = detectProvider(modelId);
79
+ const configKey = detectedProvider ? PROVIDER_CONFIG_KEYS[detectedProvider] : "smoltbot";
80
+ console.log(`\n To enable: openclaw models set ${configKey}/${modelId}`);
81
+ }
82
+ }
83
+ }
84
+ // Show provider summary
85
+ showProviderSummary();
86
+ // Show trace summary if available
87
+ if (apiCheck.status === "ok") {
88
+ await showTraceSummary(agent.agentId);
89
+ }
90
+ // Show overall status
91
+ const hasErrors = checks.some((c) => c.status === "error");
92
+ const hasWarnings = checks.some((c) => c.status === "warning");
93
+ if (hasErrors) {
94
+ console.log("\n" + fmt.header("Status: ISSUES DETECTED"));
95
+ console.log("\n Fix the errors above to ensure tracing works correctly.\n");
96
+ }
97
+ else if (hasWarnings) {
98
+ console.log("\n" + fmt.header("Status: OK (with warnings)"));
99
+ console.log();
100
+ }
101
+ else {
102
+ console.log("\n" + fmt.header("Status: ALL SYSTEMS GO"));
103
+ console.log();
104
+ }
105
+ // Refresh model cache in background (non-blocking)
106
+ refreshModelCache().catch(() => { });
107
+ }
108
+ function checkSmoltbotConfig() {
109
+ if (!configExists()) {
110
+ return {
111
+ name: "Smoltbot Config",
112
+ status: "error",
113
+ message: "Not initialized",
114
+ details: "Run `smoltbot init` to configure",
115
+ };
116
+ }
117
+ const config = loadConfig();
118
+ if (!config) {
119
+ return {
120
+ name: "Smoltbot Config",
121
+ status: "error",
122
+ message: "Config file corrupted",
123
+ details: "Delete ~/.smoltbot/config.json and run `smoltbot init`",
124
+ };
125
+ }
126
+ const defaultAgent = config.agents[config.defaultAgent];
127
+ return {
128
+ name: "Smoltbot Config",
129
+ status: "ok",
130
+ message: `Agent ID: ${defaultAgent?.agentId ?? "unknown"}`,
131
+ };
132
+ }
133
+ function checkOpenClawConfig() {
134
+ const detection = detectOpenClaw();
135
+ if (!detection.installed) {
136
+ return {
137
+ name: "OpenClaw",
138
+ status: "error",
139
+ message: "Not installed",
140
+ details: "Install from https://openclaw.ai",
141
+ };
142
+ }
143
+ if (!detection.hasApiKey) {
144
+ if (detection.isOAuth) {
145
+ return {
146
+ name: "OpenClaw",
147
+ status: "error",
148
+ message: "OAuth auth (not supported)",
149
+ details: "smoltbot requires API key authentication",
150
+ };
151
+ }
152
+ // Check if any provider has a key (not just Anthropic)
153
+ const providerDetection = detectProviders();
154
+ const anyKey = Object.values(providerDetection.providers).some((p) => p.hasApiKey);
155
+ if (anyKey) {
156
+ return {
157
+ name: "OpenClaw",
158
+ status: "ok",
159
+ message: "API key(s) found",
160
+ };
161
+ }
162
+ return {
163
+ name: "OpenClaw",
164
+ status: "error",
165
+ message: "No API keys configured",
166
+ details: "Run `openclaw auth` to add your API key",
167
+ };
168
+ }
169
+ if (!detection.smoltbotAlreadyConfigured) {
170
+ return {
171
+ name: "OpenClaw",
172
+ status: "warning",
173
+ message: "smoltbot provider not configured",
174
+ details: "Run `smoltbot init` to configure",
175
+ };
176
+ }
177
+ return {
178
+ name: "OpenClaw",
179
+ status: "ok",
180
+ message: "smoltbot provider configured",
181
+ };
182
+ }
183
+ function checkConfiguredProviders() {
184
+ const results = [];
185
+ const providerDetection = detectProviders();
186
+ if (!providerDetection.installed)
187
+ return results;
188
+ const configuredProviders = getSmoltbotConfiguredProviders();
189
+ for (const provider of ["anthropic", "openai", "gemini"]) {
190
+ const info = providerDetection.providers[provider];
191
+ const isConfigured = configuredProviders.includes(provider);
192
+ if (info.hasApiKey && isConfigured) {
193
+ results.push({
194
+ name: `${PROVIDER_LABELS[provider]}`,
195
+ status: "ok",
196
+ message: `Configured (AIP: ${AIP_SUPPORT[provider]})`,
197
+ });
198
+ }
199
+ else if (info.hasApiKey && !isConfigured) {
200
+ results.push({
201
+ name: `${PROVIDER_LABELS[provider]}`,
202
+ status: "warning",
203
+ message: "API key found but not configured",
204
+ details: "Run `smoltbot init` to configure",
205
+ });
206
+ }
207
+ // Don't show providers without keys (too noisy)
208
+ }
209
+ return results;
210
+ }
211
+ function checkCurrentModel() {
212
+ const { fullPath, provider, modelId } = getCurrentModel();
213
+ if (!fullPath) {
214
+ return {
215
+ name: "Current Model",
216
+ status: "warning",
217
+ message: "No default model set",
218
+ details: "Run `openclaw models set smoltbot/<model>`",
219
+ };
220
+ }
221
+ if (provider && (provider === "smoltbot" || provider.startsWith("smoltbot"))) {
222
+ return {
223
+ name: "Current Model",
224
+ status: "ok",
225
+ message: `${modelId} (traced)`,
226
+ };
227
+ }
228
+ return {
229
+ name: "Current Model",
230
+ status: "warning",
231
+ message: `${fullPath} (not traced)`,
232
+ details: `Switch with: openclaw models set smoltbot/${modelId}`,
233
+ };
234
+ }
235
+ function showProviderSummary() {
236
+ const providerDetection = detectProviders();
237
+ if (!providerDetection.installed)
238
+ return;
239
+ const configuredProviders = getSmoltbotConfiguredProviders();
240
+ if (configuredProviders.length === 0)
241
+ return;
242
+ console.log(fmt.section("Configured Providers"));
243
+ console.log();
244
+ for (const provider of configuredProviders) {
245
+ const label = PROVIDER_LABELS[provider];
246
+ const aip = AIP_SUPPORT[provider];
247
+ const configKey = PROVIDER_CONFIG_KEYS[provider];
248
+ console.log(` ${label}: ${configKey}/* (AIP: ${aip})`);
249
+ }
250
+ }
251
+ async function checkGatewayConnectivity() {
252
+ try {
253
+ const response = await fetch(`${GATEWAY_URL}/health`, {
254
+ signal: AbortSignal.timeout(5000),
255
+ });
256
+ if (response.ok) {
257
+ const data = (await response.json());
258
+ return {
259
+ name: "Gateway",
260
+ status: "ok",
261
+ message: `Connected (v${data.version || "unknown"})`,
262
+ };
263
+ }
264
+ return {
265
+ name: "Gateway",
266
+ status: "error",
267
+ message: `HTTP ${response.status}`,
268
+ details: "Gateway returned an error",
269
+ };
270
+ }
271
+ catch (error) {
272
+ const message = error instanceof Error ? error.message : String(error);
273
+ if (message.includes("timeout") || message.includes("TIMEOUT")) {
274
+ return {
275
+ name: "Gateway",
276
+ status: "error",
277
+ message: "Connection timeout",
278
+ details: "Check your network connection",
279
+ };
280
+ }
281
+ return {
282
+ name: "Gateway",
283
+ status: "error",
284
+ message: "Connection failed",
285
+ details: message,
286
+ };
287
+ }
288
+ }
289
+ async function checkApiConnectivity(agentId) {
290
+ try {
291
+ const agent = await getAgent(agentId);
292
+ if (agent) {
293
+ return {
294
+ name: "API",
295
+ status: "ok",
296
+ message: "Agent registered",
297
+ };
298
+ }
299
+ return {
300
+ name: "API",
301
+ status: "warning",
302
+ message: "Agent not yet registered",
303
+ details: "Will register on first traced API call",
304
+ };
305
+ }
306
+ catch (error) {
307
+ const message = error instanceof Error ? error.message : String(error);
308
+ if (message.includes("404") || message.includes("not found")) {
309
+ return {
310
+ name: "API",
311
+ status: "warning",
312
+ message: "Agent not yet registered",
313
+ details: "Will register on first traced API call",
314
+ };
315
+ }
316
+ if (message.includes("timeout") || message.includes("TIMEOUT")) {
317
+ return {
318
+ name: "API",
319
+ status: "error",
320
+ message: "Connection timeout",
321
+ details: "Check your network connection",
322
+ };
323
+ }
324
+ return {
325
+ name: "API",
326
+ status: "error",
327
+ message: "Connection failed",
328
+ details: message,
329
+ };
330
+ }
331
+ }
332
+ async function showTraceSummary(agentId) {
333
+ try {
334
+ const [integrityResult, tracesResult] = await Promise.allSettled([
335
+ getIntegrity(agentId),
336
+ getTraces(agentId, 1),
337
+ ]);
338
+ console.log(fmt.section("Trace Summary"));
339
+ console.log();
340
+ if (integrityResult.status === "fulfilled") {
341
+ const integrity = integrityResult.value;
342
+ const score = (integrity.score * 100).toFixed(1);
343
+ console.log(`Integrity Score: ${score}%`);
344
+ console.log(`Total Traces: ${integrity.total_traces}`);
345
+ console.log(`Verified: ${integrity.verified}`);
346
+ if (integrity.violations > 0) {
347
+ console.log(`Violations: ${integrity.violations}`);
348
+ }
349
+ }
350
+ else {
351
+ console.log("Integrity: No data yet");
352
+ }
353
+ if (tracesResult.status === "fulfilled" && tracesResult.value.length > 0) {
354
+ const lastTrace = tracesResult.value[0];
355
+ const lastTime = new Date(lastTrace.timestamp).toLocaleString();
356
+ console.log(`\nLast Activity: ${lastTime}`);
357
+ }
358
+ else {
359
+ console.log("\nLast Activity: None");
360
+ }
361
+ }
362
+ catch {
363
+ // Silently skip if we can't get trace info
364
+ }
365
+ }
366
+ function printChecks(checks) {
367
+ console.log(fmt.section("System Checks"));
368
+ console.log();
369
+ for (const check of checks) {
370
+ if (check.status === "ok") {
371
+ console.log(fmt.success(`${check.name}: ${check.message}`));
372
+ }
373
+ else if (check.status === "warning") {
374
+ console.log(fmt.warn(`${check.name}: ${check.message}`));
375
+ }
376
+ else {
377
+ console.log(fmt.error(`${check.name}: ${check.message}`));
378
+ }
379
+ if (check.details) {
380
+ console.log(` ${check.details}`);
381
+ }
382
+ }
383
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};