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 deploy_function call 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 🎉" },
});

Each Edge Function request has a 90-second wall-clock budget. The runtime reuses its warm isolate and resets that budget after every request; an isolate may retire after 90 seconds without a request. Each function path has at most four workers, and a request waits at most ten seconds for a runtime slot. Long polling remains supported: use a bounded poll window that returns before 90 seconds, then let a recurring schedule start the next window.

Run another function later

Schedule one exact future execution with schedule_function_once or the CLI command lollipop schedule-function-once. An edge function can schedule another by posting the same fields to TELLWANG_FUNCTION_SCHEDULE_URL with its service-role Bearer. TellWang leases work across restarts and runs one queued invocation per Wok. Ordinary failures retry up to three times. A wall-clock or supervisor cancellation fails terminally as CP_FUNCTION_INVOCATION_WALL_CLOCK. Inspect every outcome with list_function_invocations.

start-check.ts
await fetch(Deno.env.get("TELLWANG_FUNCTION_SCHEDULE_URL")!, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    function_name: "check-result",
    run_at: new Date(Date.now() + 5 * 60_000).toISOString(),
    payload: { check_id: "123" },
    idempotency_key: "check-result:123",
  }),
});

Trigger on new rows

Wire a function to run automatically when a row is written to a table. TellWang installs a trigger and delivers each change ({op, table, old, new}) to your function over the Wok's private network, with no public ingress.

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.

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 private 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.