LazyBoy2/README.md

134 lines
11 KiB
Markdown
Raw Normal View History

2026-09-15 05:20:44 +00:00
# LazyBoy
2026-09-13 16:38:32 +00:00
A local, general-purpose **GrokBot-like CLI agent**. It observes the environment, chooses tools, adapts to results, and verifies its work. Uses your existing xAI/OpenAI-compatible model configuration; no separate search API key.
2026-09-13 16:38:32 +00:00
For action tasks the agent briefly explains its approach, then starts. Multi-stage tasks get a short live plan. You can add instructions while it works, answer a question, or interrupt and resume. Simple questions remain simple answers.
2026-09-13 16:38:32 +00:00
## Start
```bash
2026-09-15 05:20:44 +00:00
# 可設項目與說明:複製 .env.example 成 .env 後填 LAZYBOY_API_KEY
2026-09-15 03:20:42 +00:00
# make start 會載入 .env
2026-09-15 05:20:44 +00:00
export LAZYBOY_API_KEY=your_key # or XAI_API_KEY
cargo run -p lazyboy -- agent
2026-09-14 09:08:35 +00:00
# API daemon (named Agents) + HTTP on :8787
2026-09-15 05:20:44 +00:00
cargo run -p lazyboy -- serve
2026-09-14 09:08:35 +00:00
# Independent frontend:
cd web && npm install && npm run dev
2026-09-15 05:20:44 +00:00
# Production UI: npm run build then lazyboy serve hosts web/dist
2026-09-14 09:08:35 +00:00
# Phone: same Wi-Fi, open the printed LAN URL, Add to Home Screen
2026-09-13 16:38:32 +00:00
# One-shot:
2026-09-15 05:20:44 +00:00
cargo run -p lazyboy -- run "整理目前目錄的資料,產生報告並讀回驗證"
2026-09-13 16:38:32 +00:00
# Resume:
2026-09-15 05:20:44 +00:00
cargo run -p lazyboy -- agent --session <id>
cargo run -p lazyboy -- run --session <id> "繼續"
```
2026-09-13 16:38:32 +00:00
While running, enter additional instructions to steer the next step. **Ctrl-C** or **`/stop`** stops the turn and saves its state. In the REPL, `/plan` shows the current plan, `/session` shows its ID, and `/exit` or `/quit` exits when idle. During work `/exit` and `/quit` stop the current turn first. At an explicit question, new text answers that question. Already queued idle inputs remain separate tasks.
2026-09-15 05:20:44 +00:00
Progress, plans and questions go to stderr; final answers go to stdout. `lazyboy chat` remains streaming chat without tools. `lazyboy web` serves the Grok Bot-shaped conversation UI (sidebar, bubbles, composer, **我的電腦** overlay) as a phone-installable PWA. `lazyboy help` lists commands and settings.
2026-09-13 16:38:32 +00:00
## Persistent agents and background work
2026-09-15 05:20:44 +00:00
Run `lazyboy serve` in one terminal, then create identities with `lazyboy agents create <name>` and open separate chats with `lazyboy agent --name <name>`. Agents learn private memories and public expertise from their conversations. They can delegate to an existing agent or create a temporary worker while you keep chatting.
2026-09-13 16:38:32 +00:00
In named-agent mode, ordinary text is new chat. Use `/tasks` and `/task <id> say|stop|resume` to manage background work. Closing a chat leaves the service and its tasks running. Agent identity and task ownership are separate: one agent can help another without losing its own conversation.
2026-09-15 05:20:44 +00:00
See [team setup and behavior](docs/TEAM.md) for commands, budgets, privacy boundaries and recovery. `LAZYBOY_DATA_DIR` defaults to `~/.lazyboy/team`; existing single-session commands keep their original behavior.
2026-09-13 16:38:32 +00:00
## Tools
2026-09-13 16:38:32 +00:00
| Capability | Tools |
| --- | --- |
2026-09-14 09:08:35 +00:00
| Voice | `send_message` (only user-visible channel; widget asks a question) |
| Progress and planning | `report_progress` (alias of send_message text), `update_plan` |
2026-09-13 16:38:32 +00:00
| Human interaction | `request_user_input`, `request_user_confirm`, `browser_handoff` |
2026-09-14 09:08:35 +00:00
| Completion | No-tool response ends the turn. `report_done` is optional. `report_blocked` when stuck. |
| Explicit local commands | `external_exec_command` (backgrounds after `block_until_ms`, default 30s), `external_await_command`, `external_write_stdin`, `external_shell` |
| Explicit local files | `external_list_dir`, `external_read_file`, `external_edit_file`, `external_write_file`, `external_grep` (regex), `external_glob`, `external_search_files` (literal) |
2026-09-14 09:13:10 +00:00
| Web | `web_fetch` (direct anonymous HTTP GET, HTML → text, short cache), `web_search` (remote search service); no browser login; Docker browser for login-gated pages |
2026-09-14 09:08:35 +00:00
| Background | `spawn_subagent` (returns immediately; `kind=computerUse` for desktop GUI), `check_subagent`, `message_subagent`, `stop_subagent`. Subagents and external command completion revive the turn; observe detached box commands with `await_shell`. |
2026-09-16 06:40:00 +00:00
| Desktop GUI | Parent: `screenshot` (read-only). Clicks: `spawn_subagent kind=computerUse`, which gets `computer` (screenshot/click/move/drag/type/key/scroll/wait via xdotool on `DISPLAY=:1`). One computerUse per agent computer. Passwords still `request_box_help`. |
2026-09-15 05:20:44 +00:00
| MCP | `get_mcp_tools`, `call_mcp_tool`, `get_mcp_server_status`, `add_mcp_server`, `remove_mcp_server`. Config: `~/.lazyboy/mcp.json` (or `LAZYBOY_MCP_CONFIG`). Prefer a connector over the browser for that service. |
2026-09-16 06:40:00 +00:00
| My computer (box) | Docker Linux desktop (XFCE + **Chromium** + 終端機 + xdotool). Named agents each get their own container; opening an agent starts it and the UI confirms ready/error. Session CLI keeps `lazyboy-box`. Default tools: `shell`, `read`, `await_shell`, `screenshot`. Profile: `/home/box/chrome-profile` on that seat. Viewer`lazyboy computer` or the agent overlay. |
2026-09-13 16:38:32 +00:00
| Browser observation | `browser_navigate`, `browser_snapshot`, `browser_read_page`, `browser_tabs` |
| Browser actions | `browser_click`, `browser_type`, `browser_press`, `browser_select`, `browser_scroll`, `browser_wait` |
| Browser file exchange | `browser_upload`, `browser_download` |
| Browser fallback | `browser_eval` |
2026-09-15 05:20:44 +00:00
Long commands return a session ID and incremental output; `external_write_stdin` polls, sends input, closes stdin or terminates the command. One foreground command at a time, piped I/O, default ten-minute deadline. The explicit local `external_shell` retains its 30-second limit. Default `shell` runs on the box and continues in the background when its foreground wait expires; use `await_shell` to observe it. Full command output is saved under `.lazyboy-output/`; large tool results are also stored there with a readable preview and path.
2026-09-14 09:08:35 +00:00
`external_read_file` accepts a zero-based line `offset` and line `limit`; `external_search_files` searches names or literal content; `external_edit_file` requires one unique exact match. File tools and browser file exchange check workspace paths and symlinks. Only `external_*` tools operate on the local machine; `shell` and `read` use the box.
2026-09-14 09:08:35 +00:00
## Browser surfaces
Docker mode includes Node, Playwright and Chromium in the image. The following setup is only for the explicit legacy local browser:
```bash
2026-09-15 05:20:44 +00:00
export LAZYBOY_BROWSER_SURFACE=local
2026-09-13 16:38:32 +00:00
cd tools/playwright
npm install
npx playwright install chromium
cd ../..
2026-09-15 05:20:44 +00:00
export LAZYBOY_BROWSER_HEADED=1 # visible browser, convenient for login handoff
cargo run -p lazyboy -- agent
```
2026-09-15 05:20:44 +00:00
Browser tools now default to **Docker Chromium**, attached to the desktop browser at `/home/box/chrome-profile`. Automation and human login share this profile; browser uploads/downloads use `/workspace` paths and explicit `copy_to_box`/`copy_from_box` transfer files. `browser_release` disconnects automation without closing the desktop. The old local browser is available only with `LAZYBOY_BROWSER_SURFACE=local`; its owner profiles are preserved and are not merged into Docker. See [surface comparison](docs/SURFACES.md) for differences and configuration.
2026-09-14 09:08:35 +00:00
2026-09-15 05:20:44 +00:00
`web_fetch` is a direct anonymous HTTP GET from the host: browser-like headers, no cookies, public hosts only (redirects are re-checked), body capped at 2 MiB, HTML reduced to readable text with link footnotes, non-UTF-8 charsets decoded, and results cached for ten minutes per URL. Only when a site refuses plain HTTP (401/403/429/503, or an empty JavaScript shell) and the model configuration is official xAI does it fall back to xAI native browsing; that result is marked `content_kind=model_rendered_web_content` and carries `fallback_reason`. `web_search` uses a remote search service with no browser cookies: official xAI configuration reuses the existing model API key for native web search; for the reconstructed AiService contract, set `LAZYBOY_WEB_BACKEND_URL` and, when required, `LAZYBOY_WEB_TOKEN`. That gateway must provide the reconstructed `RunWebSearch` JSON contract; a normal OpenAI-compatible chat endpoint alone does not provide it. Missing search configuration produces an explicit error, never a hidden browser fallback.
2026-09-14 09:08:35 +00:00
For login, OTP or captcha, `browser_handoff` shows the Docker viewer URL and parks the turn until you reply. For irreversible public actions, the agent follows the existing explicit-approval rule; plans themselves do not require approval.
2026-09-13 16:38:32 +00:00
## Settings
2026-09-13 16:38:32 +00:00
| Environment variable | Default / meaning |
| --- | --- |
2026-09-15 05:20:44 +00:00
| `LAZYBOY_API_KEY` | Falls back to `XAI_API_KEY`, then `OPENAI_API_KEY` |
| `LAZYBOY_BASE_URL` | `https://api.x.ai/v1`; fallback `OPENAI_BASE_URL` |
| `LAZYBOY_MODEL` | `grok-4.6` |
| `LAZYBOY_MAX_ROUNDS_TOTAL` | 5000 model steps **per user turn** (Grok Bot Sand-style). A step with no tool calls ends the turn. |
| `LAZYBOY_MAX_ROUNDS` | 12; local progress interval, no extra model calls |
| `LAZYBOY_CONTEXT_CHARS` | 100000 approximate UTF-8 bytes; legacy name |
| `LAZYBOY_SESSIONS_DIR` | `~/.lazyboy/sessions` |
| `LAZYBOY_PROGRESS` | `0` silences progress, but not questions |
| `LAZYBOY_BROWSER_HEADED` | `1` launches visible Chromium |
| `LAZYBOY_CONFIRM_AUTO` | Test-only approval/denial override; falls back to `LAZYBOY_HANDOFF_AUTO` |
| `LAZYBOY_HANDOFF_AUTO` | Test-only handoff override: `1` resume, `abort` deny |
2026-09-14 09:08:35 +00:00
Session stop reasons: `answer` (no tool calls — the Grok Bot end condition), `done` (optional `report_done`), `blocked`, `budget_exhausted`, `failed`, `cancelled`. One-shot exits 0 for answer/done, 1 for blocked/budget/failed, 130 for cancellation. The REPL remains usable after any turn outcome. Delivery is `send_message`; a no-tool response is not independent proof of arbitrary task correctness.
2026-09-15 03:20:42 +00:00
## Latency diagnostics
2026-09-15 05:20:44 +00:00
Set `LAZYBOY_TIMING=1` when starting the process to print elapsed milliseconds to
2026-09-15 03:20:42 +00:00
stderr for request preparation, model-slot queues, model rounds (including queue
wait), tool execution, and whole agent turns. These nested measurements must not
be added together. They contain no prompts, tool arguments, or credentials;
concurrent turns can interleave. Compare the same task and session length, and
count model rounds as well as wall time. This does not enable extra model calls.
Memory extraction starts only when no foreground chat is active and both
background slots are free; it acquires capacity without queuing. Deferred memory
remains durable and is retried by the scheduler. Already-running extraction is
allowed to finish, and continuous activity can delay memory updates. Work and
completion rules are unchanged: acknowledgement is not completion, required
results must still be observed, and sending a message alone does not end a turn.
2026-09-13 16:38:32 +00:00
## Validation
```bash
2026-09-13 16:38:32 +00:00
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
2026-09-15 05:20:44 +00:00
cargo build -p lazyboy
2026-09-13 16:38:32 +00:00
python3 tests/cli_flow.py
python3 tests/runtime_flow.py # includes a real 31-second command + local Chromium
python3 tests/browser_flow.py # headless Chromium, local fixture only
python3 tests/team_flow.py # daemon, two CLI clients, mock API + Chromium
2026-09-15 05:20:44 +00:00
cargo run -p lazyboy -- smoke
2026-09-13 16:38:32 +00:00
# Opt-in: uses your existing paid model configuration, max 12 requests:
python3 tests/live_cli.py
python3 tests/live_team.py # opt-in team workflow, root task ceiling 16
```
2026-09-13 16:38:32 +00:00
Design and Codex references: [CLI flow](docs/CLI-FLOW.md). Product scope: [PRODUCT](docs/PRODUCT.md). Acceptance scenarios: [ACCEPTANCE](docs/ACCEPTANCE.md). Older scenario playbooks remain optional examples, not hardcoded workflows: [scenarios](docs/scenarios/README.md).