diff --git a/src/langbot/pkg/agent/runner/context_builder.py b/src/langbot/pkg/agent/runner/context_builder.py index 17e92de8..8cafb67a 100644 --- a/src/langbot/pkg/agent/runner/context_builder.py +++ b/src/langbot/pkg/agent/runner/context_builder.py @@ -1,4 +1,4 @@ -"""Agent run context builder for converting Query to SDK v1 AgentRunContext.""" +"""Agent run context builder for converting Query to AgentRunContext.""" from __future__ import annotations import uuid @@ -15,7 +15,7 @@ from .state_store import get_state_store from . import events as runner_events -# Internal models for SDK v1 context protocol matching SDK v1 resources.py +# Internal models for the agent runner context protocol. class AgentTrigger(typing.TypedDict): @@ -52,32 +52,32 @@ class AgentRunState(typing.TypedDict): runner: dict[str, typing.Any] -# SDK v1 Protocol resource models - matching langbot-plugin-sdk/resources.py +# Resource payload models matching langbot-plugin-sdk/resources.py. class ModelResource(typing.TypedDict): - """Model resource per SDK v1.""" + """Model resource payload.""" model_id: str model_type: str | None provider: str | None class ToolResource(typing.TypedDict): - """Tool resource per SDK v1.""" + """Tool resource payload.""" tool_name: str tool_type: str | None description: str | None class KnowledgeBaseResource(typing.TypedDict): - """Knowledge base resource per SDK v1.""" + """Knowledge base resource payload.""" kb_id: str kb_name: str | None kb_type: str | None class FileResource(typing.TypedDict): - """File resource per SDK v1.""" + """File resource payload.""" file_id: str file_name: str | None mime_type: str | None @@ -85,13 +85,13 @@ class FileResource(typing.TypedDict): class StorageResource(typing.TypedDict): - """Storage resource per SDK v1.""" + """Storage resource payload.""" plugin_storage: bool workspace_storage: bool class AgentResources(typing.TypedDict): - """Agent resources per SDK v1.""" + """Agent resources payload.""" models: list[ModelResource] tools: list[ToolResource] knowledge_bases: list[KnowledgeBaseResource] @@ -110,8 +110,8 @@ class AgentRuntimeContext(typing.TypedDict): metadata: dict[str, typing.Any] -class AgentRunContextV1(typing.TypedDict): - """SDK v1 AgentRunContext per PROTOCOL_V1.md. +class AgentRunContextPayload(typing.TypedDict): + """AgentRunContext payload passed to an agent runner. Note: The 'config' field contains the binding config from ai.runner_config[runner_id], which is Pipeline's configuration for this specific runner binding (not plugin instance config). @@ -133,7 +133,7 @@ class AgentRunContextV1(typing.TypedDict): class AgentRunContextBuilder: - """Builder for converting Query to SDK v1 AgentRunContext. + """Builder for converting Query to AgentRunContext. Responsibilities: - Generate new run_id (UUID, not query id) @@ -168,7 +168,7 @@ class AgentRunContextBuilder: query: pipeline_query.Query, descriptor: AgentRunnerDescriptor, resources: AgentResources, - ) -> AgentRunContextV1: + ) -> AgentRunContextPayload: """Build AgentRunContext from Query. Args: @@ -177,7 +177,7 @@ class AgentRunContextBuilder: resources: Built resources from AgentResourceBuilder Returns: - AgentRunContextV1 dict matching PROTOCOL_V1.md + AgentRunContext payload for the plugin runner """ # Generate new run_id run_id = str(uuid.uuid4()) @@ -242,7 +242,7 @@ class AgentRunContextBuilder: } # Build full context - context: AgentRunContextV1 = { + context: AgentRunContextPayload = { 'run_id': run_id, 'trigger': trigger, 'conversation': conversation, diff --git a/src/langbot/pkg/agent/runner/orchestrator.py b/src/langbot/pkg/agent/runner/orchestrator.py index f9324fc2..8974de9a 100644 --- a/src/langbot/pkg/agent/runner/orchestrator.py +++ b/src/langbot/pkg/agent/runner/orchestrator.py @@ -10,7 +10,7 @@ from langbot_plugin.api.entities.builtin.pipeline import query as pipeline_query from ...core import app from .descriptor import AgentRunnerDescriptor from .registry import AgentRunnerRegistry -from .context_builder import AgentRunContextBuilder, AgentRunContextV1 +from .context_builder import AgentRunContextBuilder, AgentRunContextPayload from .resource_builder import AgentResourceBuilder from .result_normalizer import AgentResultNormalizer from .state_store import get_state_store, RunnerScopedStateStore @@ -133,7 +133,7 @@ class AgentRunOrchestrator: async def _invoke_runner( self, descriptor: AgentRunnerDescriptor, - context: AgentRunContextV1, + context: AgentRunContextPayload, ) -> typing.AsyncGenerator[dict[str, typing.Any], None]: """Invoke runner via plugin connector. @@ -229,4 +229,4 @@ class AgentRunOrchestrator: self.ap.logger.debug( f'Runner {descriptor.id} state.updated: scope={scope}, key={key}, value={value}' ) - # Invalid scope is already logged by state_store.apply_update \ No newline at end of file + # Invalid scope is already logged by state_store.apply_update diff --git a/src/langbot/pkg/agent/runner/resource_builder.py b/src/langbot/pkg/agent/runner/resource_builder.py index c3239c37..82d5e24c 100644 --- a/src/langbot/pkg/agent/runner/resource_builder.py +++ b/src/langbot/pkg/agent/runner/resource_builder.py @@ -31,7 +31,7 @@ class AgentResourceBuilder: Note: This only builds the resource declaration. The actual proxy actions in handler.py must still validate against ctx.resources at runtime. - Resource field names match SDK v1 Protocol: + Resource field names match the plugin SDK payload: - ModelResource: model_id, model_type, provider - ToolResource: tool_name, tool_type, description - KnowledgeBaseResource: kb_id, kb_name, kb_type @@ -93,7 +93,7 @@ class AgentResourceBuilder: descriptor: AgentRunnerDescriptor, query: typing.Any, ) -> list[ModelResource]: - """Build models list with SDK v1 field names.""" + """Build models list with plugin SDK field names.""" models: list[ModelResource] = [] seen_model_ids: set[str] = set() @@ -212,7 +212,7 @@ class AgentResourceBuilder: bound_mcp_servers: list[str] | None, query: typing.Any, ) -> list[ToolResource]: - """Build tools list with SDK v1 field names.""" + """Build tools list with plugin SDK field names.""" tools: list[ToolResource] = [] # Check manifest permission @@ -223,7 +223,7 @@ class AgentResourceBuilder: # Get tools from query (preproc already resolved this for local-agent) use_funcs = getattr(query, 'use_funcs', []) for tool in use_funcs: - # Use SDK v1 field names: tool_name, tool_type, description + # Use plugin SDK field names: tool_name, tool_type, description tools.append({ 'tool_name': tool.name, 'tool_type': None, # Tool type not available in current LLMTool @@ -238,7 +238,7 @@ class AgentResourceBuilder: runner_config: dict[str, typing.Any], query: typing.Any, ) -> list[KnowledgeBaseResource]: - """Build knowledge bases list with SDK v1 field names.""" + """Build knowledge bases list with plugin SDK field names.""" kb_resources: list[KnowledgeBaseResource] = [] # Check manifest permission @@ -263,7 +263,7 @@ class AgentResourceBuilder: try: kb = await self.ap.rag_mgr.get_knowledge_base_by_uuid(kb_uuid) if kb: - # Use SDK v1 field names: kb_id, kb_name, kb_type + # Use plugin SDK field names: kb_id, kb_name, kb_type kb_resources.append({ 'kb_id': kb_uuid, 'kb_name': kb.get_name(), @@ -278,7 +278,7 @@ class AgentResourceBuilder: self, manifest_perms: dict[str, list[str]], ) -> StorageResource: - """Build storage permissions with SDK v1 field names.""" + """Build storage permissions with plugin SDK field names.""" storage_perms = manifest_perms.get('storage', []) return { 'plugin_storage': 'plugin' in storage_perms, diff --git a/src/langbot/pkg/agent/runner/result_normalizer.py b/src/langbot/pkg/agent/runner/result_normalizer.py index 85fa482d..a16fd8c2 100644 --- a/src/langbot/pkg/agent/runner/result_normalizer.py +++ b/src/langbot/pkg/agent/runner/result_normalizer.py @@ -1,4 +1,4 @@ -"""Agent result normalizer for converting SDK v1 AgentRunResult to Pipeline messages.""" +"""Agent result normalizer for converting AgentRunResult to Pipeline messages.""" from __future__ import annotations import typing @@ -15,10 +15,10 @@ MAX_RESULT_SIZE_BYTES = 1024 * 1024 # 1 MB class AgentResultNormalizer: - """Normalizer for converting SDK v1 AgentRunResult to Pipeline messages. + """Normalizer for converting AgentRunResult to Pipeline messages. Responsibilities: - - Accept only SDK v1 result types (message.delta, message.completed, etc.) + - Accept only supported result types (message.delta, message.completed, etc.) - Map message.delta -> MessageChunk - Map message.completed -> Message - Map run.completed (with message) -> Message @@ -27,7 +27,7 @@ class AgentResultNormalizer: - Validate result size - Validate message schema - Per PROTOCOL_V1.md, accepted types: + Accepted result types: - message.delta - message.completed - tool.call.started @@ -144,10 +144,10 @@ class AgentResultNormalizer: return None else: - # Unknown type - warn and ignore (SDK v1 only) + # Unknown type - warn and ignore. self.ap.logger.warning( f'Runner {descriptor.id} returned unknown result type: {result_type}. ' - f'Expected SDK v1 types (message.delta, message.completed, run.completed, run.failed, etc.)' + f'Expected supported types (message.delta, message.completed, run.completed, run.failed, etc.)' ) return None diff --git a/src/langbot/pkg/agent/runner/state_store.py b/src/langbot/pkg/agent/runner/state_store.py index 0043e13e..e1a7f6e2 100644 --- a/src/langbot/pkg/agent/runner/state_store.py +++ b/src/langbot/pkg/agent/runner/state_store.py @@ -9,7 +9,7 @@ from langbot_plugin.api.entities.builtin.pipeline import query as pipeline_query from .descriptor import AgentRunnerDescriptor -# Valid state scopes per PROTOCOL_V1.md +# Valid state scopes for agent runner state updates. VALID_STATE_SCOPES = ('conversation', 'actor', 'subject', 'runner') # Key mapping for backward compatibility @@ -25,7 +25,7 @@ class RunnerScopedStateStore: Key Design Principles: 1. Host-owned: State is owned and managed by LangBot host, not by the plugin. - The plugin can only read/write through the SDK v1 protocol state API. + The plugin can only read/write through agent runner state updates. 2. Scope keys based on stable host identity: Uses host-controlled identifiers (runner_id, bot_uuid, pipeline_uuid, launcher_type, launcher_id) rather than external/unstable identifiers like external conversation id. @@ -296,4 +296,4 @@ def reset_state_store() -> None: """Reset the global state store (for testing).""" global _state_store with _state_store_lock: - _state_store = None \ No newline at end of file + _state_store = None diff --git a/src/langbot/pkg/plugin/connector.py b/src/langbot/pkg/plugin/connector.py index 7ddb88e2..d22ce6f5 100644 --- a/src/langbot/pkg/plugin/connector.py +++ b/src/langbot/pkg/plugin/connector.py @@ -641,10 +641,10 @@ class PluginRuntimeConnector: context: AgentRunContext as dict Yields: - AgentRunResult dicts per Protocol v1 + AgentRunResult dicts """ if not self.is_enable_plugin: - # Return v1 protocol run.failed + # Return a protocol-level failure result. yield { 'type': 'run.failed', 'data': { diff --git a/src/langbot/pkg/plugin/handler.py b/src/langbot/pkg/plugin/handler.py index 0902452c..dda03b28 100644 --- a/src/langbot/pkg/plugin/handler.py +++ b/src/langbot/pkg/plugin/handler.py @@ -1422,7 +1422,7 @@ class RuntimeConnectionHandler(handler.Handler): ) -> typing.AsyncGenerator[dict[str, Any], None]: """Run an AgentRunner component. - Yields AgentRunResult dicts per Protocol v1. + Yields AgentRunResult dicts. """ gen = self.call_action_generator( LangBotToRuntimeAction.RUN_AGENT, diff --git a/tests/unit_tests/agent/test_context_builder_params_state.py b/tests/unit_tests/agent/test_context_builder_params_state.py index fcffac7c..89ece4b9 100644 --- a/tests/unit_tests/agent/test_context_builder_params_state.py +++ b/tests/unit_tests/agent/test_context_builder_params_state.py @@ -330,7 +330,7 @@ class TestBuildState: @pytest.mark.asyncio async def test_context_has_state_field(self): - """AgentRunContextV1 should have state field.""" + """AgentRunContext should have state field.""" reset_state_store() ap = FakeApplication() builder = AgentRunContextBuilder(ap) @@ -394,7 +394,7 @@ class TestBuildParamsInContext: @pytest.mark.asyncio async def test_context_has_params_field(self): - """AgentRunContextV1 should have params field.""" + """AgentRunContext should have params field.""" reset_state_store() ap = FakeApplication() builder = AgentRunContextBuilder(ap)