* test(ai-evals): guard implicit trigger/schedule intent in flow chat Investigation of WIN-2228 (does flow AI chat understand it should create a flow AND its associated triggers): the flow-editor chat already exposes create_schedule and create_trigger (10 kinds), both confirmation-gated, and an A/B eval shows the model already recognizes IMPLICIT trigger intent reliably (12/12 across two new cases on the current prompt) without naming a "schedule" or "trigger". Add two ai_evals flow cases that phrase the trigger intent implicitly, to guard that recognition against future prompt/tool regressions. These are not redundant with the existing explicit cases (flow-test15/16): a trial system prompt addition that spelled out a deployment prerequisite regressed the HTTP case from 6/6 to 2/6 (the model deferred instead of creating the trigger), which these cases caught. No prompt change ships: the addition showed no measured benefit over baseline and the fuller version regressed behavior. Fixes WIN-2228 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai-chat): support email triggers in flow/script create_trigger The chat's create_trigger tool exposed 10 trigger kinds but not email, even though the backend supports email triggers and the chat's open-resource drawer was already wired for them (CreatedResourceActionDrawers, the 'email' CreatedResourceTriggerKind). So when asked to make a flow run on incoming email, the model had no email kind and substituted an HTTP trigger it mislabeled as email. Add email as a create_trigger kind (generator + regenerated zod schema + triggerConfigs → EmailTriggerService.createEmailTrigger). Email triggering only works once an instance superadmin has stood up an SMTP server and set the `email_domain` global setting, so guard the create path: read `email_domain` (readable by any authed user; returns null when unset) and, when it is not configured, return role-aware setup guidance instead of a failing create — pointing a superadmin to Instance settings and a regular user to ask a superadmin, both with the docs link. When configured, create the trigger and report the resulting inbound email address. userStore and the email-address helper are lazy-imported so the chat tools module does not drag in the heavy $lib/stores graph at load. Guarded by unit tests for both branches (shared.test.ts) and an ai_evals case (flow-test19); the model now calls create_trigger(kind=email) 3/3 on a natural "run when an email is received" prompt. Fixes WIN-2228 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai-chat): address codex review on email trigger + eval guards - [P1] Default `workspaced_local_part` on the email trigger request body before it is sent, not only when formatting the success address. The column is BOOLEAN NOT NULL, so a request omitting it (the model may) was rejected by the backend. Assert the defaulted `false` in the happy-path unit test. - [P2] Tighten the implicit-intent eval guards so they validate the requested configuration, not just tool selection + path prefix: flow-test17 now checks the cron time (07:30) and UTC timezone; flow-test18 checks kind=http, POST method, no auth, and the route path. Cases still pass 9/9 (sonnet). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
System Prompts
This directory contains the single source of truth for AI system prompts used by both the frontend copilot and CLI guidance.
Structure
system_prompts/
├── base/ # Core instruction templates (manually written)
│ ├── flow-base.md # Shared OpenFlow structure guidance
│ └── flow-cli.md # CLI/local-agent workflow guidance for write-flow skill
├── languages/ # Language-specific instructions (manually written)
└── auto-generated/ # Auto-generated files (DO NOT EDIT)
├── sdks/ # SDK documentation
├── cli/ # CLI command documentation
├── prompts.ts # TypeScript exports
└── index.ts # Helper functions
Usage
Regenerating Prompts
When SDK methods or the OpenFlow schema change, run:
python system_prompts/generate.py
To also refresh the standalone skills in a Claude plugin checkout:
python system_prompts/generate.py --plugin-dir ~/windmill-claude-plugin
--plugin-dir accepts:
- the
windmill-claude-pluginrepo root - a plugin root such as
plugins/windmill - a direct
skills/directory
To regenerate the public docs repo (consumed by context7):
python system_prompts/generate.py --context7-dir ~/windmill-cli-docs
--context7-dir writes a fully-rendered snapshot (AGENTS.md,
cli-commands.md, skills/<name>/SKILL.md, README.md, manifest.json
with the Windmill version) with all template placeholders resolved —
suitable for ingestion by docs aggregators. In CI this runs from
.github/workflows/publish-cli-docs.yml on every release tag. The
generator refuses to wipe the target directory unless it's empty or has
a context7 marker (context7.json, manifest.json, or a
windmill-cli-docs git remote), so a typo can't delete unrelated files.
This will:
- Parse TypeScript and Python SDK files to extract function signatures
- Parse the OpenFlow YAML schema
- Parse the CLI commands
- Assemble complete prompts from markdown files
- Generate TypeScript exports in
auto-generated/ - Optionally refresh plugin-ready standalone
SKILL.mdfiles in the target directory
Scope
These system prompts contain ONLY:
- How to write Windmill scripts (language syntax, conventions, SDK usage)
- How to structure Windmill flows (OpenFlow schema, module types, data flow)
- Resource type handling, S3 operations
They DO NOT contain:
- Tool usage instructions (edit_code, set_flow_json, etc.)
- IDE/editor specific commands
- Testing tool invocations
Tool instructions are added separately by the frontend and CLI.
CLI-only workflow instructions live in base/flow-cli.md and are included in the
generated write-flow skill for wmill init. They are intentionally excluded
from the frontend flow chat prompt.
Integration
Frontend
Uses Vite path alias $system_prompts pointing to auto-generated/:
import { FLOW_GUIDANCE } from "$system_prompts/flow";
import { getLangContext } from "$system_prompts/languages";
CLI
Generates /cli/src/guidance/skills.gen.ts with embedded skill content for wmill init.
Editing Guidelines
- Edit markdown files in
base/,languages/ - Never edit files in
auto-generated/directly - After editing, run
generate.pyto update exports