codexloop 0.1.0__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.
- codexloop/__init__.py +3 -0
- codexloop/application/__init__.py +1 -0
- codexloop/application/dto.py +41 -0
- codexloop/application/ports.py +158 -0
- codexloop/application/runner.py +467 -0
- codexloop/application/usecases/__init__.py +1 -0
- codexloop/application/usecases/doctor.py +37 -0
- codexloop/application/usecases/list_threads.py +14 -0
- codexloop/application/usecases/preflight.py +10 -0
- codexloop/application/usecases/resume_thread.py +11 -0
- codexloop/application/usecases/run_control.py +20 -0
- codexloop/application/usecases/run_plan.py +11 -0
- codexloop/bootstrap.py +461 -0
- codexloop/cli/__init__.py +1 -0
- codexloop/cli/app.py +94 -0
- codexloop/cli/asyncio.py +80 -0
- codexloop/cli/commands/__init__.py +1 -0
- codexloop/cli/commands/approval_cmd.py +24 -0
- codexloop/cli/commands/capacity.py +33 -0
- codexloop/cli/commands/cwd_cmd.py +22 -0
- codexloop/cli/commands/doctor.py +27 -0
- codexloop/cli/commands/effort_cmd.py +24 -0
- codexloop/cli/commands/logs.py +15 -0
- codexloop/cli/commands/model_cmd.py +22 -0
- codexloop/cli/commands/prompt.py +32 -0
- codexloop/cli/commands/reset.py +25 -0
- codexloop/cli/commands/resume.py +38 -0
- codexloop/cli/commands/run.py +50 -0
- codexloop/cli/commands/runs.py +13 -0
- codexloop/cli/commands/sandbox_cmd.py +24 -0
- codexloop/cli/commands/savepoints.py +25 -0
- codexloop/cli/commands/snapshot.py +26 -0
- codexloop/cli/commands/status.py +15 -0
- codexloop/cli/commands/stop.py +21 -0
- codexloop/cli/commands/threads.py +15 -0
- codexloop/cli/commands/unwind.py +24 -0
- codexloop/cli/commands/watch.py +66 -0
- codexloop/cli/render.py +39 -0
- codexloop/domain/__init__.py +26 -0
- codexloop/domain/approval.py +38 -0
- codexloop/domain/backoff.py +34 -0
- codexloop/domain/budget.py +56 -0
- codexloop/domain/capacity.py +81 -0
- codexloop/domain/classify.py +98 -0
- codexloop/domain/completion.py +130 -0
- codexloop/domain/control.py +167 -0
- codexloop/domain/error_codes.py +75 -0
- codexloop/domain/errors.py +35 -0
- codexloop/domain/loop.py +190 -0
- codexloop/domain/model_profile.py +30 -0
- codexloop/domain/plan.py +38 -0
- codexloop/domain/savepoint.py +32 -0
- codexloop/domain/savepoint_message.py +56 -0
- codexloop/domain/session.py +32 -0
- codexloop/domain/signals.py +25 -0
- codexloop/domain/waiting.py +120 -0
- codexloop/infrastructure/__init__.py +0 -0
- codexloop/infrastructure/agent/__init__.py +0 -0
- codexloop/infrastructure/agent/argv.py +102 -0
- codexloop/infrastructure/agent/events.py +274 -0
- codexloop/infrastructure/agent/gateway.py +189 -0
- codexloop/infrastructure/agent/probe.py +74 -0
- codexloop/infrastructure/agent/process.py +208 -0
- codexloop/infrastructure/agent/schema.py +31 -0
- codexloop/infrastructure/agent/scripted.py +201 -0
- codexloop/infrastructure/agent/translate.py +120 -0
- codexloop/infrastructure/api/__init__.py +26 -0
- codexloop/infrastructure/api/api_baseline.json +340 -0
- codexloop/infrastructure/api/binder.py +170 -0
- codexloop/infrastructure/api/gateway.py +142 -0
- codexloop/infrastructure/api/introspect.py +248 -0
- codexloop/infrastructure/api/json_io.py +26 -0
- codexloop/infrastructure/api/params.py +162 -0
- codexloop/infrastructure/api/providers.py +70 -0
- codexloop/infrastructure/api/registry.py +13 -0
- codexloop/infrastructure/appserver/__init__.py +6 -0
- codexloop/infrastructure/appserver/client.py +245 -0
- codexloop/infrastructure/appserver/gateway.py +437 -0
- codexloop/infrastructure/appserver/ratelimits.py +100 -0
- codexloop/infrastructure/audit.py +26 -0
- codexloop/infrastructure/capacity_probe.py +57 -0
- codexloop/infrastructure/clock.py +26 -0
- codexloop/infrastructure/config.py +150 -0
- codexloop/infrastructure/control.py +89 -0
- codexloop/infrastructure/doctor_env.py +239 -0
- codexloop/infrastructure/events.py +23 -0
- codexloop/infrastructure/git_savepoints.py +176 -0
- codexloop/infrastructure/lock.py +88 -0
- codexloop/infrastructure/logging.py +124 -0
- codexloop/infrastructure/notify.py +27 -0
- codexloop/infrastructure/progress.py +14 -0
- codexloop/infrastructure/redact.py +52 -0
- codexloop/infrastructure/rollout.py +113 -0
- codexloop/infrastructure/rundir.py +57 -0
- codexloop/infrastructure/snapshot.py +39 -0
- codexloop/infrastructure/state.py +32 -0
- codexloop/infrastructure/state_bus.py +27 -0
- codexloop/infrastructure/stream_ui.py +44 -0
- codexloop/py.typed +0 -0
- codexloop-0.1.0.dist-info/METADATA +104 -0
- codexloop-0.1.0.dist-info/RECORD +104 -0
- codexloop-0.1.0.dist-info/WHEEL +4 -0
- codexloop-0.1.0.dist-info/entry_points.txt +2 -0
- codexloop-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openai_version": "3.0.0",
|
|
3
|
+
"method_count": 320,
|
|
4
|
+
"local_helpers": [
|
|
5
|
+
"beta.chat.completions.parse",
|
|
6
|
+
"beta.chat.completions.stream",
|
|
7
|
+
"beta.threads.create_and_run_stream",
|
|
8
|
+
"beta.threads.runs.create_and_stream",
|
|
9
|
+
"beta.threads.runs.stream",
|
|
10
|
+
"beta.threads.runs.submit_tool_outputs_stream",
|
|
11
|
+
"chat.completions.parse",
|
|
12
|
+
"chat.completions.stream",
|
|
13
|
+
"responses.parse",
|
|
14
|
+
"responses.stream",
|
|
15
|
+
"webhooks.unwrap",
|
|
16
|
+
"webhooks.verify_signature"
|
|
17
|
+
],
|
|
18
|
+
"methods": [
|
|
19
|
+
"admin.organization.admin_api_keys.create",
|
|
20
|
+
"admin.organization.admin_api_keys.delete",
|
|
21
|
+
"admin.organization.admin_api_keys.list",
|
|
22
|
+
"admin.organization.admin_api_keys.retrieve",
|
|
23
|
+
"admin.organization.audit_logs.list",
|
|
24
|
+
"admin.organization.certificates.activate",
|
|
25
|
+
"admin.organization.certificates.create",
|
|
26
|
+
"admin.organization.certificates.deactivate",
|
|
27
|
+
"admin.organization.certificates.delete",
|
|
28
|
+
"admin.organization.certificates.list",
|
|
29
|
+
"admin.organization.certificates.retrieve",
|
|
30
|
+
"admin.organization.certificates.update",
|
|
31
|
+
"admin.organization.data_retention.retrieve",
|
|
32
|
+
"admin.organization.data_retention.update",
|
|
33
|
+
"admin.organization.groups.create",
|
|
34
|
+
"admin.organization.groups.delete",
|
|
35
|
+
"admin.organization.groups.list",
|
|
36
|
+
"admin.organization.groups.retrieve",
|
|
37
|
+
"admin.organization.groups.roles.create",
|
|
38
|
+
"admin.organization.groups.roles.delete",
|
|
39
|
+
"admin.organization.groups.roles.list",
|
|
40
|
+
"admin.organization.groups.roles.retrieve",
|
|
41
|
+
"admin.organization.groups.update",
|
|
42
|
+
"admin.organization.groups.users.create",
|
|
43
|
+
"admin.organization.groups.users.delete",
|
|
44
|
+
"admin.organization.groups.users.list",
|
|
45
|
+
"admin.organization.groups.users.retrieve",
|
|
46
|
+
"admin.organization.invites.create",
|
|
47
|
+
"admin.organization.invites.delete",
|
|
48
|
+
"admin.organization.invites.list",
|
|
49
|
+
"admin.organization.invites.retrieve",
|
|
50
|
+
"admin.organization.projects.api_keys.delete",
|
|
51
|
+
"admin.organization.projects.api_keys.list",
|
|
52
|
+
"admin.organization.projects.api_keys.retrieve",
|
|
53
|
+
"admin.organization.projects.archive",
|
|
54
|
+
"admin.organization.projects.certificates.activate",
|
|
55
|
+
"admin.organization.projects.certificates.deactivate",
|
|
56
|
+
"admin.organization.projects.certificates.list",
|
|
57
|
+
"admin.organization.projects.create",
|
|
58
|
+
"admin.organization.projects.data_retention.retrieve",
|
|
59
|
+
"admin.organization.projects.data_retention.update",
|
|
60
|
+
"admin.organization.projects.groups.create",
|
|
61
|
+
"admin.organization.projects.groups.delete",
|
|
62
|
+
"admin.organization.projects.groups.list",
|
|
63
|
+
"admin.organization.projects.groups.retrieve",
|
|
64
|
+
"admin.organization.projects.groups.roles.create",
|
|
65
|
+
"admin.organization.projects.groups.roles.delete",
|
|
66
|
+
"admin.organization.projects.groups.roles.list",
|
|
67
|
+
"admin.organization.projects.groups.roles.retrieve",
|
|
68
|
+
"admin.organization.projects.hosted_tool_permissions.retrieve",
|
|
69
|
+
"admin.organization.projects.hosted_tool_permissions.update",
|
|
70
|
+
"admin.organization.projects.list",
|
|
71
|
+
"admin.organization.projects.model_permissions.delete",
|
|
72
|
+
"admin.organization.projects.model_permissions.retrieve",
|
|
73
|
+
"admin.organization.projects.model_permissions.update",
|
|
74
|
+
"admin.organization.projects.rate_limits.list_rate_limits",
|
|
75
|
+
"admin.organization.projects.rate_limits.update_rate_limit",
|
|
76
|
+
"admin.organization.projects.retrieve",
|
|
77
|
+
"admin.organization.projects.roles.create",
|
|
78
|
+
"admin.organization.projects.roles.delete",
|
|
79
|
+
"admin.organization.projects.roles.list",
|
|
80
|
+
"admin.organization.projects.roles.retrieve",
|
|
81
|
+
"admin.organization.projects.roles.update",
|
|
82
|
+
"admin.organization.projects.service_accounts.api_keys.create",
|
|
83
|
+
"admin.organization.projects.service_accounts.create",
|
|
84
|
+
"admin.organization.projects.service_accounts.delete",
|
|
85
|
+
"admin.organization.projects.service_accounts.list",
|
|
86
|
+
"admin.organization.projects.service_accounts.retrieve",
|
|
87
|
+
"admin.organization.projects.service_accounts.update",
|
|
88
|
+
"admin.organization.projects.spend_alerts.create",
|
|
89
|
+
"admin.organization.projects.spend_alerts.delete",
|
|
90
|
+
"admin.organization.projects.spend_alerts.list",
|
|
91
|
+
"admin.organization.projects.spend_alerts.retrieve",
|
|
92
|
+
"admin.organization.projects.spend_alerts.update",
|
|
93
|
+
"admin.organization.projects.spend_limit.delete",
|
|
94
|
+
"admin.organization.projects.spend_limit.retrieve",
|
|
95
|
+
"admin.organization.projects.spend_limit.update",
|
|
96
|
+
"admin.organization.projects.update",
|
|
97
|
+
"admin.organization.projects.users.create",
|
|
98
|
+
"admin.organization.projects.users.delete",
|
|
99
|
+
"admin.organization.projects.users.list",
|
|
100
|
+
"admin.organization.projects.users.retrieve",
|
|
101
|
+
"admin.organization.projects.users.roles.create",
|
|
102
|
+
"admin.organization.projects.users.roles.delete",
|
|
103
|
+
"admin.organization.projects.users.roles.list",
|
|
104
|
+
"admin.organization.projects.users.roles.retrieve",
|
|
105
|
+
"admin.organization.projects.users.update",
|
|
106
|
+
"admin.organization.roles.create",
|
|
107
|
+
"admin.organization.roles.delete",
|
|
108
|
+
"admin.organization.roles.list",
|
|
109
|
+
"admin.organization.roles.retrieve",
|
|
110
|
+
"admin.organization.roles.update",
|
|
111
|
+
"admin.organization.spend_alerts.create",
|
|
112
|
+
"admin.organization.spend_alerts.delete",
|
|
113
|
+
"admin.organization.spend_alerts.list",
|
|
114
|
+
"admin.organization.spend_alerts.retrieve",
|
|
115
|
+
"admin.organization.spend_alerts.update",
|
|
116
|
+
"admin.organization.spend_limit.delete",
|
|
117
|
+
"admin.organization.spend_limit.retrieve",
|
|
118
|
+
"admin.organization.spend_limit.update",
|
|
119
|
+
"admin.organization.usage.audio_speeches",
|
|
120
|
+
"admin.organization.usage.audio_transcriptions",
|
|
121
|
+
"admin.organization.usage.code_interpreter_sessions",
|
|
122
|
+
"admin.organization.usage.completions",
|
|
123
|
+
"admin.organization.usage.costs",
|
|
124
|
+
"admin.organization.usage.embeddings",
|
|
125
|
+
"admin.organization.usage.file_search_calls",
|
|
126
|
+
"admin.organization.usage.images",
|
|
127
|
+
"admin.organization.usage.moderations",
|
|
128
|
+
"admin.organization.usage.vector_stores",
|
|
129
|
+
"admin.organization.usage.web_search_calls",
|
|
130
|
+
"admin.organization.users.delete",
|
|
131
|
+
"admin.organization.users.list",
|
|
132
|
+
"admin.organization.users.retrieve",
|
|
133
|
+
"admin.organization.users.roles.create",
|
|
134
|
+
"admin.organization.users.roles.delete",
|
|
135
|
+
"admin.organization.users.roles.list",
|
|
136
|
+
"admin.organization.users.roles.retrieve",
|
|
137
|
+
"admin.organization.users.update",
|
|
138
|
+
"audio.speech.create",
|
|
139
|
+
"audio.transcriptions.create",
|
|
140
|
+
"audio.translations.create",
|
|
141
|
+
"batches.cancel",
|
|
142
|
+
"batches.create",
|
|
143
|
+
"batches.list",
|
|
144
|
+
"batches.retrieve",
|
|
145
|
+
"beta.assistants.create",
|
|
146
|
+
"beta.assistants.delete",
|
|
147
|
+
"beta.assistants.list",
|
|
148
|
+
"beta.assistants.retrieve",
|
|
149
|
+
"beta.assistants.update",
|
|
150
|
+
"beta.chat.completions.create",
|
|
151
|
+
"beta.chat.completions.delete",
|
|
152
|
+
"beta.chat.completions.list",
|
|
153
|
+
"beta.chat.completions.messages.list",
|
|
154
|
+
"beta.chat.completions.parse",
|
|
155
|
+
"beta.chat.completions.retrieve",
|
|
156
|
+
"beta.chat.completions.stream",
|
|
157
|
+
"beta.chat.completions.update",
|
|
158
|
+
"beta.chatkit.sessions.cancel",
|
|
159
|
+
"beta.chatkit.sessions.create",
|
|
160
|
+
"beta.chatkit.threads.delete",
|
|
161
|
+
"beta.chatkit.threads.list",
|
|
162
|
+
"beta.chatkit.threads.list_items",
|
|
163
|
+
"beta.chatkit.threads.retrieve",
|
|
164
|
+
"beta.realtime.connect",
|
|
165
|
+
"beta.realtime.sessions.create",
|
|
166
|
+
"beta.realtime.transcription_sessions.create",
|
|
167
|
+
"beta.responses.cancel",
|
|
168
|
+
"beta.responses.compact",
|
|
169
|
+
"beta.responses.connect",
|
|
170
|
+
"beta.responses.create",
|
|
171
|
+
"beta.responses.delete",
|
|
172
|
+
"beta.responses.input_items.list",
|
|
173
|
+
"beta.responses.input_tokens.count",
|
|
174
|
+
"beta.responses.retrieve",
|
|
175
|
+
"beta.threads.create",
|
|
176
|
+
"beta.threads.create_and_run",
|
|
177
|
+
"beta.threads.create_and_run_poll",
|
|
178
|
+
"beta.threads.create_and_run_stream",
|
|
179
|
+
"beta.threads.delete",
|
|
180
|
+
"beta.threads.messages.create",
|
|
181
|
+
"beta.threads.messages.delete",
|
|
182
|
+
"beta.threads.messages.list",
|
|
183
|
+
"beta.threads.messages.retrieve",
|
|
184
|
+
"beta.threads.messages.update",
|
|
185
|
+
"beta.threads.retrieve",
|
|
186
|
+
"beta.threads.runs.cancel",
|
|
187
|
+
"beta.threads.runs.create",
|
|
188
|
+
"beta.threads.runs.create_and_poll",
|
|
189
|
+
"beta.threads.runs.create_and_stream",
|
|
190
|
+
"beta.threads.runs.list",
|
|
191
|
+
"beta.threads.runs.poll",
|
|
192
|
+
"beta.threads.runs.retrieve",
|
|
193
|
+
"beta.threads.runs.steps.list",
|
|
194
|
+
"beta.threads.runs.steps.retrieve",
|
|
195
|
+
"beta.threads.runs.stream",
|
|
196
|
+
"beta.threads.runs.submit_tool_outputs",
|
|
197
|
+
"beta.threads.runs.submit_tool_outputs_and_poll",
|
|
198
|
+
"beta.threads.runs.submit_tool_outputs_stream",
|
|
199
|
+
"beta.threads.runs.update",
|
|
200
|
+
"beta.threads.update",
|
|
201
|
+
"chat.completions.create",
|
|
202
|
+
"chat.completions.delete",
|
|
203
|
+
"chat.completions.list",
|
|
204
|
+
"chat.completions.messages.list",
|
|
205
|
+
"chat.completions.parse",
|
|
206
|
+
"chat.completions.retrieve",
|
|
207
|
+
"chat.completions.stream",
|
|
208
|
+
"chat.completions.update",
|
|
209
|
+
"completions.create",
|
|
210
|
+
"containers.create",
|
|
211
|
+
"containers.delete",
|
|
212
|
+
"containers.files.content.retrieve",
|
|
213
|
+
"containers.files.create",
|
|
214
|
+
"containers.files.delete",
|
|
215
|
+
"containers.files.list",
|
|
216
|
+
"containers.files.retrieve",
|
|
217
|
+
"containers.list",
|
|
218
|
+
"containers.retrieve",
|
|
219
|
+
"content_provenance_checks.create",
|
|
220
|
+
"conversations.create",
|
|
221
|
+
"conversations.delete",
|
|
222
|
+
"conversations.items.create",
|
|
223
|
+
"conversations.items.delete",
|
|
224
|
+
"conversations.items.list",
|
|
225
|
+
"conversations.items.retrieve",
|
|
226
|
+
"conversations.retrieve",
|
|
227
|
+
"conversations.update",
|
|
228
|
+
"embeddings.create",
|
|
229
|
+
"evals.create",
|
|
230
|
+
"evals.delete",
|
|
231
|
+
"evals.list",
|
|
232
|
+
"evals.retrieve",
|
|
233
|
+
"evals.runs.cancel",
|
|
234
|
+
"evals.runs.create",
|
|
235
|
+
"evals.runs.delete",
|
|
236
|
+
"evals.runs.list",
|
|
237
|
+
"evals.runs.output_items.list",
|
|
238
|
+
"evals.runs.output_items.retrieve",
|
|
239
|
+
"evals.runs.retrieve",
|
|
240
|
+
"evals.update",
|
|
241
|
+
"files.content",
|
|
242
|
+
"files.create",
|
|
243
|
+
"files.delete",
|
|
244
|
+
"files.list",
|
|
245
|
+
"files.retrieve",
|
|
246
|
+
"files.retrieve_content",
|
|
247
|
+
"files.wait_for_processing",
|
|
248
|
+
"fine_tuning.alpha.graders.run",
|
|
249
|
+
"fine_tuning.alpha.graders.validate",
|
|
250
|
+
"fine_tuning.checkpoints.permissions.create",
|
|
251
|
+
"fine_tuning.checkpoints.permissions.delete",
|
|
252
|
+
"fine_tuning.checkpoints.permissions.list",
|
|
253
|
+
"fine_tuning.checkpoints.permissions.retrieve",
|
|
254
|
+
"fine_tuning.jobs.cancel",
|
|
255
|
+
"fine_tuning.jobs.checkpoints.list",
|
|
256
|
+
"fine_tuning.jobs.create",
|
|
257
|
+
"fine_tuning.jobs.list",
|
|
258
|
+
"fine_tuning.jobs.list_events",
|
|
259
|
+
"fine_tuning.jobs.pause",
|
|
260
|
+
"fine_tuning.jobs.resume",
|
|
261
|
+
"fine_tuning.jobs.retrieve",
|
|
262
|
+
"images.create_variation",
|
|
263
|
+
"images.edit",
|
|
264
|
+
"images.generate",
|
|
265
|
+
"models.delete",
|
|
266
|
+
"models.list",
|
|
267
|
+
"models.retrieve",
|
|
268
|
+
"moderations.create",
|
|
269
|
+
"realtime.calls.accept",
|
|
270
|
+
"realtime.calls.create",
|
|
271
|
+
"realtime.calls.hangup",
|
|
272
|
+
"realtime.calls.refer",
|
|
273
|
+
"realtime.calls.reject",
|
|
274
|
+
"realtime.client_secrets.create",
|
|
275
|
+
"realtime.connect",
|
|
276
|
+
"responses.cancel",
|
|
277
|
+
"responses.compact",
|
|
278
|
+
"responses.connect",
|
|
279
|
+
"responses.create",
|
|
280
|
+
"responses.delete",
|
|
281
|
+
"responses.input_items.list",
|
|
282
|
+
"responses.input_tokens.count",
|
|
283
|
+
"responses.parse",
|
|
284
|
+
"responses.retrieve",
|
|
285
|
+
"responses.stream",
|
|
286
|
+
"skills.content.retrieve",
|
|
287
|
+
"skills.create",
|
|
288
|
+
"skills.delete",
|
|
289
|
+
"skills.list",
|
|
290
|
+
"skills.retrieve",
|
|
291
|
+
"skills.update",
|
|
292
|
+
"skills.versions.content.retrieve",
|
|
293
|
+
"skills.versions.create",
|
|
294
|
+
"skills.versions.delete",
|
|
295
|
+
"skills.versions.list",
|
|
296
|
+
"skills.versions.retrieve",
|
|
297
|
+
"uploads.cancel",
|
|
298
|
+
"uploads.complete",
|
|
299
|
+
"uploads.create",
|
|
300
|
+
"uploads.parts.create",
|
|
301
|
+
"uploads.upload_file_chunked",
|
|
302
|
+
"vector_stores.create",
|
|
303
|
+
"vector_stores.delete",
|
|
304
|
+
"vector_stores.file_batches.cancel",
|
|
305
|
+
"vector_stores.file_batches.create",
|
|
306
|
+
"vector_stores.file_batches.create_and_poll",
|
|
307
|
+
"vector_stores.file_batches.list_files",
|
|
308
|
+
"vector_stores.file_batches.poll",
|
|
309
|
+
"vector_stores.file_batches.retrieve",
|
|
310
|
+
"vector_stores.file_batches.upload_and_poll",
|
|
311
|
+
"vector_stores.files.content",
|
|
312
|
+
"vector_stores.files.create",
|
|
313
|
+
"vector_stores.files.create_and_poll",
|
|
314
|
+
"vector_stores.files.delete",
|
|
315
|
+
"vector_stores.files.list",
|
|
316
|
+
"vector_stores.files.poll",
|
|
317
|
+
"vector_stores.files.retrieve",
|
|
318
|
+
"vector_stores.files.update",
|
|
319
|
+
"vector_stores.files.upload",
|
|
320
|
+
"vector_stores.files.upload_and_poll",
|
|
321
|
+
"vector_stores.list",
|
|
322
|
+
"vector_stores.retrieve",
|
|
323
|
+
"vector_stores.search",
|
|
324
|
+
"vector_stores.update",
|
|
325
|
+
"videos.create",
|
|
326
|
+
"videos.create_and_poll",
|
|
327
|
+
"videos.create_character",
|
|
328
|
+
"videos.delete",
|
|
329
|
+
"videos.download_content",
|
|
330
|
+
"videos.edit",
|
|
331
|
+
"videos.extend",
|
|
332
|
+
"videos.get_character",
|
|
333
|
+
"videos.list",
|
|
334
|
+
"videos.poll",
|
|
335
|
+
"videos.remix",
|
|
336
|
+
"videos.retrieve",
|
|
337
|
+
"webhooks.unwrap",
|
|
338
|
+
"webhooks.verify_signature"
|
|
339
|
+
]
|
|
340
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""Bind discovered SDK methods to a nested Typer command tree."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from codexloop.infrastructure.api.gateway import OpenAIApiGateway, default_gateway
|
|
12
|
+
from codexloop.infrastructure.api.introspect import EndpointSpec, discover_surface, resolve_callable
|
|
13
|
+
from codexloop.infrastructure.api.params import (
|
|
14
|
+
ScalarParam,
|
|
15
|
+
scalar_parameters,
|
|
16
|
+
typer_type_for_annotation,
|
|
17
|
+
)
|
|
18
|
+
from codexloop.infrastructure.api.providers import (
|
|
19
|
+
PROVIDER_FACTORIES,
|
|
20
|
+
client_class_for_provider,
|
|
21
|
+
surface_roots_for_provider,
|
|
22
|
+
)
|
|
23
|
+
from codexloop.infrastructure.api.registry import clear_registry, register_command_path
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _scalar_default_src(scalar: ScalarParam) -> str:
|
|
27
|
+
py_type = typer_type_for_annotation(scalar.annotation).__name__
|
|
28
|
+
return (
|
|
29
|
+
f"{scalar.name}: {py_type} | None = typer.Option("
|
|
30
|
+
f'None, "--{scalar.cli_name}", help="SDK parameter {scalar.name!r}.")'
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _make_typer_command(
|
|
35
|
+
method: EndpointSpec,
|
|
36
|
+
gateway: OpenAIApiGateway,
|
|
37
|
+
*,
|
|
38
|
+
client_cls: type,
|
|
39
|
+
) -> Any:
|
|
40
|
+
fn = resolve_callable(method, client_cls=client_cls)
|
|
41
|
+
signature = inspect.signature(fn)
|
|
42
|
+
scalars = scalar_parameters(signature)
|
|
43
|
+
param_names = [s.name for s in scalars]
|
|
44
|
+
|
|
45
|
+
def bound_callback(ctx: typer.Context, **kwargs: Any) -> None:
|
|
46
|
+
root: Any = ctx
|
|
47
|
+
while root.parent is not None:
|
|
48
|
+
root = root.parent
|
|
49
|
+
obj = root.obj if isinstance(root.obj, dict) else {}
|
|
50
|
+
provider = str(obj.get("provider", "openai"))
|
|
51
|
+
base_url = obj.get("base_url")
|
|
52
|
+
json_body = kwargs.pop("json_body", None)
|
|
53
|
+
json_file = kwargs.pop("json_file", None)
|
|
54
|
+
raw = bool(kwargs.pop("raw", False))
|
|
55
|
+
stream = bool(kwargs.pop("stream", False))
|
|
56
|
+
max_items = kwargs.pop("max_items", None)
|
|
57
|
+
scalar_values = {name: kwargs.get(name) for name in param_names}
|
|
58
|
+
try:
|
|
59
|
+
text = gateway.invoke_and_print(
|
|
60
|
+
method.path,
|
|
61
|
+
provider=provider,
|
|
62
|
+
base_url=base_url if isinstance(base_url, str) else None,
|
|
63
|
+
json_body=json_body,
|
|
64
|
+
json_file=json_file,
|
|
65
|
+
raw=raw,
|
|
66
|
+
stream=stream,
|
|
67
|
+
max_items=max_items,
|
|
68
|
+
scalar_values=scalar_values,
|
|
69
|
+
method=method,
|
|
70
|
+
)
|
|
71
|
+
except (ValueError, TypeError, OSError) as exc:
|
|
72
|
+
typer.echo(str(exc), err=True)
|
|
73
|
+
raise typer.Exit(2) from exc
|
|
74
|
+
typer.echo(text)
|
|
75
|
+
|
|
76
|
+
# Option-as-default (not Annotated) so Typer works under postponed annotations.
|
|
77
|
+
args_src = [
|
|
78
|
+
"ctx: typer.Context",
|
|
79
|
+
'json_body: str | None = typer.Option(None, "--json", help="Inline JSON object.")',
|
|
80
|
+
'json_file: Path | None = typer.Option(None, "--json-file", help="JSON file path.")',
|
|
81
|
+
'raw: bool = typer.Option(False, "--raw", help="Use with_raw_response.")',
|
|
82
|
+
'stream: bool = typer.Option(False, "--stream", help="Use with_streaming_response.")',
|
|
83
|
+
'max_items: int | None = typer.Option(None, "--max-items", help="Auto-pagination cap.")',
|
|
84
|
+
]
|
|
85
|
+
args_src.extend(_scalar_default_src(s) for s in scalars)
|
|
86
|
+
scalar_dict = ", ".join(f"{n!r}: {n}" for n in param_names)
|
|
87
|
+
body = (
|
|
88
|
+
f"def command({', '.join(args_src)}) -> None:\n"
|
|
89
|
+
f" scalar_values = {{{scalar_dict}}}\n"
|
|
90
|
+
" bound_callback(\n"
|
|
91
|
+
" ctx,\n"
|
|
92
|
+
" json_body=json_body,\n"
|
|
93
|
+
" json_file=json_file,\n"
|
|
94
|
+
" raw=raw,\n"
|
|
95
|
+
" stream=stream,\n"
|
|
96
|
+
" max_items=max_items,\n"
|
|
97
|
+
" **scalar_values,\n"
|
|
98
|
+
" )\n"
|
|
99
|
+
)
|
|
100
|
+
ns: dict[str, Any] = {
|
|
101
|
+
"Path": Path,
|
|
102
|
+
"typer": typer,
|
|
103
|
+
"bound_callback": bound_callback,
|
|
104
|
+
}
|
|
105
|
+
exec(body, ns) # nosec B102 — binder-owned source string builds Typer callbacks
|
|
106
|
+
command_fn = ns["command"]
|
|
107
|
+
command_fn.__name__ = method.method_name
|
|
108
|
+
command_fn.__doc__ = f"SDK `{method.path}`."
|
|
109
|
+
return command_fn
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _ensure_group(parent: typer.Typer, name: str, groups: dict[str, typer.Typer]) -> typer.Typer:
|
|
113
|
+
key = f"{id(parent)}:{name}"
|
|
114
|
+
existing = groups.get(key)
|
|
115
|
+
if existing is not None:
|
|
116
|
+
return existing
|
|
117
|
+
child = typer.Typer(name=name, help=f"OpenAI `{name}` resource.", no_args_is_help=True)
|
|
118
|
+
parent.add_typer(child, name=name)
|
|
119
|
+
groups[key] = child
|
|
120
|
+
return child
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def build_api_typer_app(
|
|
124
|
+
*,
|
|
125
|
+
gateway: OpenAIApiGateway | None = None,
|
|
126
|
+
provider: str = "openai",
|
|
127
|
+
) -> typer.Typer:
|
|
128
|
+
"""Build the nested Typer app mounted at ``codexloop api``."""
|
|
129
|
+
clear_registry()
|
|
130
|
+
gw = gateway or default_gateway()
|
|
131
|
+
client_cls = client_class_for_provider(provider)
|
|
132
|
+
roots = surface_roots_for_provider(provider)
|
|
133
|
+
|
|
134
|
+
api = typer.Typer(
|
|
135
|
+
name="api",
|
|
136
|
+
help="Generated 1:1 OpenAI SDK REST surface.",
|
|
137
|
+
no_args_is_help=True,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
@api.callback()
|
|
141
|
+
def _api_callback(
|
|
142
|
+
ctx: typer.Context,
|
|
143
|
+
provider_opt: str = typer.Option(
|
|
144
|
+
"openai",
|
|
145
|
+
"--provider",
|
|
146
|
+
help="SDK client (azure, custom, openai).",
|
|
147
|
+
),
|
|
148
|
+
base_url: str | None = typer.Option(
|
|
149
|
+
None,
|
|
150
|
+
"--base-url",
|
|
151
|
+
help="Override API base URL (custom / openai).",
|
|
152
|
+
),
|
|
153
|
+
) -> None:
|
|
154
|
+
if provider_opt not in PROVIDER_FACTORIES:
|
|
155
|
+
typer.echo(f"unknown provider {provider_opt!r}", err=True)
|
|
156
|
+
raise typer.Exit(2)
|
|
157
|
+
ctx.ensure_object(dict)
|
|
158
|
+
ctx.obj["provider"] = provider_opt
|
|
159
|
+
ctx.obj["base_url"] = base_url
|
|
160
|
+
|
|
161
|
+
groups: dict[str, typer.Typer] = {}
|
|
162
|
+
for method in discover_surface(roots=roots, client_cls=client_cls):
|
|
163
|
+
parts = method.path.split(".")
|
|
164
|
+
current = api
|
|
165
|
+
for segment in parts[:-1]:
|
|
166
|
+
current = _ensure_group(current, segment, groups)
|
|
167
|
+
current.command(method.method_name)(_make_typer_command(method, gw, client_cls=client_cls))
|
|
168
|
+
register_command_path(method.path)
|
|
169
|
+
|
|
170
|
+
return api
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Invoke generated ``codexloop api`` commands against the OpenAI SDK."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
import json
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from openai import Omit
|
|
11
|
+
|
|
12
|
+
from codexloop.infrastructure.api.introspect import (
|
|
13
|
+
LOCAL_HELPER_PATHS,
|
|
14
|
+
EndpointSpec,
|
|
15
|
+
discover_surface,
|
|
16
|
+
resolve_callable,
|
|
17
|
+
)
|
|
18
|
+
from codexloop.infrastructure.api.json_io import load_json_payload
|
|
19
|
+
from codexloop.infrastructure.api.params import build_call_kwargs
|
|
20
|
+
from codexloop.infrastructure.api.providers import (
|
|
21
|
+
build_client,
|
|
22
|
+
client_class_for_provider,
|
|
23
|
+
surface_roots_for_provider,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _serialize(value: Any) -> Any:
|
|
28
|
+
if hasattr(value, "model_dump"):
|
|
29
|
+
return value.model_dump()
|
|
30
|
+
if hasattr(value, "read"):
|
|
31
|
+
return {"stream": "<streaming response>"}
|
|
32
|
+
if isinstance(value, (list, tuple)):
|
|
33
|
+
return [_serialize(v) for v in value]
|
|
34
|
+
if isinstance(value, dict):
|
|
35
|
+
return {k: _serialize(v) for k, v in value.items()}
|
|
36
|
+
return value
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _navigate_resource(client: Any, resource_path: tuple[str, ...]) -> Any:
|
|
40
|
+
resource: Any = client
|
|
41
|
+
for segment in resource_path:
|
|
42
|
+
resource = getattr(resource, segment)
|
|
43
|
+
return resource
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _collect_paginated(
|
|
47
|
+
first_page: Any,
|
|
48
|
+
*,
|
|
49
|
+
max_items: int | None,
|
|
50
|
+
) -> list[Any]:
|
|
51
|
+
data = getattr(first_page, "data", first_page)
|
|
52
|
+
items: list[Any] = list(data or []) if not isinstance(data, list) else list(data)
|
|
53
|
+
page = first_page
|
|
54
|
+
while getattr(page, "has_more", False):
|
|
55
|
+
if max_items is not None and len(items) >= max_items:
|
|
56
|
+
break
|
|
57
|
+
page = page.get_next_page()
|
|
58
|
+
items.extend(page.data)
|
|
59
|
+
if max_items is not None:
|
|
60
|
+
items = items[:max_items]
|
|
61
|
+
return items
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class OpenAIApiGateway:
|
|
65
|
+
"""Concrete adapter for the generated REST surface."""
|
|
66
|
+
|
|
67
|
+
def invoke(
|
|
68
|
+
self,
|
|
69
|
+
method_path: str,
|
|
70
|
+
*,
|
|
71
|
+
provider: str = "openai",
|
|
72
|
+
base_url: str | None = None,
|
|
73
|
+
json_body: str | None = None,
|
|
74
|
+
json_file: Path | None = None,
|
|
75
|
+
raw: bool = False,
|
|
76
|
+
stream: bool = False,
|
|
77
|
+
max_items: int | None = None,
|
|
78
|
+
scalar_values: dict[str, Any] | None = None,
|
|
79
|
+
method: EndpointSpec | None = None,
|
|
80
|
+
) -> Any:
|
|
81
|
+
client_cls = client_class_for_provider(provider)
|
|
82
|
+
if method is None:
|
|
83
|
+
segments = method_path.split(".")
|
|
84
|
+
method = EndpointSpec(
|
|
85
|
+
resource_path=tuple(segments[:-1]),
|
|
86
|
+
method_name=segments[-1],
|
|
87
|
+
signature="",
|
|
88
|
+
is_list=segments[-1] == "list",
|
|
89
|
+
is_streaming=False,
|
|
90
|
+
)
|
|
91
|
+
roots = surface_roots_for_provider(provider)
|
|
92
|
+
if roots is not None:
|
|
93
|
+
allowed = {m.path for m in discover_surface(roots=roots, client_cls=client_cls)}
|
|
94
|
+
if method.path not in allowed:
|
|
95
|
+
msg = f"method {method.path!r} is not available for provider {provider!r}"
|
|
96
|
+
raise ValueError(msg)
|
|
97
|
+
|
|
98
|
+
client = build_client(provider, base_url=base_url)
|
|
99
|
+
payload = load_json_payload(inline=json_body, json_file=json_file)
|
|
100
|
+
fn = resolve_callable(method, client_cls=client_cls)
|
|
101
|
+
signature = inspect.signature(fn)
|
|
102
|
+
kwargs = build_call_kwargs(
|
|
103
|
+
signature,
|
|
104
|
+
json_payload=payload,
|
|
105
|
+
scalar_values=scalar_values or {},
|
|
106
|
+
)
|
|
107
|
+
cleaned = {k: v for k, v in kwargs.items() if v is not None and not isinstance(v, Omit)}
|
|
108
|
+
|
|
109
|
+
resource = _navigate_resource(client, method.resource_path)
|
|
110
|
+
if raw:
|
|
111
|
+
resource = resource.with_raw_response
|
|
112
|
+
elif stream:
|
|
113
|
+
resource = resource.with_streaming_response
|
|
114
|
+
bound = getattr(resource, method.method_name)
|
|
115
|
+
result = bound(**cleaned)
|
|
116
|
+
|
|
117
|
+
if not raw and not stream and method.is_list and max_items is not None:
|
|
118
|
+
return _collect_paginated(result, max_items=max_items)
|
|
119
|
+
return result
|
|
120
|
+
|
|
121
|
+
def invoke_and_print(
|
|
122
|
+
self,
|
|
123
|
+
method_path: str,
|
|
124
|
+
**options: Any,
|
|
125
|
+
) -> str:
|
|
126
|
+
result = self.invoke(method_path, **options)
|
|
127
|
+
if hasattr(result, "read"):
|
|
128
|
+
text = result.read()
|
|
129
|
+
return text.decode() if isinstance(text, bytes) else str(text)
|
|
130
|
+
return json.dumps(_serialize(result), indent=2, default=str)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def default_gateway() -> OpenAIApiGateway:
|
|
134
|
+
return OpenAIApiGateway()
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# Re-export for callers that need helper membership checks without importing introspect.
|
|
138
|
+
__all__ = [
|
|
139
|
+
"LOCAL_HELPER_PATHS",
|
|
140
|
+
"OpenAIApiGateway",
|
|
141
|
+
"default_gateway",
|
|
142
|
+
]
|