@agent-commons/cli 0.1.3 → 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.
- package/dist/bin.js +553 -18
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/bin.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander16 = require("commander");
|
|
28
28
|
|
|
29
29
|
// src/commands/login.ts
|
|
30
30
|
var import_commander = require("commander");
|
|
@@ -203,14 +203,19 @@ function loginCommand() {
|
|
|
203
203
|
try {
|
|
204
204
|
const current = loadConfig();
|
|
205
205
|
const apiUrl = opts.apiUrl !== DEFAULT_API_URL ? opts.apiUrl : await prompt(`API URL [${current.apiUrl ?? DEFAULT_API_URL}]: `) || (current.apiUrl ?? DEFAULT_API_URL);
|
|
206
|
+
const appUrl = apiUrl.includes("localhost") ? "http://localhost:3000" : apiUrl.replace(/\/api$/, "").replace("api.", "").replace(":3001", ":3000");
|
|
206
207
|
let apiKey = opts.apiKey;
|
|
207
208
|
if (!apiKey) {
|
|
208
|
-
|
|
209
|
+
console.log(`
|
|
210
|
+
Generate an API key at:
|
|
211
|
+
${c.bold(`${appUrl}/settings/api-keys`)}
|
|
212
|
+
`);
|
|
213
|
+
apiKey = await prompt(`API Key (sk-ac-...): `);
|
|
209
214
|
if (!apiKey) apiKey = current.apiKey;
|
|
210
215
|
}
|
|
211
216
|
let initiator = opts.initiator;
|
|
212
217
|
if (!initiator) {
|
|
213
|
-
initiator = await prompt(`
|
|
218
|
+
initiator = await prompt(`Wallet address (0x...): `);
|
|
214
219
|
if (!initiator) initiator = current.initiator;
|
|
215
220
|
}
|
|
216
221
|
saveConfig({ apiUrl, apiKey, initiator });
|
|
@@ -376,6 +381,76 @@ ${sym.ok} Agent created`);
|
|
|
376
381
|
process.exit(1);
|
|
377
382
|
}
|
|
378
383
|
});
|
|
384
|
+
const autonomy = cmd.command("autonomy").description("Manage agent heartbeat / autonomy");
|
|
385
|
+
autonomy.command("status").description("Show autonomy status for an agent").requiredOption("--agent <agentId>", "Agent ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
386
|
+
const client = makeClient();
|
|
387
|
+
const spinner = spin("Fetching autonomy status\u2026");
|
|
388
|
+
try {
|
|
389
|
+
const res = await client.agents.getAutonomy(opts.agent);
|
|
390
|
+
spinner.stop();
|
|
391
|
+
const s = res.data;
|
|
392
|
+
if (opts.json) return jsonOut(s);
|
|
393
|
+
console.log(`
|
|
394
|
+
${c.bold("Autonomy Status")}`);
|
|
395
|
+
detail([
|
|
396
|
+
["Enabled", s.enabled ? c.bold("yes") : "no"],
|
|
397
|
+
["Interval", s.intervalSec ? `${s.intervalSec}s` : "n/a"],
|
|
398
|
+
["Armed", s.isArmed ? c.bold("yes") : "no"],
|
|
399
|
+
["Last beat", s.lastBeatAt ? new Date(s.lastBeatAt).toLocaleString() : "never"],
|
|
400
|
+
["Next beat", s.nextBeatAt ? new Date(s.nextBeatAt).toLocaleString() : "n/a"]
|
|
401
|
+
]);
|
|
402
|
+
} catch (err) {
|
|
403
|
+
spinner.stop();
|
|
404
|
+
printError(err);
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
autonomy.command("enable").description("Enable autonomous heartbeat for an agent").requiredOption("--agent <agentId>", "Agent ID").option("--interval <seconds>", "Heartbeat interval in seconds (min 30)", "300").action(async (opts) => {
|
|
409
|
+
const client = makeClient();
|
|
410
|
+
const spinner = spin("Enabling autonomy\u2026");
|
|
411
|
+
try {
|
|
412
|
+
await client.agents.setAutonomy(opts.agent, {
|
|
413
|
+
enabled: true,
|
|
414
|
+
intervalSec: parseInt(opts.interval, 10)
|
|
415
|
+
});
|
|
416
|
+
spinner.stop();
|
|
417
|
+
console.log(`
|
|
418
|
+
${sym.ok} Autonomy enabled for agent ${c.id(opts.agent)}`);
|
|
419
|
+
console.log(c.dim(` Heartbeat every ${opts.interval}s`));
|
|
420
|
+
} catch (err) {
|
|
421
|
+
spinner.stop();
|
|
422
|
+
printError(err);
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
autonomy.command("disable").description("Disable autonomous heartbeat for an agent").requiredOption("--agent <agentId>", "Agent ID").action(async (opts) => {
|
|
427
|
+
const client = makeClient();
|
|
428
|
+
const spinner = spin("Disabling autonomy\u2026");
|
|
429
|
+
try {
|
|
430
|
+
await client.agents.setAutonomy(opts.agent, { enabled: false });
|
|
431
|
+
spinner.stop();
|
|
432
|
+
console.log(`
|
|
433
|
+
${sym.ok} Autonomy disabled for agent ${c.id(opts.agent)}`);
|
|
434
|
+
} catch (err) {
|
|
435
|
+
spinner.stop();
|
|
436
|
+
printError(err);
|
|
437
|
+
process.exit(1);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
autonomy.command("trigger").description("Trigger a single heartbeat beat immediately").requiredOption("--agent <agentId>", "Agent ID").action(async (opts) => {
|
|
441
|
+
const client = makeClient();
|
|
442
|
+
const spinner = spin("Triggering heartbeat\u2026");
|
|
443
|
+
try {
|
|
444
|
+
await client.agents.triggerHeartbeat(opts.agent);
|
|
445
|
+
spinner.stop();
|
|
446
|
+
console.log(`
|
|
447
|
+
${sym.ok} Heartbeat triggered for agent ${c.id(opts.agent)}`);
|
|
448
|
+
} catch (err) {
|
|
449
|
+
spinner.stop();
|
|
450
|
+
printError(err);
|
|
451
|
+
process.exit(1);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
379
454
|
return cmd;
|
|
380
455
|
}
|
|
381
456
|
|
|
@@ -383,33 +458,29 @@ ${sym.ok} Agent created`);
|
|
|
383
458
|
var import_commander3 = require("commander");
|
|
384
459
|
function sessionsCommand() {
|
|
385
460
|
const cmd = new import_commander3.Command("sessions").description("Manage chat sessions");
|
|
386
|
-
cmd.command("list").description("List sessions for the current
|
|
461
|
+
cmd.command("list").description("List sessions \u2014 all for the current user, or filtered by agent").option("--agent <agentId>", "Filter by agent ID (default: all agents)").option("--json", "Output as JSON").action(async (opts) => {
|
|
387
462
|
const cfg = loadConfig();
|
|
388
463
|
if (!cfg.initiator) {
|
|
389
464
|
console.error(c.error("No initiator set. Run `agc login` first."));
|
|
390
465
|
process.exit(1);
|
|
391
466
|
}
|
|
392
|
-
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
393
|
-
if (!agentId) {
|
|
394
|
-
console.error(c.error("Specify --agent <agentId> or set defaultAgentId with `agc config set defaultAgentId <id>`"));
|
|
395
|
-
process.exit(1);
|
|
396
|
-
}
|
|
397
467
|
const spinner = spin("Fetching sessions\u2026");
|
|
398
468
|
try {
|
|
399
469
|
const client = makeClient();
|
|
400
|
-
const
|
|
470
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
471
|
+
const res = agentId ? await client.sessions.list(agentId, cfg.initiator) : await client.sessions.listByUser(cfg.initiator);
|
|
401
472
|
const sessions = res?.data ?? res ?? [];
|
|
402
473
|
spinner.stop();
|
|
403
474
|
if (opts.json) return jsonOut(sessions);
|
|
404
|
-
section(`Sessions (${sessions.length})`);
|
|
475
|
+
section(`Sessions (${sessions.length})${agentId ? ` \u2014 agent ${agentId.slice(0, 8)}\u2026` : " \u2014 all agents"}`);
|
|
405
476
|
table(
|
|
406
477
|
sessions.map((s) => ({
|
|
407
478
|
ID: s.sessionId.slice(0, 8) + "\u2026",
|
|
479
|
+
Agent: s.agentId ? s.agentId.slice(0, 8) + "\u2026" : "",
|
|
408
480
|
Title: s.title ?? c.dim("(untitled)"),
|
|
409
|
-
Model: s.model?.modelId ?? s.model?.name ?? "",
|
|
410
481
|
Created: relativeTime(s.createdAt)
|
|
411
482
|
})),
|
|
412
|
-
["ID", "
|
|
483
|
+
["ID", "Agent", "Title", "Created"]
|
|
413
484
|
);
|
|
414
485
|
} catch (err) {
|
|
415
486
|
spinner.stop();
|
|
@@ -661,9 +732,24 @@ function workflowCommand() {
|
|
|
661
732
|
${sym.ok} Execution started: ${c.id(execution.executionId)}`);
|
|
662
733
|
console.log(` Status: ${statusBadge(execution.status)}`);
|
|
663
734
|
if (!opts.watch) {
|
|
735
|
+
const result = execution.result ?? execution.outputData;
|
|
664
736
|
if (execution.status === "completed") {
|
|
665
737
|
console.log("\n" + c.label("Result"));
|
|
666
|
-
console.log(" " + JSON.stringify(
|
|
738
|
+
console.log(" " + JSON.stringify(result, null, 2));
|
|
739
|
+
const steps = execution.stepResults ?? execution.nodeResults;
|
|
740
|
+
if (steps && Object.keys(steps).length > 0) {
|
|
741
|
+
console.log("\n" + c.label("Step Results"));
|
|
742
|
+
for (const [nodeId, step] of Object.entries(steps)) {
|
|
743
|
+
const icon = step.status === "success" ? sym.ok : step.status === "error" ? sym.fail : "\xB7";
|
|
744
|
+
const dur = step.duration != null ? c.dim(` (${(step.duration / 1e3).toFixed(2)}s)`) : "";
|
|
745
|
+
console.log(` ${icon} ${c.id(nodeId)}${dur}`);
|
|
746
|
+
if (step.error) console.log(` ${c.error(step.error)}`);
|
|
747
|
+
else if (step.output !== void 0) console.log(` ${JSON.stringify(step.output, null, 2).replace(/\n/g, "\n ")}`);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
} else {
|
|
751
|
+
console.log(c.dim(`
|
|
752
|
+
Workflow is ${execution.status}. Use --watch to stream progress.`));
|
|
667
753
|
}
|
|
668
754
|
return;
|
|
669
755
|
}
|
|
@@ -677,10 +763,20 @@ ${sym.ok} Execution started: ${c.id(execution.executionId)}`);
|
|
|
677
763
|
console.log(`
|
|
678
764
|
${sym.ok} ${c.success("Completed")}`);
|
|
679
765
|
const e = event;
|
|
680
|
-
if (e.outputData) {
|
|
766
|
+
if (e.outputData != null) {
|
|
681
767
|
console.log("\n" + c.label("Output"));
|
|
682
768
|
console.log(" " + JSON.stringify(e.outputData, null, 2));
|
|
683
769
|
}
|
|
770
|
+
if (e.nodeResults && Object.keys(e.nodeResults).length > 0) {
|
|
771
|
+
console.log("\n" + c.label("Step Results"));
|
|
772
|
+
for (const [nodeId, step] of Object.entries(e.nodeResults)) {
|
|
773
|
+
const icon = step.status === "success" ? sym.ok : step.status === "error" ? sym.fail : "\xB7";
|
|
774
|
+
const dur = step.duration != null ? c.dim(` (${(step.duration / 1e3).toFixed(2)}s)`) : "";
|
|
775
|
+
console.log(` ${icon} ${c.id(nodeId)}${dur}`);
|
|
776
|
+
if (step.error) console.log(` ${c.error(step.error)}`);
|
|
777
|
+
else if (step.output !== void 0) console.log(` ${JSON.stringify(step.output, null, 2).replace(/\n/g, "\n ")}`);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
684
780
|
break;
|
|
685
781
|
} else if (event.type === "failed" || event.type === "cancelled") {
|
|
686
782
|
process.stdout.write("\n");
|
|
@@ -1800,7 +1896,7 @@ function walletCommand() {
|
|
|
1800
1896
|
Address: w.address,
|
|
1801
1897
|
Chain: chainName(w.chainId),
|
|
1802
1898
|
Label: w.label ?? "Primary",
|
|
1803
|
-
Active: w.isActive ? sym.
|
|
1899
|
+
Active: w.isActive ? sym.ok : sym.fail
|
|
1804
1900
|
})),
|
|
1805
1901
|
["ID", "Type", "Address", "Chain", "Label", "Active"]
|
|
1806
1902
|
);
|
|
@@ -1908,7 +2004,7 @@ function walletCommand() {
|
|
|
1908
2004
|
const w = wallet?.data ?? wallet;
|
|
1909
2005
|
if (opts.json) return jsonOut(w);
|
|
1910
2006
|
console.log(`
|
|
1911
|
-
${sym.
|
|
2007
|
+
${sym.ok} ${c.bold("Wallet created")}`);
|
|
1912
2008
|
detail([
|
|
1913
2009
|
["Address", c.bold(w.address)],
|
|
1914
2010
|
["Type", w.walletType],
|
|
@@ -1924,8 +2020,78 @@ ${sym.pass} ${c.bold("Wallet created")}`);
|
|
|
1924
2020
|
process.exit(1);
|
|
1925
2021
|
}
|
|
1926
2022
|
});
|
|
2023
|
+
cmd.command("send").description("Send USDC (or ETH) from an agent wallet to another address").requiredOption("--agent <agentId>", "Agent ID").requiredOption("--to <address>", "Recipient address (0x\u2026)").requiredOption("--amount <amount>", "Amount to send (e.g. 10.5)").option("--token <symbol>", "Token to send: USDC or ETH (default: USDC)", "USDC").option("--wallet <walletId>", "Specific wallet ID (defaults to primary)").action(async (opts) => {
|
|
2024
|
+
const client = makeClient();
|
|
2025
|
+
const spinner = spin("Preparing transfer\u2026");
|
|
2026
|
+
try {
|
|
2027
|
+
let walletId = opts.wallet;
|
|
2028
|
+
if (!walletId) {
|
|
2029
|
+
const primary = await client.wallets.primary(opts.agent);
|
|
2030
|
+
const w = primary?.data ?? primary;
|
|
2031
|
+
if (!w?.id) {
|
|
2032
|
+
spinner.stop();
|
|
2033
|
+
console.error(c.error(`No wallet found for agent ${opts.agent}. Run: agc wallet create --agent ${opts.agent}`));
|
|
2034
|
+
process.exit(1);
|
|
2035
|
+
}
|
|
2036
|
+
walletId = w.id;
|
|
2037
|
+
}
|
|
2038
|
+
spinner.text = `Sending ${opts.amount} ${opts.token} \u2192 ${opts.to}\u2026`;
|
|
2039
|
+
const result = await client.wallets.transfer(walletId, {
|
|
2040
|
+
toAddress: opts.to,
|
|
2041
|
+
amount: opts.amount,
|
|
2042
|
+
tokenSymbol: opts.token
|
|
2043
|
+
});
|
|
2044
|
+
const tx = result?.txHash ?? result?.data?.txHash ?? result;
|
|
2045
|
+
spinner.stop();
|
|
2046
|
+
console.log(`
|
|
2047
|
+
${c.bold("Transfer sent")}`);
|
|
2048
|
+
detail([
|
|
2049
|
+
["Amount", `${opts.amount} ${opts.token}`],
|
|
2050
|
+
["To", opts.to],
|
|
2051
|
+
["Tx Hash", c.id(tx)]
|
|
2052
|
+
]);
|
|
2053
|
+
} catch (err) {
|
|
2054
|
+
spinner.stop();
|
|
2055
|
+
printError(err);
|
|
2056
|
+
process.exit(1);
|
|
2057
|
+
}
|
|
2058
|
+
});
|
|
2059
|
+
cmd.command("x402-fetch").description("Fetch a URL using an agent wallet to pay any x402 (402 Payment Required) challenge").requiredOption("--agent <agentId>", "Agent ID").requiredOption("--url <url>", "Target URL to fetch").option("--method <method>", "HTTP method", "GET").option("--header <header>", "Extra header in Key:Value format (repeatable)", collect, []).option("--body <body>", "Request body string").option("--json", "Output response as JSON").action(async (opts) => {
|
|
2060
|
+
const client = makeClient();
|
|
2061
|
+
const spinner = spin(`Fetching ${opts.url}\u2026`);
|
|
2062
|
+
try {
|
|
2063
|
+
const headers = {};
|
|
2064
|
+
for (const h of opts.header) {
|
|
2065
|
+
const idx = h.indexOf(":");
|
|
2066
|
+
if (idx > 0) headers[h.slice(0, idx).trim()] = h.slice(idx + 1).trim();
|
|
2067
|
+
}
|
|
2068
|
+
const res = await client.wallets.x402Fetch(opts.agent, {
|
|
2069
|
+
url: opts.url,
|
|
2070
|
+
method: opts.method,
|
|
2071
|
+
headers: Object.keys(headers).length ? headers : void 0,
|
|
2072
|
+
body: opts.body
|
|
2073
|
+
});
|
|
2074
|
+
spinner.stop();
|
|
2075
|
+
if (opts.json) return jsonOut(res);
|
|
2076
|
+
console.log(`
|
|
2077
|
+
${c.bold("Response")} status ${res.status}`);
|
|
2078
|
+
if (res.status === 200) {
|
|
2079
|
+
console.log(c.dim(JSON.stringify(res.body, null, 2).slice(0, 1e3)));
|
|
2080
|
+
} else {
|
|
2081
|
+
console.log(c.warn(JSON.stringify(res.body, null, 2)));
|
|
2082
|
+
}
|
|
2083
|
+
} catch (err) {
|
|
2084
|
+
spinner.stop();
|
|
2085
|
+
printError(err);
|
|
2086
|
+
process.exit(1);
|
|
2087
|
+
}
|
|
2088
|
+
});
|
|
1927
2089
|
return cmd;
|
|
1928
2090
|
}
|
|
2091
|
+
function collect(val, acc) {
|
|
2092
|
+
acc.push(val);
|
|
2093
|
+
return acc;
|
|
2094
|
+
}
|
|
1929
2095
|
function chainName(chainId) {
|
|
1930
2096
|
const names = {
|
|
1931
2097
|
"84532": "Base Sepolia",
|
|
@@ -1936,8 +2102,373 @@ function chainName(chainId) {
|
|
|
1936
2102
|
return names[chainId] ?? `chain ${chainId}`;
|
|
1937
2103
|
}
|
|
1938
2104
|
|
|
2105
|
+
// src/commands/models.ts
|
|
2106
|
+
var import_commander12 = require("commander");
|
|
2107
|
+
function modelsCommand() {
|
|
2108
|
+
const cmd = new import_commander12.Command("models").description("List available LLM models");
|
|
2109
|
+
cmd.command("ls").description("List all available models grouped by provider").option("--provider <name>", "Filter by provider (openai, anthropic, google, mistral, groq, ollama)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2110
|
+
const client = makeClient();
|
|
2111
|
+
const spinner = spin("Fetching models\u2026");
|
|
2112
|
+
try {
|
|
2113
|
+
const res = await client.models.list();
|
|
2114
|
+
spinner.stop();
|
|
2115
|
+
const all = res?.data ?? res ?? [];
|
|
2116
|
+
if (opts.json) return jsonOut(all);
|
|
2117
|
+
const filtered = opts.provider ? all.filter((m) => m.provider === opts.provider) : all;
|
|
2118
|
+
if (filtered.length === 0) {
|
|
2119
|
+
console.log(c.warn(" No models found."));
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
const grouped = {};
|
|
2123
|
+
for (const m of filtered) {
|
|
2124
|
+
if (!grouped[m.provider]) grouped[m.provider] = [];
|
|
2125
|
+
grouped[m.provider].push(m);
|
|
2126
|
+
}
|
|
2127
|
+
for (const [provider, models] of Object.entries(grouped)) {
|
|
2128
|
+
console.log(`
|
|
2129
|
+
${c.bold(provider.toUpperCase())}`);
|
|
2130
|
+
for (const m of models) {
|
|
2131
|
+
const tags = [
|
|
2132
|
+
m.tier,
|
|
2133
|
+
m.supportsTools ? "tools" : "",
|
|
2134
|
+
m.supportsVision ? "vision" : ""
|
|
2135
|
+
].filter(Boolean).join(", ");
|
|
2136
|
+
const price = m.inputPricePer1kTokens > 0 ? c.dim(` ($${m.inputPricePer1kTokens}/$${m.outputPricePer1kTokens} /1k)`) : c.dim(" (free/local)");
|
|
2137
|
+
console.log(` ${c.id(m.modelId.padEnd(36))} ${m.displayName.padEnd(24)} ${c.dim(tags)}${price}`);
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
console.log();
|
|
2141
|
+
} catch (err) {
|
|
2142
|
+
spinner.stop();
|
|
2143
|
+
printError(err);
|
|
2144
|
+
process.exit(1);
|
|
2145
|
+
}
|
|
2146
|
+
});
|
|
2147
|
+
return cmd;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
// src/commands/memory.ts
|
|
2151
|
+
var import_commander13 = require("commander");
|
|
2152
|
+
function memoryCommand() {
|
|
2153
|
+
const cmd = new import_commander13.Command("memory").description("View and manage agent memories");
|
|
2154
|
+
cmd.command("list").description("List memories for an agent").option("--agent <agentId>", "Agent ID (defaults to configured agent)").option("--type <type>", "Filter by type: episodic | semantic | procedural").option("--limit <n>", "Max results", "50").option("--json", "Output as JSON").action(async (opts) => {
|
|
2155
|
+
const cfg = loadConfig();
|
|
2156
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
2157
|
+
if (!agentId) {
|
|
2158
|
+
console.error(c.error("Specify --agent <agentId> or set defaultAgentId"));
|
|
2159
|
+
process.exit(1);
|
|
2160
|
+
}
|
|
2161
|
+
const spinner = spin("Fetching memories\u2026");
|
|
2162
|
+
try {
|
|
2163
|
+
const client = makeClient();
|
|
2164
|
+
const res = await client.memory.list(agentId, {
|
|
2165
|
+
type: opts.type,
|
|
2166
|
+
limit: parseInt(opts.limit, 10)
|
|
2167
|
+
});
|
|
2168
|
+
const memories = res?.data ?? res ?? [];
|
|
2169
|
+
spinner.stop();
|
|
2170
|
+
if (opts.json) return jsonOut(memories);
|
|
2171
|
+
section(`Memories for ${agentId.slice(0, 12)}\u2026 (${memories.length})`);
|
|
2172
|
+
if (memories.length === 0) {
|
|
2173
|
+
console.log(c.dim(" No memories yet"));
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
table(
|
|
2177
|
+
memories.map((m) => ({
|
|
2178
|
+
ID: m.memoryId?.slice(0, 8) + "\u2026",
|
|
2179
|
+
Type: m.memoryType ?? "",
|
|
2180
|
+
Content: (m.content ?? "").slice(0, 60),
|
|
2181
|
+
Created: relativeTime(m.createdAt)
|
|
2182
|
+
})),
|
|
2183
|
+
["ID", "Type", "Content", "Created"]
|
|
2184
|
+
);
|
|
2185
|
+
} catch (err) {
|
|
2186
|
+
spinner.stop();
|
|
2187
|
+
printError(err);
|
|
2188
|
+
process.exit(1);
|
|
2189
|
+
}
|
|
2190
|
+
});
|
|
2191
|
+
cmd.command("stats").description("Show memory statistics for an agent").option("--agent <agentId>", "Agent ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
2192
|
+
const cfg = loadConfig();
|
|
2193
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
2194
|
+
if (!agentId) {
|
|
2195
|
+
console.error(c.error("Specify --agent <agentId>"));
|
|
2196
|
+
process.exit(1);
|
|
2197
|
+
}
|
|
2198
|
+
const spinner = spin("Fetching stats\u2026");
|
|
2199
|
+
try {
|
|
2200
|
+
const client = makeClient();
|
|
2201
|
+
const res = await client.memory.stats(agentId);
|
|
2202
|
+
const stats = res?.data ?? res;
|
|
2203
|
+
spinner.stop();
|
|
2204
|
+
if (opts.json) return jsonOut(stats);
|
|
2205
|
+
section("Memory Stats");
|
|
2206
|
+
detail([
|
|
2207
|
+
["Total", String(stats.totalCount ?? 0)],
|
|
2208
|
+
["Episodic", String(stats.episodicCount ?? 0)],
|
|
2209
|
+
["Semantic", String(stats.semanticCount ?? 0)],
|
|
2210
|
+
["Procedural", String(stats.proceduralCount ?? 0)]
|
|
2211
|
+
]);
|
|
2212
|
+
} catch (err) {
|
|
2213
|
+
spinner.stop();
|
|
2214
|
+
printError(err);
|
|
2215
|
+
process.exit(1);
|
|
2216
|
+
}
|
|
2217
|
+
});
|
|
2218
|
+
cmd.command("create").description("Manually add a memory for an agent").requiredOption("--agent <agentId>", "Agent ID").requiredOption("--content <text>", "Memory content").option("--type <type>", "Memory type: episodic | semantic | procedural", "semantic").option("--json", "Output as JSON").action(async (opts) => {
|
|
2219
|
+
const spinner = spin("Creating memory\u2026");
|
|
2220
|
+
try {
|
|
2221
|
+
const client = makeClient();
|
|
2222
|
+
const res = await client.memory.create({
|
|
2223
|
+
agentId: opts.agent,
|
|
2224
|
+
content: opts.content,
|
|
2225
|
+
memoryType: opts.type
|
|
2226
|
+
});
|
|
2227
|
+
const memory = res?.data ?? res;
|
|
2228
|
+
spinner.stop();
|
|
2229
|
+
if (opts.json) return jsonOut(memory);
|
|
2230
|
+
console.log(`
|
|
2231
|
+
${sym.ok} Memory created`);
|
|
2232
|
+
detail([
|
|
2233
|
+
["ID", c.id(memory.memoryId)],
|
|
2234
|
+
["Type", memory.memoryType ?? ""],
|
|
2235
|
+
["Content", memory.content ?? ""]
|
|
2236
|
+
]);
|
|
2237
|
+
} catch (err) {
|
|
2238
|
+
spinner.stop();
|
|
2239
|
+
printError(err);
|
|
2240
|
+
process.exit(1);
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
cmd.command("delete <memoryId>").description("Delete a memory by ID").option("--json", "Output as JSON").action(async (memoryId, opts) => {
|
|
2244
|
+
const spinner = spin("Deleting memory\u2026");
|
|
2245
|
+
try {
|
|
2246
|
+
const client = makeClient();
|
|
2247
|
+
await client.memory.delete(memoryId);
|
|
2248
|
+
spinner.stop();
|
|
2249
|
+
if (opts.json) return jsonOut({ deleted: true, memoryId });
|
|
2250
|
+
console.log(`
|
|
2251
|
+
${sym.ok} Memory ${c.id(memoryId)} deleted`);
|
|
2252
|
+
} catch (err) {
|
|
2253
|
+
spinner.stop();
|
|
2254
|
+
printError(err);
|
|
2255
|
+
process.exit(1);
|
|
2256
|
+
}
|
|
2257
|
+
});
|
|
2258
|
+
cmd.command("search <query>").description("Semantic search over agent memories").option("--agent <agentId>", "Agent ID").option("--limit <n>", "Max results", "10").option("--json", "Output as JSON").action(async (query, opts) => {
|
|
2259
|
+
const cfg = loadConfig();
|
|
2260
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
2261
|
+
if (!agentId) {
|
|
2262
|
+
console.error(c.error("Specify --agent <agentId>"));
|
|
2263
|
+
process.exit(1);
|
|
2264
|
+
}
|
|
2265
|
+
const spinner = spin("Searching memories\u2026");
|
|
2266
|
+
try {
|
|
2267
|
+
const client = makeClient();
|
|
2268
|
+
const res = await client.memory.retrieve(agentId, query, parseInt(opts.limit, 10));
|
|
2269
|
+
const memories = res?.data ?? res ?? [];
|
|
2270
|
+
spinner.stop();
|
|
2271
|
+
if (opts.json) return jsonOut(memories);
|
|
2272
|
+
section(`Search results (${memories.length})`);
|
|
2273
|
+
if (memories.length === 0) {
|
|
2274
|
+
console.log(c.dim(" No relevant memories found"));
|
|
2275
|
+
return;
|
|
2276
|
+
}
|
|
2277
|
+
memories.forEach((m, i) => {
|
|
2278
|
+
console.log(`
|
|
2279
|
+
${c.dim(`${i + 1}.`)} ${m.content ?? ""}`);
|
|
2280
|
+
console.log(` ${c.dim(`type: ${m.memoryType ?? ""} \xB7 ${relativeTime(m.createdAt)}`)}`);
|
|
2281
|
+
});
|
|
2282
|
+
} catch (err) {
|
|
2283
|
+
spinner.stop();
|
|
2284
|
+
printError(err);
|
|
2285
|
+
process.exit(1);
|
|
2286
|
+
}
|
|
2287
|
+
});
|
|
2288
|
+
return cmd;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
// src/commands/usage.ts
|
|
2292
|
+
var import_commander14 = require("commander");
|
|
2293
|
+
function usageCommand() {
|
|
2294
|
+
const cmd = new import_commander14.Command("usage").description("View token usage and cost by agent");
|
|
2295
|
+
cmd.command("agents").description("Show usage summary for all your agents").option("--owner <address>", "Owner address (defaults to configured initiator)").option("--from <date>", "Start date (ISO, e.g. 2025-01-01)").option("--to <date>", "End date (ISO)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2296
|
+
const cfg = loadConfig();
|
|
2297
|
+
const owner = opts.owner ?? cfg.initiator;
|
|
2298
|
+
if (!owner) {
|
|
2299
|
+
console.error(c.error("Specify --owner or run `agc login` first"));
|
|
2300
|
+
process.exit(1);
|
|
2301
|
+
}
|
|
2302
|
+
const spinner = spin("Fetching agents\u2026");
|
|
2303
|
+
try {
|
|
2304
|
+
const client = makeClient();
|
|
2305
|
+
const agentsRes = await client.agents.list(owner);
|
|
2306
|
+
const agents = agentsRes?.data ?? [];
|
|
2307
|
+
spinner.stop();
|
|
2308
|
+
if (agents.length === 0) {
|
|
2309
|
+
console.log(c.dim("No agents found"));
|
|
2310
|
+
return;
|
|
2311
|
+
}
|
|
2312
|
+
spin("Fetching usage\u2026");
|
|
2313
|
+
const rows = await Promise.allSettled(
|
|
2314
|
+
agents.map(
|
|
2315
|
+
(a) => client.usage.getAgentUsage(a.agentId, {
|
|
2316
|
+
from: opts.from,
|
|
2317
|
+
to: opts.to
|
|
2318
|
+
}).then((r) => ({
|
|
2319
|
+
agentId: a.agentId,
|
|
2320
|
+
name: a.name || a.agentId.slice(0, 12),
|
|
2321
|
+
...r?.data ?? r ?? {}
|
|
2322
|
+
}))
|
|
2323
|
+
)
|
|
2324
|
+
);
|
|
2325
|
+
const data = rows.filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
2326
|
+
if (opts.json) return jsonOut(data);
|
|
2327
|
+
let totalTokens = 0, totalCost = 0, totalCalls = 0;
|
|
2328
|
+
data.forEach((r) => {
|
|
2329
|
+
totalTokens += r.totalTokens ?? 0;
|
|
2330
|
+
totalCost += r.totalCostUsd ?? 0;
|
|
2331
|
+
totalCalls += r.callCount ?? 0;
|
|
2332
|
+
});
|
|
2333
|
+
section("Usage Summary");
|
|
2334
|
+
detail([
|
|
2335
|
+
["Total tokens", totalTokens.toLocaleString()],
|
|
2336
|
+
["Total cost", `$${totalCost.toFixed(4)} USD`],
|
|
2337
|
+
["LLM calls", totalCalls.toLocaleString()]
|
|
2338
|
+
]);
|
|
2339
|
+
const active = data.filter((r) => (r.totalTokens ?? 0) > 0);
|
|
2340
|
+
if (active.length) {
|
|
2341
|
+
console.log("");
|
|
2342
|
+
table(
|
|
2343
|
+
active.sort((a, b) => (b.totalCostUsd ?? 0) - (a.totalCostUsd ?? 0)).map((r) => ({
|
|
2344
|
+
Agent: r.name,
|
|
2345
|
+
Calls: (r.callCount ?? 0).toLocaleString(),
|
|
2346
|
+
Tokens: (r.totalTokens ?? 0).toLocaleString(),
|
|
2347
|
+
"Cost $": (r.totalCostUsd ?? 0).toFixed(4)
|
|
2348
|
+
})),
|
|
2349
|
+
["Agent", "Calls", "Tokens", "Cost $"]
|
|
2350
|
+
);
|
|
2351
|
+
}
|
|
2352
|
+
} catch (err) {
|
|
2353
|
+
printError(err);
|
|
2354
|
+
process.exit(1);
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
cmd.command("agent <agentId>").description("Show detailed usage for a specific agent").option("--from <date>", "Start date (ISO)").option("--to <date>", "End date (ISO)").option("--json", "Output as JSON").action(async (agentId, opts) => {
|
|
2358
|
+
const spinner = spin("Fetching usage\u2026");
|
|
2359
|
+
try {
|
|
2360
|
+
const client = makeClient();
|
|
2361
|
+
const res = await client.usage.getAgentUsage(agentId, {
|
|
2362
|
+
from: opts.from,
|
|
2363
|
+
to: opts.to
|
|
2364
|
+
});
|
|
2365
|
+
const data = res?.data ?? res;
|
|
2366
|
+
spinner.stop();
|
|
2367
|
+
if (opts.json) return jsonOut(data);
|
|
2368
|
+
section(`Usage \u2014 ${agentId.slice(0, 12)}\u2026`);
|
|
2369
|
+
detail([
|
|
2370
|
+
["Calls", (data.callCount ?? 0).toLocaleString()],
|
|
2371
|
+
["Input tokens", (data.totalInputTokens ?? 0).toLocaleString()],
|
|
2372
|
+
["Output tokens", (data.totalOutputTokens ?? 0).toLocaleString()],
|
|
2373
|
+
["Total tokens", (data.totalTokens ?? 0).toLocaleString()],
|
|
2374
|
+
["Cost", `$${(data.totalCostUsd ?? 0).toFixed(6)} USD`]
|
|
2375
|
+
]);
|
|
2376
|
+
} catch (err) {
|
|
2377
|
+
spinner.stop();
|
|
2378
|
+
printError(err);
|
|
2379
|
+
process.exit(1);
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
return cmd;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
// src/commands/logs.ts
|
|
2386
|
+
var import_commander15 = require("commander");
|
|
2387
|
+
var STATUS_COLOR = {
|
|
2388
|
+
success: (s) => c.bold(s),
|
|
2389
|
+
error: (s) => c.error(s),
|
|
2390
|
+
warning: (s) => c.warn(s)
|
|
2391
|
+
};
|
|
2392
|
+
function colorStatus(status) {
|
|
2393
|
+
return (STATUS_COLOR[status] ?? c.dim)(status);
|
|
2394
|
+
}
|
|
2395
|
+
function logsCommand() {
|
|
2396
|
+
const cmd = new import_commander15.Command("logs").description("View agent activity logs");
|
|
2397
|
+
cmd.command("list").alias("ls").description("List recent log entries for an agent").option("--agent <agentId>", "Agent ID (defaults to configured agent)").option("--session <sessionId>", "Filter by session ID").option("--status <status>", "Filter: success | error | warning").option("--limit <n>", "Max entries to show", "50").option("--json", "Output as JSON").action(async (opts) => {
|
|
2398
|
+
const cfg = loadConfig();
|
|
2399
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
2400
|
+
if (!agentId) {
|
|
2401
|
+
console.error(c.error("Specify --agent <agentId> or set defaultAgentId"));
|
|
2402
|
+
process.exit(1);
|
|
2403
|
+
}
|
|
2404
|
+
const spinner = spin("Fetching logs\u2026");
|
|
2405
|
+
try {
|
|
2406
|
+
const client = makeClient();
|
|
2407
|
+
const qs = new URLSearchParams({ limit: opts.limit });
|
|
2408
|
+
if (opts.session) qs.set("sessionId", opts.session);
|
|
2409
|
+
const res = await client.request("GET", `/v1/logs/agents/${agentId}?${qs}`);
|
|
2410
|
+
let logs = res?.data ?? res ?? [];
|
|
2411
|
+
if (opts.status) logs = logs.filter((l) => l.status === opts.status);
|
|
2412
|
+
spinner.stop();
|
|
2413
|
+
if (opts.json) return jsonOut(logs);
|
|
2414
|
+
section(`Logs \u2014 ${agentId.slice(0, 12)}\u2026 (${logs.length})`);
|
|
2415
|
+
if (logs.length === 0) {
|
|
2416
|
+
console.log(c.dim(" No logs yet"));
|
|
2417
|
+
return;
|
|
2418
|
+
}
|
|
2419
|
+
logs.forEach((l) => {
|
|
2420
|
+
const tools = (l.tools ?? []).length > 0 ? ` ${c.dim(`[${l.tools.length} tools]`)}` : "";
|
|
2421
|
+
const rt = l.responseTime > 0 ? c.dim(` ${l.responseTime}ms`) : "";
|
|
2422
|
+
console.log(
|
|
2423
|
+
` ${colorStatus((l.status ?? "info").padEnd(7))} ${c.bold(l.action ?? "")}${rt}${tools}`
|
|
2424
|
+
);
|
|
2425
|
+
if (l.message) {
|
|
2426
|
+
console.log(` ${" ".repeat(10)}${c.dim(l.message.slice(0, 80))}`);
|
|
2427
|
+
}
|
|
2428
|
+
console.log(` ${" ".repeat(10)}${c.dim(relativeTime(l.timestamp))}`);
|
|
2429
|
+
console.log("");
|
|
2430
|
+
});
|
|
2431
|
+
} catch (err) {
|
|
2432
|
+
spin("").stop();
|
|
2433
|
+
printError(err);
|
|
2434
|
+
process.exit(1);
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2437
|
+
cmd.command("errors").description("Show only error log entries for an agent").option("--agent <agentId>", "Agent ID").option("--limit <n>", "Max entries", "20").option("--json", "Output as JSON").action(async (opts) => {
|
|
2438
|
+
const cfg = loadConfig();
|
|
2439
|
+
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
2440
|
+
if (!agentId) {
|
|
2441
|
+
console.error(c.error("Specify --agent <agentId>"));
|
|
2442
|
+
process.exit(1);
|
|
2443
|
+
}
|
|
2444
|
+
const spinner = spin("Fetching error logs\u2026");
|
|
2445
|
+
try {
|
|
2446
|
+
const client = makeClient();
|
|
2447
|
+
const res = await client.request("GET", `/v1/logs/agents/${agentId}?limit=${opts.limit}`);
|
|
2448
|
+
const errors = (res?.data ?? []).filter((l) => l.status === "error");
|
|
2449
|
+
spinner.stop();
|
|
2450
|
+
if (opts.json) return jsonOut(errors);
|
|
2451
|
+
section(`Errors \u2014 ${agentId.slice(0, 12)}\u2026 (${errors.length})`);
|
|
2452
|
+
if (errors.length === 0) {
|
|
2453
|
+
console.log(`${sym.ok} No errors found`);
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
errors.forEach((l) => {
|
|
2457
|
+
console.log(` ${c.error("\u2716")} ${c.bold(l.action ?? "")} ${c.dim(relativeTime(l.timestamp))}`);
|
|
2458
|
+
if (l.message) console.log(` ${c.dim(l.message)}`);
|
|
2459
|
+
console.log("");
|
|
2460
|
+
});
|
|
2461
|
+
} catch (err) {
|
|
2462
|
+
spinner.stop();
|
|
2463
|
+
printError(err);
|
|
2464
|
+
process.exit(1);
|
|
2465
|
+
}
|
|
2466
|
+
});
|
|
2467
|
+
return cmd;
|
|
2468
|
+
}
|
|
2469
|
+
|
|
1939
2470
|
// src/bin.ts
|
|
1940
|
-
var program = new
|
|
2471
|
+
var program = new import_commander16.Command();
|
|
1941
2472
|
program.name("agc").description("Agent Commons CLI \u2014 interact with the Agent Commons platform").version("0.1.0", "-v, --version");
|
|
1942
2473
|
program.addCommand(loginCommand());
|
|
1943
2474
|
program.addCommand(logoutCommand());
|
|
@@ -1953,6 +2484,10 @@ program.addCommand(chatCommand());
|
|
|
1953
2484
|
program.addCommand(mcpCommand());
|
|
1954
2485
|
program.addCommand(skillsCommand());
|
|
1955
2486
|
program.addCommand(walletCommand());
|
|
2487
|
+
program.addCommand(modelsCommand());
|
|
2488
|
+
program.addCommand(memoryCommand());
|
|
2489
|
+
program.addCommand(usageCommand());
|
|
2490
|
+
program.addCommand(logsCommand());
|
|
1956
2491
|
program.on("command:*", () => {
|
|
1957
2492
|
console.error(`Unknown command: ${program.args.join(" ")}
|
|
1958
2493
|
Run \`agc --help\` to see available commands.`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-commons/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Agent Commons CLI — chat, run, and manage agents from your terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"commander": "^12.1.0",
|
|
15
15
|
"chalk": "^5.3.0",
|
|
16
16
|
"ora": "^8.1.1",
|
|
17
|
-
"@agent-commons/sdk": "0.1.
|
|
17
|
+
"@agent-commons/sdk": "0.1.5"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"tsup": "^8.3.5",
|