mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-20 19:36:08 +00:00
chore(agent): remove v1 wording from runner internals
This commit is contained in:
@@ -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
|
from __future__ import annotations
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
@@ -15,7 +15,7 @@ from .state_store import get_state_store
|
|||||||
from . import events as runner_events
|
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):
|
class AgentTrigger(typing.TypedDict):
|
||||||
@@ -52,32 +52,32 @@ class AgentRunState(typing.TypedDict):
|
|||||||
runner: dict[str, typing.Any]
|
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):
|
class ModelResource(typing.TypedDict):
|
||||||
"""Model resource per SDK v1."""
|
"""Model resource payload."""
|
||||||
model_id: str
|
model_id: str
|
||||||
model_type: str | None
|
model_type: str | None
|
||||||
provider: str | None
|
provider: str | None
|
||||||
|
|
||||||
|
|
||||||
class ToolResource(typing.TypedDict):
|
class ToolResource(typing.TypedDict):
|
||||||
"""Tool resource per SDK v1."""
|
"""Tool resource payload."""
|
||||||
tool_name: str
|
tool_name: str
|
||||||
tool_type: str | None
|
tool_type: str | None
|
||||||
description: str | None
|
description: str | None
|
||||||
|
|
||||||
|
|
||||||
class KnowledgeBaseResource(typing.TypedDict):
|
class KnowledgeBaseResource(typing.TypedDict):
|
||||||
"""Knowledge base resource per SDK v1."""
|
"""Knowledge base resource payload."""
|
||||||
kb_id: str
|
kb_id: str
|
||||||
kb_name: str | None
|
kb_name: str | None
|
||||||
kb_type: str | None
|
kb_type: str | None
|
||||||
|
|
||||||
|
|
||||||
class FileResource(typing.TypedDict):
|
class FileResource(typing.TypedDict):
|
||||||
"""File resource per SDK v1."""
|
"""File resource payload."""
|
||||||
file_id: str
|
file_id: str
|
||||||
file_name: str | None
|
file_name: str | None
|
||||||
mime_type: str | None
|
mime_type: str | None
|
||||||
@@ -85,13 +85,13 @@ class FileResource(typing.TypedDict):
|
|||||||
|
|
||||||
|
|
||||||
class StorageResource(typing.TypedDict):
|
class StorageResource(typing.TypedDict):
|
||||||
"""Storage resource per SDK v1."""
|
"""Storage resource payload."""
|
||||||
plugin_storage: bool
|
plugin_storage: bool
|
||||||
workspace_storage: bool
|
workspace_storage: bool
|
||||||
|
|
||||||
|
|
||||||
class AgentResources(typing.TypedDict):
|
class AgentResources(typing.TypedDict):
|
||||||
"""Agent resources per SDK v1."""
|
"""Agent resources payload."""
|
||||||
models: list[ModelResource]
|
models: list[ModelResource]
|
||||||
tools: list[ToolResource]
|
tools: list[ToolResource]
|
||||||
knowledge_bases: list[KnowledgeBaseResource]
|
knowledge_bases: list[KnowledgeBaseResource]
|
||||||
@@ -110,8 +110,8 @@ class AgentRuntimeContext(typing.TypedDict):
|
|||||||
metadata: dict[str, typing.Any]
|
metadata: dict[str, typing.Any]
|
||||||
|
|
||||||
|
|
||||||
class AgentRunContextV1(typing.TypedDict):
|
class AgentRunContextPayload(typing.TypedDict):
|
||||||
"""SDK v1 AgentRunContext per PROTOCOL_V1.md.
|
"""AgentRunContext payload passed to an agent runner.
|
||||||
|
|
||||||
Note: The 'config' field contains the binding config from ai.runner_config[runner_id],
|
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).
|
which is Pipeline's configuration for this specific runner binding (not plugin instance config).
|
||||||
@@ -133,7 +133,7 @@ class AgentRunContextV1(typing.TypedDict):
|
|||||||
|
|
||||||
|
|
||||||
class AgentRunContextBuilder:
|
class AgentRunContextBuilder:
|
||||||
"""Builder for converting Query to SDK v1 AgentRunContext.
|
"""Builder for converting Query to AgentRunContext.
|
||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
- Generate new run_id (UUID, not query id)
|
- Generate new run_id (UUID, not query id)
|
||||||
@@ -168,7 +168,7 @@ class AgentRunContextBuilder:
|
|||||||
query: pipeline_query.Query,
|
query: pipeline_query.Query,
|
||||||
descriptor: AgentRunnerDescriptor,
|
descriptor: AgentRunnerDescriptor,
|
||||||
resources: AgentResources,
|
resources: AgentResources,
|
||||||
) -> AgentRunContextV1:
|
) -> AgentRunContextPayload:
|
||||||
"""Build AgentRunContext from Query.
|
"""Build AgentRunContext from Query.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -177,7 +177,7 @@ class AgentRunContextBuilder:
|
|||||||
resources: Built resources from AgentResourceBuilder
|
resources: Built resources from AgentResourceBuilder
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AgentRunContextV1 dict matching PROTOCOL_V1.md
|
AgentRunContext payload for the plugin runner
|
||||||
"""
|
"""
|
||||||
# Generate new run_id
|
# Generate new run_id
|
||||||
run_id = str(uuid.uuid4())
|
run_id = str(uuid.uuid4())
|
||||||
@@ -242,7 +242,7 @@ class AgentRunContextBuilder:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Build full context
|
# Build full context
|
||||||
context: AgentRunContextV1 = {
|
context: AgentRunContextPayload = {
|
||||||
'run_id': run_id,
|
'run_id': run_id,
|
||||||
'trigger': trigger,
|
'trigger': trigger,
|
||||||
'conversation': conversation,
|
'conversation': conversation,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from langbot_plugin.api.entities.builtin.pipeline import query as pipeline_query
|
|||||||
from ...core import app
|
from ...core import app
|
||||||
from .descriptor import AgentRunnerDescriptor
|
from .descriptor import AgentRunnerDescriptor
|
||||||
from .registry import AgentRunnerRegistry
|
from .registry import AgentRunnerRegistry
|
||||||
from .context_builder import AgentRunContextBuilder, AgentRunContextV1
|
from .context_builder import AgentRunContextBuilder, AgentRunContextPayload
|
||||||
from .resource_builder import AgentResourceBuilder
|
from .resource_builder import AgentResourceBuilder
|
||||||
from .result_normalizer import AgentResultNormalizer
|
from .result_normalizer import AgentResultNormalizer
|
||||||
from .state_store import get_state_store, RunnerScopedStateStore
|
from .state_store import get_state_store, RunnerScopedStateStore
|
||||||
@@ -133,7 +133,7 @@ class AgentRunOrchestrator:
|
|||||||
async def _invoke_runner(
|
async def _invoke_runner(
|
||||||
self,
|
self,
|
||||||
descriptor: AgentRunnerDescriptor,
|
descriptor: AgentRunnerDescriptor,
|
||||||
context: AgentRunContextV1,
|
context: AgentRunContextPayload,
|
||||||
) -> typing.AsyncGenerator[dict[str, typing.Any], None]:
|
) -> typing.AsyncGenerator[dict[str, typing.Any], None]:
|
||||||
"""Invoke runner via plugin connector.
|
"""Invoke runner via plugin connector.
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class AgentResourceBuilder:
|
|||||||
Note: This only builds the resource declaration. The actual proxy actions
|
Note: This only builds the resource declaration. The actual proxy actions
|
||||||
in handler.py must still validate against ctx.resources at runtime.
|
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
|
- ModelResource: model_id, model_type, provider
|
||||||
- ToolResource: tool_name, tool_type, description
|
- ToolResource: tool_name, tool_type, description
|
||||||
- KnowledgeBaseResource: kb_id, kb_name, kb_type
|
- KnowledgeBaseResource: kb_id, kb_name, kb_type
|
||||||
@@ -93,7 +93,7 @@ class AgentResourceBuilder:
|
|||||||
descriptor: AgentRunnerDescriptor,
|
descriptor: AgentRunnerDescriptor,
|
||||||
query: typing.Any,
|
query: typing.Any,
|
||||||
) -> list[ModelResource]:
|
) -> list[ModelResource]:
|
||||||
"""Build models list with SDK v1 field names."""
|
"""Build models list with plugin SDK field names."""
|
||||||
models: list[ModelResource] = []
|
models: list[ModelResource] = []
|
||||||
seen_model_ids: set[str] = set()
|
seen_model_ids: set[str] = set()
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ class AgentResourceBuilder:
|
|||||||
bound_mcp_servers: list[str] | None,
|
bound_mcp_servers: list[str] | None,
|
||||||
query: typing.Any,
|
query: typing.Any,
|
||||||
) -> list[ToolResource]:
|
) -> list[ToolResource]:
|
||||||
"""Build tools list with SDK v1 field names."""
|
"""Build tools list with plugin SDK field names."""
|
||||||
tools: list[ToolResource] = []
|
tools: list[ToolResource] = []
|
||||||
|
|
||||||
# Check manifest permission
|
# Check manifest permission
|
||||||
@@ -223,7 +223,7 @@ class AgentResourceBuilder:
|
|||||||
# Get tools from query (preproc already resolved this for local-agent)
|
# Get tools from query (preproc already resolved this for local-agent)
|
||||||
use_funcs = getattr(query, 'use_funcs', [])
|
use_funcs = getattr(query, 'use_funcs', [])
|
||||||
for tool in 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({
|
tools.append({
|
||||||
'tool_name': tool.name,
|
'tool_name': tool.name,
|
||||||
'tool_type': None, # Tool type not available in current LLMTool
|
'tool_type': None, # Tool type not available in current LLMTool
|
||||||
@@ -238,7 +238,7 @@ class AgentResourceBuilder:
|
|||||||
runner_config: dict[str, typing.Any],
|
runner_config: dict[str, typing.Any],
|
||||||
query: typing.Any,
|
query: typing.Any,
|
||||||
) -> list[KnowledgeBaseResource]:
|
) -> list[KnowledgeBaseResource]:
|
||||||
"""Build knowledge bases list with SDK v1 field names."""
|
"""Build knowledge bases list with plugin SDK field names."""
|
||||||
kb_resources: list[KnowledgeBaseResource] = []
|
kb_resources: list[KnowledgeBaseResource] = []
|
||||||
|
|
||||||
# Check manifest permission
|
# Check manifest permission
|
||||||
@@ -263,7 +263,7 @@ class AgentResourceBuilder:
|
|||||||
try:
|
try:
|
||||||
kb = await self.ap.rag_mgr.get_knowledge_base_by_uuid(kb_uuid)
|
kb = await self.ap.rag_mgr.get_knowledge_base_by_uuid(kb_uuid)
|
||||||
if kb:
|
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_resources.append({
|
||||||
'kb_id': kb_uuid,
|
'kb_id': kb_uuid,
|
||||||
'kb_name': kb.get_name(),
|
'kb_name': kb.get_name(),
|
||||||
@@ -278,7 +278,7 @@ class AgentResourceBuilder:
|
|||||||
self,
|
self,
|
||||||
manifest_perms: dict[str, list[str]],
|
manifest_perms: dict[str, list[str]],
|
||||||
) -> StorageResource:
|
) -> StorageResource:
|
||||||
"""Build storage permissions with SDK v1 field names."""
|
"""Build storage permissions with plugin SDK field names."""
|
||||||
storage_perms = manifest_perms.get('storage', [])
|
storage_perms = manifest_perms.get('storage', [])
|
||||||
return {
|
return {
|
||||||
'plugin_storage': 'plugin' in storage_perms,
|
'plugin_storage': 'plugin' in storage_perms,
|
||||||
|
|||||||
@@ -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
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing
|
import typing
|
||||||
@@ -15,10 +15,10 @@ MAX_RESULT_SIZE_BYTES = 1024 * 1024 # 1 MB
|
|||||||
|
|
||||||
|
|
||||||
class AgentResultNormalizer:
|
class AgentResultNormalizer:
|
||||||
"""Normalizer for converting SDK v1 AgentRunResult to Pipeline messages.
|
"""Normalizer for converting AgentRunResult to Pipeline messages.
|
||||||
|
|
||||||
Responsibilities:
|
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.delta -> MessageChunk
|
||||||
- Map message.completed -> Message
|
- Map message.completed -> Message
|
||||||
- Map run.completed (with message) -> Message
|
- Map run.completed (with message) -> Message
|
||||||
@@ -27,7 +27,7 @@ class AgentResultNormalizer:
|
|||||||
- Validate result size
|
- Validate result size
|
||||||
- Validate message schema
|
- Validate message schema
|
||||||
|
|
||||||
Per PROTOCOL_V1.md, accepted types:
|
Accepted result types:
|
||||||
- message.delta
|
- message.delta
|
||||||
- message.completed
|
- message.completed
|
||||||
- tool.call.started
|
- tool.call.started
|
||||||
@@ -144,10 +144,10 @@ class AgentResultNormalizer:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Unknown type - warn and ignore (SDK v1 only)
|
# Unknown type - warn and ignore.
|
||||||
self.ap.logger.warning(
|
self.ap.logger.warning(
|
||||||
f'Runner {descriptor.id} returned unknown result type: {result_type}. '
|
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
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from langbot_plugin.api.entities.builtin.pipeline import query as pipeline_query
|
|||||||
from .descriptor import AgentRunnerDescriptor
|
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')
|
VALID_STATE_SCOPES = ('conversation', 'actor', 'subject', 'runner')
|
||||||
|
|
||||||
# Key mapping for backward compatibility
|
# Key mapping for backward compatibility
|
||||||
@@ -25,7 +25,7 @@ class RunnerScopedStateStore:
|
|||||||
|
|
||||||
Key Design Principles:
|
Key Design Principles:
|
||||||
1. Host-owned: State is owned and managed by LangBot host, not by the plugin.
|
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
|
2. Scope keys based on stable host identity: Uses host-controlled identifiers
|
||||||
(runner_id, bot_uuid, pipeline_uuid, launcher_type, launcher_id) rather
|
(runner_id, bot_uuid, pipeline_uuid, launcher_type, launcher_id) rather
|
||||||
than external/unstable identifiers like external conversation id.
|
than external/unstable identifiers like external conversation id.
|
||||||
|
|||||||
@@ -820,10 +820,10 @@ class PluginRuntimeConnector(ManagedRuntimeConnector):
|
|||||||
context: AgentRunContext as dict
|
context: AgentRunContext as dict
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
AgentRunResult dicts per Protocol v1
|
AgentRunResult dicts
|
||||||
"""
|
"""
|
||||||
if not self.is_enable_plugin:
|
if not self.is_enable_plugin:
|
||||||
# Return v1 protocol run.failed
|
# Return a protocol-level failure result.
|
||||||
yield {
|
yield {
|
||||||
'type': 'run.failed',
|
'type': 'run.failed',
|
||||||
'data': {
|
'data': {
|
||||||
|
|||||||
@@ -1432,7 +1432,7 @@ class RuntimeConnectionHandler(handler.Handler):
|
|||||||
) -> typing.AsyncGenerator[dict[str, Any], None]:
|
) -> typing.AsyncGenerator[dict[str, Any], None]:
|
||||||
"""Run an AgentRunner component.
|
"""Run an AgentRunner component.
|
||||||
|
|
||||||
Yields AgentRunResult dicts per Protocol v1.
|
Yields AgentRunResult dicts.
|
||||||
"""
|
"""
|
||||||
gen = self.call_action_generator(
|
gen = self.call_action_generator(
|
||||||
LangBotToRuntimeAction.RUN_AGENT,
|
LangBotToRuntimeAction.RUN_AGENT,
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ class TestBuildState:
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_context_has_state_field(self):
|
async def test_context_has_state_field(self):
|
||||||
"""AgentRunContextV1 should have state field."""
|
"""AgentRunContext should have state field."""
|
||||||
reset_state_store()
|
reset_state_store()
|
||||||
ap = FakeApplication()
|
ap = FakeApplication()
|
||||||
builder = AgentRunContextBuilder(ap)
|
builder = AgentRunContextBuilder(ap)
|
||||||
@@ -394,7 +394,7 @@ class TestBuildParamsInContext:
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_context_has_params_field(self):
|
async def test_context_has_params_field(self):
|
||||||
"""AgentRunContextV1 should have params field."""
|
"""AgentRunContext should have params field."""
|
||||||
reset_state_store()
|
reset_state_store()
|
||||||
ap = FakeApplication()
|
ap = FakeApplication()
|
||||||
builder = AgentRunContextBuilder(ap)
|
builder = AgentRunContextBuilder(ap)
|
||||||
|
|||||||
Reference in New Issue
Block a user