agentpool 2.1.9__py3-none-any.whl → 2.2.3__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.
Files changed (174) hide show
  1. acp/__init__.py +13 -0
  2. acp/bridge/README.md +15 -2
  3. acp/bridge/__init__.py +3 -2
  4. acp/bridge/__main__.py +60 -19
  5. acp/bridge/ws_server.py +173 -0
  6. acp/bridge/ws_server_cli.py +89 -0
  7. acp/notifications.py +2 -1
  8. acp/stdio.py +39 -9
  9. acp/transports.py +362 -2
  10. acp/utils.py +15 -2
  11. agentpool/__init__.py +4 -1
  12. agentpool/agents/__init__.py +2 -0
  13. agentpool/agents/acp_agent/acp_agent.py +203 -88
  14. agentpool/agents/acp_agent/acp_converters.py +46 -21
  15. agentpool/agents/acp_agent/client_handler.py +157 -3
  16. agentpool/agents/acp_agent/session_state.py +4 -1
  17. agentpool/agents/agent.py +314 -107
  18. agentpool/agents/agui_agent/__init__.py +0 -2
  19. agentpool/agents/agui_agent/agui_agent.py +90 -21
  20. agentpool/agents/agui_agent/agui_converters.py +0 -131
  21. agentpool/agents/base_agent.py +163 -1
  22. agentpool/agents/claude_code_agent/claude_code_agent.py +626 -179
  23. agentpool/agents/claude_code_agent/converters.py +71 -3
  24. agentpool/agents/claude_code_agent/history.py +474 -0
  25. agentpool/agents/context.py +40 -0
  26. agentpool/agents/events/__init__.py +2 -0
  27. agentpool/agents/events/builtin_handlers.py +2 -1
  28. agentpool/agents/events/event_emitter.py +29 -2
  29. agentpool/agents/events/events.py +20 -0
  30. agentpool/agents/modes.py +54 -0
  31. agentpool/agents/tool_call_accumulator.py +213 -0
  32. agentpool/common_types.py +21 -0
  33. agentpool/config_resources/__init__.py +38 -1
  34. agentpool/config_resources/claude_code_agent.yml +3 -0
  35. agentpool/delegation/pool.py +37 -29
  36. agentpool/delegation/team.py +1 -0
  37. agentpool/delegation/teamrun.py +1 -0
  38. agentpool/diagnostics/__init__.py +53 -0
  39. agentpool/diagnostics/lsp_manager.py +1593 -0
  40. agentpool/diagnostics/lsp_proxy.py +41 -0
  41. agentpool/diagnostics/lsp_proxy_script.py +229 -0
  42. agentpool/diagnostics/models.py +398 -0
  43. agentpool/mcp_server/__init__.py +0 -2
  44. agentpool/mcp_server/client.py +12 -3
  45. agentpool/mcp_server/manager.py +25 -31
  46. agentpool/mcp_server/registries/official_registry_client.py +25 -0
  47. agentpool/mcp_server/tool_bridge.py +78 -66
  48. agentpool/messaging/__init__.py +0 -2
  49. agentpool/messaging/compaction.py +72 -197
  50. agentpool/messaging/message_history.py +12 -0
  51. agentpool/messaging/messages.py +52 -9
  52. agentpool/messaging/processing.py +3 -1
  53. agentpool/models/acp_agents/base.py +0 -22
  54. agentpool/models/acp_agents/mcp_capable.py +8 -148
  55. agentpool/models/acp_agents/non_mcp.py +129 -72
  56. agentpool/models/agents.py +35 -13
  57. agentpool/models/claude_code_agents.py +33 -2
  58. agentpool/models/manifest.py +43 -0
  59. agentpool/repomap.py +1 -1
  60. agentpool/resource_providers/__init__.py +9 -1
  61. agentpool/resource_providers/aggregating.py +52 -3
  62. agentpool/resource_providers/base.py +57 -1
  63. agentpool/resource_providers/mcp_provider.py +23 -0
  64. agentpool/resource_providers/plan_provider.py +130 -41
  65. agentpool/resource_providers/pool.py +2 -0
  66. agentpool/resource_providers/static.py +2 -0
  67. agentpool/sessions/__init__.py +2 -1
  68. agentpool/sessions/manager.py +31 -2
  69. agentpool/sessions/models.py +50 -0
  70. agentpool/skills/registry.py +13 -8
  71. agentpool/storage/manager.py +217 -1
  72. agentpool/testing.py +537 -19
  73. agentpool/utils/file_watcher.py +269 -0
  74. agentpool/utils/identifiers.py +121 -0
  75. agentpool/utils/pydantic_ai_helpers.py +46 -0
  76. agentpool/utils/streams.py +690 -1
  77. agentpool/utils/subprocess_utils.py +155 -0
  78. agentpool/utils/token_breakdown.py +461 -0
  79. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/METADATA +27 -7
  80. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/RECORD +170 -112
  81. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/WHEEL +1 -1
  82. agentpool_cli/__main__.py +4 -0
  83. agentpool_cli/serve_acp.py +41 -20
  84. agentpool_cli/serve_agui.py +87 -0
  85. agentpool_cli/serve_opencode.py +119 -0
  86. agentpool_commands/__init__.py +30 -0
  87. agentpool_commands/agents.py +74 -1
  88. agentpool_commands/history.py +62 -0
  89. agentpool_commands/mcp.py +176 -0
  90. agentpool_commands/models.py +56 -3
  91. agentpool_commands/tools.py +57 -0
  92. agentpool_commands/utils.py +51 -0
  93. agentpool_config/builtin_tools.py +77 -22
  94. agentpool_config/commands.py +24 -1
  95. agentpool_config/compaction.py +258 -0
  96. agentpool_config/mcp_server.py +131 -1
  97. agentpool_config/storage.py +46 -1
  98. agentpool_config/tools.py +7 -1
  99. agentpool_config/toolsets.py +92 -148
  100. agentpool_server/acp_server/acp_agent.py +134 -150
  101. agentpool_server/acp_server/commands/acp_commands.py +216 -51
  102. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +10 -10
  103. agentpool_server/acp_server/server.py +23 -79
  104. agentpool_server/acp_server/session.py +181 -19
  105. agentpool_server/opencode_server/.rules +95 -0
  106. agentpool_server/opencode_server/ENDPOINTS.md +362 -0
  107. agentpool_server/opencode_server/__init__.py +27 -0
  108. agentpool_server/opencode_server/command_validation.py +172 -0
  109. agentpool_server/opencode_server/converters.py +869 -0
  110. agentpool_server/opencode_server/dependencies.py +24 -0
  111. agentpool_server/opencode_server/input_provider.py +269 -0
  112. agentpool_server/opencode_server/models/__init__.py +228 -0
  113. agentpool_server/opencode_server/models/agent.py +53 -0
  114. agentpool_server/opencode_server/models/app.py +60 -0
  115. agentpool_server/opencode_server/models/base.py +26 -0
  116. agentpool_server/opencode_server/models/common.py +23 -0
  117. agentpool_server/opencode_server/models/config.py +37 -0
  118. agentpool_server/opencode_server/models/events.py +647 -0
  119. agentpool_server/opencode_server/models/file.py +88 -0
  120. agentpool_server/opencode_server/models/mcp.py +25 -0
  121. agentpool_server/opencode_server/models/message.py +162 -0
  122. agentpool_server/opencode_server/models/parts.py +190 -0
  123. agentpool_server/opencode_server/models/provider.py +81 -0
  124. agentpool_server/opencode_server/models/pty.py +43 -0
  125. agentpool_server/opencode_server/models/session.py +99 -0
  126. agentpool_server/opencode_server/routes/__init__.py +25 -0
  127. agentpool_server/opencode_server/routes/agent_routes.py +442 -0
  128. agentpool_server/opencode_server/routes/app_routes.py +139 -0
  129. agentpool_server/opencode_server/routes/config_routes.py +241 -0
  130. agentpool_server/opencode_server/routes/file_routes.py +392 -0
  131. agentpool_server/opencode_server/routes/global_routes.py +94 -0
  132. agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
  133. agentpool_server/opencode_server/routes/message_routes.py +705 -0
  134. agentpool_server/opencode_server/routes/pty_routes.py +299 -0
  135. agentpool_server/opencode_server/routes/session_routes.py +1205 -0
  136. agentpool_server/opencode_server/routes/tui_routes.py +139 -0
  137. agentpool_server/opencode_server/server.py +430 -0
  138. agentpool_server/opencode_server/state.py +121 -0
  139. agentpool_server/opencode_server/time_utils.py +8 -0
  140. agentpool_storage/__init__.py +16 -0
  141. agentpool_storage/base.py +103 -0
  142. agentpool_storage/claude_provider.py +907 -0
  143. agentpool_storage/file_provider.py +129 -0
  144. agentpool_storage/memory_provider.py +61 -0
  145. agentpool_storage/models.py +3 -0
  146. agentpool_storage/opencode_provider.py +730 -0
  147. agentpool_storage/project_store.py +325 -0
  148. agentpool_storage/session_store.py +6 -0
  149. agentpool_storage/sql_provider/__init__.py +4 -2
  150. agentpool_storage/sql_provider/models.py +48 -0
  151. agentpool_storage/sql_provider/sql_provider.py +134 -1
  152. agentpool_storage/sql_provider/utils.py +10 -1
  153. agentpool_storage/text_log_provider.py +1 -0
  154. agentpool_toolsets/builtin/__init__.py +0 -8
  155. agentpool_toolsets/builtin/code.py +95 -56
  156. agentpool_toolsets/builtin/debug.py +16 -21
  157. agentpool_toolsets/builtin/execution_environment.py +99 -103
  158. agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
  159. agentpool_toolsets/builtin/skills.py +86 -4
  160. agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
  161. agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
  162. agentpool_toolsets/fsspec_toolset/grep.py +74 -2
  163. agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
  164. agentpool_toolsets/fsspec_toolset/toolset.py +159 -38
  165. agentpool_toolsets/mcp_discovery/__init__.py +5 -0
  166. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  167. agentpool_toolsets/mcp_discovery/toolset.py +454 -0
  168. agentpool_toolsets/mcp_run_toolset.py +84 -6
  169. agentpool_toolsets/builtin/agent_management.py +0 -239
  170. agentpool_toolsets/builtin/history.py +0 -36
  171. agentpool_toolsets/builtin/integration.py +0 -85
  172. agentpool_toolsets/builtin/tool_management.py +0 -90
  173. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/entry_points.txt +0 -0
  174. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,37 @@
1
+ """Config models."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
8
+
9
+
10
+ class Config(OpenCodeBaseModel):
11
+ """Server configuration.
12
+
13
+ This is a simplified version - we only include fields the TUI needs.
14
+ """
15
+
16
+ # Model settings
17
+ model: str | None = None
18
+ small_model: str | None = None
19
+
20
+ # Theme and UI
21
+ theme: str | None = None
22
+ username: str | None = None
23
+
24
+ # Sharing
25
+ share: str | None = None # "manual", "auto", "disabled"
26
+
27
+ # Provider configurations (simplified)
28
+ provider: dict[str, Any] | None = None
29
+
30
+ # MCP configurations
31
+ mcp: dict[str, Any] | None = None
32
+
33
+ # Instructions
34
+ instructions: list[str] | None = None
35
+
36
+ # Auto-update
37
+ autoupdate: bool | None = None
@@ -0,0 +1,647 @@
1
+ """SSE event models."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal, Self
6
+
7
+ from pydantic import Field
8
+
9
+ from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
10
+ from agentpool_server.opencode_server.models.message import ( # noqa: TC001
11
+ AssistantMessage,
12
+ UserMessage,
13
+ )
14
+ from agentpool_server.opencode_server.models.parts import Part # noqa: TC001
15
+ from agentpool_server.opencode_server.models.session import ( # noqa: TC001
16
+ Session,
17
+ SessionStatus,
18
+ )
19
+
20
+
21
+ class EmptyProperties(OpenCodeBaseModel):
22
+ """Empty properties object."""
23
+
24
+
25
+ class ServerConnectedEvent(OpenCodeBaseModel):
26
+ """Server connected event."""
27
+
28
+ type: Literal["server.connected"] = "server.connected"
29
+ properties: EmptyProperties = Field(default_factory=EmptyProperties)
30
+
31
+
32
+ class SessionInfoProperties(OpenCodeBaseModel):
33
+ """Session info wrapper for events."""
34
+
35
+ info: Session
36
+
37
+
38
+ class SessionCreatedEvent(OpenCodeBaseModel):
39
+ """Session created event."""
40
+
41
+ type: Literal["session.created"] = "session.created"
42
+ properties: SessionInfoProperties
43
+
44
+ @classmethod
45
+ def create(cls, session: Session) -> Self:
46
+ return cls(properties=SessionInfoProperties(info=session))
47
+
48
+
49
+ class SessionUpdatedEvent(OpenCodeBaseModel):
50
+ """Session updated event."""
51
+
52
+ type: Literal["session.updated"] = "session.updated"
53
+ properties: SessionInfoProperties
54
+
55
+ @classmethod
56
+ def create(cls, session: Session) -> Self:
57
+ return cls(properties=SessionInfoProperties(info=session))
58
+
59
+
60
+ class SessionDeletedProperties(OpenCodeBaseModel):
61
+ """Properties for session deleted event."""
62
+
63
+ session_id: str
64
+
65
+
66
+ class SessionDeletedEvent(OpenCodeBaseModel):
67
+ """Session deleted event."""
68
+
69
+ type: Literal["session.deleted"] = "session.deleted"
70
+ properties: SessionDeletedProperties
71
+
72
+ @classmethod
73
+ def create(cls, session_id: str) -> Self:
74
+ return cls(properties=SessionDeletedProperties(session_id=session_id))
75
+
76
+
77
+ class SessionStatusProperties(OpenCodeBaseModel):
78
+ """Properties for session status event."""
79
+
80
+ session_id: str
81
+ status: SessionStatus
82
+
83
+
84
+ class SessionStatusEvent(OpenCodeBaseModel):
85
+ """Session status event."""
86
+
87
+ type: Literal["session.status"] = "session.status"
88
+ properties: SessionStatusProperties
89
+
90
+ @classmethod
91
+ def create(cls, session_id: str, status: SessionStatus) -> Self:
92
+ return cls(properties=SessionStatusProperties(session_id=session_id, status=status))
93
+
94
+
95
+ class SessionIdleProperties(OpenCodeBaseModel):
96
+ """Properties for session idle event (deprecated but still used by TUI)."""
97
+
98
+ session_id: str
99
+
100
+
101
+ class SessionIdleEvent(OpenCodeBaseModel):
102
+ """Session idle event (deprecated but still used by TUI run command)."""
103
+
104
+ type: Literal["session.idle"] = "session.idle"
105
+ properties: SessionIdleProperties
106
+
107
+ @classmethod
108
+ def create(cls, session_id: str) -> Self:
109
+ return cls(properties=SessionIdleProperties(session_id=session_id))
110
+
111
+
112
+ class SessionCompactedProperties(OpenCodeBaseModel):
113
+ """Properties for session compacted event."""
114
+
115
+ session_id: str = Field(alias="sessionID")
116
+
117
+
118
+ class SessionCompactedEvent(OpenCodeBaseModel):
119
+ """Session compacted event - emitted when context compaction completes."""
120
+
121
+ type: Literal["session.compacted"] = "session.compacted"
122
+ properties: SessionCompactedProperties
123
+
124
+ @classmethod
125
+ def create(cls, session_id: str) -> Self:
126
+ return cls(properties=SessionCompactedProperties(sessionID=session_id))
127
+
128
+
129
+ class SessionErrorInfo(OpenCodeBaseModel):
130
+ """Error information for session error event.
131
+
132
+ Simplified version of OpenCode's error types (ProviderAuthError, UnknownError, etc.)
133
+ """
134
+
135
+ name: str
136
+ """Error type name (e.g., 'UnknownError', 'ProviderAuthError')."""
137
+
138
+ data: dict[str, Any] | None = None
139
+ """Additional error data, typically contains 'message' field."""
140
+
141
+
142
+ class SessionErrorProperties(OpenCodeBaseModel):
143
+ """Properties for session error event."""
144
+
145
+ session_id: str | None = Field(default=None, alias="sessionID")
146
+ error: SessionErrorInfo | None = None
147
+
148
+
149
+ class SessionErrorEvent(OpenCodeBaseModel):
150
+ """Session error event - emitted when an error occurs during message processing."""
151
+
152
+ type: Literal["session.error"] = "session.error"
153
+ properties: SessionErrorProperties
154
+
155
+ @classmethod
156
+ def create(
157
+ cls,
158
+ session_id: str | None = None,
159
+ error_name: str = "UnknownError",
160
+ error_message: str | None = None,
161
+ ) -> Self:
162
+ error_data = {"message": error_message} if error_message else None
163
+ return cls(
164
+ properties=SessionErrorProperties(
165
+ session_id=session_id,
166
+ error=SessionErrorInfo(name=error_name, data=error_data),
167
+ )
168
+ )
169
+
170
+
171
+ class MessageUpdatedEventProperties(OpenCodeBaseModel):
172
+ """Properties for message updated event."""
173
+
174
+ info: UserMessage | AssistantMessage
175
+
176
+
177
+ class MessageUpdatedEvent(OpenCodeBaseModel):
178
+ """Message updated event."""
179
+
180
+ type: Literal["message.updated"] = "message.updated"
181
+ properties: MessageUpdatedEventProperties
182
+
183
+ @classmethod
184
+ def create(cls, message: UserMessage | AssistantMessage) -> Self:
185
+ return cls(properties=MessageUpdatedEventProperties(info=message))
186
+
187
+
188
+ class PartUpdatedEventProperties(OpenCodeBaseModel):
189
+ """Properties for part updated event."""
190
+
191
+ part: Part
192
+ delta: str | None = None
193
+
194
+
195
+ class PartUpdatedEvent(OpenCodeBaseModel):
196
+ """Part updated event."""
197
+
198
+ type: Literal["message.part.updated"] = "message.part.updated"
199
+ properties: PartUpdatedEventProperties
200
+
201
+ @classmethod
202
+ def create(cls, part: Part, delta: str | None = None) -> Self:
203
+ return cls(properties=PartUpdatedEventProperties(part=part, delta=delta))
204
+
205
+
206
+ class PermissionTimeInfo(OpenCodeBaseModel):
207
+ """Time information for permission event."""
208
+
209
+ created: int
210
+
211
+
212
+ class PermissionUpdatedProperties(OpenCodeBaseModel):
213
+ """Properties for permission updated event.
214
+
215
+ Matches OpenCode's Permission.Info schema.
216
+ """
217
+
218
+ id: str
219
+ """Permission ID."""
220
+
221
+ type: str
222
+ """Tool type/name."""
223
+
224
+ session_id: str
225
+ """Session ID."""
226
+
227
+ message_id: str
228
+ """Message ID."""
229
+
230
+ call_id: str | None = None
231
+ """Optional tool call ID."""
232
+
233
+ title: str
234
+ """Human-readable title for the permission request."""
235
+
236
+ metadata: dict[str, Any]
237
+ """Arbitrary metadata about the tool call."""
238
+
239
+ time: PermissionTimeInfo
240
+ """Timestamp information."""
241
+
242
+ pattern: str | list[str] | None = None
243
+ """Optional pattern for matching."""
244
+
245
+
246
+ class PermissionRequestEvent(OpenCodeBaseModel):
247
+ """Permission request event - sent when a tool needs user confirmation.
248
+
249
+ Uses 'permission.updated' event type for OpenCode TUI compatibility.
250
+ """
251
+
252
+ type: Literal["permission.updated"] = "permission.updated"
253
+ properties: PermissionUpdatedProperties
254
+
255
+ @classmethod
256
+ def create(
257
+ cls,
258
+ session_id: str,
259
+ permission_id: str,
260
+ tool_name: str,
261
+ args_preview: str,
262
+ message: str,
263
+ message_id: str = "",
264
+ call_id: str | None = None,
265
+ ) -> Self:
266
+ import time
267
+
268
+ props = PermissionUpdatedProperties(
269
+ id=permission_id,
270
+ type=tool_name,
271
+ session_id=session_id,
272
+ message_id=message_id,
273
+ call_id=call_id,
274
+ title=message,
275
+ metadata={"args_preview": args_preview},
276
+ time=PermissionTimeInfo(created=int(time.time() * 1000)),
277
+ )
278
+ return cls(properties=props)
279
+
280
+
281
+ class PermissionRepliedProperties(OpenCodeBaseModel):
282
+ """Properties for permission replied event.
283
+
284
+ Matches OpenCode's permission.replied event schema.
285
+ """
286
+
287
+ session_id: str
288
+ """Session ID."""
289
+
290
+ request_id: str
291
+ """Request/Permission ID."""
292
+
293
+ reply: Literal["once", "always", "reject"]
294
+ """Reply: 'once' | 'always' | 'reject'."""
295
+
296
+
297
+ class PermissionResolvedEvent(OpenCodeBaseModel):
298
+ """Permission resolved event - sent when a permission request is answered.
299
+
300
+ Uses 'permission.replied' event type for OpenCode TUI compatibility.
301
+ """
302
+
303
+ type: Literal["permission.replied"] = "permission.replied"
304
+ properties: PermissionRepliedProperties
305
+
306
+ @classmethod
307
+ def create(
308
+ cls,
309
+ session_id: str,
310
+ request_id: str,
311
+ reply: Literal["once", "always", "reject"],
312
+ ) -> Self:
313
+ props = PermissionRepliedProperties(
314
+ session_id=session_id,
315
+ request_id=request_id,
316
+ reply=reply,
317
+ )
318
+ return cls(properties=props)
319
+
320
+
321
+ # =============================================================================
322
+ # TUI Events - for external control of the TUI (e.g., VSCode extension)
323
+ # =============================================================================
324
+
325
+
326
+ class TuiPromptAppendProperties(OpenCodeBaseModel):
327
+ """Properties for TUI prompt append event."""
328
+
329
+ text: str
330
+
331
+
332
+ class TuiPromptAppendEvent(OpenCodeBaseModel):
333
+ """TUI prompt append event - appends text to the prompt input."""
334
+
335
+ type: Literal["tui.prompt.append"] = "tui.prompt.append"
336
+ properties: TuiPromptAppendProperties
337
+
338
+ @classmethod
339
+ def create(cls, text: str) -> Self:
340
+ return cls(properties=TuiPromptAppendProperties(text=text))
341
+
342
+
343
+ class TuiCommandExecuteProperties(OpenCodeBaseModel):
344
+ """Properties for TUI command execute event."""
345
+
346
+ command: str
347
+
348
+
349
+ class TuiCommandExecuteEvent(OpenCodeBaseModel):
350
+ """TUI command execute event - executes a TUI command.
351
+
352
+ Commands include:
353
+ - session.list, session.new, session.share, session.interrupt, session.compact
354
+ - session.page.up, session.page.down, session.half.page.up, session.half.page.down
355
+ - session.first, session.last
356
+ - prompt.clear, prompt.submit
357
+ - agent.cycle
358
+ """
359
+
360
+ type: Literal["tui.command.execute"] = "tui.command.execute"
361
+ properties: TuiCommandExecuteProperties
362
+
363
+ @classmethod
364
+ def create(cls, command: str) -> Self:
365
+ return cls(properties=TuiCommandExecuteProperties(command=command))
366
+
367
+
368
+ class TuiToastShowProperties(OpenCodeBaseModel):
369
+ """Properties for TUI toast show event."""
370
+
371
+ title: str | None = None
372
+ message: str
373
+ variant: Literal["info", "success", "warning", "error"] = "info"
374
+ duration: int = 5000 # Duration in milliseconds
375
+
376
+
377
+ class TuiToastShowEvent(OpenCodeBaseModel):
378
+ """TUI toast show event - shows a toast notification."""
379
+
380
+ type: Literal["tui.toast.show"] = "tui.toast.show"
381
+ properties: TuiToastShowProperties
382
+
383
+ @classmethod
384
+ def create(
385
+ cls,
386
+ message: str,
387
+ variant: Literal["info", "success", "warning", "error"] = "info",
388
+ title: str | None = None,
389
+ duration: int = 5000,
390
+ ) -> Self:
391
+ return cls(
392
+ properties=TuiToastShowProperties(
393
+ title=title,
394
+ message=message,
395
+ variant=variant,
396
+ duration=duration,
397
+ )
398
+ )
399
+
400
+
401
+ # =============================================================================
402
+ # Todo Events
403
+ # =============================================================================
404
+
405
+
406
+ class Todo(OpenCodeBaseModel):
407
+ """A single todo item."""
408
+
409
+ id: str
410
+ """Unique identifier for the todo item."""
411
+
412
+ content: str
413
+ """Brief description of the task."""
414
+
415
+ status: str
416
+ """Current status: pending, in_progress, completed, cancelled."""
417
+
418
+ priority: str
419
+ """Priority level: high, medium, low."""
420
+
421
+
422
+ class TodoUpdatedProperties(OpenCodeBaseModel):
423
+ """Properties for todo updated event."""
424
+
425
+ session_id: str
426
+ todos: list[Todo]
427
+
428
+
429
+ class TodoUpdatedEvent(OpenCodeBaseModel):
430
+ """Todo list updated event."""
431
+
432
+ type: Literal["todo.updated"] = "todo.updated"
433
+ properties: TodoUpdatedProperties
434
+
435
+ @classmethod
436
+ def create(cls, session_id: str, todos: list[Todo]) -> Self:
437
+ return cls(properties=TodoUpdatedProperties(session_id=session_id, todos=todos))
438
+
439
+
440
+ # =============================================================================
441
+ # File Watcher Events
442
+ # =============================================================================
443
+
444
+
445
+ class FileWatcherUpdatedProperties(OpenCodeBaseModel):
446
+ """Properties for file watcher updated event."""
447
+
448
+ file: str
449
+ """Absolute path to the file that changed."""
450
+
451
+ event: Literal["add", "change", "unlink"]
452
+ """Type of change: add (created), change (modified), unlink (deleted)."""
453
+
454
+
455
+ class FileWatcherUpdatedEvent(OpenCodeBaseModel):
456
+ """File watcher updated event - sent when a project file changes."""
457
+
458
+ type: Literal["file.watcher.updated"] = "file.watcher.updated"
459
+ properties: FileWatcherUpdatedProperties
460
+
461
+ @classmethod
462
+ def create(cls, file: str, event: Literal["add", "change", "unlink"]) -> Self:
463
+ return cls(properties=FileWatcherUpdatedProperties(file=file, event=event))
464
+
465
+
466
+ # =============================================================================
467
+ # PTY Events
468
+ # =============================================================================
469
+
470
+
471
+ class PtyCreatedProperties(OpenCodeBaseModel):
472
+ """Properties for PTY created event."""
473
+
474
+ info: Any
475
+ """PTY session info."""
476
+
477
+
478
+ class PtyCreatedEvent(OpenCodeBaseModel):
479
+ """PTY session created event."""
480
+
481
+ type: Literal["pty.created"] = "pty.created"
482
+ properties: PtyCreatedProperties
483
+
484
+ @classmethod
485
+ def create(cls, info: Any) -> Self:
486
+ return cls(properties=PtyCreatedProperties(info=info))
487
+
488
+
489
+ class PtyUpdatedProperties(OpenCodeBaseModel):
490
+ """Properties for PTY updated event."""
491
+
492
+ info: Any
493
+ """PTY session info."""
494
+
495
+
496
+ class PtyUpdatedEvent(OpenCodeBaseModel):
497
+ """PTY session updated event."""
498
+
499
+ type: Literal["pty.updated"] = "pty.updated"
500
+ properties: PtyUpdatedProperties
501
+
502
+ @classmethod
503
+ def create(cls, info: Any) -> Self:
504
+ return cls(properties=PtyUpdatedProperties(info=info))
505
+
506
+
507
+ class PtyExitedProperties(OpenCodeBaseModel):
508
+ """Properties for PTY exited event."""
509
+
510
+ id: str
511
+ """PTY session ID."""
512
+
513
+ exit_code: int
514
+ """Process exit code."""
515
+
516
+
517
+ class PtyExitedEvent(OpenCodeBaseModel):
518
+ """PTY process exited event."""
519
+
520
+ type: Literal["pty.exited"] = "pty.exited"
521
+ properties: PtyExitedProperties
522
+
523
+ @classmethod
524
+ def create(cls, pty_id: str, exit_code: int) -> Self:
525
+ return cls(properties=PtyExitedProperties(id=pty_id, exit_code=exit_code))
526
+
527
+
528
+ class PtyDeletedProperties(OpenCodeBaseModel):
529
+ """Properties for PTY deleted event."""
530
+
531
+ id: str
532
+ """PTY session ID."""
533
+
534
+
535
+ class PtyDeletedEvent(OpenCodeBaseModel):
536
+ """PTY session deleted event."""
537
+
538
+ type: Literal["pty.deleted"] = "pty.deleted"
539
+ properties: PtyDeletedProperties
540
+
541
+ @classmethod
542
+ def create(cls, pty_id: str) -> Self:
543
+ return cls(properties=PtyDeletedProperties(id=pty_id))
544
+
545
+
546
+ # =============================================================================
547
+ # LSP Events
548
+ # =============================================================================
549
+
550
+
551
+ class LspStatus(OpenCodeBaseModel):
552
+ """LSP server status information."""
553
+
554
+ id: str
555
+ """Server identifier (e.g., 'pyright', 'rust-analyzer')."""
556
+
557
+ name: str
558
+ """Server name."""
559
+
560
+ root: str
561
+ """Relative workspace root path."""
562
+
563
+ status: Literal["connected", "error"]
564
+ """Connection status."""
565
+
566
+
567
+ class LspUpdatedEvent(OpenCodeBaseModel):
568
+ """LSP status updated event - sent when LSP server status changes."""
569
+
570
+ type: Literal["lsp.updated"] = "lsp.updated"
571
+ properties: EmptyProperties = Field(default_factory=EmptyProperties)
572
+
573
+ @classmethod
574
+ def create(cls) -> Self:
575
+ return cls()
576
+
577
+
578
+ class LspClientDiagnosticsProperties(OpenCodeBaseModel):
579
+ """Properties for LSP client diagnostics event."""
580
+
581
+ server_id: str = Field(alias="serverID")
582
+ """LSP server ID that produced the diagnostics."""
583
+
584
+ path: str
585
+ """File path the diagnostics apply to."""
586
+
587
+
588
+ class LspClientDiagnosticsEvent(OpenCodeBaseModel):
589
+ """LSP client diagnostics event - sent when diagnostics are published."""
590
+
591
+ type: Literal["lsp.client.diagnostics"] = "lsp.client.diagnostics"
592
+ properties: LspClientDiagnosticsProperties
593
+
594
+ @classmethod
595
+ def create(cls, server_id: str, path: str) -> Self:
596
+ return cls(properties=LspClientDiagnosticsProperties(serverID=server_id, path=path))
597
+
598
+
599
+ # =============================================================================
600
+ # VCS Events
601
+ # =============================================================================
602
+
603
+
604
+ class VcsBranchUpdatedProperties(OpenCodeBaseModel):
605
+ """Properties for VCS branch updated event."""
606
+
607
+ branch: str | None = None
608
+ """Current branch name, or None if detached HEAD."""
609
+
610
+
611
+ class VcsBranchUpdatedEvent(OpenCodeBaseModel):
612
+ """VCS branch updated event - sent when git branch changes."""
613
+
614
+ type: Literal["vcs.branch.updated"] = "vcs.branch.updated"
615
+ properties: VcsBranchUpdatedProperties
616
+
617
+ @classmethod
618
+ def create(cls, branch: str | None) -> Self:
619
+ return cls(properties=VcsBranchUpdatedProperties(branch=branch))
620
+
621
+
622
+ Event = (
623
+ ServerConnectedEvent
624
+ | SessionCreatedEvent
625
+ | SessionUpdatedEvent
626
+ | SessionDeletedEvent
627
+ | SessionStatusEvent
628
+ | SessionErrorEvent
629
+ | SessionIdleEvent
630
+ | MessageUpdatedEvent
631
+ | PartUpdatedEvent
632
+ | PermissionRequestEvent
633
+ | PermissionResolvedEvent
634
+ | TodoUpdatedEvent
635
+ | FileWatcherUpdatedEvent
636
+ | SessionCompactedEvent
637
+ | PtyCreatedEvent
638
+ | PtyUpdatedEvent
639
+ | PtyExitedEvent
640
+ | PtyDeletedEvent
641
+ | LspUpdatedEvent
642
+ | LspClientDiagnosticsEvent
643
+ | VcsBranchUpdatedEvent
644
+ | TuiPromptAppendEvent
645
+ | TuiCommandExecuteEvent
646
+ | TuiToastShowEvent
647
+ )