@zibby/skills 0.2.22 → 0.2.24
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/browser.js +3 -10
- package/dist/code-scan.d.ts +1 -1
- package/dist/index.js +81 -88
- package/dist/jira.d.ts +75 -9
- package/dist/jira.js +4 -4
- package/dist/package.json +1 -1
- package/dist/report.d.ts +51 -276
- package/dist/trackers/index.js +12 -12
- package/dist/trackers/jira-adapter.js +11 -11
- package/package.json +1 -1
- package/docs/analysis.md +0 -109
- package/docs/apps/agent-ops.md +0 -130
- package/docs/apps/auth.md +0 -158
- package/docs/apps/deploy.md +0 -207
- package/docs/apps/goal-mode.md +0 -175
- package/docs/apps/index.md +0 -149
- package/docs/apps/managing.md +0 -121
- package/docs/cli-reference.md +0 -494
- package/docs/cloning-repositories.md +0 -285
- package/docs/cloud/bundles.md +0 -92
- package/docs/cloud/dedicated-egress.md +0 -140
- package/docs/cloud/editing-prompts.md +0 -79
- package/docs/cloud/env-vars.md +0 -144
- package/docs/cloud/limits.md +0 -81
- package/docs/cloud/logs.md +0 -104
- package/docs/cloud/triggering.md +0 -128
- package/docs/concepts/agents.md +0 -112
- package/docs/concepts/designing-agents.md +0 -247
- package/docs/concepts/graph.md +0 -83
- package/docs/concepts/sessions.md +0 -70
- package/docs/concepts/skills.md +0 -86
- package/docs/concepts/state.md +0 -106
- package/docs/concepts/sub-graphs.md +0 -227
- package/docs/custom-workflows.md +0 -358
- package/docs/get-started/deploy.md +0 -75
- package/docs/get-started/install.md +0 -60
- package/docs/get-started/run-locally.md +0 -94
- package/docs/get-started/trigger-and-logs.md +0 -90
- package/docs/get-started/use-from-agents.md +0 -153
- package/docs/get-started/your-first-workflow.md +0 -69
- package/docs/getting-started.md +0 -108
- package/docs/installation.md +0 -127
- package/docs/integrations/github.md +0 -73
- package/docs/integrations/gitlab.md +0 -43
- package/docs/integrations/jira.md +0 -71
- package/docs/integrations/lark.md +0 -41
- package/docs/integrations/linear.md +0 -43
- package/docs/integrations/notion.md +0 -33
- package/docs/integrations/plane.md +0 -46
- package/docs/integrations/sentry.md +0 -42
- package/docs/integrations/slack.md +0 -33
- package/docs/intro.md +0 -86
- package/docs/legacy/test-automation.md +0 -111
- package/docs/packages/agent-workflow.md +0 -88
- package/docs/packages/cli.md +0 -73
- package/docs/packages/core.md +0 -72
- package/docs/packages/mcp-browser.md +0 -110
- package/docs/packages/mcp-cli.md +0 -176
- package/docs/packages/memory.md +0 -223
- package/docs/packages/skills.md +0 -218
- package/docs/packages/ui-memory.md +0 -245
- package/docs/recipes/bug-autofix.md +0 -85
- package/docs/recipes/github-ai-scout.md +0 -61
- package/docs/recipes/index.md +0 -68
- package/docs/recipes/pipeline-supervisor.md +0 -57
- package/docs/recipes/sentry-triage.md +0 -93
- package/docs/recipes/test.md +0 -190
- package/docs/reviewing-results.md +0 -114
- package/docs/running-tests.md +0 -134
- package/docs/self-host/backup-restore.md +0 -53
- package/docs/self-host/custom-sidecars.md +0 -136
- package/docs/self-host/index.md +0 -75
- package/docs/self-host/storage.md +0 -50
- package/docs/self-host/troubleshooting.md +0 -48
- package/docs/self-host/upgrade.md +0 -81
- package/docs/skills/browser.md +0 -97
- package/docs/skills/chat-memory.md +0 -122
- package/docs/skills/core-tools.md +0 -80
- package/docs/skills/function-skill.md +0 -93
- package/docs/skills/github.md +0 -91
- package/docs/skills/index.md +0 -46
- package/docs/skills/jira.md +0 -99
- package/docs/skills/lark.md +0 -85
- package/docs/skills/memory.md +0 -92
- package/docs/skills/sentry.md +0 -80
- package/docs/skills/slack.md +0 -89
- package/docs/tests/memory.md +0 -131
- package/docs/triggering-workflows.md +0 -552
- package/docs/workflow-artifact-layout-evaluation.md +0 -119
- package/docs/workflow.md +0 -558
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 6
|
|
3
|
-
title: Sub-graphs (parent → child)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Sub-graphs
|
|
7
|
-
|
|
8
|
-
A **sub-graph node** runs another deployed agent as a child of the current one. Use it when a step is large enough to deserve its own workflow definition — its own state schema, its own version, its own activity-tab history — but you want a parent to dispatch it as part of a larger flow.
|
|
9
|
-
|
|
10
|
-
The shape is one extra field on the existing node config:
|
|
11
|
-
|
|
12
|
-
```js
|
|
13
|
-
g.addNode('audit', {
|
|
14
|
-
workflow: 'deep-audit', // ← name of another agent in this project
|
|
15
|
-
});
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
That's it. No new imports, no UUID, no separate class. The engine recognizes `workflow:` and turns this node into a sub-graph dispatcher.
|
|
19
|
-
|
|
20
|
-
## When to use a sub-graph
|
|
21
|
-
|
|
22
|
-
| Scenario | Sub-graph? |
|
|
23
|
-
|---|---|
|
|
24
|
-
| Two parents need the same multi-node flow | ✅ Yes — define it once as a child, reference by name |
|
|
25
|
-
| One step needs different state schema than the rest | ✅ Yes — each agent has its own schema |
|
|
26
|
-
| You want per-step activity-tab history + replay | ✅ Yes — each child run gets its own row |
|
|
27
|
-
| Step is a single LLM call | ❌ No — just add a regular node |
|
|
28
|
-
| Step has its own retry policy | Either works, but a sub-graph gives independent control |
|
|
29
|
-
|
|
30
|
-
## Sync vs async
|
|
31
|
-
|
|
32
|
-
`async:` flips the dispatch mode:
|
|
33
|
-
|
|
34
|
-
```js
|
|
35
|
-
g.addNode('audit', { workflow: 'deep-audit' }); // sync (default)
|
|
36
|
-
g.addNode('notify', { workflow: 'slack-notifier', async: true }); // fire-and-forget
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
| Mode | Behavior | Returns to parent | Use for |
|
|
40
|
-
|---|---|---|---|
|
|
41
|
-
| **sync** (default) | Parent blocks, polls child until terminal status, merges result into parent state | the extracted value (see `output:` below) | Steps where downstream nodes depend on the child's result |
|
|
42
|
-
| **async** (`async: true`) | Parent dispatches the child and continues immediately. No polling. | a dispatch handle `{ jobId, status, workflow }` | Fan-out, notifications, side-effect work the parent shouldn't wait for |
|
|
43
|
-
|
|
44
|
-
Quota: every sub-graph run counts as a separate execution against the account's monthly cap (parent + 3 children = 4 executions).
|
|
45
|
-
|
|
46
|
-
## Full option surface
|
|
47
|
-
|
|
48
|
-
```js
|
|
49
|
-
g.addNode('audit', {
|
|
50
|
-
// ─── Required ─────────────────────────────────────────────────────
|
|
51
|
-
workflow: 'deep-audit', // resolved by name within this project
|
|
52
|
-
|
|
53
|
-
// ─── Mode (default sync) ──────────────────────────────────────────
|
|
54
|
-
async: false, // false = block + merge, true = fire-forget
|
|
55
|
-
|
|
56
|
-
// ─── State plumbing ───────────────────────────────────────────────
|
|
57
|
-
input: (state) => ({ // shape parent state → child input
|
|
58
|
-
ticketId: state.ticketId,
|
|
59
|
-
}), // OR a plain object OR omit (child gets {})
|
|
60
|
-
|
|
61
|
-
output: 'audit.score', // dot-path on child finalState
|
|
62
|
-
// OR (childState) => ({...}) function form
|
|
63
|
-
// OR omit → entire child finalState
|
|
64
|
-
|
|
65
|
-
// ─── Sync tunings (ignored when async: true) ──────────────────────
|
|
66
|
-
timeoutMs: 5 * 60 * 1000, // throw after this long (default 10min)
|
|
67
|
-
pollIntervalMs: 2000, // status-check frequency (default 2s)
|
|
68
|
-
|
|
69
|
-
// ─── Cross-cutting concerns ───────────────────────────────────────
|
|
70
|
-
retries: 3, // engine retries whole dispatch on transient failure
|
|
71
|
-
onComplete: (state, result) => result,
|
|
72
|
-
|
|
73
|
-
// ─── Advanced ─────────────────────────────────────────────────────
|
|
74
|
-
conversationId: 'inherit', // 'inherit' (default) | 'new' | (state) => string
|
|
75
|
-
});
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## How state flows
|
|
79
|
-
|
|
80
|
-
Each agent has its own state schema — they're independent. The parent must transform its state into the child's input shape, and (optionally) extract whatever it needs back out.
|
|
81
|
-
|
|
82
|
-
### A complete example — `parent-orchestrator` calls `child-doubler`
|
|
83
|
-
|
|
84
|
-
```js
|
|
85
|
-
// child-doubler — takes a number, returns it doubled.
|
|
86
|
-
class ChildDoublerAgent extends WorkflowAgent {
|
|
87
|
-
buildGraph() {
|
|
88
|
-
const g = new WorkflowGraph();
|
|
89
|
-
g.setStateSchema(z.object({
|
|
90
|
-
value: z.number(),
|
|
91
|
-
double: z.object({ doubled: z.number() }).optional(),
|
|
92
|
-
}));
|
|
93
|
-
g.addNode('double', {
|
|
94
|
-
_isCustomCode: true,
|
|
95
|
-
outputSchema: z.object({ doubled: z.number() }),
|
|
96
|
-
execute: async (ctx) => ({ doubled: ctx.state.getAll().value * 2 }),
|
|
97
|
-
});
|
|
98
|
-
g.setEntryPoint('double');
|
|
99
|
-
g.addEdge('double', 'END');
|
|
100
|
-
return g;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// parent-orchestrator — picks a number, calls child-doubler, reports.
|
|
105
|
-
class ParentOrchestratorAgent extends WorkflowAgent {
|
|
106
|
-
buildGraph() {
|
|
107
|
-
const g = new WorkflowGraph();
|
|
108
|
-
g.setStateSchema(z.object({
|
|
109
|
-
seed: z.number(),
|
|
110
|
-
pick_number: z.object({ value: z.number(), label: z.string() }).optional(),
|
|
111
|
-
call_doubler: z.number().optional(), // ← child's result lands here
|
|
112
|
-
report: z.object({ summary: z.string() }).optional(),
|
|
113
|
-
}));
|
|
114
|
-
|
|
115
|
-
g.addNode('pick_number', pickNumberNode);
|
|
116
|
-
|
|
117
|
-
g.addNode('call_doubler', {
|
|
118
|
-
workflow: 'child-doubler',
|
|
119
|
-
input: (state) => ({ value: state.pick_number.value }),
|
|
120
|
-
output: 'double.doubled', // dot-path through child's node name
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
g.addNode('report', reportNode); // reads state.call_doubler
|
|
124
|
-
|
|
125
|
-
g.setEntryPoint('pick_number');
|
|
126
|
-
g.addEdge('pick_number', 'call_doubler');
|
|
127
|
-
g.addEdge('call_doubler', 'report');
|
|
128
|
-
g.addEdge('report', 'END');
|
|
129
|
-
return g;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Triggering the parent with `{ seed: 21 }`:
|
|
135
|
-
|
|
136
|
-
| Step | What happens | State after |
|
|
137
|
-
|---|---|---|
|
|
138
|
-
| 1 | `pick_number` runs | `{ seed: 21, pick_number: { value: 21, label: '…' } }` |
|
|
139
|
-
| 2 | `call_doubler.input(state)` fires | returns `{ value: 21 }` |
|
|
140
|
-
| 3 | Server validates `{ value: 21 }` against child's `stateSchema` | passes |
|
|
141
|
-
| 4 | Child runs in its own Fargate task. Final state: `{ value: 21, double: { doubled: 42 } }` | (parent waiting) |
|
|
142
|
-
| 5 | Engine extracts `output: 'double.doubled'` → `42` | `state.call_doubler = 42` |
|
|
143
|
-
| 6 | `report` runs, reads `state.call_doubler` | `state.report.summary = '…42…'` |
|
|
144
|
-
|
|
145
|
-
### Why `output: 'double.doubled'` and not `'doubled'`?
|
|
146
|
-
|
|
147
|
-
Each node's output is stored at `state[nodeName]` in its own graph. So when the child's `double` node returns `{ doubled: 42 }`, that lands at `childState.double.doubled` — `doubled` is *nested under the node name*, not promoted to the top level.
|
|
148
|
-
|
|
149
|
-
If you want multiple fields, use the function form:
|
|
150
|
-
|
|
151
|
-
```js
|
|
152
|
-
output: (childState) => ({
|
|
153
|
-
doubled: childState.double.doubled,
|
|
154
|
-
echoed: childState.value,
|
|
155
|
-
isDouble: childState.double.doubled === childState.value * 2,
|
|
156
|
-
}),
|
|
157
|
-
// → state.audit = { doubled: 42, echoed: 21, isDouble: true }
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Or omit `output:` and the entire `childState` lands at `state[nodeName]` — useful when you don't know yet which fields you'll need.
|
|
161
|
-
|
|
162
|
-
## Schema validation at the boundary
|
|
163
|
-
|
|
164
|
-
The server runs the same input gate sub-graph triggers hit as user-initiated ones. If the parent's `input:` callback returns a value that doesn't satisfy the child's `stateSchema`, the trigger 400s **before** any Fargate spawn — no wasted compute. The parent's sub-graph node throws a typed error with the missing fields listed.
|
|
165
|
-
|
|
166
|
-
## Errors
|
|
167
|
-
|
|
168
|
-
Sub-graph failures throw with a `code` field so you can branch:
|
|
169
|
-
|
|
170
|
-
| `err.code` | Meaning | Useful properties |
|
|
171
|
-
|---|---|---|
|
|
172
|
-
| `SUBGRAPH_INVALID_INPUT` | Parent's `input:` produced data that violates the child's stateSchema | `err.missing[]`, `err.validationErrors` |
|
|
173
|
-
| `SUBGRAPH_QUOTA_EXCEEDED` | Account is over its execution cap; child can't dispatch | `err.quotaInfo` |
|
|
174
|
-
| `SUBGRAPH_TRIGGER_FAILED` | Any other HTTP failure from the trigger endpoint | `err.status` |
|
|
175
|
-
|
|
176
|
-
Sync-mode terminal failures (child completed in `failed` / `canceled` / `timeout`):
|
|
177
|
-
|
|
178
|
-
```js
|
|
179
|
-
err.subgraphJobId // child's executionId — look up in activity tab
|
|
180
|
-
err.subgraphStatus // 'failed' | 'canceled' | 'timeout'
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
`retries:` on the sub-graph node re-runs the whole dispatch (trigger + poll) on transient failures, same semantics as a regular node retry.
|
|
184
|
-
|
|
185
|
-
## What's deployed vs what you write
|
|
186
|
-
|
|
187
|
-
You only ever reference agents by **name**. The cloud handles the UUID resolution.
|
|
188
|
-
|
|
189
|
-
| Stage | What you write | What the backend does |
|
|
190
|
-
|---|---|---|
|
|
191
|
-
| `zibby agent deploy child-doubler` | nothing about UUIDs | mints UUID, stores `(projectId, workflowType='child-doubler', uuid='…')` |
|
|
192
|
-
| `subgraph('child-doubler')` in parent code | just the name | stored as a string in the parent's graph definition |
|
|
193
|
-
| `zibby agent deploy parent-orchestrator` | nothing | looks up `'child-doubler'` → UUID, snapshots the dependency |
|
|
194
|
-
| Parent runs in Fargate → hits sub-graph node | nothing | POSTs to `/workflows/<uuid>/trigger` with `parentExecutionId` |
|
|
195
|
-
|
|
196
|
-
Names are unique per project (DDB primary key enforces this), so `subgraph('child-doubler')` resolves unambiguously within the parent's project.
|
|
197
|
-
|
|
198
|
-
## Activity-tab tree-view
|
|
199
|
-
|
|
200
|
-
Each child execution row carries `parentExecutionId` pointing at the parent. The activity tab uses this to render parent runs as collapsible groups — expand to see the chain of children.
|
|
201
|
-
|
|
202
|
-
| Row | `parentExecutionId` | Type |
|
|
203
|
-
|---|---|---|
|
|
204
|
-
| Parent (orchestrator) | `null` | top-level (user-triggered) |
|
|
205
|
-
| Child (doubler) | `<parent's executionId>` | dispatched as sub-graph |
|
|
206
|
-
|
|
207
|
-
## Local development
|
|
208
|
-
|
|
209
|
-
Sub-graph dispatch needs the `PROGRESS_API_URL` env var (the public API base). That's set automatically on Fargate runs. For local dev, you have two options:
|
|
210
|
-
|
|
211
|
-
1. **Deploy both agents to cloud, then trigger the parent.** The cloud path always works.
|
|
212
|
-
2. **Mock the trigger + status endpoints locally.** See [`workflows/parent-orchestrator/mock-server.mjs`](https://github.com/ZibbyDev/agent-workflow/tree/main/examples) in the agent-workflow repo for a 90-line example that simulates the dispatch + poll loop.
|
|
213
|
-
|
|
214
|
-
In-process sub-graph execution (running the child in the parent's Node process directly, no HTTP) is **not supported** — we picked consistency between local and cloud over the 10s spawn-time savings.
|
|
215
|
-
|
|
216
|
-
## Cross-project sub-graphs
|
|
217
|
-
|
|
218
|
-
`workflow: 'name'` resolves within the parent's own project. To call another project's agent, pass an explicit project ID:
|
|
219
|
-
|
|
220
|
-
```js
|
|
221
|
-
g.addNode('audit', {
|
|
222
|
-
workflow: 'shared-audit',
|
|
223
|
-
project: 'b6219c3a-…', // explicit cross-project reference
|
|
224
|
-
});
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
The caller must have access to the destination project (same account, or invited). Cross-**account** sub-graphs are not in v1.
|
package/docs/custom-workflows.md
DELETED
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 5
|
|
3
|
-
title: Custom Workflows
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Custom Workflows
|
|
7
|
-
|
|
8
|
-
Build, test, and deploy your own AI workflows using Zibby's graph-based framework. Custom workflows let you define multi-step AI pipelines that run locally or in Zibby Cloud, triggered via API or subdomain URL.
|
|
9
|
-
|
|
10
|
-
## Quick Start
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
# 1. Scaffold a new workflow
|
|
14
|
-
zibby g workflow ticket-triage
|
|
15
|
-
|
|
16
|
-
# 2. Test locally
|
|
17
|
-
zibby start ticket-triage
|
|
18
|
-
|
|
19
|
-
# 3. Deploy to cloud
|
|
20
|
-
zibby deploy ticket-triage --project <project-id>
|
|
21
|
-
|
|
22
|
-
# 4. Trigger via API
|
|
23
|
-
curl -X POST https://ticket-triage-6af9.workflows.zibby.app \
|
|
24
|
-
-H "Authorization: Bearer $ZIBBY_API_KEY" \
|
|
25
|
-
-H "Content-Type: application/json" \
|
|
26
|
-
-d '{"input": {"ticket": "BUG-123"}}'
|
|
27
|
-
|
|
28
|
-
# 5. Tail logs
|
|
29
|
-
zibby logs --workflow ticket-triage --project <project-id>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Scaffolding
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
zibby g workflow <name>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
If you omit the name, Zibby generates a random one (like Heroku app names).
|
|
39
|
-
|
|
40
|
-
This creates:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
.zibby/workflows/<name>/
|
|
44
|
-
├── graph.mjs # Workflow class (entry point)
|
|
45
|
-
├── nodes/
|
|
46
|
-
│ ├── index.mjs # Barrel export
|
|
47
|
-
│ └── example.mjs # Starter node with prompt + schema
|
|
48
|
-
└── workflow.json # Manifest (metadata, triggers)
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Workflow Structure
|
|
52
|
-
|
|
53
|
-
**`graph.mjs`** — Defines the workflow class that extends `WorkflowAgent`:
|
|
54
|
-
|
|
55
|
-
```javascript
|
|
56
|
-
import { WorkflowAgent, WorkflowGraph } from '@zibby/core';
|
|
57
|
-
import { exampleNode } from './nodes/index.mjs';
|
|
58
|
-
|
|
59
|
-
export class TicketTriageWorkflow extends WorkflowAgent {
|
|
60
|
-
buildGraph() {
|
|
61
|
-
const graph = new WorkflowGraph();
|
|
62
|
-
|
|
63
|
-
graph.addNode('example', exampleNode);
|
|
64
|
-
graph.setEntryPoint('example');
|
|
65
|
-
graph.addEdge('example', 'END');
|
|
66
|
-
|
|
67
|
-
return graph;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async onComplete(result) {
|
|
71
|
-
console.log(`Workflow complete — success: ${result.success !== false}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**`nodes/example.mjs`** — Each node has a prompt function and a Zod output schema:
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
import { z } from '@zibby/core';
|
|
80
|
-
|
|
81
|
-
const ExampleOutputSchema = z.object({
|
|
82
|
-
summary: z.string().describe('A short summary of the result'),
|
|
83
|
-
status: z.enum(['ok', 'warn', 'error']).describe('Overall status'),
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
export const exampleNode = {
|
|
87
|
-
name: 'example',
|
|
88
|
-
prompt: (state) => `You are a helpful workflow node.
|
|
89
|
-
|
|
90
|
-
Input:
|
|
91
|
-
${JSON.stringify(state.input || {}, null, 2)}
|
|
92
|
-
|
|
93
|
-
Analyze the input and return a summary with a status.`,
|
|
94
|
-
outputSchema: ExampleOutputSchema,
|
|
95
|
-
};
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**`workflow.json`** — Manifest with metadata:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"name": "ticket-triage",
|
|
103
|
-
"triggers": { "api": true }
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Adding Nodes
|
|
108
|
-
|
|
109
|
-
Create a new file in `nodes/` and wire it into the graph:
|
|
110
|
-
|
|
111
|
-
```javascript
|
|
112
|
-
// nodes/classify.mjs
|
|
113
|
-
import { z } from '@zibby/core';
|
|
114
|
-
|
|
115
|
-
const ClassifySchema = z.object({
|
|
116
|
-
priority: z.enum(['critical', 'high', 'medium', 'low']),
|
|
117
|
-
category: z.string(),
|
|
118
|
-
assignTo: z.string().optional(),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
export const classifyNode = {
|
|
122
|
-
name: 'classify',
|
|
123
|
-
prompt: (state) => `Given this ticket summary:
|
|
124
|
-
${state.example.summary}
|
|
125
|
-
|
|
126
|
-
Classify the priority, category, and suggested assignee.`,
|
|
127
|
-
outputSchema: ClassifySchema,
|
|
128
|
-
};
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Then add it to `graph.mjs`:
|
|
132
|
-
|
|
133
|
-
```javascript
|
|
134
|
-
import { classifyNode } from './nodes/classify.mjs';
|
|
135
|
-
|
|
136
|
-
// In buildGraph():
|
|
137
|
-
graph.addNode('classify', classifyNode);
|
|
138
|
-
graph.addEdge('example', 'classify'); // instead of example → END
|
|
139
|
-
graph.addEdge('classify', 'END');
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Conditional Edges
|
|
143
|
-
|
|
144
|
-
Route to different nodes based on output:
|
|
145
|
-
|
|
146
|
-
```javascript
|
|
147
|
-
graph.addConditionalEdges('classify', (state) => {
|
|
148
|
-
return state.classify.priority === 'critical' ? 'escalate' : 'notify';
|
|
149
|
-
});
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Local Development
|
|
153
|
-
|
|
154
|
-
### Start a dev server
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
zibby start ticket-triage
|
|
158
|
-
zibby start ticket-triage --port 3850
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
This starts a local HTTP server that loads your workflow and exposes a trigger endpoint:
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
curl -X POST http://localhost:3848/trigger \
|
|
165
|
-
-H "Content-Type: application/json" \
|
|
166
|
-
-d '{"input": {"ticket": "BUG-456"}}'
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
The dev server uses your local `.zibby.config.mjs` for agent configuration (model, API keys, etc.) — the same config used by `zibby test`.
|
|
170
|
-
|
|
171
|
-
## Deploying to Cloud
|
|
172
|
-
|
|
173
|
-
### Prerequisites
|
|
174
|
-
|
|
175
|
-
1. **Authenticated**: Run `zibby login` (or set `ZIBBY_API_KEY`)
|
|
176
|
-
2. **Project**: Have a project ID (run `zibby list` to see yours)
|
|
177
|
-
|
|
178
|
-
### Deploy
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
zibby deploy ticket-triage --project <project-id>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
This:
|
|
185
|
-
1. Loads and serializes the workflow graph
|
|
186
|
-
2. Bundles all source files (`.mjs`, `.js`, `.json`)
|
|
187
|
-
3. Uploads to Zibby Cloud
|
|
188
|
-
4. Registers a unique subdomain
|
|
189
|
-
|
|
190
|
-
Output:
|
|
191
|
-
|
|
192
|
-
```
|
|
193
|
-
Workflow "ticket-triage" deployed to version 1
|
|
194
|
-
|
|
195
|
-
Trigger URL (API):
|
|
196
|
-
POST https://api-prod.zibby.app/projects/<id>/workflows/ticket-triage/trigger
|
|
197
|
-
|
|
198
|
-
Trigger URL (subdomain):
|
|
199
|
-
POST https://ticket-triage-6af9.workflows.zibby.app
|
|
200
|
-
|
|
201
|
-
Tail logs:
|
|
202
|
-
zibby logs <jobId> --project <id>
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Subdomain URLs
|
|
206
|
-
|
|
207
|
-
Each deployed workflow gets a globally unique subdomain:
|
|
208
|
-
|
|
209
|
-
```
|
|
210
|
-
https://<workflow-name>-<hash>.workflows.zibby.app
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
The hash is a short (4-char) deterministic suffix derived from your project ID, ensuring uniqueness across all projects.
|
|
214
|
-
|
|
215
|
-
### Authentication
|
|
216
|
-
|
|
217
|
-
Both trigger URLs require authentication via the `Authorization` header:
|
|
218
|
-
|
|
219
|
-
- **JWT token** — from `zibby login` session
|
|
220
|
-
- **Personal Access Token (PAT)** — from your project settings (`zby_xxx`)
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
curl -X POST https://ticket-triage-6af9.workflows.zibby.app \
|
|
224
|
-
-H "Authorization: Bearer zby_your_api_key" \
|
|
225
|
-
-H "Content-Type: application/json" \
|
|
226
|
-
-d '{"input": {"ticket": "BUG-789"}}'
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### How Cloud Execution Works
|
|
230
|
-
|
|
231
|
-
When triggered, the workflow runs in an isolated ECS Fargate container:
|
|
232
|
-
|
|
233
|
-
1. Lambda receives the trigger request
|
|
234
|
-
2. Workflow sources are loaded from DynamoDB and uploaded to S3
|
|
235
|
-
3. A Fargate task is launched with the workflow code
|
|
236
|
-
4. The container downloads sources, rebuilds the graph, and executes it
|
|
237
|
-
5. Agent configuration (model, API keys) comes from your project settings
|
|
238
|
-
|
|
239
|
-
Each run is fully isolated — no shared state between runs.
|
|
240
|
-
|
|
241
|
-
## Cloning Repositories
|
|
242
|
-
|
|
243
|
-
Custom workflows can clone your project's configured repositories using the `cloneRepo()` helper:
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
import { cloneRepo } from '@zibby/core';
|
|
247
|
-
|
|
248
|
-
// In a node's preProcess function
|
|
249
|
-
const repoPaths = await cloneRepo();
|
|
250
|
-
// Returns: { 'myorg/backend': '/workspace/repos/myorg-backend', ... }
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
This gives your workflow access to your actual codebase for analysis, testing, or deployment tasks.
|
|
254
|
-
|
|
255
|
-
**[See the full Cloning Repositories guide →](./cloning-repositories.md)**
|
|
256
|
-
|
|
257
|
-
## Tailing Logs
|
|
258
|
-
|
|
259
|
-
### Tail a specific job
|
|
260
|
-
|
|
261
|
-
The trigger API returns a `jobId`. Use it to tail logs:
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
zibby logs <jobId> --project <project-id>
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Tail the latest run
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
zibby logs --workflow ticket-triage --project <project-id>
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
This lists recent runs and automatically tails the latest one.
|
|
274
|
-
|
|
275
|
-
### All runs (interleaved)
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
zibby logs --workflow ticket-triage --all --project <project-id>
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
Shows logs from all past runs of the workflow, sorted chronologically with job ID separators:
|
|
282
|
-
|
|
283
|
-
```
|
|
284
|
-
── wfj-1713157331-a3 ──
|
|
285
|
-
2026-04-15 14:02:11 🚀 Starting ticket-triage workflow...
|
|
286
|
-
2026-04-15 14:02:18 ✅ Workflow complete
|
|
287
|
-
|
|
288
|
-
── wfj-1713157522-b7 ──
|
|
289
|
-
2026-04-15 14:05:22 🚀 Starting ticket-triage workflow...
|
|
290
|
-
2026-04-15 14:05:30 Running node: example
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### Options
|
|
294
|
-
|
|
295
|
-
| Flag | Description |
|
|
296
|
-
|---|---|
|
|
297
|
-
| `--project <id>` | Project ID (or `ZIBBY_PROJECT_ID` env) |
|
|
298
|
-
| `--workflow <name>` | Workflow name (tails latest run) |
|
|
299
|
-
| `--all` | Interleaved logs from all runs (requires `--workflow`) |
|
|
300
|
-
| `--no-follow` | Fetch logs once, don't stream |
|
|
301
|
-
| `--lines <n>` | Max lines per fetch (default: 200) |
|
|
302
|
-
|
|
303
|
-
## Agent Configuration
|
|
304
|
-
|
|
305
|
-
### Local
|
|
306
|
-
|
|
307
|
-
Local execution uses your `.zibby.config.mjs`:
|
|
308
|
-
|
|
309
|
-
```javascript
|
|
310
|
-
export default {
|
|
311
|
-
agent: {
|
|
312
|
-
cursor: { model: 'auto' },
|
|
313
|
-
// claude: { model: 'sonnet-4.6' },
|
|
314
|
-
},
|
|
315
|
-
};
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
API keys come from environment variables (`CURSOR_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`).
|
|
319
|
-
|
|
320
|
-
### Cloud
|
|
321
|
-
|
|
322
|
-
Cloud execution uses your **project settings** (configured in the Zibby dashboard):
|
|
323
|
-
|
|
324
|
-
- **AI Agent** — which agent to use (Cursor, Claude, Codex, Gemini)
|
|
325
|
-
- **Model** — model override
|
|
326
|
-
- **API Key** — stored encrypted, injected into the container at runtime
|
|
327
|
-
|
|
328
|
-
No config files are needed in the cloud — everything is read from project settings.
|
|
329
|
-
|
|
330
|
-
## Self-Hosting
|
|
331
|
-
|
|
332
|
-
You can run workflows on your own infrastructure without Zibby Cloud. Your server just needs:
|
|
333
|
-
|
|
334
|
-
1. `@zibby/core` and `@zibby/cli` npm packages
|
|
335
|
-
2. Environment variables for agent configuration:
|
|
336
|
-
|
|
337
|
-
```bash
|
|
338
|
-
AGENT_TYPE=cursor # or claude, codex, gemini
|
|
339
|
-
MODEL=auto
|
|
340
|
-
CURSOR_API_KEY=sk-xxx # or ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
Then trigger the workflow programmatically:
|
|
344
|
-
|
|
345
|
-
```javascript
|
|
346
|
-
import { WorkflowGraph } from '@zibby/core';
|
|
347
|
-
import { TicketTriageWorkflow } from './.zibby/workflows/ticket-triage/graph.mjs';
|
|
348
|
-
|
|
349
|
-
const agent = new TicketTriageWorkflow();
|
|
350
|
-
const graph = agent.buildGraph();
|
|
351
|
-
const result = await graph.run(agent, { input: { ticket: 'BUG-123' } });
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
Or use the CLI:
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
zibby start ticket-triage --port 8080
|
|
358
|
-
```
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 4
|
|
3
|
-
title: 4. Deploy to cloud
|
|
4
|
-
pagination_prev: get-started/run-locally
|
|
5
|
-
pagination_next: get-started/trigger-and-logs
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Ship an agent to Zibby Cloud
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
zibby agent deploy my-agent
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
If you have multiple projects, the CLI prompts you to pick one. On success it prints a UUID:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
✔ Deployed my-agent (v1)
|
|
18
|
-
✔ Bundle ready (78s) — runtime npm install eliminated
|
|
19
|
-
|
|
20
|
-
UUID: 2b1ea07f-3ede-4bfd-a51d-431f0bab008e
|
|
21
|
-
|
|
22
|
-
Next steps:
|
|
23
|
-
zibby agent run my-agent Run locally
|
|
24
|
-
zibby agent trigger 2b1ea07f-... Run in cloud
|
|
25
|
-
zibby agent list View all agents
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The UUID is **canonical** — it never changes once issued. All cloud commands (`trigger`, `logs`, `download`, `delete`) take that UUID as their identifier. The CLI caches it in `.zibby/workflows/my-agent/.zibby-deploy.json` so you don't have to remember it. Commit that file to git; collaborators share the same canonical reference.
|
|
29
|
-
|
|
30
|
-
## What deploy actually does
|
|
31
|
-
|
|
32
|
-
Two phases:
|
|
33
|
-
|
|
34
|
-
1. **Source upload** — your agent folder (sources only, no `node_modules`) is uploaded as a JSON payload to S3 via a presigned URL. The CLI also resolves your `.zibby.config.mjs` (if present at project root) and ships it inside the bundle as `zibby.config.json`, so the cloud sees the same config as your local runs.
|
|
35
|
-
2. **Bundle build (Heroku-style)** — a CodeBuild job downloads the sources, runs `npm install --omit=dev`, packages the result as a tarball, and uploads it to S3. The tarball is what each cloud execution downloads at trigger time, so there's **no `npm install` at runtime** — agents boot in seconds.
|
|
36
|
-
|
|
37
|
-
You'll see a live spinner with the active build step:
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
⠹ Building bundle on Zibby Cloud... [3/4] Installing dependencies — 32s
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Pass `--verbose` if you want to see raw CodeBuild logs.
|
|
44
|
-
|
|
45
|
-
## Re-deploys keep the same UUID
|
|
46
|
-
|
|
47
|
-
Once an agent has a UUID, every subsequent `deploy` increments the version but keeps the UUID stable:
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
v1 → v2 → v3 → ... (same UUID, same trigger URL)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
So your `curl` calls and CI integrations don't break across deploys.
|
|
54
|
-
|
|
55
|
-
## Naming vs. UUIDs
|
|
56
|
-
|
|
57
|
-
A clean mental model:
|
|
58
|
-
|
|
59
|
-
- **Agent folder name** (`my-agent`) is *local* — used by `agent new`, `start`, `deploy`. It's just a directory name.
|
|
60
|
-
- **UUID** (`2b1ea07f-...`) is *canonical* — used by `trigger`, `logs`, `download`, `delete`. Stable across deploys.
|
|
61
|
-
|
|
62
|
-
`agent list` shows both:
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
┌─────────────────────────────────────┬──────────────┬──────────┬─────┐
|
|
66
|
-
│ UUID │ Name │ Project │ Ver │
|
|
67
|
-
├─────────────────────────────────────┼──────────────┼──────────┼─────┤
|
|
68
|
-
│ 2b1ea07f-3ede-4bfd-a51d-431f0bab008e│ my-agent │ Zibby UI │ 3 │
|
|
69
|
-
│ - │ scratchpad │ - │ - │
|
|
70
|
-
└─────────────────────────────────────┴──────────────┴──────────┴─────┘
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
`-` in the UUID column means a local-only agent that hasn't been deployed yet.
|
|
74
|
-
|
|
75
|
-
→ Next: [Trigger & tail logs](./trigger-and-logs)
|