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.
- acp/__init__.py +13 -0
- acp/bridge/README.md +15 -2
- acp/bridge/__init__.py +3 -2
- acp/bridge/__main__.py +60 -19
- acp/bridge/ws_server.py +173 -0
- acp/bridge/ws_server_cli.py +89 -0
- acp/notifications.py +2 -1
- acp/stdio.py +39 -9
- acp/transports.py +362 -2
- acp/utils.py +15 -2
- agentpool/__init__.py +4 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +203 -88
- agentpool/agents/acp_agent/acp_converters.py +46 -21
- agentpool/agents/acp_agent/client_handler.py +157 -3
- agentpool/agents/acp_agent/session_state.py +4 -1
- agentpool/agents/agent.py +314 -107
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +90 -21
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/base_agent.py +163 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +626 -179
- agentpool/agents/claude_code_agent/converters.py +71 -3
- agentpool/agents/claude_code_agent/history.py +474 -0
- agentpool/agents/context.py +40 -0
- agentpool/agents/events/__init__.py +2 -0
- agentpool/agents/events/builtin_handlers.py +2 -1
- agentpool/agents/events/event_emitter.py +29 -2
- agentpool/agents/events/events.py +20 -0
- agentpool/agents/modes.py +54 -0
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/common_types.py +21 -0
- agentpool/config_resources/__init__.py +38 -1
- agentpool/config_resources/claude_code_agent.yml +3 -0
- agentpool/delegation/pool.py +37 -29
- agentpool/delegation/team.py +1 -0
- agentpool/delegation/teamrun.py +1 -0
- agentpool/diagnostics/__init__.py +53 -0
- agentpool/diagnostics/lsp_manager.py +1593 -0
- agentpool/diagnostics/lsp_proxy.py +41 -0
- agentpool/diagnostics/lsp_proxy_script.py +229 -0
- agentpool/diagnostics/models.py +398 -0
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +12 -3
- agentpool/mcp_server/manager.py +25 -31
- agentpool/mcp_server/registries/official_registry_client.py +25 -0
- agentpool/mcp_server/tool_bridge.py +78 -66
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- agentpool/messaging/message_history.py +12 -0
- agentpool/messaging/messages.py +52 -9
- agentpool/messaging/processing.py +3 -1
- agentpool/models/acp_agents/base.py +0 -22
- agentpool/models/acp_agents/mcp_capable.py +8 -148
- agentpool/models/acp_agents/non_mcp.py +129 -72
- agentpool/models/agents.py +35 -13
- agentpool/models/claude_code_agents.py +33 -2
- agentpool/models/manifest.py +43 -0
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +9 -1
- agentpool/resource_providers/aggregating.py +52 -3
- agentpool/resource_providers/base.py +57 -1
- agentpool/resource_providers/mcp_provider.py +23 -0
- agentpool/resource_providers/plan_provider.py +130 -41
- agentpool/resource_providers/pool.py +2 -0
- agentpool/resource_providers/static.py +2 -0
- agentpool/sessions/__init__.py +2 -1
- agentpool/sessions/manager.py +31 -2
- agentpool/sessions/models.py +50 -0
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +217 -1
- agentpool/testing.py +537 -19
- agentpool/utils/file_watcher.py +269 -0
- agentpool/utils/identifiers.py +121 -0
- agentpool/utils/pydantic_ai_helpers.py +46 -0
- agentpool/utils/streams.py +690 -1
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/METADATA +27 -7
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/RECORD +170 -112
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +4 -0
- agentpool_cli/serve_acp.py +41 -20
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_commands/__init__.py +30 -0
- agentpool_commands/agents.py +74 -1
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- agentpool_commands/tools.py +57 -0
- agentpool_commands/utils.py +51 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -0
- agentpool_config/mcp_server.py +131 -1
- agentpool_config/storage.py +46 -1
- agentpool_config/tools.py +7 -1
- agentpool_config/toolsets.py +92 -148
- agentpool_server/acp_server/acp_agent.py +134 -150
- agentpool_server/acp_server/commands/acp_commands.py +216 -51
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +10 -10
- agentpool_server/acp_server/server.py +23 -79
- agentpool_server/acp_server/session.py +181 -19
- agentpool_server/opencode_server/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +362 -0
- agentpool_server/opencode_server/__init__.py +27 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +869 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +269 -0
- agentpool_server/opencode_server/models/__init__.py +228 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +60 -0
- agentpool_server/opencode_server/models/base.py +26 -0
- agentpool_server/opencode_server/models/common.py +23 -0
- agentpool_server/opencode_server/models/config.py +37 -0
- agentpool_server/opencode_server/models/events.py +647 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +25 -0
- agentpool_server/opencode_server/models/message.py +162 -0
- agentpool_server/opencode_server/models/parts.py +190 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/session.py +99 -0
- agentpool_server/opencode_server/routes/__init__.py +25 -0
- agentpool_server/opencode_server/routes/agent_routes.py +442 -0
- agentpool_server/opencode_server/routes/app_routes.py +139 -0
- agentpool_server/opencode_server/routes/config_routes.py +241 -0
- agentpool_server/opencode_server/routes/file_routes.py +392 -0
- agentpool_server/opencode_server/routes/global_routes.py +94 -0
- agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
- agentpool_server/opencode_server/routes/message_routes.py +705 -0
- agentpool_server/opencode_server/routes/pty_routes.py +299 -0
- agentpool_server/opencode_server/routes/session_routes.py +1205 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +430 -0
- agentpool_server/opencode_server/state.py +121 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +16 -0
- agentpool_storage/base.py +103 -0
- agentpool_storage/claude_provider.py +907 -0
- agentpool_storage/file_provider.py +129 -0
- agentpool_storage/memory_provider.py +61 -0
- agentpool_storage/models.py +3 -0
- agentpool_storage/opencode_provider.py +730 -0
- agentpool_storage/project_store.py +325 -0
- agentpool_storage/session_store.py +6 -0
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +134 -1
- agentpool_storage/sql_provider/utils.py +10 -1
- agentpool_storage/text_log_provider.py +1 -0
- agentpool_toolsets/builtin/__init__.py +0 -8
- agentpool_toolsets/builtin/code.py +95 -56
- agentpool_toolsets/builtin/debug.py +16 -21
- agentpool_toolsets/builtin/execution_environment.py +99 -103
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +86 -4
- agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +74 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +159 -38
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +454 -0
- agentpool_toolsets/mcp_run_toolset.py +84 -6
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/licenses/LICENSE +0 -0
agentpool/storage/manager.py
CHANGED
|
@@ -9,6 +9,7 @@ from anyenv import method_spawner
|
|
|
9
9
|
from pydantic_ai import Agent
|
|
10
10
|
|
|
11
11
|
from agentpool.log import get_logger
|
|
12
|
+
from agentpool.messaging import ChatMessage
|
|
12
13
|
from agentpool.storage.serialization import serialize_messages
|
|
13
14
|
from agentpool.utils.tasks import TaskManager
|
|
14
15
|
from agentpool_config.storage import (
|
|
@@ -25,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
25
26
|
from types import TracebackType
|
|
26
27
|
|
|
27
28
|
from agentpool.common_types import JsonValue
|
|
28
|
-
from agentpool.
|
|
29
|
+
from agentpool.sessions.models import ProjectData
|
|
29
30
|
from agentpool_config.session import SessionQuery
|
|
30
31
|
from agentpool_config.storage import BaseStorageProviderConfig, StorageConfig
|
|
31
32
|
from agentpool_storage.base import StorageProvider
|
|
@@ -209,6 +210,7 @@ class StorageManager:
|
|
|
209
210
|
content=str(message.content),
|
|
210
211
|
role=message.role,
|
|
211
212
|
name=message.name,
|
|
213
|
+
parent_id=message.parent_id,
|
|
212
214
|
cost_info=message.cost_info,
|
|
213
215
|
model=message.model_name,
|
|
214
216
|
response_time=message.response_time,
|
|
@@ -363,6 +365,87 @@ class StorageManager:
|
|
|
363
365
|
provider = self.get_history_provider()
|
|
364
366
|
return await provider.get_conversation_title(conversation_id)
|
|
365
367
|
|
|
368
|
+
@method_spawner
|
|
369
|
+
async def delete_conversation_messages(
|
|
370
|
+
self,
|
|
371
|
+
conversation_id: str,
|
|
372
|
+
) -> int:
|
|
373
|
+
"""Delete all messages for a conversation in all providers.
|
|
374
|
+
|
|
375
|
+
Used for compaction - removes existing messages so they can be
|
|
376
|
+
replaced with compacted versions.
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
conversation_id: ID of the conversation to clear
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
Total number of messages deleted across all providers
|
|
383
|
+
"""
|
|
384
|
+
total_deleted = 0
|
|
385
|
+
for provider in self.providers:
|
|
386
|
+
try:
|
|
387
|
+
deleted = await provider.delete_conversation_messages(conversation_id)
|
|
388
|
+
total_deleted += deleted
|
|
389
|
+
except NotImplementedError:
|
|
390
|
+
# Provider doesn't support deletion (e.g., write-only log)
|
|
391
|
+
pass
|
|
392
|
+
except Exception:
|
|
393
|
+
logger.exception(
|
|
394
|
+
"Error deleting messages from provider",
|
|
395
|
+
provider=provider.__class__.__name__,
|
|
396
|
+
conversation_id=conversation_id,
|
|
397
|
+
)
|
|
398
|
+
return total_deleted
|
|
399
|
+
|
|
400
|
+
@method_spawner
|
|
401
|
+
async def replace_conversation_messages(
|
|
402
|
+
self,
|
|
403
|
+
conversation_id: str,
|
|
404
|
+
messages: Sequence[ChatMessage[Any]],
|
|
405
|
+
) -> tuple[int, int]:
|
|
406
|
+
"""Replace all messages for a conversation with new ones.
|
|
407
|
+
|
|
408
|
+
Deletes existing messages and logs new ones. Used for compaction
|
|
409
|
+
where the full history is replaced with a compacted version.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
conversation_id: ID of the conversation
|
|
413
|
+
messages: New messages to store
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Tuple of (deleted_count, added_count)
|
|
417
|
+
"""
|
|
418
|
+
# First delete existing messages
|
|
419
|
+
deleted = await self.delete_conversation_messages(conversation_id)
|
|
420
|
+
|
|
421
|
+
# Then log new messages
|
|
422
|
+
added = 0
|
|
423
|
+
for message in messages:
|
|
424
|
+
# Ensure conversation_id is set on the message
|
|
425
|
+
msg_to_log: ChatMessage[Any] = message
|
|
426
|
+
if not message.conversation_id:
|
|
427
|
+
msg_to_log = ChatMessage(
|
|
428
|
+
content=message.content,
|
|
429
|
+
role=message.role,
|
|
430
|
+
name=message.name,
|
|
431
|
+
conversation_id=conversation_id,
|
|
432
|
+
message_id=message.message_id,
|
|
433
|
+
parent_id=message.parent_id,
|
|
434
|
+
model_name=message.model_name,
|
|
435
|
+
cost_info=message.cost_info,
|
|
436
|
+
response_time=message.response_time,
|
|
437
|
+
forwarded_from=message.forwarded_from,
|
|
438
|
+
timestamp=message.timestamp,
|
|
439
|
+
provider_name=message.provider_name,
|
|
440
|
+
provider_response_id=message.provider_response_id,
|
|
441
|
+
messages=message.messages,
|
|
442
|
+
finish_reason=message.finish_reason,
|
|
443
|
+
)
|
|
444
|
+
await self.log_message(msg_to_log)
|
|
445
|
+
added += 1
|
|
446
|
+
|
|
447
|
+
return deleted, added
|
|
448
|
+
|
|
366
449
|
async def generate_conversation_title(
|
|
367
450
|
self,
|
|
368
451
|
conversation_id: str,
|
|
@@ -417,3 +500,136 @@ class StorageManager:
|
|
|
417
500
|
return None
|
|
418
501
|
else:
|
|
419
502
|
return title
|
|
503
|
+
|
|
504
|
+
# Project methods
|
|
505
|
+
|
|
506
|
+
def get_project_provider(self) -> StorageProvider:
|
|
507
|
+
"""Get provider capable of storing projects.
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
First provider that supports project storage.
|
|
511
|
+
|
|
512
|
+
Raises:
|
|
513
|
+
RuntimeError: If no capable provider found.
|
|
514
|
+
"""
|
|
515
|
+
for provider in self.providers:
|
|
516
|
+
# TextLogProvider doesn't support projects, others do
|
|
517
|
+
if hasattr(provider, "save_project") and not getattr(provider, "write_only", False):
|
|
518
|
+
return provider
|
|
519
|
+
msg = "No provider found that supports project storage"
|
|
520
|
+
raise RuntimeError(msg)
|
|
521
|
+
|
|
522
|
+
@method_spawner
|
|
523
|
+
async def save_project(self, project: ProjectData) -> None:
|
|
524
|
+
"""Save or update a project in all capable providers.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
project: Project data to persist
|
|
528
|
+
"""
|
|
529
|
+
for provider in self.providers:
|
|
530
|
+
try:
|
|
531
|
+
await provider.save_project(project)
|
|
532
|
+
except NotImplementedError:
|
|
533
|
+
pass
|
|
534
|
+
except Exception:
|
|
535
|
+
logger.exception(
|
|
536
|
+
"Error saving project",
|
|
537
|
+
provider=provider.__class__.__name__,
|
|
538
|
+
project_id=project.project_id,
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
@method_spawner
|
|
542
|
+
async def get_project(self, project_id: str) -> ProjectData | None:
|
|
543
|
+
"""Get a project by ID.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
project_id: Project identifier
|
|
547
|
+
|
|
548
|
+
Returns:
|
|
549
|
+
Project data if found, None otherwise
|
|
550
|
+
"""
|
|
551
|
+
provider = self.get_project_provider()
|
|
552
|
+
return await provider.get_project(project_id)
|
|
553
|
+
|
|
554
|
+
@method_spawner
|
|
555
|
+
async def get_project_by_worktree(self, worktree: str) -> ProjectData | None:
|
|
556
|
+
"""Get a project by worktree path.
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
worktree: Absolute path to the project worktree
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
Project data if found, None otherwise
|
|
563
|
+
"""
|
|
564
|
+
provider = self.get_project_provider()
|
|
565
|
+
return await provider.get_project_by_worktree(worktree)
|
|
566
|
+
|
|
567
|
+
@method_spawner
|
|
568
|
+
async def get_project_by_name(self, name: str) -> ProjectData | None:
|
|
569
|
+
"""Get a project by friendly name.
|
|
570
|
+
|
|
571
|
+
Args:
|
|
572
|
+
name: Project name
|
|
573
|
+
|
|
574
|
+
Returns:
|
|
575
|
+
Project data if found, None otherwise
|
|
576
|
+
"""
|
|
577
|
+
provider = self.get_project_provider()
|
|
578
|
+
return await provider.get_project_by_name(name)
|
|
579
|
+
|
|
580
|
+
@method_spawner
|
|
581
|
+
async def list_projects(self, limit: int | None = None) -> list[ProjectData]:
|
|
582
|
+
"""List all projects, ordered by last_active descending.
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
limit: Maximum number of projects to return
|
|
586
|
+
|
|
587
|
+
Returns:
|
|
588
|
+
List of project data objects
|
|
589
|
+
"""
|
|
590
|
+
provider = self.get_project_provider()
|
|
591
|
+
return await provider.list_projects(limit=limit)
|
|
592
|
+
|
|
593
|
+
@method_spawner
|
|
594
|
+
async def delete_project(self, project_id: str) -> bool:
|
|
595
|
+
"""Delete a project from all providers.
|
|
596
|
+
|
|
597
|
+
Args:
|
|
598
|
+
project_id: Project identifier
|
|
599
|
+
|
|
600
|
+
Returns:
|
|
601
|
+
True if project was deleted from at least one provider
|
|
602
|
+
"""
|
|
603
|
+
deleted = False
|
|
604
|
+
for provider in self.providers:
|
|
605
|
+
try:
|
|
606
|
+
if await provider.delete_project(project_id):
|
|
607
|
+
deleted = True
|
|
608
|
+
except NotImplementedError:
|
|
609
|
+
pass
|
|
610
|
+
except Exception:
|
|
611
|
+
logger.exception(
|
|
612
|
+
"Error deleting project",
|
|
613
|
+
provider=provider.__class__.__name__,
|
|
614
|
+
project_id=project_id,
|
|
615
|
+
)
|
|
616
|
+
return deleted
|
|
617
|
+
|
|
618
|
+
@method_spawner
|
|
619
|
+
async def touch_project(self, project_id: str) -> None:
|
|
620
|
+
"""Update project's last_active timestamp in all providers.
|
|
621
|
+
|
|
622
|
+
Args:
|
|
623
|
+
project_id: Project identifier
|
|
624
|
+
"""
|
|
625
|
+
for provider in self.providers:
|
|
626
|
+
try:
|
|
627
|
+
await provider.touch_project(project_id)
|
|
628
|
+
except NotImplementedError:
|
|
629
|
+
pass
|
|
630
|
+
except Exception:
|
|
631
|
+
logger.exception(
|
|
632
|
+
"Error touching project",
|
|
633
|
+
provider=provider.__class__.__name__,
|
|
634
|
+
project_id=project_id,
|
|
635
|
+
)
|