feat(agent-runner): align protocol adapter terminology

This commit is contained in:
huanghuoguoguo
2026-05-24 09:13:15 +08:00
parent ea6c8fba57
commit 90dffa7cd8
26 changed files with 471 additions and 342 deletions

View File

@@ -16,7 +16,6 @@ from .state_store import get_state_store
from .persistent_state_store import get_persistent_state_store
from . import events as runner_events
from .host_models import AgentEventEnvelope, AgentBinding
from .pipeline_compat_adapter import PipelineCompatAdapter
DEFAULT_RUNNER_TIMEOUT_SECONDS = 300
@@ -139,7 +138,7 @@ class AgentRunContextPayload(typing.TypedDict):
runtime: AgentRuntimeContext
config: dict[str, typing.Any] # Binding config from ai.runner_config[runner_id]
bootstrap: dict[str, typing.Any] | None # Optional bootstrap context
compatibility: dict[str, typing.Any] | None # Legacy compatibility context
adapter: dict[str, typing.Any] | None # Pipeline adapter context
metadata: dict[str, typing.Any] # Additional metadata
@@ -148,7 +147,7 @@ class AgentRunContextBuilder:
Two entry points:
- build_context_from_event(event, binding): Event-first Protocol v1
- build_context(query, descriptor, resources): Legacy Query-based (calls event-based internally)
- build_context(query, descriptor, resources): Pipeline adapter Query-based entry
Responsibilities:
- Generate new run_id (UUID, not query id)
@@ -212,14 +211,14 @@ class AgentRunContextBuilder:
conversation: ConversationContext | None = None
if event.conversation_id:
conversation = {
'session_id': None, # Legacy field
'session_id': None, # Pipeline adapter field
'conversation_id': event.conversation_id,
'thread_id': event.thread_id,
'launcher_type': None, # Will be filled from actor/subject if needed
'launcher_id': None,
'sender_id': event.actor.actor_id if event.actor else None,
'bot_uuid': event.bot_id,
'pipeline_uuid': binding.pipeline_uuid, # Legacy
'pipeline_uuid': binding.pipeline_uuid, # Pipeline adapter field
}
# Build event context (Protocol v1 event-first)
@@ -293,12 +292,12 @@ class AgentRunContextBuilder:
'platform_capabilities': event.delivery.platform_capabilities,
}
# Build compatibility context (empty for event-first)
compatibility_context = {
# Build adapter context (empty for event-first)
adapter_context = {
'query_id': None,
'pipeline_uuid': binding.pipeline_uuid,
'max_round': binding.max_round, # For reference only
'legacy_messages': [],
'adapter_messages': [],
'extra': {},
}
@@ -318,7 +317,7 @@ class AgentRunContextBuilder:
'runtime': runtime,
'config': binding.runner_config,
'bootstrap': None, # Optional - no messages inlined by default
'compatibility': compatibility_context,
'adapter': adapter_context,
'metadata': {}, # Additional metadata
}
@@ -332,12 +331,11 @@ class AgentRunContextBuilder:
) -> AgentRunContextPayload:
"""Build AgentRunContext envelope from Query.
This is a compatibility wrapper that converts Query to event + binding
This is a Pipeline adapter wrapper that converts Query to event + binding
and delegates to build_context_from_event().
For Protocol v1, messages are NOT inlined by default.
Legacy max-round only affects bootstrap (via compatibility adapter),
NOT Protocol v1 entities.
Pipeline max-round only affects bootstrap, NOT Protocol v1 entities.
Args:
query: Pipeline query
@@ -354,7 +352,7 @@ class AgentRunContextBuilder:
runner_id,
)
# Extract max_round for compatibility (NOT Protocol v1)
# Extract max_round for Pipeline adapter bootstrap (NOT Protocol v1)
# Note: config uses 'max-round' with hyphen, not 'max_round'
max_round = runner_config.get('max-round')
if max_round is None:
@@ -413,7 +411,7 @@ class AgentRunContextBuilder:
# Build delivery context from query adapter capabilities
delivery_context = {
'surface': 'pipeline', # Legacy pipeline surface
'surface': 'pipeline',
'reply_target': None,
'supports_streaming': streaming_supported,
'supports_edit': False,
@@ -422,8 +420,8 @@ class AgentRunContextBuilder:
'platform_capabilities': {},
}
# Build context access (for legacy, minimal API availability)
# Legacy Query-based mode does NOT have persistent state API
# Build context access for the direct Query adapter helper.
# The event-first run_from_query path uses build_context_from_event().
context_access = {
'conversation_id': conversation.get('conversation_id') if conversation else None,
'thread_id': None,
@@ -436,7 +434,7 @@ class AgentRunContextBuilder:
'delivered_count': 0,
'source_total_count': None,
'messages_complete': False,
'reason': 'legacy_pipeline',
'reason': 'pipeline_adapter',
},
'available_apis': {
'history_page': False,
@@ -445,40 +443,40 @@ class AgentRunContextBuilder:
'event_page': False,
'artifact_metadata': False,
'artifact_read': False,
'state': False, # Legacy Query mode does not have persistent state API
'state': False,
'storage': True,
},
}
# Build compatibility context (for legacy Query/Pipeline fields)
compatibility_context = {
# Build adapter context (for Pipeline adapter fields)
adapter_context = {
'query_id': query.query_id,
'pipeline_uuid': getattr(query, 'pipeline_uuid', None),
'max_round': max_round, # For reference only
'legacy_messages': [], # Will be filled if max_round is set
'adapter_messages': [], # Will be filled if max_round is set
'extra': {
'params': params, # Put params in compatibility.extra
'prompt': self._build_prompt(query), # Put prompt in compatibility.extra
'params': params, # Put params in adapter.extra
'prompt': self._build_prompt(query), # Put prompt in adapter.extra
},
}
# Build bootstrap context (optional, for legacy max-round)
# Build bootstrap context (optional, for Pipeline adapter max-round)
bootstrap_context = None
# For legacy compatibility: add bootstrap messages if max_round is set
# For Pipeline adapter: add bootstrap messages if max_round is set
# This goes into bootstrap.messages, NOT top-level messages
if max_round and max_round > 0:
packaged_context = self.context_packager.package_messages(query, runner_config)
legacy_messages = self._build_messages(packaged_context.messages)
adapter_messages = self._build_messages(packaged_context.messages)
# Put in bootstrap for Protocol v1
bootstrap_context = {
'messages': legacy_messages,
'messages': adapter_messages,
'summary': None,
'artifacts': [],
'metadata': {},
}
# Also update compatibility for legacy runners
compatibility_context['legacy_messages'] = legacy_messages
# Also update adapter for transition runners
adapter_context['adapter_messages'] = adapter_messages
# Update runtime metadata
runtime['metadata']['context_packaging'] = {
'policy': packaged_context.policy,
@@ -501,7 +499,7 @@ class AgentRunContextBuilder:
'runtime': runtime,
'config': runner_config,
'bootstrap': bootstrap_context, # Optional bootstrap
'compatibility': compatibility_context, # Legacy compatibility
'adapter': adapter_context, # Pipeline adapter context
'metadata': {}, # Additional metadata
}
@@ -902,7 +900,7 @@ class AgentRunContextBuilder:
artifact_read_enabled = 'read' in artifact_permissions
# Determine state API availability based on binding state_policy (event-first mode)
# For legacy Query-based mode, state is NOT available (no persistent state API)
# Direct Query context builder does not expose persistent state API.
state_enabled = False
if binding is not None:
state_policy = binding.state_policy

View File

@@ -7,7 +7,7 @@ import typing
from langbot_plugin.api.entities.builtin.pipeline import query as pipeline_query
DEFAULT_LEGACY_MAX_ROUND = 10
DEFAULT_MAX_ROUND = 10
@dataclasses.dataclass(frozen=True)
@@ -19,21 +19,16 @@ class ContextPackagingResult:
history: dict[str, typing.Any]
def get_legacy_max_round(runner_config: dict[str, typing.Any]) -> typing.Any:
"""Return the configured legacy max-round value.
Keep the existing config semantics intact: callers are expected to pass the
already-resolved runner binding config, and invalid values fail the same way
the old truncator failed when comparing them with an integer round count.
"""
return runner_config.get('max-round', DEFAULT_LEGACY_MAX_ROUND)
def get_max_round(runner_config: dict[str, typing.Any]) -> typing.Any:
"""Return the configured Pipeline adapter max-round value."""
return runner_config.get('max-round', DEFAULT_MAX_ROUND)
def select_legacy_max_round_messages(
def select_max_round_messages(
messages: list[typing.Any] | None,
max_round: typing.Any,
) -> list[typing.Any]:
"""Select the same message window as the legacy round truncator."""
"""Select a bounded recent message window by user-round count."""
if not messages:
return []
@@ -59,15 +54,15 @@ class AgentContextPackager:
query: pipeline_query.Query,
runner_config: dict[str, typing.Any],
) -> ContextPackagingResult:
"""Package query messages using the current legacy max-round policy."""
"""Package query messages using the Pipeline adapter max-round policy."""
source_messages = query.messages or []
max_round = get_legacy_max_round(runner_config)
packaged_messages = select_legacy_max_round_messages(source_messages, max_round)
max_round = get_max_round(runner_config)
packaged_messages = select_max_round_messages(source_messages, max_round)
return ContextPackagingResult(
messages=packaged_messages,
policy={
'mode': 'legacy_max_round',
'mode': 'max_round',
'max_round': max_round,
},
history={

View File

@@ -163,9 +163,9 @@ class AgentBinding(pydantic.BaseModel):
enabled: bool = True
"""Whether binding is enabled."""
# Legacy fields for compatibility adapter
# Fields for Pipeline adapter
pipeline_uuid: str | None = None
"""Legacy pipeline UUID (for compatibility)."""
"""Pipeline UUID (for Pipeline adapter)."""
max_round: int | None = None
"""Legacy max-round (for compatibility adapter, not Protocol v1)."""
"""max-round (for Pipeline adapter bootstrap, not Protocol v1)."""

View File

@@ -49,8 +49,7 @@ def parse_runner_id(runner_id: str) -> RunnerIdParts:
runner_name=runner_name,
)
else:
# For backward compatibility with old built-in runner names
# This should eventually be removed after migration
# Only plugin runner IDs are valid at the protocol boundary.
raise ValueError(
f'Invalid runner ID format: {runner_id}. '
f'Expected: plugin:author/plugin_name/runner_name'
@@ -89,4 +88,4 @@ def is_plugin_runner_id(runner_id: str) -> bool:
Returns:
True if runner ID starts with 'plugin:'
"""
return runner_id.startswith('plugin:')
return runner_id.startswith('plugin:')

View File

@@ -21,7 +21,7 @@ from .persistent_state_store import get_persistent_state_store, PersistentStateS
from .session_registry import get_session_registry, AgentRunSessionRegistry
from .config_migration import ConfigMigration
from .host_models import AgentEventEnvelope, AgentBinding
from .pipeline_compat_adapter import PipelineCompatAdapter
from .pipeline_adapter import PipelineAdapter
from .errors import (
RunnerNotFoundError,
RunnerExecutionError,
@@ -48,7 +48,7 @@ class AgentRunOrchestrator:
Entry points:
- run(event, binding): Main entry for event-first Protocol v1
- run_from_query(query): Compatibility wrapper for Pipeline
- run_from_query(query): Pipeline adapter wrapper
"""
ap: app.Application
@@ -86,7 +86,7 @@ class AgentRunOrchestrator:
event: AgentEventEnvelope,
binding: AgentBinding,
bound_plugins: list[str] | None = None,
compatibility_context: dict[str, typing.Any] | None = None,
adapter_context: dict[str, typing.Any] | None = None,
) -> typing.AsyncGenerator[provider_message.Message | provider_message.MessageChunk, None]:
"""Run agent runner from event-first envelope.
@@ -97,7 +97,7 @@ class AgentRunOrchestrator:
event: Event envelope from event gateway
binding: Agent binding configuration
bound_plugins: Optional list of bound plugin identities for authorization
compatibility_context: Optional compatibility context from Pipeline adapter
adapter_context: Optional adapter context from Pipeline adapter
Yields:
Message or MessageChunk for pipeline response
@@ -127,27 +127,27 @@ class AgentRunOrchestrator:
resources=resources,
)
# Merge compatibility context if provided (for Pipeline compatibility)
if compatibility_context:
# Merge params into compatibility.extra
if 'params' in compatibility_context:
context['compatibility']['extra']['params'] = compatibility_context['params']
# Merge prompt into compatibility.extra (for legacy runners)
if 'prompt' in compatibility_context:
context['compatibility']['extra']['prompt'] = compatibility_context['prompt']
# Merge adapter context if provided (for Pipeline adapter)
if adapter_context:
# Merge params into adapter.extra
if 'params' in adapter_context:
context['adapter']['extra']['params'] = adapter_context['params']
# Merge prompt into adapter.extra (for transition runners)
if 'prompt' in adapter_context:
context['adapter']['extra']['prompt'] = adapter_context['prompt']
# Merge bootstrap if provided
if compatibility_context.get('bootstrap'):
context['bootstrap'] = compatibility_context['bootstrap']
# Also set legacy_messages for legacy runners
bootstrap_messages = compatibility_context['bootstrap'].get('messages')
if adapter_context.get('bootstrap'):
context['bootstrap'] = adapter_context['bootstrap']
# Also set adapter_messages for transition runners
bootstrap_messages = adapter_context['bootstrap'].get('messages')
if bootstrap_messages:
context['compatibility']['legacy_messages'] = bootstrap_messages
context['adapter']['adapter_messages'] = bootstrap_messages
# Merge runtime metadata if provided
if compatibility_context.get('runtime_metadata'):
context['runtime']['metadata'].update(compatibility_context['runtime_metadata'])
if adapter_context.get('runtime_metadata'):
context['runtime']['metadata'].update(adapter_context['runtime_metadata'])
# Set query_id if provided
if compatibility_context.get('query_id'):
context['runtime']['query_id'] = compatibility_context['query_id']
if adapter_context.get('query_id'):
context['runtime']['query_id'] = adapter_context['query_id']
# Build state context for State API handlers
state_context = self._build_state_context(event, binding, descriptor)
@@ -243,7 +243,7 @@ class AgentRunOrchestrator:
) -> typing.AsyncGenerator[provider_message.Message | provider_message.MessageChunk, None]:
"""Run agent runner from pipeline query.
This is a compatibility wrapper for the legacy Query-based flow.
This is the Pipeline adapter wrapper for the Query-based flow.
It delegates to the event-first run(event, binding) method.
For the new event-first Protocol v1, use run(event, binding) instead.
@@ -265,34 +265,34 @@ class AgentRunOrchestrator:
raise RunnerNotFoundError('no runner configured')
# Convert Query to event-first envelope
event = PipelineCompatAdapter.query_to_event(query)
event = PipelineAdapter.query_to_event(query)
# Convert Pipeline config to binding
binding = PipelineCompatAdapter.pipeline_config_to_binding(query, runner_id)
binding = PipelineAdapter.pipeline_config_to_binding(query, runner_id)
# Extract bound plugins for authorization
bound_plugins = query.variables.get('_pipeline_bound_plugins')
# Build compatibility context for Pipeline-specific fields
compatibility_context = await self._build_compatibility_context(query, binding)
# Build adapter context for Pipeline-specific fields
adapter_context = await self._build_adapter_context(query, binding)
# Delegate to event-first run()
async for result in self.run(
event,
binding,
bound_plugins=bound_plugins,
compatibility_context=compatibility_context,
adapter_context=adapter_context,
):
yield result
async def _build_compatibility_context(
async def _build_adapter_context(
self,
query: pipeline_query.Query,
binding: AgentBinding,
) -> dict[str, typing.Any]:
"""Build compatibility context for Pipeline Query-based flow.
"""Build adapter context for Pipeline Query-based flow.
This extracts legacy fields from Query that aren't available in
This extracts adapter-specific fields from Query that aren't available in
the event-first flow:
- params (from query.variables)
- bootstrap messages (for max-round)
@@ -304,7 +304,7 @@ class AgentRunOrchestrator:
binding: Agent binding with max_round
Returns:
Compatibility context dict
Adapter context dict
"""
from .context_packager import AgentContextPackager
@@ -312,10 +312,10 @@ class AgentRunOrchestrator:
# (excludes internal vars, sensitive patterns, permission vars, non-JSON values)
params = self.context_builder._build_params(query)
# Build prompt from query.prompt.messages (for legacy compatibility)
# Build prompt from query.prompt.messages (for transition runners)
prompt = self.context_builder._build_prompt(query)
# Build bootstrap context for legacy max-round
# Build bootstrap context for max-round
bootstrap = None
runtime_metadata = {}
max_round = binding.max_round
@@ -327,12 +327,12 @@ class AgentRunOrchestrator:
packaged_context = context_packager.package_messages(query, runner_config)
# Build messages list
legacy_messages = []
adapter_messages = []
for msg in packaged_context.messages:
legacy_messages.append(msg.model_dump(mode='json'))
adapter_messages.append(msg.model_dump(mode='json'))
bootstrap = {
'messages': legacy_messages,
'messages': adapter_messages,
'summary': None,
'artifacts': [],
'metadata': {},
@@ -497,7 +497,7 @@ class AgentRunOrchestrator:
"""
data = result_dict.get('data', {})
# Extract scope (default to 'conversation' for backward compat)
# Extract scope (default to conversation when omitted by the runner)
scope = data.get('scope', 'conversation')
# Extract key and value

View File

@@ -1,7 +1,6 @@
"""Persistent state store for AgentRunner protocol state.
This module provides a database-backed state store for event-first Protocol v1,
while preserving in-memory state store for legacy Query-based flow.
This module provides a database-backed state store for event-first Protocol v1.
"""
from __future__ import annotations
@@ -25,8 +24,8 @@ from ...entity.persistence.agent_runner_state import AgentRunnerState
# Valid state scopes for agent runner state updates.
VALID_STATE_SCOPES = ('conversation', 'actor', 'subject', 'runner')
# Key mapping for backward compatibility
LEGACY_KEY_MAPPING = {
# External-facing key aliases accepted from runners.
STATE_KEY_ALIASES = {
'conversation_id': 'external.conversation_id',
}
@@ -276,9 +275,9 @@ class PersistentStateStore:
if not self._check_scope_enabled(scope, binding):
return False, f'Scope "{scope}" not enabled by binding policy'
# Map legacy key names
if key in LEGACY_KEY_MAPPING:
key = LEGACY_KEY_MAPPING[key]
# Map accepted key aliases
if key in STATE_KEY_ALIASES:
key = STATE_KEY_ALIASES[key]
# Get scope key
scope_key = self._get_scope_key(scope, event, binding, descriptor)

View File

@@ -1,7 +1,7 @@
"""Pipeline compatibility adapter for converting Query to event-first envelope.
"""Pipeline adapter for converting Query to event-first envelope.
This adapter bridges the legacy Query/Pipeline approach with the new
event-first Protocol v1 architecture. It is a compatibility layer only.
This adapter bridges the Query/Pipeline entry point with the event-first
Protocol v1 architecture.
"""
from __future__ import annotations
@@ -32,14 +32,14 @@ from .host_models import (
from . import events as runner_events
class PipelineCompatAdapter:
class PipelineAdapter:
"""Adapter for converting Pipeline Query to event-first envelope.
This adapter is responsible for:
- Converting Query to AgentEventEnvelope
- Converting Pipeline config to temporary AgentBinding
- Handling legacy max-round as bootstrap policy
- Putting Query-only fields into compatibility context
- Handling max-round as bootstrap policy
- Putting Query-only fields into adapter context
"""
@classmethod
@@ -80,7 +80,7 @@ class PipelineCompatAdapter:
event_id=event.event_id or str(query.query_id),
event_type=event.event_type or runner_events.MESSAGE_RECEIVED,
event_time=event.event_time,
source="pipeline_compat",
source="pipeline_adapter",
bot_id=query.bot_uuid,
workspace_id=None, # Not available in Query
conversation_id=conversation.conversation_id,
@@ -111,7 +111,7 @@ class PipelineCompatAdapter:
ai_config = pipeline_config.get('ai', {})
runner_config = ai_config.get('runner_config', {}).get(runner_id, {})
# Extract max_round for compatibility (used in bootstrap, not Protocol v1)
# Extract max_round for adapter (used in bootstrap, not Protocol v1)
# Note: config uses 'max-round' with hyphen, not 'max_round' with underscore
max_round = runner_config.get('max-round') or ai_config.get('max-round')
@@ -135,7 +135,6 @@ class PipelineCompatAdapter:
)
# Build delivery policy
output_config = pipeline_config.get('output', {})
delivery_policy = DeliveryPolicy(
enable_streaming=True,
enable_reply=True,
@@ -161,10 +160,10 @@ class PipelineCompatAdapter:
query: pipeline_query.Query,
binding: AgentBinding,
) -> dict[str, typing.Any]:
"""Build bootstrap context from binding for legacy max-round.
"""Build bootstrap context from binding for max-round.
This method handles the legacy max-round -> bootstrap conversion.
max-round is NOT part of Protocol v1, only used by compatibility adapter.
This method handles the max-round -> bootstrap conversion.
max-round is NOT part of Protocol v1, only used by Pipeline adapter.
Args:
query: Pipeline query
@@ -183,42 +182,42 @@ class PipelineCompatAdapter:
"artifacts": [],
"metadata": {
"policy": "self_managed",
"legacy_max_round": None,
"max_round": None,
},
}
# Legacy max-round packaging (will be handled by context_packager)
# max-round packaging (will be handled by context_packager)
return {
"messages": [], # Will be filled by context_packager
"summary": None,
"artifacts": [],
"metadata": {
"policy": "legacy_max_round",
"legacy_max_round": max_round,
"policy": "max_round",
"max_round": max_round,
},
}
@classmethod
def build_compatibility_context(
def build_adapter_context(
cls,
query: pipeline_query.Query,
) -> dict[str, typing.Any]:
"""Build compatibility context for legacy Query/Pipeline fields.
"""Build adapter context for Pipeline adapter fields.
These fields are for migration purposes only.
These fields are for transition purposes only.
Runners should NOT depend on them for long-term capabilities.
Args:
query: Pipeline query
Returns:
Compatibility context data
Adapter context data
"""
return {
"query_id": query.query_id,
"pipeline_uuid": query.pipeline_uuid,
"max_round": None, # Moved to binding, not here
"legacy_messages": [], # Will be filled by context_packager
"adapter_messages": [], # Will be filled by context_packager
"extra": {
"bot_uuid": query.bot_uuid,
"sender_id": str(query.sender_id) if query.sender_id else None,
@@ -266,7 +265,7 @@ class PipelineCompatAdapter:
event_id=str(message_id or query.query_id),
event_type=runner_events.MESSAGE_RECEIVED,
event_time=event_time,
source="pipeline_compat",
source="pipeline_adapter",
source_event_type=source_event_type,
data=event_data,
)

View File

@@ -32,7 +32,7 @@ class AgentResourceBuilder:
Entry points:
- build_resources_from_binding(event, binding, descriptor): Event-first Protocol v1
- build_resources(query, descriptor): Legacy Query-based
- build_resources(query, descriptor): Pipeline adapter Query-based
Note: This only builds the resource declaration. The actual proxy actions
in handler.py must still validate against ctx.resources at runtime.
@@ -216,7 +216,7 @@ class AgentResourceBuilder:
) -> AgentResources:
"""Build AgentResources from query and runner descriptor.
This is a compatibility wrapper for Query-based flow.
This is a Pipeline adapter wrapper for Query-based flow.
Args:
query: Pipeline query with pipeline_config and variables

View File

@@ -13,8 +13,8 @@ from .host_models import AgentEventEnvelope
# Valid state scopes for agent runner state updates.
VALID_STATE_SCOPES = ('conversation', 'actor', 'subject', 'runner')
# Key mapping for backward compatibility
LEGACY_KEY_MAPPING = {
# External-facing key aliases accepted from runners.
STATE_KEY_ALIASES = {
'conversation_id': 'external.conversation_id',
}
@@ -226,12 +226,12 @@ class RunnerScopedStateStore:
)
return False
# Map legacy key names
if key in LEGACY_KEY_MAPPING:
mapped_key = LEGACY_KEY_MAPPING[key]
# Map accepted key aliases
if key in STATE_KEY_ALIASES:
mapped_key = STATE_KEY_ALIASES[key]
if logger:
logger.debug(
f'Runner {descriptor.id} state.updated legacy key "{key}" mapped to "{mapped_key}"'
f'Runner {descriptor.id} state.updated key alias "{key}" mapped to "{mapped_key}"'
)
key = mapped_key
@@ -245,8 +245,7 @@ class RunnerScopedStateStore:
# Sync external.conversation_id to query.session.using_conversation.uuid
if scope == 'conversation' and key == 'external.conversation_id':
if query.session and query.session.using_conversation:
# Update conversation uuid for backward compatibility
# This ensures old conversation continuation behavior works
# Keep the active conversation UUID aligned with runner-owned state.
setattr(query.session.using_conversation, 'uuid', value)
if logger:
logger.debug(
@@ -564,12 +563,12 @@ class RunnerScopedStateStore:
)
return False
# Map legacy key names
if key in LEGACY_KEY_MAPPING:
mapped_key = LEGACY_KEY_MAPPING[key]
# Map accepted key aliases
if key in STATE_KEY_ALIASES:
mapped_key = STATE_KEY_ALIASES[key]
if logger:
logger.debug(
f'Runner {descriptor.id} state.updated legacy key "{key}" mapped to "{mapped_key}"'
f'Runner {descriptor.id} state.updated key alias "{key}" mapped to "{mapped_key}"'
)
key = mapped_key

View File

@@ -30,7 +30,7 @@ class EventLog(Base):
"""When the event occurred."""
source = sqlalchemy.Column(sqlalchemy.String(50), nullable=False)
"""Event source (platform, webui, api, scheduler, system, pipeline_compat)."""
"""Event source (platform, webui, api, scheduler, system, pipeline_adapter)."""
bot_id = sqlalchemy.Column(sqlalchemy.String(255), nullable=True, index=True)
"""Bot UUID that handled this event."""

View File

@@ -4,8 +4,8 @@ from .. import truncator
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
from ....agent.runner.config_migration import ConfigMigration
from ....agent.runner.context_packager import (
get_legacy_max_round,
select_legacy_max_round_messages,
get_max_round,
select_max_round_messages,
)
@@ -21,9 +21,9 @@ class RoundTruncator(truncator.Truncator):
else:
runner_config = query.pipeline_config.get('msg-truncate', {}).get('round', {})
query.messages = select_legacy_max_round_messages(
query.messages = select_max_round_messages(
query.messages,
get_legacy_max_round(runner_config),
get_max_round(runner_config),
)
return query