agentpool 2.1.9__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 +13 -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/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/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 +20 -50
- 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/stdio.py +39 -9
- acp/task/supervisor.py +2 -2
- acp/transports.py +362 -2
- acp/utils.py +17 -4
- agentpool/__init__.py +6 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +407 -277
- agentpool/agents/acp_agent/acp_converters.py +196 -38
- agentpool/agents/acp_agent/client_handler.py +191 -26
- agentpool/agents/acp_agent/session_state.py +17 -6
- agentpool/agents/agent.py +607 -572
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +176 -110
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/agui_agent/helpers.py +3 -4
- agentpool/agents/base_agent.py +632 -17
- 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 +1058 -291
- agentpool/agents/claude_code_agent/converters.py +74 -143
- agentpool/agents/claude_code_agent/history.py +474 -0
- 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/context.py +40 -0
- agentpool/agents/events/__init__.py +24 -0
- agentpool/agents/events/builtin_handlers.py +67 -1
- agentpool/agents/events/event_emitter.py +32 -2
- agentpool/agents/events/events.py +104 -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 +67 -0
- agentpool/agents/slashed_agent.py +5 -4
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/agents/tool_wrapping.py +18 -6
- agentpool/common_types.py +56 -21
- agentpool/config_resources/__init__.py +38 -1
- 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 +10 -6
- agentpool/config_resources/external_acp_agents.yml +2 -1
- agentpool/delegation/base_team.py +4 -30
- agentpool/delegation/pool.py +136 -289
- agentpool/delegation/team.py +58 -57
- agentpool/delegation/teamrun.py +51 -55
- 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/functional/run.py +10 -4
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +76 -32
- agentpool/mcp_server/conversions.py +54 -13
- agentpool/mcp_server/manager.py +34 -54
- agentpool/mcp_server/registries/official_registry_client.py +35 -1
- agentpool/mcp_server/tool_bridge.py +186 -139
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- 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 +99 -8
- agentpool/messaging/messagenode.py +52 -14
- agentpool/messaging/messages.py +54 -35
- agentpool/messaging/processing.py +12 -22
- agentpool/models/__init__.py +1 -1
- agentpool/models/acp_agents/base.py +6 -24
- agentpool/models/acp_agents/mcp_capable.py +126 -157
- agentpool/models/acp_agents/non_mcp.py +129 -95
- agentpool/models/agents.py +98 -76
- agentpool/models/agui_agents.py +1 -1
- agentpool/models/claude_code_agents.py +144 -19
- agentpool/models/file_parsing.py +0 -1
- agentpool/models/manifest.py +113 -50
- agentpool/prompts/conversion_manager.py +1 -1
- agentpool/prompts/prompts.py +5 -2
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +11 -1
- agentpool/resource_providers/aggregating.py +56 -5
- agentpool/resource_providers/base.py +70 -4
- 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 +89 -12
- agentpool/resource_providers/plan_provider.py +228 -46
- agentpool/resource_providers/pool.py +7 -3
- agentpool/resource_providers/resource_info.py +111 -0
- agentpool/resource_providers/static.py +4 -2
- agentpool/sessions/__init__.py +4 -1
- agentpool/sessions/manager.py +33 -5
- agentpool/sessions/models.py +59 -6
- agentpool/sessions/protocol.py +28 -0
- agentpool/sessions/session.py +11 -55
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +572 -49
- agentpool/talk/registry.py +4 -4
- agentpool/talk/talk.py +9 -10
- agentpool/testing.py +538 -20
- 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/file_watcher.py +269 -0
- agentpool/utils/identifiers.py +121 -0
- agentpool/utils/pydantic_ai_helpers.py +46 -0
- agentpool/utils/streams.py +616 -2
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- agentpool/vfs_registry.py +7 -2
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
- agentpool-2.5.0.dist-info/RECORD +579 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +24 -0
- agentpool_cli/create.py +1 -1
- agentpool_cli/serve_acp.py +100 -21
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_cli/ui.py +557 -0
- agentpool_commands/__init__.py +42 -5
- agentpool_commands/agents.py +75 -2
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- 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/tools.py +57 -0
- agentpool_commands/utils.py +80 -30
- agentpool_config/__init__.py +30 -2
- agentpool_config/agentpool_tools.py +498 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -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 +132 -6
- agentpool_config/nodes.py +1 -1
- agentpool_config/observability.py +44 -0
- agentpool_config/session.py +0 -3
- agentpool_config/storage.py +82 -38
- agentpool_config/task.py +3 -3
- agentpool_config/tools.py +11 -22
- agentpool_config/toolsets.py +109 -233
- agentpool_server/a2a_server/agent_worker.py +307 -0
- agentpool_server/a2a_server/server.py +23 -18
- agentpool_server/acp_server/acp_agent.py +234 -181
- agentpool_server/acp_server/commands/acp_commands.py +151 -156
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
- agentpool_server/acp_server/event_converter.py +651 -0
- agentpool_server/acp_server/input_provider.py +53 -10
- agentpool_server/acp_server/server.py +24 -90
- agentpool_server/acp_server/session.py +173 -331
- 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/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +401 -0
- agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
- agentpool_server/opencode_server/__init__.py +19 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +975 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +421 -0
- agentpool_server/opencode_server/models/__init__.py +250 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +72 -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 +821 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +44 -0
- agentpool_server/opencode_server/models/message.py +179 -0
- agentpool_server/opencode_server/models/parts.py +323 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/question.py +56 -0
- agentpool_server/opencode_server/models/session.py +111 -0
- agentpool_server/opencode_server/routes/__init__.py +29 -0
- agentpool_server/opencode_server/routes/agent_routes.py +473 -0
- agentpool_server/opencode_server/routes/app_routes.py +202 -0
- agentpool_server/opencode_server/routes/config_routes.py +302 -0
- agentpool_server/opencode_server/routes/file_routes.py +571 -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 +761 -0
- agentpool_server/opencode_server/routes/permission_routes.py +63 -0
- agentpool_server/opencode_server/routes/pty_routes.py +300 -0
- agentpool_server/opencode_server/routes/question_routes.py +128 -0
- agentpool_server/opencode_server/routes/session_routes.py +1276 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +475 -0
- agentpool_server/opencode_server/state.py +151 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +12 -0
- agentpool_storage/base.py +184 -2
- agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
- agentpool_storage/claude_provider/__init__.py +42 -0
- agentpool_storage/claude_provider/provider.py +1089 -0
- agentpool_storage/file_provider.py +278 -15
- agentpool_storage/memory_provider.py +193 -12
- agentpool_storage/models.py +3 -0
- 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/project_store.py +325 -0
- agentpool_storage/session_store.py +26 -6
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +269 -3
- agentpool_storage/sql_provider/utils.py +12 -13
- 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 -12
- agentpool_toolsets/builtin/code.py +96 -57
- agentpool_toolsets/builtin/debug.py +118 -48
- agentpool_toolsets/builtin/execution_environment.py +115 -230
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +9 -4
- 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/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +99 -7
- agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +511 -0
- agentpool_toolsets/mcp_run_toolset.py +87 -12
- agentpool_toolsets/notifications.py +33 -33
- agentpool_toolsets/openapi.py +3 -1
- agentpool_toolsets/search_toolset.py +3 -1
- agentpool-2.1.9.dist-info/RECORD +0 -474
- 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/text_log_provider.py +0 -275
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/chain.py +0 -288
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- agentpool_toolsets/builtin/user_interaction.py +0 -52
- agentpool_toolsets/semantic_memory_toolset.py +0 -536
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
agentpool_config/commands.py
CHANGED
|
@@ -6,12 +6,16 @@ from collections.abc import Callable
|
|
|
6
6
|
import inspect
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
import re
|
|
9
|
-
from typing import Annotated, Any, Literal
|
|
9
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal
|
|
10
10
|
|
|
11
11
|
from pydantic import ConfigDict, Field, ImportString
|
|
12
12
|
from schemez import Schema
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from slashed import Command
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
class BaseCommandConfig(Schema):
|
|
16
20
|
"""Base configuration for commands."""
|
|
17
21
|
|
|
@@ -43,6 +47,25 @@ class BaseCommandConfig(Schema):
|
|
|
43
47
|
"""
|
|
44
48
|
raise NotImplementedError
|
|
45
49
|
|
|
50
|
+
def get_slashed_command(self, category: str = "manifest") -> Command:
|
|
51
|
+
"""Create a slashed Command from this configuration.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
category: Category to assign to the command
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
A slashed Command instance ready for registration
|
|
58
|
+
"""
|
|
59
|
+
from slashed import Command
|
|
60
|
+
|
|
61
|
+
func = self.get_callable()
|
|
62
|
+
return Command(
|
|
63
|
+
func,
|
|
64
|
+
name=self.name,
|
|
65
|
+
description=self.description,
|
|
66
|
+
category=category,
|
|
67
|
+
)
|
|
68
|
+
|
|
46
69
|
|
|
47
70
|
class StaticCommandConfig(BaseCommandConfig):
|
|
48
71
|
"""Static command with inline content."""
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"""Compaction configuration for message history management."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
from schemez import Schema
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from agentpool.messaging.compaction import CompactionPipeline, CompactionStep
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FilterThinkingConfig(Schema):
|
|
16
|
+
"""Configuration for FilterThinking step."""
|
|
17
|
+
|
|
18
|
+
type: Literal["filter_thinking"] = "filter_thinking"
|
|
19
|
+
|
|
20
|
+
def build(self) -> CompactionStep:
|
|
21
|
+
from agentpool.messaging.compaction import FilterThinking
|
|
22
|
+
|
|
23
|
+
return FilterThinking()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class FilterRetryPromptsConfig(Schema):
|
|
27
|
+
"""Configuration for FilterRetryPrompts step."""
|
|
28
|
+
|
|
29
|
+
type: Literal["filter_retry_prompts"] = "filter_retry_prompts"
|
|
30
|
+
|
|
31
|
+
def build(self) -> CompactionStep:
|
|
32
|
+
from agentpool.messaging.compaction import FilterRetryPrompts
|
|
33
|
+
|
|
34
|
+
return FilterRetryPrompts()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class FilterBinaryContentConfig(Schema):
|
|
38
|
+
"""Configuration for FilterBinaryContent step."""
|
|
39
|
+
|
|
40
|
+
type: Literal["filter_binary"] = "filter_binary"
|
|
41
|
+
keep_references: bool = False
|
|
42
|
+
|
|
43
|
+
def build(self) -> CompactionStep:
|
|
44
|
+
from agentpool.messaging.compaction import FilterBinaryContent
|
|
45
|
+
|
|
46
|
+
return FilterBinaryContent(keep_references=self.keep_references)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class FilterToolCallsConfig(Schema):
|
|
50
|
+
"""Configuration for FilterToolCalls step."""
|
|
51
|
+
|
|
52
|
+
type: Literal["filter_tools"] = "filter_tools"
|
|
53
|
+
exclude_tools: list[str] = Field(default_factory=list)
|
|
54
|
+
include_only: list[str] | None = None
|
|
55
|
+
|
|
56
|
+
def build(self) -> CompactionStep:
|
|
57
|
+
from agentpool.messaging.compaction import FilterToolCalls
|
|
58
|
+
|
|
59
|
+
return FilterToolCalls(exclude_tools=self.exclude_tools, include_only=self.include_only)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class FilterEmptyMessagesConfig(Schema):
|
|
63
|
+
"""Configuration for FilterEmptyMessages step."""
|
|
64
|
+
|
|
65
|
+
type: Literal["filter_empty"] = "filter_empty"
|
|
66
|
+
|
|
67
|
+
def build(self) -> CompactionStep:
|
|
68
|
+
from agentpool.messaging.compaction import FilterEmptyMessages
|
|
69
|
+
|
|
70
|
+
return FilterEmptyMessages()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class TruncateToolOutputsConfig(Schema):
|
|
74
|
+
"""Configuration for TruncateToolOutputs step."""
|
|
75
|
+
|
|
76
|
+
type: Literal["truncate_tool_outputs"] = "truncate_tool_outputs"
|
|
77
|
+
max_length: int = 2000
|
|
78
|
+
suffix: str = "\n... [truncated]"
|
|
79
|
+
|
|
80
|
+
def build(self) -> CompactionStep:
|
|
81
|
+
from agentpool.messaging.compaction import TruncateToolOutputs
|
|
82
|
+
|
|
83
|
+
return TruncateToolOutputs(max_length=self.max_length, suffix=self.suffix)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class TruncateTextPartsConfig(Schema):
|
|
87
|
+
"""Configuration for TruncateTextParts step."""
|
|
88
|
+
|
|
89
|
+
type: Literal["truncate_text"] = "truncate_text"
|
|
90
|
+
max_length: int = 5000
|
|
91
|
+
suffix: str = "\n... [truncated]"
|
|
92
|
+
|
|
93
|
+
def build(self) -> CompactionStep:
|
|
94
|
+
from agentpool.messaging.compaction import TruncateTextParts
|
|
95
|
+
|
|
96
|
+
return TruncateTextParts(max_length=self.max_length, suffix=self.suffix)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class KeepLastMessagesConfig(Schema):
|
|
100
|
+
"""Configuration for KeepLastMessages step."""
|
|
101
|
+
|
|
102
|
+
type: Literal["keep_last"] = "keep_last"
|
|
103
|
+
count: int = 10
|
|
104
|
+
count_pairs: bool = True
|
|
105
|
+
|
|
106
|
+
def build(self) -> CompactionStep:
|
|
107
|
+
from agentpool.messaging.compaction import KeepLastMessages
|
|
108
|
+
|
|
109
|
+
return KeepLastMessages(count=self.count, count_pairs=self.count_pairs)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class KeepFirstMessagesConfig(Schema):
|
|
113
|
+
"""Configuration for KeepFirstMessages step."""
|
|
114
|
+
|
|
115
|
+
type: Literal["keep_first"] = "keep_first"
|
|
116
|
+
count: int = 2
|
|
117
|
+
|
|
118
|
+
def build(self) -> CompactionStep:
|
|
119
|
+
from agentpool.messaging.compaction import KeepFirstMessages
|
|
120
|
+
|
|
121
|
+
return KeepFirstMessages(count=self.count)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class KeepFirstAndLastConfig(Schema):
|
|
125
|
+
"""Configuration for KeepFirstAndLast step."""
|
|
126
|
+
|
|
127
|
+
type: Literal["keep_first_last"] = "keep_first_last"
|
|
128
|
+
first_count: int = 2
|
|
129
|
+
last_count: int = 5
|
|
130
|
+
|
|
131
|
+
def build(self) -> CompactionStep:
|
|
132
|
+
from agentpool.messaging.compaction import KeepFirstAndLast
|
|
133
|
+
|
|
134
|
+
return KeepFirstAndLast(first_count=self.first_count, last_count=self.last_count)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class TokenBudgetConfig(Schema):
|
|
138
|
+
"""Configuration for TokenBudget step."""
|
|
139
|
+
|
|
140
|
+
type: Literal["token_budget"] = "token_budget"
|
|
141
|
+
max_tokens: int = 4000
|
|
142
|
+
model: str = "gpt-4o"
|
|
143
|
+
|
|
144
|
+
def build(self) -> CompactionStep:
|
|
145
|
+
from agentpool.messaging.compaction import TokenBudget
|
|
146
|
+
|
|
147
|
+
return TokenBudget(max_tokens=self.max_tokens, model=self.model)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class SummarizeConfig(Schema):
|
|
151
|
+
"""Configuration for Summarize step."""
|
|
152
|
+
|
|
153
|
+
type: Literal["summarize"] = "summarize"
|
|
154
|
+
model: str = "openai:gpt-4o-mini"
|
|
155
|
+
threshold: int = 15
|
|
156
|
+
keep_recent: int = 5
|
|
157
|
+
summary_prompt: str | None = None
|
|
158
|
+
|
|
159
|
+
def build(self) -> CompactionStep:
|
|
160
|
+
from agentpool.messaging.compaction import Summarize
|
|
161
|
+
|
|
162
|
+
kwargs: dict[str, Any] = {
|
|
163
|
+
"model": self.model,
|
|
164
|
+
"threshold": self.threshold,
|
|
165
|
+
"keep_recent": self.keep_recent,
|
|
166
|
+
}
|
|
167
|
+
if self.summary_prompt:
|
|
168
|
+
kwargs["summary_prompt"] = self.summary_prompt
|
|
169
|
+
return Summarize(**kwargs)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class WhenMessageCountExceedsConfig(Schema):
|
|
173
|
+
"""Configuration for WhenMessageCountExceeds wrapper."""
|
|
174
|
+
|
|
175
|
+
type: Literal["when_count_exceeds"] = "when_count_exceeds"
|
|
176
|
+
threshold: int = 20
|
|
177
|
+
step: "CompactionStepConfig"
|
|
178
|
+
|
|
179
|
+
def build(self) -> CompactionStep:
|
|
180
|
+
from agentpool.messaging.compaction import WhenMessageCountExceeds
|
|
181
|
+
|
|
182
|
+
return WhenMessageCountExceeds(step=self.step.build(), threshold=self.threshold)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# Union of all config types with discriminator
|
|
186
|
+
CompactionStepConfig = Annotated[
|
|
187
|
+
FilterThinkingConfig
|
|
188
|
+
| FilterRetryPromptsConfig
|
|
189
|
+
| FilterBinaryContentConfig
|
|
190
|
+
| FilterToolCallsConfig
|
|
191
|
+
| FilterEmptyMessagesConfig
|
|
192
|
+
| TruncateToolOutputsConfig
|
|
193
|
+
| TruncateTextPartsConfig
|
|
194
|
+
| KeepLastMessagesConfig
|
|
195
|
+
| KeepFirstMessagesConfig
|
|
196
|
+
| KeepFirstAndLastConfig
|
|
197
|
+
| TokenBudgetConfig
|
|
198
|
+
| SummarizeConfig
|
|
199
|
+
| WhenMessageCountExceedsConfig,
|
|
200
|
+
Field(discriminator="type"),
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
# Update forward reference
|
|
204
|
+
WhenMessageCountExceedsConfig.model_rebuild()
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class CompactionConfig(Schema):
|
|
208
|
+
"""Configuration for message compaction/summarization.
|
|
209
|
+
|
|
210
|
+
Example YAML:
|
|
211
|
+
```yaml
|
|
212
|
+
compaction:
|
|
213
|
+
steps:
|
|
214
|
+
- type: filter_thinking
|
|
215
|
+
- type: truncate_tool_outputs
|
|
216
|
+
max_length: 1000
|
|
217
|
+
- type: keep_last
|
|
218
|
+
count: 10
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Or use a preset:
|
|
222
|
+
```yaml
|
|
223
|
+
compaction:
|
|
224
|
+
preset: balanced
|
|
225
|
+
```
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
preset: Literal["minimal", "balanced", "summarizing"] | None = None
|
|
229
|
+
"""Use a predefined compaction pipeline.
|
|
230
|
+
|
|
231
|
+
- minimal: Aggressively minimize context (filter thinking, truncate, keep last 10)
|
|
232
|
+
- balanced: Balance context preservation with size (filter thinking, truncate,
|
|
233
|
+
keep first 2 + last 8)
|
|
234
|
+
- summarizing: Summarize old messages (filter thinking, summarize when > 20 messages)
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
steps: list[CompactionStepConfig] = Field(default_factory=list)
|
|
238
|
+
"""Ordered list of compaction steps to apply (ignored if preset is set)."""
|
|
239
|
+
|
|
240
|
+
def build(self) -> CompactionPipeline:
|
|
241
|
+
"""Build a CompactionPipeline from this configuration."""
|
|
242
|
+
from agentpool.messaging.compaction import (
|
|
243
|
+
CompactionPipeline,
|
|
244
|
+
balanced_context,
|
|
245
|
+
minimal_context,
|
|
246
|
+
summarizing_context,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
if self.preset:
|
|
250
|
+
match self.preset:
|
|
251
|
+
case "minimal":
|
|
252
|
+
return minimal_context()
|
|
253
|
+
case "balanced":
|
|
254
|
+
return balanced_context()
|
|
255
|
+
case "summarizing":
|
|
256
|
+
return summarizing_context()
|
|
257
|
+
|
|
258
|
+
return CompactionPipeline(steps=[step.build() for step in self.steps])
|
agentpool_config/converters.py
CHANGED
|
@@ -392,6 +392,47 @@ class CallbackEventHandlerConfig(BaseEventHandlerConfig):
|
|
|
392
392
|
return import_callable(self.import_path)
|
|
393
393
|
|
|
394
394
|
|
|
395
|
+
class FileStreamEventHandlerConfig(BaseEventHandlerConfig):
|
|
396
|
+
"""Configuration for streaming agent output to a file."""
|
|
397
|
+
|
|
398
|
+
model_config = ConfigDict(title="File Stream Event Handler")
|
|
399
|
+
|
|
400
|
+
type: Literal["file"] = Field("file", init=False)
|
|
401
|
+
"""File stream event handler."""
|
|
402
|
+
|
|
403
|
+
path: str = Field(
|
|
404
|
+
examples=["~/agent_output.txt", "/tmp/agent.log", "./output.md"],
|
|
405
|
+
)
|
|
406
|
+
"""Path to the output file. Supports ~ expansion."""
|
|
407
|
+
|
|
408
|
+
mode: Literal["w", "a"] = Field(
|
|
409
|
+
default="a",
|
|
410
|
+
examples=["w", "a"],
|
|
411
|
+
)
|
|
412
|
+
"""File open mode.
|
|
413
|
+
|
|
414
|
+
- w: Overwrite file on each run
|
|
415
|
+
- a: Append to existing file
|
|
416
|
+
"""
|
|
417
|
+
|
|
418
|
+
include_tools: bool = Field(default=False)
|
|
419
|
+
"""Whether to include tool call and result information."""
|
|
420
|
+
|
|
421
|
+
include_thinking: bool = Field(default=False)
|
|
422
|
+
"""Whether to include thinking/reasoning content."""
|
|
423
|
+
|
|
424
|
+
def get_handler(self) -> IndividualEventHandler:
|
|
425
|
+
"""Create and return the file stream handler."""
|
|
426
|
+
from agentpool.agents.events.builtin_handlers import create_file_stream_handler
|
|
427
|
+
|
|
428
|
+
return create_file_stream_handler(
|
|
429
|
+
path=self.path,
|
|
430
|
+
mode=self.mode,
|
|
431
|
+
include_tools=self.include_tools,
|
|
432
|
+
include_thinking=self.include_thinking,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
|
|
395
436
|
class TTSEventHandlerConfig(BaseEventHandlerConfig):
|
|
396
437
|
"""Configuration for Text-to-Speech event handler with OpenAI streaming."""
|
|
397
438
|
|
|
@@ -578,6 +619,7 @@ class EdgeTTSEventHandlerConfig(BaseEventHandlerConfig):
|
|
|
578
619
|
EventHandlerConfig = Annotated[
|
|
579
620
|
StdoutEventHandlerConfig
|
|
580
621
|
| CallbackEventHandlerConfig
|
|
622
|
+
| FileStreamEventHandlerConfig
|
|
581
623
|
| TTSEventHandlerConfig
|
|
582
624
|
| EdgeTTSEventHandlerConfig,
|
|
583
625
|
Field(discriminator="type"),
|
agentpool_config/events.py
CHANGED
|
@@ -118,9 +118,6 @@ class NodeConnectionConfig(ConnectionConfig):
|
|
|
118
118
|
|
|
119
119
|
DEFAULT_MESSAGE_TEMPLATE = """
|
|
120
120
|
[{{ message.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}] {{ message.name }}: {{ message.content }}
|
|
121
|
-
{%- if message.forwarded_from %}
|
|
122
|
-
(via: {{ message.forwarded_from|join(' -> ') }})
|
|
123
|
-
{%- endif %}
|
|
124
121
|
"""
|
|
125
122
|
|
|
126
123
|
|
|
@@ -135,7 +132,7 @@ class FileConnectionConfig(ConnectionConfig):
|
|
|
135
132
|
- role: Message role (user/assistant/system)
|
|
136
133
|
- model: Model used (if any)
|
|
137
134
|
- cost_info: Token usage and cost info
|
|
138
|
-
-
|
|
135
|
+
- parent_id: ID of parent message for tracking chains
|
|
139
136
|
"""
|
|
140
137
|
|
|
141
138
|
model_config = ConfigDict(json_schema_extra={"title": "File Connection Configuration"})
|
agentpool_config/jinja.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, Literal
|
|
|
7
7
|
from pydantic import BaseModel, ConfigDict, Field
|
|
8
8
|
from schemez import Schema
|
|
9
9
|
|
|
10
|
-
from agentpool_config
|
|
10
|
+
from agentpool_config import ToolConfig
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
@@ -141,9 +141,9 @@ class Jinja2EnvironmentConfig(Schema):
|
|
|
141
141
|
try:
|
|
142
142
|
# Convert filters - use tool name as filter name
|
|
143
143
|
tools = [cfg.get_tool() for cfg in self.filters]
|
|
144
|
-
kwargs["filters"] = {tool.name: tool.
|
|
144
|
+
kwargs["filters"] = {tool.name: tool.get_callable() for tool in tools}
|
|
145
145
|
tools = [cfg.get_tool() for cfg in self.tests]
|
|
146
|
-
kwargs["tests"] = {tool.name: tool.
|
|
146
|
+
kwargs["tests"] = {tool.name: tool.get_callable() for tool in tools}
|
|
147
147
|
|
|
148
148
|
except Exception as exc:
|
|
149
149
|
msg = f"Failed to import Jinja2 filters/tests: {exc}"
|
agentpool_config/mcp_server.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import os
|
|
6
6
|
from typing import TYPE_CHECKING, Annotated, Literal, Self
|
|
7
7
|
|
|
8
|
-
from pydantic import ConfigDict, Field, HttpUrl
|
|
8
|
+
from pydantic import ConfigDict, Field, HttpUrl, model_validator
|
|
9
9
|
from schemez import Schema
|
|
10
10
|
|
|
11
11
|
|
|
@@ -73,6 +73,62 @@ class BaseMCPServerConfig(Schema):
|
|
|
73
73
|
)
|
|
74
74
|
"""Timeout for the server process in seconds."""
|
|
75
75
|
|
|
76
|
+
enabled_tools: list[str] | None = Field(
|
|
77
|
+
default=None,
|
|
78
|
+
examples=[["read_file", "list_directory"], ["search", "fetch"]],
|
|
79
|
+
title="Enabled tools",
|
|
80
|
+
)
|
|
81
|
+
"""If set, only these tools will be available (whitelist).
|
|
82
|
+
Mutually exclusive with disabled_tools."""
|
|
83
|
+
|
|
84
|
+
disabled_tools: list[str] | None = Field(
|
|
85
|
+
default=None,
|
|
86
|
+
examples=[["delete_file", "write_file"], ["dangerous_tool"]],
|
|
87
|
+
title="Disabled tools",
|
|
88
|
+
)
|
|
89
|
+
"""Tools to exclude from this server (blacklist). Mutually exclusive with enabled_tools."""
|
|
90
|
+
|
|
91
|
+
@model_validator(mode="after")
|
|
92
|
+
def _validate_tool_filters(self) -> Self:
|
|
93
|
+
"""Validate that enabled_tools and disabled_tools are mutually exclusive."""
|
|
94
|
+
if self.enabled_tools is not None and self.disabled_tools is not None:
|
|
95
|
+
msg = "Cannot specify both 'enabled_tools' and 'disabled_tools'"
|
|
96
|
+
raise ValueError(msg)
|
|
97
|
+
return self
|
|
98
|
+
|
|
99
|
+
def is_tool_allowed(self, tool_name: str) -> bool:
|
|
100
|
+
"""Check if a tool is allowed based on enabled/disabled lists.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
tool_name: Name of the tool to check
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
True if the tool is allowed, False otherwise
|
|
107
|
+
"""
|
|
108
|
+
if self.enabled_tools is not None:
|
|
109
|
+
return tool_name in self.enabled_tools
|
|
110
|
+
if self.disabled_tools is not None:
|
|
111
|
+
return tool_name not in self.disabled_tools
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
def needs_tool_filtering(self) -> bool:
|
|
115
|
+
"""Check if this config has tool filtering configured."""
|
|
116
|
+
return self.enabled_tools is not None or self.disabled_tools is not None
|
|
117
|
+
|
|
118
|
+
def wrap_with_mcp_filter(self) -> StdioMCPServerConfig:
|
|
119
|
+
"""Wrap this MCP server with mcp-filter for tool filtering.
|
|
120
|
+
|
|
121
|
+
Creates a new StdioMCPServerConfig that runs mcp-filter as a proxy,
|
|
122
|
+
applying the configured enabled_tools/disabled_tools filtering.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
A new StdioMCPServerConfig that wraps the original server with mcp-filter
|
|
126
|
+
|
|
127
|
+
Raises:
|
|
128
|
+
NotImplementedError: Subclasses must implement this method
|
|
129
|
+
"""
|
|
130
|
+
raise NotImplementedError
|
|
131
|
+
|
|
76
132
|
def get_env_vars(self) -> dict[str, str]:
|
|
77
133
|
"""Get environment variables for the server process."""
|
|
78
134
|
env = os.environ.copy()
|
|
@@ -82,11 +138,7 @@ class BaseMCPServerConfig(Schema):
|
|
|
82
138
|
return env
|
|
83
139
|
|
|
84
140
|
def to_pydantic_ai(self) -> MCPServer:
|
|
85
|
-
"""Convert to pydantic-ai MCP server instance.
|
|
86
|
-
|
|
87
|
-
Returns:
|
|
88
|
-
A pydantic-ai MCP server instance
|
|
89
|
-
"""
|
|
141
|
+
"""Convert to pydantic-ai MCP server instance."""
|
|
90
142
|
raise NotImplementedError
|
|
91
143
|
|
|
92
144
|
@property
|
|
@@ -142,6 +194,34 @@ class StdioMCPServerConfig(BaseMCPServerConfig):
|
|
|
142
194
|
"""Generate a unique client ID for this stdio server configuration."""
|
|
143
195
|
return f"{self.command}_{' '.join(self.args)}"
|
|
144
196
|
|
|
197
|
+
def wrap_with_mcp_filter(self) -> StdioMCPServerConfig:
|
|
198
|
+
"""Wrap this stdio MCP server with mcp-filter for tool filtering.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
A new StdioMCPServerConfig that wraps this server with mcp-filter
|
|
202
|
+
"""
|
|
203
|
+
filter_args = ["mcp-filter", "run", "-t", "stdio", "--stdio-command", self.command]
|
|
204
|
+
|
|
205
|
+
# Add original args as a single --stdio-arg
|
|
206
|
+
if self.args:
|
|
207
|
+
filter_args.extend(["--stdio-arg", " ".join(self.args)])
|
|
208
|
+
|
|
209
|
+
# Add allowlist (exact tool names)
|
|
210
|
+
if self.enabled_tools:
|
|
211
|
+
filter_args.extend(["-a", ",".join(self.enabled_tools)])
|
|
212
|
+
|
|
213
|
+
# Add denylist (regex patterns)
|
|
214
|
+
if self.disabled_tools:
|
|
215
|
+
filter_args.extend(["-d", ",".join(self.disabled_tools)])
|
|
216
|
+
|
|
217
|
+
return StdioMCPServerConfig(
|
|
218
|
+
name=self.name,
|
|
219
|
+
command="uvx",
|
|
220
|
+
args=filter_args,
|
|
221
|
+
env=self.env,
|
|
222
|
+
timeout=self.timeout,
|
|
223
|
+
)
|
|
224
|
+
|
|
145
225
|
def to_pydantic_ai(self) -> MCPServerStdio:
|
|
146
226
|
"""Convert to pydantic-ai MCPServerStdio instance."""
|
|
147
227
|
from pydantic_ai.mcp import MCPServerStdio
|
|
@@ -186,6 +266,29 @@ class SSEMCPServerConfig(BaseMCPServerConfig):
|
|
|
186
266
|
"""Generate a unique client ID for this SSE server configuration."""
|
|
187
267
|
return f"sse_{self.url}"
|
|
188
268
|
|
|
269
|
+
def wrap_with_mcp_filter(self) -> StdioMCPServerConfig:
|
|
270
|
+
"""Wrap this SSE MCP server with mcp-filter for tool filtering.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
A new StdioMCPServerConfig that wraps this server with mcp-filter
|
|
274
|
+
"""
|
|
275
|
+
filter_args = ["mcp-filter", "run", "-t", "http", "--http-url", str(self.url)]
|
|
276
|
+
|
|
277
|
+
# Add allowlist (exact tool names)
|
|
278
|
+
if self.enabled_tools:
|
|
279
|
+
filter_args.extend(["-a", ",".join(self.enabled_tools)])
|
|
280
|
+
|
|
281
|
+
# Add denylist (regex patterns)
|
|
282
|
+
if self.disabled_tools:
|
|
283
|
+
filter_args.extend(["-d", ",".join(self.disabled_tools)])
|
|
284
|
+
|
|
285
|
+
return StdioMCPServerConfig(
|
|
286
|
+
name=self.name,
|
|
287
|
+
command="uvx",
|
|
288
|
+
args=filter_args,
|
|
289
|
+
timeout=self.timeout,
|
|
290
|
+
)
|
|
291
|
+
|
|
189
292
|
def to_pydantic_ai(self) -> MCPServerSSE:
|
|
190
293
|
"""Convert to pydantic-ai MCPServerSSE instance."""
|
|
191
294
|
from pydantic_ai.mcp import MCPServerSSE
|
|
@@ -225,6 +328,29 @@ class StreamableHTTPMCPServerConfig(BaseMCPServerConfig):
|
|
|
225
328
|
"""Generate a unique client ID for this streamable HTTP server configuration."""
|
|
226
329
|
return f"streamable_http_{self.url}"
|
|
227
330
|
|
|
331
|
+
def wrap_with_mcp_filter(self) -> StdioMCPServerConfig:
|
|
332
|
+
"""Wrap this HTTP MCP server with mcp-filter for tool filtering.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
A new StdioMCPServerConfig that wraps this server with mcp-filter
|
|
336
|
+
"""
|
|
337
|
+
filter_args = ["mcp-filter", "run", "-t", "http", "--http-url", str(self.url)]
|
|
338
|
+
|
|
339
|
+
# Add allowlist (exact tool names)
|
|
340
|
+
if self.enabled_tools:
|
|
341
|
+
filter_args.extend(["-a", ",".join(self.enabled_tools)])
|
|
342
|
+
|
|
343
|
+
# Add denylist (regex patterns)
|
|
344
|
+
if self.disabled_tools:
|
|
345
|
+
filter_args.extend(["-d", ",".join(self.disabled_tools)])
|
|
346
|
+
|
|
347
|
+
return StdioMCPServerConfig(
|
|
348
|
+
name=self.name,
|
|
349
|
+
command="uvx",
|
|
350
|
+
args=filter_args,
|
|
351
|
+
timeout=self.timeout,
|
|
352
|
+
)
|
|
353
|
+
|
|
228
354
|
def to_pydantic_ai(self) -> MCPServerStreamableHTTP:
|
|
229
355
|
"""Convert to pydantic-ai MCPServerStreamableHTTP instance."""
|
|
230
356
|
from pydantic_ai.mcp import MCPServerStreamableHTTP
|
agentpool_config/nodes.py
CHANGED
|
@@ -149,6 +149,49 @@ class ArizePhoenixObservabilityConfig(BaseObservabilityConfig):
|
|
|
149
149
|
object.__setattr__(self, "_headers", headers)
|
|
150
150
|
|
|
151
151
|
|
|
152
|
+
class AxiomObservabilityConfig(BaseObservabilityConfig):
|
|
153
|
+
"""Configuration for Axiom endpoint."""
|
|
154
|
+
|
|
155
|
+
model_config = ConfigDict(json_schema_extra={"x-doc-title": "Axiom"})
|
|
156
|
+
|
|
157
|
+
type: Literal["axiom"] = "axiom"
|
|
158
|
+
"""Axiom observability configuration."""
|
|
159
|
+
|
|
160
|
+
api_token: SecretStr | None = Field(default=None, title="Axiom API token")
|
|
161
|
+
"""Axiom API token with ingest permissions."""
|
|
162
|
+
|
|
163
|
+
dataset: str = Field(
|
|
164
|
+
examples=["traces", "otel-traces", "my-service-traces"],
|
|
165
|
+
title="Dataset name",
|
|
166
|
+
)
|
|
167
|
+
"""Axiom dataset name where traces are sent."""
|
|
168
|
+
|
|
169
|
+
region: Literal["us", "eu"] | None = Field(
|
|
170
|
+
default=None,
|
|
171
|
+
examples=["us", "eu"],
|
|
172
|
+
title="Region",
|
|
173
|
+
)
|
|
174
|
+
"""Axiom region. If not set, uses default cloud endpoint."""
|
|
175
|
+
|
|
176
|
+
_endpoint: str = PrivateAttr()
|
|
177
|
+
_headers: dict[str, str] = PrivateAttr(default_factory=dict)
|
|
178
|
+
|
|
179
|
+
def model_post_init(self, __context: Any, /) -> None:
|
|
180
|
+
"""Compute private attributes from user config."""
|
|
181
|
+
# Axiom uses /v1/traces endpoint for OTLP
|
|
182
|
+
if self.region == "eu":
|
|
183
|
+
endpoint = "https://api.eu.axiom.co/v1/traces"
|
|
184
|
+
else:
|
|
185
|
+
endpoint = "https://api.axiom.co/v1/traces"
|
|
186
|
+
object.__setattr__(self, "_endpoint", endpoint)
|
|
187
|
+
|
|
188
|
+
headers: dict[str, str] = {}
|
|
189
|
+
if self.api_token:
|
|
190
|
+
headers["Authorization"] = f"Bearer {self.api_token.get_secret_value()}"
|
|
191
|
+
headers["X-Axiom-Dataset"] = self.dataset
|
|
192
|
+
object.__setattr__(self, "_headers", headers)
|
|
193
|
+
|
|
194
|
+
|
|
152
195
|
class CustomObservabilityConfig(BaseObservabilityConfig):
|
|
153
196
|
"""Configuration for custom OTEL endpoint."""
|
|
154
197
|
|
|
@@ -173,6 +216,7 @@ ObservabilityProviderConfig = Annotated[
|
|
|
173
216
|
| LangsmithObservabilityConfig
|
|
174
217
|
| AgentOpsObservabilityConfig
|
|
175
218
|
| ArizePhoenixObservabilityConfig
|
|
219
|
+
| AxiomObservabilityConfig
|
|
176
220
|
| CustomObservabilityConfig,
|
|
177
221
|
Field(discriminator="type"),
|
|
178
222
|
]
|
agentpool_config/session.py
CHANGED
|
@@ -103,9 +103,6 @@ class SessionQuery(Schema):
|
|
|
103
103
|
limit: int | None = Field(default=None, examples=[10, 50, 100], title="Message limit")
|
|
104
104
|
"""Maximum number of messages to return."""
|
|
105
105
|
|
|
106
|
-
include_forwarded: bool = Field(default=True, title="Include forwarded messages")
|
|
107
|
-
"""Whether to include messages forwarded through agents."""
|
|
108
|
-
|
|
109
106
|
model_config = ConfigDict(frozen=True)
|
|
110
107
|
|
|
111
108
|
def get_time_cutoff(self) -> datetime | None:
|