spacr.qt.ai.providers¶
Provider abstraction — one class per AI vendor. Each shells out to the vendor’s own coding-agent CLI so authentication piggy-backs on the user’s chat subscription (Claude.ai Pro, ChatGPT Plus/Pro/Team, Google account) — no separate API billing.
Anthropic Claude → the
claudeCLI (“Claude Code”)OpenAI ChatGPT → the
codexCLIGoogle Gemini → the
geminiCLI
- Each provider:
is_installed() — is the CLI on PATH? is_logged_in() — best-effort check; falls back to “assume yes if
installed” (the actual auth error surfaces on the first stream chunk).
stream_chat() — spawn the CLI subprocess, yield stdout chunks.
Conversation context is carried by concatenating the full message history into each prompt (simplest approach that works uniformly across all three CLIs). For subscription users token count is not a concern.
Classes¶
Abstract base for AI chat providers that shell out to a vendor CLI. |
|
Anthropic Claude via the |
|
OpenAI ChatGPT via the |
|
Google Gemini via the |
Functions¶
|
Return only providers whose CLI is installed and logged in. |
|
Look up a registered provider by its short id. |
|
Return every registered provider, regardless of install state. |
Module Contents¶
- class spacr.qt.ai.providers.ChatProvider[source]¶
Bases:
abc.ABCAbstract base for AI chat providers that shell out to a vendor CLI.
Subclasses set the
name/label/cli_name/install_hint/login_commandclass attributes and implementstream_chat().- Variables:
name – short id (“claude” / “codex” / “gemini”).
label – human-readable label shown in the UI.
cli_name – executable expected on
PATH.install_hint – shell one-liner suggested for installation.
login_command – shell one-liner the user runs to authenticate.
- cancel_stream() None[source]¶
Kill the running subprocess (if any).
This is the ONLY reliable way to unblock a stream that’s stuck waiting on stdout — flipping a Python flag would only unblock between chunks, which may never come.
- is_logged_in() bool[source]¶
Best-effort — override per provider if a cheap check exists.
Default: assume yes when installed. The real auth error will surface as a normal subprocess failure on the first send.
- source_of_key() str[source]¶
Compat string for the old KeysDialog — now describes the CLI’s install/login state.
- class spacr.qt.ai.providers.ClaudeCliProvider[source]¶
Bases:
ChatProviderAnthropic Claude via the
claude(Claude Code) CLI.- stream_chat(messages: List[Dict], system: str = '', model: str | None = None) Iterator[str][source]¶
Stream a chat completion from the
claudeCLI.- Parameters:
messages – conversation history as
{role, content}dicts.system – optional system prompt appended via
--append-system-prompt.model – optional model override passed via
--model. When None the current response-speed setting supplies one.
- Returns:
iterator yielding stdout text chunks.
- class spacr.qt.ai.providers.CodexCliProvider[source]¶
Bases:
ChatProviderOpenAI ChatGPT via the
codexCLI.- stream_chat(messages: List[Dict], system: str = '', model: str | None = None) Iterator[str][source]¶
Stream a chat completion from the
codexCLI.- Parameters:
messages – conversation history as
{role, content}dicts.system – optional system prompt folded into the prompt body.
model – optional model override passed via
--model. When None the current response-speed setting supplies one.
- Returns:
iterator yielding stdout text chunks.
- class spacr.qt.ai.providers.GeminiCliProvider[source]¶
Bases:
ChatProviderGoogle Gemini via the
geminiCLI.- stream_chat(messages: List[Dict], system: str = '', model: str | None = None) Iterator[str][source]¶
Stream a chat completion from the
geminiCLI.- Parameters:
messages – conversation history as
{role, content}dicts.system – optional system prompt folded into the prompt body.
model – optional model override passed via
-m. When None the current response-speed setting supplies one.
- Returns:
iterator yielding stdout text chunks.
- spacr.qt.ai.providers.configured_providers() List[ChatProvider][source]¶
Return only providers whose CLI is installed and logged in.
- spacr.qt.ai.providers.get_provider(name: str) ChatProvider | None[source]¶
Look up a registered provider by its short id.
- Parameters:
name – provider id (
"claude","codex","gemini").- Returns:
the matching provider, or
Noneif no such id.
- spacr.qt.ai.providers.list_providers() List[ChatProvider][source]¶
Return every registered provider, regardless of install state.