TellWang
Dashboard

Edge Functions

Run your own TypeScript/Deno code in your Wok, next to your data. Use functions for webhooks, third-party integrations, or any logic the database and REST API don't cover.

Open Build with an agent in the dashboard, choose Edge function, and paste the generated prompt into a connected coding client. The agent deploys through the same API and returns the invoke URL plus verification evidence.

Deploy

Write your function and ship it. index.ts can import local helper modules from the same function directory; TellWang deploys and persists the complete module tree. The cp's deploy_function step accepts the entrypoint as code and optional helpers as a relative-path files map. Git pushes and Wang's project deploy collect those files automatically.

you → Cursor
Deploy notify-slack as a function on my Wok.

Your function runs in your Wok, with secure access to its database and secrets — no servers to manage.

Invoke

app.ts
const { data } = await tw.functions.invoke("notify-slack", {
  body: { message: "New signup 🎉" },
});

Trigger on new rows

Wire a function to run automatically when a row is written to a table. cp installs a Postgres trigger that fires pg_notify; a per-Wok listener inside cp picks the notify up and POSTs the row payload ({op, table, old, new}) to your function. The whole loop runs over the wok-local docker network — no public ingress, no extra latency.

trigger.ts
// "run notify-slack on every INSERT into orders"
await tw.functions.triggers.create({
  table: "public.orders",
  event: "insert", // or "update" | "delete" | "*"
  function_name: "notify-slack",
});

Your function's request body looks like {trigger, fn, op, table, old?, new?}. new is the inserted/updated row; old is the deleted/pre-update row. Use the wok's in-network SUPABASE_URL (http://rest:3000) inside the function if you need to write back via PostgREST without hitting a public port.

Managed RAG (when enabled)

Customer-facing retrieval and grounded chat go through the model gateway. The function authenticates the gateway with its sllm_ key and forwards the caller's exact signed Wok bearer in X-Wok-Authorization; the gateway verifies Wok ownership before it calls RAG. Never replace that user bearer with SUPABASE_SERVICE_ROLE_KEY, which bypasses document policy. The reserved internal RAG_URL remains for independently authorized management and private scheduled ingestion, generation, or insight work.

Redis + BullMQ

Every Wok ships a dedicated Redis 7 container, with process.env.REDIS_URL wired into every edge function — no setup. Reach for it for caching, rate limits, and sessions.

For work that has to run reliably — payroll runs, print batches, billing, invoice generation — BullMQ gives you durable job queues: a job that fails is retried with backoff instead of lost, jobs run in order, and a dropped worker picks up where it left off. That's the difference between "fire an HTTP call and hope" and a queue you can trust with money and paper.

queue.ts
import { Queue, Worker } from "bullmq";
import Redis from "ioredis";

const redis = new Redis(process.env.REDIS_URL!);

const emails = new Queue("emails", { connection: redis });

// in your function — enqueue from a webhook or API call
await emails.add("welcome", { userId: "u_123" });

// in another function — process
new Worker("emails", async (job) => {
  await sendWelcomeEmail(job.data.userId);
}, { connection: redis });

Redis runs inside the wok's docker network — only your functions and database can reach it. Persisted across restarts (AOF), 200 MiB memory cap with LRU eviction. For caching: any Redis client (ioredis, redis, etc) works against the same URL.

Redis is reachable from inside the Wok only. An edge function is the way to expose exactly the operations you want to something outside it.