# DeepSeek Monitoring Completion Design **Date:** 2026-04-23 **Status:** Draft for Review ## Overview Complete `deepseek` support in the desktop monitoring pipeline so it reaches practical parity with the existing AI monitoring platforms: - visible in AI platform management - bindable and probeable through the existing desktop auth flow - executable as a hidden desktop monitoring task - able to submit answer content back to the server - able to extract and report citations when the DeepSeek web UI exposes them `hunyuan` is explicitly out of scope for this work because the product decision is to treat it as `yuanbao`. ## Current State The codebase already has the platform catalog entry and generic AI auth probing support for `deepseek`, but the desktop monitor execution layer does not provide a DeepSeek adapter and does not route monitor tasks to one. That creates a partial implementation: - AI platform management can show DeepSeek and attempt generic session probing. - The runtime treats `deepseek` as a login-required monitor platform. - Server-side monitoring tasks can reference `deepseek`. - The desktop runtime cannot actually execute a `deepseek` monitor task because `selectMonitorAdapter()` returns `null`. ## Requirements | ID | Requirement | | --- | --- | | R1 | `deepseek` monitor tasks must execute through the desktop runtime instead of falling back to scaffold results | | R2 | Existing generic AI platform bind/probe flow remains the authorization path for DeepSeek | | R3 | The adapter must ask the configured monitoring question and wait for the final answer in a hidden browser context | | R4 | The adapter must report `answer`, `provider_model`, and raw observation payload back through the existing monitoring callback API | | R5 | The adapter must collect citations when the latest DeepSeek answer exposes external references or source/search links | | R6 | Citation extraction failure must not fail an otherwise successful answer capture | | R7 | Missing login, challenge, timeout, and transport failures must be surfaced in the same failure contract used by the existing adapters | | R8 | The implementation must ship with adapter-level tests and at least one regression test covering DeepSeek result ingestion assumptions | ## Chosen Approach Use a new Playwright-based monitor adapter for DeepSeek, matching the current desktop monitoring architecture used by `kimi`, `qwen`, `yuanbao`, `doubao`, and `wenxin`. Why this approach: - It fits the current runtime model with hidden pages, task progress reporting, and task result posting. - It reuses the already-working generic AI authorization and session partition management. - It is less risky than introducing a new DeepSeek-only HTTP/SSE client against undocumented web APIs. - It lets us capture both rendered answer text and any citation UI that only exists in the browser. Not chosen: - Direct HTTP/SSE replay of private DeepSeek web APIs in this iteration - A DeepSeek-specific auth subsystem separate from the generic AI platform probing path ## User-Facing Outcome After this work: - A tenant can bind a DeepSeek session from the desktop AI platforms page using the existing platform management flow. - The desktop runtime can receive and execute `deepseek` monitor tasks. - Successful DeepSeek runs write answer text and citations into the same server-side monitoring result path used by the other platforms. - If DeepSeek returns an answer with no visible sources, the task still succeeds and stores an empty citation list. ## Design ### 1. Authorization Management No new DeepSeek-only authorization flow will be introduced. DeepSeek continues to use the existing generic AI platform detection path in `account-binder.ts` and `platform-auth-adapters.ts`: - bind flow opens the DeepSeek console URL in a dedicated partition - the generic AI page probe checks for logged-out, challenge, and authenticated states - the periodic account health worker keeps using the generic platform adapter classification path Implementation note: - No schema or API change is required for auth management. - This work may add small DeepSeek-specific failure text classification only if runtime evidence shows the generic rules miss a known DeepSeek auth/challenge string. ### 2. Desktop Monitor Adapter Add `apps/desktop-client/src/main/adapters/deepseek.ts`. Adapter contract: - `provider: "deepseek"` - `executionMode: "playwright"` - `query(context, payload)` returns the standard `AdapterExecutionResult` Execution flow: 1. Resolve the question text from the monitor payload using the same candidate field strategy as the existing adapters. 2. Ensure the hidden Playwright page is on `https://chat.deepseek.com/`. 3. Detect early terminal states before typing: - login required - human verification / challenge - page bootstrap failure 4. Focus the current input editor and submit the monitoring question. 5. Poll the page for the newest assistant response until the answer is stable or a timeout is hit. 6. Extract answer text, provider metadata, citations, and source/search panels from the latest answer surface. 7. Return a successful payload even when citation arrays are empty, as long as answer capture succeeded. ### 3. Page Observation Model The DeepSeek adapter will mirror the existing adapter pattern and keep a structured in-page snapshot instead of relying on one selector or one network response. The snapshot will capture: - current URL and page title - login-required signals - challenge/risk-control signals - busy/generating signals - latest assistant answer text - latest reasoning text if present - latest assistant message signature for stability polling - explicit citation/source links associated with the latest answer - raw link groups for fallback debugging - provider metadata when discoverable from page state This gives us a stable contract for: - wait-until-complete logic - answer completeness checks - citation extraction - regression tests that do not need a live DeepSeek account ### 4. Citation Extraction Strategy DeepSeek citation support will be best-effort but first-class in the initial implementation. The adapter will collect links in this order: 1. latest-answer inline reference anchors 2. latest-answer attached source cards / source lists / citation panels 3. explicit search/source side panels if the UI renders them for the current answer Normalization rules: - only keep non-empty external URLs - strip URL hash fragments before dedupe - preserve title and site name when present - dedupe by normalized URL - do not duplicate the same URL across `citations` and `search_results` Classification rules: - `citations`: links directly attached to the latest answer body or answer-level citation panel - `search_results`: links rendered in a clearly separate search/source results surface for the answer Fallback rules: - if the answer exists but no links are discoverable, return success with empty `citations` and empty `search_results` - if link extraction partially fails, keep the successfully parsed links and retain the raw observation in `raw_response_json` - citation parsing must never convert a successful answer capture into a failed monitor task ### 5. Provider Metadata The adapter should report: - `provider_model`: page-derived model label when available, otherwise `"deepseek-chat"` - `provider_request_id`: page-derived conversation/message/request identifier when available, otherwise omitted This is intentionally softer than the answer requirement. Missing metadata is acceptable; missing final answer is not. ### 6. Runtime Registration Wire the new adapter into the desktop runtime: - export it from `apps/desktop-client/src/main/adapters/index.ts` - import it in `apps/desktop-client/src/main/runtime-controller.ts` - return it from `selectMonitorAdapter("deepseek")` No server dispatch change is needed because the server already emits `deepseek` tasks and the runtime already treats DeepSeek as a login-required monitor platform. ### 7. Result Reporting The adapter output will flow through the existing client and server result pipeline without adding new endpoints. Successful DeepSeek result payloads will populate: - `answer` - `provider_model` - optional `provider_request_id` - `citations` - `search_results` - `raw_response_json` Server-side ingestion behavior remains unchanged: - `buildMonitoringRawPayload()` stores answer and source arrays - existing citation source resolution consumes those arrays - DeepSeek keeps the default non-Kimi behavior, meaning `search_results` remain eligible as citation source inputs when present This avoids any schema or ingestion branching that is specific to DeepSeek. ### 8. Error Handling The adapter will return `failed` with structured error payloads for: - missing question text - login required / session expired - challenge required / captcha / human verification - send action unavailable - answer timeout - aborted task The adapter will return `succeeded` when: - a stable final answer is captured, even if no citations are found The adapter will return `unknown` only for ambiguous states where: - the page remains reachable - the task did not clearly fail auth - the answer never reached a trustworthy terminal state ### 9. Testing #### Adapter Tests Add `apps/desktop-client/src/main/adapters/deepseek.test.ts`. These tests will cover helper behavior without requiring a real DeepSeek session: - question text resolution - URL normalization and link dedupe - citation classification from a synthetic page snapshot - answer completion / stability rules - failure classification for login/challenge/timeout cases #### Runtime Wiring Regression Add or extend a desktop runtime regression test so `selectMonitorAdapter("deepseek")` no longer returns `null`. If direct unit coverage of `selectMonitorAdapter()` is awkward because it is file-local, extract a tiny adapter registry helper so the routing can be tested without spinning the whole runtime controller. #### Server Ingestion Regression Add a monitoring callback regression test confirming that DeepSeek payloads with `search_results` continue to feed the normal citation source input path and do not require DeepSeek-specific server branching. ## File Changes Expected implementation touchpoints: - `apps/desktop-client/src/main/adapters/deepseek.ts` - `apps/desktop-client/src/main/adapters/deepseek.test.ts` - `apps/desktop-client/src/main/adapters/index.ts` - `apps/desktop-client/src/main/runtime-controller.ts` - `apps/desktop-client/src/main/platform-auth-adapters.ts` only if DeepSeek-specific auth/challenge wording needs classification tuning - `server/internal/tenant/app/monitoring_callback_service_test.go` ## Non-Goals - separate `hunyuan` adapter or platform entry changes - new monitoring database fields - new callback APIs - undocumented direct DeepSeek HTTP client support - perfect citation recovery from every possible DeepSeek UI variant ## Risks And Mitigations | Risk | Impact | Mitigation | | --- | --- | --- | | DeepSeek page structure differs from Kimi/Qwen enough that one selector path is brittle | answer capture breaks | use multi-signal page snapshotting instead of single-selector extraction | | Citation UI is conditional and not always present | sparse citation coverage | treat citations as best-effort and keep answer success independent from citation presence | | DeepSeek challenge/risk-control copy is not fully covered by generic auth rules | false success or unclear failures | add DeepSeek-specific failure text classification only where runtime evidence shows a gap | | Provider request identifiers are not consistently exposed in DOM state | weaker traceability | keep request id optional and fall back to stable model + raw response payload | ## Rollout Notes - This is safe to ship behind the existing runtime because unsupported DeepSeek tasks currently fail at adapter selection time. - No migration is required. - The implementation should be verified first with one manually bound DeepSeek desktop account before treating it as generally available in production monitoring runs.