opencode-py 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.
opencode/_client.py ADDED
@@ -0,0 +1,532 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional, Sequence
4
+
5
+ import httpx
6
+
7
+ from opencode._errors import ApiError
8
+
9
+
10
+ class OpencodeClient:
11
+ def __init__(
12
+ self,
13
+ *,
14
+ base_url: str = "http://127.0.0.1:4096",
15
+ directory: Optional[str] = None,
16
+ workspace: Optional[str] = None,
17
+ timeout: float = 300.0,
18
+ httpx_client: Optional[httpx.Client] = None,
19
+ ):
20
+ self.base_url = base_url.rstrip("/")
21
+ self.directory = directory
22
+ self.workspace = workspace
23
+ self._client = httpx_client or httpx.Client(timeout=httpx.Timeout(timeout))
24
+
25
+ # ------------------------------------------------------------------
26
+ # Internal helpers
27
+ # ------------------------------------------------------------------
28
+
29
+ def _build_url(self, path: str) -> str:
30
+ return f"{self.base_url}{path}"
31
+
32
+ def _merge_params(
33
+ self,
34
+ params: Optional[Dict[str, Any]] = None,
35
+ ) -> Dict[str, Any]:
36
+ params = dict(params or {})
37
+ if self.directory and "directory" not in params:
38
+ params["directory"] = self.directory
39
+ if self.workspace and "workspace" not in params:
40
+ params["workspace"] = self.workspace
41
+ return params
42
+
43
+ def _handle(self, response: httpx.Response) -> Any:
44
+ if response.is_success:
45
+ if response.status_code == 204:
46
+ return None
47
+ ct = response.headers.get("content-type", "")
48
+ if "text/event-stream" in ct:
49
+ return response
50
+ if "text/" in ct:
51
+ return response.text
52
+ return response.json()
53
+ body = None
54
+ try:
55
+ body = response.json()
56
+ except Exception:
57
+ body = response.text
58
+ message = None
59
+ if isinstance(body, dict):
60
+ message = body.get("message") or body.get("error") or str(body)
61
+ elif isinstance(body, str):
62
+ message = body
63
+ raise ApiError(
64
+ message or f"HTTP {response.status_code}: {response.reason_phrase}",
65
+ status=response.status_code,
66
+ body=body,
67
+ )
68
+
69
+ def _request(
70
+ self,
71
+ method: str,
72
+ path: str,
73
+ *,
74
+ params: Optional[Dict[str, Any]] = None,
75
+ json_body: Any = None,
76
+ headers: Optional[Dict[str, str]] = None,
77
+ ) -> Any:
78
+ url = self._build_url(path)
79
+ params = self._merge_params(params)
80
+ hdrs = {"Content-Type": "application/json", **(headers or {})}
81
+ response = self._client.request(method, url, params=params, json=json_body, headers=hdrs)
82
+ return self._handle(response)
83
+
84
+ def _request_stream(
85
+ self,
86
+ method: str,
87
+ path: str,
88
+ *,
89
+ params: Optional[Dict[str, Any]] = None,
90
+ json_body: Any = None,
91
+ headers: Optional[Dict[str, str]] = None,
92
+ ) -> httpx.Response:
93
+ url = self._build_url(path)
94
+ params = self._merge_params(params)
95
+ hdrs = {"Content-Type": "application/json", **(headers or {})}
96
+ request = self._client.build_request(method, url, params=params, json=json_body, headers=hdrs)
97
+ return self._client.send(request, stream=True)
98
+
99
+ # ------------------------------------------------------------------
100
+ # Global
101
+ # ------------------------------------------------------------------
102
+
103
+ def health(self) -> Any:
104
+ return self._request("GET", "/global/health")
105
+
106
+ def global_event(self) -> httpx.Response:
107
+ return self._request_stream("GET", "/global/event")
108
+
109
+ def global_dispose(self) -> Any:
110
+ return self._request("POST", "/global/dispose")
111
+
112
+ def global_upgrade(self, target: Optional[str] = None) -> Any:
113
+ return self._request("POST", "/global/upgrade", json_body={"target": target})
114
+
115
+ def global_config_get(self) -> Any:
116
+ return self._request("GET", "/global/config")
117
+
118
+ def global_config_update(self, config: Any) -> Any:
119
+ return self._request("PATCH", "/global/config", json_body={"config": config})
120
+
121
+ # ------------------------------------------------------------------
122
+ # Config
123
+ # ------------------------------------------------------------------
124
+
125
+ def config_get(self, **kwargs) -> Any:
126
+ return self._request("GET", "/config", params=kwargs)
127
+
128
+ def config_update(self, config: Any, **kwargs) -> Any:
129
+ return self._request("PATCH", "/config", json_body={"config": config}, params=kwargs)
130
+
131
+ def config_providers(self, **kwargs) -> Any:
132
+ return self._request("GET", "/config/providers", params=kwargs)
133
+
134
+ # ------------------------------------------------------------------
135
+ # Session
136
+ # ------------------------------------------------------------------
137
+
138
+ def session_create(self, **kwargs) -> Any:
139
+ return self._request("POST", "/session", json_body=kwargs or None)
140
+
141
+ def session_get(self, session_id: str) -> Any:
142
+ return self._request("GET", f"/session/{session_id}")
143
+
144
+ def session_list(self, **kwargs) -> Any:
145
+ return self._request("GET", "/session", params=kwargs)
146
+
147
+ def session_delete(self, session_id: str) -> Any:
148
+ return self._request("DELETE", f"/session/{session_id}")
149
+
150
+ def session_update(self, session_id: str, **kwargs) -> Any:
151
+ return self._request("PUT", f"/session/{session_id}", json_body=kwargs or None)
152
+
153
+ def session_messages(self, session_id: str, **kwargs) -> Any:
154
+ return self._request("GET", f"/session/{session_id}/message", params=kwargs)
155
+
156
+ def session_message(self, session_id: str, message_id: str) -> Any:
157
+ return self._request("GET", f"/session/{session_id}/message/{message_id}")
158
+
159
+ def session_fork(self, session_id: str, **kwargs) -> Any:
160
+ return self._request("POST", f"/session/{session_id}/fork", json_body=kwargs or None)
161
+
162
+ def session_abort(self, session_id: str) -> Any:
163
+ return self._request("POST", f"/session/{session_id}/abort")
164
+
165
+ def session_init(self, session_id: str, **kwargs) -> Any:
166
+ return self._request("POST", f"/session/{session_id}/init", json_body=kwargs or None)
167
+
168
+ def session_summarize(self, session_id: str) -> Any:
169
+ return self._request("POST", f"/session/{session_id}/summarize")
170
+
171
+ def session_todo(self, session_id: str) -> Any:
172
+ return self._request("GET", f"/session/{session_id}/todo")
173
+
174
+ def session_children(self, session_id: str) -> Any:
175
+ return self._request("GET", f"/session/{session_id}/child")
176
+
177
+ def session_diff(self, session_id: str) -> Any:
178
+ return self._request("GET", f"/session/{session_id}/diff")
179
+
180
+ def session_share(self, session_id: str) -> Any:
181
+ return self._request("POST", f"/session/{session_id}/share")
182
+
183
+ def session_unshare(self, session_id: str) -> Any:
184
+ return self._request("DELETE", f"/session/{session_id}/share")
185
+
186
+ def session_revert(self, session_id: str) -> Any:
187
+ return self._request("POST", f"/session/{session_id}/revert")
188
+
189
+ def session_unrevert(self, session_id: str) -> Any:
190
+ return self._request("POST", f"/session/{session_id}/unrevert")
191
+
192
+ def session_command(self, session_id: str, command: str, **kwargs) -> Any:
193
+ return self._request("POST", f"/session/{session_id}/command", json_body={"command": command, **kwargs})
194
+
195
+ def session_shell(self, session_id: str, command: str) -> Any:
196
+ return self._request("POST", f"/session/{session_id}/shell", json_body={"command": command})
197
+
198
+ # ------------------------------------------------------------------
199
+ # V2 Session
200
+ # ------------------------------------------------------------------
201
+
202
+ def v2_session_list(self, **kwargs) -> Any:
203
+ return self._request("GET", "/api/session", params=kwargs)
204
+
205
+ def session_send(self, session_id: str, body: Any) -> Any:
206
+ return self._request("POST", f"/session/{session_id}/message", json_body=body)
207
+
208
+ def v2_session_prompt(self, session_id: str, prompt: Any, *, delivery: str = "queue", **kwargs) -> Any:
209
+ body: Dict[str, Any] = {"prompt": prompt, "delivery": delivery, **kwargs}
210
+ return self._request("POST", f"/api/session/{session_id}/prompt", json_body=body)
211
+
212
+ def v2_session_wait(self, session_id: str) -> Any:
213
+ return self._request("POST", f"/api/session/{session_id}/wait")
214
+
215
+ def v2_session_context(self, session_id: str, **kwargs) -> Any:
216
+ return self._request("GET", f"/api/session/{session_id}/context", params=kwargs)
217
+
218
+ def v2_session_messages(self, session_id: str, **kwargs) -> Any:
219
+ return self._request("GET", f"/api/session/{session_id}/message", params=kwargs)
220
+
221
+ def v2_session_compact(self, session_id: str) -> Any:
222
+ return self._request("POST", f"/api/session/{session_id}/compact")
223
+
224
+ def v2_model_list(self, **kwargs) -> Any:
225
+ return self._request("GET", "/api/model", params=kwargs)
226
+
227
+ def v2_provider_list(self, **kwargs) -> Any:
228
+ return self._request("GET", "/api/provider", params=kwargs)
229
+
230
+ def v2_provider_get(self, provider_id: str) -> Any:
231
+ return self._request("GET", f"/api/provider/{provider_id}")
232
+
233
+ # ------------------------------------------------------------------
234
+ # Auth
235
+ # ------------------------------------------------------------------
236
+
237
+ def auth_set(self, provider_id: str, auth: Any) -> Any:
238
+ return self._request("PUT", f"/auth/{provider_id}", json_body={"auth": auth})
239
+
240
+ def auth_remove(self, provider_id: str) -> Any:
241
+ return self._request("DELETE", f"/auth/{provider_id}")
242
+
243
+ # ------------------------------------------------------------------
244
+ # App
245
+ # ------------------------------------------------------------------
246
+
247
+ def app_log(self, **kwargs) -> Any:
248
+ return self._request("POST", "/log", json_body=kwargs or None)
249
+
250
+ def app_agents(self, **kwargs) -> Any:
251
+ return self._request("GET", "/agent", params=kwargs)
252
+
253
+ # ------------------------------------------------------------------
254
+ # File
255
+ # ------------------------------------------------------------------
256
+
257
+ def file_read(self, path: str, **kwargs) -> Any:
258
+ return self._request("GET", "/file/content", params={"path": path, **kwargs})
259
+
260
+ def file_list(self, path: str, **kwargs) -> Any:
261
+ return self._request("GET", "/file", params={"path": path, **kwargs})
262
+
263
+ def file_status(self, **kwargs) -> Any:
264
+ return self._request("GET", "/file/status", params=kwargs)
265
+
266
+ # ------------------------------------------------------------------
267
+ # Find
268
+ # ------------------------------------------------------------------
269
+
270
+ def find_text(self, pattern: str, **kwargs) -> Any:
271
+ return self._request("GET", "/find", params={"pattern": pattern, **kwargs})
272
+
273
+ def find_files(self, query: str, **kwargs) -> Any:
274
+ return self._request("GET", "/find/file", params={"query": query, **kwargs})
275
+
276
+ def find_symbols(self, query: str, **kwargs) -> Any:
277
+ return self._request("GET", "/find/symbol", params={"query": query, **kwargs})
278
+
279
+ # ------------------------------------------------------------------
280
+ # VCS
281
+ # ------------------------------------------------------------------
282
+
283
+ def vcs_get(self, **kwargs) -> Any:
284
+ return self._request("GET", "/vcs", params=kwargs)
285
+
286
+ def vcs_status(self, **kwargs) -> Any:
287
+ return self._request("GET", "/vcs/status", params=kwargs)
288
+
289
+ def vcs_diff(self, mode: str = "git", **kwargs) -> Any:
290
+ return self._request("GET", "/vcs/diff", params={"mode": mode, **kwargs})
291
+
292
+ def vcs_diff_raw(self, **kwargs) -> Any:
293
+ return self._request("GET", "/vcs/diff/raw", params=kwargs)
294
+
295
+ def vcs_apply(self, patch: str, **kwargs) -> Any:
296
+ return self._request("POST", "/vcs/apply", json_body={"patch": patch, **kwargs})
297
+
298
+ # ------------------------------------------------------------------
299
+ # LSP / Formatter
300
+ # ------------------------------------------------------------------
301
+
302
+ def lsp_status(self, **kwargs) -> Any:
303
+ return self._request("GET", "/lsp", params=kwargs)
304
+
305
+ def formatter_status(self, **kwargs) -> Any:
306
+ return self._request("GET", "/formatter", params=kwargs)
307
+
308
+ # ------------------------------------------------------------------
309
+ # Provider
310
+ # ------------------------------------------------------------------
311
+
312
+ def provider_list(self, **kwargs) -> Any:
313
+ return self._request("GET", "/provider", params=kwargs)
314
+
315
+ def provider_auth(self, provider_id: str, **kwargs) -> Any:
316
+ return self._request("GET", f"/provider/{provider_id}/auth", params=kwargs)
317
+
318
+ # ------------------------------------------------------------------
319
+ # MCP
320
+ # ------------------------------------------------------------------
321
+
322
+ def mcp_list(self, **kwargs) -> Any:
323
+ return self._request("GET", "/mcp", params=kwargs)
324
+
325
+ def mcp_status(self, **kwargs) -> Any:
326
+ return self._request("GET", "/mcp/status", params=kwargs)
327
+
328
+ def mcp_add(self, config: Any) -> Any:
329
+ return self._request("PUT", "/mcp", json_body={"config": config})
330
+
331
+ def mcp_connect(self, name: str, **kwargs) -> Any:
332
+ return self._request("POST", f"/mcp/{name}/connect", json_body=kwargs or None)
333
+
334
+ def mcp_disconnect(self, name: str) -> Any:
335
+ return self._request("DELETE", f"/mcp/{name}/connect")
336
+
337
+ # ------------------------------------------------------------------
338
+ # Tool
339
+ # ------------------------------------------------------------------
340
+
341
+ def tool_list(self, **kwargs) -> Any:
342
+ return self._request("GET", "/experimental/tool", params=kwargs)
343
+
344
+ def tool_ids(self, **kwargs) -> Any:
345
+ return self._request("GET", "/experimental/tool/ids", params=kwargs)
346
+
347
+ # ------------------------------------------------------------------
348
+ # Permission
349
+ # ------------------------------------------------------------------
350
+
351
+ def permission_list(self, **kwargs) -> Any:
352
+ return self._request("GET", "/permission", params=kwargs)
353
+
354
+ def permission_reply(self, permission_id: str, **kwargs) -> Any:
355
+ return self._request("POST", f"/permission/{permission_id}", json_body=kwargs or None)
356
+
357
+ # ------------------------------------------------------------------
358
+ # Question
359
+ # ------------------------------------------------------------------
360
+
361
+ def question_list(self, **kwargs) -> Any:
362
+ return self._request("GET", "/question", params=kwargs)
363
+
364
+ def question_reply(self, question_id: str, answer: Any) -> Any:
365
+ return self._request("POST", f"/question/{question_id}", json_body={"answer": answer})
366
+
367
+ def question_reject(self, question_id: str) -> Any:
368
+ return self._request("DELETE", f"/question/{question_id}")
369
+
370
+ # ------------------------------------------------------------------
371
+ # Event (SSE)
372
+ # ------------------------------------------------------------------
373
+
374
+ def event_subscribe(self, **kwargs) -> httpx.Response:
375
+ return self._request_stream("GET", "/event", params=kwargs)
376
+
377
+ # ------------------------------------------------------------------
378
+ # PTY
379
+ # ------------------------------------------------------------------
380
+
381
+ def pty_list(self, **kwargs) -> Any:
382
+ return self._request("GET", "/pty", params=kwargs)
383
+
384
+ def pty_create(self, **kwargs) -> Any:
385
+ return self._request("POST", "/pty", json_body=kwargs or None)
386
+
387
+ def pty_get(self, pty_id: str) -> Any:
388
+ return self._request("GET", f"/pty/{pty_id}")
389
+
390
+ def pty_remove(self, pty_id: str) -> Any:
391
+ return self._request("DELETE", f"/pty/{pty_id}")
392
+
393
+ def pty_update(self, pty_id: str, **kwargs) -> Any:
394
+ return self._request("PATCH", f"/pty/{pty_id}", json_body=kwargs or None)
395
+
396
+ def pty_shells(self, **kwargs) -> Any:
397
+ return self._request("GET", "/pty/shells", params=kwargs)
398
+
399
+ # ------------------------------------------------------------------
400
+ # Path
401
+ # ------------------------------------------------------------------
402
+
403
+ def path_get(self, **kwargs) -> Any:
404
+ return self._request("GET", "/path", params=kwargs)
405
+
406
+ # ------------------------------------------------------------------
407
+ # Instance
408
+ # ------------------------------------------------------------------
409
+
410
+ def instance_dispose(self, **kwargs) -> Any:
411
+ return self._request("POST", "/instance/dispose", params=kwargs)
412
+
413
+ # ------------------------------------------------------------------
414
+ # Command
415
+ # ------------------------------------------------------------------
416
+
417
+ def command_list(self, **kwargs) -> Any:
418
+ return self._request("GET", "/command", params=kwargs)
419
+
420
+ # ------------------------------------------------------------------
421
+ # Project
422
+ # ------------------------------------------------------------------
423
+
424
+ def project_current(self, **kwargs) -> Any:
425
+ return self._request("GET", "/project/current", params=kwargs)
426
+
427
+ def project_list(self, **kwargs) -> Any:
428
+ return self._request("GET", "/project", params=kwargs)
429
+
430
+ def project_update(self, **kwargs) -> Any:
431
+ return self._request("PATCH", "/project", json_body=kwargs or None)
432
+
433
+ def project_init_git(self, **kwargs) -> Any:
434
+ return self._request("POST", "/project/init-git", json_body=kwargs or None)
435
+
436
+ # ------------------------------------------------------------------
437
+ # Worktree (experimental)
438
+ # ------------------------------------------------------------------
439
+
440
+ def worktree_list(self, **kwargs) -> Any:
441
+ return self._request("GET", "/experimental/worktree", params=kwargs)
442
+
443
+ def worktree_create(self, **kwargs) -> Any:
444
+ return self._request("POST", "/experimental/worktree", json_body=kwargs or None)
445
+
446
+ def worktree_remove(self, **kwargs) -> Any:
447
+ return self._request("DELETE", "/experimental/worktree", params=kwargs)
448
+
449
+ def worktree_reset(self, **kwargs) -> Any:
450
+ return self._request("POST", "/experimental/worktree/reset", json_body=kwargs or None)
451
+
452
+ # ------------------------------------------------------------------
453
+ # Workspace (experimental)
454
+ # ------------------------------------------------------------------
455
+
456
+ def workspace_list(self, **kwargs) -> Any:
457
+ return self._request("GET", "/experimental/workspace", params=kwargs)
458
+
459
+ def workspace_create(self, **kwargs) -> Any:
460
+ return self._request("POST", "/experimental/workspace", json_body=kwargs or None)
461
+
462
+ def workspace_status(self, **kwargs) -> Any:
463
+ return self._request("GET", "/experimental/workspace/status", params=kwargs)
464
+
465
+ def workspace_remove(self, workspace_id: str) -> Any:
466
+ return self._request("DELETE", f"/experimental/workspace/{workspace_id}")
467
+
468
+ def workspace_warp(self, **kwargs) -> Any:
469
+ return self._request("POST", "/experimental/workspace/warp", json_body=kwargs or None)
470
+
471
+ # ------------------------------------------------------------------
472
+ # Sync (experimental)
473
+ # ------------------------------------------------------------------
474
+
475
+ def sync_start(self, **kwargs) -> Any:
476
+ return self._request("POST", "/experimental/sync/start", json_body=kwargs or None)
477
+
478
+ def sync_steal(self, **kwargs) -> Any:
479
+ return self._request("POST", "/experimental/sync/steal", json_body=kwargs or None)
480
+
481
+ def sync_replay(self, session_id: str) -> Any:
482
+ return self._request("POST", f"/experimental/sync/replay/{session_id}")
483
+
484
+ def sync_history(self, session_id: str) -> Any:
485
+ return self._request("GET", f"/experimental/sync/history/{session_id}")
486
+
487
+ # ------------------------------------------------------------------
488
+ # TUI
489
+ # ------------------------------------------------------------------
490
+
491
+ def tui_submit_prompt(self, **kwargs) -> Any:
492
+ return self._request("POST", "/tui/submit", json_body=kwargs or None)
493
+
494
+ def tui_append_prompt(self, **kwargs) -> Any:
495
+ return self._request("POST", "/tui/append", json_body=kwargs or None)
496
+
497
+ def tui_clear_prompt(self) -> Any:
498
+ return self._request("POST", "/tui/clear")
499
+
500
+ def tui_execute_command(self, **kwargs) -> Any:
501
+ return self._request("POST", "/tui/command", json_body=kwargs or None)
502
+
503
+ def tui_show_toast(self, **kwargs) -> Any:
504
+ return self._request("POST", "/tui/toast", json_body=kwargs or None)
505
+
506
+ def tui_open_sessions(self) -> Any:
507
+ return self._request("POST", "/tui/sessions")
508
+
509
+ def tui_open_models(self) -> Any:
510
+ return self._request("POST", "/tui/models")
511
+
512
+ def tui_open_themes(self) -> Any:
513
+ return self._request("POST", "/tui/themes")
514
+
515
+ def tui_open_help(self) -> Any:
516
+ return self._request("POST", "/tui/help")
517
+
518
+ def tui_publish(self, **kwargs) -> Any:
519
+ return self._request("POST", "/tui/publish", json_body=kwargs or None)
520
+
521
+ def tui_control_response(self, **kwargs) -> Any:
522
+ return self._request("POST", "/tui/control/response", json_body=kwargs or None)
523
+
524
+ def tui_control_next(self, session_id: str) -> Any:
525
+ return self._request("POST", f"/tui/control/next/{session_id}")
526
+
527
+ # ------------------------------------------------------------------
528
+ # Close
529
+ # ------------------------------------------------------------------
530
+
531
+ def close(self) -> None:
532
+ self._client.close()
opencode/_errors.py ADDED
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ class OpencodeError(Exception):
5
+ def __init__(self, message: str, *, status: int | None = None, body: object = None):
6
+ self.status = status
7
+ self.body = body
8
+ super().__init__(message)
9
+
10
+
11
+ class ApiError(OpencodeError):
12
+ ...
13
+
14
+
15
+ class BinaryNotFound(OpencodeError):
16
+ ...
17
+
18
+
19
+ class ServerStartupTimeout(OpencodeError):
20
+ ...
opencode/_models.py ADDED
@@ -0,0 +1,110 @@
1
+ from __future__ import annotations
2
+
3
+ try:
4
+ from typing import NotRequired
5
+ except ImportError:
6
+ from typing_extensions import NotRequired # Python <3.11
7
+
8
+ from typing import Any, Dict, List, Literal, TypedDict
9
+
10
+
11
+ class SessionInfo(TypedDict):
12
+ id: str
13
+ agent: NotRequired[str | None]
14
+ model: NotRequired[str | None]
15
+ title: NotRequired[str | None]
16
+ created: NotRequired[float]
17
+
18
+
19
+ class AssistantMessageText(TypedDict):
20
+ type: Literal["text"]
21
+ text: str
22
+
23
+
24
+ class AssistantMessageReasoning(TypedDict):
25
+ type: Literal["reasoning"]
26
+ text: str
27
+
28
+
29
+ class AssistantMessageTool(TypedDict):
30
+ type: Literal["tool"]
31
+ tool: str
32
+ input: Any
33
+ output: NotRequired[str | None]
34
+
35
+
36
+ class ToolCall(TypedDict):
37
+ name: str
38
+ input: Dict[str, Any]
39
+
40
+
41
+ class ToolUse(TypedDict):
42
+ type: Literal["tool-use"]
43
+ toolUseID: str
44
+ tool: ToolCall
45
+
46
+
47
+ class ToolResult(TypedDict):
48
+ type: Literal["tool-result"]
49
+ toolUseID: str
50
+ tool: ToolCall
51
+ output: Dict[str, Any]
52
+
53
+
54
+ AssistantContent = AssistantMessageText | AssistantMessageReasoning | AssistantMessageTool | ToolUse
55
+
56
+
57
+ class AssistantMessage(TypedDict):
58
+ id: str
59
+ type: Literal["assistant"]
60
+ agent: NotRequired[str | None]
61
+ model: NotRequired[Dict[str, str] | None]
62
+ content: List[AssistantContent]
63
+ structured: NotRequired[Any]
64
+ finish: NotRequired[str | None]
65
+ cost: NotRequired[float | None]
66
+ tokens: NotRequired[Dict[str, int] | None]
67
+ time: Dict[str, float]
68
+
69
+
70
+ class UserMessage(TypedDict):
71
+ id: str
72
+ type: Literal["user"]
73
+ text: str
74
+ files: NotRequired[List[Any] | None]
75
+ agents: NotRequired[List[Any] | None]
76
+ references: NotRequired[List[Any] | None]
77
+ time: Dict[str, float]
78
+
79
+
80
+ SessionMessage = AssistantMessage | UserMessage
81
+
82
+
83
+ class PromptFileAttachment(TypedDict):
84
+ uri: str
85
+ mime: NotRequired[str | None]
86
+ name: NotRequired[str | None]
87
+ description: NotRequired[str | None]
88
+ source: NotRequired[Dict[str, Any] | None]
89
+
90
+
91
+ class PromptAgentAttachment(TypedDict):
92
+ name: str
93
+ source: NotRequired[Dict[str, Any] | None]
94
+
95
+
96
+ class PromptReferenceAttachment(TypedDict):
97
+ name: str
98
+ kind: NotRequired[str | None]
99
+ uri: NotRequired[str | None]
100
+ repository: NotRequired[str | None]
101
+ branch: NotRequired[str | None]
102
+ target: NotRequired[str | None]
103
+ targetUri: NotRequired[str | None]
104
+ source: NotRequired[Dict[str, Any] | None]
105
+
106
+
107
+ class OutputFormatJsonSchema(TypedDict):
108
+ type: Literal["json_schema"]
109
+ schema: Dict[str, Any]
110
+ retryCount: NotRequired[int | None]