Files
mattzh72--articraft/tests/agent/test_dashscope_provider.py
wehub-resource-sync 2c632336aa
CI / Viewer CI (push) Successful in 13m37s
CI / Core CI (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:32:38 +08:00

141 lines
4.3 KiB
Python

from __future__ import annotations
import asyncio
from types import SimpleNamespace
from agent.providers.dashscope import (
DEFAULT_DASHSCOPE_BASE_URL,
DEFAULT_DASHSCOPE_MODEL,
DashScopeLLM,
dashscope_api_key_from_env,
dashscope_api_keys_from_env,
)
def test_dashscope_api_keys_from_env_prefers_primary_key_and_dedupes() -> None:
keys = dashscope_api_keys_from_env(
{
"DASHSCOPE_API_KEY": "sk-primary",
"DASHSCOPE_API_KEYS": "sk-primary,\nsk-secondary, sk-secondary",
}
)
assert keys == ["sk-primary", "sk-secondary"]
def test_dashscope_api_key_from_env_uses_key_pool_when_primary_missing() -> None:
key = dashscope_api_key_from_env({"DASHSCOPE_API_KEYS": "sk-first,sk-second"})
assert key in {"sk-first", "sk-second"}
def test_dashscope_default_model_is_qwen_flash() -> None:
provider = DashScopeLLM(dry_run=True)
assert provider.model_id == DEFAULT_DASHSCOPE_MODEL
def test_dashscope_request_preview_uses_compatible_chat_shape() -> None:
provider = DashScopeLLM(dry_run=True)
payload = provider.build_request_preview(
system_prompt="system",
messages=[{"role": "user", "content": "task"}],
tools=[
{
"type": "function",
"function": {
"name": "compile_model",
"description": "Compile",
"parameters": {"type": "object", "properties": {}, "required": []},
},
}
],
)
assert payload["base_url"] == DEFAULT_DASHSCOPE_BASE_URL
assert payload["model"] == DEFAULT_DASHSCOPE_MODEL
assert payload["messages"] == [
{"role": "system", "content": "system"},
{"role": "user", "content": "task"},
]
assert payload["tools"][0]["type"] == "function"
assert payload["extra_body"] == {"enable_thinking": True}
assert payload["max_tokens"] == 64000
def test_dashscope_low_thinking_sets_smaller_budget() -> None:
provider = DashScopeLLM(thinking_level="low", dry_run=True)
payload = provider.build_request_preview(
system_prompt="system",
messages=[{"role": "user", "content": "task"}],
tools=[],
)
assert payload["extra_body"] == {"enable_thinking": True, "thinking_budget": 16000}
def test_dashscope_generate_uses_chat_completions() -> None:
provider = DashScopeLLM(dry_run=True)
provider._client = object()
provider._client_is_async = True
captured: dict[str, object] = {}
async def fake_chat_completion(request_payload: dict) -> SimpleNamespace:
captured.update(request_payload)
return SimpleNamespace(
choices=[SimpleNamespace(message=SimpleNamespace(content="ok", tool_calls=[]))],
usage=None,
)
provider._chat_completion = fake_chat_completion # type: ignore[method-assign]
response = asyncio.run(
provider.generate_with_tools(
system_prompt="system",
messages=[{"role": "user", "content": "task"}],
tools=[],
)
)
assert captured["model"] == DEFAULT_DASHSCOPE_MODEL
assert captured["extra_body"] == {"enable_thinking": True}
assert response["content"] == "ok"
def test_dashscope_response_preserves_reasoning_content_for_next_turn() -> None:
provider = DashScopeLLM(dry_run=True)
result = provider._convert_response(
SimpleNamespace(
choices=[
SimpleNamespace(
message=SimpleNamespace(
content="",
tool_calls=[],
reasoning_content="Planning the tool call.",
)
)
],
usage=None,
)
)
assert result["thought_summary"] == "Planning the tool call."
assert result["extra_content"]["dashscope"]["reasoning_content"] == "Planning the tool call."
payload = provider.build_request_preview(
system_prompt="system",
messages=[
{
"role": "assistant",
"content": "",
"extra_content": result["extra_content"],
},
{"role": "tool", "tool_call_id": "call_1", "content": "compiled"},
],
tools=[],
)
assert payload["messages"][1]["reasoning_content"] == "Planning the tool call."