mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-14 08:17:34 +00:00
The backend import package is now docsgpt, the name it will carry on PyPI; application was far too generic to install into anyone's site-packages. git mv plus a mechanical rewrite of every import, dotted string and path reference: 734 Python files, the compose files, Dockerfile, workflows, docs, setup scripts, devcontainer, k8s manifests, vscode config, pytest and coverage config, .gitignore. Behaviour is unchanged. Kept for one release: - A top-level application package whose meta-path finder resolves application.x.y to the already-imported docsgpt.x.y object, so old imports and entry points (celery -A application.app.celery, uvicorn application.asgi:asgi_app) keep working with a FutureWarning. - Celery registers every application.* task name as an alias of its docsgpt.* task on start-up, so messages queued by the previous release still run. The redbeat key prefix moves to redbeat:docsgpt:v2: so schedule entries the previous release wrote are left unread instead of firing twice. The backend image builds from the repository root (docker build -f docsgpt/Dockerfile .) so it can ship the alias package; a root .dockerignore allow-lists docsgpt/ and application/ and keeps caches, local data, .env files, the sample index files and the Dockerfile out. Compose and the image workflows point at the new context.
131 lines
5.1 KiB
Python
131 lines
5.1 KiB
Python
|
|
from docsgpt.llm.handlers.handler_creator import LLMHandlerCreator
|
|
from docsgpt.llm.handlers.anthropic import AnthropicLLMHandler
|
|
from docsgpt.llm.handlers.base import LLMHandler
|
|
from docsgpt.llm.handlers.openai import OpenAILLMHandler
|
|
from docsgpt.llm.handlers.google import GoogleLLMHandler
|
|
|
|
|
|
class TestLLMHandlerCreator:
|
|
"""Test LLMHandlerCreator class."""
|
|
|
|
def test_create_openai_handler(self):
|
|
"""Test creating OpenAI handler."""
|
|
handler = LLMHandlerCreator.create_handler("openai")
|
|
|
|
assert isinstance(handler, OpenAILLMHandler)
|
|
assert isinstance(handler, LLMHandler)
|
|
|
|
def test_create_openai_handler_case_insensitive(self):
|
|
"""Test creating OpenAI handler with different cases."""
|
|
handler_upper = LLMHandlerCreator.create_handler("OPENAI")
|
|
handler_mixed = LLMHandlerCreator.create_handler("OpenAI")
|
|
|
|
assert isinstance(handler_upper, OpenAILLMHandler)
|
|
assert isinstance(handler_mixed, OpenAILLMHandler)
|
|
|
|
def test_create_google_handler(self):
|
|
"""Test creating Google handler."""
|
|
handler = LLMHandlerCreator.create_handler("google")
|
|
|
|
assert isinstance(handler, GoogleLLMHandler)
|
|
assert isinstance(handler, LLMHandler)
|
|
|
|
def test_create_google_handler_case_insensitive(self):
|
|
"""Test creating Google handler with different cases."""
|
|
handler_upper = LLMHandlerCreator.create_handler("GOOGLE")
|
|
handler_mixed = LLMHandlerCreator.create_handler("Google")
|
|
|
|
assert isinstance(handler_upper, GoogleLLMHandler)
|
|
assert isinstance(handler_mixed, GoogleLLMHandler)
|
|
|
|
|
|
|
|
def test_create_default_handler(self):
|
|
"""Test creating default handler."""
|
|
handler = LLMHandlerCreator.create_handler("default")
|
|
|
|
assert isinstance(handler, OpenAILLMHandler)
|
|
|
|
def test_create_unknown_handler_fallback(self):
|
|
"""Test creating handler for unknown type falls back to OpenAI."""
|
|
handler = LLMHandlerCreator.create_handler("unknown_provider")
|
|
|
|
assert isinstance(handler, OpenAILLMHandler)
|
|
|
|
def test_create_anthropic_handler(self):
|
|
"""Anthropic has its own handler: the OpenAI one cannot read Claude's
|
|
content-block responses and would silently drop every tool call."""
|
|
handler = LLMHandlerCreator.create_handler("anthropic")
|
|
|
|
assert isinstance(handler, AnthropicLLMHandler)
|
|
assert isinstance(handler, LLMHandler)
|
|
|
|
def test_create_empty_string_handler_fallback(self):
|
|
"""Test creating handler with empty string falls back to OpenAI."""
|
|
handler = LLMHandlerCreator.create_handler("")
|
|
|
|
assert isinstance(handler, OpenAILLMHandler)
|
|
|
|
|
|
|
|
def test_handlers_registry(self):
|
|
"""Test the handlers registry contains expected mappings."""
|
|
expected_handlers = {
|
|
"openai": OpenAILLMHandler,
|
|
"google": GoogleLLMHandler,
|
|
"anthropic": AnthropicLLMHandler,
|
|
"novita": OpenAILLMHandler,
|
|
"default": OpenAILLMHandler,
|
|
}
|
|
|
|
assert LLMHandlerCreator.handlers == expected_handlers
|
|
|
|
def test_create_handler_with_args(self):
|
|
"""Test creating handler with additional arguments."""
|
|
handler = LLMHandlerCreator.create_handler("openai")
|
|
|
|
assert isinstance(handler, OpenAILLMHandler)
|
|
assert handler.llm_calls == []
|
|
assert handler.tool_calls == []
|
|
|
|
def test_create_handler_with_kwargs(self):
|
|
"""Test creating handler with keyword arguments."""
|
|
handler = LLMHandlerCreator.create_handler("google")
|
|
|
|
assert isinstance(handler, GoogleLLMHandler)
|
|
assert handler.llm_calls == []
|
|
assert handler.tool_calls == []
|
|
|
|
def test_all_registered_handlers_are_valid(self):
|
|
"""Test that all registered handlers can be instantiated."""
|
|
for handler_type in LLMHandlerCreator.handlers.keys():
|
|
handler = LLMHandlerCreator.create_handler(handler_type)
|
|
assert isinstance(handler, LLMHandler)
|
|
assert hasattr(handler, 'parse_response')
|
|
assert hasattr(handler, 'create_tool_message')
|
|
assert hasattr(handler, '_iterate_stream')
|
|
|
|
def test_handler_inheritance(self):
|
|
"""Test that all created handlers inherit from LLMHandler."""
|
|
test_types = ["openai", "google", "default", "unknown"]
|
|
|
|
for handler_type in test_types:
|
|
handler = LLMHandlerCreator.create_handler(handler_type)
|
|
assert isinstance(handler, LLMHandler)
|
|
|
|
assert callable(getattr(handler, 'parse_response'))
|
|
assert callable(getattr(handler, 'create_tool_message'))
|
|
assert callable(getattr(handler, '_iterate_stream'))
|
|
|
|
def test_create_handler_preserves_handler_state(self):
|
|
"""Test that each created handler has independent state."""
|
|
handler1 = LLMHandlerCreator.create_handler("openai")
|
|
handler2 = LLMHandlerCreator.create_handler("openai")
|
|
|
|
handler1.llm_calls.append("test_call")
|
|
|
|
assert len(handler1.llm_calls) == 1
|
|
assert len(handler2.llm_calls) == 0
|
|
assert handler1 is not handler2
|