refactor: LLM client for calling supplier LLM APIs (not server)
Replaces wrong-direction llm_api.py (which served OpenAI endpoints)
with llm_client.py -- a client that calls supplier LLM APIs.
New module: llm_client.py
- llm_chat(messages, model, temperature, ...) -> OpenAI response dict
- llm_chat_stream(messages, ...) -> async generator of SSE chunks
- llm_simple(prompt, system) -> plain text response
- llm_list_models() -> list available models from provider
- llm_get_config() -> show current config (key masked)
- Supports provider presets: openai, dashscope, deepseek, siliconflow
- Retry with exponential backoff (3 attempts)
- 429 rate limit handling with Retry-After
- Structured logging via appPublic.log
Model changes (harnessed_agent_config):
- Add llm_provider (preset name: dashscope/openai/deepseek/siliconflow)
- Add top_p field
- llm_service_url defaults to DashScope compatible endpoint
Other:
- Remove wrong-direction /v1/ endpoints
- Fix pyproject.toml deps: only sqlor + bricks_for_python
- Update init/data.json seed data with LLM config fields
- Update CRUD view with llm_provider dropdown