llmist 0.2.2 → 0.3.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.
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ import { Command, InvalidArgumentError as InvalidArgumentError3 } from "commande
|
|
|
67
67
|
// package.json
|
|
68
68
|
var package_default = {
|
|
69
69
|
name: "llmist",
|
|
70
|
-
version: "0.2.
|
|
70
|
+
version: "0.2.2",
|
|
71
71
|
description: "Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.",
|
|
72
72
|
type: "module",
|
|
73
73
|
main: "dist/index.cjs",
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/constants.ts","../src/cli/program.ts","../package.json","../src/cli/agent-command.ts","../src/cli/builtin-gadgets.ts","../src/cli/gadgets.ts","../src/cli/utils.ts","../src/cli/complete-command.ts","../src/cli/models-command.ts","../src/cli/environment.ts","../src/cli.ts"],"sourcesContent":["import type { ParameterFormat } from \"../gadgets/parser.js\";\n\n/** CLI program name */\nexport const CLI_NAME = \"llmist\";\n\n/** CLI program description shown in --help */\nexport const CLI_DESCRIPTION = \"Command line utilities for llmist agents and direct LLM access.\";\n\n/** Available CLI commands */\nexport const COMMANDS = {\n complete: \"complete\",\n agent: \"agent\",\n models: \"models\",\n} as const;\n\n/** Valid log level names */\nexport const LOG_LEVELS = [\"silly\", \"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"] as const;\nexport type LogLevelName = (typeof LOG_LEVELS)[number];\n\n/** Default model used when --model is not specified */\nexport const DEFAULT_MODEL = \"openai:gpt-5-nano\";\n\n/** Default parameter format for gadgets */\nexport const DEFAULT_PARAMETER_FORMAT: ParameterFormat = \"json\";\n\n/** Command-line option flags */\nexport const OPTION_FLAGS = {\n model: \"-m, --model <identifier>\",\n systemPrompt: \"-s, --system <prompt>\",\n temperature: \"-t, --temperature <value>\",\n maxTokens: \"--max-tokens <count>\",\n maxIterations: \"-i, --max-iterations <count>\",\n gadgetModule: \"-g, --gadget <module>\",\n parameterFormat: \"--parameter-format <format>\",\n logLevel: \"--log-level <level>\",\n logFile: \"--log-file <path>\",\n noBuiltins: \"--no-builtins\",\n} as const;\n\n/** Human-readable descriptions for command-line options */\nexport const OPTION_DESCRIPTIONS = {\n model: \"Model identifier, e.g. openai:gpt-5-nano or anthropic:claude-sonnet-4-5.\",\n systemPrompt: \"Optional system prompt prepended to the conversation.\",\n temperature: \"Sampling temperature between 0 and 2.\",\n maxTokens: \"Maximum number of output tokens requested from the model.\",\n maxIterations: \"Maximum number of agent loop iterations before exiting.\",\n gadgetModule:\n \"Path or module specifier for a gadget export. Repeat to register multiple gadgets.\",\n parameterFormat: \"Format for gadget parameter schemas: 'json', 'yaml', or 'auto'.\",\n logLevel: \"Log level: silly, trace, debug, info, warn, error, fatal.\",\n logFile: \"Path to log file. When set, logs are written to file instead of stderr.\",\n noBuiltins: \"Disable built-in gadgets (AskUser, TellUser).\",\n} as const;\n\n/** Prefix for summary output written to stderr */\nexport const SUMMARY_PREFIX = \"[llmist]\";\n","import { Command, InvalidArgumentError } from \"commander\";\n\nimport packageJson from \"../../package.json\";\n\nimport { registerAgentCommand } from \"./agent-command.js\";\nimport { registerCompleteCommand } from \"./complete-command.js\";\nimport { registerModelsCommand } from \"./models-command.js\";\nimport {\n CLI_DESCRIPTION,\n CLI_NAME,\n LOG_LEVELS,\n type LogLevelName,\n OPTION_DESCRIPTIONS,\n OPTION_FLAGS,\n} from \"./constants.js\";\nimport type { CLIEnvironment, CLILoggerConfig } from \"./environment.js\";\nimport { createDefaultEnvironment } from \"./environment.js\";\n\n/**\n * Parses and validates the log level option value.\n */\nfunction parseLogLevel(value: string): LogLevelName {\n const normalized = value.toLowerCase() as LogLevelName;\n if (!LOG_LEVELS.includes(normalized)) {\n throw new InvalidArgumentError(`Log level must be one of: ${LOG_LEVELS.join(\", \")}`);\n }\n return normalized;\n}\n\n/**\n * Global CLI options that apply to all commands.\n */\ninterface GlobalOptions {\n logLevel?: LogLevelName;\n logFile?: string;\n}\n\n/**\n * Creates and configures the CLI program with complete and agent commands.\n *\n * @param env - CLI environment configuration for I/O and dependencies\n * @returns Configured Commander program ready for parsing\n */\nexport function createProgram(env: CLIEnvironment): Command {\n const program = new Command();\n\n program\n .name(CLI_NAME)\n .description(CLI_DESCRIPTION)\n .version(packageJson.version)\n .option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel)\n .option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile)\n .configureOutput({\n writeOut: (str) => env.stdout.write(str),\n writeErr: (str) => env.stderr.write(str),\n });\n\n registerCompleteCommand(program, env);\n registerAgentCommand(program, env);\n registerModelsCommand(program, env);\n\n return program;\n}\n\n/**\n * Main entry point for running the CLI.\n * Creates environment, parses arguments, and executes the appropriate command.\n *\n * @param overrides - Optional environment overrides for testing or customization\n */\nexport async function runCLI(overrides: Partial<CLIEnvironment> = {}): Promise<void> {\n // First pass: parse global options only (skip if help requested)\n const preParser = new Command();\n preParser\n .option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel)\n .option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile)\n .allowUnknownOption()\n .allowExcessArguments()\n .helpOption(false); // Don't intercept --help\n\n preParser.parse(process.argv);\n const globalOpts = preParser.opts<GlobalOptions>();\n\n // Create environment with logger config from global options\n const loggerConfig: CLILoggerConfig = {\n logLevel: globalOpts.logLevel,\n logFile: globalOpts.logFile,\n };\n\n const defaultEnv = createDefaultEnvironment(loggerConfig);\n const env: CLIEnvironment = { ...defaultEnv, ...overrides };\n const program = createProgram(env);\n await program.parseAsync(env.argv);\n}\n","{\n \"name\": \"llmist\",\n \"version\": \"0.2.1\",\n \"description\": \"Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.\",\n \"type\": \"module\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./testing\": {\n \"import\": {\n \"types\": \"./dist/testing/index.d.ts\",\n \"default\": \"./dist/testing/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/testing/index.d.cts\",\n \"default\": \"./dist/testing/index.cjs\"\n }\n }\n },\n \"scripts\": {\n \"cli\": \"bun run scripts/cli-runner.ts\",\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome lint .\",\n \"format\": \"biome format --write .\",\n \"check\": \"biome check --write .\",\n \"test\": \"bun test\",\n \"test:unit\": \"bun test src/agent src/core src/gadgets src/providers src/testing\",\n \"test:watch\": \"bun test --watch\",\n \"test:e2e\": \"bun test src/e2e --timeout 60000 --bail 1\",\n \"test:e2e:watch\": \"bun test src/e2e --watch --timeout 60000\",\n \"test:all\": \"bun run test && bun run test:e2e\",\n \"clean\": \"rimraf dist\",\n \"prepare\": \"node scripts/install-hooks.js || true\",\n \"release:dry\": \"bunx semantic-release --dry-run\"\n },\n \"bin\": {\n \"llmist\": \"dist/cli.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/zbigniewsobiecki/llmist.git\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"llm\",\n \"ai\",\n \"agent\",\n \"agents\",\n \"openai\",\n \"anthropic\",\n \"claude\",\n \"gemini\",\n \"gpt\",\n \"streaming\",\n \"function-calling\",\n \"tool-calling\",\n \"typescript\",\n \"universal-client\",\n \"multi-provider\",\n \"hooks\",\n \"gadgets\"\n ],\n \"author\": \"\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@anthropic-ai/sdk\": \"^0.69.0\",\n \"@google/genai\": \"^1.27.0\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^12.1.0\",\n \"js-yaml\": \"^4.1.0\",\n \"openai\": \"^6.0.0\",\n \"tiktoken\": \"^1.0.22\",\n \"tslog\": \"^4.10.2\",\n \"zod\": \"^4.1.12\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.3.2\",\n \"@commitlint/cli\": \"^20.1.0\",\n \"@commitlint/config-conventional\": \"^20.0.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^20.12.7\",\n \"bun-types\": \"^1.3.2\",\n \"dotenv\": \"^17.2.3\",\n \"rimraf\": \"^5.0.5\",\n \"semantic-release\": \"^25.0.2\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.4.5\"\n }\n}\n","import { createInterface } from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { type Command, InvalidArgumentError } from \"commander\";\nimport { AgentBuilder } from \"../agent/builder.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport type { ParameterFormat } from \"../gadgets/parser.js\";\nimport { GadgetRegistry } from \"../gadgets/registry.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport { builtinGadgets } from \"./builtin-gadgets.js\";\nimport {\n COMMANDS,\n DEFAULT_MODEL,\n DEFAULT_PARAMETER_FORMAT,\n OPTION_DESCRIPTIONS,\n OPTION_FLAGS,\n} from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport { loadGadgets } from \"./gadgets.js\";\nimport {\n createNumericParser,\n executeAction,\n isInteractive,\n renderSummary,\n resolvePrompt,\n StreamPrinter,\n StreamProgress,\n} from \"./utils.js\";\n\n/**\n * Configuration options for the agent command.\n */\ninterface AgentCommandOptions {\n model: string;\n system?: string;\n temperature?: number;\n maxIterations?: number;\n gadget?: string[];\n parameterFormat: ParameterFormat;\n builtins: boolean; // --no-builtins sets this to false\n}\n\nconst PARAMETER_FORMAT_VALUES: ParameterFormat[] = [\"json\", \"yaml\", \"auto\"];\n\n/**\n * Parses and validates the parameter format option value.\n *\n * @param value - User-provided parameter format string\n * @returns Validated parameter format\n * @throws InvalidArgumentError if format is not one of: json, yaml, auto\n */\nfunction parseParameterFormat(value: string): ParameterFormat {\n const normalized = value.toLowerCase() as ParameterFormat;\n if (!PARAMETER_FORMAT_VALUES.includes(normalized)) {\n throw new InvalidArgumentError(\"Parameter format must be one of 'json', 'yaml', or 'auto'.\");\n }\n return normalized;\n}\n\n/**\n * Creates a human input handler for interactive mode.\n * Only returns a handler if stdin is a TTY (terminal), not a pipe.\n *\n * @param env - CLI environment\n * @param progress - Progress indicator to pause during input\n * @returns Human input handler function or undefined if not interactive\n */\nfunction createHumanInputHandler(\n env: CLIEnvironment,\n progress: StreamProgress,\n): ((question: string) => Promise<string>) | undefined {\n const stdout = env.stdout as NodeJS.WriteStream;\n if (!isInteractive(env.stdin) || typeof stdout.isTTY !== \"boolean\" || !stdout.isTTY) {\n return undefined;\n }\n\n return async (question: string): Promise<string> => {\n progress.pause(); // Pause progress indicator during human input\n const rl = createInterface({ input: env.stdin, output: env.stdout });\n try {\n // Display question on first prompt only\n const questionLine = question.trim() ? `\\n${question.trim()}` : \"\";\n let isFirst = true;\n\n // Loop until non-empty input (like a REPL)\n while (true) {\n const statsPrompt = progress.formatPrompt();\n const prompt = isFirst ? `${questionLine}\\n${statsPrompt}` : statsPrompt;\n isFirst = false;\n\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed) {\n return trimmed;\n }\n // Empty input - show prompt again (no question repeat)\n }\n } finally {\n rl.close();\n }\n };\n}\n\n/**\n * Formats a gadget execution result for stderr output with colors.\n *\n * @param result - Gadget execution result with timing and output info\n * @returns Formatted summary string with ANSI colors\n */\nfunction formatGadgetSummary(result: {\n gadgetName: string;\n executionTimeMs: number;\n error?: string;\n result?: string;\n breaksLoop?: boolean;\n}): string {\n const gadgetLabel = chalk.magenta.bold(result.gadgetName);\n const timeLabel = chalk.dim(`${Math.round(result.executionTimeMs)}ms`);\n\n if (result.error) {\n return `${chalk.red(\"✗\")} ${gadgetLabel} ${chalk.red(\"error:\")} ${result.error} ${timeLabel}`;\n }\n\n if (result.breaksLoop) {\n return `${chalk.yellow(\"⏹\")} ${gadgetLabel} ${chalk.yellow(\"finished:\")} ${result.result} ${timeLabel}`;\n }\n\n // For TellUser, show full text without truncation since it's meant for user messages\n // For other gadgets, truncate long results for cleaner output\n const maxLen = 80;\n const shouldTruncate = result.gadgetName !== \"TellUser\";\n const resultText = result.result\n ? shouldTruncate && result.result.length > maxLen\n ? `${result.result.slice(0, maxLen)}...`\n : result.result\n : \"\";\n\n return `${chalk.green(\"✓\")} ${gadgetLabel} ${chalk.dim(\"→\")} ${resultText} ${timeLabel}`;\n}\n\n/**\n * Handles the agent command execution.\n * Runs the full agent loop with gadgets and streams output.\n *\n * @param promptArg - User prompt from command line argument (optional if using stdin)\n * @param options - Agent command options (model, gadgets, max iterations, etc.)\n * @param env - CLI environment for I/O operations\n */\nasync function handleAgentCommand(\n promptArg: string | undefined,\n options: AgentCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const prompt = await resolvePrompt(promptArg, env);\n const client = env.createClient();\n\n const registry = new GadgetRegistry();\n\n // Register built-in gadgets by default (AskUser, TellUser)\n // --no-builtins sets options.builtins to false\n if (options.builtins !== false) {\n for (const gadget of builtinGadgets) {\n registry.registerByClass(gadget);\n }\n }\n\n // Load and register user-provided gadgets (can override built-ins)\n const gadgetSpecifiers = options.gadget ?? [];\n if (gadgetSpecifiers.length > 0) {\n const gadgets = await loadGadgets(gadgetSpecifiers, process.cwd());\n for (const gadget of gadgets) {\n registry.registerByClass(gadget);\n }\n }\n\n const printer = new StreamPrinter(env.stdout);\n const stderrTTY = (env.stderr as NodeJS.WriteStream).isTTY === true;\n const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);\n\n let finishReason: string | null | undefined;\n let usage: TokenUsage | undefined;\n let iterations = 0;\n\n // Estimate tokens from all messages\n const estimateMessagesTokens = (messages: Array<{ role: string; content: string }>) => {\n const totalChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);\n return Math.round(totalChars / FALLBACK_CHARS_PER_TOKEN);\n };\n\n const builder = new AgentBuilder(client)\n .withModel(options.model)\n .withLogger(env.createLogger(\"llmist:cli:agent\"))\n .withHooks({\n observers: {\n onLLMCallStart: async (context) => {\n // Start new call in streaming mode with model and estimated tokens from full messages\n const estimate = estimateMessagesTokens(context.options.messages);\n progress.startCall(context.options.model, estimate);\n },\n onStreamChunk: async (context) => {\n // Update output token estimate from accumulated text\n progress.update(context.accumulatedText.length);\n // Capture actual tokens when available from stream\n if (context.usage) {\n if (context.usage.inputTokens) {\n progress.setInputTokens(context.usage.inputTokens, false);\n }\n if (context.usage.outputTokens) {\n progress.setOutputTokens(context.usage.outputTokens, false);\n }\n }\n },\n onLLMCallComplete: async (context) => {\n finishReason = context.finishReason;\n usage = context.usage;\n iterations = Math.max(iterations, context.iteration + 1);\n // End call and switch to cumulative mode\n progress.endCall(context.usage);\n },\n },\n });\n\n // Add optional configurations\n if (options.system) {\n builder.withSystem(options.system);\n }\n if (options.maxIterations !== undefined) {\n builder.withMaxIterations(options.maxIterations);\n }\n if (options.temperature !== undefined) {\n builder.withTemperature(options.temperature);\n }\n\n const humanInputHandler = createHumanInputHandler(env, progress);\n if (humanInputHandler) {\n builder.onHumanInput(humanInputHandler);\n }\n\n // Add gadgets from the registry\n const gadgets = registry.getAll();\n if (gadgets.length > 0) {\n builder.withGadgets(...gadgets);\n }\n\n // Note: parameterFormat is not directly supported in AgentBuilder\n // This might need to be added to AgentBuilder API if needed\n\n const agent = builder.ask(prompt);\n\n for await (const event of agent.run()) {\n if (event.type === \"text\") {\n progress.pause(); // Must pause to avoid stderr/stdout interleaving\n printer.write(event.content);\n } else if (event.type === \"gadget_result\") {\n progress.pause(); // Clear progress before gadget output\n // Only show gadget summaries if stderr is a TTY (not redirected)\n if (stderrTTY) {\n env.stderr.write(`${formatGadgetSummary(event.result)}\\n`);\n }\n // Note: progress.start() is called by onLLMCallStart hook\n }\n // Note: human_input_required event is not emitted - handled by callback in createHumanInputHandler\n }\n\n progress.complete();\n printer.ensureNewline();\n\n // Only show summary if stderr is a TTY (not redirected)\n if (stderrTTY) {\n const summary = renderSummary({\n finishReason,\n usage,\n iterations,\n cost: progress.getTotalCost(),\n });\n if (summary) {\n env.stderr.write(`${summary}\\n`);\n }\n }\n}\n\n/**\n * Registers the agent command with the CLI program.\n * Configures options for model, gadgets, max iterations, temperature, and parameter format.\n *\n * @param program - Commander program to register the command with\n * @param env - CLI environment for dependencies and I/O\n */\nexport function registerAgentCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.agent)\n .description(\"Run the llmist agent loop with optional gadgets.\")\n .argument(\"[prompt]\", \"Prompt for the agent loop. Falls back to stdin when available.\")\n .option(OPTION_FLAGS.model, OPTION_DESCRIPTIONS.model, DEFAULT_MODEL)\n .option(OPTION_FLAGS.systemPrompt, OPTION_DESCRIPTIONS.systemPrompt)\n .option(\n OPTION_FLAGS.temperature,\n OPTION_DESCRIPTIONS.temperature,\n createNumericParser({ label: \"Temperature\", min: 0, max: 2 }),\n )\n .option(\n OPTION_FLAGS.maxIterations,\n OPTION_DESCRIPTIONS.maxIterations,\n createNumericParser({ label: \"Max iterations\", integer: true, min: 1 }),\n )\n .option(\n OPTION_FLAGS.gadgetModule,\n OPTION_DESCRIPTIONS.gadgetModule,\n (value: string, previous: string[] = []) => [...previous, value],\n [] as string[],\n )\n .option(\n OPTION_FLAGS.parameterFormat,\n OPTION_DESCRIPTIONS.parameterFormat,\n parseParameterFormat,\n DEFAULT_PARAMETER_FORMAT,\n )\n .option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins)\n .action((prompt, options) =>\n executeAction(() => handleAgentCommand(prompt, options as AgentCommandOptions, env), env),\n );\n}\n","/**\n * Built-in gadgets for CLI agent command.\n * These gadgets provide basic communication capabilities out-of-the-box.\n */\nimport chalk from \"chalk\";\nimport { z } from \"zod\";\n\nimport { createGadget } from \"../gadgets/create-gadget.js\";\nimport { BreakLoopException, HumanInputException } from \"../gadgets/exceptions.js\";\n\n/**\n * AskUser gadget - Asks the user a question and waits for their response.\n *\n * Use this when you need more information or clarification from the user.\n */\nexport const askUser = createGadget({\n name: \"AskUser\",\n description:\n \"Ask the user a question when you need more information or clarification. The user's response will be provided back to you.\",\n schema: z.object({\n question: z.string().describe(\"The question to ask the user\"),\n }),\n execute: ({ question }) => {\n throw new HumanInputException(question);\n },\n});\n\n/**\n * TellUser gadget - Outputs a message to the user and optionally ends the conversation.\n *\n * Use this for key results, warnings, or structured output that should stand out\n * from regular streamed text. Set done=true when the task is complete.\n */\nexport const tellUser = createGadget({\n name: \"TellUser\",\n description:\n \"Tell the user something important. Set done=true when your work is complete and you want to end the conversation.\",\n schema: z.object({\n message: z.string().describe(\"The message to display to the user\"),\n done: z.boolean().describe(\"Set to true to end the conversation, false to continue\"),\n type: z\n .enum([\"info\", \"success\", \"warning\", \"error\"])\n .default(\"info\")\n .describe(\"Message type: info, success, warning, or error\"),\n }),\n execute: ({ message, done, type }) => {\n // Format message for display, but return plain text for LLM context\n // This prevents ANSI color codes from polluting the conversation\n const prefixes = {\n info: \"ℹ️ \",\n success: \"✅ \",\n warning: \"⚠️ \",\n error: \"❌ \",\n };\n const plainResult = prefixes[type] + message;\n\n if (done) {\n throw new BreakLoopException(plainResult);\n }\n return plainResult;\n },\n});\n\n/**\n * All built-in gadgets as an array for easy registration.\n */\nexport const builtinGadgets = [askUser, tellUser];\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { BaseGadget } from \"../gadgets/gadget.js\";\n\n/**\n * Function type for importing modules dynamically.\n */\nexport type GadgetImportFunction = (specifier: string) => Promise<unknown>;\n\nconst PATH_PREFIXES = [\".\", \"/\", \"~\"];\n\n/**\n * Type guard to check if a value is a Gadget constructor.\n *\n * @param value - Value to check\n * @returns True if value is a Gadget constructor\n */\nfunction isGadgetConstructor(value: unknown): value is new () => BaseGadget {\n if (typeof value !== \"function\") {\n return false;\n }\n\n const prototype = value.prototype as unknown;\n return Boolean(prototype) && prototype instanceof BaseGadget;\n}\n\n/**\n * Expands ~ to the user's home directory.\n *\n * @param input - Path that may start with ~\n * @returns Expanded path with HOME directory\n */\nfunction expandHomePath(input: string): string {\n if (!input.startsWith(\"~\")) {\n return input;\n }\n\n const home = process.env.HOME;\n if (!home) {\n return input;\n }\n\n return path.join(home, input.slice(1));\n}\n\n/**\n * Determines if a specifier is a file path vs npm module name.\n * File paths start with ., /, ~ or contain path separators.\n *\n * @param specifier - Module specifier to check\n * @returns True if specifier represents a file path\n */\nfunction isFileLikeSpecifier(specifier: string): boolean {\n return (\n PATH_PREFIXES.some((prefix) => specifier.startsWith(prefix)) || specifier.includes(path.sep)\n );\n}\n\n/**\n * Resolves a gadget specifier to either a file URL or npm module name.\n * File paths are resolved relative to cwd and converted to file:// URLs.\n *\n * @param specifier - Original gadget specifier (file path or module name)\n * @param cwd - Current working directory for resolving relative paths\n * @returns Resolved specifier (file:// URL for files, module name for packages)\n * @throws Error if file path doesn't exist\n */\nexport function resolveGadgetSpecifier(specifier: string, cwd: string): string {\n if (!isFileLikeSpecifier(specifier)) {\n return specifier;\n }\n\n const expanded = expandHomePath(specifier);\n const resolvedPath = path.resolve(cwd, expanded);\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Gadget module not found at ${resolvedPath}`);\n }\n return pathToFileURL(resolvedPath).href;\n}\n\n/**\n * Recursively extracts all Gadget instances and classes from a module's exports.\n * Searches default export, named exports, nested objects, and arrays.\n * Automatically instantiates Gadget classes.\n *\n * @param moduleExports - Module exports object to search\n * @returns Array of Gadget instances found in exports\n */\nexport function extractGadgetsFromModule(moduleExports: unknown): BaseGadget[] {\n const results: BaseGadget[] = [];\n const visited = new Set<unknown>();\n\n const visit = (value: unknown) => {\n if (value === undefined || value === null) {\n return;\n }\n\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n\n if (value instanceof BaseGadget) {\n results.push(value);\n return;\n }\n\n if (isGadgetConstructor(value)) {\n results.push(new value());\n return;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n visit(entry);\n }\n return;\n }\n\n if (typeof value === \"object\") {\n for (const entry of Object.values(value as Record<string, unknown>)) {\n visit(entry);\n }\n }\n };\n\n visit(moduleExports);\n return results;\n}\n\n/**\n * Loads gadgets from one or more file paths or npm module names.\n * Resolves paths, imports modules, and extracts gadgets.\n *\n * @param specifiers - Array of gadget specifiers (file paths or module names)\n * @param cwd - Current working directory for resolving relative paths\n * @param importer - Function to dynamically import modules (default: native import)\n * @returns Array of loaded Gadget instances\n * @throws Error if module fails to load, contains no gadgets, or initialization fails\n */\nexport async function loadGadgets(\n specifiers: string[],\n cwd: string,\n importer: GadgetImportFunction = (specifier) => import(specifier),\n): Promise<BaseGadget[]> {\n const gadgets: BaseGadget[] = [];\n\n for (const specifier of specifiers) {\n const resolved = resolveGadgetSpecifier(specifier, cwd);\n let exports: unknown;\n try {\n exports = await importer(resolved);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load gadget module '${specifier}': ${message}`);\n }\n\n let extracted: BaseGadget[];\n try {\n extracted = extractGadgetsFromModule(exports);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to initialize gadgets from module '${specifier}': ${message}`);\n }\n if (extracted.length === 0) {\n throw new Error(`Module '${specifier}' does not export any Gadget instances.`);\n }\n gadgets.push(...extracted);\n }\n\n return gadgets;\n}\n","import chalk from \"chalk\";\nimport { InvalidArgumentError } from \"commander\";\n\nimport type { ModelRegistry } from \"../core/model-registry.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport type { CLIEnvironment, TTYStream } from \"./environment.js\";\n\n/**\n * Options for creating a numeric value parser.\n */\nexport interface NumericParserOptions {\n label: string;\n integer?: boolean;\n min?: number;\n max?: number;\n}\n\n/**\n * Creates a parser function for numeric command-line options with validation.\n * Validates that values are numbers, optionally integers, and within min/max bounds.\n *\n * @param options - Parser configuration (label, integer, min, max)\n * @returns Parser function that validates and returns the numeric value\n * @throws InvalidArgumentError if validation fails\n */\nexport function createNumericParser({\n label,\n integer = false,\n min,\n max,\n}: NumericParserOptions): (value: string) => number {\n return (value: string) => {\n const parsed = Number(value);\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`${label} must be a number.`);\n }\n\n if (integer && !Number.isInteger(parsed)) {\n throw new InvalidArgumentError(`${label} must be an integer.`);\n }\n\n if (min !== undefined && parsed < min) {\n throw new InvalidArgumentError(`${label} must be greater than or equal to ${min}.`);\n }\n\n if (max !== undefined && parsed > max) {\n throw new InvalidArgumentError(`${label} must be less than or equal to ${max}.`);\n }\n\n return parsed;\n };\n}\n\n/**\n * Helper class for writing text to a stream while tracking newline state.\n * Ensures output ends with a newline for proper terminal formatting.\n */\nexport class StreamPrinter {\n private endedWithNewline = true;\n\n constructor(private readonly target: NodeJS.WritableStream) {}\n\n /**\n * Writes text to the target stream and tracks newline state.\n *\n * @param text - Text to write\n */\n write(text: string): void {\n if (!text) {\n return;\n }\n this.target.write(text);\n this.endedWithNewline = text.endsWith(\"\\n\");\n }\n\n /**\n * Ensures output ends with a newline by writing one if needed.\n */\n ensureNewline(): void {\n if (!this.endedWithNewline) {\n this.target.write(\"\\n\");\n this.endedWithNewline = true;\n }\n }\n}\n\n/**\n * Checks if a stream is a TTY (terminal) for interactive input.\n *\n * @param stream - Stream to check\n * @returns True if stream is a TTY\n */\nexport function isInteractive(stream: TTYStream): boolean {\n return Boolean(stream.isTTY);\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_DELAY_MS = 500; // Don't show spinner for fast responses\n\ntype ProgressMode = \"streaming\" | \"cumulative\";\n\n/**\n * Progress indicator shown while waiting for LLM response.\n * Two modes:\n * - streaming: Shows current LLM call stats (out/in tokens, call time)\n * - cumulative: Shows total stats across all calls (total tokens, iterations, total time)\n * Only displays on TTY (interactive terminal), silent when piped.\n */\nexport class StreamProgress {\n // Animation state\n private frameIndex = 0;\n private interval: ReturnType<typeof setInterval> | null = null;\n private delayTimeout: ReturnType<typeof setTimeout> | null = null;\n private isRunning = false;\n private hasRendered = false;\n\n // Current call stats (streaming mode)\n private mode: ProgressMode = \"cumulative\";\n private model = \"\";\n private callStartTime = Date.now();\n private callInputTokens = 0;\n private callInputTokensEstimated = true;\n private callOutputTokens = 0;\n private callOutputTokensEstimated = true;\n private callOutputChars = 0;\n private isStreaming = false;\n\n // Cumulative stats (cumulative mode)\n private totalStartTime = Date.now();\n private totalTokens = 0;\n private totalCost = 0;\n private iterations = 0;\n\n constructor(\n private readonly target: NodeJS.WritableStream,\n private readonly isTTY: boolean,\n private readonly modelRegistry?: ModelRegistry,\n ) {}\n\n /**\n * Starts a new LLM call. Switches to streaming mode.\n * @param model - Model name being used\n * @param estimatedInputTokens - Estimated input tokens based on prompt length\n */\n startCall(model: string, estimatedInputTokens?: number): void {\n this.mode = \"streaming\";\n this.model = model;\n this.callStartTime = Date.now();\n this.callInputTokens = estimatedInputTokens ?? 0;\n this.callInputTokensEstimated = true;\n this.callOutputTokens = 0;\n this.callOutputTokensEstimated = true;\n this.callOutputChars = 0;\n this.isStreaming = false;\n this.start();\n }\n\n /**\n * Ends the current LLM call. Updates cumulative stats and switches to cumulative mode.\n * @param usage - Final token usage from the call\n */\n endCall(usage?: { inputTokens: number; outputTokens: number; totalTokens: number }): void {\n this.iterations++;\n if (usage) {\n this.totalTokens += usage.totalTokens;\n\n // Calculate and accumulate cost if model registry is available\n if (this.modelRegistry && this.model) {\n try {\n // Strip provider prefix if present (e.g., \"openai:gpt-5-nano\" -> \"gpt-5-nano\")\n const modelName = this.model.includes(\":\")\n ? this.model.split(\":\")[1]\n : this.model;\n\n const cost = this.modelRegistry.estimateCost(\n modelName,\n usage.inputTokens,\n usage.outputTokens,\n );\n if (cost) {\n this.totalCost += cost.totalCost;\n }\n } catch {\n // Ignore errors (e.g., unknown model) - just don't add to cost\n }\n }\n }\n this.pause();\n this.mode = \"cumulative\";\n }\n\n /**\n * Sets the input token count for current call (from stream metadata).\n * @param tokens - Token count\n * @param estimated - If true, shown with ~ prefix until actual count arrives\n */\n setInputTokens(tokens: number, estimated = false): void {\n // Don't overwrite actual count with a new estimate\n if (estimated && !this.callInputTokensEstimated) {\n return;\n }\n this.callInputTokens = tokens;\n this.callInputTokensEstimated = estimated;\n }\n\n /**\n * Sets the output token count for current call (from stream metadata).\n * @param tokens - Token count\n * @param estimated - If true, shown with ~ prefix until actual count arrives\n */\n setOutputTokens(tokens: number, estimated = false): void {\n // Don't overwrite actual count with a new estimate\n if (estimated && !this.callOutputTokensEstimated) {\n return;\n }\n this.callOutputTokens = tokens;\n this.callOutputTokensEstimated = estimated;\n }\n\n /**\n * Starts the progress indicator animation after a brief delay.\n */\n start(): void {\n if (!this.isTTY || this.isRunning) return;\n this.isRunning = true;\n\n // Delay showing spinner to avoid flicker for fast responses\n this.delayTimeout = setTimeout(() => {\n if (this.isRunning) {\n this.interval = setInterval(() => this.render(), 80);\n this.render();\n }\n }, SPINNER_DELAY_MS);\n }\n\n /**\n * Updates output character count for current call and marks streaming as active.\n * @param totalChars - Total accumulated character count\n */\n update(totalChars: number): void {\n this.callOutputChars = totalChars;\n this.isStreaming = true;\n }\n\n private render(): void {\n const spinner = SPINNER_FRAMES[this.frameIndex++ % SPINNER_FRAMES.length];\n\n if (this.mode === \"streaming\") {\n this.renderStreamingMode(spinner);\n } else {\n this.renderCumulativeMode(spinner);\n }\n this.hasRendered = true;\n }\n\n private renderStreamingMode(spinner: string): void {\n const elapsed = ((Date.now() - this.callStartTime) / 1000).toFixed(1);\n\n // Output tokens: use actual if available, otherwise estimate from chars\n const outTokens = this.callOutputTokensEstimated\n ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN)\n : this.callOutputTokens;\n\n // Build status parts: model, out (sent), in (received), cost, time\n const parts: string[] = [];\n if (this.model) {\n parts.push(chalk.cyan(this.model));\n }\n if (this.callInputTokens > 0) {\n const prefix = this.callInputTokensEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"out:\") + chalk.yellow(` ${prefix}${this.callInputTokens}`));\n }\n if (this.isStreaming || outTokens > 0) {\n const prefix = this.callOutputTokensEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"in:\") + chalk.green(` ${prefix}${outTokens}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.dim(\"cost:\") + chalk.cyan(` $${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n\n this.target.write(`\\r${chalk.cyan(spinner)} ${parts.join(chalk.dim(\" | \"))}`);\n }\n\n private renderCumulativeMode(spinner: string): void {\n const elapsed = ((Date.now() - this.totalStartTime) / 1000).toFixed(1);\n\n // Build status parts: model, total tokens, iterations, cost, total time\n const parts: string[] = [];\n if (this.model) {\n parts.push(chalk.cyan(this.model));\n }\n if (this.totalTokens > 0) {\n parts.push(chalk.dim(\"total:\") + chalk.magenta(` ${this.totalTokens}`));\n }\n if (this.iterations > 0) {\n parts.push(chalk.dim(\"iter:\") + chalk.blue(` ${this.iterations}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.dim(\"cost:\") + chalk.cyan(` $${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n\n this.target.write(`\\r${chalk.cyan(spinner)} ${parts.join(chalk.dim(\" | \"))}`);\n }\n\n /**\n * Pauses the progress indicator and clears the line.\n * Can be resumed with start().\n */\n pause(): void {\n if (!this.isTTY || !this.isRunning) return;\n\n if (this.delayTimeout) {\n clearTimeout(this.delayTimeout);\n this.delayTimeout = null;\n }\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n this.isRunning = false;\n\n // Only clear the line if we actually rendered something\n if (this.hasRendered) {\n this.target.write(\"\\r\\x1b[K\");\n this.hasRendered = false;\n }\n }\n\n /**\n * Completes the progress indicator and clears the line.\n */\n complete(): void {\n this.pause();\n }\n\n /**\n * Returns the total accumulated cost across all calls.\n */\n getTotalCost(): number {\n return this.totalCost;\n }\n\n /**\n * Returns a formatted prompt string with stats (like bash PS1).\n * Shows current call stats during streaming, cumulative stats otherwise.\n * Format: \"out: 1.2k │ in: ~300 │ 5s > \" or \"3.6k │ i2 │ 34s > \"\n */\n formatPrompt(): string {\n const parts: string[] = [];\n\n if (this.mode === \"streaming\") {\n // During a call: show current call stats\n const elapsed = Math.round((Date.now() - this.callStartTime) / 1000);\n\n // Output tokens: use actual if available, otherwise estimate from chars\n const outTokens = this.callOutputTokensEstimated\n ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN)\n : this.callOutputTokens;\n const outEstimated = this.callOutputTokensEstimated;\n\n if (this.callInputTokens > 0) {\n const prefix = this.callInputTokensEstimated ? \"~\" : \"\";\n parts.push(\n chalk.dim(\"out:\") + chalk.yellow(` ${prefix}${this.formatTokens(this.callInputTokens)}`),\n );\n }\n if (outTokens > 0) {\n const prefix = outEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"in:\") + chalk.green(` ${prefix}${this.formatTokens(outTokens)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n } else {\n // Between calls: show cumulative stats\n const elapsed = Math.round((Date.now() - this.totalStartTime) / 1000);\n\n if (this.totalTokens > 0) {\n parts.push(chalk.magenta(this.formatTokens(this.totalTokens)));\n }\n if (this.iterations > 0) {\n parts.push(chalk.blue(`i${this.iterations}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.cyan(`$${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n }\n\n return `${parts.join(chalk.dim(\" │ \"))} ${chalk.green(\">\")} `;\n }\n\n /**\n * Formats token count compactly (3625 -> \"3.6k\").\n */\n private formatTokens(tokens: number): string {\n return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : `${tokens}`;\n }\n\n /**\n * Formats cost compactly (0.0001234 -> \"0.00012\", 0.1234 -> \"0.12\", 1.234 -> \"1.23\").\n */\n private formatCost(cost: number): string {\n if (cost < 0.001) {\n return cost.toFixed(5);\n }\n if (cost < 0.01) {\n return cost.toFixed(4);\n }\n if (cost < 1) {\n return cost.toFixed(3);\n }\n return cost.toFixed(2);\n }\n}\n\n/**\n * Reads all data from a readable stream into a string.\n *\n * @param stream - Stream to read from\n * @returns Complete stream contents as string\n */\nasync function readStream(stream: NodeJS.ReadableStream): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of stream) {\n if (typeof chunk === \"string\") {\n chunks.push(chunk);\n } else {\n chunks.push(chunk.toString(\"utf8\"));\n }\n }\n return chunks.join(\"\");\n}\n\n/**\n * Normalizes a prompt by trimming whitespace.\n *\n * @param value - Prompt to normalize\n * @returns Trimmed prompt\n */\nfunction normalizePrompt(value: string): string {\n return value.trim();\n}\n\n/**\n * Resolves the user prompt from either command-line argument or stdin.\n * Priority: 1) promptArg if provided, 2) stdin if piped, 3) error if neither.\n *\n * @param promptArg - Optional prompt from command-line argument\n * @param env - CLI environment for accessing stdin\n * @returns Resolved and normalized prompt\n * @throws Error if no prompt available or stdin is empty\n */\nexport async function resolvePrompt(\n promptArg: string | undefined,\n env: CLIEnvironment,\n): Promise<string> {\n if (promptArg?.trim()) {\n return normalizePrompt(promptArg);\n }\n\n if (isInteractive(env.stdin)) {\n throw new Error(\"Prompt is required. Provide an argument or pipe content via stdin.\");\n }\n\n const pipedInput = normalizePrompt(await readStream(env.stdin));\n if (!pipedInput) {\n throw new Error(\"Received empty stdin payload. Provide a prompt to continue.\");\n }\n\n return pipedInput;\n}\n\n/**\n * Metadata for generating execution summaries.\n */\nexport interface SummaryMetadata {\n finishReason?: string | null;\n usage?: TokenUsage;\n iterations?: number;\n cost?: number;\n}\n\n/**\n * Renders execution metadata as a formatted summary string with colors.\n * Includes iterations, finish reason, and token usage.\n *\n * @param metadata - Summary metadata to format\n * @returns Formatted summary string or null if no metadata\n */\nexport function renderSummary(metadata: SummaryMetadata): string | null {\n const parts: string[] = [];\n\n if (metadata.iterations !== undefined) {\n parts.push(chalk.dim(`iterations: ${metadata.iterations}`));\n }\n\n if (metadata.finishReason) {\n parts.push(chalk.dim(`finish: ${metadata.finishReason}`));\n }\n\n if (metadata.usage) {\n const { inputTokens, outputTokens, totalTokens } = metadata.usage;\n parts.push(\n chalk.dim(`tokens: `) +\n chalk.cyan(`${totalTokens}`) +\n chalk.dim(` (in: ${inputTokens}, out: ${outputTokens})`),\n );\n }\n\n if (metadata.cost !== undefined && metadata.cost > 0) {\n // Format cost with appropriate precision\n let formattedCost: string;\n if (metadata.cost < 0.001) {\n formattedCost = metadata.cost.toFixed(5);\n } else if (metadata.cost < 0.01) {\n formattedCost = metadata.cost.toFixed(4);\n } else if (metadata.cost < 1) {\n formattedCost = metadata.cost.toFixed(3);\n } else {\n formattedCost = metadata.cost.toFixed(2);\n }\n parts.push(chalk.dim(`cost: `) + chalk.cyan(`$${formattedCost}`));\n }\n\n if (parts.length === 0) {\n return null;\n }\n\n return parts.join(chalk.dim(\" │ \"));\n}\n\n/**\n * Executes a CLI action with error handling.\n * Catches errors, writes to stderr, and sets exit code 1 on failure.\n *\n * @param action - Async action to execute\n * @param env - CLI environment for error output and exit code\n */\nexport async function executeAction(\n action: () => Promise<void>,\n env: CLIEnvironment,\n): Promise<void> {\n try {\n await action();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n env.stderr.write(`${chalk.red.bold(\"Error:\")} ${message}\\n`);\n env.setExitCode(1);\n }\n}\n","import type { Command } from \"commander\";\n\nimport { LLMMessageBuilder } from \"../core/messages.js\";\nimport { resolveModel } from \"../core/model-shortcuts.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport { COMMANDS, DEFAULT_MODEL, OPTION_DESCRIPTIONS, OPTION_FLAGS } from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport {\n createNumericParser,\n executeAction,\n renderSummary,\n resolvePrompt,\n StreamPrinter,\n StreamProgress,\n} from \"./utils.js\";\n\n/**\n * Configuration options for the complete command.\n */\ninterface CompleteCommandOptions {\n model: string;\n system?: string;\n temperature?: number;\n maxTokens?: number;\n}\n\n/**\n * Handles the complete command execution.\n * Streams a single LLM response without agent loop or gadgets.\n *\n * @param promptArg - User prompt from command line argument (optional if using stdin)\n * @param options - Complete command options (model, system prompt, temperature, etc.)\n * @param env - CLI environment for I/O operations\n */\nasync function handleCompleteCommand(\n promptArg: string | undefined,\n options: CompleteCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const prompt = await resolvePrompt(promptArg, env);\n const client = env.createClient();\n const model = resolveModel(options.model);\n\n const builder = new LLMMessageBuilder();\n if (options.system) {\n builder.addSystem(options.system);\n }\n builder.addUser(prompt);\n\n const stream = client.stream({\n model,\n messages: builder.build(),\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n });\n\n const printer = new StreamPrinter(env.stdout);\n const stderrTTY = (env.stderr as NodeJS.WriteStream).isTTY === true;\n const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);\n\n // Start call with model and estimate based on prompt length\n const estimatedInputTokens = Math.round(prompt.length / FALLBACK_CHARS_PER_TOKEN);\n progress.startCall(model, estimatedInputTokens);\n\n let finishReason: string | null | undefined;\n let usage: TokenUsage | undefined;\n let totalChars = 0;\n\n for await (const chunk of stream) {\n // Capture actual usage from stream\n if (chunk.usage) {\n usage = chunk.usage;\n if (chunk.usage.inputTokens) {\n progress.setInputTokens(chunk.usage.inputTokens, false);\n }\n if (chunk.usage.outputTokens) {\n progress.setOutputTokens(chunk.usage.outputTokens, false);\n }\n }\n if (chunk.text) {\n progress.pause(); // Must pause to avoid stderr/stdout interleaving\n totalChars += chunk.text.length;\n progress.update(totalChars); // Update token estimate from chars\n printer.write(chunk.text);\n }\n if (chunk.finishReason !== undefined) {\n finishReason = chunk.finishReason;\n }\n }\n\n progress.endCall(usage); // Calculate cost before completing\n progress.complete();\n printer.ensureNewline();\n\n // Only show summary if stderr is a TTY (not redirected)\n if (stderrTTY) {\n const summary = renderSummary({ finishReason, usage, cost: progress.getTotalCost() });\n if (summary) {\n env.stderr.write(`${summary}\\n`);\n }\n }\n}\n\n/**\n * Registers the complete command with the CLI program.\n * Configures options for model, system prompt, temperature, and max tokens.\n *\n * @param program - Commander program to register the command with\n * @param env - CLI environment for dependencies and I/O\n */\nexport function registerCompleteCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.complete)\n .description(\"Stream a single completion from a specified model.\")\n .argument(\"[prompt]\", \"Prompt to send to the LLM. If omitted, stdin is used when available.\")\n .option(OPTION_FLAGS.model, OPTION_DESCRIPTIONS.model, DEFAULT_MODEL)\n .option(OPTION_FLAGS.systemPrompt, OPTION_DESCRIPTIONS.systemPrompt)\n .option(\n OPTION_FLAGS.temperature,\n OPTION_DESCRIPTIONS.temperature,\n createNumericParser({ label: \"Temperature\", min: 0, max: 2 }),\n )\n .option(\n OPTION_FLAGS.maxTokens,\n OPTION_DESCRIPTIONS.maxTokens,\n createNumericParser({ label: \"Max tokens\", integer: true, min: 1 }),\n )\n .action((prompt, options) =>\n executeAction(\n () => handleCompleteCommand(prompt, options as CompleteCommandOptions, env),\n env,\n ),\n );\n}\n","import { type Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { COMMANDS } from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport { executeAction } from \"./utils.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport { MODEL_ALIASES } from \"../core/model-shortcuts.js\";\n\ninterface ModelsCommandOptions {\n provider?: string;\n format?: \"table\" | \"json\";\n verbose?: boolean;\n}\n\nasync function handleModelsCommand(\n options: ModelsCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const client = env.createClient();\n\n // Get models, optionally filtered by provider\n const models = client.modelRegistry.listModels(options.provider);\n\n if (options.format === \"json\") {\n renderJSON(models, env.stdout);\n } else {\n renderTable(models, options.verbose || false, env.stdout);\n }\n}\n\nfunction renderTable(models: ModelSpec[], verbose: boolean, stream: NodeJS.WritableStream): void {\n // Group models by provider\n const grouped = new Map<string, ModelSpec[]>();\n for (const model of models) {\n const provider = model.provider;\n if (!grouped.has(provider)) {\n grouped.set(provider, []);\n }\n grouped.get(provider)!.push(model);\n }\n\n // Header\n stream.write(chalk.bold.cyan(\"\\nAvailable Models\\n\"));\n stream.write(chalk.cyan(\"=\".repeat(80)) + \"\\n\\n\");\n\n // Display each provider's models\n const providers = Array.from(grouped.keys()).sort();\n for (const provider of providers) {\n const providerModels = grouped.get(provider)!;\n const providerName = provider.charAt(0).toUpperCase() + provider.slice(1);\n\n stream.write(chalk.bold.yellow(`${providerName} Models\\n`));\n\n if (verbose) {\n renderVerboseTable(providerModels, stream);\n } else {\n renderCompactTable(providerModels, stream);\n }\n\n stream.write(\"\\n\");\n }\n\n // Display shortcuts\n stream.write(chalk.bold.magenta(\"Model Shortcuts\\n\"));\n stream.write(chalk.dim(\"─\".repeat(80)) + \"\\n\");\n\n const shortcuts = Object.entries(MODEL_ALIASES).sort((a, b) => a[0].localeCompare(b[0]));\n for (const [shortcut, fullName] of shortcuts) {\n stream.write(chalk.cyan(` ${shortcut.padEnd(15)}`) + chalk.dim(\" → \") + chalk.white(fullName) + \"\\n\");\n }\n stream.write(\"\\n\");\n}\n\nfunction renderCompactTable(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n // Column widths\n const idWidth = 25;\n const nameWidth = 22;\n const contextWidth = 13;\n const inputWidth = 10;\n const outputWidth = 10;\n\n // Header\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n stream.write(\n chalk.bold(\n \"Model ID\".padEnd(idWidth) +\n \" \" + \"Display Name\".padEnd(nameWidth) +\n \" \" + \"Context\".padEnd(contextWidth) +\n \" \" + \"Input\".padEnd(inputWidth) +\n \" \" + \"Output\".padEnd(outputWidth)\n ) + \"\\n\"\n );\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n\n // Rows\n for (const model of models) {\n const contextFormatted = formatTokens(model.contextWindow);\n const inputPrice = `$${model.pricing.input.toFixed(2)}`;\n const outputPrice = `$${model.pricing.output.toFixed(2)}`;\n\n stream.write(\n chalk.green(model.modelId.padEnd(idWidth)) +\n \" \" + chalk.white(model.displayName.padEnd(nameWidth)) +\n \" \" + chalk.yellow(contextFormatted.padEnd(contextWidth)) +\n \" \" + chalk.cyan(inputPrice.padEnd(inputWidth)) +\n \" \" + chalk.cyan(outputPrice.padEnd(outputWidth)) +\n \"\\n\"\n );\n }\n\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n stream.write(chalk.dim(` * Prices are per 1M tokens\\n`));\n}\n\nfunction renderVerboseTable(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n for (const model of models) {\n stream.write(chalk.bold.green(`\\n ${model.modelId}\\n`));\n stream.write(chalk.dim(\" \" + \"─\".repeat(60)) + \"\\n\");\n stream.write(` ${chalk.dim(\"Name:\")} ${chalk.white(model.displayName)}\\n`);\n stream.write(` ${chalk.dim(\"Context:\")} ${chalk.yellow(formatTokens(model.contextWindow))}\\n`);\n stream.write(` ${chalk.dim(\"Max Output:\")} ${chalk.yellow(formatTokens(model.maxOutputTokens))}\\n`);\n stream.write(` ${chalk.dim(\"Pricing:\")} ${chalk.cyan(`$${model.pricing.input.toFixed(2)} input`)} ${chalk.dim(\"/\")} ${chalk.cyan(`$${model.pricing.output.toFixed(2)} output`)} ${chalk.dim(\"(per 1M tokens)\")}\\n`);\n\n if (model.pricing.cachedInput !== undefined) {\n stream.write(` ${chalk.dim(\"Cached Input:\")} ${chalk.cyan(`$${model.pricing.cachedInput.toFixed(2)} per 1M tokens`)}\\n`);\n }\n\n if (model.knowledgeCutoff) {\n stream.write(` ${chalk.dim(\"Knowledge:\")} ${model.knowledgeCutoff}\\n`);\n }\n\n // Features\n const features: string[] = [];\n if (model.features.streaming) features.push(\"streaming\");\n if (model.features.functionCalling) features.push(\"function-calling\");\n if (model.features.vision) features.push(\"vision\");\n if (model.features.reasoning) features.push(\"reasoning\");\n if (model.features.structuredOutputs) features.push(\"structured-outputs\");\n if (model.features.fineTuning) features.push(\"fine-tuning\");\n\n if (features.length > 0) {\n stream.write(` ${chalk.dim(\"Features:\")} ${chalk.blue(features.join(\", \"))}\\n`);\n }\n\n // Metadata\n if (model.metadata) {\n if (model.metadata.family) {\n stream.write(` ${chalk.dim(\"Family:\")} ${model.metadata.family}\\n`);\n }\n if (model.metadata.releaseDate) {\n stream.write(` ${chalk.dim(\"Released:\")} ${model.metadata.releaseDate}\\n`);\n }\n if (model.metadata.notes) {\n stream.write(` ${chalk.dim(\"Notes:\")} ${chalk.italic(model.metadata.notes)}\\n`);\n }\n }\n }\n stream.write(\"\\n\");\n}\n\nfunction renderJSON(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n const output = {\n models: models.map(model => ({\n provider: model.provider,\n modelId: model.modelId,\n displayName: model.displayName,\n contextWindow: model.contextWindow,\n maxOutputTokens: model.maxOutputTokens,\n pricing: {\n input: model.pricing.input,\n output: model.pricing.output,\n cachedInput: model.pricing.cachedInput,\n currency: \"USD\",\n per: \"1M tokens\",\n },\n knowledgeCutoff: model.knowledgeCutoff,\n features: model.features,\n metadata: model.metadata,\n })),\n shortcuts: MODEL_ALIASES,\n };\n\n stream.write(JSON.stringify(output, null, 2) + \"\\n\");\n}\n\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) {\n return `${(count / 1_000_000).toFixed(1)}M tokens`;\n } else if (count >= 1_000) {\n return `${(count / 1_000).toFixed(0)}K tokens`;\n } else {\n return `${count} tokens`;\n }\n}\n\nexport function registerModelsCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.models)\n .description(\"List all available LLM models with pricing and capabilities.\")\n .option(\"--provider <name>\", \"Filter by provider (openai, anthropic, gemini)\")\n .option(\"--format <format>\", \"Output format: table or json\", \"table\")\n .option(\"--verbose\", \"Show detailed model information\", false)\n .action((options) =>\n executeAction(\n () => handleModelsCommand(options as ModelsCommandOptions, env),\n env,\n ),\n );\n}\n","import readline from \"node:readline\";\nimport chalk from \"chalk\";\nimport type { ILogObj, Logger } from \"tslog\";\nimport { LLMist } from \"../core/client.js\";\nimport type { LoggerOptions } from \"../logging/logger.js\";\nimport { createLogger } from \"../logging/logger.js\";\n\n/**\n * Stream type that may have TTY capabilities.\n */\nexport type TTYStream = NodeJS.ReadableStream & { isTTY?: boolean };\n\n/**\n * Logger configuration for CLI commands.\n */\nexport interface CLILoggerConfig {\n logLevel?: string;\n logFile?: string;\n}\n\n/**\n * Environment abstraction for CLI dependencies and I/O.\n * Allows dependency injection for testing.\n */\nexport interface CLIEnvironment {\n argv: string[];\n stdin: TTYStream;\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n createClient: () => LLMist;\n setExitCode: (code: number) => void;\n loggerConfig?: CLILoggerConfig;\n createLogger: (name: string) => Logger<ILogObj>;\n /** Whether stdin is a TTY (interactive terminal) */\n isTTY: boolean;\n /** Prompt the user for input (only works when isTTY is true) */\n prompt: (question: string) => Promise<string>;\n}\n\nconst LOG_LEVEL_MAP: Record<string, number> = {\n silly: 0,\n trace: 1,\n debug: 2,\n info: 3,\n warn: 4,\n error: 5,\n fatal: 6,\n};\n\n/**\n * Creates a logger factory based on CLI configuration.\n * Priority: CLI options > environment variables > defaults\n */\nfunction createLoggerFactory(config?: CLILoggerConfig): (name: string) => Logger<ILogObj> {\n return (name: string) => {\n const options: LoggerOptions = { name };\n\n // CLI --log-level takes priority over LLMIST_LOG_LEVEL env var\n if (config?.logLevel) {\n const level = config.logLevel.toLowerCase();\n if (level in LOG_LEVEL_MAP) {\n options.minLevel = LOG_LEVEL_MAP[level];\n }\n }\n\n // CLI --log-file takes priority over LLMIST_LOG_FILE env var\n // When log file is set via CLI, we temporarily set the env var\n // so createLogger picks it up\n if (config?.logFile) {\n const originalLogFile = process.env.LLMIST_LOG_FILE;\n process.env.LLMIST_LOG_FILE = config.logFile;\n const logger = createLogger(options);\n // Restore original (or delete if it wasn't set)\n if (originalLogFile === undefined) {\n delete process.env.LLMIST_LOG_FILE;\n } else {\n process.env.LLMIST_LOG_FILE = originalLogFile;\n }\n return logger;\n }\n\n // If no log file, default to pretty output (not hidden)\n if (!process.env.LLMIST_LOG_FILE) {\n options.type = \"pretty\";\n }\n\n return createLogger(options);\n };\n}\n\n/**\n * Creates a readline-based prompt function for user input.\n */\nfunction createPromptFunction(\n stdin: NodeJS.ReadableStream,\n stdout: NodeJS.WritableStream,\n): (question: string) => Promise<string> {\n return (question: string) => {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: stdin,\n output: stdout,\n });\n // Display question with visual styling\n stdout.write(\"\\n\");\n stdout.write(`${chalk.cyan(\"─\".repeat(60))}\\n`);\n stdout.write(chalk.cyan.bold(\"🤖 Agent asks:\\n\"));\n stdout.write(`${question}\\n`);\n stdout.write(`${chalk.cyan(\"─\".repeat(60))}\\n`);\n rl.question(chalk.green.bold(\"You: \"), (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n };\n}\n\n/**\n * Creates the default CLI environment using Node.js process globals.\n * Uses process.argv, process.stdin/stdout/stderr, and creates a new LLMist client.\n *\n * @param loggerConfig - Optional logger configuration from CLI options\n * @returns Default CLI environment\n */\nexport function createDefaultEnvironment(loggerConfig?: CLILoggerConfig): CLIEnvironment {\n const isTTY = Boolean(process.stdin.isTTY);\n\n return {\n argv: process.argv,\n stdin: process.stdin,\n stdout: process.stdout,\n stderr: process.stderr,\n createClient: () => new LLMist(),\n setExitCode: (code: number) => {\n process.exitCode = code;\n },\n loggerConfig,\n createLogger: createLoggerFactory(loggerConfig),\n isTTY,\n prompt: isTTY\n ? createPromptFunction(process.stdin, process.stdout)\n : async () => {\n throw new Error(\"Cannot prompt for input: stdin is not a TTY\");\n },\n };\n}\n","#!/usr/bin/env node\nimport { SUMMARY_PREFIX } from \"./cli/constants.js\";\nimport { runCLI } from \"./cli/program.js\";\n\nrunCLI().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`${SUMMARY_PREFIX} Error: ${message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["InvalidArgumentError","chalk","InvalidArgumentError","InvalidArgumentError","chalk","gadgets","chalk","chalk","chalk","InvalidArgumentError"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/constants.ts","../src/cli/program.ts","../package.json","../src/cli/agent-command.ts","../src/cli/builtin-gadgets.ts","../src/cli/gadgets.ts","../src/cli/utils.ts","../src/cli/complete-command.ts","../src/cli/models-command.ts","../src/cli/environment.ts","../src/cli.ts"],"sourcesContent":["import type { ParameterFormat } from \"../gadgets/parser.js\";\n\n/** CLI program name */\nexport const CLI_NAME = \"llmist\";\n\n/** CLI program description shown in --help */\nexport const CLI_DESCRIPTION = \"Command line utilities for llmist agents and direct LLM access.\";\n\n/** Available CLI commands */\nexport const COMMANDS = {\n complete: \"complete\",\n agent: \"agent\",\n models: \"models\",\n} as const;\n\n/** Valid log level names */\nexport const LOG_LEVELS = [\"silly\", \"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"] as const;\nexport type LogLevelName = (typeof LOG_LEVELS)[number];\n\n/** Default model used when --model is not specified */\nexport const DEFAULT_MODEL = \"openai:gpt-5-nano\";\n\n/** Default parameter format for gadgets */\nexport const DEFAULT_PARAMETER_FORMAT: ParameterFormat = \"json\";\n\n/** Command-line option flags */\nexport const OPTION_FLAGS = {\n model: \"-m, --model <identifier>\",\n systemPrompt: \"-s, --system <prompt>\",\n temperature: \"-t, --temperature <value>\",\n maxTokens: \"--max-tokens <count>\",\n maxIterations: \"-i, --max-iterations <count>\",\n gadgetModule: \"-g, --gadget <module>\",\n parameterFormat: \"--parameter-format <format>\",\n logLevel: \"--log-level <level>\",\n logFile: \"--log-file <path>\",\n noBuiltins: \"--no-builtins\",\n} as const;\n\n/** Human-readable descriptions for command-line options */\nexport const OPTION_DESCRIPTIONS = {\n model: \"Model identifier, e.g. openai:gpt-5-nano or anthropic:claude-sonnet-4-5.\",\n systemPrompt: \"Optional system prompt prepended to the conversation.\",\n temperature: \"Sampling temperature between 0 and 2.\",\n maxTokens: \"Maximum number of output tokens requested from the model.\",\n maxIterations: \"Maximum number of agent loop iterations before exiting.\",\n gadgetModule:\n \"Path or module specifier for a gadget export. Repeat to register multiple gadgets.\",\n parameterFormat: \"Format for gadget parameter schemas: 'json', 'yaml', or 'auto'.\",\n logLevel: \"Log level: silly, trace, debug, info, warn, error, fatal.\",\n logFile: \"Path to log file. When set, logs are written to file instead of stderr.\",\n noBuiltins: \"Disable built-in gadgets (AskUser, TellUser).\",\n} as const;\n\n/** Prefix for summary output written to stderr */\nexport const SUMMARY_PREFIX = \"[llmist]\";\n","import { Command, InvalidArgumentError } from \"commander\";\n\nimport packageJson from \"../../package.json\";\n\nimport { registerAgentCommand } from \"./agent-command.js\";\nimport { registerCompleteCommand } from \"./complete-command.js\";\nimport { registerModelsCommand } from \"./models-command.js\";\nimport {\n CLI_DESCRIPTION,\n CLI_NAME,\n LOG_LEVELS,\n type LogLevelName,\n OPTION_DESCRIPTIONS,\n OPTION_FLAGS,\n} from \"./constants.js\";\nimport type { CLIEnvironment, CLILoggerConfig } from \"./environment.js\";\nimport { createDefaultEnvironment } from \"./environment.js\";\n\n/**\n * Parses and validates the log level option value.\n */\nfunction parseLogLevel(value: string): LogLevelName {\n const normalized = value.toLowerCase() as LogLevelName;\n if (!LOG_LEVELS.includes(normalized)) {\n throw new InvalidArgumentError(`Log level must be one of: ${LOG_LEVELS.join(\", \")}`);\n }\n return normalized;\n}\n\n/**\n * Global CLI options that apply to all commands.\n */\ninterface GlobalOptions {\n logLevel?: LogLevelName;\n logFile?: string;\n}\n\n/**\n * Creates and configures the CLI program with complete and agent commands.\n *\n * @param env - CLI environment configuration for I/O and dependencies\n * @returns Configured Commander program ready for parsing\n */\nexport function createProgram(env: CLIEnvironment): Command {\n const program = new Command();\n\n program\n .name(CLI_NAME)\n .description(CLI_DESCRIPTION)\n .version(packageJson.version)\n .option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel)\n .option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile)\n .configureOutput({\n writeOut: (str) => env.stdout.write(str),\n writeErr: (str) => env.stderr.write(str),\n });\n\n registerCompleteCommand(program, env);\n registerAgentCommand(program, env);\n registerModelsCommand(program, env);\n\n return program;\n}\n\n/**\n * Main entry point for running the CLI.\n * Creates environment, parses arguments, and executes the appropriate command.\n *\n * @param overrides - Optional environment overrides for testing or customization\n */\nexport async function runCLI(overrides: Partial<CLIEnvironment> = {}): Promise<void> {\n // First pass: parse global options only (skip if help requested)\n const preParser = new Command();\n preParser\n .option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel)\n .option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile)\n .allowUnknownOption()\n .allowExcessArguments()\n .helpOption(false); // Don't intercept --help\n\n preParser.parse(process.argv);\n const globalOpts = preParser.opts<GlobalOptions>();\n\n // Create environment with logger config from global options\n const loggerConfig: CLILoggerConfig = {\n logLevel: globalOpts.logLevel,\n logFile: globalOpts.logFile,\n };\n\n const defaultEnv = createDefaultEnvironment(loggerConfig);\n const env: CLIEnvironment = { ...defaultEnv, ...overrides };\n const program = createProgram(env);\n await program.parseAsync(env.argv);\n}\n","{\n \"name\": \"llmist\",\n \"version\": \"0.2.2\",\n \"description\": \"Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.\",\n \"type\": \"module\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./testing\": {\n \"import\": {\n \"types\": \"./dist/testing/index.d.ts\",\n \"default\": \"./dist/testing/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/testing/index.d.cts\",\n \"default\": \"./dist/testing/index.cjs\"\n }\n }\n },\n \"scripts\": {\n \"cli\": \"bun run scripts/cli-runner.ts\",\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome lint .\",\n \"format\": \"biome format --write .\",\n \"check\": \"biome check --write .\",\n \"test\": \"bun test\",\n \"test:unit\": \"bun test src/agent src/core src/gadgets src/providers src/testing\",\n \"test:watch\": \"bun test --watch\",\n \"test:e2e\": \"bun test src/e2e --timeout 60000 --bail 1\",\n \"test:e2e:watch\": \"bun test src/e2e --watch --timeout 60000\",\n \"test:all\": \"bun run test && bun run test:e2e\",\n \"clean\": \"rimraf dist\",\n \"prepare\": \"node scripts/install-hooks.js || true\",\n \"release:dry\": \"bunx semantic-release --dry-run\"\n },\n \"bin\": {\n \"llmist\": \"dist/cli.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/zbigniewsobiecki/llmist.git\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"llm\",\n \"ai\",\n \"agent\",\n \"agents\",\n \"openai\",\n \"anthropic\",\n \"claude\",\n \"gemini\",\n \"gpt\",\n \"streaming\",\n \"function-calling\",\n \"tool-calling\",\n \"typescript\",\n \"universal-client\",\n \"multi-provider\",\n \"hooks\",\n \"gadgets\"\n ],\n \"author\": \"\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@anthropic-ai/sdk\": \"^0.69.0\",\n \"@google/genai\": \"^1.27.0\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^12.1.0\",\n \"js-yaml\": \"^4.1.0\",\n \"openai\": \"^6.0.0\",\n \"tiktoken\": \"^1.0.22\",\n \"tslog\": \"^4.10.2\",\n \"zod\": \"^4.1.12\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.3.2\",\n \"@commitlint/cli\": \"^20.1.0\",\n \"@commitlint/config-conventional\": \"^20.0.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^20.12.7\",\n \"bun-types\": \"^1.3.2\",\n \"dotenv\": \"^17.2.3\",\n \"rimraf\": \"^5.0.5\",\n \"semantic-release\": \"^25.0.2\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.4.5\"\n }\n}\n","import { createInterface } from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { type Command, InvalidArgumentError } from \"commander\";\nimport { AgentBuilder } from \"../agent/builder.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport type { ParameterFormat } from \"../gadgets/parser.js\";\nimport { GadgetRegistry } from \"../gadgets/registry.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport { builtinGadgets } from \"./builtin-gadgets.js\";\nimport {\n COMMANDS,\n DEFAULT_MODEL,\n DEFAULT_PARAMETER_FORMAT,\n OPTION_DESCRIPTIONS,\n OPTION_FLAGS,\n} from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport { loadGadgets } from \"./gadgets.js\";\nimport {\n createNumericParser,\n executeAction,\n isInteractive,\n renderSummary,\n resolvePrompt,\n StreamPrinter,\n StreamProgress,\n} from \"./utils.js\";\n\n/**\n * Configuration options for the agent command.\n */\ninterface AgentCommandOptions {\n model: string;\n system?: string;\n temperature?: number;\n maxIterations?: number;\n gadget?: string[];\n parameterFormat: ParameterFormat;\n builtins: boolean; // --no-builtins sets this to false\n}\n\nconst PARAMETER_FORMAT_VALUES: ParameterFormat[] = [\"json\", \"yaml\", \"auto\"];\n\n/**\n * Parses and validates the parameter format option value.\n *\n * @param value - User-provided parameter format string\n * @returns Validated parameter format\n * @throws InvalidArgumentError if format is not one of: json, yaml, auto\n */\nfunction parseParameterFormat(value: string): ParameterFormat {\n const normalized = value.toLowerCase() as ParameterFormat;\n if (!PARAMETER_FORMAT_VALUES.includes(normalized)) {\n throw new InvalidArgumentError(\"Parameter format must be one of 'json', 'yaml', or 'auto'.\");\n }\n return normalized;\n}\n\n/**\n * Creates a human input handler for interactive mode.\n * Only returns a handler if stdin is a TTY (terminal), not a pipe.\n *\n * @param env - CLI environment\n * @param progress - Progress indicator to pause during input\n * @returns Human input handler function or undefined if not interactive\n */\nfunction createHumanInputHandler(\n env: CLIEnvironment,\n progress: StreamProgress,\n): ((question: string) => Promise<string>) | undefined {\n const stdout = env.stdout as NodeJS.WriteStream;\n if (!isInteractive(env.stdin) || typeof stdout.isTTY !== \"boolean\" || !stdout.isTTY) {\n return undefined;\n }\n\n return async (question: string): Promise<string> => {\n progress.pause(); // Pause progress indicator during human input\n const rl = createInterface({ input: env.stdin, output: env.stdout });\n try {\n // Display question on first prompt only\n const questionLine = question.trim() ? `\\n${question.trim()}` : \"\";\n let isFirst = true;\n\n // Loop until non-empty input (like a REPL)\n while (true) {\n const statsPrompt = progress.formatPrompt();\n const prompt = isFirst ? `${questionLine}\\n${statsPrompt}` : statsPrompt;\n isFirst = false;\n\n const answer = await rl.question(prompt);\n const trimmed = answer.trim();\n if (trimmed) {\n return trimmed;\n }\n // Empty input - show prompt again (no question repeat)\n }\n } finally {\n rl.close();\n }\n };\n}\n\n/**\n * Formats a gadget execution result for stderr output with colors.\n *\n * @param result - Gadget execution result with timing and output info\n * @returns Formatted summary string with ANSI colors\n */\nfunction formatGadgetSummary(result: {\n gadgetName: string;\n executionTimeMs: number;\n error?: string;\n result?: string;\n breaksLoop?: boolean;\n}): string {\n const gadgetLabel = chalk.magenta.bold(result.gadgetName);\n const timeLabel = chalk.dim(`${Math.round(result.executionTimeMs)}ms`);\n\n if (result.error) {\n return `${chalk.red(\"✗\")} ${gadgetLabel} ${chalk.red(\"error:\")} ${result.error} ${timeLabel}`;\n }\n\n if (result.breaksLoop) {\n return `${chalk.yellow(\"⏹\")} ${gadgetLabel} ${chalk.yellow(\"finished:\")} ${result.result} ${timeLabel}`;\n }\n\n // For TellUser, show full text without truncation since it's meant for user messages\n // For other gadgets, truncate long results for cleaner output\n const maxLen = 80;\n const shouldTruncate = result.gadgetName !== \"TellUser\";\n const resultText = result.result\n ? shouldTruncate && result.result.length > maxLen\n ? `${result.result.slice(0, maxLen)}...`\n : result.result\n : \"\";\n\n return `${chalk.green(\"✓\")} ${gadgetLabel} ${chalk.dim(\"→\")} ${resultText} ${timeLabel}`;\n}\n\n/**\n * Handles the agent command execution.\n * Runs the full agent loop with gadgets and streams output.\n *\n * @param promptArg - User prompt from command line argument (optional if using stdin)\n * @param options - Agent command options (model, gadgets, max iterations, etc.)\n * @param env - CLI environment for I/O operations\n */\nasync function handleAgentCommand(\n promptArg: string | undefined,\n options: AgentCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const prompt = await resolvePrompt(promptArg, env);\n const client = env.createClient();\n\n const registry = new GadgetRegistry();\n\n // Register built-in gadgets by default (AskUser, TellUser)\n // --no-builtins sets options.builtins to false\n if (options.builtins !== false) {\n for (const gadget of builtinGadgets) {\n registry.registerByClass(gadget);\n }\n }\n\n // Load and register user-provided gadgets (can override built-ins)\n const gadgetSpecifiers = options.gadget ?? [];\n if (gadgetSpecifiers.length > 0) {\n const gadgets = await loadGadgets(gadgetSpecifiers, process.cwd());\n for (const gadget of gadgets) {\n registry.registerByClass(gadget);\n }\n }\n\n const printer = new StreamPrinter(env.stdout);\n const stderrTTY = (env.stderr as NodeJS.WriteStream).isTTY === true;\n const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);\n\n let finishReason: string | null | undefined;\n let usage: TokenUsage | undefined;\n let iterations = 0;\n\n // Estimate tokens from all messages\n const estimateMessagesTokens = (messages: Array<{ role: string; content: string }>) => {\n const totalChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);\n return Math.round(totalChars / FALLBACK_CHARS_PER_TOKEN);\n };\n\n const builder = new AgentBuilder(client)\n .withModel(options.model)\n .withLogger(env.createLogger(\"llmist:cli:agent\"))\n .withHooks({\n observers: {\n onLLMCallStart: async (context) => {\n // Start new call in streaming mode with model and estimated tokens from full messages\n const estimate = estimateMessagesTokens(context.options.messages);\n progress.startCall(context.options.model, estimate);\n },\n onStreamChunk: async (context) => {\n // Update output token estimate from accumulated text\n progress.update(context.accumulatedText.length);\n // Capture actual tokens when available from stream\n if (context.usage) {\n if (context.usage.inputTokens) {\n progress.setInputTokens(context.usage.inputTokens, false);\n }\n if (context.usage.outputTokens) {\n progress.setOutputTokens(context.usage.outputTokens, false);\n }\n }\n },\n onLLMCallComplete: async (context) => {\n finishReason = context.finishReason;\n usage = context.usage;\n iterations = Math.max(iterations, context.iteration + 1);\n // End call and switch to cumulative mode\n progress.endCall(context.usage);\n },\n },\n });\n\n // Add optional configurations\n if (options.system) {\n builder.withSystem(options.system);\n }\n if (options.maxIterations !== undefined) {\n builder.withMaxIterations(options.maxIterations);\n }\n if (options.temperature !== undefined) {\n builder.withTemperature(options.temperature);\n }\n\n const humanInputHandler = createHumanInputHandler(env, progress);\n if (humanInputHandler) {\n builder.onHumanInput(humanInputHandler);\n }\n\n // Add gadgets from the registry\n const gadgets = registry.getAll();\n if (gadgets.length > 0) {\n builder.withGadgets(...gadgets);\n }\n\n // Note: parameterFormat is not directly supported in AgentBuilder\n // This might need to be added to AgentBuilder API if needed\n\n const agent = builder.ask(prompt);\n\n for await (const event of agent.run()) {\n if (event.type === \"text\") {\n progress.pause(); // Must pause to avoid stderr/stdout interleaving\n printer.write(event.content);\n } else if (event.type === \"gadget_result\") {\n progress.pause(); // Clear progress before gadget output\n // Only show gadget summaries if stderr is a TTY (not redirected)\n if (stderrTTY) {\n env.stderr.write(`${formatGadgetSummary(event.result)}\\n`);\n }\n // Note: progress.start() is called by onLLMCallStart hook\n }\n // Note: human_input_required event is not emitted - handled by callback in createHumanInputHandler\n }\n\n progress.complete();\n printer.ensureNewline();\n\n // Only show summary if stderr is a TTY (not redirected)\n if (stderrTTY) {\n const summary = renderSummary({\n finishReason,\n usage,\n iterations,\n cost: progress.getTotalCost(),\n });\n if (summary) {\n env.stderr.write(`${summary}\\n`);\n }\n }\n}\n\n/**\n * Registers the agent command with the CLI program.\n * Configures options for model, gadgets, max iterations, temperature, and parameter format.\n *\n * @param program - Commander program to register the command with\n * @param env - CLI environment for dependencies and I/O\n */\nexport function registerAgentCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.agent)\n .description(\"Run the llmist agent loop with optional gadgets.\")\n .argument(\"[prompt]\", \"Prompt for the agent loop. Falls back to stdin when available.\")\n .option(OPTION_FLAGS.model, OPTION_DESCRIPTIONS.model, DEFAULT_MODEL)\n .option(OPTION_FLAGS.systemPrompt, OPTION_DESCRIPTIONS.systemPrompt)\n .option(\n OPTION_FLAGS.temperature,\n OPTION_DESCRIPTIONS.temperature,\n createNumericParser({ label: \"Temperature\", min: 0, max: 2 }),\n )\n .option(\n OPTION_FLAGS.maxIterations,\n OPTION_DESCRIPTIONS.maxIterations,\n createNumericParser({ label: \"Max iterations\", integer: true, min: 1 }),\n )\n .option(\n OPTION_FLAGS.gadgetModule,\n OPTION_DESCRIPTIONS.gadgetModule,\n (value: string, previous: string[] = []) => [...previous, value],\n [] as string[],\n )\n .option(\n OPTION_FLAGS.parameterFormat,\n OPTION_DESCRIPTIONS.parameterFormat,\n parseParameterFormat,\n DEFAULT_PARAMETER_FORMAT,\n )\n .option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins)\n .action((prompt, options) =>\n executeAction(() => handleAgentCommand(prompt, options as AgentCommandOptions, env), env),\n );\n}\n","/**\n * Built-in gadgets for CLI agent command.\n * These gadgets provide basic communication capabilities out-of-the-box.\n */\nimport chalk from \"chalk\";\nimport { z } from \"zod\";\n\nimport { createGadget } from \"../gadgets/create-gadget.js\";\nimport { BreakLoopException, HumanInputException } from \"../gadgets/exceptions.js\";\n\n/**\n * AskUser gadget - Asks the user a question and waits for their response.\n *\n * Use this when you need more information or clarification from the user.\n */\nexport const askUser = createGadget({\n name: \"AskUser\",\n description:\n \"Ask the user a question when you need more information or clarification. The user's response will be provided back to you.\",\n schema: z.object({\n question: z.string().describe(\"The question to ask the user\"),\n }),\n execute: ({ question }) => {\n throw new HumanInputException(question);\n },\n});\n\n/**\n * TellUser gadget - Outputs a message to the user and optionally ends the conversation.\n *\n * Use this for key results, warnings, or structured output that should stand out\n * from regular streamed text. Set done=true when the task is complete.\n */\nexport const tellUser = createGadget({\n name: \"TellUser\",\n description:\n \"Tell the user something important. Set done=true when your work is complete and you want to end the conversation.\",\n schema: z.object({\n message: z.string().describe(\"The message to display to the user\"),\n done: z.boolean().describe(\"Set to true to end the conversation, false to continue\"),\n type: z\n .enum([\"info\", \"success\", \"warning\", \"error\"])\n .default(\"info\")\n .describe(\"Message type: info, success, warning, or error\"),\n }),\n execute: ({ message, done, type }) => {\n // Format message for display, but return plain text for LLM context\n // This prevents ANSI color codes from polluting the conversation\n const prefixes = {\n info: \"ℹ️ \",\n success: \"✅ \",\n warning: \"⚠️ \",\n error: \"❌ \",\n };\n const plainResult = prefixes[type] + message;\n\n if (done) {\n throw new BreakLoopException(plainResult);\n }\n return plainResult;\n },\n});\n\n/**\n * All built-in gadgets as an array for easy registration.\n */\nexport const builtinGadgets = [askUser, tellUser];\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { BaseGadget } from \"../gadgets/gadget.js\";\n\n/**\n * Function type for importing modules dynamically.\n */\nexport type GadgetImportFunction = (specifier: string) => Promise<unknown>;\n\nconst PATH_PREFIXES = [\".\", \"/\", \"~\"];\n\n/**\n * Type guard to check if a value is a Gadget constructor.\n *\n * @param value - Value to check\n * @returns True if value is a Gadget constructor\n */\nfunction isGadgetConstructor(value: unknown): value is new () => BaseGadget {\n if (typeof value !== \"function\") {\n return false;\n }\n\n const prototype = value.prototype as unknown;\n return Boolean(prototype) && prototype instanceof BaseGadget;\n}\n\n/**\n * Expands ~ to the user's home directory.\n *\n * @param input - Path that may start with ~\n * @returns Expanded path with HOME directory\n */\nfunction expandHomePath(input: string): string {\n if (!input.startsWith(\"~\")) {\n return input;\n }\n\n const home = process.env.HOME;\n if (!home) {\n return input;\n }\n\n return path.join(home, input.slice(1));\n}\n\n/**\n * Determines if a specifier is a file path vs npm module name.\n * File paths start with ., /, ~ or contain path separators.\n *\n * @param specifier - Module specifier to check\n * @returns True if specifier represents a file path\n */\nfunction isFileLikeSpecifier(specifier: string): boolean {\n return (\n PATH_PREFIXES.some((prefix) => specifier.startsWith(prefix)) || specifier.includes(path.sep)\n );\n}\n\n/**\n * Resolves a gadget specifier to either a file URL or npm module name.\n * File paths are resolved relative to cwd and converted to file:// URLs.\n *\n * @param specifier - Original gadget specifier (file path or module name)\n * @param cwd - Current working directory for resolving relative paths\n * @returns Resolved specifier (file:// URL for files, module name for packages)\n * @throws Error if file path doesn't exist\n */\nexport function resolveGadgetSpecifier(specifier: string, cwd: string): string {\n if (!isFileLikeSpecifier(specifier)) {\n return specifier;\n }\n\n const expanded = expandHomePath(specifier);\n const resolvedPath = path.resolve(cwd, expanded);\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Gadget module not found at ${resolvedPath}`);\n }\n return pathToFileURL(resolvedPath).href;\n}\n\n/**\n * Recursively extracts all Gadget instances and classes from a module's exports.\n * Searches default export, named exports, nested objects, and arrays.\n * Automatically instantiates Gadget classes.\n *\n * @param moduleExports - Module exports object to search\n * @returns Array of Gadget instances found in exports\n */\nexport function extractGadgetsFromModule(moduleExports: unknown): BaseGadget[] {\n const results: BaseGadget[] = [];\n const visited = new Set<unknown>();\n\n const visit = (value: unknown) => {\n if (value === undefined || value === null) {\n return;\n }\n\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n\n if (value instanceof BaseGadget) {\n results.push(value);\n return;\n }\n\n if (isGadgetConstructor(value)) {\n results.push(new value());\n return;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n visit(entry);\n }\n return;\n }\n\n if (typeof value === \"object\") {\n for (const entry of Object.values(value as Record<string, unknown>)) {\n visit(entry);\n }\n }\n };\n\n visit(moduleExports);\n return results;\n}\n\n/**\n * Loads gadgets from one or more file paths or npm module names.\n * Resolves paths, imports modules, and extracts gadgets.\n *\n * @param specifiers - Array of gadget specifiers (file paths or module names)\n * @param cwd - Current working directory for resolving relative paths\n * @param importer - Function to dynamically import modules (default: native import)\n * @returns Array of loaded Gadget instances\n * @throws Error if module fails to load, contains no gadgets, or initialization fails\n */\nexport async function loadGadgets(\n specifiers: string[],\n cwd: string,\n importer: GadgetImportFunction = (specifier) => import(specifier),\n): Promise<BaseGadget[]> {\n const gadgets: BaseGadget[] = [];\n\n for (const specifier of specifiers) {\n const resolved = resolveGadgetSpecifier(specifier, cwd);\n let exports: unknown;\n try {\n exports = await importer(resolved);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load gadget module '${specifier}': ${message}`);\n }\n\n let extracted: BaseGadget[];\n try {\n extracted = extractGadgetsFromModule(exports);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to initialize gadgets from module '${specifier}': ${message}`);\n }\n if (extracted.length === 0) {\n throw new Error(`Module '${specifier}' does not export any Gadget instances.`);\n }\n gadgets.push(...extracted);\n }\n\n return gadgets;\n}\n","import chalk from \"chalk\";\nimport { InvalidArgumentError } from \"commander\";\n\nimport type { ModelRegistry } from \"../core/model-registry.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport type { CLIEnvironment, TTYStream } from \"./environment.js\";\n\n/**\n * Options for creating a numeric value parser.\n */\nexport interface NumericParserOptions {\n label: string;\n integer?: boolean;\n min?: number;\n max?: number;\n}\n\n/**\n * Creates a parser function for numeric command-line options with validation.\n * Validates that values are numbers, optionally integers, and within min/max bounds.\n *\n * @param options - Parser configuration (label, integer, min, max)\n * @returns Parser function that validates and returns the numeric value\n * @throws InvalidArgumentError if validation fails\n */\nexport function createNumericParser({\n label,\n integer = false,\n min,\n max,\n}: NumericParserOptions): (value: string) => number {\n return (value: string) => {\n const parsed = Number(value);\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`${label} must be a number.`);\n }\n\n if (integer && !Number.isInteger(parsed)) {\n throw new InvalidArgumentError(`${label} must be an integer.`);\n }\n\n if (min !== undefined && parsed < min) {\n throw new InvalidArgumentError(`${label} must be greater than or equal to ${min}.`);\n }\n\n if (max !== undefined && parsed > max) {\n throw new InvalidArgumentError(`${label} must be less than or equal to ${max}.`);\n }\n\n return parsed;\n };\n}\n\n/**\n * Helper class for writing text to a stream while tracking newline state.\n * Ensures output ends with a newline for proper terminal formatting.\n */\nexport class StreamPrinter {\n private endedWithNewline = true;\n\n constructor(private readonly target: NodeJS.WritableStream) {}\n\n /**\n * Writes text to the target stream and tracks newline state.\n *\n * @param text - Text to write\n */\n write(text: string): void {\n if (!text) {\n return;\n }\n this.target.write(text);\n this.endedWithNewline = text.endsWith(\"\\n\");\n }\n\n /**\n * Ensures output ends with a newline by writing one if needed.\n */\n ensureNewline(): void {\n if (!this.endedWithNewline) {\n this.target.write(\"\\n\");\n this.endedWithNewline = true;\n }\n }\n}\n\n/**\n * Checks if a stream is a TTY (terminal) for interactive input.\n *\n * @param stream - Stream to check\n * @returns True if stream is a TTY\n */\nexport function isInteractive(stream: TTYStream): boolean {\n return Boolean(stream.isTTY);\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_DELAY_MS = 500; // Don't show spinner for fast responses\n\ntype ProgressMode = \"streaming\" | \"cumulative\";\n\n/**\n * Progress indicator shown while waiting for LLM response.\n * Two modes:\n * - streaming: Shows current LLM call stats (out/in tokens, call time)\n * - cumulative: Shows total stats across all calls (total tokens, iterations, total time)\n * Only displays on TTY (interactive terminal), silent when piped.\n */\nexport class StreamProgress {\n // Animation state\n private frameIndex = 0;\n private interval: ReturnType<typeof setInterval> | null = null;\n private delayTimeout: ReturnType<typeof setTimeout> | null = null;\n private isRunning = false;\n private hasRendered = false;\n\n // Current call stats (streaming mode)\n private mode: ProgressMode = \"cumulative\";\n private model = \"\";\n private callStartTime = Date.now();\n private callInputTokens = 0;\n private callInputTokensEstimated = true;\n private callOutputTokens = 0;\n private callOutputTokensEstimated = true;\n private callOutputChars = 0;\n private isStreaming = false;\n\n // Cumulative stats (cumulative mode)\n private totalStartTime = Date.now();\n private totalTokens = 0;\n private totalCost = 0;\n private iterations = 0;\n\n constructor(\n private readonly target: NodeJS.WritableStream,\n private readonly isTTY: boolean,\n private readonly modelRegistry?: ModelRegistry,\n ) {}\n\n /**\n * Starts a new LLM call. Switches to streaming mode.\n * @param model - Model name being used\n * @param estimatedInputTokens - Estimated input tokens based on prompt length\n */\n startCall(model: string, estimatedInputTokens?: number): void {\n this.mode = \"streaming\";\n this.model = model;\n this.callStartTime = Date.now();\n this.callInputTokens = estimatedInputTokens ?? 0;\n this.callInputTokensEstimated = true;\n this.callOutputTokens = 0;\n this.callOutputTokensEstimated = true;\n this.callOutputChars = 0;\n this.isStreaming = false;\n this.start();\n }\n\n /**\n * Ends the current LLM call. Updates cumulative stats and switches to cumulative mode.\n * @param usage - Final token usage from the call\n */\n endCall(usage?: { inputTokens: number; outputTokens: number; totalTokens: number }): void {\n this.iterations++;\n if (usage) {\n this.totalTokens += usage.totalTokens;\n\n // Calculate and accumulate cost if model registry is available\n if (this.modelRegistry && this.model) {\n try {\n // Strip provider prefix if present (e.g., \"openai:gpt-5-nano\" -> \"gpt-5-nano\")\n const modelName = this.model.includes(\":\")\n ? this.model.split(\":\")[1]\n : this.model;\n\n const cost = this.modelRegistry.estimateCost(\n modelName,\n usage.inputTokens,\n usage.outputTokens,\n );\n if (cost) {\n this.totalCost += cost.totalCost;\n }\n } catch {\n // Ignore errors (e.g., unknown model) - just don't add to cost\n }\n }\n }\n this.pause();\n this.mode = \"cumulative\";\n }\n\n /**\n * Sets the input token count for current call (from stream metadata).\n * @param tokens - Token count\n * @param estimated - If true, shown with ~ prefix until actual count arrives\n */\n setInputTokens(tokens: number, estimated = false): void {\n // Don't overwrite actual count with a new estimate\n if (estimated && !this.callInputTokensEstimated) {\n return;\n }\n this.callInputTokens = tokens;\n this.callInputTokensEstimated = estimated;\n }\n\n /**\n * Sets the output token count for current call (from stream metadata).\n * @param tokens - Token count\n * @param estimated - If true, shown with ~ prefix until actual count arrives\n */\n setOutputTokens(tokens: number, estimated = false): void {\n // Don't overwrite actual count with a new estimate\n if (estimated && !this.callOutputTokensEstimated) {\n return;\n }\n this.callOutputTokens = tokens;\n this.callOutputTokensEstimated = estimated;\n }\n\n /**\n * Starts the progress indicator animation after a brief delay.\n */\n start(): void {\n if (!this.isTTY || this.isRunning) return;\n this.isRunning = true;\n\n // Delay showing spinner to avoid flicker for fast responses\n this.delayTimeout = setTimeout(() => {\n if (this.isRunning) {\n this.interval = setInterval(() => this.render(), 80);\n this.render();\n }\n }, SPINNER_DELAY_MS);\n }\n\n /**\n * Updates output character count for current call and marks streaming as active.\n * @param totalChars - Total accumulated character count\n */\n update(totalChars: number): void {\n this.callOutputChars = totalChars;\n this.isStreaming = true;\n }\n\n private render(): void {\n const spinner = SPINNER_FRAMES[this.frameIndex++ % SPINNER_FRAMES.length];\n\n if (this.mode === \"streaming\") {\n this.renderStreamingMode(spinner);\n } else {\n this.renderCumulativeMode(spinner);\n }\n this.hasRendered = true;\n }\n\n private renderStreamingMode(spinner: string): void {\n const elapsed = ((Date.now() - this.callStartTime) / 1000).toFixed(1);\n\n // Output tokens: use actual if available, otherwise estimate from chars\n const outTokens = this.callOutputTokensEstimated\n ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN)\n : this.callOutputTokens;\n\n // Build status parts: model, out (sent), in (received), cost, time\n const parts: string[] = [];\n if (this.model) {\n parts.push(chalk.cyan(this.model));\n }\n if (this.callInputTokens > 0) {\n const prefix = this.callInputTokensEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"out:\") + chalk.yellow(` ${prefix}${this.callInputTokens}`));\n }\n if (this.isStreaming || outTokens > 0) {\n const prefix = this.callOutputTokensEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"in:\") + chalk.green(` ${prefix}${outTokens}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.dim(\"cost:\") + chalk.cyan(` $${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n\n this.target.write(`\\r${chalk.cyan(spinner)} ${parts.join(chalk.dim(\" | \"))}`);\n }\n\n private renderCumulativeMode(spinner: string): void {\n const elapsed = ((Date.now() - this.totalStartTime) / 1000).toFixed(1);\n\n // Build status parts: model, total tokens, iterations, cost, total time\n const parts: string[] = [];\n if (this.model) {\n parts.push(chalk.cyan(this.model));\n }\n if (this.totalTokens > 0) {\n parts.push(chalk.dim(\"total:\") + chalk.magenta(` ${this.totalTokens}`));\n }\n if (this.iterations > 0) {\n parts.push(chalk.dim(\"iter:\") + chalk.blue(` ${this.iterations}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.dim(\"cost:\") + chalk.cyan(` $${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n\n this.target.write(`\\r${chalk.cyan(spinner)} ${parts.join(chalk.dim(\" | \"))}`);\n }\n\n /**\n * Pauses the progress indicator and clears the line.\n * Can be resumed with start().\n */\n pause(): void {\n if (!this.isTTY || !this.isRunning) return;\n\n if (this.delayTimeout) {\n clearTimeout(this.delayTimeout);\n this.delayTimeout = null;\n }\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n this.isRunning = false;\n\n // Only clear the line if we actually rendered something\n if (this.hasRendered) {\n this.target.write(\"\\r\\x1b[K\");\n this.hasRendered = false;\n }\n }\n\n /**\n * Completes the progress indicator and clears the line.\n */\n complete(): void {\n this.pause();\n }\n\n /**\n * Returns the total accumulated cost across all calls.\n */\n getTotalCost(): number {\n return this.totalCost;\n }\n\n /**\n * Returns a formatted prompt string with stats (like bash PS1).\n * Shows current call stats during streaming, cumulative stats otherwise.\n * Format: \"out: 1.2k │ in: ~300 │ 5s > \" or \"3.6k │ i2 │ 34s > \"\n */\n formatPrompt(): string {\n const parts: string[] = [];\n\n if (this.mode === \"streaming\") {\n // During a call: show current call stats\n const elapsed = Math.round((Date.now() - this.callStartTime) / 1000);\n\n // Output tokens: use actual if available, otherwise estimate from chars\n const outTokens = this.callOutputTokensEstimated\n ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN)\n : this.callOutputTokens;\n const outEstimated = this.callOutputTokensEstimated;\n\n if (this.callInputTokens > 0) {\n const prefix = this.callInputTokensEstimated ? \"~\" : \"\";\n parts.push(\n chalk.dim(\"out:\") + chalk.yellow(` ${prefix}${this.formatTokens(this.callInputTokens)}`),\n );\n }\n if (outTokens > 0) {\n const prefix = outEstimated ? \"~\" : \"\";\n parts.push(chalk.dim(\"in:\") + chalk.green(` ${prefix}${this.formatTokens(outTokens)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n } else {\n // Between calls: show cumulative stats\n const elapsed = Math.round((Date.now() - this.totalStartTime) / 1000);\n\n if (this.totalTokens > 0) {\n parts.push(chalk.magenta(this.formatTokens(this.totalTokens)));\n }\n if (this.iterations > 0) {\n parts.push(chalk.blue(`i${this.iterations}`));\n }\n if (this.totalCost > 0) {\n parts.push(chalk.cyan(`$${this.formatCost(this.totalCost)}`));\n }\n parts.push(chalk.dim(`${elapsed}s`));\n }\n\n return `${parts.join(chalk.dim(\" │ \"))} ${chalk.green(\">\")} `;\n }\n\n /**\n * Formats token count compactly (3625 -> \"3.6k\").\n */\n private formatTokens(tokens: number): string {\n return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : `${tokens}`;\n }\n\n /**\n * Formats cost compactly (0.0001234 -> \"0.00012\", 0.1234 -> \"0.12\", 1.234 -> \"1.23\").\n */\n private formatCost(cost: number): string {\n if (cost < 0.001) {\n return cost.toFixed(5);\n }\n if (cost < 0.01) {\n return cost.toFixed(4);\n }\n if (cost < 1) {\n return cost.toFixed(3);\n }\n return cost.toFixed(2);\n }\n}\n\n/**\n * Reads all data from a readable stream into a string.\n *\n * @param stream - Stream to read from\n * @returns Complete stream contents as string\n */\nasync function readStream(stream: NodeJS.ReadableStream): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of stream) {\n if (typeof chunk === \"string\") {\n chunks.push(chunk);\n } else {\n chunks.push(chunk.toString(\"utf8\"));\n }\n }\n return chunks.join(\"\");\n}\n\n/**\n * Normalizes a prompt by trimming whitespace.\n *\n * @param value - Prompt to normalize\n * @returns Trimmed prompt\n */\nfunction normalizePrompt(value: string): string {\n return value.trim();\n}\n\n/**\n * Resolves the user prompt from either command-line argument or stdin.\n * Priority: 1) promptArg if provided, 2) stdin if piped, 3) error if neither.\n *\n * @param promptArg - Optional prompt from command-line argument\n * @param env - CLI environment for accessing stdin\n * @returns Resolved and normalized prompt\n * @throws Error if no prompt available or stdin is empty\n */\nexport async function resolvePrompt(\n promptArg: string | undefined,\n env: CLIEnvironment,\n): Promise<string> {\n if (promptArg?.trim()) {\n return normalizePrompt(promptArg);\n }\n\n if (isInteractive(env.stdin)) {\n throw new Error(\"Prompt is required. Provide an argument or pipe content via stdin.\");\n }\n\n const pipedInput = normalizePrompt(await readStream(env.stdin));\n if (!pipedInput) {\n throw new Error(\"Received empty stdin payload. Provide a prompt to continue.\");\n }\n\n return pipedInput;\n}\n\n/**\n * Metadata for generating execution summaries.\n */\nexport interface SummaryMetadata {\n finishReason?: string | null;\n usage?: TokenUsage;\n iterations?: number;\n cost?: number;\n}\n\n/**\n * Renders execution metadata as a formatted summary string with colors.\n * Includes iterations, finish reason, and token usage.\n *\n * @param metadata - Summary metadata to format\n * @returns Formatted summary string or null if no metadata\n */\nexport function renderSummary(metadata: SummaryMetadata): string | null {\n const parts: string[] = [];\n\n if (metadata.iterations !== undefined) {\n parts.push(chalk.dim(`iterations: ${metadata.iterations}`));\n }\n\n if (metadata.finishReason) {\n parts.push(chalk.dim(`finish: ${metadata.finishReason}`));\n }\n\n if (metadata.usage) {\n const { inputTokens, outputTokens, totalTokens } = metadata.usage;\n parts.push(\n chalk.dim(`tokens: `) +\n chalk.cyan(`${totalTokens}`) +\n chalk.dim(` (in: ${inputTokens}, out: ${outputTokens})`),\n );\n }\n\n if (metadata.cost !== undefined && metadata.cost > 0) {\n // Format cost with appropriate precision\n let formattedCost: string;\n if (metadata.cost < 0.001) {\n formattedCost = metadata.cost.toFixed(5);\n } else if (metadata.cost < 0.01) {\n formattedCost = metadata.cost.toFixed(4);\n } else if (metadata.cost < 1) {\n formattedCost = metadata.cost.toFixed(3);\n } else {\n formattedCost = metadata.cost.toFixed(2);\n }\n parts.push(chalk.dim(`cost: `) + chalk.cyan(`$${formattedCost}`));\n }\n\n if (parts.length === 0) {\n return null;\n }\n\n return parts.join(chalk.dim(\" │ \"));\n}\n\n/**\n * Executes a CLI action with error handling.\n * Catches errors, writes to stderr, and sets exit code 1 on failure.\n *\n * @param action - Async action to execute\n * @param env - CLI environment for error output and exit code\n */\nexport async function executeAction(\n action: () => Promise<void>,\n env: CLIEnvironment,\n): Promise<void> {\n try {\n await action();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n env.stderr.write(`${chalk.red.bold(\"Error:\")} ${message}\\n`);\n env.setExitCode(1);\n }\n}\n","import type { Command } from \"commander\";\n\nimport { LLMMessageBuilder } from \"../core/messages.js\";\nimport { resolveModel } from \"../core/model-shortcuts.js\";\nimport type { TokenUsage } from \"../core/options.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"../providers/constants.js\";\nimport { COMMANDS, DEFAULT_MODEL, OPTION_DESCRIPTIONS, OPTION_FLAGS } from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport {\n createNumericParser,\n executeAction,\n renderSummary,\n resolvePrompt,\n StreamPrinter,\n StreamProgress,\n} from \"./utils.js\";\n\n/**\n * Configuration options for the complete command.\n */\ninterface CompleteCommandOptions {\n model: string;\n system?: string;\n temperature?: number;\n maxTokens?: number;\n}\n\n/**\n * Handles the complete command execution.\n * Streams a single LLM response without agent loop or gadgets.\n *\n * @param promptArg - User prompt from command line argument (optional if using stdin)\n * @param options - Complete command options (model, system prompt, temperature, etc.)\n * @param env - CLI environment for I/O operations\n */\nasync function handleCompleteCommand(\n promptArg: string | undefined,\n options: CompleteCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const prompt = await resolvePrompt(promptArg, env);\n const client = env.createClient();\n const model = resolveModel(options.model);\n\n const builder = new LLMMessageBuilder();\n if (options.system) {\n builder.addSystem(options.system);\n }\n builder.addUser(prompt);\n\n const stream = client.stream({\n model,\n messages: builder.build(),\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n });\n\n const printer = new StreamPrinter(env.stdout);\n const stderrTTY = (env.stderr as NodeJS.WriteStream).isTTY === true;\n const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);\n\n // Start call with model and estimate based on prompt length\n const estimatedInputTokens = Math.round(prompt.length / FALLBACK_CHARS_PER_TOKEN);\n progress.startCall(model, estimatedInputTokens);\n\n let finishReason: string | null | undefined;\n let usage: TokenUsage | undefined;\n let totalChars = 0;\n\n for await (const chunk of stream) {\n // Capture actual usage from stream\n if (chunk.usage) {\n usage = chunk.usage;\n if (chunk.usage.inputTokens) {\n progress.setInputTokens(chunk.usage.inputTokens, false);\n }\n if (chunk.usage.outputTokens) {\n progress.setOutputTokens(chunk.usage.outputTokens, false);\n }\n }\n if (chunk.text) {\n progress.pause(); // Must pause to avoid stderr/stdout interleaving\n totalChars += chunk.text.length;\n progress.update(totalChars); // Update token estimate from chars\n printer.write(chunk.text);\n }\n if (chunk.finishReason !== undefined) {\n finishReason = chunk.finishReason;\n }\n }\n\n progress.endCall(usage); // Calculate cost before completing\n progress.complete();\n printer.ensureNewline();\n\n // Only show summary if stderr is a TTY (not redirected)\n if (stderrTTY) {\n const summary = renderSummary({ finishReason, usage, cost: progress.getTotalCost() });\n if (summary) {\n env.stderr.write(`${summary}\\n`);\n }\n }\n}\n\n/**\n * Registers the complete command with the CLI program.\n * Configures options for model, system prompt, temperature, and max tokens.\n *\n * @param program - Commander program to register the command with\n * @param env - CLI environment for dependencies and I/O\n */\nexport function registerCompleteCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.complete)\n .description(\"Stream a single completion from a specified model.\")\n .argument(\"[prompt]\", \"Prompt to send to the LLM. If omitted, stdin is used when available.\")\n .option(OPTION_FLAGS.model, OPTION_DESCRIPTIONS.model, DEFAULT_MODEL)\n .option(OPTION_FLAGS.systemPrompt, OPTION_DESCRIPTIONS.systemPrompt)\n .option(\n OPTION_FLAGS.temperature,\n OPTION_DESCRIPTIONS.temperature,\n createNumericParser({ label: \"Temperature\", min: 0, max: 2 }),\n )\n .option(\n OPTION_FLAGS.maxTokens,\n OPTION_DESCRIPTIONS.maxTokens,\n createNumericParser({ label: \"Max tokens\", integer: true, min: 1 }),\n )\n .action((prompt, options) =>\n executeAction(\n () => handleCompleteCommand(prompt, options as CompleteCommandOptions, env),\n env,\n ),\n );\n}\n","import { type Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { COMMANDS } from \"./constants.js\";\nimport type { CLIEnvironment } from \"./environment.js\";\nimport { executeAction } from \"./utils.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport { MODEL_ALIASES } from \"../core/model-shortcuts.js\";\n\ninterface ModelsCommandOptions {\n provider?: string;\n format?: \"table\" | \"json\";\n verbose?: boolean;\n}\n\nasync function handleModelsCommand(\n options: ModelsCommandOptions,\n env: CLIEnvironment,\n): Promise<void> {\n const client = env.createClient();\n\n // Get models, optionally filtered by provider\n const models = client.modelRegistry.listModels(options.provider);\n\n if (options.format === \"json\") {\n renderJSON(models, env.stdout);\n } else {\n renderTable(models, options.verbose || false, env.stdout);\n }\n}\n\nfunction renderTable(models: ModelSpec[], verbose: boolean, stream: NodeJS.WritableStream): void {\n // Group models by provider\n const grouped = new Map<string, ModelSpec[]>();\n for (const model of models) {\n const provider = model.provider;\n if (!grouped.has(provider)) {\n grouped.set(provider, []);\n }\n grouped.get(provider)!.push(model);\n }\n\n // Header\n stream.write(chalk.bold.cyan(\"\\nAvailable Models\\n\"));\n stream.write(chalk.cyan(\"=\".repeat(80)) + \"\\n\\n\");\n\n // Display each provider's models\n const providers = Array.from(grouped.keys()).sort();\n for (const provider of providers) {\n const providerModels = grouped.get(provider)!;\n const providerName = provider.charAt(0).toUpperCase() + provider.slice(1);\n\n stream.write(chalk.bold.yellow(`${providerName} Models\\n`));\n\n if (verbose) {\n renderVerboseTable(providerModels, stream);\n } else {\n renderCompactTable(providerModels, stream);\n }\n\n stream.write(\"\\n\");\n }\n\n // Display shortcuts\n stream.write(chalk.bold.magenta(\"Model Shortcuts\\n\"));\n stream.write(chalk.dim(\"─\".repeat(80)) + \"\\n\");\n\n const shortcuts = Object.entries(MODEL_ALIASES).sort((a, b) => a[0].localeCompare(b[0]));\n for (const [shortcut, fullName] of shortcuts) {\n stream.write(chalk.cyan(` ${shortcut.padEnd(15)}`) + chalk.dim(\" → \") + chalk.white(fullName) + \"\\n\");\n }\n stream.write(\"\\n\");\n}\n\nfunction renderCompactTable(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n // Column widths\n const idWidth = 25;\n const nameWidth = 22;\n const contextWidth = 13;\n const inputWidth = 10;\n const outputWidth = 10;\n\n // Header\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n stream.write(\n chalk.bold(\n \"Model ID\".padEnd(idWidth) +\n \" \" + \"Display Name\".padEnd(nameWidth) +\n \" \" + \"Context\".padEnd(contextWidth) +\n \" \" + \"Input\".padEnd(inputWidth) +\n \" \" + \"Output\".padEnd(outputWidth)\n ) + \"\\n\"\n );\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n\n // Rows\n for (const model of models) {\n const contextFormatted = formatTokens(model.contextWindow);\n const inputPrice = `$${model.pricing.input.toFixed(2)}`;\n const outputPrice = `$${model.pricing.output.toFixed(2)}`;\n\n stream.write(\n chalk.green(model.modelId.padEnd(idWidth)) +\n \" \" + chalk.white(model.displayName.padEnd(nameWidth)) +\n \" \" + chalk.yellow(contextFormatted.padEnd(contextWidth)) +\n \" \" + chalk.cyan(inputPrice.padEnd(inputWidth)) +\n \" \" + chalk.cyan(outputPrice.padEnd(outputWidth)) +\n \"\\n\"\n );\n }\n\n stream.write(chalk.dim(\"─\".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + \"\\n\");\n stream.write(chalk.dim(` * Prices are per 1M tokens\\n`));\n}\n\nfunction renderVerboseTable(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n for (const model of models) {\n stream.write(chalk.bold.green(`\\n ${model.modelId}\\n`));\n stream.write(chalk.dim(\" \" + \"─\".repeat(60)) + \"\\n\");\n stream.write(` ${chalk.dim(\"Name:\")} ${chalk.white(model.displayName)}\\n`);\n stream.write(` ${chalk.dim(\"Context:\")} ${chalk.yellow(formatTokens(model.contextWindow))}\\n`);\n stream.write(` ${chalk.dim(\"Max Output:\")} ${chalk.yellow(formatTokens(model.maxOutputTokens))}\\n`);\n stream.write(` ${chalk.dim(\"Pricing:\")} ${chalk.cyan(`$${model.pricing.input.toFixed(2)} input`)} ${chalk.dim(\"/\")} ${chalk.cyan(`$${model.pricing.output.toFixed(2)} output`)} ${chalk.dim(\"(per 1M tokens)\")}\\n`);\n\n if (model.pricing.cachedInput !== undefined) {\n stream.write(` ${chalk.dim(\"Cached Input:\")} ${chalk.cyan(`$${model.pricing.cachedInput.toFixed(2)} per 1M tokens`)}\\n`);\n }\n\n if (model.knowledgeCutoff) {\n stream.write(` ${chalk.dim(\"Knowledge:\")} ${model.knowledgeCutoff}\\n`);\n }\n\n // Features\n const features: string[] = [];\n if (model.features.streaming) features.push(\"streaming\");\n if (model.features.functionCalling) features.push(\"function-calling\");\n if (model.features.vision) features.push(\"vision\");\n if (model.features.reasoning) features.push(\"reasoning\");\n if (model.features.structuredOutputs) features.push(\"structured-outputs\");\n if (model.features.fineTuning) features.push(\"fine-tuning\");\n\n if (features.length > 0) {\n stream.write(` ${chalk.dim(\"Features:\")} ${chalk.blue(features.join(\", \"))}\\n`);\n }\n\n // Metadata\n if (model.metadata) {\n if (model.metadata.family) {\n stream.write(` ${chalk.dim(\"Family:\")} ${model.metadata.family}\\n`);\n }\n if (model.metadata.releaseDate) {\n stream.write(` ${chalk.dim(\"Released:\")} ${model.metadata.releaseDate}\\n`);\n }\n if (model.metadata.notes) {\n stream.write(` ${chalk.dim(\"Notes:\")} ${chalk.italic(model.metadata.notes)}\\n`);\n }\n }\n }\n stream.write(\"\\n\");\n}\n\nfunction renderJSON(models: ModelSpec[], stream: NodeJS.WritableStream): void {\n const output = {\n models: models.map(model => ({\n provider: model.provider,\n modelId: model.modelId,\n displayName: model.displayName,\n contextWindow: model.contextWindow,\n maxOutputTokens: model.maxOutputTokens,\n pricing: {\n input: model.pricing.input,\n output: model.pricing.output,\n cachedInput: model.pricing.cachedInput,\n currency: \"USD\",\n per: \"1M tokens\",\n },\n knowledgeCutoff: model.knowledgeCutoff,\n features: model.features,\n metadata: model.metadata,\n })),\n shortcuts: MODEL_ALIASES,\n };\n\n stream.write(JSON.stringify(output, null, 2) + \"\\n\");\n}\n\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) {\n return `${(count / 1_000_000).toFixed(1)}M tokens`;\n } else if (count >= 1_000) {\n return `${(count / 1_000).toFixed(0)}K tokens`;\n } else {\n return `${count} tokens`;\n }\n}\n\nexport function registerModelsCommand(program: Command, env: CLIEnvironment): void {\n program\n .command(COMMANDS.models)\n .description(\"List all available LLM models with pricing and capabilities.\")\n .option(\"--provider <name>\", \"Filter by provider (openai, anthropic, gemini)\")\n .option(\"--format <format>\", \"Output format: table or json\", \"table\")\n .option(\"--verbose\", \"Show detailed model information\", false)\n .action((options) =>\n executeAction(\n () => handleModelsCommand(options as ModelsCommandOptions, env),\n env,\n ),\n );\n}\n","import readline from \"node:readline\";\nimport chalk from \"chalk\";\nimport type { ILogObj, Logger } from \"tslog\";\nimport { LLMist } from \"../core/client.js\";\nimport type { LoggerOptions } from \"../logging/logger.js\";\nimport { createLogger } from \"../logging/logger.js\";\n\n/**\n * Stream type that may have TTY capabilities.\n */\nexport type TTYStream = NodeJS.ReadableStream & { isTTY?: boolean };\n\n/**\n * Logger configuration for CLI commands.\n */\nexport interface CLILoggerConfig {\n logLevel?: string;\n logFile?: string;\n}\n\n/**\n * Environment abstraction for CLI dependencies and I/O.\n * Allows dependency injection for testing.\n */\nexport interface CLIEnvironment {\n argv: string[];\n stdin: TTYStream;\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n createClient: () => LLMist;\n setExitCode: (code: number) => void;\n loggerConfig?: CLILoggerConfig;\n createLogger: (name: string) => Logger<ILogObj>;\n /** Whether stdin is a TTY (interactive terminal) */\n isTTY: boolean;\n /** Prompt the user for input (only works when isTTY is true) */\n prompt: (question: string) => Promise<string>;\n}\n\nconst LOG_LEVEL_MAP: Record<string, number> = {\n silly: 0,\n trace: 1,\n debug: 2,\n info: 3,\n warn: 4,\n error: 5,\n fatal: 6,\n};\n\n/**\n * Creates a logger factory based on CLI configuration.\n * Priority: CLI options > environment variables > defaults\n */\nfunction createLoggerFactory(config?: CLILoggerConfig): (name: string) => Logger<ILogObj> {\n return (name: string) => {\n const options: LoggerOptions = { name };\n\n // CLI --log-level takes priority over LLMIST_LOG_LEVEL env var\n if (config?.logLevel) {\n const level = config.logLevel.toLowerCase();\n if (level in LOG_LEVEL_MAP) {\n options.minLevel = LOG_LEVEL_MAP[level];\n }\n }\n\n // CLI --log-file takes priority over LLMIST_LOG_FILE env var\n // When log file is set via CLI, we temporarily set the env var\n // so createLogger picks it up\n if (config?.logFile) {\n const originalLogFile = process.env.LLMIST_LOG_FILE;\n process.env.LLMIST_LOG_FILE = config.logFile;\n const logger = createLogger(options);\n // Restore original (or delete if it wasn't set)\n if (originalLogFile === undefined) {\n delete process.env.LLMIST_LOG_FILE;\n } else {\n process.env.LLMIST_LOG_FILE = originalLogFile;\n }\n return logger;\n }\n\n // If no log file, default to pretty output (not hidden)\n if (!process.env.LLMIST_LOG_FILE) {\n options.type = \"pretty\";\n }\n\n return createLogger(options);\n };\n}\n\n/**\n * Creates a readline-based prompt function for user input.\n */\nfunction createPromptFunction(\n stdin: NodeJS.ReadableStream,\n stdout: NodeJS.WritableStream,\n): (question: string) => Promise<string> {\n return (question: string) => {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: stdin,\n output: stdout,\n });\n // Display question with visual styling\n stdout.write(\"\\n\");\n stdout.write(`${chalk.cyan(\"─\".repeat(60))}\\n`);\n stdout.write(chalk.cyan.bold(\"🤖 Agent asks:\\n\"));\n stdout.write(`${question}\\n`);\n stdout.write(`${chalk.cyan(\"─\".repeat(60))}\\n`);\n rl.question(chalk.green.bold(\"You: \"), (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n };\n}\n\n/**\n * Creates the default CLI environment using Node.js process globals.\n * Uses process.argv, process.stdin/stdout/stderr, and creates a new LLMist client.\n *\n * @param loggerConfig - Optional logger configuration from CLI options\n * @returns Default CLI environment\n */\nexport function createDefaultEnvironment(loggerConfig?: CLILoggerConfig): CLIEnvironment {\n const isTTY = Boolean(process.stdin.isTTY);\n\n return {\n argv: process.argv,\n stdin: process.stdin,\n stdout: process.stdout,\n stderr: process.stderr,\n createClient: () => new LLMist(),\n setExitCode: (code: number) => {\n process.exitCode = code;\n },\n loggerConfig,\n createLogger: createLoggerFactory(loggerConfig),\n isTTY,\n prompt: isTTY\n ? createPromptFunction(process.stdin, process.stdout)\n : async () => {\n throw new Error(\"Cannot prompt for input: stdin is not a TTY\");\n },\n };\n}\n","#!/usr/bin/env node\nimport { SUMMARY_PREFIX } from \"./cli/constants.js\";\nimport { runCLI } from \"./cli/program.js\";\n\nrunCLI().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`${SUMMARY_PREFIX} Error: ${message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["InvalidArgumentError","chalk","InvalidArgumentError","InvalidArgumentError","chalk","gadgets","chalk","chalk","chalk","InvalidArgumentError"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llmist",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|