feat(agentscope): add memory system and automation job support
- Add consumer_registry and pipeline_registry for runtime orchestration - Add Visibility schema for message filtering - Add PipelineSpec for agent pipeline configuration - Add automation job models and configuration - Remove memory_prompt.py (consolidated into memory system) - Update runtime components: context_loader, context_service, orchestrator, runner, tasks - Update toolkit: tool_config, tool_middleware, custom tools (calendar, user_lookup) - Add auth_helpers and calendar_domain utilities - Add system_agents.yaml configuration
This commit is contained in:
@@ -1,99 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from core.agentscope import schemas as exported_schemas
|
||||
from core.agentscope.schemas.agent_runtime import (
|
||||
AcceptedTaskResponse,
|
||||
AgUiWireEvent,
|
||||
HistorySnapshot,
|
||||
HistorySnapshotResponse,
|
||||
InternalRuntimeEvent,
|
||||
RunCommand,
|
||||
pytest.skip(
|
||||
"legacy agent_runtime schemas removed; covered by agui_input tests",
|
||||
allow_module_level=True,
|
||||
)
|
||||
|
||||
|
||||
def test_run_command_alias_roundtrip() -> None:
|
||||
payload = {
|
||||
"threadId": "thread-001",
|
||||
"runId": "run-001",
|
||||
"state": {"cursor": 1},
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"tools": [{"name": "calendar.lookup"}],
|
||||
"context": {"locale": "zh-CN"},
|
||||
"forwardedProps": {"traceId": "trace-1"},
|
||||
}
|
||||
|
||||
command = RunCommand.model_validate(payload)
|
||||
|
||||
assert command.thread_id == "thread-001"
|
||||
assert command.run_id == "run-001"
|
||||
assert command.forwarded_props == {"traceId": "trace-1"}
|
||||
|
||||
dumped = command.model_dump(mode="json", by_alias=True)
|
||||
assert dumped["threadId"] == "thread-001"
|
||||
assert dumped["runId"] == "run-001"
|
||||
assert dumped["forwardedProps"] == {"traceId": "trace-1"}
|
||||
|
||||
|
||||
def test_history_snapshot_response_shape() -> None:
|
||||
response = HistorySnapshotResponse(
|
||||
threadId="thread-123",
|
||||
snapshot=HistorySnapshot(
|
||||
threadId="thread-123",
|
||||
day="2026-03-11",
|
||||
hasMore=False,
|
||||
messages=[{"id": "msg-1"}],
|
||||
),
|
||||
)
|
||||
|
||||
dumped = response.model_dump(mode="json", by_alias=True, exclude_none=True)
|
||||
assert dumped["type"] == "STATE_SNAPSHOT"
|
||||
assert dumped["threadId"] == "thread-123"
|
||||
assert dumped["snapshot"]["scope"] == "history_day"
|
||||
assert dumped["snapshot"]["hasMore"] is False
|
||||
assert dumped["snapshot"]["messages"] == [{"id": "msg-1"}]
|
||||
|
||||
|
||||
def test_runtime_event_validation_basics() -> None:
|
||||
internal = InternalRuntimeEvent(type="RUN_STARTED", data={"step": 1})
|
||||
assert internal.type == "RUN_STARTED"
|
||||
assert internal.model_dump(mode="json", by_alias=True)["data"] == {"step": 1}
|
||||
|
||||
wire = AgUiWireEvent(type="TEXT_MESSAGE_CONTENT", payload={"delta": "hello"})
|
||||
dumped = wire.model_dump(mode="json", by_alias=True, exclude_none=True)
|
||||
assert dumped["type"] == "TEXT_MESSAGE_CONTENT"
|
||||
assert dumped["payload"] == {"delta": "hello"}
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
InternalRuntimeEvent.model_validate({"threadId": "t-1", "data": {}})
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
AgUiWireEvent.model_validate({"payload": {"delta": "hello"}})
|
||||
|
||||
|
||||
def test_schemas_exports_include_task_and_history_models() -> None:
|
||||
assert exported_schemas.AcceptedTaskResponse is AcceptedTaskResponse
|
||||
assert exported_schemas.TaskAccepted is AcceptedTaskResponse
|
||||
assert exported_schemas.TaskAcceptedResponse is AcceptedTaskResponse
|
||||
assert exported_schemas.HistorySnapshotResponse is HistorySnapshotResponse
|
||||
|
||||
|
||||
def test_run_command_accepts_agui_context_list_and_parent_run_id() -> None:
|
||||
payload = {
|
||||
"threadId": "thread-xyz",
|
||||
"runId": "run-xyz",
|
||||
"state": {},
|
||||
"messages": [{"id": "u1", "role": "user", "content": "hello"}],
|
||||
"tools": [],
|
||||
"context": [],
|
||||
"forwardedProps": {},
|
||||
"parentRunId": None,
|
||||
}
|
||||
|
||||
command = RunCommand.model_validate(payload)
|
||||
|
||||
dumped = command.model_dump(mode="json", by_alias=True)
|
||||
assert dumped["context"] == []
|
||||
assert "parentRunId" in dumped
|
||||
|
||||
@@ -20,7 +20,7 @@ def _base_payload() -> dict[str, object]:
|
||||
"messages": [{"id": "u1", "role": "user", "content": "hello"}],
|
||||
"tools": [],
|
||||
"context": [],
|
||||
"forwardedProps": {},
|
||||
"forwardedProps": {"agent_type": "worker"},
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ def test_parse_run_input_accepts_snake_case_aliases() -> None:
|
||||
],
|
||||
"tools": [],
|
||||
"context": [],
|
||||
"forwarded_props": {},
|
||||
"forwarded_props": {"agent_type": "worker"},
|
||||
}
|
||||
|
||||
run_input = parse_run_input(payload)
|
||||
@@ -162,11 +162,12 @@ def test_parse_run_input_accepts_snake_case_aliases() -> None:
|
||||
def test_parse_run_input_accepts_client_time_forwarded_props() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"agent_type": "worker",
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
run_input = parse_run_input(payload)
|
||||
@@ -177,11 +178,12 @@ def test_parse_run_input_accepts_client_time_forwarded_props() -> None:
|
||||
def test_parse_run_input_rejects_invalid_client_time_timezone() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"agent_type": "worker",
|
||||
"client_time": {
|
||||
"device_timezone": "Mars/OlympusMons",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
@@ -191,11 +193,12 @@ def test_parse_run_input_rejects_invalid_client_time_timezone() -> None:
|
||||
def test_parse_run_input_rejects_invalid_client_time_now_iso() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"agent_type": "worker",
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16 09:12:33",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
@@ -205,11 +208,12 @@ def test_parse_run_input_rejects_invalid_client_time_now_iso() -> None:
|
||||
def test_parse_run_input_rejects_invalid_client_time_epoch_type() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"agent_type": "worker",
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": "1773658353000",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
@@ -219,6 +223,7 @@ def test_parse_run_input_rejects_invalid_client_time_epoch_type() -> None:
|
||||
def test_parse_run_input_rejects_unknown_forwarded_props_key() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"agent_type": "worker",
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
@@ -229,3 +234,17 @@ def test_parse_run_input_rejects_unknown_forwarded_props_key() -> None:
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
|
||||
def test_parse_run_input_rejects_missing_forwarded_props_agent_type() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
Reference in New Issue
Block a user