refactor: remove parseArgs value casts in subcommands (#1157)
This commit is contained in:
@@ -38,23 +38,29 @@ function parseTags(value: unknown): string[] | undefined {
|
||||
return tags.length > 0 ? tags : undefined;
|
||||
}
|
||||
|
||||
const AGENTS_OPTIONS = {
|
||||
help: { type: "boolean", short: "h" },
|
||||
name: { type: "string" },
|
||||
query: { type: "string" },
|
||||
tags: { type: "string" },
|
||||
"match-all-tags": { type: "boolean" },
|
||||
"include-blocks": { type: "boolean" },
|
||||
limit: { type: "string" },
|
||||
} as const;
|
||||
|
||||
function parseAgentsArgs(argv: string[]) {
|
||||
return parseArgs({
|
||||
args: argv,
|
||||
options: AGENTS_OPTIONS,
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
}
|
||||
|
||||
export async function runAgentsSubcommand(argv: string[]): Promise<number> {
|
||||
let parsed: ReturnType<typeof parseArgs>;
|
||||
let parsed: ReturnType<typeof parseAgentsArgs>;
|
||||
try {
|
||||
parsed = parseArgs({
|
||||
args: argv,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
name: { type: "string" },
|
||||
query: { type: "string" },
|
||||
tags: { type: "string" },
|
||||
"match-all-tags": { type: "boolean" },
|
||||
"include-blocks": { type: "boolean" },
|
||||
limit: { type: "string" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
parsed = parseAgentsArgs(argv);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.error(`Error: ${message}`);
|
||||
|
||||
@@ -27,6 +27,26 @@ function getAgentId(agentFromArgs?: string, agentIdFromArgs?: string): string {
|
||||
return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
|
||||
}
|
||||
|
||||
const BLOCKS_OPTIONS = {
|
||||
help: { type: "boolean", short: "h" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
limit: { type: "string" },
|
||||
"block-id": { type: "string" },
|
||||
label: { type: "string" },
|
||||
override: { type: "boolean" },
|
||||
"read-only": { type: "boolean" },
|
||||
} as const;
|
||||
|
||||
function parseBlocksArgs(argv: string[]) {
|
||||
return parseArgs({
|
||||
args: argv,
|
||||
options: BLOCKS_OPTIONS,
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
}
|
||||
|
||||
type CopyBlockResult = {
|
||||
sourceBlock: Awaited<
|
||||
ReturnType<Awaited<ReturnType<typeof getClient>>["blocks"]["retrieve"]>
|
||||
@@ -253,23 +273,9 @@ async function attachBlock(
|
||||
}
|
||||
|
||||
export async function runBlocksSubcommand(argv: string[]): Promise<number> {
|
||||
let parsed: ReturnType<typeof parseArgs>;
|
||||
let parsed: ReturnType<typeof parseBlocksArgs>;
|
||||
try {
|
||||
parsed = parseArgs({
|
||||
args: argv,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
limit: { type: "string" },
|
||||
"block-id": { type: "string" },
|
||||
label: { type: "string" },
|
||||
override: { type: "boolean" },
|
||||
"read-only": { type: "boolean" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
parsed = parseBlocksArgs(argv);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.error(`Error: ${message}`);
|
||||
@@ -306,8 +312,8 @@ export async function runBlocksSubcommand(argv: string[]): Promise<number> {
|
||||
return 1;
|
||||
}
|
||||
const agentId = getAgentId(
|
||||
parsed.values.agent as string | undefined,
|
||||
parsed.values["agent-id"] as string | undefined,
|
||||
parsed.values.agent,
|
||||
parsed.values["agent-id"],
|
||||
);
|
||||
const result = await copyBlock(client, blockId, {
|
||||
labelOverride:
|
||||
@@ -328,8 +334,8 @@ export async function runBlocksSubcommand(argv: string[]): Promise<number> {
|
||||
return 1;
|
||||
}
|
||||
const agentId = getAgentId(
|
||||
parsed.values.agent as string | undefined,
|
||||
parsed.values["agent-id"] as string | undefined,
|
||||
parsed.values.agent,
|
||||
parsed.values["agent-id"],
|
||||
);
|
||||
const result = await attachBlock(client, blockId, {
|
||||
readOnly: parsed.values["read-only"] === true,
|
||||
|
||||
@@ -40,6 +40,24 @@ function getAgentId(agentFromArgs?: string, agentIdFromArgs?: string): string {
|
||||
return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
|
||||
}
|
||||
|
||||
const MEMFS_OPTIONS = {
|
||||
help: { type: "boolean", short: "h" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
from: { type: "string" },
|
||||
force: { type: "boolean" },
|
||||
out: { type: "string" },
|
||||
} as const;
|
||||
|
||||
function parseMemfsArgs(argv: string[]) {
|
||||
return parseArgs({
|
||||
args: argv,
|
||||
options: MEMFS_OPTIONS,
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
}
|
||||
|
||||
function getMemoryRoot(agentId: string): string {
|
||||
return join(homedir(), ".letta", "agents", agentId, "memory");
|
||||
}
|
||||
@@ -97,21 +115,9 @@ function resolveBackupPath(agentId: string, from: string): string {
|
||||
}
|
||||
|
||||
export async function runMemfsSubcommand(argv: string[]): Promise<number> {
|
||||
let parsed: ReturnType<typeof parseArgs>;
|
||||
let parsed: ReturnType<typeof parseMemfsArgs>;
|
||||
try {
|
||||
parsed = parseArgs({
|
||||
args: argv,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
from: { type: "string" },
|
||||
force: { type: "boolean" },
|
||||
out: { type: "string" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
parsed = parseMemfsArgs(argv);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.error(`Error: ${message}`);
|
||||
@@ -126,10 +132,7 @@ export async function runMemfsSubcommand(argv: string[]): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const agentId = getAgentId(
|
||||
parsed.values.agent as string | undefined,
|
||||
parsed.values["agent-id"] as string | undefined,
|
||||
);
|
||||
const agentId = getAgentId(parsed.values.agent, parsed.values["agent-id"]);
|
||||
|
||||
if (!agentId) {
|
||||
console.error(
|
||||
@@ -204,7 +207,7 @@ export async function runMemfsSubcommand(argv: string[]): Promise<number> {
|
||||
}
|
||||
|
||||
if (action === "restore") {
|
||||
const from = parsed.values.from as string | undefined;
|
||||
const from = parsed.values.from;
|
||||
if (!from) {
|
||||
console.error("Missing --from <backup>.");
|
||||
return 1;
|
||||
@@ -231,7 +234,7 @@ export async function runMemfsSubcommand(argv: string[]): Promise<number> {
|
||||
}
|
||||
|
||||
if (action === "export") {
|
||||
const out = parsed.values.out as string | undefined;
|
||||
const out = parsed.values.out;
|
||||
if (!out) {
|
||||
console.error("Missing --out <dir>.");
|
||||
return 1;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { parseArgs } from "node:util";
|
||||
import { getClient } from "../../agent/client";
|
||||
|
||||
type SearchMode = "vector" | "fts" | "hybrid";
|
||||
type ListOrder = "asc" | "desc";
|
||||
|
||||
function printUsage(): void {
|
||||
console.log(
|
||||
@@ -52,32 +53,45 @@ function parseMode(value: unknown): SearchMode | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseOrder(value: unknown): ListOrder | undefined {
|
||||
if (typeof value === "string" && (value === "asc" || value === "desc")) {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getAgentId(agentFromArgs?: string, agentIdFromArgs?: string): string {
|
||||
return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
|
||||
}
|
||||
|
||||
const MESSAGES_OPTIONS = {
|
||||
help: { type: "boolean", short: "h" },
|
||||
query: { type: "string" },
|
||||
mode: { type: "string" },
|
||||
"start-date": { type: "string" },
|
||||
"end-date": { type: "string" },
|
||||
limit: { type: "string" },
|
||||
"all-agents": { type: "boolean" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
after: { type: "string" },
|
||||
before: { type: "string" },
|
||||
order: { type: "string" },
|
||||
} as const;
|
||||
|
||||
function parseMessagesArgs(argv: string[]) {
|
||||
return parseArgs({
|
||||
args: argv,
|
||||
options: MESSAGES_OPTIONS,
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
}
|
||||
|
||||
export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
let parsed: ReturnType<typeof parseArgs>;
|
||||
let parsed: ReturnType<typeof parseMessagesArgs>;
|
||||
try {
|
||||
parsed = parseArgs({
|
||||
args: argv,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
query: { type: "string" },
|
||||
mode: { type: "string" },
|
||||
"start-date": { type: "string" },
|
||||
"end-date": { type: "string" },
|
||||
limit: { type: "string" },
|
||||
"all-agents": { type: "boolean" },
|
||||
agent: { type: "string" },
|
||||
"agent-id": { type: "string" },
|
||||
after: { type: "string" },
|
||||
before: { type: "string" },
|
||||
order: { type: "string" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
parsed = parseMessagesArgs(argv);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.error(`Error: ${message}`);
|
||||
@@ -103,8 +117,8 @@ export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
|
||||
const allAgents = parsed.values["all-agents"] ?? false;
|
||||
const agentId = getAgentId(
|
||||
parsed.values.agent as string | undefined,
|
||||
parsed.values["agent-id"] as string | undefined,
|
||||
parsed.values.agent,
|
||||
parsed.values["agent-id"],
|
||||
);
|
||||
if (!allAgents && !agentId) {
|
||||
console.error(
|
||||
@@ -117,8 +131,8 @@ export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
query,
|
||||
agent_id: allAgents ? undefined : agentId,
|
||||
search_mode: parseMode(parsed.values.mode) ?? "hybrid",
|
||||
start_date: parsed.values["start-date"] as string | undefined,
|
||||
end_date: parsed.values["end-date"] as string | undefined,
|
||||
start_date: parsed.values["start-date"],
|
||||
end_date: parsed.values["end-date"],
|
||||
limit: parseLimit(parsed.values.limit, 10),
|
||||
});
|
||||
|
||||
@@ -128,8 +142,8 @@ export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
|
||||
if (action === "list") {
|
||||
const agentId = getAgentId(
|
||||
parsed.values.agent as string | undefined,
|
||||
parsed.values["agent-id"] as string | undefined,
|
||||
parsed.values.agent,
|
||||
parsed.values["agent-id"],
|
||||
);
|
||||
if (!agentId) {
|
||||
console.error(
|
||||
@@ -138,11 +152,18 @@ export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const orderRaw = parsed.values.order;
|
||||
const order = parseOrder(orderRaw);
|
||||
if (orderRaw !== undefined && !order) {
|
||||
console.error(`Invalid --order "${orderRaw}". Use "asc" or "desc".`);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const response = await client.agents.messages.list(agentId, {
|
||||
limit: parseLimit(parsed.values.limit, 20),
|
||||
after: parsed.values.after as string | undefined,
|
||||
before: parsed.values.before as string | undefined,
|
||||
order: parsed.values.order as "asc" | "desc" | undefined,
|
||||
after: parsed.values.after,
|
||||
before: parsed.values.before,
|
||||
order,
|
||||
});
|
||||
|
||||
const messages = response.items ?? [];
|
||||
@@ -151,11 +172,9 @@ export async function runMessagesSubcommand(argv: string[]): Promise<number> {
|
||||
|
||||
let filtered = messages;
|
||||
if (startDate || endDate) {
|
||||
const startTime = startDate
|
||||
? new Date(startDate as string).getTime()
|
||||
: 0;
|
||||
const startTime = startDate ? new Date(startDate).getTime() : 0;
|
||||
const endTime = endDate
|
||||
? new Date(endDate as string).getTime()
|
||||
? new Date(endDate).getTime()
|
||||
: Number.POSITIVE_INFINITY;
|
||||
filtered = messages.filter((msg) => {
|
||||
if (!("date" in msg) || !msg.date) return true;
|
||||
|
||||
Reference in New Issue
Block a user