364 lines
14 KiB
Markdown
364 lines
14 KiB
Markdown
# sgClaw Floating Chat Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Replace the current debug-style `sgclaw-chat` page as the primary UX with a floating page button + popup chat window, add real multi-turn conversation support, and harden the DeepSeek/browser tool protocol so browser automation is stable.
|
|
|
|
**Architecture:** Keep `chrome://superrpa-functions/sgclaw-chat` and `chrome://superrpa-functions/sgclaw-config` as debug/config pages, but make the user-facing entry a floating page launcher injected into allowed HTTP/HTTPS pages via existing SuperRPA page-injection capabilities. Reuse the browser-side persistent `SgClawSessionService` as the session owner, extend it from “logs + final result” to “conversation + runtime state”, and extend the sgClaw pipe path so each submit can carry conversation context instead of behaving like a fresh one-shot task. Fix protocol bugs in parallel: strict action-schema validation, better browser/sgClaw error attribution, and DeepSeek tool-call history compatibility.
|
|
|
|
**Tech Stack:** Chromium WebUI + Lit, existing SuperRPA page injection (`sg_compat.js` / hook injection), browser-side `FunctionsUI`/`SgClawSessionService`, Rust `sgClaw`, ZeroClaw compatibility runtime, DeepSeek OpenAI-compatible chat API.
|
|
|
|
### Task 1: Freeze Current Baseline And Add Pure UI State Tests
|
|
|
|
**Files:**
|
|
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-floating_state.ts`
|
|
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-floating_state_mainline_unittest.ts`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/BUILD.gn`
|
|
|
|
**Step 1: Write the failing test**
|
|
|
|
Write a pure state test that describes the floating UX:
|
|
|
|
```ts
|
|
import {
|
|
collapseFloatingWindow,
|
|
createFloatingViewState,
|
|
openFloatingWindow,
|
|
toggleSettingsPanel,
|
|
} from './sgclaw-floating_state.js';
|
|
|
|
test('opens from fab and collapses back on blur', () => {
|
|
let state = createFloatingViewState();
|
|
state = openFloatingWindow(state);
|
|
expect(state.windowOpen).toBe(true);
|
|
state = collapseFloatingWindow(state);
|
|
expect(state.windowOpen).toBe(false);
|
|
expect(state.fabVisible).toBe(true);
|
|
});
|
|
```
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease sgclaw-chat_build_ts`
|
|
|
|
Expected: build/test target fails because the new state module and test do not exist yet.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Create a small pure state module with:
|
|
- `fabVisible`
|
|
- `windowOpen`
|
|
- `settingsOpen`
|
|
- `statusBadge`
|
|
- `unreadCount`
|
|
|
|
Keep it logic-only; no DOM code here.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run the same `autoninja` target or the relevant TS unit target once wired.
|
|
|
|
Expected: the new state test compiles and passes.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git -C /home/zyl/projects/superRpa/src add \
|
|
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-floating_state.ts \
|
|
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-floating_state_mainline_unittest.ts \
|
|
chrome/browser/resources/superrpa/devtools/BUILD.gn
|
|
git -C /home/zyl/projects/superRpa/src commit -m "test: add sgclaw floating UI state"
|
|
```
|
|
|
|
### Task 2: Build The Floating Page Entry Using Existing SuperRPA Overlay Capabilities
|
|
|
|
**Files:**
|
|
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/sgclaw_overlay.js`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/sg_compat.js`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/hooks/hook_injector.cc`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/hooks/hook_injector.h`
|
|
- Test: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_chat_smoke.mjs`
|
|
|
|
**Step 1: Write the failing smoke expectation**
|
|
|
|
Update the browser smoke so it expects:
|
|
- a floating button exists on a normal page
|
|
- clicking it opens the sgClaw popup
|
|
- clicking outside collapses the popup back to the button
|
|
|
|
Use an assertion like:
|
|
|
|
```js
|
|
await waitFor(() => page.evaluate(() =>
|
|
!!document.querySelector('#superrpa-sgclaw-fab')));
|
|
```
|
|
|
|
**Step 2: Run smoke to verify it fails**
|
|
|
|
Run: `node /home/zyl/projects/sgClaw/claw/tools/browser_smoke/run_deepseek_browser_smoke.mjs`
|
|
|
|
Expected: smoke fails because the floating entry does not exist.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Implement the launcher inside injected page JS, not a side panel:
|
|
- floating circular button in bottom-right
|
|
- popup window anchored to the button
|
|
- button actions: open chat, stop/start runtime, open settings
|
|
- blur/outside-click collapses popup back to button
|
|
|
|
Prefer reusing the existing SuperRPA overlay/dialog/message primitives in `sg_compat.js` instead of inventing a second overlay stack.
|
|
|
|
**Step 4: Run smoke to verify it passes**
|
|
|
|
Run the same smoke command.
|
|
|
|
Expected: smoke reaches the popup, submits a task, and collapses correctly after blur.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git -C /home/zyl/projects/superRpa/src add \
|
|
chrome/browser/resources/superrpa/sgclaw_overlay.js \
|
|
chrome/browser/resources/superrpa/sg_compat.js \
|
|
chrome/browser/superrpa/hooks/hook_injector.cc \
|
|
chrome/browser/superrpa/hooks/hook_injector.h \
|
|
chrome/browser/superrpa/sgclaw/sgclaw_chat_smoke.mjs
|
|
git -C /home/zyl/projects/superRpa/src commit -m "feat: add sgclaw floating launcher"
|
|
```
|
|
|
|
### Task 3: Upgrade Browser Session State From “Result Page” To “Real Conversation”
|
|
|
|
**Files:**
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.h`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui.h`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui.cc`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts`
|
|
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_messages.ts`
|
|
- Test: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc`
|
|
|
|
**Step 1: Write the failing browser-side tests**
|
|
|
|
Add tests for:
|
|
- conversation messages are returned by `sgclawConnect`
|
|
- reopening the chat keeps prior user/assistant turns
|
|
- `sgclawSubmitTask` appends a user turn immediately and an assistant turn when complete
|
|
|
|
Example expectation:
|
|
|
|
```cc
|
|
EXPECT_EQ("user", FindStringValue(*message, "role"));
|
|
EXPECT_EQ("打开百度搜索天气", FindStringValue(*message, "content"));
|
|
```
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease \
|
|
functions_ui_mainline_unittests
|
|
./out/KylinRelease/functions_ui_mainline_unittests
|
|
```
|
|
|
|
Expected: tests fail because runtime state only has logs/final result.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Extend `SgClawSessionService` to store:
|
|
- conversation id
|
|
- ordered messages
|
|
- pending assistant reply state
|
|
- runtime status/logs
|
|
|
|
Keep the debug page and popup both consuming the same runtime shape.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run the same test command.
|
|
|
|
Expected: connect/reopen behavior passes and conversation persists while browser stays open.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git -C /home/zyl/projects/superRpa/src add \
|
|
chrome/browser/ui/webui/superrpa/sgclaw_session_service.h \
|
|
chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc \
|
|
chrome/browser/ui/webui/superrpa/functions_ui.h \
|
|
chrome/browser/ui/webui/superrpa/functions_ui.cc \
|
|
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts \
|
|
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_messages.ts \
|
|
chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc
|
|
git -C /home/zyl/projects/superRpa/src commit -m "feat: persist sgclaw conversation state"
|
|
```
|
|
|
|
### Task 4: Extend sgClaw Submit Protocol For Multi-Turn Context
|
|
|
|
**Files:**
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_pipe_protocol.h`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_pipe_protocol.cc`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_process_host.cc`
|
|
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/src/pipe/protocol.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/src/agent/mod.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
|
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
|
- Test: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_process_host_mainline_unittest.cc`
|
|
|
|
**Step 1: Write the failing protocol tests**
|
|
|
|
Add tests that `submit_task` can carry:
|
|
- current user input
|
|
- prior user/assistant turns
|
|
- active page URL / title hints if needed
|
|
|
|
For Rust, add a test that two consecutive submits produce a provider request containing prior turns.
|
|
|
|
**Step 2: Run tests to verify they fail**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
python3 /home/zyl/projects/superRpa/src/tools/crates/run_cargo.py test \
|
|
--manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml --test compat_runtime_test
|
|
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease \
|
|
sgclaw_process_host_mainline_unittests
|
|
./out/KylinRelease/sgclaw_process_host_mainline_unittests \
|
|
--gtest_filter='SgClawProcessHostMainlineTest.*'
|
|
```
|
|
|
|
Expected: tests fail because submit currently only sends a raw instruction string.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Change the pipe payload from one-shot instruction to:
|
|
|
|
```json
|
|
{
|
|
"type": "submit_task",
|
|
"instruction": "...",
|
|
"messages": [
|
|
{"role": "user", "content": "..."},
|
|
{"role": "assistant", "content": "..."}
|
|
]
|
|
}
|
|
```
|
|
|
|
On the Rust side, feed this history into the ZeroClaw turn so the next submit is a continuation, not a new session.
|
|
|
|
**Step 4: Run tests to verify they pass**
|
|
|
|
Run the same Rust + browser unit commands.
|
|
|
|
Expected: previous-turn context reaches the provider path.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git -C /home/zyl/projects/sgClaw/claw add \
|
|
src/pipe/protocol.rs src/agent/mod.rs src/compat/runtime.rs tests/compat_runtime_test.rs
|
|
git -C /home/zyl/projects/sgClaw/claw commit -m "feat: carry conversation history through sgclaw pipe"
|
|
|
|
git -C /home/zyl/projects/superRpa/src add \
|
|
chrome/browser/superrpa/sgclaw/sgclaw_pipe_protocol.h \
|
|
chrome/browser/superrpa/sgclaw/sgclaw_pipe_protocol.cc \
|
|
chrome/browser/superrpa/sgclaw/sgclaw_process_host.cc \
|
|
chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc \
|
|
chrome/browser/superrpa/sgclaw/sgclaw_process_host_mainline_unittest.cc
|
|
git -C /home/zyl/projects/superRpa/src commit -m "feat: send sgclaw conversation context"
|
|
```
|
|
|
|
### Task 5: Harden Tool Schema And DeepSeek Compatibility
|
|
|
|
**Files:**
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/browser_tool_adapter.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_browser_tool_test.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
|
- Modify: `/home/zyl/projects/sgClaw/claw/tools/browser_smoke/run_deepseek_browser_smoke.mjs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Cover:
|
|
- `getText` without `selector` is rejected before it hits the browser
|
|
- `click` without `selector` is rejected
|
|
- `navigate` without `url` is rejected
|
|
- DeepSeek multi-round tool-call history does not trigger the `role=tool` 400 anymore
|
|
- non-task greeting behavior is explicit: either reject or answer in chat-only mode, but not silently pretend to be a browser task
|
|
|
|
**Step 2: Run tests to verify they fail**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
python3 /home/zyl/projects/superRpa/src/tools/crates/run_cargo.py test \
|
|
--manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml --lib --tests
|
|
node /home/zyl/projects/sgClaw/claw/tools/browser_smoke/run_deepseek_browser_smoke.mjs
|
|
```
|
|
|
|
Expected: current code allows incomplete tool args and still has DeepSeek history edge cases.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Implement:
|
|
- action-specific required param validation in `browser_tool_adapter.rs`
|
|
- better tool-result/history formatting if needed for DeepSeek compatibility
|
|
- explicit user-facing handling for non-browser-chat input
|
|
|
|
**Step 4: Run tests to verify they pass**
|
|
|
|
Run the same Rust tests and browser smoke.
|
|
|
|
Expected: no malformed tool actions, no DeepSeek `role=tool` 400 in smoke.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git -C /home/zyl/projects/sgClaw/claw add \
|
|
src/compat/browser_tool_adapter.rs \
|
|
src/compat/runtime.rs \
|
|
tests/compat_browser_tool_test.rs \
|
|
tests/compat_runtime_test.rs \
|
|
tools/browser_smoke/run_deepseek_browser_smoke.mjs
|
|
git -C /home/zyl/projects/sgClaw/claw commit -m "fix: harden sgclaw tool protocol for DeepSeek"
|
|
```
|
|
|
|
### Task 6: Final Verification And Manual Smoke Checklist
|
|
|
|
**Files:**
|
|
- Modify if needed: `/home/zyl/projects/superRpa/src/chrome/browser/superrpa/sgclaw/sgclaw_chat_smoke.mjs`
|
|
- Document manual steps in PR/summary, not code
|
|
|
|
**Step 1: Run automated verification**
|
|
|
|
```bash
|
|
python3 /home/zyl/projects/superRpa/src/tools/crates/run_cargo.py test \
|
|
--manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml --lib --tests
|
|
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease \
|
|
functions_ui_mainline_unittests \
|
|
sgclaw_process_host_mainline_unittests
|
|
./out/KylinRelease/functions_ui_mainline_unittests
|
|
./out/KylinRelease/sgclaw_process_host_mainline_unittests \
|
|
--gtest_filter='SgClawProcessHostMainlineTest.*'
|
|
node /home/zyl/projects/sgClaw/claw/tools/browser_smoke/run_deepseek_browser_smoke.mjs
|
|
```
|
|
|
|
Expected: all pass.
|
|
|
|
**Step 2: Manual smoke**
|
|
|
|
1. Open a normal HTTP/HTTPS page.
|
|
2. Verify the floating button appears.
|
|
3. Click to open popup.
|
|
4. Start sgClaw from popup.
|
|
5. Submit one browser task and one follow-up task.
|
|
6. Click outside popup and verify it collapses to the button.
|
|
7. Reopen popup and verify conversation history is still present.
|
|
8. Open settings from the launcher, update model/base URL, return to popup, submit again, and verify hot update.
|
|
|
|
**Step 3: Final commit if verification requires touch-ups**
|
|
|
|
Use focused commit messages only for actual fixes found during verification.
|