router-maestro 0.1.6__py3-none-any.whl → 0.1.7__py3-none-any.whl
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.
- router_maestro/__init__.py +1 -1
- router_maestro/cli/config.py +126 -0
- router_maestro/providers/__init__.py +8 -0
- router_maestro/providers/base.py +80 -0
- router_maestro/providers/copilot.py +322 -1
- router_maestro/routing/router.py +158 -2
- router_maestro/server/app.py +8 -1
- router_maestro/server/routes/__init__.py +8 -1
- router_maestro/server/routes/anthropic.py +79 -0
- router_maestro/server/routes/chat.py +1 -2
- router_maestro/server/routes/models.py +1 -2
- router_maestro/server/routes/responses.py +517 -0
- router_maestro/server/schemas/__init__.py +33 -0
- router_maestro/server/schemas/responses.py +214 -0
- {router_maestro-0.1.6.dist-info → router_maestro-0.1.7.dist-info}/METADATA +24 -3
- {router_maestro-0.1.6.dist-info → router_maestro-0.1.7.dist-info}/RECORD +19 -17
- {router_maestro-0.1.6.dist-info → router_maestro-0.1.7.dist-info}/WHEEL +0 -0
- {router_maestro-0.1.6.dist-info → router_maestro-0.1.7.dist-info}/entry_points.txt +0 -0
- {router_maestro-0.1.6.dist-info → router_maestro-0.1.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""OpenAI Responses API schemas for Codex models."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
# ============================================================================
|
|
8
|
+
# Input Types
|
|
9
|
+
# ============================================================================
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ResponsesInputTextContent(BaseModel):
|
|
13
|
+
"""Text content block in input message."""
|
|
14
|
+
|
|
15
|
+
type: str = "input_text"
|
|
16
|
+
text: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ResponsesInputMessage(BaseModel):
|
|
20
|
+
"""An input message for the Responses API.
|
|
21
|
+
|
|
22
|
+
Supports both simple string content and array of content blocks.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
type: str = "message"
|
|
26
|
+
role: str
|
|
27
|
+
content: str | list[ResponsesInputTextContent | dict[str, Any]]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ResponsesFunctionCallInput(BaseModel):
|
|
31
|
+
"""A function call from a previous assistant response."""
|
|
32
|
+
|
|
33
|
+
type: str = "function_call"
|
|
34
|
+
id: str | None = None
|
|
35
|
+
call_id: str
|
|
36
|
+
name: str
|
|
37
|
+
arguments: str
|
|
38
|
+
status: str = "completed"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ResponsesFunctionCallOutput(BaseModel):
|
|
42
|
+
"""Output/result from a function call execution."""
|
|
43
|
+
|
|
44
|
+
type: str = "function_call_output"
|
|
45
|
+
call_id: str
|
|
46
|
+
output: str
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ============================================================================
|
|
50
|
+
# Tool Definitions
|
|
51
|
+
# ============================================================================
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ResponsesFunctionParameters(BaseModel):
|
|
55
|
+
"""JSON Schema for function parameters."""
|
|
56
|
+
|
|
57
|
+
type: str = "object"
|
|
58
|
+
properties: dict[str, Any] = Field(default_factory=dict)
|
|
59
|
+
required: list[str] = Field(default_factory=list)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ResponsesFunctionTool(BaseModel):
|
|
63
|
+
"""A function tool definition."""
|
|
64
|
+
|
|
65
|
+
type: str = "function"
|
|
66
|
+
name: str
|
|
67
|
+
description: str | None = None
|
|
68
|
+
parameters: dict[str, Any] | None = None
|
|
69
|
+
strict: bool | None = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ResponsesToolChoiceFunction(BaseModel):
|
|
73
|
+
"""Specific function tool choice."""
|
|
74
|
+
|
|
75
|
+
type: str = "function"
|
|
76
|
+
name: str
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# ============================================================================
|
|
80
|
+
# Request
|
|
81
|
+
# ============================================================================
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ResponsesRequest(BaseModel):
|
|
85
|
+
"""Request for the Responses API (used by Codex models).
|
|
86
|
+
|
|
87
|
+
The input can be:
|
|
88
|
+
- A simple string prompt
|
|
89
|
+
- A list of message objects with role and content
|
|
90
|
+
- A list including function_call and function_call_output items
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
model: str
|
|
94
|
+
input: (
|
|
95
|
+
str
|
|
96
|
+
| list[
|
|
97
|
+
ResponsesInputMessage
|
|
98
|
+
| ResponsesFunctionCallInput
|
|
99
|
+
| ResponsesFunctionCallOutput
|
|
100
|
+
| dict[str, Any]
|
|
101
|
+
]
|
|
102
|
+
)
|
|
103
|
+
stream: bool = False
|
|
104
|
+
instructions: str | None = None
|
|
105
|
+
temperature: float = Field(default=1.0, ge=0, le=2)
|
|
106
|
+
max_output_tokens: int | None = None
|
|
107
|
+
# Tool support
|
|
108
|
+
tools: list[ResponsesFunctionTool | dict[str, Any]] | None = None
|
|
109
|
+
tool_choice: str | ResponsesToolChoiceFunction | dict[str, Any] | None = None
|
|
110
|
+
parallel_tool_calls: bool | None = None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# ============================================================================
|
|
114
|
+
# Output Types
|
|
115
|
+
# ============================================================================
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ResponsesOutputText(BaseModel):
|
|
119
|
+
"""Text content in the response output."""
|
|
120
|
+
|
|
121
|
+
type: str = "output_text"
|
|
122
|
+
text: str
|
|
123
|
+
annotations: list[Any] = Field(default_factory=list)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ResponsesMessageOutput(BaseModel):
|
|
127
|
+
"""A message output in the response."""
|
|
128
|
+
|
|
129
|
+
type: str = "message"
|
|
130
|
+
id: str
|
|
131
|
+
role: str = "assistant"
|
|
132
|
+
status: str = "completed"
|
|
133
|
+
content: list[ResponsesOutputText]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ResponsesFunctionCallOutput(BaseModel):
|
|
137
|
+
"""A function call output in the response."""
|
|
138
|
+
|
|
139
|
+
type: str = "function_call"
|
|
140
|
+
id: str
|
|
141
|
+
call_id: str
|
|
142
|
+
name: str
|
|
143
|
+
arguments: str
|
|
144
|
+
status: str = "completed"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ResponsesReasoningOutput(BaseModel):
|
|
148
|
+
"""A reasoning output in the response."""
|
|
149
|
+
|
|
150
|
+
type: str = "reasoning"
|
|
151
|
+
id: str
|
|
152
|
+
summary: list[dict[str, Any]] = Field(default_factory=list)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class ResponsesUsage(BaseModel):
|
|
156
|
+
"""Token usage information for Responses API."""
|
|
157
|
+
|
|
158
|
+
input_tokens: int
|
|
159
|
+
output_tokens: int
|
|
160
|
+
total_tokens: int
|
|
161
|
+
input_tokens_details: dict[str, int] | None = None
|
|
162
|
+
output_tokens_details: dict[str, int] | None = None
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# ============================================================================
|
|
166
|
+
# Response
|
|
167
|
+
# ============================================================================
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class ResponsesResponse(BaseModel):
|
|
171
|
+
"""Response from the Responses API."""
|
|
172
|
+
|
|
173
|
+
id: str
|
|
174
|
+
object: str = "response"
|
|
175
|
+
model: str
|
|
176
|
+
status: str = "completed"
|
|
177
|
+
output: list[
|
|
178
|
+
ResponsesReasoningOutput
|
|
179
|
+
| ResponsesMessageOutput
|
|
180
|
+
| ResponsesFunctionCallOutput
|
|
181
|
+
| dict[str, Any]
|
|
182
|
+
]
|
|
183
|
+
usage: ResponsesUsage | None = None
|
|
184
|
+
error: dict[str, Any] | None = None
|
|
185
|
+
incomplete_details: dict[str, Any] | None = None
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
# ============================================================================
|
|
189
|
+
# Streaming Events
|
|
190
|
+
# ============================================================================
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class ResponsesStreamEvent(BaseModel):
|
|
194
|
+
"""A streaming event from the Responses API."""
|
|
195
|
+
|
|
196
|
+
type: str
|
|
197
|
+
# Additional fields depend on event type
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class ResponsesDeltaEvent(BaseModel):
|
|
201
|
+
"""A delta event in streaming response."""
|
|
202
|
+
|
|
203
|
+
type: str = "response.output_text.delta"
|
|
204
|
+
item_id: str
|
|
205
|
+
output_index: int
|
|
206
|
+
content_index: int
|
|
207
|
+
delta: str
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class ResponsesDoneEvent(BaseModel):
|
|
211
|
+
"""A done event in streaming response."""
|
|
212
|
+
|
|
213
|
+
type: str = "response.done"
|
|
214
|
+
response: ResponsesResponse
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: router-maestro
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: Multi-model routing and load balancing system with OpenAI-compatible API
|
|
5
5
|
Author-email: Kanwen Li <likanwen@icloud.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pydantic>=2.5.0
|
|
|
26
26
|
Requires-Dist: python-dotenv>=1.0.0
|
|
27
27
|
Requires-Dist: rich>=13.7.0
|
|
28
28
|
Requires-Dist: tiktoken>=0.5.0
|
|
29
|
+
Requires-Dist: tomlkit>=0.12.0
|
|
29
30
|
Requires-Dist: typer>=0.12.0
|
|
30
31
|
Requires-Dist: uvicorn>=0.27.0
|
|
31
32
|
Provides-Extra: dev
|
|
@@ -118,14 +119,33 @@ router-maestro auth login github-copilot
|
|
|
118
119
|
# 3. Authorize "GitHub Copilot Chat"
|
|
119
120
|
```
|
|
120
121
|
|
|
121
|
-
### 4. Configure
|
|
122
|
+
### 4. Configure Your CLI Tool
|
|
123
|
+
|
|
124
|
+
#### Claude Code
|
|
122
125
|
|
|
123
126
|
```bash
|
|
124
127
|
router-maestro config claude-code
|
|
125
128
|
# Follow the wizard to select models
|
|
126
129
|
```
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
#### OpenAI Codex (CLI, Extension, App)
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
router-maestro config codex
|
|
135
|
+
# Follow the wizard to select models
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
After configuration, set the API key environment variable:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Get your API key
|
|
142
|
+
router-maestro server show-key
|
|
143
|
+
|
|
144
|
+
# Set the environment variable (add to your shell profile)
|
|
145
|
+
export ROUTER_MAESTRO_API_KEY="your-api-key-here"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Done!** Now run `claude` or `codex` and your requests will route through Router-Maestro.
|
|
129
149
|
|
|
130
150
|
> **For production deployment**, see the [Deployment](#deployment) section.
|
|
131
151
|
|
|
@@ -258,6 +278,7 @@ router-maestro model list
|
|
|
258
278
|
| Command | Description |
|
|
259
279
|
| -------------------- | ----------------------------- |
|
|
260
280
|
| `config claude-code` | Generate Claude Code settings |
|
|
281
|
+
| `config codex` | Generate Codex config (CLI/Extension/App) |
|
|
261
282
|
|
|
262
283
|
## API Reference
|
|
263
284
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
router_maestro/__init__.py,sha256=
|
|
1
|
+
router_maestro/__init__.py,sha256=fhbALhHgLCddTisEcBMbNKolBeLpN0d7DdpFObDkDx4,92
|
|
2
2
|
router_maestro/__main__.py,sha256=cUHr8B7JBiv5HhnN6l2iayDkGSBpI5Kf4I3jv9I_I3o,121
|
|
3
3
|
router_maestro/auth/__init__.py,sha256=0JgD1w2gtGSkj809kgSKQanYYkncg6eF-hHoz-jQPgo,353
|
|
4
4
|
router_maestro/auth/github_oauth.py,sha256=acQlAA2Zh6c8KQYdzXbC4ww0EJ41AgvbI5ixpFuNoRg,5060
|
|
@@ -7,7 +7,7 @@ router_maestro/auth/storage.py,sha256=TCLxgQ1lWcWD4xJXJzx5OMpvuAun_LSRItK0zhR6H0
|
|
|
7
7
|
router_maestro/cli/__init__.py,sha256=yIAshaHpLL0WrDFmRpoMRM2EUe75x0wmM5NlGW3C89s,37
|
|
8
8
|
router_maestro/cli/auth.py,sha256=eq5LBUohbMnHS4dZeyvq4OQAjzdrJ-StP2FGuUhkKa0,5940
|
|
9
9
|
router_maestro/cli/client.py,sha256=mRzpsA_Dxn-Xq7W1_t6EiyddMI0a3cvuTL6-2JuV4mE,9383
|
|
10
|
-
router_maestro/cli/config.py,sha256=
|
|
10
|
+
router_maestro/cli/config.py,sha256=5r3r8_VH18C0zEYpRDV4ZslbtJ9HfKWUMzKXcwtNU0M,10734
|
|
11
11
|
router_maestro/cli/context.py,sha256=EPbT7fReIW17veU76CSAcv8QjzMsCIPm1QDBlGsV8fQ,4549
|
|
12
12
|
router_maestro/cli/main.py,sha256=5yiK4Q149goSB2KKzgMuF5EpcC8FBzOUCkEt8wY5NAU,1314
|
|
13
13
|
router_maestro/cli/model.py,sha256=2IG3IpQWh8Ejdv5Htcgr90O2v2UAa80TU15oOniPdvk,9054
|
|
@@ -19,34 +19,36 @@ router_maestro/config/priorities.py,sha256=wEBs6CmLQiw0ehuA-kh7topyac6APopxaR83C
|
|
|
19
19
|
router_maestro/config/providers.py,sha256=yMU_DFh4_eQXMT8jGImqwzAPHp0L3fR34gG2r-4Zhnw,1158
|
|
20
20
|
router_maestro/config/server.py,sha256=Mr7Axbo8b1z3OFEe_G8VuO7wvx_pA32-ZBbT4nSRdX0,3049
|
|
21
21
|
router_maestro/config/settings.py,sha256=cEgE0XjdYMbB39wJDQiTurWSbfJwjAjLI8g7ZOiyd1o,2363
|
|
22
|
-
router_maestro/providers/__init__.py,sha256=
|
|
22
|
+
router_maestro/providers/__init__.py,sha256=ozZMBw5SPoUd8OoTaLWX7ddlxz6hHMlMpsJXf3D9g8g,955
|
|
23
23
|
router_maestro/providers/anthropic.py,sha256=zhBDtPootCVCYfGyrsogdy3j8jC1aMwi01hWkg-uKmA,8077
|
|
24
|
-
router_maestro/providers/base.py,sha256=
|
|
25
|
-
router_maestro/providers/copilot.py,sha256=
|
|
24
|
+
router_maestro/providers/base.py,sha256=YeejIPYXPv00fbup5ahuYvL362rXw2yn4RHY5TElCw0,5367
|
|
25
|
+
router_maestro/providers/copilot.py,sha256=UuFL8v9f_xxQ9rYSvsbp8n6dR6q7Dd4tl4E4bBeXxeg,26476
|
|
26
26
|
router_maestro/providers/openai.py,sha256=Bsq5mzAVf4CawH2Tn80y3-MyLLVeZ3VsPxGDNH1t_Nk,7647
|
|
27
27
|
router_maestro/providers/openai_compat.py,sha256=ef4RttKVZUTBiRed4BEuC2Jg8vr5GM7YqPUtFYeAhZo,6383
|
|
28
28
|
router_maestro/routing/__init__.py,sha256=eCEQVbg1LAfcSVLQZpZtYf8ImbOhFIaR7POUb1pCbXM,169
|
|
29
|
-
router_maestro/routing/router.py,sha256=
|
|
29
|
+
router_maestro/routing/router.py,sha256=gi1Zy7Eo5SasdY4tpkXj5X3bFZ3UR4Efc-RW0Xq_YpA,26617
|
|
30
30
|
router_maestro/server/__init__.py,sha256=YzExJfP0jw6hXx84lo0yPVU0wG17B16SfdyEpjstpxk,128
|
|
31
|
-
router_maestro/server/app.py,sha256=
|
|
31
|
+
router_maestro/server/app.py,sha256=SIYdqlA93QzHDZuicG4-cXwkjelteeeyfe04iZUIkn8,2831
|
|
32
32
|
router_maestro/server/oauth_sessions.py,sha256=r_VM6vAtbo5HAmXjYt6XoECBcWGxqABKGbVmW8HoCz0,4625
|
|
33
33
|
router_maestro/server/translation.py,sha256=TrYfIb5M5MAUC4TD5By8X3RONSZ6cV1YS_JwzIc-bVk,22170
|
|
34
34
|
router_maestro/server/middleware/__init__.py,sha256=PhtP2E04wApnOUBLE76mrOa0sSHp7reHmIl7PaCAylY,187
|
|
35
35
|
router_maestro/server/middleware/auth.py,sha256=Ak3k5cC8m4qPGUIheuOB--QiFvs6GIAcTRJqtCGCjAA,2018
|
|
36
|
-
router_maestro/server/routes/__init__.py,sha256=
|
|
36
|
+
router_maestro/server/routes/__init__.py,sha256=5gOgr_rSX_YtSwAxSW1RfC1kLyHOu9SIaWdkTvLo1MU,518
|
|
37
37
|
router_maestro/server/routes/admin.py,sha256=oub4hDrYaytuorXkJzmz0YZ4Z2rcyNuwKcK_4IGvcDY,8942
|
|
38
|
-
router_maestro/server/routes/anthropic.py,sha256=
|
|
39
|
-
router_maestro/server/routes/chat.py,sha256=
|
|
40
|
-
router_maestro/server/routes/models.py,sha256=
|
|
41
|
-
router_maestro/server/
|
|
38
|
+
router_maestro/server/routes/anthropic.py,sha256=vzbgnYNYt5mOCeZgarSZ6jiIr_d9v64BPtIjIquz6Ew,13287
|
|
39
|
+
router_maestro/server/routes/chat.py,sha256=nXeZVXaJl9BsU3OMs1OW6vFV5PRHOjylyOitM2dXpFM,4729
|
|
40
|
+
router_maestro/server/routes/models.py,sha256=SYHwaMCLrz3F-9fIpPAFjmS_wil5DQIPtzqHV_rimfc,704
|
|
41
|
+
router_maestro/server/routes/responses.py,sha256=bftEW7_osQEeo15kuwrmNb4Q2btUOPd1Q-GFCLHR4Po,17672
|
|
42
|
+
router_maestro/server/schemas/__init__.py,sha256=VQqkyEhoRuXJxPs87rMT6rrfupxcY_qBSbU-7t6ZdZQ,2102
|
|
42
43
|
router_maestro/server/schemas/admin.py,sha256=DuUojkCcq9n8pDhWG6L0SpzQooh91lmHjCRzgZ4AMwk,2369
|
|
43
44
|
router_maestro/server/schemas/anthropic.py,sha256=S5TFYDd8Iw7Oxjki6ng84DGVB90G0-mOza5D5r3rwOY,6566
|
|
44
45
|
router_maestro/server/schemas/openai.py,sha256=s2487RYIn1h-CIaUpLue9BScDaTsafbVg5yc-kKhfME,2141
|
|
46
|
+
router_maestro/server/schemas/responses.py,sha256=v6AqmgE4OVz8Funu2e-SIP52eIJlRW1naudCqZ0SJIU,5538
|
|
45
47
|
router_maestro/utils/__init__.py,sha256=oSQyV--FueMPggRfjWWVnAKtjkcZWFOm9hCTymu0oZU,409
|
|
46
48
|
router_maestro/utils/logging.py,sha256=gJWoRYibAxCWn4VmTmnrwpBRzQ7Uu5YIEk5zDiF9X_k,2393
|
|
47
49
|
router_maestro/utils/tokens.py,sha256=U5PXJv_6ba5xgMBG0c5qB96Yu6uLscSUjMWYTdNests,1530
|
|
48
|
-
router_maestro-0.1.
|
|
49
|
-
router_maestro-0.1.
|
|
50
|
-
router_maestro-0.1.
|
|
51
|
-
router_maestro-0.1.
|
|
52
|
-
router_maestro-0.1.
|
|
50
|
+
router_maestro-0.1.7.dist-info/METADATA,sha256=FwyXaFWxGcDSrAkDDyEamj_p2EnEEk88zYG8erWAd_0,12984
|
|
51
|
+
router_maestro-0.1.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
52
|
+
router_maestro-0.1.7.dist-info/entry_points.txt,sha256=zoFUxxvNcFe0nTgpRbIdygIDEOla3KbvW6HbOCOlgv4,63
|
|
53
|
+
router_maestro-0.1.7.dist-info/licenses/LICENSE,sha256=Ea86BSGu7_tpLAuzif_JmM9zjMoKQEf95VVF9sZw3Jo,1084
|
|
54
|
+
router_maestro-0.1.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|