Files
Ben Senescu 361d488dff chore: remove the onboarding chat (#572)
The OnboardingChatAgent Durable Object namespace has had zero invocations for
months and the "onboarding" credit feature zero events since June 2026. Nothing
in the app linked to /onboarding/chat any more, so the route was unreachable.

Removes the agent DO, its tools, the client route and UI, the server functions,
and the shared free-question cap. The SAM agent keeps the pieces it shared:
ChatComposer moved to src/client/features/sam, and openseo-fact-sheet.md moved
next to samChatTools.

wrangler.jsonc gains migration tag v5 with deleted_classes:
["OnboardingChatAgent"]. That destroys the namespace's stored conversations,
which is the intent. Alchemy derives its DO bindings from
wrangler.durable_objects.bindings, so dropping the binding there is the whole
change on the Alchemy side.

Claude-Session: https://claude.ai/code/session_019qJewihUwwbdtYDsHa73Gc
2026-09-11 20:11:32 -07:00

150 lines
5.4 KiB
JSON

{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "open-seo",
"main": "src/server.ts",
"compatibility_date": "2025-09-02",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"observability": {
"enabled": true,
// Spans are billed as observability events (free tier 200k/day); add a
// traces head_sampling_rate below 1 if span volume becomes a cost concern.
"traces": {
"enabled": true,
},
},
// Smart Placement relocates only the `fetch` handler (cron + Workflow runs
// stay at the edge) toward external subrequests — Postgres via Hyperdrive,
// SEO APIs — not D1/KV/R2 bindings, so it's a DB no-op on the D1 default.
// Must live here: a dashboard-only toggle is wiped by `wrangler deploy`.
"placement": {
"mode": "smart",
},
"workflows": [
// The site-audit engine lives in the open-seo-audit aux worker
// (wrangler.audit.jsonc) — its memory spikes (multi-MB Lighthouse
// payloads, in-flight HTML) OOMed this worker's near-limit baseline
// heap. This is a cross-script binding for starting audits and reading
// instance status.
{
"name": "site-audit-workflow",
"binding": "SITE_AUDIT_WORKFLOW",
"class_name": "SiteAuditWorkflow",
"script_name": "open-seo-audit",
},
{
"name": "rank-check-workflow",
"binding": "RANK_CHECK_WORKFLOW",
"class_name": "RankCheckWorkflow",
},
],
// Durable Object backing the SAM in-app agent (Agents SDK AIChatAgent). One
// instance per chat session; messages persist in the DO's SQLite.
// SQLite-backed classes must be declared in `migrations` below for the
// wrangler/workerd surfaces (local dev, Docker self-host); Alchemy deploys
// derive SQLite backing on their own.
"durable_objects": {
"bindings": [
{
"name": "SAM_CHAT",
"class_name": "SamChatAgent",
},
],
},
// The site-audit engine lives in the open-seo-audit aux worker
// (wrangler.audit.jsonc), including the scratchpad DO — the DO cannot be
// bound cross-script here (the Cloudflare API rejects deleting the class
// below while any binding still references its name). Cancel + GDPR
// erasure go through this service binding's AuditEngine entrypoint.
"services": [
{
"binding": "AUDIT_ENGINE",
"service": "open-seo-audit",
},
],
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["OnboardingChatAgent"],
},
{
"tag": "v2",
"new_sqlite_classes": ["SamChatAgent"],
},
{
"tag": "v3",
"new_sqlite_classes": ["AuditScratchpad"],
},
// AuditScratchpad moved to the open-seo-audit worker (no binding may
// still reference the class name in the same upload — see the services
// comment above). Deleting it here is safe: scratchpad state is
// disposable by design (destroyed at finalize, 7-day cleanup alarm) —
// in-flight audits at the cutover fail once and the stale-audit
// reconciler reaps them.
{
"tag": "v4",
"deleted_classes": ["AuditScratchpad"],
},
// The onboarding strategy chat was removed: the namespace had had zero
// invocations for months. Deleting the class destroys every instance's
// stored conversation, which is the intent — nothing else reads it.
{
"tag": "v5",
"deleted_classes": ["OnboardingChatAgent"],
},
],
"triggers": {
// Every 5 min: rank checks + stale-audit reconcile. Daily: OAuth KV GC.
// Dispatched on controller.cron in src/server.ts `scheduled`.
"crons": ["*/5 * * * *", "17 3 * * *"],
},
// This config serves local dev and Docker self-host only. All Cloudflare
// deployments — previews, prod, self-host — go through Alchemy
// (alchemy.run.ts), which provisions real resources per stage and never
// reads these ids.
//
// The ids below are NOT dead config: miniflare derives its on-disk storage
// filenames (.wrangler/state, a persistent volume in Docker self-hosts)
// from an HMAC of `id`/`database_id`. Changing them orphans every existing
// local and self-hosted database. Leave them as-is.
"kv_namespaces": [
{
"binding": "KV",
"id": "4abd52f3f2c549ac83cc2cb4ceec8620",
},
{
"binding": "OAUTH_KV",
"id": "bd1759494309474a9b423b029967b0db",
},
],
"d1_databases": [
{
"binding": "DB",
"database_name": "open-seo",
"database_id": "37bee90a-e1aa-404f-b01e-b0d1d479bda1",
"migrations_dir": "drizzle",
},
],
// Postgres scale path (opt-in; D1 is the default). Hyperdrive is the ONLY way
// the app connects to Postgres — there is no direct-connection fallback. For
// local dev, `localConnectionString` is the throwaway Docker Postgres from
// docs/LOCAL_POSTGRES.md, and nothing connects to it unless
// DATABASE_PROVIDER=postgres is set in .env.local.
//
// Kept commented out: the id lives in OpenSEO's account, and only local
// Postgres dev reads this block (Alchemy deploys and the Docker image never
// do). Uncomment when running local Postgres dev per docs/LOCAL_POSTGRES.md.
// "hyperdrive": [
// {
// "binding": "HYPERDRIVE",
// "id": "9d64ccfb559f44449ce52a143912f898",
// "localConnectionString": "postgres://openseo:openseo@localhost:5433/openseo",
// },
// ],
"r2_buckets": [
{
"bucket_name": "open-seo",
"binding": "R2",
},
],
}