# GrokBoy product notes **North star:** a local **Grok Bot–like** agent — thin CLI core, tool-using ReAct loop, optional Playwright **DOM** browser (not screenshot-first). GrokBoy is the sole main line; LazyBoy is reference only (no fork). ## Done (P0–P6) | Phase | What | |-------|------| | **P0** | Streaming chat CLI (`grokboy chat`), xAI/OpenAI-compatible API | | **P1** | Tools + ReAct (`shell`, files), sessions under `~/.grokboy/sessions/` | | **P2** | Completion contract (`report_done` / `report_blocked`), loop guard, context truncation | | **P3** | Optional Playwright DOM tools: navigate / snapshot / click / type / eval (fail-closed) | | **P4** | Human browser handoff (`browser_handoff`) for login / OTP / captcha | | **P5** | Interactive multi-turn agent REPL (`grokboy agent`) with tools + session persist | | **P6** | Scenario playbooks + `request_user_confirm` (confirm-before-post) | ## P5 — Interactive multi-turn agent Gap after P4: `chat` streams but has no tools; `run` has tools but is one-shot. P5 adds **`grokboy agent`**: 1. REPL reads a user line (ignore empty; `/exit` `/quit` leave; `/session` prints id). 2. Each turn runs the **same** ReAct loop as `run` (tools + handoff inherited). 3. Prints the verdict / assistant answer; **saves** under `~/.grokboy/sessions/` after every turn. 4. `--session ` resumes; omitting id auto-creates and prints the session id. 5. `chat` stays streaming no-tools; `run` stays one-shot. ### Env - `GROKBOY_BROWSER_HEADED=1` — always launch Chromium headed (recommended for `run` / `agent` when handoff is likely). - `GROKBOY_HANDOFF_AUTO=1` — auto-resume (tests / CI); `abort` to auto-abort. ### Non-goals (this slice) - Multi-agent orchestration - Desktop accessibility / native UI automation - External connectors / SaaS integrations - Forking LazyBoy or Codex - Turning `chat` into a tools REPL (kept simple on purpose) ### Acceptance (summary) See `docs/ACCEPTANCE.md` section P5. ## P6 — Scenario playbooks + confirm-before-post **Capability:** reusable **scenario playbooks** for Grok Bot–style acceptance — not a single vertical hardcode. Pattern: 1. **Phase A** — research + draft on a source portal (**no** irreversible publish) 2. Human only for: auth `browser_handoff` + final confirm 3. **Phase B** — publish to target channel **only** after explicit approval **Product primitive:** `request_user_confirm` (bilingual stdin gate; `GROKBOY_CONFIRM_AUTO` for tests, falls back to `GROKBOY_HANDOFF_AUTO`). AGENT_SYSTEM forbids irreversible public social posts without (a) explicit user approval this turn of the exact draft, or (b) confirm → approved. Prefer draft → confirm → act; prefer `browser_handoff` only for auth walls. **Docs:** [`docs/scenarios/README.md`](scenarios/README.md) (可推廣 pattern), [`docs/SCENARIO-TEMPLATE.md`](SCENARIO-TEMPLATE.md), `prompts/templates/`. **Example only (範例,非唯一路徑):** Shopee Affiliate → Threads — [`docs/scenarios/examples/shopee-threads-affiliate.md`](scenarios/examples/shopee-threads-affiliate.md) + `prompts/examples/shopee-threads-phase-*.txt`. ### Env (P6) - `GROKBOY_CONFIRM_AUTO=1` — auto-approve confirm (tests); `abort` to deny - Falls back to `GROKBOY_HANDOFF_AUTO` when CONFIRM_AUTO unset - `GROKBOY_BROWSER_HEADED=1` — required for real cookie/auth scenarios ### Acceptance (summary) See `docs/ACCEPTANCE.md` section P6. ## P7 slice — agent UX polish (chat / max-rounds / blocked recovery) Small product UX fixes (not a full phase): 1. **Natural chat answers** — `AGENT_SYSTEM` prefers plain assistant text for greetings / small talk / no-tools; `report_done` only after a real tool workflow; `report_blocked` when stuck. 2. **Max-rounds progress summary** — hitting `GROKBOY_MAX_ROUNDS` (default 12) triggers one final no-tools completion asking for a concise progress summary (Traditional Chinese welcome); that text becomes the Blocked message (`blocked: reached max rounds (N). Progress so far:\n…`). Falls back to the bare max-rounds string if the summary call fails. 3. **Blocked recovery hint** — `run` / `agent` eprintln a Traditional Chinese tip to continue with a shorter concrete instruction (session kept; do not paste the blocked blob back). ### Env - `GROKBOY_MAX_ROUNDS` — ReAct tool rounds **per chunk** (default 12; `DEFAULT_MAX_ROUNDS`). ## P8 — auto-continue chunks like Grok Bot Long legitimate work should **not** hard-stop at max rounds with only `blocked: max rounds` waiting for the user to paste a recovery command. Match real Grok Bot: keep going, post progress beats, fail-closed only when truly stuck. 1. **`GROKBOY_MAX_ROUNDS`** (default 12) = rounds **per chunk** (one progress beat). 2. When a chunk ends without `report_done` / `report_blocked` / final Answer → short progress summary (no-tools) → **auto-continue** another chunk in the **same** `run_agent` invocation. 3. **Stop conditions:** completion tools / empty-tools Answer; identical-tool loop guard ×3 (no continue); absolute ceiling **`GROKBOY_MAX_ROUNDS_TOTAL`** (default 48) → Blocked with progress + total-budget-exhausted note. 4. Progress on stderr (always on unless `GROKBOY_PROGRESS=0`): live beats so the terminal is never blank during API/tool waits — `〔開始〕`, `〔思考中〕`, `〔工具〕`, `〔完成〕`/`〔失敗〕`, `〔進度|尚未完成〕〔續跑〕…`, `〔結束〕`. 5. Blocked recovery hint only when truly stopped (loop guard or total ceiling), not after every chunk. ### Live terminal progress + conclusion only when done - Mid-task: runtime shows where work is (`做到哪`); do **not** treat chunk progress as the user-facing final answer. - `AGENT_SYSTEM`: no `report_done` / final wrap-up until the task is actually complete; mid-flight plain text must be labeled partial — prefer continuing tools. - CLI `run` / `agent`: final Done/Answer printed as blank line + `〔結論〕…`; Blocked keeps recovery hint. Progress stays on stderr. ### Env (P8) - `GROKBOY_MAX_ROUNDS` — rounds per chunk (default 12) - `GROKBOY_MAX_ROUNDS_TOTAL` — absolute ceiling (default 48) - `GROKBOY_PROGRESS=0` — silence all live progress lines on stderr ## Roadmap hint (later) Later may deepen session UX further, richer browser persistence across process restarts, or more tools — still thin core, DOM-first browser, playbook-driven acceptance.