---------------------------------------------------------------------- This is the API documentation for the spawnllm library. ---------------------------------------------------------------------- ## Calling One-shot LLM calls and structured output. schema_for(model: 'type[BaseModel]') -> 'str' Serialize a Pydantic model's JSON schema, with `additionalProperties` set to false. resolve_schema_path(backend: 'LlmBackend', schema: 'str | None') -> 'str | None' Resolve a JSON schema into the argument form the backend's CLI expects. Args: backend: The backend the schema is destined for. schema: The JSON schema string, or `None`. Returns: A temp-file path for `CodexCliBackend`, the schema unchanged for other backends, or `None` without a schema. extract_structured(events: 'list[dict[str, Any]]', model: 'type[M]') -> 'M | None' Return the validated `structured_output` from a stream-json event list, if present. parse_structured_output(raw: 'str', response_model: 'type[M] | None') -> 'str | M' Parse raw CLI stdout into text or a validated model. Args: raw: Raw stdout from the backend CLI. response_model: The Pydantic model to validate against, or `None` for text. Returns: `raw` for text calls; otherwise `structured_output` from the stream-json events, else `raw` validated as JSON. parse_result_envelope(stdout: 'bytes', *, argv: 'list[str]', stderr: 'bytes') -> 'str' Parse a `{is_error, result}` JSON envelope into its result text. Args: stdout: Raw stdout bytes holding the envelope. argv: The argv that produced the output, for error reporting. stderr: Raw stderr bytes, attached to the error. Returns: The `result` payload. Raises: subprocess.CalledProcessError: When the envelope marks the run as an error. ## Backends CLI backends, the specialty registry, and Claude status checks. LlmBackend() Abstract interface for an LLM CLI backend. Concrete backends map abstract model sizes to provider-specific model names and encapsulate how to invoke the provider's CLI and parse the raw response. Attributes: models: Mapping from abstract model size to the provider's model name. ClaudeCliBackend(inline_system_prompt: 'str' = '', verbose: 'bool' = False) -> None `LlmBackend` for the Anthropic `claude` CLI. The default (no-arg) construction delivers the prompt over stdin with abstract model tiers and structured-output parsing. The `cc_sentiment` preset configures inline `-p` prompting with `{is_error, result}` envelope parsing. Attributes: models: Mapping from abstract model size to a Claude model alias (`haiku`/`sonnet`/`opus`). inline_system_prompt: System prompt that `build_argv` passes via `--system-prompt`. verbose: Whether `build_argv` appends `--verbose`. Example: >>> ClaudeCliBackend().build_command("haiku", None, agent=False)[:5] ['claude', '-p', '--no-session-persistence', '--model', 'haiku'] CodexCliBackend() `LlmBackend` for the OpenAI `codex` CLI. Invokes `codex exec` with an ephemeral session and a read-only sandbox. Attributes: models: Mapping from abstract model size to an OpenAI model name. LlmBackends() Registry mapping each specialty to the `LlmBackend` that serves it. `debugging` and `review` route to `CodexCliBackend`; `general` routes to `ClaudeCliBackend`. Attributes: LLM_BACKENDS: Mapping from specialty to its backend instance. check_status(timeout: 'int' = 10) -> 'ClaudeStatus' Check whether the `claude` CLI is installed and authenticated. Looks for `claude` on PATH, then runs `claude auth status`. Args: timeout: Seconds to wait for `claude auth status` before `subprocess.TimeoutExpired` is raised. Returns: `ClaudeReady` when authenticated, `ClaudeNotInstalled` when not on PATH, else `ClaudeNotAuthenticated`. Union Represent a union type E.g. for int | str ClaudeReady() -> None The `claude` CLI is installed and authenticated. ClaudeNotInstalled(brew_available: 'bool') -> None The `claude` CLI is not on PATH. Attributes: brew_available: Whether the `brew` executable is on PATH to install it with. ClaudeNotAuthenticated() -> None The `claude` CLI is installed but not authenticated. ## ClaudeCliBackend Methods Methods for the ClaudeCliBackend class cc_sentiment(*, system_prompt: 'str', verbose: 'bool' = False) -> 'ClaudeCliBackend' Build a backend preset for the sentiment/pushback scoring path. Args: system_prompt: System prompt that `build_argv` passes via `--system-prompt`. verbose: Whether `build_argv` appends `--verbose`. Returns: A `ClaudeCliBackend` for inline `-p` prompting; parse its stdout with `parse_result_envelope`. build_command(self, model: 'str', schema_path: 'str | None', agent: 'bool') -> 'list[str]' Build the `claude -p` argv for one stdin-prompted invocation. Every invocation runs without session persistence. Agent invocations add `--permission-mode auto` and a $1 `--max-budget-usd` cap; non-agent invocations empty the system prompt, disable setting sources, and load no MCP servers. A schema adds `--json-schema` with `--output-format json`. Args: model: Claude model name or alias, e.g. `haiku`. schema_path: Inline JSON schema passed to `--json-schema`, or `None`. agent: Whether the invocation may use tools / agent capabilities. Returns: The argv list to execute. parse_response(self, raw: 'str', response_model: 'type[BaseModel] | None') -> 'str | BaseModel' Parse `claude` stdout into text or a validated model. Args: raw: Raw stdout from the `claude` CLI. response_model: Model to validate against, or `None` for raw text. Returns: `raw` for text calls; otherwise the validated `structured_output` from the result event, else `raw` as JSON. env(self) -> 'dict[str, str]' Return no extra environment variables; the `claude` CLI runs with the inherited environment. build_argv(self, content: 'str', *, model: 'str') -> 'list[str]' Build the inline `-p` argv for the sentiment/pushback scoring path. The prompt travels inline as the `-p` argument instead of over stdin. The invocation uses `inline_system_prompt` as the system prompt, JSON output, a single turn, no tools, and no slash commands; `verbose` appends `--verbose`. Args: content: Prompt text passed inline via `-p`. model: Claude model name or alias, e.g. `haiku`. Returns: The argv list to execute; parse its stdout with `parse_result_envelope`. parse_result_envelope(stdout: 'bytes', *, argv: 'list[str]', stderr: 'bytes') -> 'str' Parse the `{is_error, result}` JSON envelope from `claude -p --output-format json`. Args: stdout: Raw stdout bytes holding the JSON envelope. argv: The argv that produced the output, recorded on the raised error. stderr: Raw stderr bytes, recorded on the raised error. Returns: The envelope's `result` string. Raises: subprocess.CalledProcessError: If the envelope's `is_error` flag is set. ## Transport Subprocess plumbing shared by the CLI backends. run_cli(argv: 'list[str]', *, input: 'str | None' = None, timeout: 'int' = 30, env: 'dict[str, str] | None' = None, cwd: 'str | None' = None) -> 'str' Run a CLI command to completion and return its stdout. Args: argv: The command and its arguments. input: Text delivered to the process over stdin. timeout: Seconds to wait before the process is killed. env: Environment for the process; `None` inherits the current environment. cwd: Working directory for the process. Returns: The decoded stdout. Raises: subprocess.CalledProcessError: On a nonzero exit code, with the argv, exit code, and stdout/stderr tails attached as notes. subprocess.TimeoutExpired: When the process outlives `timeout`. arun_cli(argv: 'list[str]', *, input: 'str | None' = None, env: 'dict[str, str] | None' = None, cwd: 'str | None' = None, stderr_tee: 'Callable[[bytes], None] | None' = None) -> 'bytes' Run a CLI command asynchronously and return its stdout. Args: argv: The command and its arguments. input: Text delivered to the process over stdin. env: Environment for the process; `None` inherits the current environment. cwd: Working directory for the process. stderr_tee: Callback invoked with each stderr line as it arrives. Returns: The raw stdout bytes. Raises: subprocess.CalledProcessError: On a nonzero exit code. collect_process(proc: 'asyncio.subprocess.Process', *, stderr_tee: 'Callable[[bytes], None] | None' = None) -> 'tuple[bytes, bytes, int]' Drain a subprocess's stdout and stderr concurrently and wait for it to exit. Args: proc: A process created with both stdout and stderr piped. stderr_tee: Callback invoked with each stderr line as it arrives. Returns: A `(stdout, stderr, returncode)` tuple. map_concurrent(items: 'Sequence[T]', fn: 'Callable[[T], Awaitable[R]]', *, limit: 'int', on_done: 'Callable[[int], None] | None' = None) -> 'list[R]' Map an async function over items with bounded concurrency. Args: items: The inputs to process. fn: Async function applied to each item. limit: Maximum number of in-flight calls. on_done: Progress callback invoked with `1` as each item completes. Returns: The results, in input order. ## Types Shared type aliases. Literal(*args, **kwargs) Literal(*args, **kwargs) ## MLX Local Apple-Silicon engine, adapter codec, fuser, and runtime patches. ---------------------------------------------------------------------- This is the CLI documentation for the package. ---------------------------------------------------------------------- ## CLI: spawnllm ``` Usage: spawnllm [OPTIONS] COMMAND [ARGS]... Subshell + MLX LLM-calling backends (Claude/Codex CLI, local MLX) shared across tools. Options: --version Show the version and exit. --help Show this message and exit. Commands: backends List the LLM backends spawnllm can drive. call Make a one-off LLM call (reads PROMPT or stdin) and print the... ``` ### spawnllm backends ``` Usage: spawnllm backends [OPTIONS] List the LLM backends spawnllm can drive. Options: --help Show this message and exit. ``` ### spawnllm call ``` Usage: spawnllm call [OPTIONS] [PROMPT] Make a one-off LLM call (reads PROMPT or stdin) and print the response. Options: --backend [claude|codex] [required] --model [small|medium|large] --agent Allow tools / agent capabilities. --help Show this message and exit. ```