kitty-bridge 0.1.5__tar.gz
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.
- kitty_bridge-0.1.5/.github/workflows/ci.yml +27 -0
- kitty_bridge-0.1.5/.github/workflows/publish.yml +50 -0
- kitty_bridge-0.1.5/.gitignore +13 -0
- kitty_bridge-0.1.5/LICENSE +21 -0
- kitty_bridge-0.1.5/PKG-INFO +317 -0
- kitty_bridge-0.1.5/README.md +276 -0
- kitty_bridge-0.1.5/pyproject.toml +124 -0
- kitty_bridge-0.1.5/src/kitty/__init__.py +4 -0
- kitty_bridge-0.1.5/src/kitty/__main__.py +6 -0
- kitty_bridge-0.1.5/src/kitty/bridge/__init__.py +5 -0
- kitty_bridge-0.1.5/src/kitty/bridge/config.py +108 -0
- kitty_bridge-0.1.5/src/kitty/bridge/engine.py +126 -0
- kitty_bridge-0.1.5/src/kitty/bridge/gemini/__init__.py +1 -0
- kitty_bridge-0.1.5/src/kitty/bridge/gemini/events.py +19 -0
- kitty_bridge-0.1.5/src/kitty/bridge/gemini/translator.py +310 -0
- kitty_bridge-0.1.5/src/kitty/bridge/keys.py +74 -0
- kitty_bridge-0.1.5/src/kitty/bridge/manage.py +179 -0
- kitty_bridge-0.1.5/src/kitty/bridge/messages/__init__.py +1 -0
- kitty_bridge-0.1.5/src/kitty/bridge/messages/events.py +94 -0
- kitty_bridge-0.1.5/src/kitty/bridge/messages/translator.py +453 -0
- kitty_bridge-0.1.5/src/kitty/bridge/responses/__init__.py +1 -0
- kitty_bridge-0.1.5/src/kitty/bridge/responses/events.py +251 -0
- kitty_bridge-0.1.5/src/kitty/bridge/responses/translator.py +653 -0
- kitty_bridge-0.1.5/src/kitty/bridge/server.py +1592 -0
- kitty_bridge-0.1.5/src/kitty/bridge/service.py +135 -0
- kitty_bridge-0.1.5/src/kitty/bridge/state.py +65 -0
- kitty_bridge-0.1.5/src/kitty/bridge_runner.py +164 -0
- kitty_bridge-0.1.5/src/kitty/cli/__init__.py +0 -0
- kitty_bridge-0.1.5/src/kitty/cli/cleanup_cmd.py +99 -0
- kitty_bridge-0.1.5/src/kitty/cli/doctor_cmd.py +148 -0
- kitty_bridge-0.1.5/src/kitty/cli/launcher.py +341 -0
- kitty_bridge-0.1.5/src/kitty/cli/main.py +534 -0
- kitty_bridge-0.1.5/src/kitty/cli/profile_cmd.py +296 -0
- kitty_bridge-0.1.5/src/kitty/cli/router.py +142 -0
- kitty_bridge-0.1.5/src/kitty/cli/setup_cmd.py +156 -0
- kitty_bridge-0.1.5/src/kitty/credentials/__init__.py +13 -0
- kitty_bridge-0.1.5/src/kitty/credentials/file_backend.py +102 -0
- kitty_bridge-0.1.5/src/kitty/credentials/keyring_backend.py +36 -0
- kitty_bridge-0.1.5/src/kitty/credentials/store.py +67 -0
- kitty_bridge-0.1.5/src/kitty/launchers/__init__.py +5 -0
- kitty_bridge-0.1.5/src/kitty/launchers/base.py +61 -0
- kitty_bridge-0.1.5/src/kitty/launchers/claude.py +206 -0
- kitty_bridge-0.1.5/src/kitty/launchers/codex.py +50 -0
- kitty_bridge-0.1.5/src/kitty/launchers/discovery.py +139 -0
- kitty_bridge-0.1.5/src/kitty/launchers/gemini.py +41 -0
- kitty_bridge-0.1.5/src/kitty/launchers/kilo.py +176 -0
- kitty_bridge-0.1.5/src/kitty/profiles/__init__.py +6 -0
- kitty_bridge-0.1.5/src/kitty/profiles/resolver.py +93 -0
- kitty_bridge-0.1.5/src/kitty/profiles/schema.py +116 -0
- kitty_bridge-0.1.5/src/kitty/profiles/store.py +162 -0
- kitty_bridge-0.1.5/src/kitty/providers/__init__.py +33 -0
- kitty_bridge-0.1.5/src/kitty/providers/anthropic.py +347 -0
- kitty_bridge-0.1.5/src/kitty/providers/azure.py +145 -0
- kitty_bridge-0.1.5/src/kitty/providers/base.py +217 -0
- kitty_bridge-0.1.5/src/kitty/providers/bedrock.py +452 -0
- kitty_bridge-0.1.5/src/kitty/providers/fireworks.py +79 -0
- kitty_bridge-0.1.5/src/kitty/providers/minimax.py +74 -0
- kitty_bridge-0.1.5/src/kitty/providers/novita.py +58 -0
- kitty_bridge-0.1.5/src/kitty/providers/ollama.py +190 -0
- kitty_bridge-0.1.5/src/kitty/providers/openai.py +54 -0
- kitty_bridge-0.1.5/src/kitty/providers/openrouter.py +55 -0
- kitty_bridge-0.1.5/src/kitty/providers/registry.py +52 -0
- kitty_bridge-0.1.5/src/kitty/providers/vertex.py +171 -0
- kitty_bridge-0.1.5/src/kitty/providers/zai.py +76 -0
- kitty_bridge-0.1.5/src/kitty/tui/__init__.py +0 -0
- kitty_bridge-0.1.5/src/kitty/tui/display.py +78 -0
- kitty_bridge-0.1.5/src/kitty/tui/menu.py +58 -0
- kitty_bridge-0.1.5/src/kitty/tui/prompts.py +68 -0
- kitty_bridge-0.1.5/src/kitty/types.py +12 -0
- kitty_bridge-0.1.5/src/kitty/validation.py +136 -0
- kitty_bridge-0.1.5/tests/bridge/__init__.py +0 -0
- kitty_bridge-0.1.5/tests/bridge/test_access_logging.py +144 -0
- kitty_bridge-0.1.5/tests/bridge/test_all_protocol_routing.py +219 -0
- kitty_bridge-0.1.5/tests/bridge/test_api_key_auth.py +225 -0
- kitty_bridge-0.1.5/tests/bridge/test_balancing_server.py +271 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_config.py +166 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_engine.py +166 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_management.py +225 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_server.py +696 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_server_anthropic.py +113 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_server_bedrock.py +102 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_server_claude_e2e.py +1258 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_server_kilo.py +278 -0
- kitty_bridge-0.1.5/tests/bridge/test_bridge_state.py +152 -0
- kitty_bridge-0.1.5/tests/bridge/test_circuit_breaker.py +323 -0
- kitty_bridge-0.1.5/tests/bridge/test_connection_retries.py +521 -0
- kitty_bridge-0.1.5/tests/bridge/test_host_port_config.py +99 -0
- kitty_bridge-0.1.5/tests/bridge/test_messages_events.py +184 -0
- kitty_bridge-0.1.5/tests/bridge/test_messages_translator.py +555 -0
- kitty_bridge-0.1.5/tests/bridge/test_responses_events.py +266 -0
- kitty_bridge-0.1.5/tests/bridge/test_responses_translator.py +993 -0
- kitty_bridge-0.1.5/tests/bridge/test_service_install.py +118 -0
- kitty_bridge-0.1.5/tests/bridge/test_sse_line_buffering.py +143 -0
- kitty_bridge-0.1.5/tests/bridge/test_streaming_hang_fixes.py +585 -0
- kitty_bridge-0.1.5/tests/bridge/test_tls_support.py +123 -0
- kitty_bridge-0.1.5/tests/bridge/test_upstream_error_translation.py +246 -0
- kitty_bridge-0.1.5/tests/cli/__init__.py +0 -0
- kitty_bridge-0.1.5/tests/cli/test_cleanup_cmd.py +129 -0
- kitty_bridge-0.1.5/tests/conftest.py +74 -0
- kitty_bridge-0.1.5/tests/integration/__init__.py +0 -0
- kitty_bridge-0.1.5/tests/integration/test_agent_e2e.py +227 -0
- kitty_bridge-0.1.5/tests/test_balancing_resolver.py +147 -0
- kitty_bridge-0.1.5/tests/test_balancing_schema.py +92 -0
- kitty_bridge-0.1.5/tests/test_balancing_store.py +167 -0
- kitty_bridge-0.1.5/tests/test_bridge_mode.py +210 -0
- kitty_bridge-0.1.5/tests/test_claude_settings_api_key.py +193 -0
- kitty_bridge-0.1.5/tests/test_claude_settings_override.py +179 -0
- kitty_bridge-0.1.5/tests/test_cli_main.py +120 -0
- kitty_bridge-0.1.5/tests/test_cli_router.py +271 -0
- kitty_bridge-0.1.5/tests/test_credential_store.py +137 -0
- kitty_bridge-0.1.5/tests/test_doctor_cmd.py +133 -0
- kitty_bridge-0.1.5/tests/test_exit_code_mapping.py +45 -0
- kitty_bridge-0.1.5/tests/test_gemini_protocol.py +71 -0
- kitty_bridge-0.1.5/tests/test_gemini_translator.py +358 -0
- kitty_bridge-0.1.5/tests/test_github_actions.py +203 -0
- kitty_bridge-0.1.5/tests/test_integration.py +199 -0
- kitty_bridge-0.1.5/tests/test_kilo_config.py +145 -0
- kitty_bridge-0.1.5/tests/test_kilo_protocol.py +115 -0
- kitty_bridge-0.1.5/tests/test_launch_orchestrator.py +263 -0
- kitty_bridge-0.1.5/tests/test_launcher_base.py +70 -0
- kitty_bridge-0.1.5/tests/test_launcher_claude.py +90 -0
- kitty_bridge-0.1.5/tests/test_launcher_codex.py +79 -0
- kitty_bridge-0.1.5/tests/test_launcher_discovery.py +152 -0
- kitty_bridge-0.1.5/tests/test_profile_resolver.py +115 -0
- kitty_bridge-0.1.5/tests/test_profile_schema.py +254 -0
- kitty_bridge-0.1.5/tests/test_profile_store.py +148 -0
- kitty_bridge-0.1.5/tests/test_provider_anthropic.py +450 -0
- kitty_bridge-0.1.5/tests/test_provider_azure.py +296 -0
- kitty_bridge-0.1.5/tests/test_provider_base.py +135 -0
- kitty_bridge-0.1.5/tests/test_provider_bedrock.py +584 -0
- kitty_bridge-0.1.5/tests/test_provider_fireworks.py +212 -0
- kitty_bridge-0.1.5/tests/test_provider_list_sync.py +65 -0
- kitty_bridge-0.1.5/tests/test_provider_minimax.py +123 -0
- kitty_bridge-0.1.5/tests/test_provider_novita.py +99 -0
- kitty_bridge-0.1.5/tests/test_provider_ollama.py +171 -0
- kitty_bridge-0.1.5/tests/test_provider_openai.py +162 -0
- kitty_bridge-0.1.5/tests/test_provider_openrouter.py +136 -0
- kitty_bridge-0.1.5/tests/test_provider_registry.py +75 -0
- kitty_bridge-0.1.5/tests/test_provider_vertex.py +385 -0
- kitty_bridge-0.1.5/tests/test_provider_zai.py +212 -0
- kitty_bridge-0.1.5/tests/test_pypi_packaging.py +253 -0
- kitty_bridge-0.1.5/tests/test_validation.py +179 -0
- kitty_bridge-0.1.5/tests/tui/test_display.py +170 -0
- kitty_bridge-0.1.5/tests/tui/test_menu.py +95 -0
- kitty_bridge-0.1.5/tests/tui/test_profile_menu.py +93 -0
- kitty_bridge-0.1.5/tests/tui/test_prompts.py +112 -0
- kitty_bridge-0.1.5/tests/tui/test_setup_wizard.py +141 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.10"
|
|
18
|
+
cache: pip
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: pip install -e ".[dev]"
|
|
22
|
+
|
|
23
|
+
- name: Lint
|
|
24
|
+
run: ruff check .
|
|
25
|
+
|
|
26
|
+
- name: Test
|
|
27
|
+
run: pytest
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment:
|
|
12
|
+
name: pypi
|
|
13
|
+
url: https://pypi.org/project/kitty-bridge
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
id-token: write
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 1
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.10"
|
|
25
|
+
|
|
26
|
+
- name: Verify tag version matches pyproject.toml
|
|
27
|
+
run: |
|
|
28
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
29
|
+
PYPROJECT_VERSION=$(python -c "
|
|
30
|
+
import re, sys
|
|
31
|
+
text = open('pyproject.toml').read()
|
|
32
|
+
for line in text.splitlines():
|
|
33
|
+
if line.startswith('version ='):
|
|
34
|
+
print(line.split('=', 1)[1].strip().strip(\"'\").strip('\"'))
|
|
35
|
+
break
|
|
36
|
+
")
|
|
37
|
+
if [ "$TAG_VERSION" != "$PYPROJECT_VERSION" ]; then
|
|
38
|
+
echo "ERROR: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION)"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
echo "Version check passed: $TAG_VERSION"
|
|
42
|
+
|
|
43
|
+
- name: Install build dependency
|
|
44
|
+
run: pip install build
|
|
45
|
+
|
|
46
|
+
- name: Build package
|
|
47
|
+
run: python -m build
|
|
48
|
+
|
|
49
|
+
- name: Publish to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shelpuk AI Technology Consulting
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kitty-bridge
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: Kitty Bridge — launch coding agents through a local API bridge
|
|
5
|
+
Project-URL: Homepage, https://github.com/Shelpuk-AI-Technology-Consulting/kitty-bridge
|
|
6
|
+
Project-URL: Repository, https://github.com/Shelpuk-AI-Technology-Consulting/kitty-bridge
|
|
7
|
+
Project-URL: Issues, https://github.com/Shelpuk-AI-Technology-Consulting/kitty-bridge/issues
|
|
8
|
+
Author: Shelpuk AI Technology Consulting
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api-bridge,claude-code,cli,codex,coding-agent,llm
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: aiohttp>=3.9
|
|
23
|
+
Requires-Dist: boto3>=1.34
|
|
24
|
+
Requires-Dist: filelock>=3.13
|
|
25
|
+
Requires-Dist: keyring>=23.0
|
|
26
|
+
Requires-Dist: platformdirs>=4.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: rich>=13.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: aioresponses>=0.7; extra == 'dev'
|
|
32
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: hatchling>=1.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: import-linter>=2.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
39
|
+
Requires-Dist: twine>=4.0; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# Kitty Bridge
|
|
43
|
+
|
|
44
|
+
A thin launcher for coding agents that routes requests through a local API bridge to any upstream Chat Completions provider.
|
|
45
|
+
|
|
46
|
+
## What it does
|
|
47
|
+
|
|
48
|
+
kitty sits between your coding agent and the upstream API:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Agent (codex / claude / gemini / kilo) → kitty bridge → Chat Completions → upstream provider
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The bridge translates between the agent's wire protocol (Responses API, Messages API, or Gemini API) and a standard Chat Completions API, so you can use any compatible provider without the agent needing native support.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install -e .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Requires Python 3.10+.
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# First-time setup — interactive wizard creates a profile
|
|
68
|
+
kitty setup
|
|
69
|
+
|
|
70
|
+
# Launch Codex CLI through the bridge
|
|
71
|
+
kitty codex
|
|
72
|
+
|
|
73
|
+
# Launch Claude Code through the bridge
|
|
74
|
+
kitty claude
|
|
75
|
+
|
|
76
|
+
# Launch Gemini CLI through the bridge
|
|
77
|
+
kitty gemini
|
|
78
|
+
|
|
79
|
+
# Launch Kilo Code through the bridge
|
|
80
|
+
kitty kilo
|
|
81
|
+
|
|
82
|
+
# Use a specific profile
|
|
83
|
+
kitty my-profile codex
|
|
84
|
+
|
|
85
|
+
# Start a standalone OpenAI-compatible API server (bridge mode)
|
|
86
|
+
kitty bridge
|
|
87
|
+
kitty my-profile bridge
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Commands
|
|
91
|
+
|
|
92
|
+
| Command | Description |
|
|
93
|
+
|---------|-------------|
|
|
94
|
+
| `kitty setup` | Interactive wizard to create your first profile |
|
|
95
|
+
| `kitty profile` | Manage profiles (create, delete, set default, list) |
|
|
96
|
+
| `kitty doctor` | Diagnose installation issues |
|
|
97
|
+
| `kitty cleanup` | Remove stale bridge values from agent config files |
|
|
98
|
+
| `kitty codex` | Launch Codex CLI through the bridge |
|
|
99
|
+
| `kitty claude` | Launch Claude Code through the bridge |
|
|
100
|
+
| `kitty gemini` | Launch Gemini CLI through the bridge |
|
|
101
|
+
| `kitty kilo` | Launch Kilo Code through the bridge |
|
|
102
|
+
| `kitty bridge` | Start a standalone OpenAI-compatible API server |
|
|
103
|
+
| `kitty <profile>` | Launch default agent with a named profile |
|
|
104
|
+
| `kitty <profile> codex` | Launch Codex with a named profile |
|
|
105
|
+
| `kitty <profile> claude` | Launch Claude Code with a named profile |
|
|
106
|
+
| `kitty <profile> gemini` | Launch Gemini CLI with a named profile |
|
|
107
|
+
| `kitty <profile> kilo` | Launch Kilo Code with a named profile |
|
|
108
|
+
| `kitty <profile> bridge` | Start bridge server with a named profile |
|
|
109
|
+
| `kitty --version` | Print version |
|
|
110
|
+
| `kitty --help` | Print help |
|
|
111
|
+
|
|
112
|
+
## Supported agents
|
|
113
|
+
|
|
114
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — Anthropic's coding agent (Messages API)
|
|
115
|
+
- [Codex CLI](https://github.com/openai/codex) — OpenAI's coding agent (Responses API)
|
|
116
|
+
- [Gemini CLI](https://github.com/google-gemini/gemini-cli) — Google's coding agent (Gemini API)
|
|
117
|
+
- [Kilo Code](https://github.com/kilocode/kilo-code) — Open-source coding agent
|
|
118
|
+
|
|
119
|
+
## Supported providers
|
|
120
|
+
|
|
121
|
+
| Provider | Type ID | Notes |
|
|
122
|
+
|--------------------|---------|------------------------------------------|
|
|
123
|
+
| Z.AI (regular) | `zai_regular` | Standard Z.AI API |
|
|
124
|
+
| Z.AI (coding plan) | `zai_coding` | Z.AI Coding Plan endpoint |
|
|
125
|
+
| MiniMax | `minimax` | |
|
|
126
|
+
| Novita | `novita` | |
|
|
127
|
+
| Ollama | `ollama` | Local LLM deployment (OpenAI-compatible) |
|
|
128
|
+
| OpenAI | `openai` | |
|
|
129
|
+
| OpenRouter | `openrouter` | Multi-provider router |
|
|
130
|
+
| Fireworks | `fireworks` | Fire Pass endpoint |
|
|
131
|
+
| Anthropic | `anthropic` | Direct Anthropic Messages API |
|
|
132
|
+
| AWS Bedrock | `bedrock` | Uses boto3 SigV4 auth |
|
|
133
|
+
| Azure OpenAI | `azure` | Azure-specific endpoint format |
|
|
134
|
+
| Google Vertex AI | `vertex` | Requires project/location config |
|
|
135
|
+
|
|
136
|
+
## How it works
|
|
137
|
+
|
|
138
|
+
### Agent launch mode
|
|
139
|
+
|
|
140
|
+
1. kitty resolves your profile (provider, model, API key)
|
|
141
|
+
2. Starts a local HTTP bridge on a random port
|
|
142
|
+
3. Configures the agent to talk to the bridge
|
|
143
|
+
4. The bridge translates requests to Chat Completions format and forwards them to your provider
|
|
144
|
+
5. Responses are translated back to the agent's native format
|
|
145
|
+
6. When the agent exits, kitty restores the agent's config files to their original state
|
|
146
|
+
|
|
147
|
+
### Bridge mode
|
|
148
|
+
|
|
149
|
+
Start a standalone OpenAI-compatible API server without launching an agent:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Use default profile
|
|
153
|
+
kitty bridge
|
|
154
|
+
|
|
155
|
+
# Use a specific profile
|
|
156
|
+
kitty my-profile bridge
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The server exposes:
|
|
160
|
+
- `POST /v1/chat/completions` — Chat Completions API (streaming and non-streaming)
|
|
161
|
+
- `POST /v1/messages` — Anthropic Messages API (for Claude Code)
|
|
162
|
+
- `POST /v1/responses` — OpenAI Responses API (for Codex)
|
|
163
|
+
- `POST /v1/gemini/generateContent` — Gemini API (for Gemini CLI)
|
|
164
|
+
- `GET /healthz` — Health check
|
|
165
|
+
|
|
166
|
+
### Balancing profiles
|
|
167
|
+
|
|
168
|
+
Balancing profiles distribute LLM calls across multiple providers in round-robin order:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Create a balancing profile via the profile menu
|
|
172
|
+
kitty profile
|
|
173
|
+
# → "Create balancing profile" → select 2+ member profiles
|
|
174
|
+
|
|
175
|
+
# Use a balancing profile
|
|
176
|
+
kitty my-balancer codex
|
|
177
|
+
kitty my-balancer bridge
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Each request is routed to the next provider in the rotation. Useful for cost optimization, rate limit distribution, and resilience across multiple providers.
|
|
181
|
+
|
|
182
|
+
## Profiles
|
|
183
|
+
|
|
184
|
+
A **profile** binds a provider, model, and API key together. Profiles are stored in `~/.config/kitty/profiles.json`.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Create profiles interactively
|
|
188
|
+
kitty setup
|
|
189
|
+
kitty profile
|
|
190
|
+
|
|
191
|
+
# Use a specific profile
|
|
192
|
+
kitty my-profile claude
|
|
193
|
+
|
|
194
|
+
# Set a default profile (used when no profile is named)
|
|
195
|
+
kitty profile # → "Set default profile"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
A **balancing profile** is a list of regular profiles. Requests are round-robined across members.
|
|
199
|
+
|
|
200
|
+
## Pre-flight validation
|
|
201
|
+
|
|
202
|
+
Before launching, kitty validates your API key by making a lightweight test request to the upstream provider. If the key is expired or invalid, kitty reports the error immediately and exits.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Skip validation (e.g. in air-gapped environments)
|
|
206
|
+
kitty --no-validate my-profile claude
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Cleanup
|
|
210
|
+
|
|
211
|
+
kitty uses a three-layer cleanup strategy to restore agent config files:
|
|
212
|
+
|
|
213
|
+
1. **`finally` block** — normal path after agent exits
|
|
214
|
+
2. **`atexit` handler** — runs on `sys.exit()`, unhandled exceptions, and `SIGTERM`
|
|
215
|
+
3. **`kitty cleanup`** — manual fallback for `SIGKILL` or kernel OOM
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Manually restore stale agent config
|
|
219
|
+
kitty cleanup
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Architecture
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
src/kitty/
|
|
226
|
+
├── bridge/ # HTTP bridge server + protocol translation
|
|
227
|
+
│ ├── server.py # aiohttp-based bridge with round-robin balancing
|
|
228
|
+
│ ├── engine.py # Shared translation primitives
|
|
229
|
+
│ ├── responses/ # Responses API translation (Codex)
|
|
230
|
+
│ ├── messages/ # Messages API translation (Claude Code)
|
|
231
|
+
│ └── gemini/ # Gemini API translation
|
|
232
|
+
├── cli/ # Command-line interface
|
|
233
|
+
│ ├── main.py # Entry point
|
|
234
|
+
│ ├── router.py # Argument routing
|
|
235
|
+
│ ├── launcher.py # Bridge + child process orchestration
|
|
236
|
+
│ ├── doctor_cmd.py
|
|
237
|
+
│ ├── setup_cmd.py
|
|
238
|
+
│ └── profile_cmd.py
|
|
239
|
+
├── credentials/ # API key storage (file backend)
|
|
240
|
+
├── launchers/ # Agent-specific adapters
|
|
241
|
+
│ ├── claude.py # Claude Code adapter (env vars + settings.json)
|
|
242
|
+
│ ├── codex.py # Codex CLI adapter
|
|
243
|
+
│ ├── gemini.py # Gemini CLI adapter
|
|
244
|
+
│ ├── kilo.py # Kilo Code adapter
|
|
245
|
+
│ └── discovery.py # Binary discovery (PATH + fallbacks)
|
|
246
|
+
├── profiles/ # Profile management
|
|
247
|
+
│ ├── schema.py # Profile, BalancingProfile, BackendConfig
|
|
248
|
+
│ ├── store.py # JSON persistence with type discriminator
|
|
249
|
+
│ └── resolver.py # Profile lookup and default resolution
|
|
250
|
+
├── providers/ # Upstream provider adapters
|
|
251
|
+
├── tui/ # Terminal UI components
|
|
252
|
+
└── types.py # Shared types
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Development
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Install with dev dependencies
|
|
259
|
+
pip install -e ".[dev]"
|
|
260
|
+
|
|
261
|
+
# Run tests
|
|
262
|
+
pytest
|
|
263
|
+
|
|
264
|
+
# Lint
|
|
265
|
+
ruff check .
|
|
266
|
+
|
|
267
|
+
# Type check
|
|
268
|
+
mypy src/kitty
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## FAQ
|
|
272
|
+
|
|
273
|
+
### "API Error: Unable to connect to API (ConnectionRefused)"
|
|
274
|
+
|
|
275
|
+
The coding agent is trying to connect to a bridge server that isn't running. Two common causes:
|
|
276
|
+
|
|
277
|
+
**Stale config from a crashed session.** If kitty was killed with `SIGKILL`, the agent's config file may still contain stale values. Fix:
|
|
278
|
+
```bash
|
|
279
|
+
kitty cleanup
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Running the agent directly without kitty.** Always launch through kitty, or run `kitty cleanup` first.
|
|
283
|
+
|
|
284
|
+
### "API Error: 401" or "token expired or incorrect"
|
|
285
|
+
|
|
286
|
+
Your API key has expired or been revoked:
|
|
287
|
+
```bash
|
|
288
|
+
kitty setup
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### "Prompt exceeds max length" (Z.AI error 1261)
|
|
292
|
+
|
|
293
|
+
The conversation context has grown beyond the model's context window. Use `/clear` in the agent to reset the conversation.
|
|
294
|
+
|
|
295
|
+
### "pip's dependency resolver ... langchain/langchain-core requires langsmith<0.4, but you have langsmith 0.4.x"
|
|
296
|
+
|
|
297
|
+
`kitty-bridge` does not depend on `langsmith`. This warning means your current Python environment already has a `langchain 0.3.x` stack that is incompatible with the installed `langsmith` version.
|
|
298
|
+
|
|
299
|
+
If you are staying on `langchain 0.3.x`, repair the environment first:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
python -m pip check
|
|
303
|
+
python -m pip install --upgrade "langsmith<0.4"
|
|
304
|
+
python -m pip check
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Then install kitty again:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
python -m pip install -e .
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Using a fresh virtual environment per project avoids this class of cross-project dependency conflict.
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT
|