|
| 1 | +# Chat Worker |
| 2 | + |
| 3 | +Cloudflare Worker that powers the **KI-Assistent** view in |
| 4 | +`prototype-sqlite/`. Proxies Anthropic API calls and exposes the |
| 5 | +catalog SQLite database to Claude via a `query_catalog(sql)` tool. |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +``` |
| 10 | +Browser ──POST /chat──▶ Worker ──┐ |
| 11 | + ├──▶ Anthropic API (Claude Sonnet 4.6) |
| 12 | + └──▶ sql.js + catalog.db (bundled) |
| 13 | +``` |
| 14 | + |
| 15 | +- **Anthropic SDK** sends/receives messages with prompt caching on the system prompt. |
| 16 | +- **sql.js** loads `data/catalog.db` once per Worker isolate (warm-start cache). |
| 17 | +- **Read-only** at two layers: `PRAGMA query_only = 1` on the engine, plus a regex check that rejects DML/DDL keywords before SQL touches the DB. |
| 18 | + |
| 19 | +## Deploy via GitHub Actions (recommended) |
| 20 | + |
| 21 | +The workflow at [`.github/workflows/deploy-chat-worker.yml`](../.github/workflows/deploy-chat-worker.yml) deploys on every push to `main` that touches `chat-worker/**` or `prototype-sqlite/data/catalog.db`. It also has a "Run workflow" button for manual re-deploys. |
| 22 | + |
| 23 | +**One-time setup**: |
| 24 | + |
| 25 | +1. Create a Cloudflare API token at <https://dash.cloudflare.com/profile/api-tokens> with the "Edit Cloudflare Workers" template. Note your **Account ID** from the dashboard sidebar. |
| 26 | +2. In the GitHub repo → **Settings → Secrets and variables → Actions**: |
| 27 | + |
| 28 | + On the **Secrets** tab: |
| 29 | + |
| 30 | + | Name | Value | |
| 31 | + |---|---| |
| 32 | + | `CLOUDFLARE_API_TOKEN` | the token from step 1 | |
| 33 | + | `ANTHROPIC_API_KEY` | `sk-ant-…` from console.anthropic.com | |
| 34 | + |
| 35 | + On the **Variables** tab: |
| 36 | + |
| 37 | + | Name | Value | |
| 38 | + |---|---| |
| 39 | + | `CLOUDFLARE_ACCOUNT_ID` | your CF account ID (not sensitive, just an identifier) | |
| 40 | + |
| 41 | +3. Run `npm install` locally once to generate `package-lock.json`, then commit it (the workflow uses `npm ci` and needs the lockfile). |
| 42 | +4. Push to `main`. The Action deploys the worker and syncs the Anthropic key as a Cloudflare secret on every run. |
| 43 | + |
| 44 | +Wrangler prints the public URL in the Action logs, e.g.: |
| 45 | + |
| 46 | +``` |
| 47 | +Published bbl-datenkatalog-chat |
| 48 | + https://bbl-datenkatalog-chat.<your-account>.workers.dev |
| 49 | +``` |
| 50 | + |
| 51 | +## Deploy from your machine (alternative) |
| 52 | + |
| 53 | +```bash |
| 54 | +cd chat-worker |
| 55 | +npm install |
| 56 | +npx wrangler login # OAuth into your CF account |
| 57 | +npx wrangler secret put ANTHROPIC_API_KEY # paste sk-ant-... |
| 58 | +npm run deploy |
| 59 | +``` |
| 60 | + |
| 61 | +`predeploy` copies `../prototype-sqlite/data/catalog.db` into `data/catalog.db` so the bundled DB matches the frontend. |
| 62 | + |
| 63 | +## Wire to the frontend |
| 64 | + |
| 65 | +Open `prototype-sqlite/js/views/search.js` and set: |
| 66 | + |
| 67 | +```js |
| 68 | +const CHAT_WORKER_URL = 'https://bbl-datenkatalog-chat.<your-account>.workers.dev'; |
| 69 | +``` |
| 70 | + |
| 71 | +Refresh the catalog, navigate to **KI-Assistent**, ask a question. |
| 72 | + |
| 73 | +## Local dev |
| 74 | + |
| 75 | +```bash |
| 76 | +npm run dev |
| 77 | +``` |
| 78 | + |
| 79 | +Starts a local worker on `http://localhost:8787`. Point `CHAT_WORKER_URL` there to test before deploying. |
| 80 | + |
| 81 | +## Updating the catalog |
| 82 | + |
| 83 | +Whenever `prototype-sqlite/data/catalog.db` changes, re-run `npm run deploy`. The DB is bundled into the worker, so a redeploy is required to pick up new data. |
| 84 | + |
| 85 | +## Configuration |
| 86 | + |
| 87 | +`wrangler.toml`: |
| 88 | + |
| 89 | +| Variable | Default | Purpose | |
| 90 | +|--------------------|-------------------------|--------------------------------------------| |
| 91 | +| `ALLOWED_ORIGIN` | `*` | CORS origin. Tighten in production. | |
| 92 | +| `ANTHROPIC_MODEL` | `claude-sonnet-4-6` | Override to `claude-opus-4-7` or `claude-haiku-4-5-20251001`. | |
| 93 | + |
| 94 | +Secrets (set via `wrangler secret put`): |
| 95 | + |
| 96 | +| Name | Required | Notes | |
| 97 | +|---------------------|----------|--------------------------------| |
| 98 | +| `ANTHROPIC_API_KEY` | yes | From console.anthropic.com. | |
| 99 | + |
| 100 | +## Cost |
| 101 | + |
| 102 | +- **Cloudflare Worker**: free tier (100k requests/day). The bundle is ~1.5 MB, comfortably under the 3 MiB free limit. |
| 103 | +- **Anthropic API**: with prompt caching enabled on the system prompt, expect roughly $0.005–0.02 per conversation turn at Sonnet 4.6 rates. |
| 104 | + |
| 105 | +## Limits & caveats |
| 106 | + |
| 107 | +- The tool loop is capped at 8 turns to prevent runaway costs. |
| 108 | +- Query results are truncated at 200 rows. |
| 109 | +- The catalog DB ships with the worker — anyone hitting the endpoint can introspect the schema. Acceptable since the data is non-sensitive metadata; tighten `ALLOWED_ORIGIN` and add auth (JWT/eIAM) before production. |
0 commit comments