跳转到内容

Build Your Own Admin Panel

此内容尚不支持你的语言。

Wetel’s own dashboard (where a tenant creates agents, designs workflow graphs, and watches test conversations) is built entirely on the Admin API — the same JWT-authenticated GraphQL surface documented in this section. Nothing about it is special-cased or internal-only. If you’d rather run your own dashboard — white-labeled, embedded in your own product, or shaped around a narrower workflow than a general-purpose builder — you can build it against the exact same API, while your tenant’s usage is still metered and billed through Wetel normally.

This is a real, supported path, not a workaround: it’s the same model a System Integrator uses to deliver “an AI agent platform” as part of their own product, with Wetel as the underlying engine. This page covers the parts of that build that aren’t just CRUD — the ones a plain API reference doesn’t answer.

You’re building one of:

  • A white-labeled version of the Wetel dashboard for your own customers, so they never see the word “Wetel.”
  • An embedded builder inside a larger product — a settings page that happens to include “configure your AI agent,” not a standalone app.
  • A narrower, opinionated builder for one use case (e.g. only support workflows, with your own templates and vocabulary), rather than Wetel’s general-purpose canvas.

In every case, you keep a normal Wetel account and API key/JWT — you’re not forking the backend, just building a different front door to it.

A minimal version of “your own app.wetel.dev” is three screens, in this order:

  1. Agent list + editor — plain CRUD against createAgent/updateAgent/agents/deleteAgent. See Admin API Overview for the exact mutation shapes. This screen alone is a form; nothing here needs a canvas library.
  2. Workflow canvas — the part people picture when they hear “workflow builder.” Covered in detail below.
  3. Test / preview pane — a live conversation against the draft agent, so a non-technical user can sanity-check a persona or workflow before publishing. Built from the same session mutations and sessionEvents subscription documented in Admin API Overview §4.

Everything past this — templates, versioning UI, team permissions, usage dashboards — is polish on top of these three, not a prerequisite for a working v1.

The workflow canvas: what to actually render

Section titled “The workflow canvas: what to actually render”

The workflow graph itself (Workflows Overview) is just JSON — an array of nodes and an array of edges, each node carrying a type and a data object shaped differently per type. A canvas library (React Flow is what Wetel’s own dashboard uses, but the graph shape has no dependency on it) gives you drag-and-drop and connection-drawing for free; the part you have to design yourself is what property panel to show when a node is selected, since that panel’s fields are different for every node type.

Don’t hand-copy the config shapes. Query nodeConfigSchemas once at load — it returns a real JSON Schema (draft 2020-12) per node type, generated from the backend’s own validation code, and works with an API key or a JWT. Drive your property panels (or a form generator) from that, so a new config field appears in your UI the day it ships instead of the day someone notices your snapshot is stale.

Here’s the config surface for each type — this is the part a schema won’t tell you, because it’s a UI design decision, not a field list:

Node typeWhat it needs a form for
startNothing — the entry point, no config
llmpromptTemplate (large text area — put persona and {{variable}} data here; do not expose systemPrompt as the main field, since setting it makes the backend ignore promptTemplate entirely), outputVar name, and toggles for matchAnyOf/excludeHistory/knowledgeBaseId
conditionAn expression editor — even a plain text input for ctx.turnCount >= 3-style expressions is enough for v1
routerA list of named branches, each mapped to a condition or a fixed label to match against upstream llm output
responseA canned text template with {{variable}} placeholders — a good place to show a live preview of the interpolated result
webhookURL, HTTP method, a JSON body template — same templating rules as response
toolA connector picker (populated from listMcpTools) plus an args template — ideally pre-filled from the tool’s own discovered schema
actionA Custom Action picker (from customActions — the URL/method/credential live on the Custom Action, not the node), an optional certified-operation picker (from certifiedOperations), an args template, outputVar
end_sessionOptional requireConfirmation toggle and its confirmationPromptTemplate — there is no final-message field; put the goodbye in a preceding response node

The one non-obvious trap here: tool and action nodes accept a raw JSON template as a string field, not a structured object — your property panel should validate that the template is syntactically valid JSON before save, because the backend will accept malformed JSON as a string and only fail at actual workflow-run time, which is a much worse debugging experience for whoever’s using your builder.

Wetel’s own dashboard includes a “generate a draft from a prompt” feature: a user describes a flow in plain language, an LLM call produces the node/edge JSON directly, and it’s saved via a normal updateWorkflow call — no different from a human editing the canvas by hand. There’s no dedicated Wetel API for this; it’s just a client-side (or your-own-backend) LLM call whose system prompt describes the node/edge schema and whose output you parse and pass straight to updateWorkflow.

If you build this yourself, two things matter more than they’d seem to: constrain the LLM’s output to only the JSON (a trailing sentence of explanation breaks a naive JSON.parse), and validate the generated graph has exactly one start node and no orphaned nodes before you let a user publish it — a malformed generated graph fails the same way a malformed hand-authored one does, silently, at publishWorkflow time.

Live debugging, not just “it works or it doesn’t”

Section titled “Live debugging, not just “it works or it doesn’t””

The single feature that separates a toy builder from one people trust in production is watching a test run node-by-node as it happens, not just seeing the final reply. This comes for free from the sessionEvents subscription — every node execution fires an event with the node ID and its output, so your test pane can highlight the currently-executing node on the canvas in real time. After the run, workflowRun.nodeTrace gives you the same information for post-hoc replay, which is what Troubleshooting & FAQ covers for the “why did my workflow do that” case.

Build the live and post-hoc views on the same data shape from day one — it’s the same trace, just consumed live via subscription vs. queried after the fact.

Your dashboard’s own users authenticate however you want on your side — the only requirement Wetel imposes is that whatever backend of yours talks to Wetel’s Admin API does so with a real Wetel-issued JWT (obtained via normal login) scoped to the correct tenant. If your product has its own user/org model, the common pattern is: one Wetel tenant per one of your customers, with your backend holding that tenant’s Wetel credentials server-side and never exposing them to your own frontend directly — the same “your backend holds the socket” pattern described in Core API Flow for the session-integration case applies here too.

Never put a Wetel JWT or API key in your own frontend’s client-side code, for the same reason Troubleshooting gives for the SDK integration case.

A few things are tempting to reimplement and genuinely aren’t worth it:

  • SSRF protection on tool/action/webhook node URLs — Wetel’s backend already blocks private-IP-range targets on every outbound call a workflow makes. You don’t need to validate URLs on your own builder’s save path; the backend enforces this regardless of what your UI allows through.
  • Rate limiting — already enforced on the mutations your builder calls, keyed by the calling client’s IP (not per API key or tenant — see Rate Limiting). If your builder proxies many end users through one server, all of them share that server’s bucket, so add your own per-user fairness limiter in front only for that reason — not to duplicate Wetel’s.
  • Credential storage for registered toolscreateMcpConnector’s apiKey is swapped server-side for an opaque reference and never returned again. Your builder never needs to store or re-display it; design your connector-editing UI around “write-only, re-enter to rotate” from the start.

Admin API Overview for the full CRUD contract this guide builds on, Workflows Overview for the node/edge JSON shape, MCP Connectors for the tool-registration integration side, and Troubleshooting & FAQ for debugging a run after the fact.