Presets
Each preset is a Provider: optional seed (mutates WorldState) and optional handle (returns a Response or null).
Helper factories (github, stripe, …) wrap *Provider with a default name.
GitHub (github)
- GET
https://api.github.com/repos/{owner}/{repo}/issues— list issues forrepoasowner/repo. - POST same path — create issue from JSON body.
Config: issues?: Array<{ repo: string; title: string; body?: string; labels?: string[]; state?: string }>
Stripe (stripe)
- GET
https://api.stripe.com/v1/customers— list seeded customers.
Config: customers?: Array<{ id?: string; email: string }>
Postgres facade (postgres)
No HTTP handler. Seeds rows into WorldState under pg:{table}.
Config: tables?: Record<string, Array<Record<string, unknown>>>
Use env.db().query(sql, params) — minimal parser: FROM table and optional WHERE col = $1 (heuristic).
OpenAI (openai)
- POST hosts matching
api.openai.com, typically chat/completions paths.
Config: responses?: Array<{ match?: { model?: string }; response: Record<string, unknown> }>
Cycles through responses; defaults to a tiny canned choices payload.
Anthropic (anthropic)
- POST
api.anthropic.compaths containing/v1/messages.
Config: texts?: string[] (rotated per request), model?: string
S3-shaped (s3)
- Virtual-hosted:
https://{bucket}.s3…amazonaws.com/{key}— GET object. - Path-style:
https://s3.amazonaws.com/{bucket}/{key}— GET object. - List:
GET https://s3.amazonaws.com/{bucket}?list-type=2&prefix=…
Config: objects?: Array<{ bucket: string; key: string; body?: string; etag?: string }>
Slack (slack)
- GET/POST
https://slack.com/api/auth.test - POST
https://slack.com/api/chat.postMessage
Config: botUserId?: string
Custom providers
Implement Provider: name, optional seed(world, rng), optional handle(url, method, body, world) returning Promise<Response | null>. Register alongside built-ins.