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:
qzl
2026-03-19 18:42:35 +08:00
parent 0661016827
commit 0abf51e837
55 changed files with 2172 additions and 1233 deletions
@@ -1,12 +1,13 @@
from __future__ import annotations
from uuid import UUID
from uuid import uuid4
import pytest
from core.agentscope.persistence.user_context_cache import UserContextCache
from core.agentscope.schemas.user_context import (
UserAgentContext,
from schemas.user.context import (
UserContext,
parse_profile_settings,
)
@@ -45,15 +46,15 @@ class _FakeRedis:
self.set_store.pop(key, None)
return len(keys)
async def sadd(self, key: str, *values: str) -> int:
bucket = self.set_store.setdefault(key, set())
async def sadd(self, name: str, *values: str) -> int:
bucket = self.set_store.setdefault(name, set())
before = len(bucket)
for value in values:
bucket.add(value)
return len(bucket) - before
async def smembers(self, key: str) -> set[str]:
return set(self.set_store.get(key, set()))
async def smembers(self, name: str) -> set[str]:
return set(self.set_store.get(name, set()))
class _BrokenRedis:
@@ -77,18 +78,18 @@ class _BrokenRedis:
del keys
raise RuntimeError("redis down")
async def sadd(self, key: str, *values: str) -> int:
del key, values
async def sadd(self, name: str, *values: str) -> int:
del name, values
raise RuntimeError("redis down")
async def smembers(self, key: str) -> set[str]:
del key
async def smembers(self, name: str) -> set[str]:
del name
raise RuntimeError("redis down")
def _build_context() -> UserAgentContext:
return UserAgentContext(
user_id=uuid4(),
def _build_context() -> UserContext:
return UserContext(
id=str(uuid4()),
username="demo-user",
bio="demo bio",
settings=parse_profile_settings({"preferences": {"ai_language": "en-US"}}),
@@ -111,11 +112,11 @@ async def test_user_context_cache_set_and_get_hit() -> None:
loaded = await cache.get(session_id=session_id)
assert loaded is not None
assert loaded.user_id == context.user_id
assert loaded.id == context.id
assert loaded.username == "demo-user"
assert redis.expire_calls == [
(f"agent:user-context:{session_id}", 600),
(f"agent:user-context:sessions:{context.user_id}", 600),
(f"agent:user-context:sessions:{context.id}", 600),
]
assert redis.hincrby_calls == [
(f"agent:user-context:{session_id}", "turns_used", 1)
@@ -138,12 +139,14 @@ async def test_user_context_cache_invalidate_user_deletes_all_sessions() -> None
await cache.set(session_id=s1, context=context)
await cache.set(session_id=s2, context=context)
deleted = await cache.invalidate_user(user_id=context.user_id)
deleted = await cache.invalidate_user(user_id=UUID(context.id))
assert deleted == 2
assert f"agent:user-context:{s1}" in redis.delete_calls
assert f"agent:user-context:{s2}" in redis.delete_calls
assert f"agent:user-context:sessions:{context.user_id}" in redis.delete_calls
assert any(
key.startswith("agent:user-context:sessions:") for key in redis.delete_calls
)
@pytest.mark.asyncio