# AI Runtime Client Sync Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Synchronize AI calls in web, web-admin, life-script, and mini-program so user-facing AI output uses the backend scene routing runtime and streams text progressively. **Architecture:** The backend remains the single trust boundary for provider credentials, scene bindings, user context enrichment, and workflow selection. Browser and mini-program clients call `/ai/runtime/stream` with `sceneCode` and `inputs`, while existing WebSocket chat is bridged through `AiRuntimeService` so chat also follows the configured `chat` scene. Existing business save APIs remain responsible for persistence after a stream completes. **Tech Stack:** Spring Boot, STOMP WebSocket, FastJSON, Vue 3, React/Vite, uni-app chunked request, Element Plus. --- ### Task 1: Backend Chat Bridge To Runtime **Files:** - Modify: `backend-single/src/main/java/com/emotion/service/impl/WebSocketServiceImpl.java` - Modify: `backend-single/src/main/java/com/emotion/dto/websocket/WebSocketMessage.java` - [x] Route chat generation through `AiRuntimeService` with `sceneCode=chat`. - [x] Push `start`, `delta`, `done`, and `error` events over the existing user WebSocket topic. - [x] Save the final assistant message after `done` using the accumulated stream output. - [x] Preserve the existing user-message persistence and conversation ID behavior. ### Task 2: Shared Runtime Clients **Files:** - Create: `web/src/services/aiRuntime.ts` - Create: `life-script/src/services/aiRuntime.js` - Modify: `mini-program/src/services/aiRuntime.js` - Modify: `web-admin/src/api/aiconfig.ts` - Modify: `web-admin/src/views/aiconfig/AiRoutingList.vue` - [x] Add browser SSE client helpers that parse unified AI stream events. - [x] Keep mini-program chunk parsing but localize error messages and flush trailing frames. - [x] Add a web-admin stream test helper and make the test dialog render output progressively. ### Task 3: Client Scene Migration **Files:** - Modify: `life-script/src/services/ai.js` - Modify: `life-script/src/views/ScriptView.jsx` - Modify: `life-script/src/views/TimelineView.jsx` - Modify: `life-script/src/views/PathView.jsx` - Modify: `mini-program/src/pages/main/ScriptView.vue` - Inspect: `web/src/stores/chat.ts` - [x] Remove direct OpenRouter calls and hard-coded client API keys. - [x] Route `script_generate`, `life_healing`, and path generation through `streamAiScene`. - [x] Ensure pages append `delta` content instead of waiting for complete text. - [x] Keep final persistence through existing business save APIs after stream completion. ### Task 4: Verification **Commands:** - `mvn test` - `mvn -DskipTests clean package` - `npm run build` in `web` - `npm run build` in `web-admin` - `npm run build` in `life-script` - `npm run build:mp-weixin` in `mini-program` - [x] Backend tests pass. - [x] Backend package succeeds. - [x] All four frontend builds succeed. - [x] Source scan shows no client-side external AI provider key or direct Dify/Coze/OpenRouter call. - [x] Database scene bindings are enabled with streaming endpoints for `chat`, `script_generate`, `short_story_generate`, `diary_summary`, `emotion_summary`, `emotion_analysis`, and `life_healing`.