refactor: centralize cli timeout parsing
This commit is contained in:
@@ -114,7 +114,7 @@
|
||||
- Docs: expand parameter descriptions for agent/wake hooks. (#532) — thanks @mcinteerj
|
||||
- Docs: add community showcase entries from Discord. (#476) — thanks @gupsammy
|
||||
- TUI: refresh status bar after think/verbose/reasoning changes. (#519) — thanks @jdrhyne
|
||||
- TUI: stop overriding agent timeout so config defaults apply. (#549)
|
||||
- TUI: stop overriding agent timeout so config defaults apply; warn on invalid `--timeout-ms`. (#549)
|
||||
- Status: show Verbose/Elevated only when enabled.
|
||||
- Status: filter usage summary to the active model provider.
|
||||
- Status: map model providers to usage sources so unrelated usage doesn’t appear.
|
||||
|
||||
@@ -109,7 +109,7 @@ Session lifecycle:
|
||||
- `--session <key>`: Session key (default: `main`, or `global` when scope is global)
|
||||
- `--deliver`: Deliver assistant replies to the provider (default off)
|
||||
- `--thinking <level>`: Override thinking level for sends
|
||||
- `--timeout-ms <ms>`: Agent timeout (defaults to `agents.defaults.timeoutSeconds`)
|
||||
- `--timeout-ms <ms>`: Agent timeout in ms (defaults to `agents.defaults.timeoutSeconds`)
|
||||
- `--history-limit <n>`: History entries to load (default 200)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { parseTimeoutMs } from "./parse-timeout.js";
|
||||
|
||||
export function parseEnvPairs(
|
||||
pairs: unknown,
|
||||
): Record<string, string> | undefined {
|
||||
@@ -14,17 +16,4 @@ export function parseEnvPairs(
|
||||
return Object.keys(env).length > 0 ? env : undefined;
|
||||
}
|
||||
|
||||
export function parseTimeoutMs(raw: unknown): number | undefined {
|
||||
if (raw === undefined || raw === null) return undefined;
|
||||
let value = Number.NaN;
|
||||
if (typeof raw === "number") {
|
||||
value = raw;
|
||||
} else if (typeof raw === "bigint") {
|
||||
value = Number(raw);
|
||||
} else if (typeof raw === "string") {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) return undefined;
|
||||
value = Number.parseInt(trimmed, 10);
|
||||
}
|
||||
return Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
export { parseTimeoutMs };
|
||||
|
||||
14
src/cli/parse-timeout.ts
Normal file
14
src/cli/parse-timeout.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export function parseTimeoutMs(raw: unknown): number | undefined {
|
||||
if (raw === undefined || raw === null) return undefined;
|
||||
let value = Number.NaN;
|
||||
if (typeof raw === "number") {
|
||||
value = raw;
|
||||
} else if (typeof raw === "bigint") {
|
||||
value = Number(raw);
|
||||
} else if (typeof raw === "string") {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) return undefined;
|
||||
value = Number.parseInt(trimmed, 10);
|
||||
}
|
||||
return Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
@@ -98,6 +98,19 @@ describe("cli program", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("warns and ignores invalid tui timeout override", async () => {
|
||||
const program = buildProgram();
|
||||
await program.parseAsync(["tui", "--timeout-ms", "nope"], {
|
||||
from: "user",
|
||||
});
|
||||
expect(runtime.error).toHaveBeenCalledWith(
|
||||
'warning: invalid --timeout-ms "nope"; ignoring',
|
||||
);
|
||||
expect(runTui).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ timeoutMs: undefined }),
|
||||
);
|
||||
});
|
||||
|
||||
it("runs config alias as configure", async () => {
|
||||
const program = buildProgram();
|
||||
await program.parseAsync(["config"], { from: "user" });
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Command } from "commander";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { runTui } from "../tui/tui.js";
|
||||
import { parseTimeoutMs } from "./parse-timeout.js";
|
||||
|
||||
export function registerTuiCli(program: Command) {
|
||||
program
|
||||
@@ -26,14 +27,12 @@ export function registerTuiCli(program: Command) {
|
||||
.option("--history-limit <n>", "History entries to load", "200")
|
||||
.action(async (opts) => {
|
||||
try {
|
||||
const timeoutMs =
|
||||
typeof opts.timeoutMs === "undefined"
|
||||
? undefined
|
||||
: Number.parseInt(String(opts.timeoutMs), 10);
|
||||
const normalizedTimeoutMs =
|
||||
typeof timeoutMs === "number" && Number.isFinite(timeoutMs)
|
||||
? timeoutMs
|
||||
: undefined;
|
||||
const timeoutMs = parseTimeoutMs(opts.timeoutMs);
|
||||
if (opts.timeoutMs !== undefined && timeoutMs === undefined) {
|
||||
defaultRuntime.error(
|
||||
`warning: invalid --timeout-ms "${String(opts.timeoutMs)}"; ignoring`,
|
||||
);
|
||||
}
|
||||
const historyLimit = Number.parseInt(
|
||||
String(opts.historyLimit ?? "200"),
|
||||
10,
|
||||
@@ -46,7 +45,7 @@ export function registerTuiCli(program: Command) {
|
||||
deliver: Boolean(opts.deliver),
|
||||
thinking: opts.thinking as string | undefined,
|
||||
message: opts.message as string | undefined,
|
||||
timeoutMs: normalizedTimeoutMs,
|
||||
timeoutMs,
|
||||
historyLimit: Number.isNaN(historyLimit) ? undefined : historyLimit,
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user