@controllerai/cli 0.2.17 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.js +32 -0
- package/dist/api/client.js.map +1 -1
- package/dist/commands/agent.js +101 -8
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/expr.js +3 -10
- package/dist/commands/expr.js.map +1 -1
- package/dist/commands/file.js +11 -1
- package/dist/commands/file.js.map +1 -1
- package/dist/commands/integration.js +8 -2
- package/dist/commands/integration.js.map +1 -1
- package/dist/commands/workflow.js +29 -6
- package/dist/commands/workflow.js.map +1 -1
- package/dist/errors.js +5 -2
- package/dist/errors.js.map +1 -1
- package/package.json +1 -1
- package/skills/controllerai-agents/SKILL.md +25 -192
- package/skills/controllerai-agents/references/command-reference.md +205 -0
- package/skills/controllerai-ai-nodes/SKILL.md +11 -92
- package/skills/controllerai-ai-nodes/references/command-reference.md +98 -0
- package/skills/controllerai-data/SKILL.md +34 -159
- package/skills/controllerai-data/references/command-reference.md +177 -0
- package/skills/controllerai-expressions/SKILL.md +29 -151
- package/skills/controllerai-expressions/references/command-reference.md +166 -0
- package/skills/controllerai-expressions/references/dsl-and-recipes.md +1 -1
- package/skills/controllerai-flow-control/SKILL.md +21 -160
- package/skills/controllerai-flow-control/references/command-reference.md +171 -0
- package/skills/controllerai-integration-actions/SKILL.md +11 -112
- package/skills/controllerai-integration-actions/references/command-reference.md +118 -0
- package/skills/controllerai-node-config/SKILL.md +18 -178
- package/skills/controllerai-node-config/references/command-reference.md +186 -0
- package/skills/controllerai-runs/SKILL.md +25 -117
- package/skills/controllerai-runs/references/command-reference.md +113 -0
- package/skills/controllerai-start/SKILL.md +36 -67
- package/skills/controllerai-start/references/mcp-tool-map.md +6 -0
- package/skills/controllerai-triggers/SKILL.md +16 -210
- package/skills/controllerai-triggers/references/command-reference.md +215 -0
- package/skills/controllerai-workflows/SKILL.md +24 -104
- package/skills/controllerai-workflows/references/command-reference.md +118 -0
- package/skills/manifest.json +120 -60
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Controller AI node configuration
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
A node is ready only after its component, connection, dependency-ordered props, wiring, and output type are valid. Treat configuration as a state machine, not a bag of property writes.
|
|
5
|
+
|
|
6
|
+
## Deterministic sequence
|
|
7
|
+
|
|
8
|
+
### 1. Find an exact component
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cai integration actions "<capability>" --json
|
|
12
|
+
cai integration action --integration <nodeSlug> --key <nodeKey> --json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Use the returned `nodeSlug` and full `key`. Do not infer a component key from its display name. If discovery is broad, narrow it with:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cai integration search "<integration>" --actions --json
|
|
19
|
+
cai integration actions "<action>" --integration <nodeSlug> --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Inspect static prop metadata before creating the node. `required`, `remoteOptions`, and `reloadProps` determine configuration order.
|
|
23
|
+
|
|
24
|
+
### 2. Resolve the account
|
|
25
|
+
|
|
26
|
+
If the component requires auth:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cai connection list --node <nodeSlug> --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- One active connection: use its exact `id` as the `connectionId`.
|
|
33
|
+
- Several: use an explicit user preference; otherwise ask which account.
|
|
34
|
+
- None: add the real component without `--connection`; `missingConnection: true` is a valid handoff state. On CLI, get the link with `cai connection connect <nodeSlug> --no-open` and share it right away; do not block on `--wait` before sharing.
|
|
35
|
+
|
|
36
|
+
MCP: call `connection_connect_url` with `nodeSlug`, show its `url` as a markdown link, ask the user to finish, then confirm with `connection_list` using its `integration`.
|
|
37
|
+
|
|
38
|
+
After they confirm, run `cai connection list --integration <nodeSlug> --json` and bind the new ID with `cai node set-connection <nodeId> --connection <connectionId>`.
|
|
39
|
+
|
|
40
|
+
Never substitute a connection from a similar slug.
|
|
41
|
+
|
|
42
|
+
Rename or change the default with `cai connection update <id> [--name "<displayName>"] [--default|--no-default]` (MCP: `connection_update`); delete only intentionally with `cai connection delete <id> --yes` (MCP: `connection_delete`).
|
|
43
|
+
Deleting a connection immediately removes authorization from bound nodes and agent tools.
|
|
44
|
+
|
|
45
|
+
A missing connection is never a reason to substitute `registry_http-http-request` for a catalog component. A raw endpoint mentioned by the user is background context, not an instruction to hand-roll the call.
|
|
46
|
+
|
|
47
|
+
### 3. Initialize once
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cai node init \
|
|
51
|
+
--flow <flowId> \
|
|
52
|
+
--node <nodeSlug> \
|
|
53
|
+
--key <nodeKey> \
|
|
54
|
+
--name "<data this node produces>" \
|
|
55
|
+
--connection <connectionId> \
|
|
56
|
+
--after <upstreamNodeId> \
|
|
57
|
+
--json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
MCP: use `node_add`; `cai node init` is the CLI alias of `cai node add`.
|
|
61
|
+
|
|
62
|
+
Omit flags that do not apply. `--after` creates the ordinary main/error wire at creation. Use it when later props need upstream data. Initialization also accepts `--props`, but use it only for static, non-option values already present in the inspected component metadata. Never inline a `remoteOptions` value, a reload selector and its dependents, or a prop that has not materialized yet; initialize first and set those sequentially. Use `--enable-prop <name...>` only for optional props confirmed by component metadata.
|
|
63
|
+
|
|
64
|
+
Capture the returned `nodeId`; do not rediscover it by name. Inspect the complete create result before projecting fields. A missing projection is not proof that creation failed, so read the captured ID or exact flow inventory before any retry.
|
|
65
|
+
|
|
66
|
+
When repairing an existing node, keep its node ID and configure it in place. Do not delete and recreate it merely to clear bad props, select a component, or refresh generated props; deletion discards wiring, conditions, and identity-based references. Replace it only when the requested component itself must change. Then capture the replacement ID, reconnect every dependent, and revalidate them.
|
|
67
|
+
|
|
68
|
+
### 4. Follow readiness, not guesses
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cai node status <nodeId> --json
|
|
72
|
+
cai node props <nodeId> --json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For option-backed props, `node props` and write readback may report `optionsAvailability`: `available`, `blocked_upstream` with `blockedBy`, or `dynamic_upstream`. It is positional: earlier single `DROPDOWN` selectors gate later options. Older backends, and responses without a dependency catalog, may omit it; treat absence as unknown, not available.
|
|
76
|
+
|
|
77
|
+
Work through blockers in this order:
|
|
78
|
+
|
|
79
|
+
1. Missing connection
|
|
80
|
+
2. Required selector props with `reloadProps`
|
|
81
|
+
3. Newly revealed required props
|
|
82
|
+
4. Static and remote-option props
|
|
83
|
+
5. Wiring required for expressions
|
|
84
|
+
6. Expressions
|
|
85
|
+
7. Unresolved output type
|
|
86
|
+
|
|
87
|
+
Follow `next`. When a disabled required prop has an activating selector, its blocker names that selector; when it is the next blocker, `next` gives the exact `cai node set` command. `dynamicSelectorNotes` is non-blocking: a node may read ready while its dynamic selector's dependents still reflect the last concrete resolution.
|
|
88
|
+
|
|
89
|
+
After every concrete reload-selector or connection change, re-run `node props`; dynamic props can appear, disappear, or reset. Use `cai node reload <nodeId> --json` to re-resolve without re-setting a selector. If an explicit reload finds an unset materialized reload selector, it returns `reconcileSkipped: "unset_selector"` plus a note and preserves materialized dependent props instead of reconciling them.
|
|
90
|
+
|
|
91
|
+
### 5. Set props safely
|
|
92
|
+
|
|
93
|
+
Static value:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cai node set <nodeId> --prop <exactName> --value '<literal-or-json>' --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
MCP: use `node_prop_set` with `value`; it also handles expression writes through `js`.
|
|
100
|
+
|
|
101
|
+
Optional prop:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cai node optional-props <nodeId> --json
|
|
105
|
+
cai node set <nodeId> --prop <exactName> --value '<literal-or-json>' --json
|
|
106
|
+
# or: cai expr set <nodeId> --prop <exactName> --js '<expression>' --json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
MCP: `cai expr set` is the `js` form of `node_prop_set`.
|
|
110
|
+
|
|
111
|
+
`node set` and `expr set` auto-enable a catalog-only optional prop, refresh its metadata, then write. Do not run a separate enable step first. If validation or the later write fails, the prop stays enabled; repair with `cai node disable-prop <nodeId> --prop <exactName>` and re-read props. This is also the repair for the Update-data wipe footgun: that action writes every enabled field, so disable any accidentally enabled field before running it.
|
|
112
|
+
|
|
113
|
+
MCP: use `node_optional_prop_set` with `enabled: false` to disable or `enabled: true` to enable.
|
|
114
|
+
|
|
115
|
+
Remote or dynamic option:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cai node options <nodeId> --prop <exactName> --query "<specific label>" --json
|
|
119
|
+
cai node set <nodeId> \
|
|
120
|
+
--prop <exactName> \
|
|
121
|
+
--value '<returned value>' \
|
|
122
|
+
--label '<returned label>' \
|
|
123
|
+
--json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`node options` also supports `--prev-context '<context JSON>'` from the preceding page and repeatable `--for '<earlierProp>=<value>'` overrides for read-only hypothetical resolution; JSON literals are accepted and bare text stays a string. If options are `blocked_upstream`, both `node options` and `node set` name the blocking prop and print the exact `cai node set` command to run first.
|
|
127
|
+
|
|
128
|
+
For an ordinary remote option, preserve both fields from the same returned option. The label is not cosmetic: it is used to search providers that do not index opaque IDs, then the returned value is verified before writing. For a multi-select, pass a JSON array of returned values and one `--label` argument per value, in the same order. The write supplies the persisted label shape, chooses the correct expression storage channel, and verifies read-back.
|
|
129
|
+
|
|
130
|
+
When an earlier selector makes the prop `dynamic_upstream`, no option list exists. Use a known exact ID or an expression:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
cai node set <nodeId> --prop <exactName> --value '<exact-id>' --label '<display label>' --json
|
|
134
|
+
cai node set <nodeId> --prop <exactName> --js '<expression>' --json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`--value` stores the literal without provider-option validation and prints a note; on a label-bearing selector, `--label` controls its display label. This is the sole raw `--value` exception when the CLI has an advertised option set: outside `dynamic_upstream`, a missing prop row, a failed or empty advertised remote-options lookup, or a value absent from advertised options fails closed. The exception still requires prop metadata and verified read-back. Do not bypass failures with a raw API call.
|
|
138
|
+
|
|
139
|
+
For components whose dependent props exist only after a concrete selector value, use a template first: set one concrete value, re-read `node props`, configure or record the revealed dependents, then switch the selector to `--js`. Those materialized props persist as the last concrete schema. Starting dynamic leaves them absent; neither that write nor `node reload` materializes them until one concrete selection is made.
|
|
140
|
+
|
|
141
|
+
For dynamic values, load `controllerai-expressions` and prefer `cai expr set`.
|
|
142
|
+
|
|
143
|
+
### 6. Wire and verify
|
|
144
|
+
|
|
145
|
+
Ordinary outputs:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cai node connect --flow <flowId> --from <sourceNodeId> --to <targetNodeId> --output main --json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Use `--output error` only for the automatic error path. Router and If/Else outputs require `cai branch connect` from the flow-control skill.
|
|
152
|
+
|
|
153
|
+
Finish with:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
cai node status <nodeId> --json
|
|
157
|
+
cai run node <nodeId> --inputs <values.json> --json
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
MCP: `run_node` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
|
|
161
|
+
|
|
162
|
+
If the node has a wired input or consumes `inputs.<name>`, the node test is only an isolated configuration check. Run `cai run flow <flowId> --inputs <values.json> --json` before declaring its upstream expressions verified.
|
|
163
|
+
|
|
164
|
+
MCP: `run_flow` takes the parsed `inputs` object and `waitSeconds` (default 60, max 120).
|
|
165
|
+
|
|
166
|
+
If a dynamic provider action cannot be run but its response is documented, declare an unverified output contract:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
cai node declare-output <nodeId> --sample-file provider-response.json --json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
MCP: call `node_output_type_declare` with the parsed provider response in `sample`; the server cannot read `provider-response.json`.
|
|
173
|
+
|
|
174
|
+
The sample must be a JSON object or a non-empty JSON array of provider items. Re-read status and expression context afterward; the first real completed run verifies the declaration.
|
|
175
|
+
|
|
176
|
+
Read [prop-and-readiness.md](prop-and-readiness.md) when a prop is dynamic, option-backed, expression-capable, or unexpectedly absent.
|
|
177
|
+
|
|
178
|
+
## Hard rules
|
|
179
|
+
|
|
180
|
+
- Configure props in returned order; later props may depend on earlier values.
|
|
181
|
+
- Never write a prop absent from `node props`.
|
|
182
|
+
- Let `node set` or `expr set` auto-enable catalog-only optional props; disable the prop explicitly after a failed write.
|
|
183
|
+
- Wire before authoring an expression that consumes upstream data.
|
|
184
|
+
- Changing a connection invalidates connection-scoped options; re-read props and options.
|
|
185
|
+
- A successful write is not completion. Require read-back plus `node status`.
|
|
186
|
+
- If output type remains unresolved, perform a realistic development test and inspect the resulting execution. Declare only a documented provider sample; never fabricate an output schema.
|
|
@@ -1,133 +1,41 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: controllerai-runs
|
|
3
|
-
description:
|
|
3
|
+
description: Test and debug Controller AI workflows, flows and nodes using execution history, inputs, resolved configuration, ports, output values and record effects. Use to prove a build works or investigate a failed or suspicious result.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Prove workflow behavior
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Execution tools show what the platform actually ran: inputs, node configuration, output values, selected ports, skips and errors. Use them to verify contracts and effects, not just a green status.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Select the right test
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- Test a **node** to establish its configuration, provider connection or output shape. Node tests use development state.
|
|
13
|
+
- Run a **flow** to verify connected steps and the return contract. Choose development or the published live version explicitly.
|
|
14
|
+
- Test an **agent conversation** to verify its tool choice and file handling, then correlate workflow calls with their executions.
|
|
15
|
+
- Replay a **trigger sample** into development to verify event-to-flow mapping before enabling live behavior.
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
Development and live use different data stores, but development provider actions can still perform real external operations. Test within the user's authorized scope and use synthetic data where appropriate.
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
- Record deletes/updates → "Is there a record I can safely use, or shall I create one first and delete that?"
|
|
18
|
-
- People-affecting actions (e.g. reject a candidate) → "Which one is safe to use for this run?"
|
|
19
|
+
## Run and inspect
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
Inspect required inputs, pass explicit representative values, and capture the returned execution ID. MCP runs support a bounded wait. A timeout or running status means inspect that execution later; it does not mean repeat the operation.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
cai node declare-output <nodeId> --sample-file shape.json
|
|
24
|
-
```
|
|
23
|
+
Start with the compact execution summary or tree. Drill into a failing, skipped or suspicious node to inspect its received inputs, resolved config and output. Check the expected port before moving downstream. Compare an actual returned value with the promised flow contract.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
For data changes, query the affected records on the same environment. For files, verify the returned artifact and contents. For direct provider actions, verify the provider result or intended external state rather than expecting a workflow ID.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
## Diagnose common failures
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
| Symptom | Inspect next |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| Missing required config | Selector choice, refreshed props, enabled fields and literal/expression mode |
|
|
32
|
+
| Unknown field/binding | Node expression context, exact connection output and current input binding |
|
|
33
|
+
| Empty query | Record environment, field key, optional-filter handling and matching semantics |
|
|
34
|
+
| Provider authentication failure | Connection identity and provider error code; saved active status is not a fresh credential test |
|
|
35
|
+
| Green run but no useful output | Return-node mappings, skipped branches and resolved empty values |
|
|
36
|
+
| Mutation result too large or uncertain | Download/reference receipt and exact current target state before retrying |
|
|
37
|
+
| Graph changed unexpectedly | Saved-state history and current node/edge identities; do not replace a newer graph with a cached copy |
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
Fix the cause and rerun the affected scenario. Broaden tests when the fix changes shared behavior. Keep failed-run evidence with a clear distinction between historical failures and the final verified result.
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
cai run flow <flowId> --inputs values.json --target live --confirm-live --json
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_flow`.
|
|
39
|
-
|
|
40
|
-
This command fires external actions and spends usage. For risky sends, build the safe-audience harness: branch on the `isLiveVersion` data source with If/Else — the false branch targets the developer (own email/channel), the true branch targets the real audience. Use this direct live run for explicit verification; do not wait for a real trigger event.
|
|
41
|
-
|
|
42
|
-
## Prepare exact run inputs
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
cai run inputs <nodeId> --json
|
|
46
|
-
cai run inputs <flowId> --flow --json
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Use returned opaque input IDs. Flow mode lists EVERY declared input with a `used` flag: supply the used ones (an unsupplied used input falls back to its saved test value), while values keyed to unused inputs are accepted and ignored. The input object can be a flat map; the CLI may load it from a file:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"<inputId>": "representative value"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Do not key test values by a guessed display name.
|
|
58
|
-
|
|
59
|
-
Before an isolated node run, `cai run inputs <nodeId> --json` calls `get_node_test_inputs`; supply every referenced `flowInputs[].id` explicitly. Missing one fails before execution with `ISOLATED_FLOW_CONTEXT_REQUIRED`. Explicit `null`, `""`, `false`, and `0` are valid supplied values.
|
|
60
|
-
|
|
61
|
-
Date-typed inputs take plain ISO-8601 strings, e.g. `"2026-06-05"` or `"2026-06-05T12:30:00Z"` (no double-encoding, no epoch strings).
|
|
62
|
-
|
|
63
|
-
## Run the smallest useful scope
|
|
64
|
-
|
|
65
|
-
Start with a changed node, then run its containing flow:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
cai run node <nodeId> --inputs values.json --json
|
|
69
|
-
cai run flow <flowId> --inputs values.json --json
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_node` or `run_flow`.
|
|
73
|
-
|
|
74
|
-
`run node` is deliberately isolated: it does not execute wired upstream nodes. Read its `runScope`. If `endToEndValidationRequired` is true, values derived from upstream can be empty even when the selected node is green; do not accept that run as expression proof. `run flow` is the end-to-end check that executes upstream wiring.
|
|
75
|
-
|
|
76
|
-
The CLI waits for a terminal execution state by default. MCP polling is bounded by `waitSeconds` and may return an unfinished execution ID. Capture `workflowExecutionId` and `nodeExecutionId` from the result.
|
|
77
|
-
|
|
78
|
-
For every node test, inspect:
|
|
79
|
-
|
|
80
|
-
- `status` and `errorMessage`
|
|
81
|
-
- `skipReason`
|
|
82
|
-
- `runScope`, especially `upstreamNodesExecuted` and `endToEndValidationRequired`
|
|
83
|
-
- `resolvedConfigs`
|
|
84
|
-
- `resolvedConfigs[].resolutionWarnings`: trust every structured entry; `[]` is authoritatively clean. Also read any transport warnings; CLI runs may mirror them on stderr.
|
|
85
|
-
- `outputTypeAdoption`: the server verifies the exact completed `nodeExecutionId`, derives its persisted output shape, and updates only that non-static node. `adopted` or `already_typed` lets the next `node status` converge; `no_observed_output` means the representative run returned no reusable shape. `adoptedNodeIds` must be empty or contain only the tested node; stop if it names a sibling.
|
|
86
|
-
- output shape and values
|
|
87
|
-
|
|
88
|
-
A dynamic prop with a null/empty resolved config is a failure even when status is green. `0` and `false` are valid resolved values.
|
|
89
|
-
|
|
90
|
-
## Debug from the execution tree
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
cai exec tree <workflowExecutionId> --limit 50 --json
|
|
94
|
-
cai exec get <workflowExecutionId> --json
|
|
95
|
-
cai exec flow <flowExecutionId> --json
|
|
96
|
-
cai exec node <nodeExecutionId> --full --json
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Page with the returned `nextCursor` via `--cursor`; narrow large runs with repeatable `--status`
|
|
100
|
-
or `--flow <flowId>`. Use the tree to locate the first unexpected status. Use the full node
|
|
101
|
-
execution to inspect its status, resolved configuration, and untruncated output. Read
|
|
102
|
-
[references/debugging.md](references/debugging.md) for the fault-isolation order.
|
|
103
|
-
|
|
104
|
-
## Output discovery
|
|
105
|
-
|
|
106
|
-
Prefer a configured node test. If a component is not yet in the graph, `run discover` creates a scratch node and deletes it after execution:
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
cai run discover \
|
|
110
|
-
--node <nodeSlug> \
|
|
111
|
-
--key <nodeKey> \
|
|
112
|
-
--connection <connectionId|none> \
|
|
113
|
-
--props '<json>' \
|
|
114
|
-
--json
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
MCP: `run_discover` always removes the scratch graph and exposes neither `keep` nor `waitSeconds`.
|
|
118
|
-
|
|
119
|
-
This calls the real third-party action and spends usage. For a destructive action, do not probe merely to learn its output — first ask the user for a safe target (see "Consequential actions" above); if they decline, declare the expected shape instead. On CLI, use `--keep` only when the user wants the scratch node retained.
|
|
120
|
-
|
|
121
|
-
After successful output discovery, re-read `cai node status` and downstream `cai expr context`; verify the adopted output type is concrete.
|
|
122
|
-
|
|
123
|
-
## Completion gate
|
|
124
|
-
|
|
125
|
-
- CLI scripts may gate on `cai workflow validate` exiting 1; MCP callers inspect `valid` and `errors`.
|
|
126
|
-
- The test exercised the changed path with credible values.
|
|
127
|
-
- The first unexpected node, if any, was identified rather than inferred from the final error.
|
|
128
|
-
- All dynamic configs resolved to intended values.
|
|
129
|
-
- Output fields and types match downstream expectations.
|
|
130
|
-
- Branch skips are intentional and error paths are accounted for.
|
|
131
|
-
- A full flow test passes after isolated node fixes.
|
|
132
|
-
- `completed` with an empty or null output is treated as a failure until the output values are read and explained — an empty result usually means a mis-mapped input or an expression that null-propagated silently.
|
|
133
|
-
- The final report cites execution IDs and distinguishes development testing from live verification.
|
|
41
|
+
Commands: [reference](references/command-reference.md). Execution details: [debugging](references/debugging.md).
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Controller AI runs
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Think "real run", not "simulation". `run node` always uses development; `run flow` defaults to development and can target the published live version. Both rails execute real integration actions (messages send, records change, provider usage is spent); development isolation covers the data store only. Running is a required part of building — one successful run is how a dynamic node's output type gets resolved for the next step — so mitigate risk before running.
|
|
5
|
+
|
|
6
|
+
## Consequential actions: mitigate with the user, don't refuse
|
|
7
|
+
|
|
8
|
+
Use the task's existing authorization and a safe test target for actions with external consequences. For authorized CRUD testing, create synthetic records and exercise updates/deletion on those. Ask only when a needed external side effect or target is not covered by the user's request. Test runs execute real actions.
|
|
9
|
+
|
|
10
|
+
## First live run is part of development
|
|
11
|
+
|
|
12
|
+
After publishing, run the published version directly under supervision:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cai run flow <flowId> --inputs values.json --target live --confirm-live --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_flow`.
|
|
19
|
+
|
|
20
|
+
This command fires external actions and spends usage. For risky sends, build the safe-audience harness: branch on the `isLiveVersion` data source with If/Else — the false branch targets the developer (own email/channel), the true branch targets the real audience. Use this direct live run for explicit verification; do not wait for a real trigger event.
|
|
21
|
+
|
|
22
|
+
## Prepare exact run inputs
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cai run inputs <nodeId> --json
|
|
26
|
+
cai run inputs <flowId> --flow --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use returned opaque input IDs. Flow mode lists EVERY declared input with a `used` flag: supply the used ones (an unsupplied used input falls back to its saved test value), while values keyed to unused inputs are accepted and ignored. The input object can be a flat map; the CLI may load it from a file:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"<inputId>": "representative value"
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Do not key test values by a guessed display name.
|
|
38
|
+
|
|
39
|
+
Before an isolated node run, `cai run inputs <nodeId> --json` calls `get_node_test_inputs`; supply every referenced `flowInputs[].id` explicitly. Missing one fails before execution with `ISOLATED_FLOW_CONTEXT_REQUIRED`. Explicit `null`, `""`, `false`, and `0` are valid supplied values.
|
|
40
|
+
|
|
41
|
+
Date-typed inputs take plain ISO-8601 strings, e.g. `"2026-06-05"` or `"2026-06-05T12:30:00Z"` (no double-encoding, no epoch strings).
|
|
42
|
+
|
|
43
|
+
## Run the smallest useful scope
|
|
44
|
+
|
|
45
|
+
Start with a changed node, then run its containing flow:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cai run node <nodeId> --inputs values.json --json
|
|
49
|
+
cai run flow <flowId> --inputs values.json --json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
MCP: pass parsed values in `inputs` and set `waitSeconds` on `run_node` or `run_flow`.
|
|
53
|
+
|
|
54
|
+
`run node` is deliberately isolated: it does not execute wired upstream nodes. Read its `runScope`. If `endToEndValidationRequired` is true, values derived from upstream can be empty even when the selected node is green; do not accept that run as expression proof. `run flow` is the end-to-end check that executes upstream wiring.
|
|
55
|
+
|
|
56
|
+
The CLI waits for a terminal execution state by default. MCP polling is bounded by `waitSeconds` and may return an unfinished execution ID. Capture `workflowExecutionId` and `nodeExecutionId` from the result.
|
|
57
|
+
|
|
58
|
+
For every node test, inspect:
|
|
59
|
+
|
|
60
|
+
- `status` and `errorMessage`
|
|
61
|
+
- `skipReason`
|
|
62
|
+
- `runScope`, especially `upstreamNodesExecuted` and `endToEndValidationRequired`
|
|
63
|
+
- `resolvedConfigs`
|
|
64
|
+
- `resolvedConfigs[].resolutionWarnings`: trust every structured entry; `[]` is authoritatively clean. Also read any transport warnings; CLI runs may mirror them on stderr.
|
|
65
|
+
- `outputTypeAdoption`: the server verifies the exact completed `nodeExecutionId`, derives its persisted output shape, and updates only that non-static node. `adopted` or `already_typed` lets the next `node status` converge; `no_observed_output` means the representative run returned no reusable shape. `adoptedNodeIds` must be empty or contain only the tested node; stop if it names a sibling.
|
|
66
|
+
- output shape and values
|
|
67
|
+
|
|
68
|
+
A dynamic prop with a null/empty resolved config is a failure even when status is green. `0` and `false` are valid resolved values.
|
|
69
|
+
|
|
70
|
+
## Debug from the execution tree
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cai exec tree <workflowExecutionId> --limit 50 --json
|
|
74
|
+
cai exec get <workflowExecutionId> --json
|
|
75
|
+
cai exec flow <flowExecutionId> --json
|
|
76
|
+
cai exec node <nodeExecutionId> --full --json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Page with the returned `nextCursor` via `--cursor`; narrow large runs with repeatable `--status`
|
|
80
|
+
or `--flow <flowId>`. Use the tree to locate the first unexpected status. Use the full node
|
|
81
|
+
execution to inspect its status, resolved configuration, and untruncated output. Read
|
|
82
|
+
[debugging.md](debugging.md) for the fault-isolation order.
|
|
83
|
+
|
|
84
|
+
## Output discovery
|
|
85
|
+
|
|
86
|
+
Prefer a configured node test. If a component is not yet in the graph, `run discover` creates a scratch node and deletes it after execution:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cai run discover \
|
|
90
|
+
--node <nodeSlug> \
|
|
91
|
+
--key <nodeKey> \
|
|
92
|
+
--connection <connectionId|none> \
|
|
93
|
+
--props '<json>' \
|
|
94
|
+
--json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
MCP: `run_discover` always removes the scratch graph and exposes neither `keep` nor `waitSeconds`.
|
|
98
|
+
|
|
99
|
+
This calls the real third-party action and spends usage. For a destructive action, do not probe merely to learn its output — first ask the user for a safe target (see "Consequential actions" above); if they decline, declare the expected shape instead. On CLI, use `--keep` only when the user wants the scratch node retained.
|
|
100
|
+
|
|
101
|
+
After successful output discovery, re-read `cai node status` and downstream `cai expr context`; verify the adopted output type is concrete.
|
|
102
|
+
|
|
103
|
+
## Completion gate
|
|
104
|
+
|
|
105
|
+
- CLI scripts may gate on `cai workflow validate` exiting 1; MCP callers inspect `valid` and `errors`.
|
|
106
|
+
- The test exercised the changed path with credible values.
|
|
107
|
+
- The first unexpected node, if any, was identified rather than inferred from the final error.
|
|
108
|
+
- All dynamic configs resolved to intended values.
|
|
109
|
+
- Output fields and types match downstream expectations.
|
|
110
|
+
- Branch skips are intentional and error paths are accounted for.
|
|
111
|
+
- A full flow test passes after isolated node fixes.
|
|
112
|
+
- `completed` with an empty or null output is treated as a failure until the output values are read and explained — an empty result usually means a mis-mapped input or an expression that null-propagated silently.
|
|
113
|
+
- The final report cites execution IDs and distinguishes development testing from live verification.
|
|
@@ -1,89 +1,58 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: controllerai-start
|
|
3
|
-
description:
|
|
3
|
+
description: Understand Controller AI and choose, build, test, or operate its agents, workflows, integrations, triggers and workflow data stores through MCP or the cai CLI. Use at the start of a Controller AI task, especially when a user describes an outcome without naming the right platform surface.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Build with Controller AI
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Controller AI is a platform for agents that do work and reusable automations that those agents can call. You are the builder: create and operate the user's artifacts through the connected tools. A **Controller AI agent** is the user-facing assistant you build, not you.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## What the platform can do
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
| Building block | What it provides | Choose it for |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| Agent | Chat, reasoning, uploaded files, knowledge, integration actions and workflow tools | An assistant a person talks to, including “drop this CSV here and enrich it” |
|
|
15
|
+
| Ready integration action | One existing operation in an external app or native service | Search the web, read a sheet, create a CRM contact; attach directly to an agent when sufficient |
|
|
16
|
+
| Workflow | A container of reusable typed flows, shared schemas and durable data | Deterministic processing, business rules, reusable APIs, scheduled or event-driven work |
|
|
17
|
+
| Flow | One callable contract: typed inputs, connected nodes, typed return values | `researchInvestor(name, company)`, `createContact(...)`, `searchContacts(...)` |
|
|
18
|
+
| Nodes and expressions | Actions, calculations, branches, loops and subflow calls | Transform and route values without writing an application server |
|
|
19
|
+
| Workflow data store | Custom schemas and persisted records, with separate development and live stores | A CRM, tracker, knowledge index, audit log or application state |
|
|
20
|
+
| Trigger | Schedule, webhook, email or integration event mapped into a flow | Run an automation without a chat message |
|
|
13
21
|
|
|
14
|
-
|
|
22
|
+
An agent can call several flows in one workflow. Their inputs become tool arguments and their flow outputs become tool results. The data store is shared by that workflow's flows on the selected environment. Reusable flow contracts make a workflow an agent's application backend.
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
- **Finished agent:** Call `agent_present` and relay the returned agent card, including its link.
|
|
18
|
-
- **File for the user:** Call `file_share` and relay its returned link; Claude Code users may also just read it from the terminal.
|
|
24
|
+
## Choose the deliverable from the experience
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
Use the user's intended interaction, even when they casually call everything a “workflow.”
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
- **File dropped into chat → enriched file back:** build an agent plus a per-record enrichment flow. The agent reads the attachment, handles rows and CSV formatting, calls the flow, and shares the resulting file. A workflow's `file` value is hosted-file metadata; it is not a native chat attachment upload or CSV parser.
|
|
29
|
+
- **CRM for an agent:** build a workflow containing typed CRUD/search flows over custom data schemas. Add a conversational agent only if requested or needed for the interaction.
|
|
30
|
+
- **One app operation:** attach the discovered action directly to the agent. A workflow wrapper is useful when it adds validation, transformation, persistence or a stable contract.
|
|
31
|
+
- **Several steps on an event:** build a workflow and trigger. Add an agent when a human also needs to ask questions or direct the process.
|
|
23
32
|
|
|
24
|
-
|
|
33
|
+
Make reasonable routine choices from context. Ask for missing information only when it changes the intended result; meanwhile finish independent work. A limitation in one surface can often be solved by combining the platform's surfaces. Explain a necessary change in architecture and keep pursuing the original outcome.
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
## Orient once, then build
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
cai doctor
|
|
30
|
-
```
|
|
37
|
+
Use `account_status` to identify the connected workspace. MCP is already authenticated and has no local workflow pin: pass the returned `workflowId` on scoped calls. Do not ask an authenticated user to sign up again. Account claiming is optional and relevant to recovery or usage limits, not a build or publishing prerequisite.
|
|
31
38
|
|
|
32
|
-
For a new
|
|
33
|
-
Cursor, ensures login, and installs the best available plugin or MCP-and-skills
|
|
34
|
-
fallback; use `cai agent setup --status --json` for a read-only machine plan.
|
|
35
|
-
Use `cai doctor` to compare installed version stamps and see the exact update
|
|
36
|
-
command, and `cai docs [path]` (or `cai docs --list`) to read platform docs in
|
|
37
|
-
the terminal.
|
|
39
|
+
For an existing artifact, resolve its exact ID and inspect its outline or tool list. Keep returned IDs during the task. For a new artifact, create it and use its returned ID; inspect `flowCount` and `nextStep`: reuse a returned default flow, or create the first flow when the workflow is empty.
|
|
38
40
|
|
|
39
|
-
MCP
|
|
41
|
+
Use the tools actually available in the session. MCP takes inline JSON/text; CLI examples take files where shown and accept `--json` for machine-readable output. The [tool map](references/mcp-tool-map.md) maps the CLI grammar to MCP names and exceptions. There is no need to perform local CLI installation to use connected MCP.
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
## Build, verify and deliver
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
1. Define the experience and a small representative test. For a complex API, decide schemas, inputs, outputs and error behavior before assembling nodes.
|
|
46
|
+
2. Discover capabilities and current schemas. Use exact action keys and the current expression bindings rather than guessing names.
|
|
47
|
+
3. Build a complete path, then test its actual outputs and stored or external effects. Expand the proven pattern to the remaining paths.
|
|
48
|
+
4. Validate the graph, inspect suspicious runs, and re-read saved state. A green run alone does not prove returned data or persistence is correct.
|
|
49
|
+
5. Publish when the user's request authorizes a live result. Explicit authorization persists; do not ask again just because publishing is the next step. Verify the live result after publication.
|
|
50
|
+
6. Return product links, the observed result, environment and any concrete limitation. Remove only scratch artifacts you created for abandoned attempts.
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
Development graph edits are separate from the published live graph. Publishing does **not** copy development records into the live data store. Agents have their own draft/published versions; agent Test calls development workflows, while Live calls each workflow's latest live release.
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
For mutation errors or large-result downloads, inspect the complete result and the target state before retrying a create. Missing projected fields do not prove failure. Never treat an unknown outcome as permission to repeat a write.
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
Deleting a connection immediately removes authorization from bound nodes and agent tools.
|
|
56
|
+
## Go deeper when needed
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Identify the deliverable before mutating anything:
|
|
55
|
-
|
|
56
|
-
| Outcome | Load next |
|
|
57
|
-
| --- | --- |
|
|
58
|
-
| A user-facing agent that can converse and act | `controllerai-agents` |
|
|
59
|
-
| One ready app operation attached to an agent | `controllerai-integration-actions` and `controllerai-agents` |
|
|
60
|
-
| A multi-step, triggered, stateful, or reusable automation | `controllerai-workflows` plus the relevant workflow skills |
|
|
61
|
-
| An agent with orchestrated capabilities | `controllerai-agents`, then both integration-action and workflow skills as needed |
|
|
62
|
-
|
|
63
|
-
Prefer a ready integration action when one existing operation completes the capability. Use a workflow when the behavior needs multiple steps, transformations, branches, loops, durable data, triggers, custom typed input/output, or reuse outside the agent.
|
|
64
|
-
|
|
65
|
-
If the user's outcome does not reveal whether they want an agent or an automation that runs on an event, ask one short clarifying question. Otherwise proceed with the smallest suitable surface.
|
|
66
|
-
|
|
67
|
-
## Lock targets before mutation
|
|
68
|
-
|
|
69
|
-
Before the first write, resolve every existing target against the effective workflow. Prefer an explicit ID or an object already connected to the pinned workflow. When a list is account-wide, filter it by exact name or ID; never take the first, latest, or similarly named result. Read back the chosen object's ID, name, and owning workflow or flow. Keep those IDs for the task and never rediscover the target by name.
|
|
70
|
-
|
|
71
|
-
Check `ok` and the complete `data` object from every mutation before projecting fields. A missing projected field is not proof that the mutation failed. Read back the returned ID or list the exact target before retrying. Never repeat a create until readback proves the first call created nothing.
|
|
72
|
-
|
|
73
|
-
## Platform docs
|
|
74
|
-
|
|
75
|
-
The platform reference lives at https://docs.getcontroller.ai. Fetch https://docs.getcontroller.ai/llms.txt for the machine-readable index of every page; append `.md` to any page path for raw markdown (for example https://docs.getcontroller.ai/start/safety.md), or fetch /llms-full.txt for the whole corpus at once. Skills remain the procedural authority — consult the docs for what they do not carry: the execution and cost models, type-system and version-rail contracts, the full CLI and expression-operation references, and the workflow API. When a docs page and a skill disagree, prefer the skill and its live platform queries (`cai expr ops`, `cai integration actions`).
|
|
76
|
-
|
|
77
|
-
## Keep rails explicit
|
|
78
|
-
|
|
79
|
-
- Agent Test mode uses the owner's mutable draft, current workflow development heads, current draft knowledge, and live runtime files overlaid by development/test runtime files. Live mode uses the latest published agent version, each workflow's latest live release, frozen published knowledge, and live runtime files only.
|
|
80
|
-
- Agent draft edits require another agent publish to reach Live. Publishing restamps existing live conversations; shared users always receive the latest published version and never the draft.
|
|
81
|
-
- Workflow publishes and direct-action connection/authorization grants are live bindings: a rebind can redirect Live, while revocation or detachment can block Live without another agent publish.
|
|
82
|
-
- Coding-agent subscriptions cover builder reasoning, not Controller AI hosted-agent runtime usage.
|
|
83
|
-
- Provider actions can send messages, mutate or delete records, and incur provider charges. Decide the per-action confirmation policy before attaching one.
|
|
84
|
-
- Never publish, share with the organization, replay a live trigger, or perform a consequential external test without clear user intent.
|
|
85
|
-
- A missing business rule is a blocker, not permission to infer one from names or sample data. Ask the user and leave the affected state unchanged.
|
|
86
|
-
- Stop when the requested state and its required evidence are reached. Do not add objects, publish, or keep probing beyond that boundary.
|
|
87
|
-
- When a platform limitation blocks the outcome, STOP and report the partial result with the blocking error; never keep probing until the clock expires.
|
|
88
|
-
|
|
89
|
-
At completion, report what was created, what is still draft or live, the evidence actually observed, and any connection or user decision still required.
|
|
58
|
+
Load the relevant skill at the point of use: `controllerai-agents`, `controllerai-workflows`, `controllerai-data`, `controllerai-expressions`, `controllerai-node-config`, `controllerai-flow-control`, `controllerai-triggers`, `controllerai-runs`, `controllerai-ai-nodes`, or `controllerai-integration-actions`. Each explains its capability and links detailed command examples. Platform reference: https://docs.getcontroller.ai/llms.txt; hosted current guides: `guide_list` and `guide_get`.
|
|
@@ -168,3 +168,9 @@ This registry-derived map covers 162 CLI commands and 149 typed MCP tools. CLI e
|
|
|
168
168
|
| `cai workflow status` | `workflow_status` | `--workflow` → `workflowId` | — |
|
|
169
169
|
| `cai workflow validate` | `workflow_validate` | `--workflow` → `workflowId` | — |
|
|
170
170
|
| `cai workflow versions` | `workflow_version_list` | `<workflowId>` / `--workflow` → `workflowId` | — |
|
|
171
|
+
|
|
172
|
+
## Conversation files and compact history
|
|
173
|
+
|
|
174
|
+
`agent_conversation_file_add` accepts `conversationId`, `name`, `type`, and inline text `content`. `agent_conversation_file_list` returns both chat attachments and context files, with `cursor`, `limit`, and `search`. Read UTF-8 content using `agent_conversation_file_read`; retrieve original bytes through `agent_conversation_file_download`, which returns a temporary downloadable URL. Both take the conversation and file IDs.
|
|
175
|
+
|
|
176
|
+
Conversation history defaults to a compact, paginated message view. Use `limit` and `before`; `raw: true` is for SDK diagnostics only. On the CLI, the corresponding commands are `agent conversation add-file`, `files`, `read-file`, and `download-file --out <path>`. CLI upload uses `--file`, while MCP upload uses inline `content`.
|