feat(cli): add mem0 whoami + mem0 agent-rush subcommands
Mirrors implementation across Node (TypeScript) and Python CLIs.
mem0 whoami:
Prints the agent's default_user_id from local config — the AGENTRUSH
leaderboard identifier. Used by players to cross-verify their row.
mem0 agent-rush <add|search>:
Wraps the platform's /v1/agent-rush/{memories/, memories/search/}
endpoints. Project routing is implicit (server-resolved); no flags.
Pretty-prints platform error codes into actionable hints (e.g.
agentrush_search_first → "Run 3 'mem0 agent-rush search' commands
before adding.").
Adds X-Mem0-Mode: agent-rush header for telemetry. Reuses existing
agent-mode API key from config; surfaces a graceful error if config
is missing or the key was created outside agent-mode.
Platform PR: mem0ai/platform#2804
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* `mem0 agent-rush <add|search> "..."` — wraps the AGENTRUSH platform endpoints.
|
||||
* Project routing is implicit (server-side); zero flags needed.
|
||||
*/
|
||||
|
||||
import { colors, printError, printSuccess } from "../branding.js";
|
||||
import { loadConfig } from "../config.js";
|
||||
import { CLI_VERSION } from "../version.js";
|
||||
|
||||
const ERROR_HINTS: Record<string, string> = {
|
||||
agentrush_search_first:
|
||||
"Run 3 'mem0 agent-rush search' commands before adding.",
|
||||
agentrush_search_quota: "You've used your 3 lifetime searches.",
|
||||
agentrush_add_quota: "You've used your 3 lifetime adds.",
|
||||
agentrush_not_agent_mode:
|
||||
"Re-run 'mem0 init --agent' to bootstrap an agent-mode key.",
|
||||
agentrush_length: "Memory text must be 50-1000 characters.",
|
||||
agentrush_no_urls: "URLs are not allowed.",
|
||||
agentrush_blocklist: "Content contains a blocked term.",
|
||||
agentrush_global_quota: "Event-wide cap reached. Try again later.",
|
||||
agentrush_not_provisioned:
|
||||
"AGENTRUSH is not provisioned in this environment.",
|
||||
};
|
||||
|
||||
async function callEndpoint(
|
||||
path: string,
|
||||
body: Record<string, unknown>,
|
||||
): Promise<unknown> {
|
||||
const config = loadConfig();
|
||||
const baseUrl = (config.platform?.baseUrl ?? "https://api.mem0.ai").replace(
|
||||
/\/+$/,
|
||||
"",
|
||||
);
|
||||
|
||||
if (!config.platform?.apiKey) {
|
||||
printError("Not initialized. Run `mem0 init --agent` first.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const resp = await fetch(`${baseUrl}${path}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Token ${config.platform.apiKey}`,
|
||||
"Content-Type": "application/json",
|
||||
"X-Mem0-Source": "cli",
|
||||
"X-Mem0-Client-Language": "node",
|
||||
"X-Mem0-Client-Version": CLI_VERSION,
|
||||
"X-Mem0-Mode": "agent-rush",
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
});
|
||||
|
||||
const json = await resp.json().catch(() => ({}));
|
||||
|
||||
if (!resp.ok) {
|
||||
const code =
|
||||
(json as { error?: { code?: string } }).error?.code ?? "unknown";
|
||||
printError(`AGENTRUSH error: ${code}`);
|
||||
if (ERROR_HINTS[code]) {
|
||||
console.log(` ${colors.dim(ERROR_HINTS[code])}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
export async function cmdAgentRushAdd(content: string): Promise<void> {
|
||||
const result = await callEndpoint("/v1/agent-rush/memories/", { content });
|
||||
printSuccess(
|
||||
`Memory submitted (event_id: ${(result as { event_id?: string }).event_id ?? "?"})`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function cmdAgentRushSearch(query: string): Promise<void> {
|
||||
const result = (await callEndpoint("/v1/agent-rush/memories/search/", {
|
||||
query,
|
||||
})) as {
|
||||
results?: Array<{ memory?: string }>;
|
||||
memories?: Array<{ memory?: string }>;
|
||||
};
|
||||
|
||||
const memories = result.results ?? result.memories ?? [];
|
||||
|
||||
if (memories.length === 0) {
|
||||
console.log(colors.dim("(no results)"));
|
||||
return;
|
||||
}
|
||||
|
||||
memories.slice(0, 5).forEach((m, i) => {
|
||||
console.log(` ${i + 1}. ${m.memory ?? JSON.stringify(m)}`);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* `mem0 whoami` — print the active agent's default_user_id (AGENTRUSH identifier).
|
||||
* Reads from local config; no network call.
|
||||
*/
|
||||
|
||||
import { colors, printError, printInfo } from "../branding.js";
|
||||
import { loadConfig } from "../config.js";
|
||||
|
||||
export async function cmdWhoami(): Promise<void> {
|
||||
const config = loadConfig();
|
||||
const sessionId = config.platform?.defaultUserId;
|
||||
if (!sessionId) {
|
||||
printError(
|
||||
"No default_user_id found. Run `mem0 init --agent` first.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`Your AGENTRUSH identifier: ${colors.brand(sessionId)}`);
|
||||
printInfo("Find your row at https://mem0.ai/agentrush");
|
||||
}
|
||||
@@ -262,6 +262,48 @@ program
|
||||
await runIdentify(name);
|
||||
});
|
||||
|
||||
// ── Setup: whoami (print active agent identifier) ────────────────────────
|
||||
|
||||
program
|
||||
.command("whoami")
|
||||
.description("Print the active agent's AGENTRUSH identifier.")
|
||||
.action(async () => {
|
||||
const { cmdWhoami } = await import("./commands/whoami.js");
|
||||
await cmdWhoami();
|
||||
});
|
||||
|
||||
// ── AGENTRUSH subcommand group ────────────────────────────────────────────
|
||||
|
||||
const agentRush = program
|
||||
.command("agent-rush")
|
||||
.description("AGENTRUSH game commands.")
|
||||
.addHelpCommand(false)
|
||||
.configureHelp({ formatHelp: richFormatHelp });
|
||||
|
||||
agentRush
|
||||
.command("add <content...>")
|
||||
.description("Submit a memory to AGENTRUSH.")
|
||||
.addHelpText(
|
||||
"after",
|
||||
'\nExamples:\n $ mem0 agent-rush add "I used mem0 to build a coding agent"\n $ mem0 agent-rush add "Agents that remember are better agents"',
|
||||
)
|
||||
.action(async (parts: string[]) => {
|
||||
const { cmdAgentRushAdd } = await import("./commands/agent-rush.js");
|
||||
await cmdAgentRushAdd(parts.join(" "));
|
||||
});
|
||||
|
||||
agentRush
|
||||
.command("search <query...>")
|
||||
.description("Search AGENTRUSH memories.")
|
||||
.addHelpText(
|
||||
"after",
|
||||
'\nExamples:\n $ mem0 agent-rush search "agents and memory and tools"\n $ mem0 agent-rush search "coding assistant"',
|
||||
)
|
||||
.action(async (parts: string[]) => {
|
||||
const { cmdAgentRushSearch } = await import("./commands/agent-rush.js");
|
||||
await cmdAgentRushSearch(parts.join(" "));
|
||||
});
|
||||
|
||||
// ── Memory: add ───────────────────────────────────────────────────────────
|
||||
|
||||
program
|
||||
|
||||
Reference in New Issue
Block a user