codai-sdk 0.53.0__tar.gz → 0.67.0__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.
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/CHANGELOG.md +142 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/PKG-INFO +12 -4
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/README.md +11 -3
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/pyproject.toml +3 -1
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/__init__.py +29 -4
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/_http.py +2 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/_operations.py +54 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/_types.py +1532 -21
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/__init__.py +19 -1
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/billing.py +31 -1
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/core.py +6 -2
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/creatives.py +200 -3
- codai_sdk-0.67.0/src/codai/resources/lyrics.py +112 -0
- codai_sdk-0.67.0/src/codai/resources/media_ops.py +133 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/memory.py +7 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/platform.py +39 -2
- codai_sdk-0.67.0/src/codai/resources/productions.py +108 -0
- codai_sdk-0.67.0/src/codai/resources/prompts.py +180 -0
- codai_sdk-0.67.0/src/codai/resources/research.py +107 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/sandboxes.py +16 -8
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/templates.py +14 -3
- codai_sdk-0.67.0/src/codai/resources/vault.py +325 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_billing_referrals.py +15 -0
- codai_sdk-0.67.0/tests/test_creatives_cx07.py +146 -0
- codai_sdk-0.67.0/tests/test_lyrics.py +72 -0
- codai_sdk-0.67.0/tests/test_media_ops.py +74 -0
- codai_sdk-0.67.0/tests/test_os_gate.py +48 -0
- codai_sdk-0.67.0/tests/test_productions.py +39 -0
- codai_sdk-0.67.0/tests/test_prompts.py +67 -0
- codai_sdk-0.67.0/tests/test_research.py +91 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_resources.py +1 -3
- codai_sdk-0.67.0/tests/test_vault.py +239 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/uv.lock +1 -1
- codai_sdk-0.53.0/src/codai/resources/prompts.py +0 -86
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.github/dependabot.yml +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.github/pull_request_template.md +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.github/workflows/publish.yml +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/.gitignore +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/CODE_OF_CONDUCT.md +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/CONTRIBUTING.md +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/LICENSE +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/SECURITY.md +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/examples/agent.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/examples/chat.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/examples/feedback.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/examples/streaming.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/scripts/gen-types.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/scripts/smoke_local.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/_resolve_types.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/_base.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/abuse_reports.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/agents.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/batches.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/brand_kits.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/cards.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/chat.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/environments.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/exports.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/lists.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/messages.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/provenance.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/referrals.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/resolve.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/responses.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/schedules.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/sessions.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/shares.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/transcripts.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/triggers.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/usage_keys.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/src/codai/resources/voice_revocations.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/conftest.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_abuse_reports.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_batches.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_brand_kits.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_cards.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_creatives.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_creatives_documents.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_creatives_e11.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_creatives_e11b.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_environments_exec.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_exports.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_http.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_lists.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_memory.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_parity.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_provenance.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_resolve.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_sandboxes.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_settings.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_shares_e12a.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_templates.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_transcripts.py +0 -0
- {codai_sdk-0.53.0 → codai_sdk-0.67.0}/tests/test_voice_revocations.py +0 -0
|
@@ -6,6 +6,148 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.67.0] - 2026-10-20
|
|
10
|
+
|
|
11
|
+
- Creatives (CX-07/08/09): `creatives.build(..., format=, format_id=, crop_marks=)` builds carousel (`png` | `pdf`)
|
|
12
|
+
and print (`pdf`, PDF/X-4) creatives, which answer HTTP 202 with a queued export job in `export`; new helper
|
|
13
|
+
`is_paged_build(r)` and `creatives.build_and_wait(...)` (build, then `exports.wait` the export).
|
|
14
|
+
- `creatives.post_copy(creative_id, platforms=, language=, brief=, tone=, seq=, idempotency_key=)`
|
|
15
|
+
(`POST /v1/studio/creatives/{id}/post-copy`): caption + hashtags per platform and alt text per slide; token-metered.
|
|
16
|
+
- `creatives.transcript_cut(creative_id, node_id=, remove=, base_seq=, force=)`
|
|
17
|
+
(`POST /v1/studio/creatives/{id}/transcript-cut`): delete transcript word ranges from a video clip; free.
|
|
18
|
+
- `creatives.regenerate_node(creative_id, node_id, prompt=, model=, aspect_ratio=, base_seq=, force=,
|
|
19
|
+
idempotency_key=)` (`POST /v1/studio/creatives/{id}/nodes/{nodeId}/regenerate`): new picture for an image node,
|
|
20
|
+
cast-consistent; billed like an image generation.
|
|
21
|
+
- `media_ops.quote` / `run` / `run_and_wait` accept `mask_png_b64=` for `image.inpaint` / `image.erase`.
|
|
22
|
+
- `videos.create` / `images.generate` document `reference_asset_ids` (Studio image assets as references).
|
|
23
|
+
- Regenerated `_types.py`: `CreativeCast`, `CreativePagedBuildRequest`, `StudioCreativePagedBuild`,
|
|
24
|
+
`CreativePrintLintIssue`, `StudioPostCopyRequest`, `StudioPostCopy`, `CreativeTranscriptCutRequest` / `Result`,
|
|
25
|
+
`CreativeRegenerateNodeRequest` / `Result`; `CreativeOp` gains `trimVideo`, `splitVideo`, `setVideoRate`,
|
|
26
|
+
`addCast`, `updateCast`, `removeCast`; `StudioExport.kind` gains `carousel_png`, `carousel_pdf`, `print_pdf`.
|
|
27
|
+
|
|
28
|
+
## [0.66.0] - 2026-10-20
|
|
29
|
+
|
|
30
|
+
- New `client.media_ops` for codai Studio media operations (AR-02): `list()`, `quote(op, asset_ids, params)`,
|
|
31
|
+
`run(op, asset_ids, params, idempotency_key=)` (a `media_op.result` for sync ops, a `media_op.job` for async ops),
|
|
32
|
+
`job(id)`, `wait(id, interval=, timeout=)` and `run_and_wait(...)`; helpers `is_media_op_job`,
|
|
33
|
+
`MEDIA_JOB_TERMINAL_STATUSES`.
|
|
34
|
+
- Creatives: `CreativeKind` gains `audio` (songs and podcasts); new generated types `CreativeAudio`,
|
|
35
|
+
`CreativeAudioTrack`, `CreativeAudioClip`, `CreativeAudioSection`, `CreativeAudioFx` and the media-op schemas.
|
|
36
|
+
- New `client.lyrics` (MU-06): `write(brief, language, genre=, mood=, structure=, syllables_per_line=,
|
|
37
|
+
rhyme_scheme=, lines_per_section=, title=, idempotency_key=)` (`POST /v1/studio/lyrics`) and `align(creative_id,
|
|
38
|
+
clip_id, lyrics_text, language=, apply=, base_seq=, retranscribe=, idempotency_key=)` (`POST /v1/studio/lyrics/align`,
|
|
39
|
+
timed lines + LRC).
|
|
40
|
+
- `client.creatives.render_audio(creative_id, formats=, stems=, lrc=, loudness=, title=, idempotency_key=)` (MU-05):
|
|
41
|
+
mixdown + mastering + exports of an `audio` creative. New generated types `StudioLyrics*`,
|
|
42
|
+
`CreativeAudioRenderRequest`, `CreativeAudioRenderAccepted`, `StudioAudioRender`; `RenderCreativeBody` /
|
|
43
|
+
`RenderCreativeResponse202` / `GetRenderResponse` are now video | audio unions. The live jam WebSocket
|
|
44
|
+
(`/v1/studio/jam`) has no Python helper; see the Lyrics & live jam docs page for the protocol.
|
|
45
|
+
|
|
46
|
+
## [0.65.0] - 2026-10-20
|
|
47
|
+
|
|
48
|
+
- Vault guards v4 (V-18, V-19, V-21, V-32, V-35): `vault.update_settings(default_tier=, guards=)` changes the anomaly
|
|
49
|
+
guards (new host in 30 days, burst, allowed hours; an anomaly forces t4 with reason `anomaly:new_host|burst|hour`);
|
|
50
|
+
`vault.lock(via=)` is the panic lock (revokes grants, denies pending approvals, agent uses then answer
|
|
51
|
+
`vault_locked`); `vault.unlock_challenge()` + `vault.unlock(challenge, proof)` end a lock with a device-key or
|
|
52
|
+
passkey proof over `vault_unlock_message(challenge, device_id_or_passkey)`; `vault.limits()` /
|
|
53
|
+
`vault.set_limits(item_id, per_minute, per_day, units_per_day)` manage per-handle caps (over a cap the broker calls
|
|
54
|
+
raise a 429 error with code `vault_rate_limited` and `Retry-After`); `vault.revoke_task_grants(task)` ends the
|
|
55
|
+
grants of a finished task. Generated types gain `VaultGuards`, `VaultItemLimits`, `VaultLockResult`,
|
|
56
|
+
`VaultUnlockChallenge`.
|
|
57
|
+
|
|
58
|
+
## [0.64.0] - 2026-10-20
|
|
59
|
+
|
|
60
|
+
- Prompt organisation (PR-04/05/07): prompt rows carry `tags`, `priority` (0–3), `recurrence`
|
|
61
|
+
(`{"every": "day"|"week"|"month", "at"?}` or `{"on": "session_end"}`), `next_prompt_id`, `launch`
|
|
62
|
+
(`{"agent"?, "model"?, "folder"?}`) and `is_template`, also accepted by `prompts.create` / `prompts.update`.
|
|
63
|
+
`prompts.list` takes `tag` (str or list, AND), `priority_min`, `q`, `templates="only"|"exclude"`, `sort` and `order`.
|
|
64
|
+
- New prompt methods: `prompts.export_prompts(format="csv"|"md", ...)` (`GET /v1/prompts/export`, returns the text),
|
|
65
|
+
`prompts.bulk(ids, action, ...)` (`POST /v1/prompts/bulk` → `{"updated": n}`), `prompts.events(id)`
|
|
66
|
+
(`GET /v1/prompts/{id}/events`) and `prompts.instantiate(id)` (`POST /v1/prompts/{id}/instantiate`).
|
|
67
|
+
- Generated types: `Prompt` gains the organise fields, new `PromptRecurrence`, `PromptLaunchConfig`, `PromptEvent`,
|
|
68
|
+
`PromptBulkRequest`; sessions gain `stub` (create with `stub: True` for a title-only mirror) and
|
|
69
|
+
`SessionControlKind` gains `hydrate` (session owner only) to ask the executor for the transcript.
|
|
70
|
+
|
|
71
|
+
## [0.63.0] - 2026-10-19
|
|
72
|
+
|
|
73
|
+
- Sandboxes v2 are generally available and the default backend: `sandboxes.create()` without `backend` starts a
|
|
74
|
+
v2 pod (the gateway falls back to v1 when v2 is unavailable for the key; read `backend` on the reply). Pass
|
|
75
|
+
`backend="v1"` for Cloud Run.
|
|
76
|
+
- v2 now accepts `egress` (`pypi` / `npm` preset or an allowlist, through the codai egress proxy), `inputs` on
|
|
77
|
+
exec and `artifacts()`; the image ships Node 24 + npm. `snapshot()` stays v1 only (409 `not_supported_on_v2`).
|
|
78
|
+
- Documented caps: 5 running v2 sandboxes per user (429 `sandbox_concurrency_limit`), 10 paused per user
|
|
79
|
+
(429 `sandbox_paused_limit` on `pause()`), platform capacity 503 `sandbox_capacity` (retry). Docstrings only;
|
|
80
|
+
no signature changes.
|
|
81
|
+
|
|
82
|
+
## [0.62.0] - 2026-10-20
|
|
83
|
+
|
|
84
|
+
- New `client.os_gate` for the OS protection gate: `policy()` (`GET /v1/policy`, `{"os_gate": {"allow_override": bool}}`
|
|
85
|
+
folded over every org of the caller, strictest wins; a 503 `policy_unavailable` means keep your cached value) and
|
|
86
|
+
`record_event(action, checks, surface, app_version, at)` (`POST /v1/os-gate/events`, 202 `{"ok": True}`; audit an
|
|
87
|
+
override granted/revoked with check ids, surface, app version and time only). Typed shapes `PolicyResponse`,
|
|
88
|
+
`OsGateEvent`, `OsGateEventAccepted` in `codai._types`.
|
|
89
|
+
|
|
90
|
+
## [0.61.0] - 2026-10-20
|
|
91
|
+
|
|
92
|
+
- `client.memory.delete_all()` (`DELETE /v1/memory?confirm=all`, AL-234): erase every memory of your account in one
|
|
93
|
+
call; returns `{"deleted": {tier: n}, "total": n}`.
|
|
94
|
+
|
|
95
|
+
## [0.60.0] - 2026-10-19
|
|
96
|
+
|
|
97
|
+
- Vault approvals bind the request preview and use number matching (V-30/V-31): `vault.use` / `vault.http` /
|
|
98
|
+
`vault.resolve` answers carry `match_number`; `vault.decide(..., match_number=...)` sends the number the user
|
|
99
|
+
tapped with a device or passkey proof over the approve/v3 message (403 `match_required` / `match_mismatch`).
|
|
100
|
+
|
|
101
|
+
## [0.59.0] - 2026-10-19
|
|
102
|
+
|
|
103
|
+
- New `client.productions` for codai Studio brief → promo video (RC-20): `create(brief, language=, aspect_ratio=,
|
|
104
|
+
starter=, voice=, narration=, budget_micro_usd=, title=, idempotency_key=)`, `retrieve(id)`, `wait(id)`, `run(brief)`.
|
|
105
|
+
|
|
106
|
+
## [0.58.0] - 2026-10-19
|
|
107
|
+
|
|
108
|
+
- Studio templates (RC-29): `client.templates.list(source=, locale=, month=)`; lists include the 40 built-in starter
|
|
109
|
+
templates (`source: "starter"`, ids `starter:<slug>:<en|ro>`) after your own. A starter id works in `retrieve`,
|
|
110
|
+
`creatives.create({"template": ...})` and batch `template_id`.
|
|
111
|
+
|
|
112
|
+
## [0.57.0] - 2026-10-19
|
|
113
|
+
|
|
114
|
+
- New `client.vault.devices` for hardware-backed device approval keys (V-27): `challenge()`,
|
|
115
|
+
`enroll(device_id, kind, name, surface, public_key, nonce, vault_signature, device_signature, attestation=)`,
|
|
116
|
+
`list()`, `rename(device_id, name)` and `revoke(device_id)`.
|
|
117
|
+
- `vault.decide(..., proof=)` sends a v2 proof (`{"type": "device", "device_id", "signature"}` or
|
|
118
|
+
`{"type": "passkey", "response"}`); `signature` is now optional (a deny needs no proof), passing both raises
|
|
119
|
+
`ValueError`, and `step_up_acr` is deprecated (ignored by the gateway).
|
|
120
|
+
- Regenerated `_types.py` from the current OpenAPI spec.
|
|
121
|
+
|
|
122
|
+
## [0.56.0] - 2026-10-19
|
|
123
|
+
|
|
124
|
+
- New `client.research` for async deep research (`POST /v1/research`, `GET /v1/research/{id}`):
|
|
125
|
+
`create(question, time_budget_s=, max_sources=, include_domains=, published_after=, output_schema=, wait_s=,
|
|
126
|
+
idempotency_key=)`, `retrieve(job_id)`, `wait(job_id, interval=3.0, timeout=360.0)` and `run(question, ...)`
|
|
127
|
+
(create + wait). `RESEARCH_TERMINAL_STATUSES` exported.
|
|
128
|
+
- `tools.search` / `tools.fetch` docstrings and generated types follow the shared web tools contract (domain,
|
|
129
|
+
publish-date and freshness filters, `content_chars`, `published_at` vs `crawled_at`, `notes`; fetch `max_chars`
|
|
130
|
+
default 8000, max 40000).
|
|
131
|
+
- Regenerated `_types.py` from the current OpenAPI spec.
|
|
132
|
+
|
|
133
|
+
## [0.55.0] - 2026-10-19
|
|
134
|
+
|
|
135
|
+
- `billing.studio_quote(action, ...)` — `GET /v1/studio/quote`: the price of a codai Studio action (USD and wallet
|
|
136
|
+
EUR micros) and your spendable balance before you run it.
|
|
137
|
+
- `ext={"idempotency_key": ...}` sends `Idempotency-Key`: a retried billed Studio POST replays the first answer
|
|
138
|
+
instead of charging twice (24 h).
|
|
139
|
+
- Paid Studio calls can now answer 402 `insufficient_funds` (`quote_micro_eur`, `balance_micro_eur`) as a `CodaiError`.
|
|
140
|
+
|
|
141
|
+
## [0.54.0] - 2026-10-18
|
|
142
|
+
|
|
143
|
+
- Vault: `client.vault` covers every `/v1/vault/*` route (account, settings, vaults, items, cloud copy, rules,
|
|
144
|
+
grants, events, approvals + `decide`, and the agent broker `catalog` / `use` / `http_call` / `resolve`). The server
|
|
145
|
+
only stores ciphertext built client-side; the broker calls never return secret values. Typed dicts for the
|
|
146
|
+
`Vault*` schemas.
|
|
147
|
+
- Studio share links: `creatives.create_share(..., expires_in_days=...)` also accepts `"never"`; omitted now means 30 days
|
|
148
|
+
(was: never expires).
|
|
149
|
+
- Public review dicts carry `decided_by_kind` (`"self_declared"`): the approver name is typed by the link holder, not verified.
|
|
150
|
+
|
|
9
151
|
## [0.53.0] - 2026-10-17
|
|
10
152
|
|
|
11
153
|
- Sandboxes v2 (closed canary): `sandboxes.create(backend="v2", template=...)` with templates `codai-base`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codai-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.67.0
|
|
4
4
|
Summary: Official Python SDK for the codai AI gateway — chat, messages, responses, streaming, agents, sessions, hosts, tasks, account.
|
|
5
5
|
Project-URL: Homepage, https://codai.ro
|
|
6
6
|
Project-URL: Repository, https://github.com/codai-ro/codai-sdk-python
|
|
@@ -35,13 +35,21 @@ Zero dependencies (stdlib only), Python 3.9+.
|
|
|
35
35
|
pip install codai-sdk
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
>
|
|
39
|
-
>
|
|
38
|
+
> **The package is `codai-sdk`.** `pip install codai` installs an unrelated
|
|
39
|
+
> project from another author that uses the same import name and will shadow
|
|
40
|
+
> this SDK. If `from codai import Codai` fails, run `pip uninstall codai` and
|
|
41
|
+
> `pip install codai-sdk`.
|
|
42
|
+
|
|
43
|
+
You need a codai API key — keys start with `codai_`. Create one at
|
|
44
|
+
**[hub.codai.ro](https://hub.codai.ro)** and export it as `CODAI_API_KEY`.
|
|
45
|
+
The import name is `codai`:
|
|
40
46
|
|
|
41
47
|
```python
|
|
48
|
+
import os
|
|
49
|
+
|
|
42
50
|
from codai import Codai
|
|
43
51
|
|
|
44
|
-
client = Codai(api_key="
|
|
52
|
+
client = Codai(api_key=os.environ["CODAI_API_KEY"], session_id="my-project")
|
|
45
53
|
|
|
46
54
|
# Chat (OpenAI-compatible, smart-routed)
|
|
47
55
|
result = client.chat([{"role": "user", "content": "Explain asyncio.gather"}])
|
|
@@ -11,13 +11,21 @@ Zero dependencies (stdlib only), Python 3.9+.
|
|
|
11
11
|
pip install codai-sdk
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
>
|
|
15
|
-
>
|
|
14
|
+
> **The package is `codai-sdk`.** `pip install codai` installs an unrelated
|
|
15
|
+
> project from another author that uses the same import name and will shadow
|
|
16
|
+
> this SDK. If `from codai import Codai` fails, run `pip uninstall codai` and
|
|
17
|
+
> `pip install codai-sdk`.
|
|
18
|
+
|
|
19
|
+
You need a codai API key — keys start with `codai_`. Create one at
|
|
20
|
+
**[hub.codai.ro](https://hub.codai.ro)** and export it as `CODAI_API_KEY`.
|
|
21
|
+
The import name is `codai`:
|
|
16
22
|
|
|
17
23
|
```python
|
|
24
|
+
import os
|
|
25
|
+
|
|
18
26
|
from codai import Codai
|
|
19
27
|
|
|
20
|
-
client = Codai(api_key="
|
|
28
|
+
client = Codai(api_key=os.environ["CODAI_API_KEY"], session_id="my-project")
|
|
21
29
|
|
|
22
30
|
# Chat (OpenAI-compatible, smart-routed)
|
|
23
31
|
result = client.chat([{"role": "user", "content": "Explain asyncio.gather"}])
|
|
@@ -4,9 +4,11 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codai-sdk"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.67.0"
|
|
8
8
|
description = "Official Python SDK for the codai AI gateway — chat, messages, responses, streaming, agents, sessions, hosts, tasks, account."
|
|
9
9
|
readme = "README.md"
|
|
10
|
+
|
|
11
|
+
|
|
10
12
|
license = "MIT"
|
|
11
13
|
requires-python = ">=3.9"
|
|
12
14
|
authors = [{ name = "codai", email = "support@codai.ro" }]
|
|
@@ -51,11 +51,19 @@ from .resources import (
|
|
|
51
51
|
Creatives,
|
|
52
52
|
BrandKits,
|
|
53
53
|
Templates,
|
|
54
|
+
Productions,
|
|
55
|
+
MediaOps,
|
|
56
|
+
Lyrics,
|
|
57
|
+
MEDIA_JOB_TERMINAL_STATUSES,
|
|
58
|
+
is_media_op_job,
|
|
59
|
+
is_paged_build,
|
|
54
60
|
Exports,
|
|
55
61
|
Batches,
|
|
56
62
|
Shares,
|
|
57
63
|
share_token_from,
|
|
58
64
|
VoiceRevocations,
|
|
65
|
+
Vault,
|
|
66
|
+
vault_unlock_message,
|
|
59
67
|
AbuseReports,
|
|
60
68
|
Provenance,
|
|
61
69
|
Devices,
|
|
@@ -95,6 +103,7 @@ from .resources import (
|
|
|
95
103
|
Responses,
|
|
96
104
|
Sessions,
|
|
97
105
|
Settings,
|
|
106
|
+
OsGate,
|
|
98
107
|
Sfx,
|
|
99
108
|
SfxSearchResult,
|
|
100
109
|
SystemOne,
|
|
@@ -111,6 +120,8 @@ from .resources import (
|
|
|
111
120
|
verify_attestation_with_keys,
|
|
112
121
|
verify_resolve_webhook,
|
|
113
122
|
settings_conflict_current,
|
|
123
|
+
Research,
|
|
124
|
+
RESEARCH_TERMINAL_STATUSES,
|
|
114
125
|
)
|
|
115
126
|
|
|
116
127
|
__all__ = [
|
|
@@ -139,6 +150,9 @@ __all__ = [
|
|
|
139
150
|
"RESOLVE_OPERATION_METHODS",
|
|
140
151
|
"RESOLVE_ATTESTATION_PAYLOAD_TYPE",
|
|
141
152
|
"RESOLVE_TERMINAL_STATUSES",
|
|
153
|
+
"Research",
|
|
154
|
+
"RESEARCH_TERMINAL_STATUSES",
|
|
155
|
+
"Vault",
|
|
142
156
|
"ResolveError",
|
|
143
157
|
"ResolveInsufficientFundsError",
|
|
144
158
|
"STREAMING_OPERATIONS",
|
|
@@ -150,10 +164,9 @@ __all__ = [
|
|
|
150
164
|
"verify_resolve_webhook",
|
|
151
165
|
"settings_conflict_current",
|
|
152
166
|
"share_token_from",
|
|
167
|
+
"vault_unlock_message",
|
|
153
168
|
]
|
|
154
|
-
__version__ = "0.
|
|
155
|
-
|
|
156
|
-
|
|
169
|
+
__version__ = "0.67.0"
|
|
157
170
|
class _CallableGroup:
|
|
158
171
|
"""A resource group that is also callable — keeps ``client.chat(...)``,
|
|
159
172
|
``client.embeddings(...)``, ``client.models()`` and ``client.feedback(...)``
|
|
@@ -229,6 +242,12 @@ class Codai:
|
|
|
229
242
|
self.brand_kits = BrandKits(http)
|
|
230
243
|
# Studio templates saved from your creatives (creatives.save_template); free.
|
|
231
244
|
self.templates = Templates(http)
|
|
245
|
+
# Studio productions: brief -> storyboard -> images + voice-over -> creative -> draft render -> review.
|
|
246
|
+
self.productions = Productions(http)
|
|
247
|
+
# Studio media operations: background removal, upscale, inpaint, stems, denoise, MIDI, mastering, ACE-Step music.
|
|
248
|
+
self.media_ops = MediaOps(http)
|
|
249
|
+
# Studio lyrics: write (syllable + rhyme checked, token-metered) and align to an audio clip (LRC + setLyrics).
|
|
250
|
+
self.lyrics = Lyrics(http)
|
|
232
251
|
# Studio FCPXML exports queued with creatives.export_fcpxml; wait() polls until the zip is ready.
|
|
233
252
|
self.exports = Exports(http)
|
|
234
253
|
# Studio batches: one creative per CSV / sheet row (free; row translations and renders billed); wait() polls.
|
|
@@ -237,6 +256,8 @@ class Codai:
|
|
|
237
256
|
self.shares = Shares(http)
|
|
238
257
|
# Public takedown tickets for voices cloned in codai Studio (no key needed by the route).
|
|
239
258
|
self.voice_revocations = VoiceRevocations(http)
|
|
259
|
+
# Zero-knowledge credentials vault: ciphertext only; the agent broker calls never return secret values.
|
|
260
|
+
self.vault = Vault(http)
|
|
240
261
|
# Public DSA notices about codai Studio share / review links (no key needed by the route).
|
|
241
262
|
self.abuse_reports = AbuseReports(http)
|
|
242
263
|
# Public AI-provenance checker: which codai marks a file carries (no key needed by the route).
|
|
@@ -246,6 +267,8 @@ class Codai:
|
|
|
246
267
|
self.health = Health(http)
|
|
247
268
|
self.agents = Agents(http)
|
|
248
269
|
self.tools = Tools(http)
|
|
270
|
+
# Async deep research (/v1/research): create / retrieve / wait / run -> cited report + sources.
|
|
271
|
+
self.research = Research(http)
|
|
249
272
|
# Typed card data (/v1/cards/*): weather / places / geocode / static_map / fx / unfurl -> {block, provenance}.
|
|
250
273
|
self.cards = Cards(http)
|
|
251
274
|
self.tasks = Tasks(http)
|
|
@@ -255,13 +278,15 @@ class Codai:
|
|
|
255
278
|
self.orgs = Orgs(http)
|
|
256
279
|
self.projects = Projects(http)
|
|
257
280
|
self.environments = Environments(http)
|
|
258
|
-
# Agent sandboxes (
|
|
281
|
+
# Agent sandboxes (backend v2 by default): isolated gVisor workspaces — exec / files / artifacts / run.
|
|
259
282
|
self.sandboxes = Sandboxes(http)
|
|
260
283
|
# EXPERIMENTAL (HIDE, unaudited): verify signed agent outputs — provenance only.
|
|
261
284
|
self.verify = Verify(http)
|
|
262
285
|
self.account = Account(http)
|
|
263
286
|
# Account-level settings shared by every device (per user): get() / update(partial, version=...).
|
|
264
287
|
self.settings = Settings(http)
|
|
288
|
+
# OS protection gate: policy() (org override policy) / record_event(...) (override audit).
|
|
289
|
+
self.os_gate = OsGate(http)
|
|
265
290
|
# READ-ONLY billing (plan, wallet, invoices, watch_balance); payments only via the returned links.
|
|
266
291
|
self.billing = Billing(http)
|
|
267
292
|
# Referral stats + invitees; redeem() / set_consent() go through PATCH /v1/account.
|
|
@@ -68,6 +68,8 @@ EXTENSION_HEADERS: Dict[str, str] = {
|
|
|
68
68
|
"device_platform": "x-codai-device-platform",
|
|
69
69
|
"push_token": "x-codai-push-token",
|
|
70
70
|
"share_token": "x-codai-share-token",
|
|
71
|
+
# Billed codai Studio POSTs: a retry with the same key and body replays the first answer (24 h, no double charge).
|
|
72
|
+
"idempotency_key": "Idempotency-Key",
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
RequestExtensions = Mapping[str, Any]
|
|
@@ -104,6 +104,39 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
104
104
|
"reopenPublicReviewThread": "shares.reopen",
|
|
105
105
|
"decidePublicReview": "shares.decide",
|
|
106
106
|
"createVoiceRevocation": "voice_revocations.create",
|
|
107
|
+
"getVaultAccount": "vault.account",
|
|
108
|
+
"putVaultAccount": "vault.put_account",
|
|
109
|
+
"patchVaultSettings": "vault.update_settings",
|
|
110
|
+
"lockVault": "vault.lock",
|
|
111
|
+
"createVaultUnlockChallenge": "vault.unlock_challenge",
|
|
112
|
+
"unlockVault": "vault.unlock",
|
|
113
|
+
"listVaultLimits": "vault.limits",
|
|
114
|
+
"setVaultItemLimits": "vault.set_limits",
|
|
115
|
+
"revokeVaultTaskGrants": "vault.revoke_task_grants",
|
|
116
|
+
"listVaults": "vault.vaults",
|
|
117
|
+
"createVault": "vault.create_vault",
|
|
118
|
+
"listVaultItems": "vault.items",
|
|
119
|
+
"putVaultItem": "vault.put_item",
|
|
120
|
+
"deleteVaultItem": "vault.delete_item",
|
|
121
|
+
"setVaultItemCloud": "vault.set_item_cloud",
|
|
122
|
+
"listVaultRules": "vault.rules",
|
|
123
|
+
"createVaultRule": "vault.create_rule",
|
|
124
|
+
"deleteVaultRule": "vault.delete_rule",
|
|
125
|
+
"listVaultGrants": "vault.grants",
|
|
126
|
+
"revokeVaultGrant": "vault.revoke_grant",
|
|
127
|
+
"listVaultEvents": "vault.events",
|
|
128
|
+
"listVaultApprovals": "vault.approvals",
|
|
129
|
+
"getVaultApproval": "vault.approval",
|
|
130
|
+
"decideVaultApproval": "vault.decide",
|
|
131
|
+
"createVaultDeviceChallenge": "vault.devices.challenge",
|
|
132
|
+
"enrollVaultDevice": "vault.devices.enroll",
|
|
133
|
+
"listVaultDevices": "vault.devices.list",
|
|
134
|
+
"renameVaultDevice": "vault.devices.rename",
|
|
135
|
+
"revokeVaultDevice": "vault.devices.revoke",
|
|
136
|
+
"vaultCatalog": "vault.catalog",
|
|
137
|
+
"vaultUse": "vault.use",
|
|
138
|
+
"vaultHttp": "vault.http_call",
|
|
139
|
+
"vaultResolve": "vault.resolve",
|
|
107
140
|
"createStudioAbuseReport": "abuse_reports.create",
|
|
108
141
|
"checkProvenance": "provenance.check",
|
|
109
142
|
"createStudioBatch": "batches.create",
|
|
@@ -115,6 +148,14 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
115
148
|
"zipStudioBatch": "batches.zip",
|
|
116
149
|
"saveCreativeTemplate": "creatives.save_template",
|
|
117
150
|
"listCreativeTemplates": "templates.list",
|
|
151
|
+
"createStudioProduction": "productions.create",
|
|
152
|
+
"getStudioProduction": "productions.retrieve",
|
|
153
|
+
"listStudioMediaOps": "media_ops.list",
|
|
154
|
+
"quoteStudioMediaOp": "media_ops.quote",
|
|
155
|
+
"runStudioMediaOp": "media_ops.run",
|
|
156
|
+
"getStudioMediaOpJob": "media_ops.job",
|
|
157
|
+
"writeStudioLyrics": "lyrics.write",
|
|
158
|
+
"alignStudioLyrics": "lyrics.align",
|
|
118
159
|
"getCreativeTemplate": "templates.retrieve",
|
|
119
160
|
"deleteCreativeTemplate": "templates.delete",
|
|
120
161
|
"exportCreativeFcpxml": "creatives.export_fcpxml",
|
|
@@ -122,6 +163,9 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
122
163
|
"getStudioExport": "exports.retrieve",
|
|
123
164
|
"createCreativeFromDocument": "creatives.from_document",
|
|
124
165
|
"buildCreative": "creatives.build",
|
|
166
|
+
"writeCreativePostCopy": "creatives.post_copy",
|
|
167
|
+
"transcriptCutCreative": "creatives.transcript_cut",
|
|
168
|
+
"regenerateCreativeNode": "creatives.regenerate_node",
|
|
125
169
|
"createSystemOne": "system_one.create",
|
|
126
170
|
"createTranscription": "audio.transcribe",
|
|
127
171
|
"createSpeech": "audio.speech",
|
|
@@ -145,6 +189,8 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
145
189
|
"toolsSearch": "tools.search",
|
|
146
190
|
"toolsFetch": "tools.fetch",
|
|
147
191
|
"toolsGround": "tools.ground",
|
|
192
|
+
"createResearch": "research.create",
|
|
193
|
+
"getResearch": "research.retrieve",
|
|
148
194
|
# Tasks
|
|
149
195
|
"listTasks": "tasks.list",
|
|
150
196
|
"listPendingTasks": "tasks.pending",
|
|
@@ -252,6 +298,10 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
252
298
|
"verifyPrompt": "prompts.verify",
|
|
253
299
|
"verifyPrompts": "prompts.verify_many",
|
|
254
300
|
"streamPrompts": "prompts.stream",
|
|
301
|
+
"exportPrompts": "prompts.export_prompts",
|
|
302
|
+
"bulkPrompts": "prompts.bulk",
|
|
303
|
+
"listPromptEvents": "prompts.events",
|
|
304
|
+
"instantiatePrompt": "prompts.instantiate",
|
|
255
305
|
# Transcripts
|
|
256
306
|
"listTranscripts": "transcripts.list",
|
|
257
307
|
"createTranscript": "transcripts.create",
|
|
@@ -336,6 +386,7 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
336
386
|
"searchMemories": "memory.search",
|
|
337
387
|
"createMemory": "memory.create",
|
|
338
388
|
"deleteMemory": "memory.delete",
|
|
389
|
+
"deleteAllMemories": "memory.delete_all",
|
|
339
390
|
# Sandboxes
|
|
340
391
|
"createSandbox": "sandboxes.create",
|
|
341
392
|
"listSandboxes": "sandboxes.list",
|
|
@@ -359,9 +410,12 @@ OPERATION_METHODS: Dict[str, str] = {
|
|
|
359
410
|
"patchAccount": "account.update",
|
|
360
411
|
"getBilling": "billing.get",
|
|
361
412
|
"listBillingInvoices": "billing.invoices",
|
|
413
|
+
"getStudioQuote": "billing.studio_quote",
|
|
362
414
|
"getReferrals": "referrals.get",
|
|
363
415
|
"getSettings": "settings.get",
|
|
364
416
|
"patchSettings": "settings.update",
|
|
417
|
+
"getPolicy": "os_gate.policy",
|
|
418
|
+
"recordOsGateEvent": "os_gate.record_event",
|
|
365
419
|
"getReceipt": "receipt.get",
|
|
366
420
|
"submitFeedback": "feedback.submit",
|
|
367
421
|
"listPhoneModels": "phone_models.list",
|