agentpool 2.2.3__py3-none-any.whl → 2.5.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.
- acp/__init__.py +0 -4
- acp/acp_requests.py +20 -77
- acp/agent/connection.py +8 -0
- acp/agent/implementations/debug_server/debug_server.py +6 -2
- acp/agent/protocol.py +6 -0
- acp/client/connection.py +38 -29
- acp/client/implementations/default_client.py +3 -2
- acp/client/implementations/headless_client.py +2 -2
- acp/connection.py +2 -2
- acp/notifications.py +18 -49
- acp/schema/__init__.py +2 -0
- acp/schema/agent_responses.py +21 -0
- acp/schema/client_requests.py +3 -3
- acp/schema/session_state.py +63 -29
- acp/task/supervisor.py +2 -2
- acp/utils.py +2 -2
- agentpool/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +278 -263
- agentpool/agents/acp_agent/acp_converters.py +150 -17
- agentpool/agents/acp_agent/client_handler.py +35 -24
- agentpool/agents/acp_agent/session_state.py +14 -6
- agentpool/agents/agent.py +471 -643
- agentpool/agents/agui_agent/agui_agent.py +104 -107
- agentpool/agents/agui_agent/helpers.py +3 -4
- agentpool/agents/base_agent.py +485 -32
- agentpool/agents/claude_code_agent/FORKING.md +191 -0
- agentpool/agents/claude_code_agent/__init__.py +13 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +654 -334
- agentpool/agents/claude_code_agent/converters.py +4 -141
- agentpool/agents/claude_code_agent/models.py +77 -0
- agentpool/agents/claude_code_agent/static_info.py +100 -0
- agentpool/agents/claude_code_agent/usage.py +242 -0
- agentpool/agents/events/__init__.py +22 -0
- agentpool/agents/events/builtin_handlers.py +65 -0
- agentpool/agents/events/event_emitter.py +3 -0
- agentpool/agents/events/events.py +84 -3
- agentpool/agents/events/infer_info.py +145 -0
- agentpool/agents/events/processors.py +254 -0
- agentpool/agents/interactions.py +41 -6
- agentpool/agents/modes.py +13 -0
- agentpool/agents/slashed_agent.py +5 -4
- agentpool/agents/tool_wrapping.py +18 -6
- agentpool/common_types.py +35 -21
- agentpool/config_resources/acp_assistant.yml +2 -2
- agentpool/config_resources/agents.yml +3 -0
- agentpool/config_resources/agents_template.yml +1 -0
- agentpool/config_resources/claude_code_agent.yml +9 -8
- agentpool/config_resources/external_acp_agents.yml +2 -1
- agentpool/delegation/base_team.py +4 -30
- agentpool/delegation/pool.py +104 -265
- agentpool/delegation/team.py +57 -57
- agentpool/delegation/teamrun.py +50 -55
- agentpool/functional/run.py +10 -4
- agentpool/mcp_server/client.py +73 -38
- agentpool/mcp_server/conversions.py +54 -13
- agentpool/mcp_server/manager.py +9 -23
- agentpool/mcp_server/registries/official_registry_client.py +10 -1
- agentpool/mcp_server/tool_bridge.py +114 -79
- agentpool/messaging/connection_manager.py +11 -10
- agentpool/messaging/event_manager.py +5 -5
- agentpool/messaging/message_container.py +6 -30
- agentpool/messaging/message_history.py +87 -8
- agentpool/messaging/messagenode.py +52 -14
- agentpool/messaging/messages.py +2 -26
- agentpool/messaging/processing.py +10 -22
- agentpool/models/__init__.py +1 -1
- agentpool/models/acp_agents/base.py +6 -2
- agentpool/models/acp_agents/mcp_capable.py +124 -15
- agentpool/models/acp_agents/non_mcp.py +0 -23
- agentpool/models/agents.py +66 -66
- agentpool/models/agui_agents.py +1 -1
- agentpool/models/claude_code_agents.py +111 -17
- agentpool/models/file_parsing.py +0 -1
- agentpool/models/manifest.py +70 -50
- agentpool/prompts/conversion_manager.py +1 -1
- agentpool/prompts/prompts.py +5 -2
- agentpool/resource_providers/__init__.py +2 -0
- agentpool/resource_providers/aggregating.py +4 -2
- agentpool/resource_providers/base.py +13 -3
- agentpool/resource_providers/codemode/code_executor.py +72 -5
- agentpool/resource_providers/codemode/helpers.py +2 -2
- agentpool/resource_providers/codemode/provider.py +64 -12
- agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
- agentpool/resource_providers/codemode/remote_provider.py +9 -12
- agentpool/resource_providers/filtering.py +3 -1
- agentpool/resource_providers/mcp_provider.py +66 -12
- agentpool/resource_providers/plan_provider.py +111 -18
- agentpool/resource_providers/pool.py +5 -3
- agentpool/resource_providers/resource_info.py +111 -0
- agentpool/resource_providers/static.py +2 -2
- agentpool/sessions/__init__.py +2 -0
- agentpool/sessions/manager.py +2 -3
- agentpool/sessions/models.py +9 -6
- agentpool/sessions/protocol.py +28 -0
- agentpool/sessions/session.py +11 -55
- agentpool/storage/manager.py +361 -54
- agentpool/talk/registry.py +4 -4
- agentpool/talk/talk.py +9 -10
- agentpool/testing.py +1 -1
- agentpool/tool_impls/__init__.py +6 -0
- agentpool/tool_impls/agent_cli/__init__.py +42 -0
- agentpool/tool_impls/agent_cli/tool.py +95 -0
- agentpool/tool_impls/bash/__init__.py +64 -0
- agentpool/tool_impls/bash/helpers.py +35 -0
- agentpool/tool_impls/bash/tool.py +171 -0
- agentpool/tool_impls/delete_path/__init__.py +70 -0
- agentpool/tool_impls/delete_path/tool.py +142 -0
- agentpool/tool_impls/download_file/__init__.py +80 -0
- agentpool/tool_impls/download_file/tool.py +183 -0
- agentpool/tool_impls/execute_code/__init__.py +55 -0
- agentpool/tool_impls/execute_code/tool.py +163 -0
- agentpool/tool_impls/grep/__init__.py +80 -0
- agentpool/tool_impls/grep/tool.py +200 -0
- agentpool/tool_impls/list_directory/__init__.py +73 -0
- agentpool/tool_impls/list_directory/tool.py +197 -0
- agentpool/tool_impls/question/__init__.py +42 -0
- agentpool/tool_impls/question/tool.py +127 -0
- agentpool/tool_impls/read/__init__.py +104 -0
- agentpool/tool_impls/read/tool.py +305 -0
- agentpool/tools/__init__.py +2 -1
- agentpool/tools/base.py +114 -34
- agentpool/tools/manager.py +57 -1
- agentpool/ui/base.py +2 -2
- agentpool/ui/mock_provider.py +2 -2
- agentpool/ui/stdlib_provider.py +2 -2
- agentpool/utils/streams.py +21 -96
- agentpool/vfs_registry.py +7 -2
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/METADATA +16 -22
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/RECORD +242 -195
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +20 -0
- agentpool_cli/create.py +1 -1
- agentpool_cli/serve_acp.py +59 -1
- agentpool_cli/serve_opencode.py +1 -1
- agentpool_cli/ui.py +557 -0
- agentpool_commands/__init__.py +12 -5
- agentpool_commands/agents.py +1 -1
- agentpool_commands/pool.py +260 -0
- agentpool_commands/session.py +1 -1
- agentpool_commands/text_sharing/__init__.py +119 -0
- agentpool_commands/text_sharing/base.py +123 -0
- agentpool_commands/text_sharing/github_gist.py +80 -0
- agentpool_commands/text_sharing/opencode.py +462 -0
- agentpool_commands/text_sharing/paste_rs.py +59 -0
- agentpool_commands/text_sharing/pastebin.py +116 -0
- agentpool_commands/text_sharing/shittycodingagent.py +112 -0
- agentpool_commands/utils.py +31 -32
- agentpool_config/__init__.py +30 -2
- agentpool_config/agentpool_tools.py +498 -0
- agentpool_config/converters.py +1 -1
- agentpool_config/event_handlers.py +42 -0
- agentpool_config/events.py +1 -1
- agentpool_config/forward_targets.py +1 -4
- agentpool_config/jinja.py +3 -3
- agentpool_config/mcp_server.py +1 -5
- agentpool_config/nodes.py +1 -1
- agentpool_config/observability.py +44 -0
- agentpool_config/session.py +0 -3
- agentpool_config/storage.py +38 -39
- agentpool_config/task.py +3 -3
- agentpool_config/tools.py +11 -28
- agentpool_config/toolsets.py +22 -90
- agentpool_server/a2a_server/agent_worker.py +307 -0
- agentpool_server/a2a_server/server.py +23 -18
- agentpool_server/acp_server/acp_agent.py +125 -56
- agentpool_server/acp_server/commands/acp_commands.py +46 -216
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +8 -7
- agentpool_server/acp_server/event_converter.py +651 -0
- agentpool_server/acp_server/input_provider.py +53 -10
- agentpool_server/acp_server/server.py +1 -11
- agentpool_server/acp_server/session.py +90 -410
- agentpool_server/acp_server/session_manager.py +8 -34
- agentpool_server/agui_server/server.py +3 -1
- agentpool_server/mcp_server/server.py +5 -2
- agentpool_server/opencode_server/ENDPOINTS.md +53 -14
- agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
- agentpool_server/opencode_server/__init__.py +0 -8
- agentpool_server/opencode_server/converters.py +132 -26
- agentpool_server/opencode_server/input_provider.py +160 -8
- agentpool_server/opencode_server/models/__init__.py +42 -20
- agentpool_server/opencode_server/models/app.py +12 -0
- agentpool_server/opencode_server/models/events.py +203 -29
- agentpool_server/opencode_server/models/mcp.py +19 -0
- agentpool_server/opencode_server/models/message.py +18 -1
- agentpool_server/opencode_server/models/parts.py +134 -1
- agentpool_server/opencode_server/models/question.py +56 -0
- agentpool_server/opencode_server/models/session.py +13 -1
- agentpool_server/opencode_server/routes/__init__.py +4 -0
- agentpool_server/opencode_server/routes/agent_routes.py +33 -2
- agentpool_server/opencode_server/routes/app_routes.py +66 -3
- agentpool_server/opencode_server/routes/config_routes.py +66 -5
- agentpool_server/opencode_server/routes/file_routes.py +184 -5
- agentpool_server/opencode_server/routes/global_routes.py +1 -1
- agentpool_server/opencode_server/routes/lsp_routes.py +1 -1
- agentpool_server/opencode_server/routes/message_routes.py +122 -66
- agentpool_server/opencode_server/routes/permission_routes.py +63 -0
- agentpool_server/opencode_server/routes/pty_routes.py +23 -22
- agentpool_server/opencode_server/routes/question_routes.py +128 -0
- agentpool_server/opencode_server/routes/session_routes.py +139 -68
- agentpool_server/opencode_server/routes/tui_routes.py +1 -1
- agentpool_server/opencode_server/server.py +47 -2
- agentpool_server/opencode_server/state.py +30 -0
- agentpool_storage/__init__.py +0 -4
- agentpool_storage/base.py +81 -2
- agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
- agentpool_storage/claude_provider/__init__.py +42 -0
- agentpool_storage/{claude_provider.py → claude_provider/provider.py} +190 -8
- agentpool_storage/file_provider.py +149 -15
- agentpool_storage/memory_provider.py +132 -12
- agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
- agentpool_storage/opencode_provider/__init__.py +16 -0
- agentpool_storage/opencode_provider/helpers.py +414 -0
- agentpool_storage/opencode_provider/provider.py +895 -0
- agentpool_storage/session_store.py +20 -6
- agentpool_storage/sql_provider/sql_provider.py +135 -2
- agentpool_storage/sql_provider/utils.py +2 -12
- agentpool_storage/zed_provider/__init__.py +16 -0
- agentpool_storage/zed_provider/helpers.py +281 -0
- agentpool_storage/zed_provider/models.py +130 -0
- agentpool_storage/zed_provider/provider.py +442 -0
- agentpool_storage/zed_provider.py +803 -0
- agentpool_toolsets/__init__.py +0 -2
- agentpool_toolsets/builtin/__init__.py +2 -4
- agentpool_toolsets/builtin/code.py +4 -4
- agentpool_toolsets/builtin/debug.py +115 -40
- agentpool_toolsets/builtin/execution_environment.py +54 -165
- agentpool_toolsets/builtin/skills.py +0 -77
- agentpool_toolsets/builtin/subagent_tools.py +64 -51
- agentpool_toolsets/builtin/workers.py +4 -2
- agentpool_toolsets/composio_toolset.py +2 -2
- agentpool_toolsets/entry_points.py +3 -1
- agentpool_toolsets/fsspec_toolset/grep.py +25 -5
- agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
- agentpool_toolsets/fsspec_toolset/toolset.py +350 -66
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +74 -17
- agentpool_toolsets/mcp_run_toolset.py +8 -11
- agentpool_toolsets/notifications.py +33 -33
- agentpool_toolsets/openapi.py +3 -1
- agentpool_toolsets/search_toolset.py +3 -1
- agentpool_config/resources.py +0 -33
- agentpool_server/acp_server/acp_tools.py +0 -43
- agentpool_server/acp_server/commands/spawn.py +0 -210
- agentpool_storage/opencode_provider.py +0 -730
- agentpool_storage/text_log_provider.py +0 -276
- agentpool_toolsets/builtin/chain.py +0 -288
- agentpool_toolsets/builtin/user_interaction.py +0 -52
- agentpool_toolsets/semantic_memory_toolset.py +0 -536
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,6 +6,7 @@ from typing import Any, Literal, Self
|
|
|
6
6
|
|
|
7
7
|
from pydantic import Field
|
|
8
8
|
|
|
9
|
+
from agentpool_server.opencode_server.models.app import Project # noqa: TC001
|
|
9
10
|
from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
|
|
10
11
|
from agentpool_server.opencode_server.models.message import ( # noqa: TC001
|
|
11
12
|
AssistantMessage,
|
|
@@ -203,26 +204,68 @@ class PartUpdatedEvent(OpenCodeBaseModel):
|
|
|
203
204
|
return cls(properties=PartUpdatedEventProperties(part=part, delta=delta))
|
|
204
205
|
|
|
205
206
|
|
|
206
|
-
class
|
|
207
|
-
"""
|
|
207
|
+
class MessageRemovedProperties(OpenCodeBaseModel):
|
|
208
|
+
"""Properties for message removed event."""
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
session_id: str = Field(alias="sessionID")
|
|
211
|
+
message_id: str = Field(alias="messageID")
|
|
210
212
|
|
|
211
213
|
|
|
212
|
-
class
|
|
213
|
-
"""
|
|
214
|
+
class MessageRemovedEvent(OpenCodeBaseModel):
|
|
215
|
+
"""Message removed event - emitted during revert."""
|
|
214
216
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
type: Literal["message.removed"] = "message.removed"
|
|
218
|
+
properties: MessageRemovedProperties
|
|
217
219
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
@classmethod
|
|
221
|
+
def create(cls, session_id: str, message_id: str) -> Self:
|
|
222
|
+
"""Create message removed event.
|
|
220
223
|
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
Args:
|
|
225
|
+
session_id: Session identifier
|
|
226
|
+
message_id: Message identifier
|
|
223
227
|
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
Returns:
|
|
229
|
+
MessageRemovedEvent instance
|
|
230
|
+
"""
|
|
231
|
+
return cls(properties=MessageRemovedProperties(sessionID=session_id, messageID=message_id))
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class PartRemovedProperties(OpenCodeBaseModel):
|
|
235
|
+
"""Properties for part removed event."""
|
|
236
|
+
|
|
237
|
+
session_id: str = Field(alias="sessionID")
|
|
238
|
+
message_id: str = Field(alias="messageID")
|
|
239
|
+
part_id: str = Field(alias="partID")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class PartRemovedEvent(OpenCodeBaseModel):
|
|
243
|
+
"""Part removed event - emitted during revert."""
|
|
244
|
+
|
|
245
|
+
type: Literal["message.part.removed"] = "message.part.removed"
|
|
246
|
+
properties: PartRemovedProperties
|
|
247
|
+
|
|
248
|
+
@classmethod
|
|
249
|
+
def create(cls, session_id: str, message_id: str, part_id: str) -> Self:
|
|
250
|
+
"""Create part removed event.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
session_id: Session identifier
|
|
254
|
+
message_id: Message identifier
|
|
255
|
+
part_id: Part identifier
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
PartRemovedEvent instance
|
|
259
|
+
"""
|
|
260
|
+
return cls(
|
|
261
|
+
properties=PartRemovedProperties(
|
|
262
|
+
sessionID=session_id, messageID=message_id, partID=part_id
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class PermissionToolInfo(OpenCodeBaseModel):
|
|
268
|
+
"""Tool information for permission event."""
|
|
226
269
|
|
|
227
270
|
message_id: str
|
|
228
271
|
"""Message ID."""
|
|
@@ -230,27 +273,43 @@ class PermissionUpdatedProperties(OpenCodeBaseModel):
|
|
|
230
273
|
call_id: str | None = None
|
|
231
274
|
"""Optional tool call ID."""
|
|
232
275
|
|
|
233
|
-
|
|
234
|
-
|
|
276
|
+
|
|
277
|
+
class PermissionAskedProperties(OpenCodeBaseModel):
|
|
278
|
+
"""Properties for permission.asked event.
|
|
279
|
+
|
|
280
|
+
Matches OpenCode's PermissionNext.Event.Asked schema.
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
id: str
|
|
284
|
+
"""Permission request ID."""
|
|
285
|
+
|
|
286
|
+
session_id: str
|
|
287
|
+
"""Session ID."""
|
|
288
|
+
|
|
289
|
+
permission: str
|
|
290
|
+
"""Tool/permission type name."""
|
|
291
|
+
|
|
292
|
+
patterns: list[str]
|
|
293
|
+
"""Patterns for matching (e.g., file paths, commands)."""
|
|
235
294
|
|
|
236
295
|
metadata: dict[str, Any]
|
|
237
296
|
"""Arbitrary metadata about the tool call."""
|
|
238
297
|
|
|
239
|
-
|
|
240
|
-
"""
|
|
298
|
+
always: list[str]
|
|
299
|
+
"""Patterns that would be approved for future requests if user selects 'always'."""
|
|
241
300
|
|
|
242
|
-
|
|
243
|
-
"""
|
|
301
|
+
tool: PermissionToolInfo
|
|
302
|
+
"""Tool call information."""
|
|
244
303
|
|
|
245
304
|
|
|
246
305
|
class PermissionRequestEvent(OpenCodeBaseModel):
|
|
247
306
|
"""Permission request event - sent when a tool needs user confirmation.
|
|
248
307
|
|
|
249
|
-
Uses 'permission.
|
|
308
|
+
Uses 'permission.asked' event type for OpenCode TUI compatibility.
|
|
250
309
|
"""
|
|
251
310
|
|
|
252
|
-
type: Literal["permission.
|
|
253
|
-
properties:
|
|
311
|
+
type: Literal["permission.asked"] = "permission.asked"
|
|
312
|
+
properties: PermissionAskedProperties
|
|
254
313
|
|
|
255
314
|
@classmethod
|
|
256
315
|
def create(
|
|
@@ -263,17 +322,17 @@ class PermissionRequestEvent(OpenCodeBaseModel):
|
|
|
263
322
|
message_id: str = "",
|
|
264
323
|
call_id: str | None = None,
|
|
265
324
|
) -> Self:
|
|
266
|
-
|
|
325
|
+
# Create pattern from tool name and args
|
|
326
|
+
pattern = f"{tool_name}: {args_preview}" if args_preview else tool_name
|
|
267
327
|
|
|
268
|
-
props =
|
|
328
|
+
props = PermissionAskedProperties(
|
|
269
329
|
id=permission_id,
|
|
270
|
-
type=tool_name,
|
|
271
330
|
session_id=session_id,
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
title=message,
|
|
331
|
+
permission=tool_name,
|
|
332
|
+
patterns=[pattern],
|
|
275
333
|
metadata={"args_preview": args_preview},
|
|
276
|
-
|
|
334
|
+
always=[pattern], # Same pattern for "always" approval
|
|
335
|
+
tool=PermissionToolInfo(message_id=message_id, call_id=call_id),
|
|
277
336
|
)
|
|
278
337
|
return cls(properties=props)
|
|
279
338
|
|
|
@@ -601,6 +660,25 @@ class LspClientDiagnosticsEvent(OpenCodeBaseModel):
|
|
|
601
660
|
# =============================================================================
|
|
602
661
|
|
|
603
662
|
|
|
663
|
+
class ProjectUpdatedEvent(OpenCodeBaseModel):
|
|
664
|
+
"""Project metadata updated event."""
|
|
665
|
+
|
|
666
|
+
type: Literal["project.updated"] = "project.updated"
|
|
667
|
+
properties: Project
|
|
668
|
+
|
|
669
|
+
@classmethod
|
|
670
|
+
def create(cls, project: Project) -> Self:
|
|
671
|
+
"""Create project updated event.
|
|
672
|
+
|
|
673
|
+
Args:
|
|
674
|
+
project: The updated project data
|
|
675
|
+
|
|
676
|
+
Returns:
|
|
677
|
+
ProjectUpdatedEvent instance
|
|
678
|
+
"""
|
|
679
|
+
return cls(properties=project)
|
|
680
|
+
|
|
681
|
+
|
|
604
682
|
class VcsBranchUpdatedProperties(OpenCodeBaseModel):
|
|
605
683
|
"""Properties for VCS branch updated event."""
|
|
606
684
|
|
|
@@ -619,6 +697,96 @@ class VcsBranchUpdatedEvent(OpenCodeBaseModel):
|
|
|
619
697
|
return cls(properties=VcsBranchUpdatedProperties(branch=branch))
|
|
620
698
|
|
|
621
699
|
|
|
700
|
+
class QuestionAskedProperties(OpenCodeBaseModel):
|
|
701
|
+
"""Properties for question asked event."""
|
|
702
|
+
|
|
703
|
+
id: str
|
|
704
|
+
session_id: str
|
|
705
|
+
questions: list[dict[str, Any]]
|
|
706
|
+
tool: dict[str, str] | None = None
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
class QuestionAskedEvent(OpenCodeBaseModel):
|
|
710
|
+
"""Question asked event - sent when agent asks a question."""
|
|
711
|
+
|
|
712
|
+
type: Literal["question.asked"] = "question.asked"
|
|
713
|
+
properties: QuestionAskedProperties
|
|
714
|
+
|
|
715
|
+
@classmethod
|
|
716
|
+
def create(
|
|
717
|
+
cls,
|
|
718
|
+
request_id: str,
|
|
719
|
+
session_id: str,
|
|
720
|
+
questions: list[dict[str, Any]],
|
|
721
|
+
tool: dict[str, str] | None = None,
|
|
722
|
+
) -> Self:
|
|
723
|
+
return cls(
|
|
724
|
+
properties=QuestionAskedProperties(
|
|
725
|
+
id=request_id,
|
|
726
|
+
sessionID=session_id,
|
|
727
|
+
questions=questions,
|
|
728
|
+
tool=tool,
|
|
729
|
+
)
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
class QuestionRepliedProperties(OpenCodeBaseModel):
|
|
734
|
+
"""Properties for question replied event."""
|
|
735
|
+
|
|
736
|
+
session_id: str
|
|
737
|
+
request_id: str
|
|
738
|
+
answers: list[list[str]]
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
class QuestionRepliedEvent(OpenCodeBaseModel):
|
|
742
|
+
"""Question replied event - sent when user answers a question."""
|
|
743
|
+
|
|
744
|
+
type: Literal["question.replied"] = "question.replied"
|
|
745
|
+
properties: QuestionRepliedProperties
|
|
746
|
+
|
|
747
|
+
@classmethod
|
|
748
|
+
def create(
|
|
749
|
+
cls,
|
|
750
|
+
session_id: str,
|
|
751
|
+
request_id: str,
|
|
752
|
+
answers: list[list[str]],
|
|
753
|
+
) -> Self:
|
|
754
|
+
return cls(
|
|
755
|
+
properties=QuestionRepliedProperties(
|
|
756
|
+
sessionID=session_id,
|
|
757
|
+
requestID=request_id,
|
|
758
|
+
answers=answers,
|
|
759
|
+
)
|
|
760
|
+
)
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
class QuestionRejectedProperties(OpenCodeBaseModel):
|
|
764
|
+
"""Properties for question rejected event."""
|
|
765
|
+
|
|
766
|
+
session_id: str
|
|
767
|
+
request_id: str
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
class QuestionRejectedEvent(OpenCodeBaseModel):
|
|
771
|
+
"""Question rejected event - sent when user dismisses a question."""
|
|
772
|
+
|
|
773
|
+
type: Literal["question.rejected"] = "question.rejected"
|
|
774
|
+
properties: QuestionRejectedProperties
|
|
775
|
+
|
|
776
|
+
@classmethod
|
|
777
|
+
def create(
|
|
778
|
+
cls,
|
|
779
|
+
session_id: str,
|
|
780
|
+
request_id: str,
|
|
781
|
+
) -> Self:
|
|
782
|
+
return cls(
|
|
783
|
+
properties=QuestionRejectedProperties(
|
|
784
|
+
sessionID=session_id,
|
|
785
|
+
requestID=request_id,
|
|
786
|
+
)
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
|
|
622
790
|
Event = (
|
|
623
791
|
ServerConnectedEvent
|
|
624
792
|
| SessionCreatedEvent
|
|
@@ -628,9 +796,14 @@ Event = (
|
|
|
628
796
|
| SessionErrorEvent
|
|
629
797
|
| SessionIdleEvent
|
|
630
798
|
| MessageUpdatedEvent
|
|
799
|
+
| MessageRemovedEvent
|
|
631
800
|
| PartUpdatedEvent
|
|
801
|
+
| PartRemovedEvent
|
|
632
802
|
| PermissionRequestEvent
|
|
633
803
|
| PermissionResolvedEvent
|
|
804
|
+
| QuestionAskedEvent
|
|
805
|
+
| QuestionRepliedEvent
|
|
806
|
+
| QuestionRejectedEvent
|
|
634
807
|
| TodoUpdatedEvent
|
|
635
808
|
| FileWatcherUpdatedEvent
|
|
636
809
|
| SessionCompactedEvent
|
|
@@ -640,6 +813,7 @@ Event = (
|
|
|
640
813
|
| PtyDeletedEvent
|
|
641
814
|
| LspUpdatedEvent
|
|
642
815
|
| LspClientDiagnosticsEvent
|
|
816
|
+
| ProjectUpdatedEvent
|
|
643
817
|
| VcsBranchUpdatedEvent
|
|
644
818
|
| TuiPromptAppendEvent
|
|
645
819
|
| TuiCommandExecuteEvent
|
|
@@ -23,3 +23,22 @@ class MCPStatus(OpenCodeBaseModel):
|
|
|
23
23
|
status: Literal["connected", "disconnected", "error"]
|
|
24
24
|
tools: list[str] = Field(default_factory=list)
|
|
25
25
|
error: str | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class McpResource(OpenCodeBaseModel):
|
|
29
|
+
"""MCP resource info matching OpenCode SDK McpResource type."""
|
|
30
|
+
|
|
31
|
+
name: str
|
|
32
|
+
"""Name of the resource."""
|
|
33
|
+
|
|
34
|
+
uri: str
|
|
35
|
+
"""URI identifying the resource location."""
|
|
36
|
+
|
|
37
|
+
description: str | None = None
|
|
38
|
+
"""Optional description of the resource."""
|
|
39
|
+
|
|
40
|
+
mime_type: str | None = None
|
|
41
|
+
"""MIME type of the resource content."""
|
|
42
|
+
|
|
43
|
+
client: str
|
|
44
|
+
"""Name of the MCP client/server providing this resource."""
|
|
@@ -11,6 +11,14 @@ from agentpool_server.opencode_server.models.common import TimeCreated # noqa:
|
|
|
11
11
|
from agentpool_server.opencode_server.models.parts import Part # noqa: TC001
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
class MessageSummary(OpenCodeBaseModel):
|
|
15
|
+
"""Summary information for a message."""
|
|
16
|
+
|
|
17
|
+
title: str | None = None
|
|
18
|
+
body: str | None = None
|
|
19
|
+
diffs: list[Any] = Field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
14
22
|
class MessagePath(OpenCodeBaseModel):
|
|
15
23
|
"""Path context for a message."""
|
|
16
24
|
|
|
@@ -56,7 +64,11 @@ class UserMessage(OpenCodeBaseModel):
|
|
|
56
64
|
session_id: str
|
|
57
65
|
time: TimeCreated
|
|
58
66
|
agent: str = "default"
|
|
59
|
-
model: UserMessageModel
|
|
67
|
+
model: UserMessageModel | None = None
|
|
68
|
+
summary: MessageSummary | None = None
|
|
69
|
+
system: str | None = None
|
|
70
|
+
tools: dict[str, bool] | None = None
|
|
71
|
+
variant: str | None = None
|
|
60
72
|
|
|
61
73
|
|
|
62
74
|
class AssistantMessage(OpenCodeBaseModel):
|
|
@@ -160,3 +172,8 @@ class CommandRequest(OpenCodeBaseModel):
|
|
|
160
172
|
agent: str | None = None
|
|
161
173
|
model: str | None = None # Format: "providerID/modelID"
|
|
162
174
|
message_id: str | None = None
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# Type unions
|
|
178
|
+
|
|
179
|
+
MessageInfo = UserMessage | AssistantMessage
|
|
@@ -7,6 +7,7 @@ from typing import Any, Literal
|
|
|
7
7
|
from pydantic import Field
|
|
8
8
|
|
|
9
9
|
from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
|
|
10
|
+
from agentpool_server.opencode_server.models.common import TimeCreated # noqa: TC001
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class TimeStart(OpenCodeBaseModel):
|
|
@@ -148,6 +149,125 @@ class FilePart(OpenCodeBaseModel):
|
|
|
148
149
|
source: FileSource | None = None
|
|
149
150
|
|
|
150
151
|
|
|
152
|
+
class AgentPartSource(OpenCodeBaseModel):
|
|
153
|
+
"""Agent part source location in original text."""
|
|
154
|
+
|
|
155
|
+
value: str
|
|
156
|
+
start: int
|
|
157
|
+
end: int
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class AgentPart(OpenCodeBaseModel):
|
|
161
|
+
"""Agent mention part - references a sub-agent to delegate to.
|
|
162
|
+
|
|
163
|
+
When a user types @agent-name in the prompt, this part is created.
|
|
164
|
+
The server should inject a synthetic instruction to call the task tool
|
|
165
|
+
with the specified agent.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
id: str
|
|
169
|
+
type: Literal["agent"] = "agent"
|
|
170
|
+
message_id: str
|
|
171
|
+
session_id: str
|
|
172
|
+
name: str
|
|
173
|
+
"""Name of the agent to delegate to."""
|
|
174
|
+
source: AgentPartSource | None = None
|
|
175
|
+
"""Source location in the original prompt text."""
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class SnapshotPart(OpenCodeBaseModel):
|
|
179
|
+
"""File system snapshot reference."""
|
|
180
|
+
|
|
181
|
+
id: str
|
|
182
|
+
type: Literal["snapshot"] = "snapshot"
|
|
183
|
+
message_id: str
|
|
184
|
+
session_id: str
|
|
185
|
+
snapshot: str
|
|
186
|
+
"""Snapshot identifier."""
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class PatchPart(OpenCodeBaseModel):
|
|
190
|
+
"""Diff/patch content part."""
|
|
191
|
+
|
|
192
|
+
id: str
|
|
193
|
+
type: Literal["patch"] = "patch"
|
|
194
|
+
message_id: str
|
|
195
|
+
session_id: str
|
|
196
|
+
hash: str
|
|
197
|
+
"""Hash of the patch."""
|
|
198
|
+
files: list[str] = Field(default_factory=list)
|
|
199
|
+
"""List of files affected by this patch."""
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ReasoningPart(OpenCodeBaseModel):
|
|
203
|
+
"""Extended thinking/reasoning content part.
|
|
204
|
+
|
|
205
|
+
Used for models that support extended thinking (e.g., Claude with thinking tokens).
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
id: str
|
|
209
|
+
type: Literal["reasoning"] = "reasoning"
|
|
210
|
+
message_id: str
|
|
211
|
+
session_id: str
|
|
212
|
+
text: str
|
|
213
|
+
"""The reasoning/thinking content."""
|
|
214
|
+
metadata: dict[str, Any] | None = None
|
|
215
|
+
time: TimeStartEndOptional | None = None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class CompactionPart(OpenCodeBaseModel):
|
|
219
|
+
"""Marks where conversation was compacted/summarized."""
|
|
220
|
+
|
|
221
|
+
id: str
|
|
222
|
+
type: Literal["compaction"] = "compaction"
|
|
223
|
+
message_id: str
|
|
224
|
+
session_id: str
|
|
225
|
+
auto: bool = False
|
|
226
|
+
"""Whether this was an automatic compaction."""
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class SubtaskPart(OpenCodeBaseModel):
|
|
230
|
+
"""References a spawned subtask."""
|
|
231
|
+
|
|
232
|
+
id: str
|
|
233
|
+
type: Literal["subtask"] = "subtask"
|
|
234
|
+
message_id: str
|
|
235
|
+
session_id: str
|
|
236
|
+
prompt: str
|
|
237
|
+
"""The prompt for the subtask."""
|
|
238
|
+
description: str
|
|
239
|
+
"""Description of what the subtask does."""
|
|
240
|
+
agent: str
|
|
241
|
+
"""The agent handling this subtask."""
|
|
242
|
+
command: str | None = None
|
|
243
|
+
"""Optional command associated with the subtask."""
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class APIErrorInfo(OpenCodeBaseModel):
|
|
247
|
+
"""API error information for retry parts."""
|
|
248
|
+
|
|
249
|
+
message: str
|
|
250
|
+
status_code: int | None = None
|
|
251
|
+
is_retryable: bool = False
|
|
252
|
+
response_headers: dict[str, str] | None = None
|
|
253
|
+
response_body: str | None = None
|
|
254
|
+
metadata: dict[str, str] | None = None
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class RetryPart(OpenCodeBaseModel):
|
|
258
|
+
"""Marks a retry of a failed operation."""
|
|
259
|
+
|
|
260
|
+
id: str
|
|
261
|
+
type: Literal["retry"] = "retry"
|
|
262
|
+
message_id: str
|
|
263
|
+
session_id: str
|
|
264
|
+
attempt: int
|
|
265
|
+
"""Which retry attempt this is."""
|
|
266
|
+
error: APIErrorInfo
|
|
267
|
+
"""Error information from the failed attempt."""
|
|
268
|
+
time: TimeCreated
|
|
269
|
+
|
|
270
|
+
|
|
151
271
|
class StepStartPart(OpenCodeBaseModel):
|
|
152
272
|
"""Step start marker."""
|
|
153
273
|
|
|
@@ -187,4 +307,17 @@ class StepFinishPart(OpenCodeBaseModel):
|
|
|
187
307
|
tokens: StepFinishTokens = Field(default_factory=StepFinishTokens)
|
|
188
308
|
|
|
189
309
|
|
|
190
|
-
Part =
|
|
310
|
+
Part = (
|
|
311
|
+
TextPart
|
|
312
|
+
| ToolPart
|
|
313
|
+
| FilePart
|
|
314
|
+
| AgentPart
|
|
315
|
+
| SnapshotPart
|
|
316
|
+
| PatchPart
|
|
317
|
+
| ReasoningPart
|
|
318
|
+
| CompactionPart
|
|
319
|
+
| SubtaskPart
|
|
320
|
+
| RetryPart
|
|
321
|
+
| StepStartPart
|
|
322
|
+
| StepFinishPart
|
|
323
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Question models for OpenCode compatibility."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class QuestionOption(OpenCodeBaseModel):
|
|
11
|
+
"""A single option for a question."""
|
|
12
|
+
|
|
13
|
+
label: str
|
|
14
|
+
"""Display text (1-5 words, concise)."""
|
|
15
|
+
|
|
16
|
+
description: str
|
|
17
|
+
"""Explanation of choice."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class QuestionInfo(OpenCodeBaseModel):
|
|
21
|
+
"""Information about a single question."""
|
|
22
|
+
|
|
23
|
+
question: str
|
|
24
|
+
"""Complete question."""
|
|
25
|
+
|
|
26
|
+
header: str = Field(max_length=12)
|
|
27
|
+
"""Very short label (max 12 chars)."""
|
|
28
|
+
|
|
29
|
+
options: list[QuestionOption]
|
|
30
|
+
"""Available choices."""
|
|
31
|
+
|
|
32
|
+
multiple: bool | None = None
|
|
33
|
+
"""Allow selecting multiple choices."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class QuestionRequest(OpenCodeBaseModel):
|
|
37
|
+
"""A pending question request."""
|
|
38
|
+
|
|
39
|
+
id: str
|
|
40
|
+
"""Unique question identifier."""
|
|
41
|
+
|
|
42
|
+
session_id: str
|
|
43
|
+
"""Session identifier."""
|
|
44
|
+
|
|
45
|
+
questions: list[QuestionInfo]
|
|
46
|
+
"""List of questions to ask."""
|
|
47
|
+
|
|
48
|
+
tool: dict[str, str] | None = None
|
|
49
|
+
"""Optional tool context: {message_id, call_id}."""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class QuestionReply(OpenCodeBaseModel):
|
|
53
|
+
"""Reply to a question request."""
|
|
54
|
+
|
|
55
|
+
answers: list[list[str]]
|
|
56
|
+
"""User answers in order of questions (each answer is an array of selected labels)."""
|
|
@@ -2,12 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import Literal
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
6
8
|
|
|
7
9
|
from agentpool_server.opencode_server.models.base import OpenCodeBaseModel
|
|
8
10
|
from agentpool_server.opencode_server.models.common import TimeCreatedUpdated # noqa: TC001
|
|
9
11
|
|
|
10
12
|
|
|
13
|
+
class SessionSummary(OpenCodeBaseModel):
|
|
14
|
+
"""Summary information for a session."""
|
|
15
|
+
|
|
16
|
+
additions: int | None = None
|
|
17
|
+
deletions: int | None = None
|
|
18
|
+
files: int | None = None
|
|
19
|
+
diffs: list[Any] = Field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
11
22
|
class SessionRevert(OpenCodeBaseModel):
|
|
12
23
|
"""Revert information for a session."""
|
|
13
24
|
|
|
@@ -33,6 +44,7 @@ class Session(OpenCodeBaseModel):
|
|
|
33
44
|
version: str = "1"
|
|
34
45
|
time: TimeCreatedUpdated
|
|
35
46
|
parent_id: str | None = None
|
|
47
|
+
summary: SessionSummary | None = None
|
|
36
48
|
revert: SessionRevert | None = None
|
|
37
49
|
share: SessionShare | None = None
|
|
38
50
|
|
|
@@ -7,6 +7,8 @@ from agentpool_server.opencode_server.routes.session_routes import router as ses
|
|
|
7
7
|
from agentpool_server.opencode_server.routes.message_routes import router as message_router
|
|
8
8
|
from agentpool_server.opencode_server.routes.file_routes import router as file_router
|
|
9
9
|
from agentpool_server.opencode_server.routes.agent_routes import router as agent_router
|
|
10
|
+
from agentpool_server.opencode_server.routes.permission_routes import router as permission_router
|
|
11
|
+
from agentpool_server.opencode_server.routes.question_routes import router as question_router
|
|
10
12
|
from agentpool_server.opencode_server.routes.pty_routes import router as pty_router
|
|
11
13
|
from agentpool_server.opencode_server.routes.tui_routes import router as tui_router
|
|
12
14
|
from agentpool_server.opencode_server.routes.lsp_routes import router as lsp_router
|
|
@@ -19,7 +21,9 @@ __all__ = [
|
|
|
19
21
|
"global_router",
|
|
20
22
|
"lsp_router",
|
|
21
23
|
"message_router",
|
|
24
|
+
"permission_router",
|
|
22
25
|
"pty_router",
|
|
26
|
+
"question_router",
|
|
23
27
|
"session_router",
|
|
24
28
|
"tui_router",
|
|
25
29
|
]
|
|
@@ -21,11 +21,12 @@ from agentpool_config.mcp_server import (
|
|
|
21
21
|
StdioMCPServerConfig,
|
|
22
22
|
StreamableHTTPMCPServerConfig,
|
|
23
23
|
)
|
|
24
|
-
from agentpool_server.opencode_server.dependencies import StateDep
|
|
25
|
-
from agentpool_server.opencode_server.models import (
|
|
24
|
+
from agentpool_server.opencode_server.dependencies import StateDep
|
|
25
|
+
from agentpool_server.opencode_server.models import (
|
|
26
26
|
Agent,
|
|
27
27
|
Command,
|
|
28
28
|
LogRequest,
|
|
29
|
+
McpResource,
|
|
29
30
|
MCPStatus,
|
|
30
31
|
)
|
|
31
32
|
|
|
@@ -178,6 +179,36 @@ async def log(request: LogRequest, state: StateDep) -> bool:
|
|
|
178
179
|
return True
|
|
179
180
|
|
|
180
181
|
|
|
182
|
+
@router.get("/experimental/resource")
|
|
183
|
+
async def list_mcp_resources(state: StateDep) -> dict[str, McpResource]:
|
|
184
|
+
"""Get all available MCP resources from connected servers.
|
|
185
|
+
|
|
186
|
+
Returns a dictionary mapping resource keys to McpResource objects.
|
|
187
|
+
Keys are formatted as "{client}:{resource_name}" for uniqueness.
|
|
188
|
+
"""
|
|
189
|
+
try:
|
|
190
|
+
resources = await state.agent.tools.list_resources()
|
|
191
|
+
result: dict[str, McpResource] = {}
|
|
192
|
+
|
|
193
|
+
for resource in resources:
|
|
194
|
+
# Create unique key: sanitize client and resource names
|
|
195
|
+
client_name = (resource.client or "unknown").replace("/", "_")
|
|
196
|
+
resource_name = resource.name.replace("/", "_")
|
|
197
|
+
key = f"{client_name}:{resource_name}"
|
|
198
|
+
|
|
199
|
+
result[key] = McpResource(
|
|
200
|
+
name=resource.name,
|
|
201
|
+
uri=resource.uri,
|
|
202
|
+
description=resource.description,
|
|
203
|
+
mime_type=resource.mime_type,
|
|
204
|
+
client=resource.client or "unknown",
|
|
205
|
+
)
|
|
206
|
+
except Exception: # noqa: BLE001
|
|
207
|
+
return {}
|
|
208
|
+
else:
|
|
209
|
+
return result
|
|
210
|
+
|
|
211
|
+
|
|
181
212
|
@router.get("/experimental/tool/ids")
|
|
182
213
|
async def list_tool_ids(state: StateDep) -> list[str]:
|
|
183
214
|
"""List all available tool IDs.
|