mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-04 04:54:36 +00:00
refactor(agent-runner): align config with agent semantics
This commit is contained in:
@@ -36,7 +36,6 @@ class TestMigratePipelineConfig:
|
||||
assert 'plugin:langbot/local-agent/default' in migrated['ai']['runner_config']
|
||||
assert migrated['ai']['runner_config']['plugin:langbot/local-agent/default']['knowledge-bases'] == ['kb-uuid']
|
||||
assert 'knowledge-base' not in migrated['ai']['runner_config']['plugin:langbot/local-agent/default']
|
||||
assert 'max-round' not in migrated['ai']['runner_config']['plugin:langbot/local-agent/default']
|
||||
|
||||
# Expire-time preserved
|
||||
assert migrated['ai']['runner']['expire-time'] == 0
|
||||
@@ -270,7 +269,7 @@ class TestResolveRunnerConfig:
|
||||
"""resolve_runner_config should not read old ai.local-agent at runtime."""
|
||||
config = {
|
||||
'ai': {
|
||||
'local-agent': {'max-round': 15, 'custom-option': 20},
|
||||
'local-agent': {'custom-option': 20},
|
||||
},
|
||||
}
|
||||
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot/local-agent/default')
|
||||
@@ -280,7 +279,7 @@ class TestResolveRunnerConfig:
|
||||
"""resolve_legacy_runner_config should read old ai.local-agent for migration."""
|
||||
config = {
|
||||
'ai': {
|
||||
'local-agent': {'max-round': 15, 'custom-option': 20},
|
||||
'local-agent': {'custom-option': 20},
|
||||
},
|
||||
}
|
||||
runner_config = ConfigMigration.resolve_legacy_runner_config(config, 'plugin:langbot/local-agent/default')
|
||||
@@ -293,7 +292,7 @@ class TestResolveRunnerConfig:
|
||||
'runner_config': {
|
||||
'plugin:langbot/local-agent/default': {'custom-option': 25},
|
||||
},
|
||||
'local-agent': {'max-round': 10, 'custom-option': 10}, # Old, should be ignored
|
||||
'local-agent': {'custom-option': 10}, # Old, should be ignored
|
||||
},
|
||||
}
|
||||
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot/local-agent/default')
|
||||
|
||||
@@ -8,7 +8,7 @@ Tests focus on:
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock, patch
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from langbot.pkg.agent.runner.context_builder import AgentRunContextBuilder
|
||||
from langbot.pkg.agent.runner.host_models import AgentEventEnvelope, AgentBinding, BindingScope, StatePolicy
|
||||
@@ -67,7 +67,7 @@ class TestContextAccessStateDetermination:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(
|
||||
enable_state=True,
|
||||
state_scopes=['conversation', 'actor'],
|
||||
@@ -88,7 +88,7 @@ class TestContextAccessStateDetermination:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(
|
||||
enable_state=False,
|
||||
state_scopes=[],
|
||||
@@ -109,7 +109,7 @@ class TestContextAccessStateDetermination:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(
|
||||
enable_state=True,
|
||||
state_scopes=[], # Empty scopes - state not available
|
||||
@@ -177,7 +177,7 @@ class TestContextAccessStateDetermination:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_003',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(
|
||||
enable_state=True,
|
||||
state_scopes=['conversation', 'actor', 'subject', 'runner'],
|
||||
@@ -226,7 +226,7 @@ class TestBindingWithStatePolicy:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(
|
||||
enable_state=True,
|
||||
state_scopes=['conversation'],
|
||||
@@ -260,7 +260,7 @@ class TestContextAccessOtherAPIs:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(enable_state=False, state_scopes=[]),
|
||||
)
|
||||
|
||||
@@ -288,7 +288,7 @@ class TestContextAccessOtherAPIs:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(enable_state=False, state_scopes=[]),
|
||||
)
|
||||
|
||||
@@ -316,7 +316,7 @@ class TestContextAccessOtherAPIs:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(enable_state=False, state_scopes=[]),
|
||||
)
|
||||
|
||||
@@ -342,7 +342,7 @@ class TestContextAccessOtherAPIs:
|
||||
binding = AgentBinding(
|
||||
binding_id='binding_001',
|
||||
runner_id='plugin:test/runner/default',
|
||||
scope=BindingScope(scope_type='pipeline', scope_id='conv_001'),
|
||||
scope=BindingScope(scope_type='agent', scope_id='conv_001'),
|
||||
state_policy=StatePolicy(enable_state=False, state_scopes=[]),
|
||||
)
|
||||
|
||||
|
||||
@@ -66,11 +66,11 @@ class TestContextValidation:
|
||||
"""Create a test binding."""
|
||||
return AgentBinding(
|
||||
binding_id="binding_1",
|
||||
scope=BindingScope(scope_type="pipeline", scope_id="pipeline_1"),
|
||||
scope=BindingScope(scope_type="agent", scope_id="pipeline_1"),
|
||||
event_types=["message.received"],
|
||||
runner_id="plugin:test/plugin/runner",
|
||||
runner_config={"timeout": 300},
|
||||
pipeline_uuid="pipeline_1",
|
||||
agent_id="pipeline_1",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -144,17 +144,9 @@ class TestPipelineConfigToBinding:
|
||||
mock_query, "plugin:test/plugin/runner"
|
||||
)
|
||||
|
||||
assert binding.scope.scope_type == "pipeline"
|
||||
assert binding.scope.scope_type == "agent"
|
||||
assert binding.scope.scope_id == mock_query.pipeline_uuid
|
||||
|
||||
def test_config_to_binding_does_not_add_host_context_window(self, mock_query):
|
||||
"""Pipeline binding should not define Host-side context window controls."""
|
||||
binding = PipelineAdapter.pipeline_config_to_binding(
|
||||
mock_query, "plugin:test/plugin/runner"
|
||||
)
|
||||
|
||||
assert not hasattr(binding, "max_round")
|
||||
|
||||
assert binding.agent_id == mock_query.pipeline_uuid
|
||||
|
||||
class TestAgentRunContextProtocolV1:
|
||||
"""Test AgentRunContext Protocol v1 behavior."""
|
||||
@@ -238,23 +230,14 @@ class TestAgentRunContextProtocolV1:
|
||||
assert ctx.bootstrap is None or isinstance(ctx.bootstrap.messages, list)
|
||||
|
||||
|
||||
class TestHostContextWindowNotInProtocol:
|
||||
"""Test that Host-side context window controls are not in Protocol v1."""
|
||||
class TestHostManagedHistoryNotInProtocol:
|
||||
"""Test that Host-managed history payloads are not in Protocol v1."""
|
||||
|
||||
def test_context_window_not_in_sdk_context(self):
|
||||
"""AgentRunContext should not expose Host-side window controls."""
|
||||
def test_messages_not_in_sdk_context_top_level(self):
|
||||
"""AgentRunContext should not expose top-level history messages."""
|
||||
ctx_fields = AgentRunContext.model_fields.keys()
|
||||
|
||||
assert "max_round" not in ctx_fields
|
||||
assert "maxRound" not in ctx_fields
|
||||
|
||||
def test_binding_has_no_context_window_field(self, mock_query):
|
||||
"""Pipeline adapter should not attach context window policy to binding."""
|
||||
binding = PipelineAdapter.pipeline_config_to_binding(
|
||||
mock_query, "plugin:test/plugin/runner"
|
||||
)
|
||||
|
||||
assert not hasattr(binding, "max_round")
|
||||
assert "messages" not in ctx_fields
|
||||
|
||||
|
||||
class TestSDKCapabilitiesProtocolV1:
|
||||
|
||||
@@ -56,7 +56,7 @@ def make_binding(runner_id: str = "plugin:test/plugin/runner") -> AgentBinding:
|
||||
"""Create a test binding."""
|
||||
return AgentBinding(
|
||||
binding_id="binding_1",
|
||||
scope=BindingScope(scope_type="pipeline", scope_id="pipeline_1"),
|
||||
scope=BindingScope(scope_type="agent", scope_id="pipeline_1"),
|
||||
event_types=["message.received"],
|
||||
runner_id=runner_id,
|
||||
runner_config={},
|
||||
|
||||
@@ -347,7 +347,7 @@ async def test_orchestrator_does_not_package_query_messages_into_context(clean_a
|
||||
ap = FakeApplication(plugin_connector, db_engine)
|
||||
orchestrator = AgentRunOrchestrator(ap, FakeRegistry(descriptor))
|
||||
query = make_query()
|
||||
query.pipeline_config["ai"]["runner_config"][RUNNER_ID]["agent-window"] = 2
|
||||
query.pipeline_config["ai"]["runner_config"][RUNNER_ID]["custom-option"] = 2
|
||||
query.messages = [
|
||||
provider_message.Message(role="user", content="message 1"),
|
||||
provider_message.Message(role="assistant", content="response 1"),
|
||||
@@ -361,9 +361,9 @@ async def test_orchestrator_does_not_package_query_messages_into_context(clean_a
|
||||
|
||||
assert len(messages) == 1
|
||||
context = plugin_connector.contexts[0]
|
||||
assert context["config"]["agent-window"] == 2
|
||||
assert context["config"]["custom-option"] == 2
|
||||
assert context["bootstrap"] is None
|
||||
assert "adapter_messages" not in context["adapter"]
|
||||
assert set(context["adapter"]) == {"query_id", "extra"}
|
||||
assert "context_packaging" not in context["runtime"]["metadata"]
|
||||
assert [message.content for message in query.messages] == [
|
||||
"message 1",
|
||||
@@ -538,7 +538,7 @@ class TestPipelineCompatibilityQueryIdInSession:
|
||||
)
|
||||
binding = AgentBinding(
|
||||
binding_id="binding_001",
|
||||
scope=BindingScope(scope_type="pipeline", scope_id="pipeline_001"),
|
||||
scope=BindingScope(scope_type="agent", scope_id="pipeline_001"),
|
||||
event_types=["message.received"],
|
||||
runner_id=RUNNER_ID,
|
||||
runner_config={},
|
||||
|
||||
@@ -82,8 +82,8 @@ class FakeBinding:
|
||||
self,
|
||||
binding_id: str = 'binding_001',
|
||||
state_policy: StatePolicy | None = None,
|
||||
scope_type: str = 'pipeline',
|
||||
scope_id: str = 'pipeline_001',
|
||||
scope_type: str = 'agent',
|
||||
scope_id: str = 'agent_001',
|
||||
):
|
||||
self.binding_id = binding_id
|
||||
self.scope = BindingScope(scope_type=scope_type, scope_id=scope_id)
|
||||
|
||||
Reference in New Issue
Block a user