Commit Graph
37 Commits
Author SHA1 Message Date
wangweiandCopilot 31bbf80aeb feat: surface MCP server status in System Status page
Add per-tool in-memory call counters to the MCP module and a
GET /api/v1/status/mcp endpoint that joins them with the live tool
registry and endpoint config, then render it as a new card on the
System Status page with a one-click client-config copy button.

- app/mcp/stats.py: lock-guarded MCPStatsTracker (the mcp SDK runs sync
  tool bodies via anyio.to_thread.run_sync, so this is genuinely
  multi-threaded, unlike the async REST routes)
- app/mcp/server.py: instrument search_regulations, add get_mcp_status()
- app/config/settings.py: optional MCP_PUBLIC_URL override, required
  because the Vite proxy and reverse proxies rewrite the Host header
- StatusPage.tsx: MCP Server card, joins the existing parallel fetch

Counters are process-local by design; token usage is already persisted
by ModelUsageTracker since MCP calls route through ask().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-03 11:37:22 +08:00
wangweiandCopilot 49ee50c104 fix: harden MCP endpoint after code review
Critical: the MCP SDK auto-enables DNS-rebinding protection when its host
parameter is left at the 127.0.0.1 default, hard-coding a loopback-only Host
allow-list. Every remote client (the only deployment this feature targets) was
refused with HTTP 421 before auth or the tool ran. Now driven by a new
MCP_ALLOWED_HOSTS setting, with '*' as an explicit, logged opt-out.

Also bounds query/top_k to match AskRequest (top_k is amplified 4x downstream,
so an unbounded value was a resource-exhaustion vector), decodes the
Authorization header as latin-1 per the ASGI spec instead of raising a 500 on
malformed bytes, and returns WWW-Authenticate on 401 per RFC 7235.

Moves the psycopg2 import guard into backend/tests/conftest.py: duplicated
across four test modules, it only worked because of alphabetical collection
order, and any earlier-sorting package would have reintroduced a live
connection attempt against the production database.

Registers the mcp module in the authoritative backend architecture doc.

84 backend tests pass. Verified against a live server: allowed remote Host
returns a valid initialize result, unknown Host returns 421, missing token
returns 401 with WWW-Authenticate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-29 17:11:54 +08:00
wangweiandCopilot bd3dc38d1d feat: add MCP server module exposing search_regulations tool
- New backend/app/mcp/ module: MCPServer instance with a single
  search_regulations tool backed by the existing AgentConversationService.
- MCPAuthMiddleware reuses existing JWT auth (no new auth mechanism).
- Mounted at /mcp/ in api/main.py via Streamable HTTP transport; wired the
  MCP session manager into the existing lifespan() via AsyncExitStack
  (app.mount() does not propagate nested ASGI lifespans automatically).
- Fixed a doubled /mcp/mcp path by setting streamable_http_path to "/"
  (MCPServer.streamable_http_app() defaults to registering its own /mcp route).
- Verified end-to-end with the real mcp Python client: list_tools() returns
  search_regulations, auth correctly 401s without or with an invalid token.
- 7 new tests, 76 total (up from 69), all passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-29 13:00:52 +08:00
wangweiandCopilot 0907470a2d fix: offload flush to thread pool, add QwenVL stream_options assert, document single-worker assumption
Fix 1 (bootstrap.py): wrap store.flush() in asyncio.to_thread() inside the
periodic _flush_loop() to avoid blocking the async event loop every 60s.
Synchronous signatures of _start/_stop_model_usage_persistence() and the
one-time seed/shutdown flushes are left unchanged per review scope.

Fix 2 (test_stream_chat_usage_capture.py): add the two-line stream_options
assertion to test_qwen_vl_stream_chat_returns_usage_from_trailing_chunk,
matching the identical check already present in the DeepSeek and Qwen tests.

Fix 3 (design doc): note the single-worker assumption in A3's write strategy
section — multi-worker deployments get last-writer-wins per-row semantics.

Tests: 69 passed, 0 failed (python -m pytest backend/tests -q)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 15:30:21 +08:00
wangweiandCopilot 29f79d7434 feat: seed and periodically persist model usage stats to Postgres
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 14:32:21 +08:00
wangweiandCopilot 5d132981ad feat: add PostgresModelUsageStore and ModelUsageTracker.seed()
- Add seed() method to ModelUsageTracker for bulk-loading persisted entries at startup
- Create PostgresModelUsageStore for persistence of model usage counters to Postgres
- Store only current cumulative snapshots (no historical time-series)
- Use standard CREATE TABLE IF NOT EXISTS idiom matching other Postgres stores
- Add comprehensive mocked unit tests for both components

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 14:18:22 +08:00
wangweiandCopilot 7adc050968 feat: record streaming token usage in TrackedLLMClient.stream_chat
Implement manual generator driving using next()/StopIteration to capture
the return value (trailing usage dict) from inner stream_chat() implementations,
enabling token tracking for streaming LLM calls.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 13:42:33 +08:00
wangweiandCopilot f2bd0deeb3 feat: capture streaming token usage in QwenClient and QwenVLClient
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 13:19:23 +08:00
wangweiandCopilot 81a6d54fff feat: capture streaming token usage in DeepSeekClient.stream_chat
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-23 11:24:31 +08:00
wangwei 52e67b0e7b Add LLM token 2026-07-02 22:03:39 +08:00
wangweiandCopilot e3afb8a07a fix: normalize LLM provider key lookup and skip disabled HyDE ping (final review)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 21:24:22 +08:00
wangweiandCopilot d83286edd4 fix: honor hyde_enabled toggle and record ping failures before client creation (Task 6 review)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 16:42:58 +08:00
wangweiandCopilot 169911ab46 feat: add GET/POST /status/models routes for AI model connection status
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 16:20:35 +08:00
wangweiandCopilot 66fc388bfb feat: record reranker call outcome into ModelUsageTracker
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 15:42:20 +08:00
wangwei 41096369d3 feat: record embedding call usage into ModelUsageTracker 2026-07-02 15:15:03 +08:00
wangwei 4fea159f5b feat: wrap LLM clients with TrackedLLMClient in LLMFactory 2026-07-02 15:03:12 +08:00
wangweiandCopilot 37ea27fcbe feat: add TrackedLLMClient decorator for transparent usage recording
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 14:49:06 +08:00
wangwei 74f327c85e feat: add ModelUsageTracker for per-model token/connection tracking 2026-07-02 14:41:21 +08:00
wangwei 9212747e1b update for 1. 优化 2.中英切换 2026-06-10 11:10:36 +08:00
wangwei e7963b267e fix somethings 2026-06-08 11:16:28 +08:00
wangwei 9fea9c6a53 1. Add 登陆功能
2. 调整字体大小
3. 新增部分功能
2026-06-05 18:00:31 +08:00
wangwei 06e0967128 add 2026-06-05 09:00:36 +08:00
wangwei 746513cc54 fix 2026-06-04 15:43:44 +08:00
ash66 30c7bda389 Refactor document handling and update Milvus collection settings
- Removed multiple failed document entries from `documents.json`.
- Added a new document entry with updated metadata and changed the index name to `regulations_dense_1024_v2`.
- Updated architecture documentation to reflect changes in the Milvus collection name.
- Adjusted requirements by removing the sqlalchemy dependency.
- Modified test cases to align with new document structure and naming conventions.
- Introduced a new test file for Milvus vector index runtime recovery and error handling.
- Updated assertions in various test files to ensure compatibility with the new schema.
2026-05-26 20:21:31 +08:00
ash66 fec22a3a2c Fix centered content layout widths 2026-05-26 12:34:12 +08:00
ash66 10a034e294 feat(bootstrap): refactor runtime dependency management and add lazy loading for binary store and vector index
feat(agent): update import for agent session service
feat(openai): add context truncation check in OpenAI answer generator
docs(README): update frontend environment file conventions
fix(vite): default local frontend development to local backend
2026-05-25 13:58:48 +08:00
ash66 091a02c522 Add AgentSessionService and refactor agent routes
Move session-related responsibilities into a new application-layer AgentSessionService (and AgentSessionFeedbackResult dataclass), provide a bootstrap factory (get_agent_session_service), and update agent API routes to call the service instead of accessing ConversationStore directly. Routes now translate ValueError into 404 responses and use service methods for get/list/history/delete/feedback. Also update package exports and docs/READMEs to declare the backend architecture authority, enforce api -> application -> domain ports -> infrastructure boundaries, and call out legacy services/workflows as migration-only. These changes centralize session logic in the application layer and tighten architecture guidance for future backend work.
2026-05-22 09:50:30 +08:00
wangwei f9ee644f25 feat(perception): backend - mock event store, perception service, /perception API routes 2026-05-22 00:33:43 +08:00
wangwei 6bf5600a26 feat(status): add /health aggregate endpoint and 10s TTL cache on /stats 2026-05-21 23:53:15 +08:00
wangwei bf6d47e1fd Fix 法规对话 2026-05-21 23:20:39 +08:00
wangwei 1b640f0084 fix 法规对话模块 2026-05-20 23:39:15 +08:00
wangwei b065d55c86 fix 文档管理模块 & 法规对话模块 2026-05-20 23:34:08 +08:00
ash66 c22b03dc07 feat: Migrate document parsing to Aliyun and update embedding configurations
- Updated LocalDocumentParser to include raw_layouts and artifact_prefix from settings.
- Added new documents with failure reasons and metadata to documents.json for better error tracking.
- Created a new documentation file detailing the Aliyun ingest implementation process.
- Updated RFC to reflect changes in the parsing backend and embedding dimensions.
- Modified tests to accommodate the new embedding dimension of 1024 and updated parser and chunk builder assertions.
- Verified migration configurations to ensure correct settings for embedding model and backend.
2026-05-18 22:30:28 +08:00
ash66 3f69cad404 Fix SSE route dependency and align architecture docs 2026-05-18 16:32:42 +08:00
ash66 86b9ac806a Delete log file for May 14, 2026, to clean up unnecessary data and maintain log management. 2026-05-18 13:29:57 +08:00
ash66 35cd927d02 Refactor code structure for improved readability and maintainability 2026-05-14 18:09:15 +08:00
wangwei 10d04c4083 update 2026-05-14 15:07:34 +08:00