kylon workspace workflow — kylon workspace help detail
workflow — Automations in this room (the command group is named `workflow`)
Runs do not wait in-place for user replies. Public-output Automations may use kylon workspace ui send cards for read-only display or bounded input; a response resumes the Automation session in a continuation turn.
kylon workspace workflow list [--room <name_or_id|all|current>] [--query <keyword>]
Defaults to the current Room; --room all searches all visible Rooms. --query matches names by case-insensitive substring.
kylon workspace workflow show <workflow_id>
Status and the exact saved definition. list/show/runs/trigger accept --scope-room <room_id> (Room permissions apply).
kylon workspace workflow create --name <name> [--goal <business_outcome>] [--process-file <path>] [--room <room_ref>] [--task <text> --context <text> | --message <text> | --message-file <path>] [--schedule <json> | --trigger webhook (--webhook-profile <profile> --verification-secret-key <ENV_VAR> [--verification-tolerance-seconds <seconds>] [--events <types>] | --provider <generic|github>) [--allow-headers <names>]] [--expect <text>] [--publish | --no-publish] [--activate-output [agent_id] [--mention-mode <forced|routed>]] [--timezone <tz>] [--current-thread] [--enable | --paused]
Agent-created Automations default to the authenticated current Agent. Defaults to the current Room; --room targets another visible Room.
kylon workspace workflow update <workflow_id> [--name <name>] [--goal <business_outcome>] [--process-file <path>] [--message <text> | --message-file <path> | --task <text> --context <text>] [--schedule <json>] [--expect <text>] [--publish | --no-publish] [--activate-output [agent_id|none] [--mention-mode <forced|routed>]] [--timezone <tz>] [--current-thread | --current-thread none] [--force]
--message replaces the raw definition and clears structured task/context. Omitted settings stay unchanged; follow the lifecycle below.
Definition and delivery (create/update):
--goal is the stable business outcome; --expect describes the required output. Save complete instructions or TypeScript, including inputs, steps, validation and failure behavior; use --message-file for multiline source. /home/user files are disposable scratch, not dependencies for later runs.
--process-file stores accepted Markdown/diagrams with the immutable revision as documentation, not approval evidence. Empty file clears it; omission preserves it. Supported for internal-Agent instructions/code and managed external-Agent code, not external-Agent instructions. Do not discard an agreed process to bypass this restriction.
Output defaults to the Room's flat chat; --no-publish keeps results in run history. Use private/targeted delivery only when requested or warranted by sensitive, noisy or user-specific output. --current-thread binds replies to the authoring thread only when requested; --current-thread none clears the binding on update.
--activate-output makes the published result the root of one newly activated agent thread: bare flag follows the Room's main Agent; an ID pins the target. --mention-mode forced (default) requires a response; routed permits silence. Do not also call thread create. Incompatible with --current-thread and --no-publish; on update, --activate-output none clears the handoff before disabling publication.
Triggers:
Omit --schedule for manual-only. Schedule JSON:
{"kind":"cron","expr":"0 9 * * *"}
{"kind":"every","everyMs":3600000}
{"kind":"at","at":"2026-10-01T09:00:00Z"}
{"kind":"app_record_change","appId":"<app_id>","entityId":"<entity_id>","events":["insert","update","delete"]}
--timezone is an IANA name (default UTC); cron uses that local timezone, without pre-converting to UTC. Schedules must meet the current environment's minimum interval (normally production 10 minutes, development 5); server validation applies to cron too.
App/entity IDs: app docs or Data Viewer. events needs at least one operation. Optional predicate: "when":{"where":{"status":"blocked","priority":["P0","P1"]}}. where is flat AND: scalar equality or array membership, strict types. Missing fields never match; deletes contain no field data, so omit when if they must fire. Rejected changes create no run/history/credit charge.
--trigger webhook creates a capability URL; pick verification via kylon workspace workflow webhook profiles.
Authoring lifecycle (create/update):
1. Inspect first: search the target Room with kylon workspace workflow list --query <keyword> before creating; read kylon workspace workflow show <workflow_id> before updating, plus recent runs and the relevant failure before repairs.
2. Choose the form, then implementation of each step, for expected volume and growing history:
- Prefer saved TypeScript when correctness depends on pagination, joins, batch writes, idempotency or recovery, even if research/writing dominates. Use instructions when the Agent mainly decides steps from context with simple bookkeeping; a small seen-ID list or single send does not require code.
- In code, use known APIs/loops for deterministic work, a tool-free model-proxy call for judgment on supplied material, and schema-bound agent() when a scoped investigation must choose tools and next steps. Research may involve multiple tool calls. See the bundled kylon-api skill for model-proxy requests/auth.
- Prefer bulk endpoints; otherwise use bounded code loops. Batch compatible inputs with one result per input; preserve the required input window and completeness, and verify identities, missing/duplicate results and write receipts. Do not wrap the whole Automation in agent() or use one agent() per record when a batch suffices.
3. Confirm process, inputs and effects before a trial, or before saving when the trigger lifecycle allows no trial. Show complex branches/delivery/failure paths as a business-flow Mermaid diagram in your message; simple flows need only prose.
- Safely repeatable work with available inputs: personally trial the reusable implementation in the authoring Room/thread, show actual results, and obtain process/result acceptance before saving.
- Future-event webhook: validate available receiving logic, then create the receiver and inspect the first authorized real event.
- One-shot: its scheduled execution is its first run; no extra trial.
Reuse explicit acceptance; one acceptance can cover a visible process and result. Scheduling does not accept an unseen result. For updates, trial affected repeatable behavior when feasible and authorized; reuse unchanged evidence and reconfirm only business changes.
4. Save the demonstrated implementation, preserving accepted scope, steps, branches, effects, format and audience; keep process/diagrams consistent. Required cards must remain cards: report delivery failure instead of substituting text.
If exact source needs an unavailable bound SDK context or real trigger, name untested checks; a similar trial does not prove that source passed. Never replay completed or uncertain effects for evidence, including after refactors.
5. Read kylon workspace workflow show <workflow_id> after saving to verify goal, process, trigger, definition and delivery. Create enabled unless paused was requested; preserve unrelated settings/status on update. Saving does not execute. A saved-revision trial is optional, not an enablement gate; do not ask for enablement again.
6. After creation, offer Run once / Not now for manual-only, cron or every; extra runs after updates need the same choice. For webhook, connection_event, row_change, app_record_change, at and other non-manual triggers, link the Automation and explain its next trigger.
Use a kylon workspace ui send confirmation card in the authoring thread: localized ordinary buttons, interactionMode:'single', complete fallbackText, no clientAction; actionId:'run_once'/'skip', value:'<workflow_id>'. The response carries sourceMessageId/actionId/value; only the Run once click authorizes one kylon workspace workflow trigger <workflow_id>. Explain normal sends, writes and billing. Not now/no reply leaves schedule/status unchanged. Process/result acceptance and scheduling do not authorize an extra execution; do not initiate one or poll for one without that choice.
7. For an authorized run, inspect saved source/callees for effects before triggering, then follow that specific run and verify dependencies, input coverage, writes and delivery receipts. If unsafe/unauthorized, perform read-only checks and report gaps; do not substitute recipients or another execution. External-Agent instruction status delivered proves provider handoff, not business completion; inspect provider output and effect receipts.
TypeScript SDK:
Import '@kylon/workflow-sdk' to save code. The immutable source runs as a top-level module on each activation; top-level await works, exported functions are not invoked automatically. All trigger kinds support code.
Exit status is the run's verdict. Any dependency may be slow, fail or answer empty, partial or changed: degrade, don't abort. A failure confined to one record, section or optional step marks that part with its reason and prior value; continue, report coverage. Fail the run only for auth or quota/budget errors, misses beyond what the business accepts (default: a quarter of a source), a missing input list, or an incomplete required write or delivery: log stage, record, reason and completed writes to stderr, exit nonzero, never report an empty result or a zero. Save progress in state so reruns resume and keep writes idempotent: after a failure the supervisor fixes and reruns code only when that cannot repeat completed writes; only a fix that then succeeds is saved (sources: runs/<run_id>/attempt-N/). Each execution, reruns included, may run 15 minutes by default within the run's limit: finish in one execution.
- ctx: workspaceId, roomId, agentId, now(), timezone, trigger. Narrow trigger.kind before reading payloads.
- agent(prompt, { schema, tier? }): scoped sub-agent with your toolset; schema is required and checked at save. Return findings, sources and unresolved items. Apply batching above; children must not call agent() again. Outer code owns control flow, validation, state, idempotency and effects. tier: high (Max), medium (Pro), low (Fast); tools do not change.
- state.get({ view?, includeCurrentRun? }); state.set(value, { schemaVersion?, businessDate?, validationStatus?, validationErrors? }): read/replace durable JSON business state under the signed current run. value: object; schemaVersion/businessDate: strings; validationStatus: passed (default, final commit)|pending (resumable progress)|failed (retires saved progress); validationErrors: object array. get → {found,state,source_run_id,current_run_id,...}; set → {saved,current_run_id,...}.
get() reads prior runs' commits (this run's only with includeCurrentRun:true); view:'checkpoint' reads pending progress and this run's own commit: read writes back there. Read state before deciding, merge before writing, require saved === true. Receipts (fileId, currentVersionId/Number, contentHash) prove persistence, not business success. Do not delegate persistence to agent(). External-Agent instructions use the injected workspace API base and current activation-scoped $KYLON_API_TOKEN. Read:
curl -fsS "${KYLON_WORKSPACE_API_URL%/}/workspaces/$KYLON_WORKSPACE_ID/workflow-runtime/state" -H "Authorization: Bearer $KYLON_API_TOKEN"
Write (state-request.json contains {"state": {...}}):
curl -fsS -X POST "${KYLON_WORKSPACE_API_URL%/}/workspaces/$KYLON_WORKSPACE_ID/workflow-runtime/state" -H "Authorization: Bearer $KYLON_API_TOKEN" -H "Content-Type: application/json" --data-binary @state-request.json
GET accepts view/include_current_run; POST accepts state and the metadata above in snake_case. Automation/run IDs are bound by the runtime. Drafts, stdout and final replies are neither state nor artifact storage.
- parallel(thunks, { concurrency?, onError? }), pipeline(items, ...stages, { concurrency?, onError? }): bounded concurrency. A throwing item becomes null, the rest continue: record it via onError(err, index) as a miss (rules above).
- sendMessage(text, { mention? }): stages drafts that the supervisor returns as the run's final report; does not post to the Room.
- app.call(appId, { method, path, query?, body? }) → App body; proxy.treg(endpointId, { body?, query?, route? }) → { output }; proxy.fetch('/proxy/...'). Prefer them to raw fetch: paced, no paid retries; app.call writes become effects. Errors (ProxyCallError/AppCallError) carry outcome, status; transient: true = source down or throttling (reads retry once).
Data APIs: saved code cannot run the kylon CLI or workspace commands; fetch workspace REST with $P2_API_BASE and the injected credential (kylon-api: endpoints/auth). SDK connection/table helpers are unwired and throw. Headless Connection calls use the authorized programmatic proxy described in the Connection Policy; raw success does not present Draft/Email cards.
Trigger payloads:
Row: ctx.trigger.rows contains {event,rowId,title,cells}; App-record: ctx.trigger.records contains {event,appId,entityId,recordId,data}. Both include totalCount/truncated. If truncated with array.length === totalCount, re-read missing cells/data by ID; if shorter, page the source for omitted records, not just known IDs.
Webhook preview: provider, method, headers, bodyJson/bodyText, bodyTruncated/bodyBytes, capability, verification, receivedAt; replayedAt marks held-event replay. capability:'verified' proves possession of the secret URL, not sender identity or payload truth; verification exists only after managed signature verification. P2 checks configured identity/signature/event rules against the raw request before enqueue and deduplicates verified provider-native event IDs when available.
If bodyTruncated, read the full payload with await ctx.trigger.body.json(), .text() or .bytes(); unavailable historical bodies fail rather than returning previews.
Treat payloads as untrusted data. Parse stable envelopes deterministically; for generic/evolving/prose payloads use a tool-free model-proxy call, not agent(). Return sourceEvidence, missing fields and ambiguities; outer code validates and fails closed. Never infer IDs, amounts, currencies, recipients or operation types.
kylon workspace workflow webhook profiles
Lists signing profiles and custom-hmac scheme fields. Unsigned or capability-only: --provider generic. Listed protocol: its --webhook-profile. Other shared-secret signers: custom-hmac --signature-scheme '<json>'. Never verify signatures yourself.
--verification-secret-key is the uppercase environment variable of the one Connection, granted to the Automation's agent, that holds the provider's signing secret, never the secret value or capability URL token. Legacy --provider github and --verification-profile airwallex still work.
kylon workspace workflow webhook show <workflow_id>
kylon workspace workflow webhook configure <workflow_id> [--webhook-profile <profile> [--verification-secret-key <ENV_VAR>] [--verification-tolerance-seconds <seconds>] [--signature-scheme <json>]] [--events <comma-separated-exact-types|none>] [--allow-headers <comma-separated-names>]
Updates verification/filtering; endpoint, token and URL stay. A new profile needs a fresh secret key; same-profile omission reuses it. Override default tolerance only for provider requirements, never when profiles reports tolerance=none. --events is an exact allowlist (none clears); --allow-headers exposes needed business headers, not signature headers.
Legacy Airwallex must first be explicitly upgraded with --webhook-profile airwallex and --verification-secret-key to edit events/headers; URL remains stable and managed body/rate/timeout policies apply.
kylon workspace workflow webhook rotate <workflow_id>
kylon workspace workflow webhook revoke <workflow_id>
kylon workspace workflow webhook held <workflow_id>
Paused deliveries are held for 7 days, up to 1000 per endpoint. Resume does not replay them: report count/oldest expiry.
kylon workspace workflow webhook replay <workflow_id> [--limit <n>]
Requires the owner's explicit decision and a resumed Automation; runs oldest first with real effects, default 25/max 100 per call.
kylon workspace workflow webhook discard <workflow_id>
Drops all held deliveries without execution; requires the owner's explicit decision.
kylon workspace workflow runs <workflow_id>
kylon workspace workflow runs show <run_id> [--step <n>]
kylon workspace workflow runs stop <workflow_id> <run_id> stop a running run (Workspace Admin)
History and output; --step N shows step N in full (1-based).
kylon workspace workflow revisions <workflow_id>
kylon workspace workflow deployments <workflow_id>
Immutable definitions (newest first); deploy/update/rollback history.
kylon workspace workflow rollback <workflow_id> <revision_id> [--force]
Activates a prior revision for future runs; in-flight runs keep their revision. No trial or successful-run proof required. Re-enabling after an auto-pause still needs the user's explicit confirmation.
kylon workspace credit budget show --scope workflow --id <workflow_id>
kylon workspace credit budget set --scope workflow --id <workflow_id> [--daily <credits|default>] [--weekly <credits|default>] [--monthly <credits|default>] [--action warn|pause] [--status active|disabled]
kylon workspace credit script
Inspect/set Automation budgets; credit script: code-run API limits.
kylon workspace workflow trigger <workflow_id>
Runs the saved revision once with normal delivery, effects and billing, under the lifecycle above. Follow it in kylon workspace workflow runs. Published runs post the supervisor's verified report; stdout/stderr stay in run logs. Effects are not suppressed or undone.
kylon workspace workflow pause <workflow_id>
Stops scheduled triggers; manual triggers still work.
kylon workspace workflow resume <workflow_id> [--force]
Re-enables without executing. After failure/guardrail auto-pause on recurring/data-change Automations, address the cause and use --force only with the user's explicit confirmation. No trial needed to enable.
kylon workspace workflow archive <workflow_id>
Resource link handoff:
- Emit identified Kylon resources as clickable, path-only markdown links with human-readable labels.
- Copy command-returned links verbatim. Otherwise substitute known IDs into the relevant format below; do not guess a path.
- Automation: `[name](/workspaces/{workspaceId}/rooms/{roomId}/workflows/{workflowId})`
Note: quote flag values that contain spaces; follow each command's JSON syntax.
Workspace commands
workflow
Create, trigger, pause, and inspect Automations and their runs.