mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-09-07 08:26:06 +00:00
* refactor(file_chunker): replace file parser with file chunker component - Rename file_parser module to file_chunker across codebase - Update BaseFileParser to BaseFileChunker with corresponding component type - Rename LinkedFileParser to MarkdownFileChunker for markdown-specific chunking - Rename ChunkedFileParser to DefaultFileChunker for default byte-based chunking - Update documentation references from file_parser to file_chunker - Modify dependency injection in BaseStep to use file_chunker instead of file_parser - Update configuration and component registration to use new chunker naming - Rename all related test files and update test assertions accordingly - Add recursive option to scan_store_changes_step in default configuration * feat(database): enhance Neo4j connection with environment variable support - Add support for NEO4J_PASSWORD environment variable as fallback - Make password parameter optional in constructor with validation - Update chromadb dependency from 1.3.5 to 1.5.7 - Configure CORS credentials based on origin settings - Import os module for environment variable access * feat(config): add timezone support and remove unused dialog directory - Added timezone field to application config with IANA timezone support - Removed unused dialog_dir configuration and related directory creation - Replaced date.today() with timezone-aware now() function across daily operations - Created evolve module with timezone-aware datetime functionality - Updated daily_create, daily_list, and daily_reindex steps to use timezone-aware dates * refactor(steps): update file chunker implementation - Replace ChunkedFileParser with DefaultFileChunker in background steps - Add module docstring to evolve steps package - Update return type annotation to reflect new chunker class usage * refactor(components): rename embedding and llm components to as_embedding and as_llm - Rename reme4/components/embedding to reme4/components/as_embedding - Rename reme4/components/llm to reme4/components/as_llm - Update all imports and references from embedding to as_embedding - Update all imports and references from llm to as_llm - Change BaseEmbedding to BaseAsEmbedding and update inheritance - Change BaseLLM to BaseAsLLM and update inheritance - Update component types from LLM/EMBEDDING to AS_LLM/AS_EMBEDDING - Update configuration keys from embedding/llm to as_embedding/as_llm - Update all property references from llm to as_llm in step classes - Update test assertions to use new component enum values * refactor(embedding_store): rename embedding parameter to as_embedding - Updated configuration key from 'embedding' to 'as_embedding' - Renamed class attribute from 'embedding' to 'as_embedding' - Updated method calls to use 'as_embedding' instead of 'embedding' - Changed parameter name in constructor from 'embedding' to 'as_embedding' - Updated documentation to reflect new parameter name - Modified health check to use 'as_embedding' property * feat(agent_wrapper): add unified agent wrapper component with multiple backends - Introduce BaseAgentWrapper abstract base class for agent implementations - Add AsAgentWrapper implementation using AgentScope framework - Add CcAgentWrapper implementation using Claude Code SDK - Register agent_wrapper component type in ComponentEnum - Configure default agent_wrapper settings in default.yaml - Implement tool integration for both AgentScope and Claude Code backends - Support fluent configuration via set_system_prompt() and add_tools() methods * feat(agent-wrapper): add structured output support for agent wrappers - Import SystemMsg in AsAgentWrapper for structured output handling - Add output_schema parameter support in AsAgentWrapper with generate_structured_output - Implement set_output_schema method in BaseAgentWrapper for chaining configuration - Add output schema support in CcAgentWrapper with JSON schema format option - Return structured output when available in CcAgentWrapper response - Refactor kwargs handling to use default values consistently across wrapper classes
151 lines
4.3 KiB
Python
151 lines
4.3 KiB
Python
"""Tests for ComponentRegistry."""
|
|
|
|
# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,unused-argument
|
|
|
|
import pytest
|
|
|
|
from reme4.components.base_component import BaseComponent
|
|
from reme4.components.component_registry import ComponentRegistry
|
|
from reme4.enumeration import ComponentEnum
|
|
|
|
|
|
class _DummyComponent(BaseComponent):
|
|
component_type = ComponentEnum.FILE_CHUNKER
|
|
|
|
|
|
class _AnotherComponent(BaseComponent):
|
|
component_type = ComponentEnum.KEYWORD_INDEX
|
|
|
|
|
|
class _NoComponentType:
|
|
pass
|
|
|
|
|
|
class _BaseComponentType(BaseComponent):
|
|
component_type = ComponentEnum.BASE
|
|
|
|
|
|
# -- register & get -----------------------------------------------------------
|
|
|
|
|
|
def test_register_direct_with_explicit_name():
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent, "my_parser")
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "my_parser") is _DummyComponent
|
|
|
|
|
|
def test_register_direct_defaults_to_class_name():
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent)
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "_DummyComponent") is _DummyComponent
|
|
|
|
|
|
def test_register_decorator():
|
|
reg = ComponentRegistry()
|
|
|
|
@reg.register("alias")
|
|
class MyParser(BaseComponent):
|
|
component_type = ComponentEnum.FILE_CHUNKER
|
|
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "alias") is MyParser
|
|
|
|
|
|
def test_register_overwrite_warns(caplog):
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent, "dup")
|
|
reg.register(_DummyComponent, "dup")
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "dup") is _DummyComponent
|
|
|
|
|
|
def test_register_rejects_missing_component_type():
|
|
reg = ComponentRegistry()
|
|
with pytest.raises(TypeError, match="ComponentEnum"):
|
|
reg.register(_NoComponentType, "bad")
|
|
|
|
|
|
def test_register_rejects_empty_name():
|
|
reg = ComponentRegistry()
|
|
with pytest.raises(ValueError, match="empty"):
|
|
reg._do_register(_DummyComponent, "")
|
|
|
|
|
|
def test_register_rejects_non_class_non_string():
|
|
reg = ComponentRegistry()
|
|
with pytest.raises(TypeError, match="Expected a class or string"):
|
|
reg.register(42)
|
|
|
|
|
|
# -- get_all ------------------------------------------------------------------
|
|
|
|
|
|
def test_get_all_returns_copy():
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent, "a")
|
|
reg.register(_AnotherComponent, "b")
|
|
|
|
parsers = reg.get_all(ComponentEnum.FILE_CHUNKER)
|
|
assert parsers == {"a": _DummyComponent}
|
|
|
|
indexes = reg.get_all(ComponentEnum.KEYWORD_INDEX)
|
|
assert indexes == {"b": _AnotherComponent}
|
|
|
|
# Mutating the copy doesn't affect the registry.
|
|
parsers["hacked"] = _DummyComponent
|
|
assert "hacked" not in reg.get_all(ComponentEnum.FILE_CHUNKER)
|
|
|
|
|
|
def test_get_all_unknown_type_returns_empty():
|
|
reg = ComponentRegistry()
|
|
assert not reg.get_all(ComponentEnum.AS_LLM)
|
|
|
|
|
|
# -- get (miss) ---------------------------------------------------------------
|
|
|
|
|
|
def test_get_nonexistent_returns_none():
|
|
reg = ComponentRegistry()
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "nope") is None
|
|
|
|
|
|
# -- unregister ---------------------------------------------------------------
|
|
|
|
|
|
def test_unregister_existing():
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent, "x")
|
|
assert reg.unregister(ComponentEnum.FILE_CHUNKER, "x") is True
|
|
assert reg.get(ComponentEnum.FILE_CHUNKER, "x") is None
|
|
|
|
|
|
def test_unregister_missing_returns_false():
|
|
reg = ComponentRegistry()
|
|
assert reg.unregister(ComponentEnum.FILE_CHUNKER, "nope") is False
|
|
|
|
|
|
# -- clear --------------------------------------------------------------------
|
|
|
|
|
|
def test_clear():
|
|
reg = ComponentRegistry()
|
|
reg.register(_DummyComponent, "a")
|
|
reg.register(_AnotherComponent, "b")
|
|
reg.clear()
|
|
assert not reg.get_all(ComponentEnum.FILE_CHUNKER)
|
|
assert not reg.get_all(ComponentEnum.KEYWORD_INDEX)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("\n=== ComponentRegistry Tests ===")
|
|
test_register_direct_with_explicit_name()
|
|
test_register_direct_defaults_to_class_name()
|
|
test_register_decorator()
|
|
test_register_rejects_missing_component_type()
|
|
test_register_rejects_empty_name()
|
|
test_register_rejects_non_class_non_string()
|
|
test_get_all_returns_copy()
|
|
test_get_all_unknown_type_returns_empty()
|
|
test_get_nonexistent_returns_none()
|
|
test_unregister_existing()
|
|
test_unregister_missing_returns_false()
|
|
test_clear()
|
|
print("\n所有测试通过!")
|