clark-platform-client 0.1.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.
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ dist/
7
+ build/
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: clark-platform-client
3
+ Version: 0.1.0
4
+ Summary: Typed sync/async Python client for the Clark Platform API
5
+ Project-URL: Homepage, https://www.clarkchat.com
6
+ Author: Clark Labs
7
+ License: MIT
8
+ Keywords: agent,api-client,clark,clark-labs,httpx
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.9
17
+ Requires-Dist: httpx>=0.24
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
20
+ Requires-Dist: pytest>=7.4; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # clark-platform-client
24
+
25
+ Typed, standalone Python client (sync + async) for the [Clark Platform
26
+ API](https://www.clarkchat.com) — the OpenAI-compatible-ish public HTTP API
27
+ for creating Clark agent runs, streaming their progress, and reading back
28
+ chat-completion/response objects, usage, artifacts, and durable memory.
29
+
30
+ This client implements the wire contract documented in
31
+ [`platform/clients/API_CONTRACT.md`](../API_CONTRACT.md) in the Clark
32
+ monorepo. If something here disagrees with that file, the contract file is
33
+ the source of truth.
34
+
35
+ - Only required dependency: [`httpx`](https://www.python-httpx.org/).
36
+ - No `pydantic` — models are plain stdlib `dataclasses`.
37
+ - Both a sync client (`ClarkClient`) and an async client (`AsyncClarkClient`);
38
+ pick one without pulling in `asyncio` machinery you don't need.
39
+ - Python 3.9+.
40
+
41
+ ## Install
42
+
43
+ Not published to PyPI yet. Install directly from a local checkout of this
44
+ directory:
45
+
46
+ ```bash
47
+ # with uv, inside another project
48
+ uv add /path/to/clark/platform/clients/python
49
+
50
+ # or with pip, editable install for local development
51
+ pip install -e /path/to/clark/platform/clients/python
52
+ ```
53
+
54
+ ## Authentication
55
+
56
+ Platform API keys (`clk_live_...`) are minted from the signed-in `/platform`
57
+ page in the Clark web app — there is no public self-serve key-creation
58
+ endpoint. Every key carries a fixed scope set
59
+ (`responses:create`, `responses:read`, `models:read`, `artifacts:read`,
60
+ `memories:read`).
61
+
62
+ ```python
63
+ from clark_platform import ClarkClient
64
+
65
+ client = ClarkClient(api_key="clk_live_xxxxxxxxxxxxxxxxxxxx")
66
+ ```
67
+
68
+ By default the client talks to production (`https://www.clarkchat.com`).
69
+
70
+ ## Quickstart — sync
71
+
72
+ ```python
73
+ from clark_platform import ClarkClient
74
+
75
+ with ClarkClient(api_key="clk_live_...") as client:
76
+ models = client.models.list()
77
+ print([m.id for m in models.data])
78
+
79
+ response = client.responses.create(model="clark", input="Summarize this repo's README.")
80
+ print(response.status, response.output_text)
81
+
82
+ chat = client.chat.completions.create(
83
+ model="openrouter:qwen35_flash",
84
+ messages=[{"role": "user", "content": "hello"}],
85
+ )
86
+ print(chat.output_text)
87
+ ```
88
+
89
+ ## Quickstart — async
90
+
91
+ ```python
92
+ import asyncio
93
+ from clark_platform import AsyncClarkClient
94
+
95
+
96
+ async def main() -> None:
97
+ async with AsyncClarkClient(api_key="clk_live_...") as client:
98
+ response = await client.responses.create(model="clark", input="hello")
99
+ print(response.output_text)
100
+
101
+
102
+ asyncio.run(main())
103
+ ```
104
+
105
+ ## Two families of tier: agentic vs. `clark-code` passthrough
106
+
107
+ The API has two entirely different behaviors depending on `model`:
108
+
109
+ 1. **Agentic tiers** (`clark`, `clark_max`, `openrouter:*`) — Clark runs its
110
+ own internal agent loop and returns only the final projected answer.
111
+ `tools`/`tool_choice` are not accepted by these methods (the server
112
+ rejects them with `400 unsupported_parameter`, so the SDK doesn't even
113
+ expose those parameters on `responses.create`/`chat.completions.create`).
114
+ 2. **The `clark-code` passthrough tier** — your `messages` (including prior
115
+ `tool_calls`/`tool` messages) are forwarded verbatim to the underlying
116
+ OpenRouter-compatible model, and native OpenAI-format `tool_calls` come
117
+ back for you to execute yourself. Clark does not run tools for this tier.
118
+ This is **only** available via `/v1/chat/completions`, never
119
+ `/v1/responses`.
120
+
121
+ Because these are different response *shapes*, the passthrough tier is
122
+ exposed via clearly separate methods that return the raw upstream JSON dict
123
+ instead of a typed Clark object:
124
+
125
+ ```python
126
+ # Agentic — typed ChatCompletionObject, no tools allowed.
127
+ chat = client.chat.completions.create(model="clark", messages=[...])
128
+
129
+ # Passthrough — raw OpenAI-compatible dict, tools/tool_choice forwarded verbatim.
130
+ raw = client.chat.completions.create_passthrough(
131
+ model="clark-code",
132
+ messages=[...],
133
+ tools=[{"type": "function", "function": {...}}],
134
+ )
135
+ ```
136
+
137
+ ## Streaming
138
+
139
+ ### `responses.stream(...)`
140
+
141
+ Named SSE events (`response.created`, `response.output_text.delta`,
142
+ `response.artifact.completed`, `response.usage.updated`,
143
+ `response.completed`/`response.failed`, ...). Per the contract, the full
144
+ answer arrives as a **single** `response.output_text.delta` event, not
145
+ token-by-token — the iterator API is for symmetry with chat-completions
146
+ streaming and future finer-grained deltas.
147
+
148
+ ```python
149
+ for event in client.responses.stream(model="clark", input="hello"):
150
+ if event.type == "response.output_text.delta":
151
+ print(event.delta, end="")
152
+ elif event.type == "response.completed":
153
+ print("\n--- done ---", event.response.status)
154
+ ```
155
+
156
+ Async:
157
+
158
+ ```python
159
+ async for event in async_client.responses.stream(model="clark", input="hello"):
160
+ ...
161
+ ```
162
+
163
+ ### `chat.completions.stream(...)`
164
+
165
+ Plain `data:`-only SSE (no `event:` name), `chat.completion.chunk` objects,
166
+ terminated by the server's literal `data: [DONE]` (already consumed for you
167
+ — it never appears as a yielded item):
168
+
169
+ ```python
170
+ for chunk in client.chat.completions.stream(
171
+ model="clark",
172
+ messages=[{"role": "user", "content": "hello"}],
173
+ stream_options={"include_usage": True},
174
+ ):
175
+ for choice in chunk.choices:
176
+ if choice.delta.content:
177
+ print(choice.delta.content, end="")
178
+ if chunk.usage:
179
+ print("\nusage:", chunk.usage)
180
+ ```
181
+
182
+ ### `chat.completions.stream_passthrough(...)`
183
+
184
+ Same framing, but yields raw upstream JSON dicts (native `tool_calls`
185
+ deltas and all) instead of a typed `ChatCompletionChunk`, since the
186
+ passthrough tier's chunk shape is whatever the upstream OpenAI-compatible
187
+ provider sends.
188
+
189
+ ## Other endpoints
190
+
191
+ ```python
192
+ # Poll a response (e.g. after background=True, or to recover from a chat
193
+ # completions timeout by replacing the "chatcmpl_" prefix with "resp_").
194
+ response = client.responses.get("resp_01jz4n8h2f7g9k4q2m6s")
195
+
196
+ # Progress events for a response.
197
+ events = client.responses.list_events("resp_01jz4n8h2f7g9k4q2m6s", after_seq=0, limit=200)
198
+
199
+ # Durable memory.
200
+ memories = client.memories.list(q="deploy checklist")
201
+ ```
202
+
203
+ ## Errors
204
+
205
+ All non-2xx responses raise `ClarkApiError`, parsed from the API's error
206
+ envelope:
207
+
208
+ ```python
209
+ from clark_platform import ClarkApiError
210
+
211
+ try:
212
+ client.responses.create(model="clark", input="hello")
213
+ except ClarkApiError as err:
214
+ print(err.status_code, err.type, err.code, err.param, err.message)
215
+ ```
216
+
217
+ Network-level failures (connection errors, timeouts, DNS failures) are
218
+ **not** wrapped — they surface as the underlying `httpx` exception (e.g.
219
+ `httpx.ConnectError`, `httpx.TimeoutException`), so you can rely on
220
+ `httpx`'s own exception hierarchy for those.
221
+
222
+ ## Timeouts
223
+
224
+ Non-background `responses`/`chat.completions` calls can legitimately take up
225
+ to ~120s server-side (`CLARK_PLATFORM_RESPONSE_WAIT_MS`, default 120000ms).
226
+ The client defaults its `httpx` timeout to 150s to comfortably clear that;
227
+ pass your own `timeout=` (or a pre-configured `http_client=`) to
228
+ `ClarkClient`/`AsyncClarkClient` to change it.
229
+
230
+ ## Development
231
+
232
+ ```bash
233
+ cd platform/clients/python
234
+ uv sync --python 3.12
235
+ uv run --python 3.12 pytest -q
236
+ ```
237
+
238
+ `examples/live_smoke.py` is an opt-in, real-network smoke test — it reads
239
+ `CLARK_API_BASE_URL`, `CLARK_API_KEY`, and `CLARK_TEST_MODEL` from the
240
+ environment and exits early with a clear message if `CLARK_API_KEY` is
241
+ unset. It is not part of the test suite and is never run automatically.
@@ -0,0 +1,219 @@
1
+ # clark-platform-client
2
+
3
+ Typed, standalone Python client (sync + async) for the [Clark Platform
4
+ API](https://www.clarkchat.com) — the OpenAI-compatible-ish public HTTP API
5
+ for creating Clark agent runs, streaming their progress, and reading back
6
+ chat-completion/response objects, usage, artifacts, and durable memory.
7
+
8
+ This client implements the wire contract documented in
9
+ [`platform/clients/API_CONTRACT.md`](../API_CONTRACT.md) in the Clark
10
+ monorepo. If something here disagrees with that file, the contract file is
11
+ the source of truth.
12
+
13
+ - Only required dependency: [`httpx`](https://www.python-httpx.org/).
14
+ - No `pydantic` — models are plain stdlib `dataclasses`.
15
+ - Both a sync client (`ClarkClient`) and an async client (`AsyncClarkClient`);
16
+ pick one without pulling in `asyncio` machinery you don't need.
17
+ - Python 3.9+.
18
+
19
+ ## Install
20
+
21
+ Not published to PyPI yet. Install directly from a local checkout of this
22
+ directory:
23
+
24
+ ```bash
25
+ # with uv, inside another project
26
+ uv add /path/to/clark/platform/clients/python
27
+
28
+ # or with pip, editable install for local development
29
+ pip install -e /path/to/clark/platform/clients/python
30
+ ```
31
+
32
+ ## Authentication
33
+
34
+ Platform API keys (`clk_live_...`) are minted from the signed-in `/platform`
35
+ page in the Clark web app — there is no public self-serve key-creation
36
+ endpoint. Every key carries a fixed scope set
37
+ (`responses:create`, `responses:read`, `models:read`, `artifacts:read`,
38
+ `memories:read`).
39
+
40
+ ```python
41
+ from clark_platform import ClarkClient
42
+
43
+ client = ClarkClient(api_key="clk_live_xxxxxxxxxxxxxxxxxxxx")
44
+ ```
45
+
46
+ By default the client talks to production (`https://www.clarkchat.com`).
47
+
48
+ ## Quickstart — sync
49
+
50
+ ```python
51
+ from clark_platform import ClarkClient
52
+
53
+ with ClarkClient(api_key="clk_live_...") as client:
54
+ models = client.models.list()
55
+ print([m.id for m in models.data])
56
+
57
+ response = client.responses.create(model="clark", input="Summarize this repo's README.")
58
+ print(response.status, response.output_text)
59
+
60
+ chat = client.chat.completions.create(
61
+ model="openrouter:qwen35_flash",
62
+ messages=[{"role": "user", "content": "hello"}],
63
+ )
64
+ print(chat.output_text)
65
+ ```
66
+
67
+ ## Quickstart — async
68
+
69
+ ```python
70
+ import asyncio
71
+ from clark_platform import AsyncClarkClient
72
+
73
+
74
+ async def main() -> None:
75
+ async with AsyncClarkClient(api_key="clk_live_...") as client:
76
+ response = await client.responses.create(model="clark", input="hello")
77
+ print(response.output_text)
78
+
79
+
80
+ asyncio.run(main())
81
+ ```
82
+
83
+ ## Two families of tier: agentic vs. `clark-code` passthrough
84
+
85
+ The API has two entirely different behaviors depending on `model`:
86
+
87
+ 1. **Agentic tiers** (`clark`, `clark_max`, `openrouter:*`) — Clark runs its
88
+ own internal agent loop and returns only the final projected answer.
89
+ `tools`/`tool_choice` are not accepted by these methods (the server
90
+ rejects them with `400 unsupported_parameter`, so the SDK doesn't even
91
+ expose those parameters on `responses.create`/`chat.completions.create`).
92
+ 2. **The `clark-code` passthrough tier** — your `messages` (including prior
93
+ `tool_calls`/`tool` messages) are forwarded verbatim to the underlying
94
+ OpenRouter-compatible model, and native OpenAI-format `tool_calls` come
95
+ back for you to execute yourself. Clark does not run tools for this tier.
96
+ This is **only** available via `/v1/chat/completions`, never
97
+ `/v1/responses`.
98
+
99
+ Because these are different response *shapes*, the passthrough tier is
100
+ exposed via clearly separate methods that return the raw upstream JSON dict
101
+ instead of a typed Clark object:
102
+
103
+ ```python
104
+ # Agentic — typed ChatCompletionObject, no tools allowed.
105
+ chat = client.chat.completions.create(model="clark", messages=[...])
106
+
107
+ # Passthrough — raw OpenAI-compatible dict, tools/tool_choice forwarded verbatim.
108
+ raw = client.chat.completions.create_passthrough(
109
+ model="clark-code",
110
+ messages=[...],
111
+ tools=[{"type": "function", "function": {...}}],
112
+ )
113
+ ```
114
+
115
+ ## Streaming
116
+
117
+ ### `responses.stream(...)`
118
+
119
+ Named SSE events (`response.created`, `response.output_text.delta`,
120
+ `response.artifact.completed`, `response.usage.updated`,
121
+ `response.completed`/`response.failed`, ...). Per the contract, the full
122
+ answer arrives as a **single** `response.output_text.delta` event, not
123
+ token-by-token — the iterator API is for symmetry with chat-completions
124
+ streaming and future finer-grained deltas.
125
+
126
+ ```python
127
+ for event in client.responses.stream(model="clark", input="hello"):
128
+ if event.type == "response.output_text.delta":
129
+ print(event.delta, end="")
130
+ elif event.type == "response.completed":
131
+ print("\n--- done ---", event.response.status)
132
+ ```
133
+
134
+ Async:
135
+
136
+ ```python
137
+ async for event in async_client.responses.stream(model="clark", input="hello"):
138
+ ...
139
+ ```
140
+
141
+ ### `chat.completions.stream(...)`
142
+
143
+ Plain `data:`-only SSE (no `event:` name), `chat.completion.chunk` objects,
144
+ terminated by the server's literal `data: [DONE]` (already consumed for you
145
+ — it never appears as a yielded item):
146
+
147
+ ```python
148
+ for chunk in client.chat.completions.stream(
149
+ model="clark",
150
+ messages=[{"role": "user", "content": "hello"}],
151
+ stream_options={"include_usage": True},
152
+ ):
153
+ for choice in chunk.choices:
154
+ if choice.delta.content:
155
+ print(choice.delta.content, end="")
156
+ if chunk.usage:
157
+ print("\nusage:", chunk.usage)
158
+ ```
159
+
160
+ ### `chat.completions.stream_passthrough(...)`
161
+
162
+ Same framing, but yields raw upstream JSON dicts (native `tool_calls`
163
+ deltas and all) instead of a typed `ChatCompletionChunk`, since the
164
+ passthrough tier's chunk shape is whatever the upstream OpenAI-compatible
165
+ provider sends.
166
+
167
+ ## Other endpoints
168
+
169
+ ```python
170
+ # Poll a response (e.g. after background=True, or to recover from a chat
171
+ # completions timeout by replacing the "chatcmpl_" prefix with "resp_").
172
+ response = client.responses.get("resp_01jz4n8h2f7g9k4q2m6s")
173
+
174
+ # Progress events for a response.
175
+ events = client.responses.list_events("resp_01jz4n8h2f7g9k4q2m6s", after_seq=0, limit=200)
176
+
177
+ # Durable memory.
178
+ memories = client.memories.list(q="deploy checklist")
179
+ ```
180
+
181
+ ## Errors
182
+
183
+ All non-2xx responses raise `ClarkApiError`, parsed from the API's error
184
+ envelope:
185
+
186
+ ```python
187
+ from clark_platform import ClarkApiError
188
+
189
+ try:
190
+ client.responses.create(model="clark", input="hello")
191
+ except ClarkApiError as err:
192
+ print(err.status_code, err.type, err.code, err.param, err.message)
193
+ ```
194
+
195
+ Network-level failures (connection errors, timeouts, DNS failures) are
196
+ **not** wrapped — they surface as the underlying `httpx` exception (e.g.
197
+ `httpx.ConnectError`, `httpx.TimeoutException`), so you can rely on
198
+ `httpx`'s own exception hierarchy for those.
199
+
200
+ ## Timeouts
201
+
202
+ Non-background `responses`/`chat.completions` calls can legitimately take up
203
+ to ~120s server-side (`CLARK_PLATFORM_RESPONSE_WAIT_MS`, default 120000ms).
204
+ The client defaults its `httpx` timeout to 150s to comfortably clear that;
205
+ pass your own `timeout=` (or a pre-configured `http_client=`) to
206
+ `ClarkClient`/`AsyncClarkClient` to change it.
207
+
208
+ ## Development
209
+
210
+ ```bash
211
+ cd platform/clients/python
212
+ uv sync --python 3.12
213
+ uv run --python 3.12 pytest -q
214
+ ```
215
+
216
+ `examples/live_smoke.py` is an opt-in, real-network smoke test — it reads
217
+ `CLARK_API_BASE_URL`, `CLARK_API_KEY`, and `CLARK_TEST_MODEL` from the
218
+ environment and exits early with a clear message if `CLARK_API_KEY` is
219
+ unset. It is not part of the test suite and is never run automatically.
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python3
2
+ """Opt-in real-network smoke test for the Clark Platform API client.
3
+
4
+ This is NOT part of the automated test suite (it is never imported or run by
5
+ pytest) and is never invoked automatically. It exists so a human can sanity
6
+ check the client against a live Clark deployment.
7
+
8
+ Usage:
9
+
10
+ export CLARK_API_BASE_URL="https://www.clarkchat.com" # or prod default
11
+ export CLARK_API_KEY="clk_live_xxxxxxxxxxxxxxxxxxxx"
12
+ export CLARK_TEST_MODEL="openrouter:qwen35_flash" # optional
13
+ python examples/live_smoke.py
14
+
15
+ If ``CLARK_API_KEY`` is unset, this script prints a clear message and exits
16
+ without making any network calls.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import os
22
+ import sys
23
+
24
+ from clark_platform import ClarkApiError, ClarkClient
25
+
26
+
27
+ def main() -> int:
28
+ api_key = os.environ.get("CLARK_API_KEY")
29
+ if not api_key:
30
+ print(
31
+ "CLARK_API_KEY is not set -- skipping live smoke test.\n"
32
+ "Set CLARK_API_KEY (and optionally CLARK_API_BASE_URL, CLARK_TEST_MODEL) "
33
+ "to run this against a real Clark deployment.",
34
+ file=sys.stderr,
35
+ )
36
+ return 0
37
+
38
+ base_url = os.environ.get("CLARK_API_BASE_URL", "https://www.clarkchat.com")
39
+ model = os.environ.get("CLARK_TEST_MODEL", "openrouter:qwen35_flash")
40
+
41
+ with ClarkClient(api_key=api_key, base_url=base_url) as client:
42
+ print(f"Listing models from {base_url} ...")
43
+ models = client.models.list()
44
+ for m in models.data:
45
+ print(f" - {m.id} ({m.label})")
46
+
47
+ print(f"\nRunning a trivial non-streaming chat completion with model={model!r} ...")
48
+ try:
49
+ completion = client.chat.completions.create(
50
+ model=model,
51
+ messages=[{"role": "user", "content": "Reply with exactly the word: pong"}],
52
+ )
53
+ except ClarkApiError as err:
54
+ print(f"Chat completion failed: {err.status_code} {err.type}: {err.message}", file=sys.stderr)
55
+ return 1
56
+
57
+ print("Response:")
58
+ print(f" id: {completion.id}")
59
+ print(f" finish_reason: {completion.choices[0].finish_reason if completion.choices else None}")
60
+ print(f" content: {completion.output_text!r}")
61
+ if completion.usage:
62
+ print(f" usage: {completion.usage}")
63
+
64
+ return 0
65
+
66
+
67
+ if __name__ == "__main__":
68
+ raise SystemExit(main())
@@ -0,0 +1,39 @@
1
+ [project]
2
+ name = "clark-platform-client"
3
+ version = "0.1.0"
4
+ description = "Typed sync/async Python client for the Clark Platform API"
5
+ readme = "README.md"
6
+ requires-python = ">=3.9"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "Clark Labs" }]
9
+ keywords = ["clark", "clark-labs", "api-client", "agent", "httpx"]
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "Programming Language :: Python :: 3.9",
13
+ "Programming Language :: Python :: 3.10",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Operating System :: OS Independent",
17
+ "Typing :: Typed",
18
+ ]
19
+ dependencies = ["httpx>=0.24"]
20
+
21
+ [project.optional-dependencies]
22
+ dev = ["pytest>=7.4", "pytest-asyncio>=0.21"]
23
+
24
+ [project.urls]
25
+ Homepage = "https://www.clarkchat.com"
26
+
27
+ [build-system]
28
+ requires = ["hatchling"]
29
+ build-backend = "hatchling.build"
30
+
31
+ [tool.hatch.build.targets.wheel]
32
+ packages = ["src/clark_platform"]
33
+
34
+ [tool.pytest.ini_options]
35
+ asyncio_mode = "auto"
36
+ testpaths = ["tests"]
37
+
38
+ [dependency-groups]
39
+ dev = ["pytest>=7.4", "pytest-asyncio>=0.21"]
@@ -0,0 +1,61 @@
1
+ """Typed sync/async Python client for the Clark Platform API.
2
+
3
+ See https://www.clarkchat.com and ``platform/clients/API_CONTRACT.md`` in the
4
+ Clark monorepo for the full wire contract this client implements.
5
+ """
6
+
7
+ from .async_client import AsyncClarkClient
8
+ from .client import ClarkClient
9
+ from .errors import ClarkApiError
10
+ from .models import (
11
+ Artifact,
12
+ Capabilities,
13
+ ChatChoice,
14
+ ChatCompletionChunk,
15
+ ChatCompletionObject,
16
+ ChatMessage,
17
+ ClarkMetadata,
18
+ Cost,
19
+ MemoryList,
20
+ MemoryRecord,
21
+ ModelInfo,
22
+ ModelList,
23
+ ModelOption,
24
+ OutputMessage,
25
+ Pricing,
26
+ ResponseError,
27
+ ResponseEvent,
28
+ ResponseEventList,
29
+ ResponseObject,
30
+ ResponseStreamEvent,
31
+ Usage,
32
+ )
33
+
34
+ __version__ = "0.1.0"
35
+
36
+ __all__ = [
37
+ "ClarkClient",
38
+ "AsyncClarkClient",
39
+ "ClarkApiError",
40
+ "ModelInfo",
41
+ "ModelOption",
42
+ "ModelList",
43
+ "Pricing",
44
+ "Capabilities",
45
+ "ResponseObject",
46
+ "ResponseStreamEvent",
47
+ "ResponseEvent",
48
+ "ResponseEventList",
49
+ "OutputMessage",
50
+ "Artifact",
51
+ "ClarkMetadata",
52
+ "ResponseError",
53
+ "Cost",
54
+ "Usage",
55
+ "ChatCompletionObject",
56
+ "ChatCompletionChunk",
57
+ "ChatChoice",
58
+ "ChatMessage",
59
+ "MemoryRecord",
60
+ "MemoryList",
61
+ ]