Commit Graph
8 Commits
Author SHA1 Message Date
Eric Wang e5d2a78886 feat(config): named LLM provider list via env vars, runtime selection
- Config.llm_profiles: LLM_PROVIDERS declares names, each group defined by
  LLM_<NAME>_BASE_URL/_API_KEY/_MODEL (required) and optional _TIMEOUT_SECONDS/
  _MAX_RETRIES/_TEMPERATURE/_EXTRA_BODY; JSON-dict form of LLM_PROVIDERS also
  supported. LLM_PROVIDER selects the active group at runtime; empty/fake =
  offline scripted model
- removed fixed openai/kimi groups (AGENT_LLM_PROVIDER, KIMI_LLM_*)
- validate(): incomplete groups and unknown LLM_PROVIDER fail fast with
  the configured-name list
- OpenAILLMService: http client trust_env from LLM_HTTP_TRUST_ENV (default
  False - local gateways must bypass the Windows system proxy)
- build_llm_service(provider): explicit name or LLM_PROVIDER default
- .env/.env.example: deepseek + kimi groups side by side, switch by
  LLM_PROVIDER=kimi (thinking off via EXTRA_BODY reasoning_effort=none)
- eval probe scripts updated to the new config interface

Verified: 172 unit tests; live calls succeed on both providers
(deepseek 28s, kimi 6.6s, both emitting valid <state> prefixes)
2026-10-22 13:59:18 +08:00
Eric Wang a5407e03b2 feat(agent): align prompts and runtime with workflow@20261020
- archive workflow/20261020 export (diff vs 20261016: collection prompt
  only - state-decides-body rule, route when info complete)
- prompts: collection.md updated; 6 photo/confirm prompts archived with
  source nodeIds; render_prompt replaces {{$vars}} (Asia/Shanghai clock,
  person fields, explicit 'not provided' for missing prefills)
- llm: message history passed as user/assistant roles (chatNode history=50);
  optional LLM_TEMPERATURE; FakeLLMService supports history-aware responders
- collect: context via system supplement, raw user input as user message
  (Text Editor#2 parity), shared validated_reply (one call, one repair)
- welcome: Assigned Reply#3 original text, stored in dialogue history
- transitions: 2004 plate-confirm entries (2003->2004/2005, 2004->2005)
- verified: prompt files byte-identical to workflow JSON (parametrized test)
2026-10-21 15:10:51 +08:00
Eric Wang 1c6b1a513d feat(agent): LLM-powered collection node with welcome stage and session-scoped delete (assignment 4)
- prompts/collection.md: versioned collection system prompt extracted
  from workflow node yQaBxfrWjbRr with source/version/porting notes
- llm.py: LLMService protocol; FakeLLMService (scripted, records
  calls); OpenAILLMService (async, wait_for timeout with cancellation,
  retry only on timeout/429/connection, errors normalized)
- collect.py: run_collect reference impl - one LLM call produces
  state prefix + body, controlled repair (max 1 retry) for missing
  prefix or illegal stage proposal, whitelist guard, CollectReplyError
  without raw model content; dialogue history + confirmed fields
  injected into prompt so the model skips known info (作业4-5)
- fields.py / clock.py: three-state field candidates (unknown/
  candidate/confirmed), per-type validation (count not inferred from
  description, future time rejected), injectable Clock
- graph.py: welcome node - first message returns fixed 1001 greeting
  without LLM (mirrors workflow is_first_message -> Assigned Reply#3),
  route empty stage to welcome
- endpoints/delete_session: backend switch - langgraph clears graph
  checkpoint, fastgpt path unchanged
- config: AGENT_LLM_PROVIDER fake|openai with validation
- untrack .env (secrets), move template to root .env.example

Verified:
- pytest 103 passed; smoke turns 1/2/1
- Real LLM e2e: POST /chat multi-turn context works
- Golden eval collection_skip_known_info: 12/12 cases pass
- Golden eval no_false: 8/10 cases pass; 4 confirm/photo cases fail
  at final step - model routes on short reply '对' (prompt-adherence
  gap, photo/confirm stages are assignment 5 scope); recorded in
  evals/results/20261020-144856

Known limits: field extraction from model reply not wired (stub);
photo/confirm nodes still scaffold; clarify counting is approximate.
2026-10-20 14:53:46 +08:00
Eric Wang 5d68b731d4 feat(backends): wire LangGraph backend behind AGENT_BACKEND switch (assignment 2)
- src/backends/langgraph.py: LangGraphBackend implements ChatBackend;
  complete() runs one graph turn per session (thread_id=sessionId) and
  returns state-prefixed content; stream() emits the full state prefix
  before body fragments (full-answer slicing, not yet real incremental
  output - assignment 8)
- src/core/config.py: AGENT_BACKEND=fastgpt|langgraph, langgraph mode
  no longer requires FastGPT credentials at startup
- src/core/fastgpt_client.py: lifespan builds the backend by switch
- test/backends/test_langgraph_backend.py: adapter acceptance tests

Verified:
- pytest: 48 passed
- AGENT_BACKEND=langgraph uvicorn: POST /chat -> 1002;
  browser_addon -> browser_addon.1002; SSE = stage_code, text_delta,
  single done

Known limit: stream slices a complete answer; no formUpdate deltas yet
(assignment 6).
2026-10-19 14:29:31 +08:00
Xin Wang be6af046ca Simplify client mode to single FastGPT app 2026-07-28 10:38:01 +08:00
Xin Wang 3e9385b0ca Add client-mode FastGPT routing 2026-07-28 08:41:34 +08:00
Xin Wang d5f81ef79f use fastgpt python sdk 2026-01-08 16:22:25 +08:00
Xin Wang a1a4bceb9a Add api server code and workflow 2025-04-29 15:03:02 +08:00