feat(llm): провайдер за протоколом — OpenAI-совместимый API и mock, фабрика по конфигу
- LLMProvider: complete(messages, schema) -> LLMResult (текст, разобранный JSON, токены) - openai_compat: /chat/completions, structured output через response_format json_schema, JSON из ```-обёртки тоже разбирается; ретраи на 429/5xx и сетевые ошибки, 4xx — сразу ошибка - mock: детерминированные правила для тестов и демо без сети - LLMSettings (LLM_PROVIDER/BASE_URL/MODEL/API_KEY…), CLI python -m app.llm.cli Refs #17 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Debug CLI: `python -m app.llm.cli 'вопрос'` — one completion with the configured provider."""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from app.config import LLMSettings
|
||||
from app.llm.factory import make_provider
|
||||
from app.llm.provider import ChatMessage
|
||||
|
||||
|
||||
async def ask(question: str) -> None:
|
||||
settings = LLMSettings()
|
||||
provider = make_provider(settings)
|
||||
try:
|
||||
result = await provider.complete([ChatMessage("user", question)])
|
||||
finally:
|
||||
await provider.aclose()
|
||||
print(f"[{settings.provider} {settings.model or '-'}] tokens={result.tokens}\n{result.text}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit("usage: python -m app.llm.cli 'question'")
|
||||
asyncio.run(ask(" ".join(sys.argv[1:])))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user