mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 21:05:09 +00:00
* feat(openclaw): add foundation — paths constant, browseros-dir helper, static compose file Add OPENCLAW_DIR_NAME to shared paths constant, getOpenClawDir() to browseros-dir.ts, and a static docker-compose.yml resource file that uses native .env variable substitution instead of YAML template strings. * feat(openclaw): add PodmanRuntime container engine abstraction Manages Podman CLI interactions: machine lifecycle (init/start/stop), availability checks, command execution with streaming output, and running container enumeration. Linux skips machine ops since Podman runs natively. * feat(openclaw): add config builder and container runtime openclaw-config.ts: pure functions to build openclaw.json and .env files from BrowserOS settings. Maps provider keys, sets permissive defaults (full exec, cron, web search, MCP bridge to BrowserOS). container-runtime.ts: compose-level abstraction over PodmanRuntime for the browseros-openclaw project. Handles up/down/restart/pull, health checks, .env file writes, and safe machine shutdown. * feat(openclaw): add OpenClawService orchestrator Main service managing the single OpenClaw container. Handles full lifecycle (setup/start/stop/restart/shutdown), agent CRUD with config rewrites and gateway restarts, chat proxy to /v1/chat/completions, provider key updates, auto-start on BrowserOS boot, and status reporting. * feat(openclaw): add API routes and server wiring Add /api/claw/* routes for container lifecycle (setup/start/stop/restart), agent CRUD (list/create/delete), chat proxy with SSE streaming, provider key management, and log retrieval. Register routes in server.ts, add OpenClaw auto-start on BrowserOS boot and graceful shutdown in main.ts. * fix(openclaw): resolve type errors in service and podman runtime Fix TIMEOUTS.TOOL_EXECUTION → TIMEOUTS.TOOL_CALL to match shared constants. Fix ReadableStream undefined/null type mismatch in PodmanRuntime.runCommand stream draining. * feat(openclaw): add agents page UI with chat, create, and lifecycle controls Add /agents route with AgentsPage showing OpenClaw status, agent list, create dialog, and per-agent chat. Includes useOpenClaw hook for server communication, AgentChat component with SSE streaming, and sidebar navigation entry. * feat(openclaw): add provider selector to setup flow Add LLM provider selector using useLlmProviders hook. Filters out OAuth-only providers, pre-selects the user's default, and passes providerType/apiKey/modelId to the setup endpoint so OpenClaw gets a working LLM configuration on first setup. * feat(openclaw): per-agent provider selection Each agent can now have its own LLM provider. The Create Agent dialog includes a provider selector that passes providerType/apiKey/modelId to the backend. The service writes per-agent model config to openclaw.json and merges the API key into the container's .env file. * fix(openclaw): write gateway auth token to openclaw.json The gateway was returning 401 because auth.mode was set to "token" without providing the actual token value. Now the token is written to gateway.auth.token in openclaw.json so the gateway and our chat proxy agree on the same token. * feat(openclaw): add GatewayClient WebSocket RPC client Persistent WS client for the OpenClaw Gateway protocol. Handles the challenge → connect → hello-ok handshake (as openclaw-control-ui with operator.admin scope), JSON-RPC with pending map + timeouts, and auto-reconnect. Exposes typed methods for agents.list, agents.create, agents.delete, and health. * refactor(openclaw): simplify config to bootstrap-only, add /readyz health Config no longer contains agents.list — agent CRUD is handled via WS RPC. buildOpenClawConfig → buildBootstrapConfig, removed makeAgentEntry and AgentEntry (agents managed by OpenClaw runtime). Added isReady() and waitForReady() using /readyz for gateway readiness checks. * refactor(openclaw): agent CRUD via WS RPC, per-agent chat targeting Replace JSON mutation + restart with GatewayClient WS RPC calls for agents.create, agents.delete, agents.list. Chat proxy now uses model: "openclaw/<agentId>" for per-agent targeting. Setup writes bootstrap config once then creates "main" agent via WS after gateway starts. Container restarts only when a new provider env var is added. * fix(openclaw): use agentId field in setup response mapping Fix type error: GatewayAgentEntry uses agentId not id. * fix(openclaw): log service progress through server logger * feat(openclaw): WS streaming, device auth, MCP port fix (#687) * feat(openclaw): WS streaming, device auth, MCP port fix - Fix GatewayClient WS handshake: add Ed25519 device identity signing, Origin header, mode: cli (mode: ui requires device identity always) - Add auto device pairing flow: generate client identity, attempt WS connect (triggers pending), approve via openclaw CLI, reconnect - Replace HTTP /v1/chat/completions proxy with WS-based streaming that surfaces tool calls, thinking blocks, and text deltas - Add chatStream() to GatewayClient returning ReadableStream of typed OpenClawStreamEvent (text-delta, thinking, tool-start/end, lifecycle) - Update chat route to stream WS events as SSE to the extension - Pass actual server port to OpenClaw config (fixes MCP bridge in dev) - Rewrite AgentChat.tsx with turn-based model using Message/MessageContent components matching sidepanel pattern, with tool batching logic that groups consecutive tools and breaks on text/thinking (same as sidepanel) - Add execInContainer() to ContainerRuntime for CLI commands - Fix gateway response field mapping (id→agentId, agents.list/create) - Skip creating main agent if gateway auto-creates it * fix(openclaw): retry WS connect on signature expired (Podman clock skew) Podman VM clock drifts when Mac sleeps, causing Ed25519 signature validation to fail with "device signature expired" on auto-start. Add connectGatewayWithRetry() that restarts the container (resyncs clock) and re-approves the device if needed. * fix(openclaw): address PR review — stream cleanup, error handling - Fix silent catch in setup(): only swallow "pairing required" and "signature expired" errors, re-throw everything else - Guard JSON.parse in approvePendingDevice(): check exit code and wrap parse in try/catch with descriptive error messages - Add try/finally in chat SSE route: reader.cancel() on disconnect - Add cancel callback to chatStream ReadableStream: restores ws.onmessage when stream is cancelled (prevents handler leak) --------- Co-authored-by: shivammittal274 <56757235+shivammittal274@users.noreply.github.com>