Files
openworker/surfaces/gui
Devika Verma 5aa27e2c76 Step 3b: web_search -> EGRESS + the 1.9 egress cards
web_search reclassified EGRESS (spec 2.2, decided 2026-08-12): the destination is
fixed (the configured provider) but the query is model-chosen free text - the same
outbound channel web_fetch's URL is. It ran completely ungated in every mode until
now; it gates like any egress from here on, which also puts it in front of the
Auto-Approve reviewer.

The egress approval cards (spec 1.9):
- web_fetch offers "Always allow <host> this session" -> ALWAYS_DOMAIN. Tool-wide
  "always" is gone from the card AND server-refused (_grant_offered): it would
  cover every future destination, and the live A/B showed exactly that (one click
  on a bbc.com card ran promptless fetches to hosts no card ever named).
- www. stripped at grant minting (allow_domain_for_session) - pure spelling only,
  never eTLD+1. The card button shows the exact spelling the grant mints.
- web_search offers "Always allow searches this session" -> ALWAYS_TOOL (tool-wide
  IS provider-wide for a fixed destination), with the card naming the LIVE
  destination: "Queries go to your configured search provider (currently: <name>)".
  Provider resolved when the card is raised (engine.approval_extras hook), not at
  session start.
- Provider-change invalidation: set_web_search clears the web_search session grant
  in every live engine when the provider actually changes - the grant was consent
  to a named destination.
- Auto-Approve fall-through cards hide every session "always" button: grants don't
  skip the reviewer there (1.5), and a button that lies is worse than none.
- scopeNote tells the truth for egress: "leaves this computer -> <host>" replaces
  "stays on this computer" on fetch/search cards.

Corpora gain web_search cases (benign 22 / dangerous 17 / injection 14), including
query-borne secret exfiltration and a planted search-the-credentials injection.

Tests: test_egress_and_overrides (EGRESS class, gating, www-strip, 1.5 in
Auto-Approve), test_approval_integrity (tool-wide refused for URL-carrying egress,
kept for web_search; provider-change invalidation), ApprovalCard.test.tsx (domain
button + www-strip, provider line, Auto-Approve hides always). Full suites pass;
the 22 pre-existing failures (Slack fake-gateway timeouts, a Windows file-lock
rename) fail identically on the pre-change tree.
2026-08-13 08:41:44 -07:00
..
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00
2026-07-21 11:09:41 -07:00

coworker GUI (React + Tauri)

A thin client of the coworker server (OpenAI-compatible API + WS event/approval stream). Same codebase runs in a browser (dev) and as the OpenWorker desktop app.

First time: bootstrap the Python backend

A fresh checkout has no server to run — create the venv both flows below expect (from the repo root):

bash packaging/setup_dev_env.sh   # → .venv (server + aisuite)

Run it (browser, two terminals)

  1. Start the server (needs a model key, e.g. OPENAI_API_KEY, in the environment — or add one later in the app's Settings), from the repo root:
    ./.venv/bin/openworker-server --cwd /path/to/your/project --port 8765
    
  2. Start the UI:
    cd surfaces/gui
    npm install      # first time
    npm run dev      # → http://localhost:5173
    

Open http://localhost:5173. The UI talks to http://127.0.0.1:8765 (override with VITE_COWORKER_HTTP / VITE_COWORKER_WS). Start the server before Vite so the UI can read its per-launch token from <state-dir>/sidecar-8765.token; restart Vite if the server is restarted.

Run the desktop app from source

The Tauri shell wraps the same UI and supervises the Python server itself — no separate terminal. It needs the Rust toolchain (rustup) plus the venv from the bootstrap step; in dev it finds the server at .venv/bin/openworker-server automatically (a packaged sidecar binary is only produced by the release scripts in packaging/).

cd surfaces/gui
npm install        # first time
npm run tauri dev  # builds the shell, launches the window, starts the server

Tests

npx tsc --noEmit && npx vitest run   # typecheck + unit
npx playwright test                  # hermetic e2e (mocked /v1 + WS, no Python needed)