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.
Files changed (147) hide show
  1. kitty_bridge-0.1.5/.github/workflows/ci.yml +27 -0
  2. kitty_bridge-0.1.5/.github/workflows/publish.yml +50 -0
  3. kitty_bridge-0.1.5/.gitignore +13 -0
  4. kitty_bridge-0.1.5/LICENSE +21 -0
  5. kitty_bridge-0.1.5/PKG-INFO +317 -0
  6. kitty_bridge-0.1.5/README.md +276 -0
  7. kitty_bridge-0.1.5/pyproject.toml +124 -0
  8. kitty_bridge-0.1.5/src/kitty/__init__.py +4 -0
  9. kitty_bridge-0.1.5/src/kitty/__main__.py +6 -0
  10. kitty_bridge-0.1.5/src/kitty/bridge/__init__.py +5 -0
  11. kitty_bridge-0.1.5/src/kitty/bridge/config.py +108 -0
  12. kitty_bridge-0.1.5/src/kitty/bridge/engine.py +126 -0
  13. kitty_bridge-0.1.5/src/kitty/bridge/gemini/__init__.py +1 -0
  14. kitty_bridge-0.1.5/src/kitty/bridge/gemini/events.py +19 -0
  15. kitty_bridge-0.1.5/src/kitty/bridge/gemini/translator.py +310 -0
  16. kitty_bridge-0.1.5/src/kitty/bridge/keys.py +74 -0
  17. kitty_bridge-0.1.5/src/kitty/bridge/manage.py +179 -0
  18. kitty_bridge-0.1.5/src/kitty/bridge/messages/__init__.py +1 -0
  19. kitty_bridge-0.1.5/src/kitty/bridge/messages/events.py +94 -0
  20. kitty_bridge-0.1.5/src/kitty/bridge/messages/translator.py +453 -0
  21. kitty_bridge-0.1.5/src/kitty/bridge/responses/__init__.py +1 -0
  22. kitty_bridge-0.1.5/src/kitty/bridge/responses/events.py +251 -0
  23. kitty_bridge-0.1.5/src/kitty/bridge/responses/translator.py +653 -0
  24. kitty_bridge-0.1.5/src/kitty/bridge/server.py +1592 -0
  25. kitty_bridge-0.1.5/src/kitty/bridge/service.py +135 -0
  26. kitty_bridge-0.1.5/src/kitty/bridge/state.py +65 -0
  27. kitty_bridge-0.1.5/src/kitty/bridge_runner.py +164 -0
  28. kitty_bridge-0.1.5/src/kitty/cli/__init__.py +0 -0
  29. kitty_bridge-0.1.5/src/kitty/cli/cleanup_cmd.py +99 -0
  30. kitty_bridge-0.1.5/src/kitty/cli/doctor_cmd.py +148 -0
  31. kitty_bridge-0.1.5/src/kitty/cli/launcher.py +341 -0
  32. kitty_bridge-0.1.5/src/kitty/cli/main.py +534 -0
  33. kitty_bridge-0.1.5/src/kitty/cli/profile_cmd.py +296 -0
  34. kitty_bridge-0.1.5/src/kitty/cli/router.py +142 -0
  35. kitty_bridge-0.1.5/src/kitty/cli/setup_cmd.py +156 -0
  36. kitty_bridge-0.1.5/src/kitty/credentials/__init__.py +13 -0
  37. kitty_bridge-0.1.5/src/kitty/credentials/file_backend.py +102 -0
  38. kitty_bridge-0.1.5/src/kitty/credentials/keyring_backend.py +36 -0
  39. kitty_bridge-0.1.5/src/kitty/credentials/store.py +67 -0
  40. kitty_bridge-0.1.5/src/kitty/launchers/__init__.py +5 -0
  41. kitty_bridge-0.1.5/src/kitty/launchers/base.py +61 -0
  42. kitty_bridge-0.1.5/src/kitty/launchers/claude.py +206 -0
  43. kitty_bridge-0.1.5/src/kitty/launchers/codex.py +50 -0
  44. kitty_bridge-0.1.5/src/kitty/launchers/discovery.py +139 -0
  45. kitty_bridge-0.1.5/src/kitty/launchers/gemini.py +41 -0
  46. kitty_bridge-0.1.5/src/kitty/launchers/kilo.py +176 -0
  47. kitty_bridge-0.1.5/src/kitty/profiles/__init__.py +6 -0
  48. kitty_bridge-0.1.5/src/kitty/profiles/resolver.py +93 -0
  49. kitty_bridge-0.1.5/src/kitty/profiles/schema.py +116 -0
  50. kitty_bridge-0.1.5/src/kitty/profiles/store.py +162 -0
  51. kitty_bridge-0.1.5/src/kitty/providers/__init__.py +33 -0
  52. kitty_bridge-0.1.5/src/kitty/providers/anthropic.py +347 -0
  53. kitty_bridge-0.1.5/src/kitty/providers/azure.py +145 -0
  54. kitty_bridge-0.1.5/src/kitty/providers/base.py +217 -0
  55. kitty_bridge-0.1.5/src/kitty/providers/bedrock.py +452 -0
  56. kitty_bridge-0.1.5/src/kitty/providers/fireworks.py +79 -0
  57. kitty_bridge-0.1.5/src/kitty/providers/minimax.py +74 -0
  58. kitty_bridge-0.1.5/src/kitty/providers/novita.py +58 -0
  59. kitty_bridge-0.1.5/src/kitty/providers/ollama.py +190 -0
  60. kitty_bridge-0.1.5/src/kitty/providers/openai.py +54 -0
  61. kitty_bridge-0.1.5/src/kitty/providers/openrouter.py +55 -0
  62. kitty_bridge-0.1.5/src/kitty/providers/registry.py +52 -0
  63. kitty_bridge-0.1.5/src/kitty/providers/vertex.py +171 -0
  64. kitty_bridge-0.1.5/src/kitty/providers/zai.py +76 -0
  65. kitty_bridge-0.1.5/src/kitty/tui/__init__.py +0 -0
  66. kitty_bridge-0.1.5/src/kitty/tui/display.py +78 -0
  67. kitty_bridge-0.1.5/src/kitty/tui/menu.py +58 -0
  68. kitty_bridge-0.1.5/src/kitty/tui/prompts.py +68 -0
  69. kitty_bridge-0.1.5/src/kitty/types.py +12 -0
  70. kitty_bridge-0.1.5/src/kitty/validation.py +136 -0
  71. kitty_bridge-0.1.5/tests/bridge/__init__.py +0 -0
  72. kitty_bridge-0.1.5/tests/bridge/test_access_logging.py +144 -0
  73. kitty_bridge-0.1.5/tests/bridge/test_all_protocol_routing.py +219 -0
  74. kitty_bridge-0.1.5/tests/bridge/test_api_key_auth.py +225 -0
  75. kitty_bridge-0.1.5/tests/bridge/test_balancing_server.py +271 -0
  76. kitty_bridge-0.1.5/tests/bridge/test_bridge_config.py +166 -0
  77. kitty_bridge-0.1.5/tests/bridge/test_bridge_engine.py +166 -0
  78. kitty_bridge-0.1.5/tests/bridge/test_bridge_management.py +225 -0
  79. kitty_bridge-0.1.5/tests/bridge/test_bridge_server.py +696 -0
  80. kitty_bridge-0.1.5/tests/bridge/test_bridge_server_anthropic.py +113 -0
  81. kitty_bridge-0.1.5/tests/bridge/test_bridge_server_bedrock.py +102 -0
  82. kitty_bridge-0.1.5/tests/bridge/test_bridge_server_claude_e2e.py +1258 -0
  83. kitty_bridge-0.1.5/tests/bridge/test_bridge_server_kilo.py +278 -0
  84. kitty_bridge-0.1.5/tests/bridge/test_bridge_state.py +152 -0
  85. kitty_bridge-0.1.5/tests/bridge/test_circuit_breaker.py +323 -0
  86. kitty_bridge-0.1.5/tests/bridge/test_connection_retries.py +521 -0
  87. kitty_bridge-0.1.5/tests/bridge/test_host_port_config.py +99 -0
  88. kitty_bridge-0.1.5/tests/bridge/test_messages_events.py +184 -0
  89. kitty_bridge-0.1.5/tests/bridge/test_messages_translator.py +555 -0
  90. kitty_bridge-0.1.5/tests/bridge/test_responses_events.py +266 -0
  91. kitty_bridge-0.1.5/tests/bridge/test_responses_translator.py +993 -0
  92. kitty_bridge-0.1.5/tests/bridge/test_service_install.py +118 -0
  93. kitty_bridge-0.1.5/tests/bridge/test_sse_line_buffering.py +143 -0
  94. kitty_bridge-0.1.5/tests/bridge/test_streaming_hang_fixes.py +585 -0
  95. kitty_bridge-0.1.5/tests/bridge/test_tls_support.py +123 -0
  96. kitty_bridge-0.1.5/tests/bridge/test_upstream_error_translation.py +246 -0
  97. kitty_bridge-0.1.5/tests/cli/__init__.py +0 -0
  98. kitty_bridge-0.1.5/tests/cli/test_cleanup_cmd.py +129 -0
  99. kitty_bridge-0.1.5/tests/conftest.py +74 -0
  100. kitty_bridge-0.1.5/tests/integration/__init__.py +0 -0
  101. kitty_bridge-0.1.5/tests/integration/test_agent_e2e.py +227 -0
  102. kitty_bridge-0.1.5/tests/test_balancing_resolver.py +147 -0
  103. kitty_bridge-0.1.5/tests/test_balancing_schema.py +92 -0
  104. kitty_bridge-0.1.5/tests/test_balancing_store.py +167 -0
  105. kitty_bridge-0.1.5/tests/test_bridge_mode.py +210 -0
  106. kitty_bridge-0.1.5/tests/test_claude_settings_api_key.py +193 -0
  107. kitty_bridge-0.1.5/tests/test_claude_settings_override.py +179 -0
  108. kitty_bridge-0.1.5/tests/test_cli_main.py +120 -0
  109. kitty_bridge-0.1.5/tests/test_cli_router.py +271 -0
  110. kitty_bridge-0.1.5/tests/test_credential_store.py +137 -0
  111. kitty_bridge-0.1.5/tests/test_doctor_cmd.py +133 -0
  112. kitty_bridge-0.1.5/tests/test_exit_code_mapping.py +45 -0
  113. kitty_bridge-0.1.5/tests/test_gemini_protocol.py +71 -0
  114. kitty_bridge-0.1.5/tests/test_gemini_translator.py +358 -0
  115. kitty_bridge-0.1.5/tests/test_github_actions.py +203 -0
  116. kitty_bridge-0.1.5/tests/test_integration.py +199 -0
  117. kitty_bridge-0.1.5/tests/test_kilo_config.py +145 -0
  118. kitty_bridge-0.1.5/tests/test_kilo_protocol.py +115 -0
  119. kitty_bridge-0.1.5/tests/test_launch_orchestrator.py +263 -0
  120. kitty_bridge-0.1.5/tests/test_launcher_base.py +70 -0
  121. kitty_bridge-0.1.5/tests/test_launcher_claude.py +90 -0
  122. kitty_bridge-0.1.5/tests/test_launcher_codex.py +79 -0
  123. kitty_bridge-0.1.5/tests/test_launcher_discovery.py +152 -0
  124. kitty_bridge-0.1.5/tests/test_profile_resolver.py +115 -0
  125. kitty_bridge-0.1.5/tests/test_profile_schema.py +254 -0
  126. kitty_bridge-0.1.5/tests/test_profile_store.py +148 -0
  127. kitty_bridge-0.1.5/tests/test_provider_anthropic.py +450 -0
  128. kitty_bridge-0.1.5/tests/test_provider_azure.py +296 -0
  129. kitty_bridge-0.1.5/tests/test_provider_base.py +135 -0
  130. kitty_bridge-0.1.5/tests/test_provider_bedrock.py +584 -0
  131. kitty_bridge-0.1.5/tests/test_provider_fireworks.py +212 -0
  132. kitty_bridge-0.1.5/tests/test_provider_list_sync.py +65 -0
  133. kitty_bridge-0.1.5/tests/test_provider_minimax.py +123 -0
  134. kitty_bridge-0.1.5/tests/test_provider_novita.py +99 -0
  135. kitty_bridge-0.1.5/tests/test_provider_ollama.py +171 -0
  136. kitty_bridge-0.1.5/tests/test_provider_openai.py +162 -0
  137. kitty_bridge-0.1.5/tests/test_provider_openrouter.py +136 -0
  138. kitty_bridge-0.1.5/tests/test_provider_registry.py +75 -0
  139. kitty_bridge-0.1.5/tests/test_provider_vertex.py +385 -0
  140. kitty_bridge-0.1.5/tests/test_provider_zai.py +212 -0
  141. kitty_bridge-0.1.5/tests/test_pypi_packaging.py +253 -0
  142. kitty_bridge-0.1.5/tests/test_validation.py +179 -0
  143. kitty_bridge-0.1.5/tests/tui/test_display.py +170 -0
  144. kitty_bridge-0.1.5/tests/tui/test_menu.py +95 -0
  145. kitty_bridge-0.1.5/tests/tui/test_profile_menu.py +93 -0
  146. kitty_bridge-0.1.5/tests/tui/test_prompts.py +112 -0
  147. 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,13 @@
1
+ /.claude/
2
+ /.import_linter_cache/
3
+ /.requirements/
4
+ /.serena/
5
+ /.system_design/
6
+ /.venv/
7
+ /debug/
8
+ /.codex
9
+ /build/
10
+ /dist/
11
+ *.egg-info/
12
+ *.whl
13
+ *.tar.gz
@@ -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