@controllerai/cli 0.2.0
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/README.md +180 -0
- package/dist/api/client.js +330 -0
- package/dist/api/client.js.map +1 -0
- package/dist/appLinks.js +99 -0
- package/dist/appLinks.js.map +1 -0
- package/dist/argv.js +124 -0
- package/dist/argv.js.map +1 -0
- package/dist/commands/agent.js +813 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/auth.js +327 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/branch.js +441 -0
- package/dist/commands/branch.js.map +1 -0
- package/dist/commands/connect.js +148 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/connection.js +148 -0
- package/dist/commands/connection.js.map +1 -0
- package/dist/commands/data.js +441 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/deps.js +63 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/doctor.js +102 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +72 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/exec.js +306 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/expr.js +346 -0
- package/dist/commands/expr.js.map +1 -0
- package/dist/commands/flow.js +447 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/integration.js +102 -0
- package/dist/commands/integration.js.map +1 -0
- package/dist/commands/node.js +885 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/organize.js +234 -0
- package/dist/commands/organize.js.map +1 -0
- package/dist/commands/run.js +437 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/schema.js +269 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/skills.js +1156 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/trigger.js +992 -0
- package/dist/commands/trigger.js.map +1 -0
- package/dist/commands/workflow.js +503 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +39 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/jsSource.js +32 -0
- package/dist/jsSource.js.map +1 -0
- package/dist/nodeProps.js +177 -0
- package/dist/nodeProps.js.map +1 -0
- package/dist/output.js +85 -0
- package/dist/output.js.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +41 -0
- package/skills/controllerai-agents/SKILL.md +169 -0
- package/skills/controllerai-agents/agents/openai.yaml +4 -0
- package/skills/controllerai-agents/references/instructions-and-versioning.md +76 -0
- package/skills/controllerai-ai-nodes/SKILL.md +83 -0
- package/skills/controllerai-ai-nodes/agents/openai.yaml +4 -0
- package/skills/controllerai-ai-nodes/references/selection-and-testing.md +46 -0
- package/skills/controllerai-data/SKILL.md +121 -0
- package/skills/controllerai-data/agents/openai.yaml +4 -0
- package/skills/controllerai-data/references/data-rails.md +46 -0
- package/skills/controllerai-expressions/SKILL.md +115 -0
- package/skills/controllerai-expressions/agents/openai.yaml +4 -0
- package/skills/controllerai-expressions/references/dsl-and-recipes.md +120 -0
- package/skills/controllerai-flow-control/SKILL.md +132 -0
- package/skills/controllerai-flow-control/agents/openai.yaml +4 -0
- package/skills/controllerai-flow-control/references/patterns.md +61 -0
- package/skills/controllerai-integration-actions/SKILL.md +95 -0
- package/skills/controllerai-integration-actions/agents/openai.yaml +4 -0
- package/skills/controllerai-node-config/SKILL.md +138 -0
- package/skills/controllerai-node-config/agents/openai.yaml +4 -0
- package/skills/controllerai-node-config/references/prop-and-readiness.md +72 -0
- package/skills/controllerai-runs/SKILL.md +109 -0
- package/skills/controllerai-runs/agents/openai.yaml +4 -0
- package/skills/controllerai-runs/references/debugging.md +53 -0
- package/skills/controllerai-start/SKILL.md +44 -0
- package/skills/controllerai-start/agents/openai.yaml +4 -0
- package/skills/controllerai-triggers/SKILL.md +174 -0
- package/skills/controllerai-triggers/agents/openai.yaml +4 -0
- package/skills/controllerai-triggers/references/lifecycle.md +54 -0
- package/skills/controllerai-workflows/SKILL.md +86 -0
- package/skills/controllerai-workflows/agents/openai.yaml +4 -0
- package/skills/controllerai-workflows/references/command-map.md +64 -0
- package/skills/manifest.json +248 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
const packageMetadata = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
3
|
+
if (typeof packageMetadata.version !== 'string' || !packageMetadata.version) {
|
|
4
|
+
throw new Error('CLI package.json does not contain a valid version.');
|
|
5
|
+
}
|
|
6
|
+
export const CLI_VERSION = packageMetadata.version;
|
|
7
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAChC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CACzC,CAAA;AAE1B,IAAI,OAAO,eAAe,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;IAC5E,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@controllerai/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Build and operate Controller AI workflows and agents from any AI coding agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cai": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public",
|
|
12
|
+
"provenance": true
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"skills"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -p tsconfig.json && node scripts/sync-skills.mjs",
|
|
23
|
+
"lint": "tsc -p tsconfig.json --noEmit && eslint 'src/**/*.ts' 'test/**/*.ts'",
|
|
24
|
+
"test": "node scripts/sync-skills.mjs && node --test --import tsx test/*.test.ts test/*.test.mjs",
|
|
25
|
+
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
|
|
26
|
+
"dev": "tsx src/index.ts",
|
|
27
|
+
"prepack": "yarn build"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"commander": "^12.1.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.14.0",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
35
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
36
|
+
"eslint": "^8.57.0",
|
|
37
|
+
"prettier": "^3.3.3",
|
|
38
|
+
"tsx": "^4.19.0",
|
|
39
|
+
"typescript": "^5.5.4"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-agents
|
|
3
|
+
description: Design, assemble, test, publish, and share user-facing Controller AI agents with ready integration actions, workflow tools, instructions, and knowledge files. Use when creating or editing an agent, choosing its tool architecture, attaching or updating tools, verifying draft/live conversations, or publishing and sharing an agent safely.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI agents
|
|
7
|
+
|
|
8
|
+
An agent has one mutable draft and immutable published versions. Its capabilities may be ready integration actions, workflow tools, or both. Build on the draft, verify through a draft conversation, and publish the agent last. Editing the draft never updates the live agent by itself.
|
|
9
|
+
|
|
10
|
+
Agent design is a lifecycle — hold the whole arc, not just the current step:
|
|
11
|
+
|
|
12
|
+
1. Write the instructions (the agent's system prompt).
|
|
13
|
+
2. Add tools — workflow flows and/or ready integration actions.
|
|
14
|
+
3. Set each tool's permission level WITH the user — HITL is a design decision.
|
|
15
|
+
4. Set tool descriptions (optional but powerful for workflow tools).
|
|
16
|
+
5. Add reference files (`txt, md, json, csv, html, xml`).
|
|
17
|
+
6. Save — the draft IS the test environment.
|
|
18
|
+
7. Test it — and let the user test it in the product themselves.
|
|
19
|
+
8. Publish when it looks good.
|
|
20
|
+
9. Offer Slack access and organization sharing.
|
|
21
|
+
|
|
22
|
+
Use the `cai` CLI only. Do not call Controller AI REST or MCP routes directly.
|
|
23
|
+
|
|
24
|
+
## 1. Choose the capability architecture
|
|
25
|
+
|
|
26
|
+
For each capability:
|
|
27
|
+
|
|
28
|
+
- Use `controllerai-integration-actions` when one existing app operation completes it.
|
|
29
|
+
- Use a workflow tool for multiple steps, transformations, branching, looping, durable state, triggers, a custom typed contract, or reusable business logic.
|
|
30
|
+
- Put conversational judgment, when-to-use rules, tone, and escalation in agent instructions.
|
|
31
|
+
- Put stable source material in a knowledge file.
|
|
32
|
+
|
|
33
|
+
Do not create a one-node workflow merely to expose a ready action. Do not replace orchestration with several independent direct actions when ordering or data handling must be deterministic.
|
|
34
|
+
|
|
35
|
+
## 2. Build and verify capabilities
|
|
36
|
+
|
|
37
|
+
For a ready action, follow `controllerai-integration-actions`: discover the exact integration/action, select a connection, decide confirmation policy, then attach it.
|
|
38
|
+
|
|
39
|
+
For every workflow tool, load the relevant workflow skills and test the development state before attaching:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cai use <workflowId>
|
|
43
|
+
cai flow get <flowId> --json
|
|
44
|
+
cai run flow <flowId> --inputs values.json --json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Capture the successful workflow execution ID. Workflow inputs become tool parameters and outputs become its result.
|
|
48
|
+
|
|
49
|
+
## 3. Create and assemble the draft
|
|
50
|
+
|
|
51
|
+
Write short instructions covering role, tool-selection rules, expected inputs/results, safety boundaries, response style, and error behavior. Require: "If an action returns an error, tell the user what failed and what you were trying to do; do not retry more than once."
|
|
52
|
+
|
|
53
|
+
Read [references/instructions-and-versioning.md](references/instructions-and-versioning.md) before publishing or explaining Test versus Live behavior.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cai agent create --name "<agent name>" --instructions-file instructions.md --json
|
|
57
|
+
|
|
58
|
+
cai agent add-action <agentId> \
|
|
59
|
+
--integration <integrationSlug> \
|
|
60
|
+
--action <actionKey> \
|
|
61
|
+
--connection <connectionId> \
|
|
62
|
+
--description "Use when ..." \
|
|
63
|
+
--json
|
|
64
|
+
|
|
65
|
+
cai agent add-workflow <agentId> \
|
|
66
|
+
--workflow-id <workflowId> \
|
|
67
|
+
--flow <flowId> \
|
|
68
|
+
--description "Use when ...; accepts ...; returns ..." \
|
|
69
|
+
--json
|
|
70
|
+
|
|
71
|
+
cai agent add-file <agentId> --file <path> --json
|
|
72
|
+
cai agent tools <agentId> --json
|
|
73
|
+
cai agent get <agentId> --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Permission is part of agent design, not an afterthought. For every tool, settle the approval level WITH the user before attaching: present the tool list and ask which steps they want a human in the loop for ("should sending the email require your approval each time, or run automatically?"). The default is no approval. Add `--require-confirmation` for consequential writes, deletion, external communications, permission changes, purchases/spend, or an ambiguous destination; `cai agent update-tool` changes it later. Omitting the flag must be the user's informed autonomy decision, not an unnoticed default.
|
|
77
|
+
|
|
78
|
+
Keep the two modes straight:
|
|
79
|
+
|
|
80
|
+
| Context | Test / draft conversation | Live / shared conversation |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| Agent configuration | Current mutable draft | Latest published immutable agent version |
|
|
83
|
+
| Workflow tools | Current workflow development heads | Each workflow's latest live release; never pinned |
|
|
84
|
+
| Reference files | Current draft knowledge files | Knowledge frozen into the published agent version |
|
|
85
|
+
| Runtime files | Current live runtime files, overlaid by development/test runtime files at the same path | Current live runtime files only |
|
|
86
|
+
| Access | Owner only | Owner, plus organization members when shared; non-owners never see the draft |
|
|
87
|
+
|
|
88
|
+
Publishing the agent snapshots its display name, instructions, tool identities, descriptions and approval policies, and knowledge files. It moves the live pointer and restamps every existing live conversation to that new version. It does not snapshot the selected runtime model.
|
|
89
|
+
|
|
90
|
+
Publishing is a hard cutover: live conversations that are mid-turn are interrupted immediately (the person's in-flight answer never arrives), their unexecuted approval requests expire, and each conversation reopens on its own next message running the new version. Time publishes with that in mind and tell the user what a publish does to active conversations.
|
|
91
|
+
|
|
92
|
+
## Runtime usage boundary
|
|
93
|
+
|
|
94
|
+
The user's local Codex, Claude, or other coding-agent subscription can cover builder reasoning. Hosted agent tests and conversations consume Controller AI runtime usage from the organization's shared pool. Connected providers may add charges or side effects. State this before starting a hosted test or describing this route as free.
|
|
95
|
+
|
|
96
|
+
## 4. Verify the draft as an agent
|
|
97
|
+
|
|
98
|
+
Saving the draft is what updates the agent's Test environment — there is no separate deploy step for testing. Test conversations run each workflow tool's DEVELOPMENT version.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cai agent test <agentId> --draft --message "<representative request>" --json
|
|
102
|
+
cai agent conversation history <conversationId> --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Test requests that should and should not select each tool. Verify exact arguments, truthful use of results, errors, and knowledge behavior.
|
|
106
|
+
|
|
107
|
+
The user can also test the draft themselves in the product — offer them the agent's page in the app so they can try it hands-on before publishing (`cai agent create`/`publish`/`test` outputs include `appUrl` links to the agent and conversation pages when the app origin is known). Their impression of the conversation matters more than your transcript reading.
|
|
108
|
+
|
|
109
|
+
- For a workflow tool, correlate a side-effectful call with its terminal workflow execution ID.
|
|
110
|
+
- For a direct integration action, inspect persisted conversation action events/run result and the intended external effect. Direct actions do not create workflow execution IDs.
|
|
111
|
+
|
|
112
|
+
For pending approval, inspect the exact request before choosing:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cai agent conversation approve <conversationId> --request <requestId> --tool <toolName> --json
|
|
116
|
+
cai agent conversation deny <conversationId> --request <requestId> --tool <toolName> --message "<reason>" --json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Do not approve merely to make a test continue.
|
|
120
|
+
|
|
121
|
+
## 5. Publish in dependency order
|
|
122
|
+
|
|
123
|
+
For attached workflows only:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cai use <workflowId>
|
|
127
|
+
cai workflow status --json
|
|
128
|
+
cai workflow publish --name "<release>" --json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Publish the workflow only when its verified development state must become live and the user authorized it. Publishing a workflow already followed by any live agent changes that tool's live behavior immediately; do not republish the agent merely to pick up that workflow release.
|
|
132
|
+
|
|
133
|
+
Then publish the agent:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
cai agent publish-preflight <agentId> --json
|
|
137
|
+
cai agent publish <agentId> --name "<release>" --json
|
|
138
|
+
cai agent versions <agentId> --json
|
|
139
|
+
cai agent test <agentId> --live --message "<representative request>" --json
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Use this update loop for versioned agent state: edit the draft, read it back, verify in Test, publish the agent, then verify Live. A name, instruction, tool identity, tool description, approval-policy, or knowledge-file change is not reflected in the published agent version until the agent is published again.
|
|
143
|
+
|
|
144
|
+
There is no rollback for published agent versions — never promise to "revert" an agent. Recovery is forward: bring the DRAFT back to the wanted state, then publish a new version on top. For the agent itself, read the earlier version's snapshot (`cai agent versions`, then get that version) and re-apply its content to the draft. For a workflow tool, `cai workflow history` + `cai workflow restore <stateId>` returns the dev DEFINITION (graph and schemas; deactivated types reactivate) — record data is not versioned and stays as it currently is — then republish the workflow.
|
|
145
|
+
|
|
146
|
+
The explicit live-bound exceptions are:
|
|
147
|
+
|
|
148
|
+
- Workflow tools resolve the workflow's latest live release per runtime session, so a later workflow publish changes live behavior without another agent publish. An in-flight turn or approval episode may finish on its cached prior release; verify with a fresh Live conversation after the session refresh.
|
|
149
|
+
- A direct action's connection and authorization grant are live security bindings, not frozen version data. Rebinding the grant can redirect Live immediately; failure, revocation, or detachment can block Live immediately. Detaching also edits the draft, so publish the agent afterward to remove the unavailable tool from the published tool list.
|
|
150
|
+
- Runtime files are not part of the agent snapshot. Live conversations read current live runtime files; Test additionally overlays development/test runtime files, with the development copy winning on a path collision.
|
|
151
|
+
|
|
152
|
+
Draft evidence does not prove the live agent. Test is owner-only. Shared users always run the latest published agent version and never receive draft instructions, draft tools, or draft knowledge.
|
|
153
|
+
|
|
154
|
+
## 6. Offer Slack and organization sharing
|
|
155
|
+
|
|
156
|
+
After a successful publish, offer the next steps rather than waiting to be asked:
|
|
157
|
+
|
|
158
|
+
- **Slack**: if the user wants to talk to the agent in Slack, that requires the Slack ↔ Controller AI connection plus per-agent Slack configuration (agent slug, channel) — both set up in the product, not the CLI. Point the user to the relevant product page and offer to walk them through it.
|
|
159
|
+
- **Sharing**: agents remain private unless the user explicitly asks for organization access:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
cai agent visibility <agentId> --value organization --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Organization members use the published version. Direct actions run through the agent owner's connected external account, while Controller AI usage comes from the organization's shared pool. Rebinding, revoking, or detaching that live grant can immediately affect published agents. Return to private visibility to revoke organization access.
|
|
166
|
+
|
|
167
|
+
## Final report
|
|
168
|
+
|
|
169
|
+
State the agent ID/version, tool types and identities, confirmation policies, workflow execution evidence, direct-action conversation/run evidence, draft/live status, live connection bindings, organization access, and anything unverified.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Controller AI Agents"
|
|
3
|
+
short_description: "Build and publish agents with the right tools"
|
|
4
|
+
default_prompt: "Use $controllerai-agents to build or edit this Controller AI agent, choose ready actions or workflows, verify the draft, and publish only when requested."
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Agent instructions and versioning
|
|
2
|
+
|
|
3
|
+
## Instruction template
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
You are <role> for <audience>. You own <outcome>.
|
|
7
|
+
|
|
8
|
+
## Actions
|
|
9
|
+
|
|
10
|
+
- `<tool_name>`: Use when <specific situation>. Pass <inputs in user terms>. It returns <result>; <how to use it>.
|
|
11
|
+
|
|
12
|
+
## Judgment
|
|
13
|
+
|
|
14
|
+
- <decision threshold or boundary>
|
|
15
|
+
- <what requires clarification or approval>
|
|
16
|
+
- <what must never happen>
|
|
17
|
+
|
|
18
|
+
## Responses
|
|
19
|
+
|
|
20
|
+
- <tone, length, format>
|
|
21
|
+
|
|
22
|
+
## When something fails
|
|
23
|
+
|
|
24
|
+
- Tell the user what failed and what you were trying to do.
|
|
25
|
+
- Do not retry more than once.
|
|
26
|
+
- If a connection is broken, name the integration that needs attention.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Delete any sentence that does not change behavior. Do not expose workflow, flow, node, rail, prop, schema tier, or version internals to the runtime user.
|
|
30
|
+
|
|
31
|
+
## Draft and live model
|
|
32
|
+
|
|
33
|
+
- Agent edits change only the mutable draft.
|
|
34
|
+
- Publishing snapshots display name, instructions, tool identities, descriptions and approval policies, and knowledge files into a new immutable version. The runtime model is not part of that snapshot.
|
|
35
|
+
- Publishing moves the agent's live pointer and restamps every existing live conversation to the new version. New and existing shared conversations therefore use the latest published agent version.
|
|
36
|
+
- Non-owners never receive draft instructions, tools, or knowledge. Test/draft conversations are owner-only.
|
|
37
|
+
- There is no rollback command; correct a bad version by editing the draft and publishing forward.
|
|
38
|
+
- Test/draft conversations use the current agent draft. Workflow tools run against each workflow's current development head.
|
|
39
|
+
- Live/shared conversations use the latest published agent version. Workflow tools follow each workflow's latest live release and cannot be pinned to an agent version.
|
|
40
|
+
- Direct action identity, description, and confirmation policy are captured in the agent version. Its connection and authorization grant remain live-bound: rebinding can redirect an invocation, while failure, revocation, or detachment can block it immediately without publishing the agent. Detachment still changes the draft tool list, so publish afterward to remove that tool from the published list.
|
|
41
|
+
- Organization members use the agent owner's connected external accounts for direct actions. Controller AI usage comes from the organization's shared pool.
|
|
42
|
+
- Workflow and agent publishing are independent. Publish only attached workflows whose verified development changes must become live. A workflow publish changes every live agent that follows it without another agent publish. Live workflow resolution is cached per runtime session: an in-flight turn or approval episode may finish on the prior release, then the session refreshes. Use a fresh Live conversation for post-publish proof and disclose any refresh warning.
|
|
43
|
+
- Development and live workflow records are separate. Stateful behavior needs live-data verification.
|
|
44
|
+
|
|
45
|
+
## File context by mode
|
|
46
|
+
|
|
47
|
+
- **Live/shared:** frozen knowledge from the latest published agent version plus current live shared/runtime files.
|
|
48
|
+
- **Test/draft:** current draft knowledge plus current live shared/runtime files overlaid by development/test shared/runtime files. On the same sandbox path, the development/test file wins.
|
|
49
|
+
- Runtime files are maintained outside the immutable agent snapshot. A live runtime-file change can therefore appear in live conversations without publishing the agent.
|
|
50
|
+
|
|
51
|
+
Do not describe Test and Live as sharing one mutable file context. Knowledge is versioned with the agent; runtime files are environment-aware live state.
|
|
52
|
+
|
|
53
|
+
## Updating an agent
|
|
54
|
+
|
|
55
|
+
For name, instructions, tool identity/description, tool approval policy, or knowledge-file changes:
|
|
56
|
+
|
|
57
|
+
1. Edit the mutable draft.
|
|
58
|
+
2. Read it back and verify it in a Test/draft conversation.
|
|
59
|
+
3. Publish any changed workflow dependency that should become live.
|
|
60
|
+
4. Run agent preflight and publish the agent.
|
|
61
|
+
5. Verify with a new Live conversation.
|
|
62
|
+
|
|
63
|
+
Do not republish the agent merely to make a followed workflow's new live release or a direct-action grant/connection rebind, failure, revocation, or detachment take effect; those effects are already live. After detaching an action, still publish the agent to remove the now-unavailable tool from its published tool list. Verify and disclose every live-bound change.
|
|
64
|
+
|
|
65
|
+
## Verification matrix
|
|
66
|
+
|
|
67
|
+
| Layer | Evidence |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| Workflow tool | Completed development `cai run flow` execution |
|
|
70
|
+
| Direct action | Persisted conversation action/run events, returned result, and intended external effect |
|
|
71
|
+
| Draft routing | Draft conversation chooses the correct tool and arguments |
|
|
72
|
+
| Published workflow | `workflow status` reports the intended live release and active state |
|
|
73
|
+
| Published agent | `agent publish` version plus a new live conversation |
|
|
74
|
+
| Stateful live behavior | Live conversation or trigger run reads/writes expected live records |
|
|
75
|
+
|
|
76
|
+
Direct actions do not create workflow execution IDs. Never claim a higher layer from only lower-layer evidence.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-ai-nodes
|
|
3
|
+
description: Configure and verify AI-powered Controller AI workflow nodes, especially Ask AI and actions that interact with Controller AI agents. Use when a workflow needs generation, classification, extraction, summarization, structured AI output, model/provider selection, or a workflow action that creates or messages an agent conversation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI AI nodes
|
|
7
|
+
|
|
8
|
+
First decide whether the capability belongs inside a deterministic workflow or in a user-facing Controller AI agent:
|
|
9
|
+
|
|
10
|
+
- Use Ask AI for one bounded transformation with explicit inputs and output contract.
|
|
11
|
+
- Use a Controller AI agent for conversational judgment, multiple tools, durable instructions, and knowledge files. Load `controllerai-agents`.
|
|
12
|
+
- Use `registry_agent` workflow actions only when a workflow must create/message a platform agent conversation or manage its files; discover the exact action and props rather than treating the whole agent as one node.
|
|
13
|
+
|
|
14
|
+
## Configure Ask AI in dependency order
|
|
15
|
+
|
|
16
|
+
Discover the current component instead of hardcoding a key:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cai node find "ask AI" --json
|
|
20
|
+
cai node component --node <nodeSlug> --key <nodeKey> --json
|
|
21
|
+
cai node init --flow <flowId> --node <nodeSlug> --key <nodeKey> --name "<result produced>" --json
|
|
22
|
+
cai node status <nodeId> --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Typical selectors are provider, model, prompt/user message, and response data type. Trust current prop metadata over these names.
|
|
26
|
+
|
|
27
|
+
1. Set the provider or other `reloadProps` selector.
|
|
28
|
+
2. Re-read props.
|
|
29
|
+
3. Fetch live model options; never invent a model identifier.
|
|
30
|
+
4. Set the returned model value.
|
|
31
|
+
5. Set the response type.
|
|
32
|
+
6. Author the prompt with expression context.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cai node set <nodeId> --prop <providerProp> --value '<provider>' --json
|
|
36
|
+
cai node props <nodeId> --json
|
|
37
|
+
cai node options <nodeId> --prop <modelProp> --query '<model family>' --json
|
|
38
|
+
cai node set <nodeId> --prop <modelProp> --value '<returned value>' --label '<returned label>' --json
|
|
39
|
+
cai expr set <nodeId> --prop <promptProp> --js '<prompt expression>' --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Model catalogs, availability, and prices change. Use current options and honor the user's cost/quality preference; do not claim a model exists because it appears in an old example.
|
|
43
|
+
|
|
44
|
+
## Prefer typed output for downstream logic
|
|
45
|
+
|
|
46
|
+
If downstream nodes need fields, create a small `custom.*` shape first:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cai schema create custom.classification \
|
|
50
|
+
--field category:text:"Category" \
|
|
51
|
+
--field confidence:number:"Confidence" \
|
|
52
|
+
--field rationale:text:"Rationale" \
|
|
53
|
+
--json
|
|
54
|
+
cai node set <nodeId> --prop <responseTypeProp> --value 'custom.classification' --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Tell the model exactly what each field means, allowed values, and how to represent uncertainty. Never parse free-form prose downstream when a structured response contract is available.
|
|
58
|
+
|
|
59
|
+
## Prompt contract
|
|
60
|
+
|
|
61
|
+
A useful workflow prompt contains only behavior-changing material:
|
|
62
|
+
|
|
63
|
+
- Task and audience
|
|
64
|
+
- Actual input data through exact bindings
|
|
65
|
+
- Decision rules and constraints
|
|
66
|
+
- Required output fields/format
|
|
67
|
+
- Explicit uncertainty or no-data behavior
|
|
68
|
+
|
|
69
|
+
Avoid filler personas, repeated instructions, and claims about data not present in expression context. For untrusted input, delimit it clearly and state that embedded instructions are data, not authority.
|
|
70
|
+
|
|
71
|
+
Read [references/selection-and-testing.md](references/selection-and-testing.md) for node choice and evaluation.
|
|
72
|
+
|
|
73
|
+
## Verify
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cai node status <nodeId> --json
|
|
77
|
+
cai run node <nodeId> --inputs values.json --json
|
|
78
|
+
cai exec ports <nodeExecutionId> --json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Test at least: normal input, missing/ambiguous input, and an adversarial or boundary case relevant to the task. Check resolved prompt/config, output type, required fields, and values—not just that text was returned.
|
|
82
|
+
|
|
83
|
+
AI execution inside the workflow is platform/API usage. Installing `cai` lets the user's subscribed coding agent build on Controller AI; it does not automatically transfer that subscription to runtime AI nodes.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# AI node selection and testing
|
|
2
|
+
|
|
3
|
+
## Choose the surface
|
|
4
|
+
|
|
5
|
+
| Need | Surface |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| Extract/classify/summarize one payload | Ask AI node |
|
|
8
|
+
| Deterministic transformation | Expression or normal action node; avoid AI |
|
|
9
|
+
| Conversational assistant with several capabilities | Controller AI agent with workflow tools |
|
|
10
|
+
| Workflow starts or messages an existing platform agent | Exact `registry_agent` action |
|
|
11
|
+
|
|
12
|
+
Do not use AI for logic that can be expressed deterministically and tested exactly.
|
|
13
|
+
|
|
14
|
+
## Model selection
|
|
15
|
+
|
|
16
|
+
After provider selection reloads props:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cai node options <nodeId> --prop <modelProp> --query '<preference>' --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Set only a returned value, and pass its matching displayed label with `cai node set ... --value '<value>' --label '<label>'`. Balance:
|
|
23
|
+
|
|
24
|
+
- Quality/reasoning complexity
|
|
25
|
+
- Latency
|
|
26
|
+
- Runtime cost
|
|
27
|
+
- Structured-output reliability
|
|
28
|
+
- User-stated provider or privacy constraints
|
|
29
|
+
|
|
30
|
+
If no option meets an explicit requirement, report the gap rather than silently choosing another provider.
|
|
31
|
+
|
|
32
|
+
## Minimal evaluation set
|
|
33
|
+
|
|
34
|
+
For a classifier/extractor, test:
|
|
35
|
+
|
|
36
|
+
1. Clear positive/normal case
|
|
37
|
+
2. Clear negative or alternate category
|
|
38
|
+
3. Missing or insufficient data
|
|
39
|
+
4. Conflicting/ambiguous evidence
|
|
40
|
+
5. Malicious or instruction-like text inside the data when applicable
|
|
41
|
+
|
|
42
|
+
Assert the structured fields and allowed values. A fluent answer with the wrong schema is a failure.
|
|
43
|
+
|
|
44
|
+
## Runtime evidence
|
|
45
|
+
|
|
46
|
+
`resolvedConfigs` proves what prompt and settings reached the action. The node output proves what the provider returned. Inspect both. Redact secrets and avoid placing credentials or unnecessary personal data in prompts.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-data
|
|
3
|
+
description: Define Controller AI custom data types and safely read, write, import, copy, and debug workflow records across development and live stores. Use when a workflow needs durable state, custom structured types, collections, record queries, CSV import, workflowData expressions, or data migration between dev and live.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI data
|
|
7
|
+
|
|
8
|
+
Controller AI has two separate concerns:
|
|
9
|
+
|
|
10
|
+
- A `custom.*` schema defines fields and makes a collection available.
|
|
11
|
+
- Development and live record stores hold separate rows. Publishing graph/configuration does not copy records.
|
|
12
|
+
|
|
13
|
+
## A type vs a stored record
|
|
14
|
+
|
|
15
|
+
`custom.customer` and `dataRecord.custom.customer` are different things, and the difference carries through everything:
|
|
16
|
+
|
|
17
|
+
- `custom.customer` is the TYPE — the shape, like a TypeScript interface. A value of this type is just data in that shape.
|
|
18
|
+
- `dataRecord.custom.customer` is an ACTUAL STORED RECORD of that shape — the same fields plus record identity (`id`, `createdAt`, `updatedAt`) proving it lives in the collection.
|
|
19
|
+
|
|
20
|
+
In the product UI this appears as the "data record" checkbox when selecting a type for a flow input or run-subflow-on-list: unchecked means "data shaped like a customer", checked means "a real stored customer record". Users find this checkbox confusing — be ready to explain it in these terms.
|
|
21
|
+
|
|
22
|
+
Consequences:
|
|
23
|
+
|
|
24
|
+
- Only real records satisfy a `dataRecord.*` input. An expression that CONSTRUCTS record-shaped objects (e.g. a `.map()` that builds new objects) produces `custom.*`-shaped values with no identity — pass fetched records through instead.
|
|
25
|
+
- Record metadata (`id`, `createdAt`) exists only on `dataRecord.*` values; on plain `custom.*` values those paths resolve empty.
|
|
26
|
+
|
|
27
|
+
## Data nodes: update semantics
|
|
28
|
+
|
|
29
|
+
- "Update multiple data records" takes an expression typed `list.dataRecord.custom.<type>` — real stored records passed through from a query or `workflowData(...)`. The batch is ONE transaction: if any resolved record is stale (deleted since fetched) or foreign to the collection, the node errors and NOTHING updates. A failed run therefore means zero changes — fix and rerun safely.
|
|
30
|
+
- On the single-record "Update data" node, every ENABLED field is written. Enable only the fields you intend to change; disabled fields keep their stored values.
|
|
31
|
+
|
|
32
|
+
## Define a schema deliberately
|
|
33
|
+
|
|
34
|
+
Inspect existing types first:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cai schema list --json
|
|
38
|
+
cai schema get custom.<name> --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Create a type with stable field IDs:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cai schema create custom.customer \
|
|
45
|
+
--display "Customer" \
|
|
46
|
+
--field email:text:"Email" \
|
|
47
|
+
--field score:number:"Score" \
|
|
48
|
+
--json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Creating the schema creates/synchronizes its collection. `cai data collection create` is only an alias for schema creation.
|
|
52
|
+
|
|
53
|
+
`schema update --field` replaces the complete field list; it does not append — this is deliberate, so a subset CAN intentionally replace the whole schema. Read the current schema, preserve intended fields, and disclose any removals. The CLI warns about every field being dropped and echoes back the COMPLETE stored shape after the write — always read that echo and confirm it matches intent. Deleting a schema hides its collection and records and breaks dependent expressions — tell the user, and know it is recoverable (see below).
|
|
54
|
+
|
|
55
|
+
## How schema changes affect stored records
|
|
56
|
+
|
|
57
|
+
Schema changes never hard-delete data. There is no delete path for records in schema sync — everything is deactivation and hiding:
|
|
58
|
+
|
|
59
|
+
- Delete a type → its collection goes INACTIVE on the next saved state; every record row survives. Re-add the same `custom.*` key and the same collection reactivates with all records intact.
|
|
60
|
+
- Delete a field → its values stay inside each record, unaddressable. Re-add the SAME field id and the old values reappear.
|
|
61
|
+
- Add a field → purely additive; existing records read the new field as null.
|
|
62
|
+
- Change a field's type → values are never converted or erased; incompatible values read as null and return if the type is changed back. The schema hash changes, which blocks copy-to-live until dev and live match again.
|
|
63
|
+
- Publish applies the same deactivate/reactivate logic to live. Live records are hidden, never deleted.
|
|
64
|
+
- Restoring an older workflow state rolls back the DEFINITION (graph and schemas), never the data. The record store is not versioned and only moves forward: a deleted type reactivates with whatever the store holds NOW — records created, edited, or soft-deleted after the restored state stay exactly as they are. Restore is not a data snapshot.
|
|
65
|
+
|
|
66
|
+
The truly destructive operations are record-level only: `data delete`, `data delete-many`, and overwriting edits. Those have no undo — treat them with explicit user intent; everything schema-shaped is safely reversible.
|
|
67
|
+
|
|
68
|
+
One rename trap: renaming a type key is create-new + deactivate-old — all existing records stay stranded under the OLD key's collection, invisible. Migrate records explicitly (export/import) or rename back to recover.
|
|
69
|
+
|
|
70
|
+
## Respect field-key asymmetry
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cai data fields --type custom.customer --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- `data create` and `data update` take field IDs.
|
|
77
|
+
- Query/get results are keyed by field display names.
|
|
78
|
+
- CSV columns are also matched by display names.
|
|
79
|
+
|
|
80
|
+
Never feed a queried record directly into a write. Build a new fields object keyed by the `writeKey` mapping and omit reserved `id`, `createdAt`, and `updatedAt`.
|
|
81
|
+
|
|
82
|
+
## Work on the correct rail
|
|
83
|
+
|
|
84
|
+
Development is the default:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cai data collections --env dev --json
|
|
88
|
+
cai data query --type custom.customer --env dev --json
|
|
89
|
+
cai data create --type custom.customer --fields '{"email":"a@example.com","score":5}' --env dev --json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use `--env live` only when the user intends to inspect or mutate production state. Before a live write, say that published/triggered runs read this store.
|
|
93
|
+
|
|
94
|
+
`data query --query` is plain-text search over serialized records and metadata, not a field predicate. Perform exact field filtering inside workflow expressions or inspect results explicitly.
|
|
95
|
+
|
|
96
|
+
## Import and promote
|
|
97
|
+
|
|
98
|
+
Validate CSV before writing:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cai data import --type custom.customer --file customers.csv --mode dryRun --json
|
|
102
|
+
cai data import --type custom.customer --file customers.csv --mode commit --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The commit appends. Verify result counts and query the imported rows.
|
|
106
|
+
|
|
107
|
+
To seed live from development:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
cai workflow publish --json
|
|
111
|
+
cai data copy-to-live --type custom.customer --json
|
|
112
|
+
cai data collections --env live --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The live schema must exist through a publish before copying. Treat copy-to-live as a production mutation and report counts/results.
|
|
116
|
+
|
|
117
|
+
## Workflow expressions
|
|
118
|
+
|
|
119
|
+
`workflowData("custom.customer")` requires an active collection on the executing rail. Read `controllerai-expressions` for filtering. Test stateful behavior against development, then independently verify required live seed data.
|
|
120
|
+
|
|
121
|
+
Read [references/data-rails.md](references/data-rails.md) before schema rewrites, deletion, bulk deletion, import, or copy-to-live.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Data rails and safety
|
|
2
|
+
|
|
3
|
+
## What publishing copies
|
|
4
|
+
|
|
5
|
+
| Asset | Workflow publish |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| Graph, props, expressions, schemas | Promoted to live |
|
|
8
|
+
| Development records | Not copied |
|
|
9
|
+
| Existing live records | Remain on live |
|
|
10
|
+
|
|
11
|
+
Use `cai data copy-to-live --type <custom.type>` only for an intentional data promotion.
|
|
12
|
+
|
|
13
|
+
## Safe schema update
|
|
14
|
+
|
|
15
|
+
1. `cai schema get <type> --json`
|
|
16
|
+
2. Search workflow expressions and node props that reference its fields.
|
|
17
|
+
3. Prepare the complete replacement field list.
|
|
18
|
+
4. Identify dropped/renamed/type-changed fields and their record impact.
|
|
19
|
+
5. Run `cai schema update`.
|
|
20
|
+
6. Read schema, collections, and affected expression contexts again.
|
|
21
|
+
7. Rerun stateful flows.
|
|
22
|
+
|
|
23
|
+
Field IDs are contracts. Prefer keeping an ID stable and changing only its display label.
|
|
24
|
+
|
|
25
|
+
## Destructive operations
|
|
26
|
+
|
|
27
|
+
- `data delete` soft-deletes one record.
|
|
28
|
+
- `data delete-many --all` is broad and development-only through its REST route.
|
|
29
|
+
- `schema delete` removes access to the whole collection and breaks its type references.
|
|
30
|
+
- CSV `--mode commit` appends rows.
|
|
31
|
+
- `copy-to-live` changes production data.
|
|
32
|
+
|
|
33
|
+
Resolve exact workflow, environment, type, and record targets before these actions. Do not use a broad deletion to repair a schema mistake.
|
|
34
|
+
|
|
35
|
+
## Dev/live diagnosis
|
|
36
|
+
|
|
37
|
+
If a manual test passes but a trigger does not:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cai data collections --env dev --json
|
|
41
|
+
cai data collections --env live --json
|
|
42
|
+
cai data query --type <type> --env dev --json
|
|
43
|
+
cai data query --type <type> --env live --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Different row counts are expected until data is intentionally copied or written on both rails.
|