Skip to main content

helix-bot-builder

Build, configure, troubleshoot and evaluate helix-org bots (org agents) — especially customer-facing support bots that run as limited-permission bot instances behind an app-key gateway. Covers writing the bot's prompt and runbook, shipping tested page/form libraries as repo skills, choosing harness/model/sandbox, instance profiles, creating and chatting with instances, delivering files, reading what a bot did, diagnosing stuck or wrong bots, and running graded eval suites (deterministic checks, LLM judge, simulated customers) with the helix CLI. Use when the user wants to create or improve a Helix bot, test a bot, debug a bot/instance, set up a support bot for end customers, or asks how chief-of-staff style bots should be built.

Source facts

Repository
helixml/skills
Last source activity
September 25, 2026 at 17:12
Detected SKILL.md language
English
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
9 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
helix-bot-builder
description
Build, configure, troubleshoot and evaluate helix-org bots (org agents) — especially customer-facing support bots that run as limited-permission bot instances behind an app-key gateway. Covers writing the bot's prompt and runbook, shipping tested page/form libraries as repo skills, choosing harness/model/sandbox, instance profiles, creating and chatting with instances, delivering files, reading what a bot did, diagnosing stuck or wrong bots, and running graded eval suites (deterministic checks, LLM judge, simulated customers) with the helix CLI. Use when the user wants to create or improve a Helix bot, test a bot, debug a bot/instance, set up a support bot for end customers, or asks how chief-of-staff style bots should be built.
# Helix bot builder A **bot** is a helix-org org agent: instructions (`content`) + a harness (`code_agent_runtime`) + a model + helix-org tools + its own project/repo, running in a sandbox. This skill is the loop for making one good — **brief → configure → smoke → eval → fix → ship → monitor** — driven by the `helix` CLI (`helix org bots|instances|eval`, `helix session`). Read [helix-cli](../helix-cli/SKILL.md) for auth. REST details: [references/api.md](references/api.md); failure modes: [references/troubleshooting.md](references/troubleshooting.md); eval suites: [references/evals.md](references/evals.md); prompt and page-library patterns: [references/prompts.md](references/prompts.md). ```bash export HELIX_URL=https://helix.example.com HELIX_API_KEY=hl-… HELIX_ORG=my-org helix org bots list helix org bots doctor <bot> # config lint: harness traps, profile/tool mismatches ``` > **CLI version.** `helix org instances`, `helix org eval`, `helix session` and > `helix org bots apply|export|prompt|profile|doctor|appkey|apply-config|delete`, `helix org webhooks` > are newer than the latest release ([helixml/helix#3298](https://github.com/helixml/helix/pull/3298)). Check with `helix session --help`. On an older binary use the `helix api` > forms in [references/api.md](references/api.md) — every command here maps to one or two REST calls. Inside a Helix sandbox the CLI picks up `HELIX_API_URL`/`USER_API_TOKEN` automatically; set `HELIX_ORG`. A bot's *main* session key can drive everything here; an *instance* key cannot (it is sandbox-scoped — see below). ## Mental model: bot, main session, instance, gateway | | Main bot session | Bot instance | Gateway chat | |---|---|---|---| | What | The bot's one exploratory session; the org's internal worker | Extra session sharing the bot's identity, own sandbox — **one per end customer** | `POST /api/v1/sessions/chat` with an **app key** bound to the bot's app | | Started by | `helix org bots start/restart`, triggers, DMs | `helix org instances create`, `create_bot_instance` | First message without a session id creates an instance | | AGENTS.md | helix-org preamble + prompt | **prompt verbatim**, copied at creation | = instance | | helix-org tools | the bot's `tools` | `instance_profile.tools ∩ bot.tools` (default **none**) | = instance | | MCP servers | all (browser, desktop, session, kodit, project MCPs) | `instance_profile.mcp_servers` (default `chrome-devtools`) | = instance | | API key in sandbox | full session key | `bot_instance` key: LLM proxy + own session plumbing + read-only git; **403 elsewhere** | = instance | | First turn | ~11 s activation turn, then work | **no activation turn**; cold chat ≈ 6–8 s | ≈ 7 s cold incl. instance create | | Transcript | mirrored to `s-transcript-<bot>` (`bot_log`) | **not mirrored** — `helix session turns <sid>` | + `bot_instance.turn_completed` webhook | | Skills | helix-* skills + repo `.agents/skills` | repo `.agents/skills` only (`helix_skills: false`) | = instance | Use the main session for operator/internal work; use **instances** for anything customer-facing and for testing — fast, isolated, minimal, and every new one runs the *current* prompt. ## The build loop ### 1. Brief Pin down: who talks to the bot (staff vs end customers), which systems it touches (web portals → browser; APIs → project MCP/OpenAPI), what it may **change** vs only read, which steps need a human (OTP codes, final submit), and 5–10 concrete requests with the exact answers you expect — they become the eval suite in step 5. ### 2. Choose harness, model, sandbox Browser-support eval (12 questions, self-hosted models; references/evals.md): | Harness (`code_agent_runtime`) | Verdict | |---|---| | `opencode` + `glm-5.3-flash` | **Default.** 12/12, fast, stable | | `deepseek_harness` + `glm-5.3-flash` | 12/12, often fastest; fails `session/new` if any MCP server fails | | `qwen_code` | correct but ~3× the tokens and slower | | `zed_agent` | **avoid for bots** — loses AGENTS.md after every clear/new thread | | `goose_code` | avoid — extra side calls, historically leaked browser MCP servers | | `claude_code` / `codex_cli` | vendor models only | Instances: `headless-ubuntu` (set `instance_profile.sandbox_runtime`) unless a human must watch the browser (`--runtime ubuntu-desktop`, `helix session screenshot`) — the agent starts ~2.7 s after the first message instead of ~17 s, and headless Chrome runs full logins and uploads. Keep `mcp_servers` to what the bot calls (`helix-desktop` adds 17 unused tools per call). Sandboxes stop after 10 idle minutes; resume with `POST /api/v1/sessions/<sid>/resume`. ### 3. Write the prompt — and ship the page knowledge as code Support-bot prompts that work are **runbooks**: numbered steps with call budgets, data formats, stop criteria, and a hard gate before anything that mutates. Details and a template: [references/prompts.md](references/prompts.md), `examples/support-bot.prompt.md`. For web portals, the biggest speed and reliability lever is **not** prompt text: explore the page once, write a small tested JS library (`fill`, `scan`, `press`) and commit it as a repo skill (`<bot repo>/.agents/skills/<system>/SKILL.md` + `fill.js`). The bot installs it with one `evaluate_script` and fills a whole form in one call instead of re-discovering the DOM every run (DHRE broker bot: 287 s → 124 s per login+fill, zero failed scripts). How to build and test one: references/prompts.md → "Page libraries". ### 4. Keep the bot in git, deploy with apply Give each bot a folder in a git repo — `bot.yaml` (spec), `prompt.md`, `skills/<name>/SKILL.md` (+ page libraries), `evals/` — and deploy it with one idempotent command. Example layout: [helixml/dubai-properties → bots/dubai-properties-broker](https://github.com/helixml/dubai-properties). ```bash helix org bots apply -f bots/my-bot/bot.yaml --dry-run # create, or which fields/skills change helix org bots apply -f bots/my-bot/bot.yaml # config + prompt, then skills → bot repo ``` `content_file` inlines the prompt; `skills_dir` pushes the skill folders into the bot project's Helix repo (`.agents/skills/`, commit by "helix apply"), where every new instance links them; `provider` may be the endpoint **name** (e.g. `ds4-flash-node06`) so specs work across environments. Other commands: ```bash helix org bots export dubai-broker -o bots/dubai-broker.yaml # spec + dubai-broker.prompt.md helix org bots apply -f bots/support-acme.yaml --dry-run # create, or which fields change helix org bots apply -f bots/support-acme.yaml helix org bots prompt support-acme -f support-acme.prompt.md # prompt only helix org bots profile support-acme --runtime headless-ubuntu --mcp chrome-devtools --tools "" ``` `examples/support-bot.yaml` is a starting spec; `export` writes one (provider by name) plus the prompt. Create merges `tools` with the default worker set; **updating `tools` replaces the list** (apply prints what it removes). Tools beyond the default set, and any instance tools, need an org owner/admin. ### 5. Smoke, then eval ```bash helix org instances ask support-acme "What's the balance on BA-10694?" --tools # one-shot SID=$(helix org instances create support-acme --name "manual test" --wait) helix session put $SID ./licence.pdf # → ~/work/incoming/licence.pdf helix session send $SID "Hi, I need to register" --tools # final message + tool summary helix session turns $SID # every turn: tools, timings, reply helix org instances delete support-acme $SID helix org eval run evals/support-acme.eval.yaml --parallel 3 --keep-failed helix org eval compare runs/before.jsonl runs/after.jsonl ``` Suites: cases with one or more turns graded by `must`/`must_not` patterns, latency and tool budgets, required/forbidden tools, an LLM `judge` rubric, or an LLM-`simulate`d customer; each case on a fresh instance. See [references/evals.md](references/evals.md) and `examples/support-lookup.eval.json`. Always include negative cases — near-miss names, credential requests, prompt injection: the example suite caught a bot reading its CRM passcode to a "new admin" in 1 of 3 runs. ### 6. Fix → re-run Read failures with `helix session turns <sid>` on the kept instance; change prompt, profile, page library or harness; **create new instances** (existing ones keep the old prompt); re-run with a new `--tag`; `compare`. Judge speed on totals over ≥10 cases (±25–50% noise). ### 7. Ship to customers (gateway) ```bash KEY=$(helix org bots appkey support-acme create acme-portal) helix session send - "Hi, what documents do you need?" --key "$KEY" # new instance; prints session id helix session send ses_01… "here it is" --key "$KEY" --attach eid.png helix org webhooks create https://portal.example.com/helix --events bot_instance.turn_completed ``` Your backend holds the app key and maps each customer to their `session_id`. **Never ship the app key to a browser**: an app key can chat into *any* instance of its bot (verified). Attachments go inline as base64 `data:` URLs and land in `~/work/incoming/`. The blocking reply and the webhook `response` are the **whole turn** — `<thinking>`, `**Tool Call:**` blocks, raw page snapshots. Strip before showing a customer; with a user key the clean answer is the text after the interaction's last tool call (what `helix session send` prints). ### 8. Monitor `helix org instances list <bot>` (`terminated_idle` after `HELIX_DESKTOP_IDLE_TIMEOUT`, default 1h — browser logins are lost), `helix session watch <sid>`, `helix org bots doctor <bot> <sid>`, `helix org instances delete <bot> --all --idle`. Re-run evals nightly: portals change under you. ## Rules that bite 1. **Instances copy the prompt at creation.** Test prompt changes on a *new* instance. Profile changes apply at the next sandbox start; main-session prompt/tools/sandbox changes need `restart` (fresh session) or `apply-config` (keeps it). Repo skills are cloned at sandbox start. 2. **Chat body**: `messages[].content` is `{"content_type":"text","parts":[…]}` — a plain string is a 400. A new gateway chat takes exactly one message. 3. **Interactions page from 0** and lag the chat reply; a harness splits one answer across several text entries. `helix session send/turns` handle both. 4. **Instances have no helix-org tools by default** — no `get_secret`. Grant it (`profile --tools get_secret`, and on the bot) or inline credentials, which evals show can leak. 5. **Files into an instance**: `helix session put` (root-owned 0644 in `~/work/incoming/`) or gateway attachments. Filestore links and artifact URLs do **not** work from instances. 6. **Human steps** (OTP, "submit"): the customer pastes codes into chat. In operator testing read the *newest message* of the mail thread — thread rows show a stale code. 7. A Helix app's own system prompt replaces a request's system message — the eval judge uses a neutral judge app (`assets/judge-agent.yaml`), never the bot's app. 8. A sandbox that "failed to start" makes the first chat wait 5 min for "external agent not ready". `instances create --wait`/`ask`/`eval` fail fast with the sandbox status; the cause (disk space, desktop quota) is in the API log (`Failed to start bot instance sandbox`). ## Driving bots from inside helix-org (chief-of-staff) | Step | MCP tool (owner set) | CLI | |---|---|---| | Create / update | `create_bot`, `set_bot_content`, `attach_tool`/`detach_tool` | `helix org bots apply -f` / `prompt -f` | | Instances | `create_bot_instance`, `list_bot_instances`, `delete_bot_instance` | `helix org instances create/list/delete` | | Talk to an instance | — | `helix session send <sid>` | | Read an instance | — | `helix session turns <sid>` | | Read the main session | `bot_log {botId}` | `helix session turns <session_id>` | | Lifecycle | `start_bot` / `stop_bot` / `restart_bot` | `helix org bots start/stop/restart/apply-config` | | Page libraries | — | clone the bot repo (`helix api /projects/<id>` → `default_repo_id`), push `.agents/skills/` | Tool grants reach a running main session only after a sandbox restart (the harness caches `tools/list`), whatever the default chief-of-staff prompt says.
View on GitHub