mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-08-28 05:25:04 +00:00
* refactor(embedding): replace embedding model with embedding store architecture - Remove as_token_counter component and its estimated token counter implementation - Replace BaseEmbeddingModel with BaseEmbedding that wraps AgentScope embedding models - Add support for multiple embedding providers (OpenAI, DashScope, Gemini, Ollama) - Introduce BaseEmbeddingStore and LocalEmbeddingStore for caching and persistence - Update component registry to use new embedding and embedding_store types - Modify file stores to use embedding_store instead of embedding_model - Update health check to monitor embedding_store instead of embedding_model - Change default config to use embedding_store with local backend - Add estimate_token_count utility function to utils module * refactor(llm): replace as_llm components with unified llm implementation - Remove deprecated as_llm and as_llm_formatter modules - Add new llm module with BaseLLM and provider-specific implementations - Update component registry to use LLM instead of AS_LLM - Replace all as_llm/as_llm_formatter references with llm in steps - Update configuration schema to use llm instead of as_llm - Rename integration test file from test_as_llm to test_llm - Add proper docstrings to embedding store dimension property - Add pylint disable comment for embedding model call - Remove unused FormatterBase import in base_step - Update token_utils with function docstring * refactor(evolve): replace ReActAgent with Agent and update message handling - Removed FlexReActAgent class and direct ReActAgent imports - Updated Agent instantiation to use new constructor parameters - Changed message content to use TextBlock format instead of plain strings - Modified timestamp access from msg.timestamp to msg.created_at - Updated metadata access pattern for structured outputs - Replaced Msg.from_dict with Msg.model_validate in auto_memory.py - Updated test mocks to patch Agent instead of ReActAgent - Changed message serialization from to_dict to model_dump in tests - Moved component references to base class definition - Updated demo tools to return strings instead of ToolResponse objects * feat(step): migrate to FunctionTool and add streaming support - Replace deprecated ToolResponse with FunctionTool in base_step.py - Remove unused TextBlock import from base_step.py - Update job registration to use new FunctionTool API - Add thinking_budget parameter to llm_demo configuration - Introduce StreamLLMDemoStep with streaming output capability - Add structured output support to LLMDemoStep via generate_structured_output - Implement streaming event handling for text/thinking/tool calls - Add integration tests for embedding functionality - Add integration tests for structured output and streaming features - Update tool usage in demo steps to use new function naming convention * fix(ci): correct package installation path in unittest workflow - Updated pip install command to use proper package path "./reme4[dev,core]" - Fixed dependency installation step in CI workflow configuration * chore(workflow): update python versions in unittest workflow - Remove Python 3.10 from test matrix - Add Python 3.11 to test matrix - Add Python 3.12 to test matrix - Keep Python 3.13 in test matrix - Update matrix configuration for better version coverage * fix(health): handle missing dimensions attribute in embedding status - Wrap dimensions access in try-except to prevent AttributeError - Return None when dimensions attribute is not available - Maintain backward compatibility for components without dimensions test(component): add comprehensive tests for BaseComponent and related classes - Add tests for Dependency class including repr and attribute access - Add tests for bind method with various scenarios and edge cases - Add tests for lifecycle management and async context handling - Add tests for standalone and context-bound dependency resolution - Add tests for ComponentMixin path utilities test(common): update LocalFileStore initialization parameter - Change embedding_model parameter to embedding_store in test setup - Update all affected test files consistently test(registry): add complete test suite for ComponentRegistry - Add tests for register method with explicit names and defaults - Add tests for decorator registration pattern - Add tests for get_all method returning copies - Add tests for unregister and clear operations - Add tests for error handling of invalid registrations test(job): add comprehensive tests for BaseJob and BackgroundJob - Add tests for step resolution and exception handling - Add tests for backoff delay calculation with jitter - Add tests for supervisor loop restart behavior - Add tests for task shutdown and cancellation test(prompt): add complete test suite for PromptHandler - Add tests for prompt loading from dictionaries and files - Add tests for internationalization and language fallback - Add tests for flag filtering and variable substitution - Add tests for format validation and error handling test(runtime): add basic tests for RuntimeContext dictionary access - Add tests for item getting, setting and containment checks - Add tests for missing key error handling * feat(evolve): add permission context and agent state management - Import PermissionContext, PermissionMode and AgentState modules - Add state configuration with bypass permission mode to AutoDream agents - Add state configuration with bypass permission mode to AutoMemory agents - Implement static _to_msg method for message validation and formatting - Refactor message processing to use the new _to_msg method - Ensure proper content structure for text blocks in message conversion * style(tests): update test files with linting rules and code improvements - Add missing pylint disable directives for docstring and attribute warnings - Replace lambda expressions with proper function definitions in test cases - Import Path directly instead of using lambda with __import__ - Simplify assertion checks by using truthiness instead of equality to empty dict - Remove unused imports and reorder imports consistently - Format dictionary literals with proper indentation and line breaks
181 lines
4.4 KiB
Python
181 lines
4.4 KiB
Python
"""Tests for RuntimeContext."""
|
|
|
|
# pylint: disable=protected-access,missing-function-docstring
|
|
|
|
import asyncio
|
|
|
|
import pytest
|
|
|
|
from reme4.components.runtime_context import RuntimeContext
|
|
from reme4.enumeration import ChunkEnum
|
|
|
|
|
|
# -- dict-like access ---------------------------------------------------------
|
|
|
|
|
|
def test_getitem_setitem():
|
|
ctx = RuntimeContext(foo="bar")
|
|
assert ctx["foo"] == "bar"
|
|
ctx["baz"] = 42
|
|
assert ctx["baz"] == 42
|
|
|
|
|
|
def test_getitem_missing_raises():
|
|
ctx = RuntimeContext()
|
|
with pytest.raises(KeyError):
|
|
_ = ctx["nope"]
|
|
|
|
|
|
def test_contains():
|
|
ctx = RuntimeContext(a=1)
|
|
assert "a" in ctx
|
|
assert "b" not in ctx
|
|
|
|
|
|
def test_delitem():
|
|
ctx = RuntimeContext(a=1)
|
|
del ctx["a"]
|
|
assert "a" not in ctx
|
|
|
|
|
|
def test_get_with_default():
|
|
ctx = RuntimeContext(a=1)
|
|
assert ctx.get("a") == 1
|
|
assert ctx.get("b", "fallback") == "fallback"
|
|
assert ctx.get("b") is None
|
|
|
|
|
|
def test_update_merges_and_returns_self():
|
|
ctx = RuntimeContext(a=1)
|
|
result = ctx.update({"b": 2, "c": 3})
|
|
assert result is ctx
|
|
assert ctx["b"] == 2
|
|
assert ctx["c"] == 3
|
|
|
|
|
|
# -- from_context -------------------------------------------------------------
|
|
|
|
|
|
def test_from_context_creates_new_when_none():
|
|
ctx = RuntimeContext.from_context(None, x=10)
|
|
assert ctx["x"] == 10
|
|
|
|
|
|
def test_from_context_reuses_existing():
|
|
original = RuntimeContext(a=1)
|
|
reused = RuntimeContext.from_context(original, b=2)
|
|
assert reused is original
|
|
assert reused["a"] == 1
|
|
assert reused["b"] == 2
|
|
|
|
|
|
# -- apply_mapping ------------------------------------------------------------
|
|
|
|
|
|
def test_apply_mapping_copies_values():
|
|
ctx = RuntimeContext(src="hello")
|
|
result = ctx.apply_mapping({"src": "dst"})
|
|
assert result is ctx
|
|
assert ctx["dst"] == "hello"
|
|
assert ctx["src"] == "hello"
|
|
|
|
|
|
def test_apply_mapping_skips_missing_source():
|
|
ctx = RuntimeContext(a=1)
|
|
ctx.apply_mapping({"missing_key": "target"})
|
|
assert "target" not in ctx
|
|
|
|
|
|
def test_apply_mapping_empty_is_noop():
|
|
ctx = RuntimeContext(a=1)
|
|
result = ctx.apply_mapping({})
|
|
assert result is ctx
|
|
|
|
|
|
# -- streaming ----------------------------------------------------------------
|
|
|
|
|
|
def test_stream_property():
|
|
ctx_no_queue = RuntimeContext()
|
|
assert ctx_no_queue.stream is False
|
|
|
|
ctx_with_queue = RuntimeContext(stream_queue=asyncio.Queue())
|
|
assert ctx_with_queue.stream is True
|
|
|
|
|
|
def test_enqueue_raises_without_queue():
|
|
async def run():
|
|
ctx = RuntimeContext()
|
|
with pytest.raises(RuntimeError, match="Stream queue not initialized"):
|
|
await ctx._enqueue(None)
|
|
|
|
asyncio.run(run())
|
|
|
|
|
|
def test_add_stream_string():
|
|
async def run():
|
|
q = asyncio.Queue()
|
|
ctx = RuntimeContext(stream_queue=q)
|
|
result = await ctx.add_stream_string("hello", ChunkEnum.CONTENT)
|
|
assert result is ctx
|
|
|
|
chunk = q.get_nowait()
|
|
assert chunk.chunk == "hello"
|
|
assert chunk.chunk_type == ChunkEnum.CONTENT
|
|
assert chunk.done is False
|
|
|
|
asyncio.run(run())
|
|
|
|
|
|
def test_add_stream_done():
|
|
async def run():
|
|
q = asyncio.Queue()
|
|
ctx = RuntimeContext(stream_queue=q)
|
|
result = await ctx.add_stream_done()
|
|
assert result is ctx
|
|
|
|
chunk = q.get_nowait()
|
|
assert chunk.chunk_type == ChunkEnum.DONE
|
|
assert chunk.done is True
|
|
|
|
asyncio.run(run())
|
|
|
|
|
|
# -- response -----------------------------------------------------------------
|
|
|
|
|
|
def test_default_response():
|
|
ctx = RuntimeContext()
|
|
assert ctx.response.success is True
|
|
assert ctx.response.answer == ""
|
|
|
|
|
|
def test_custom_response():
|
|
from reme4.schema import Response
|
|
|
|
resp = Response(answer="ok", success=False)
|
|
ctx = RuntimeContext(response=resp)
|
|
assert ctx.response is resp
|
|
assert ctx.response.success is False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("\n=== RuntimeContext Tests ===")
|
|
test_getitem_setitem()
|
|
test_getitem_missing_raises()
|
|
test_contains()
|
|
test_delitem()
|
|
test_get_with_default()
|
|
test_update_merges_and_returns_self()
|
|
test_from_context_creates_new_when_none()
|
|
test_from_context_reuses_existing()
|
|
test_apply_mapping_copies_values()
|
|
test_apply_mapping_skips_missing_source()
|
|
test_apply_mapping_empty_is_noop()
|
|
test_stream_property()
|
|
test_enqueue_raises_without_queue()
|
|
test_add_stream_string()
|
|
test_add_stream_done()
|
|
test_default_response()
|
|
test_custom_response()
|
|
print("\n所有测试通过!")
|