@zibby/skills 0.1.11 → 0.1.12

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.
@@ -0,0 +1,140 @@
1
+ ---
2
+ sidebar_position: 5
3
+ title: Dedicated egress IP
4
+ ---
5
+
6
+ # Dedicated egress IP
7
+
8
+ By default, every Zibby workflow exits via a random AWS IP that changes every run.
9
+ For most customers that's fine — but if your workflow needs to talk to a service
10
+ behind a firewall (private GitLab, Salesforce, Oracle Cloud, internal API behind a
11
+ corporate VPN), the random-IP behavior makes it unusable.
12
+
13
+ The **dedicated egress IP** addon pins all your workflow's outbound traffic to a
14
+ single static IP that you can whitelist once on the destination service.
15
+
16
+ ## Pricing
17
+
18
+ **$50/month per account.** All your projects share the same IP.
19
+
20
+ ## How it works
21
+
22
+ ```
23
+ Your Fargate task (random IP per run)
24
+
25
+ │ All HTTPS traffic tunneled through:
26
+
27
+ ┌──────────────────────────────────┐
28
+ │ Zibby's egress proxy │
29
+ │ - Validates your auth │
30
+ │ - Routes via YOUR static IP │
31
+ └──────────────────────────────────┘
32
+
33
+
34
+ Internet (sees your static IP, e.g. 54.66.241.180)
35
+ ```
36
+
37
+ Every outbound HTTPS call from your workflow exits via your dedicated IP:
38
+
39
+ | What | Whether it tunnels |
40
+ |---|---|
41
+ | `fetch()` from workflow code | ✅ via static IP |
42
+ | `git clone` private repos | ✅ via static IP |
43
+ | `npm install` from private registries | ✅ via static IP |
44
+ | `curl` / `wget` in shell scripts | ✅ via static IP |
45
+ | AWS SDK calls (S3, DynamoDB) | ❌ direct (AWS doesn't care about source IP) |
46
+
47
+ ## Enabling
48
+
49
+ ```bash
50
+ # 1. Enable the addon for your account (paid)
51
+ zibby deploy --dedicated-ip enable
52
+
53
+ # Output:
54
+ # Provisioning your dedicated egress IP...
55
+ # Done in 8s.
56
+ #
57
+ # Your static IP: 54.66.241.180
58
+ #
59
+ # Add this to your firewall allowlist, then opt projects in:
60
+ # zibby deploy --dedicated-ip use --project <project-id>
61
+
62
+ # 2. Opt each project in (free)
63
+ zibby deploy --dedicated-ip use --project my-project
64
+ ```
65
+
66
+ ## Checking status
67
+
68
+ ```bash
69
+ zibby deploy --dedicated-ip status
70
+
71
+ # Output:
72
+ # Dedicated egress IP: active
73
+ #
74
+ # Your static IP: 54.66.241.180
75
+ # Provisioned: 2026-05-02
76
+ #
77
+ # Projects opted in:
78
+ # ✓ my-project
79
+ # ✗ other-project (not opted in)
80
+ ```
81
+
82
+ ## Whitelisting on common services
83
+
84
+ **GitLab self-hosted:**
85
+ ```
86
+ Admin → Settings → Network → Outbound requests
87
+ → Allowlist: 54.66.241.180
88
+ ```
89
+
90
+ **GitHub Enterprise:**
91
+ ```
92
+ Site admin → Authentication → IP allowlist
93
+ → Add: 54.66.241.180
94
+ ```
95
+
96
+ **AWS Security Group (e.g. for a private RDS/ECS endpoint):**
97
+ ```
98
+ Inbound rule → HTTPS → Source: 54.66.241.180/32
99
+ ```
100
+
101
+ **Salesforce:**
102
+ ```
103
+ Setup → Network Access → Trusted IP ranges
104
+ → Add: 54.66.241.180 to 54.66.241.180
105
+ ```
106
+
107
+ ## What stays the same
108
+
109
+ Your IP is **stable for as long as you have the addon enabled**:
110
+
111
+ - Survives Zibby infrastructure changes (we replace proxy boxes regularly)
112
+ - Survives our region failovers
113
+ - Survives your own workflow redeploys
114
+
115
+ The only way the IP changes is if **you** disable the addon, in which case the IP
116
+ is released back to AWS at the end of your billing period.
117
+
118
+ ## Disabling
119
+
120
+ ```bash
121
+ zibby deploy --dedicated-ip disable
122
+ ```
123
+
124
+ The IP stays attached until the end of your current billing period (no immediate
125
+ proration). After that, the IP is released.
126
+
127
+ If you re-enable later, you'll get a **different** IP — we can't guarantee the
128
+ same one. Re-whitelist on your destination services if you re-enable.
129
+
130
+ ## Per-project IPs
131
+
132
+ Currently every project on your account shares the same IP. If you need separate
133
+ IPs per project (for compliance isolation, dev/staging/prod separation, etc.),
134
+ contact support.
135
+
136
+ ## Limitations
137
+
138
+ - Currently only available in `ap-southeast-2` (Sydney). Multi-region coming.
139
+ - Only IPv4. No IPv6 yet.
140
+ - Outbound only. We don't host inbound services on your IP.
@@ -0,0 +1,144 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: Per-workflow env vars
4
+ ---
5
+
6
+ # Per-workflow env vars
7
+
8
+ Each deployed workflow has its own encrypted env-var bag. The cloud runtime injects those vars into the Fargate task that runs the workflow — they show up in `process.env` like any other env var.
9
+
10
+ Use this for credentials that are **specific to one workflow** — different `ANTHROPIC_API_KEY` per pipeline, a workflow-only `DATABASE_URL`, an external webhook secret. Project-wide secrets stay on the project record (set in dashboard); workflow env wins on conflict.
11
+
12
+ ## The fast path: `--env` at deploy
13
+
14
+ Most users want to ship a `.env` alongside the workflow:
15
+
16
+ ```bash
17
+ zibby workflow deploy my-pipeline --env .env
18
+ ```
19
+
20
+ The CLI deploys the workflow as usual, then syncs the `.env` into per-workflow env vars. You'll see:
21
+
22
+ ```
23
+ ✔ Deployed my-pipeline (v1)
24
+ ✔ Bundle ready (78s)
25
+ ✔ Synced 4 env vars from .env
26
+ ```
27
+
28
+ Multiple files merge with later wins (mirrors how dotenv libraries usually layer):
29
+
30
+ ```bash
31
+ zibby workflow deploy my-pipeline --env .env --env .env.prod
32
+ ```
33
+
34
+ ## Manage after deploy: `zibby workflow env`
35
+
36
+ Four verbs, all keyed by the workflow UUID (from `zibby workflow list` or `.zibby-deploy.json`):
37
+
38
+ ```bash
39
+ zibby workflow env list <uuid> # show key names (no values)
40
+ zibby workflow env set <uuid> ANTHROPIC_API_KEY=sk-… # add or rotate one
41
+ zibby workflow env unset <uuid> OLD_KEY # remove one
42
+ zibby workflow env push <uuid> --file .env [--file .env.prod] # bulk replace
43
+ ```
44
+
45
+ `set` is for surgical updates — leaves every other key alone. `push` is the deploy-flow `--env` exposed as a standalone command for when you want to update env without redeploying the workflow itself.
46
+
47
+ `list` only returns key names, never values. Once you set a value, the only place it surfaces is inside the running container.
48
+
49
+ ### Examples
50
+
51
+ Rotate one key:
52
+ ```bash
53
+ zibby workflow env set 1a255ded-9f57-44ad-81cf-70726b13d653 ANTHROPIC_API_KEY=sk-ant-rotated
54
+ ```
55
+
56
+ Wipe all env on a workflow (push an empty file):
57
+ ```bash
58
+ zibby workflow env push <uuid> --file /dev/null
59
+ ```
60
+
61
+ CI rotation (GitHub Actions):
62
+ ```yaml
63
+ - run: |
64
+ echo "ANTHROPIC_API_KEY=$ANTHROPIC_KEY" > .env.cd
65
+ npx @zibby/cli workflow env push $WORKFLOW_UUID --file .env.cd
66
+ env:
67
+ ANTHROPIC_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
68
+ WORKFLOW_UUID: ${{ vars.WORKFLOW_UUID }}
69
+ ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
70
+ ```
71
+
72
+ ## Resolution order at trigger time
73
+
74
+ When a Fargate task starts, env vars come from three layers (later wins):
75
+
76
+ ```
77
+ built-in container vars → project secrets (DDB) → workflow env (DDB)
78
+ ```
79
+
80
+ So if both your project record and your workflow env define `ANTHROPIC_API_KEY`, the workflow's value is what `process.env.ANTHROPIC_API_KEY` returns inside the run.
81
+
82
+ ## Validation
83
+
84
+ | Field | Rule |
85
+ |---|---|
86
+ | Key name | Must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters, digits, underscores; can't start with a digit). Bash-compatible. |
87
+ | Value | Any string. Empty string is allowed. |
88
+ | `.env` files | Standard dotenv syntax — comments, quoted values, blank lines, `KEY=value` per line. |
89
+
90
+ The CLI validates locally before the API round-trip, so `zibby workflow env set <uuid> lowercase=v` fails fast with a readable message instead of a 400.
91
+
92
+ ## Use case: multi-agent workflows
93
+
94
+ Different nodes in the same workflow may want to call different model vendors:
95
+
96
+ ```js
97
+ // graph.mjs
98
+ graph
99
+ .addNode('plan', { prompt, outputSchema: Plan, agent: 'claude' }) // uses ANTHROPIC_API_KEY
100
+ .addNode('implement', { prompt, outputSchema: Diff, agent: 'cursor' }) // uses CURSOR_API_KEY
101
+ .addNode('verify', { prompt, outputSchema: Result, agent: 'codex' }); // uses OPENAI_API_KEY
102
+ ```
103
+
104
+ Drop the three keys into `.env`, deploy:
105
+
106
+ ```bash
107
+ cat > .env <<EOF
108
+ ANTHROPIC_API_KEY=sk-ant-...
109
+ CURSOR_API_KEY=key_...
110
+ OPENAI_API_KEY=sk-...
111
+ EOF
112
+
113
+ zibby workflow deploy multi-agent --env .env
114
+ ```
115
+
116
+ Each agent reads its own env var when invoked. No prompt-stuffing keys, no per-node config.
117
+
118
+ ## Security model
119
+
120
+ - **Encryption**: KMS envelope encryption with per-account keys. The plaintext never lands in CloudWatch, DDB, or Lambda logs.
121
+ - **Access control**: every env command needs project-level access on the workflow's project — checked on every request.
122
+ - **Audit**: KMS logs every decrypt operation. Cross-reference with `WORKFLOW_JOB_ID` to see exactly which run pulled which secret.
123
+ - **Rotation**: `zibby workflow env set` with a new value — the next triggered run picks it up. Currently in-flight runs keep using the value they decrypted at start time.
124
+
125
+ ## What this is *not*
126
+
127
+ - **Not for the project's primary credentials** — those live on the project record (dashboard → Project → Secrets). Use workflow env for *workflow-specific* overrides.
128
+ - **Not a values-readable store** — `list` returns key names only. If you need to retrieve the value, you'll have to push it again. This is intentional.
129
+ - **Not 1Password / Vault** — no rotation policies, no version history. Plain CRUD.
130
+
131
+ ## HTTP API (advanced / scripting)
132
+
133
+ If you can't use the CLI (e.g. inline server-side trigger, similar to `triggering.md`'s webhook section), the routes are exposed directly:
134
+
135
+ ```
136
+ GET /workflows/{uuid}/env
137
+ PUT /workflows/{uuid}/env body: {"env": {"KEY": "value", ...}}
138
+ PATCH /workflows/{uuid}/env/{key} body: {"value": "..."}
139
+ DELETE /workflows/{uuid}/env/{key}
140
+ ```
141
+
142
+ Auth is `Bearer` (session JWT or `ZIBBY_API_KEY`). Host is `https://api-prod.zibby.app`. There is no `/v1` prefix.
143
+
144
+ For everything else, use the CLI — it's the supported public surface and handles auth + UUID resolution + error messages for you.
@@ -0,0 +1,81 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: Limits & quotas
4
+ ---
5
+
6
+ # Limits & quotas
7
+
8
+ ## Workflow runtime cap
9
+
10
+ Every workflow execution has a **30-minute hard cap**. If a workflow exceeds it, the
11
+ container is terminated with exit code `124` (timeout) and the execution is marked
12
+ `failed` with reason `TIMEOUT`.
13
+
14
+ Why this exists:
15
+ - Stops runaway workflows (infinite loops, hung HTTP calls, stuck npm installs)
16
+ from burning unbounded compute
17
+ - Predictable per-execution cost ceiling
18
+ - Industry standard — GitHub Actions defaults to 6 hours, GitLab CI defaults to
19
+ 1 hour, Vercel functions cap at 5 minutes. We picked 30 min as the sweet spot
20
+ for AI-driven workflows
21
+
22
+ If your workflow needs to run longer:
23
+ - Split it into multiple shorter executions chained via input/output
24
+ - Move long-running work (large npm installs, video processing) into your bundled
25
+ artifact at deploy time so the workflow itself stays short
26
+ - Contact us about a Pro tier with a longer cap
27
+
28
+ The cap is enforced **inside** the container by a watchdog timer set on startup,
29
+ so it works even if the AWS-side controls fail.
30
+
31
+ ## Per-execution resource budget
32
+
33
+ | Resource | Limit |
34
+ |---|---|
35
+ | Runtime | 30 min |
36
+ | CPU | 1 vCPU |
37
+ | Memory | 2 GB |
38
+ | Disk | 20 GB ephemeral |
39
+ | Outbound bandwidth | Unmetered |
40
+
41
+ If you hit memory or CPU limits, the container is OOM-killed and the execution is
42
+ marked failed.
43
+
44
+ ## Container freedom (what you CAN do)
45
+
46
+ Inside your container, your workflow has **full control**:
47
+
48
+ - Install any npm package (`npm install`, `pip install`, `apt install` if root)
49
+ - Run any shell command (`curl`, `git`, `docker`-in-docker not supported)
50
+ - Spawn child processes
51
+ - Read/write files in `/workspace`
52
+ - Use the full CPU/memory budget for compute
53
+
54
+ Your code runs in an isolated Fargate task — no shared state with other customers,
55
+ no side effects on Zibby infrastructure.
56
+
57
+ ## What you CAN'T do
58
+
59
+ | Boundary | Why |
60
+ |---|---|
61
+ | Talk to other customers' workflows | Each task is a separate isolated container |
62
+ | Use someone else's static IP | Only your account's IP is reachable from your task |
63
+ | Run beyond the 30-min cap | Watchdog kills the process |
64
+ | Read Zibby infra secrets | Container IAM role only sees your execution data |
65
+ | Persist state between runs | Containers are ephemeral — use S3 or your DB for state |
66
+
67
+ ## Outbound network
68
+
69
+ By default your workflow exits via a random AWS IP that changes every run. If you
70
+ need a stable IP for whitelisting customer firewalls, see
71
+ [Dedicated egress IP](./dedicated-egress) ($50/mo addon).
72
+
73
+ ## Rate limits
74
+
75
+ | Endpoint | Limit |
76
+ |---|---|
77
+ | Trigger workflow | 60/min per account |
78
+ | Read logs | 600/min per account |
79
+ | Deploy workflow | 30/hour per account |
80
+
81
+ Hitting a rate limit returns `429 Too Many Requests` with a `Retry-After` header.
@@ -0,0 +1,104 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: Logs
4
+ ---
5
+
6
+ # Logs
7
+
8
+ Cloud workflow runs stream to CloudWatch in real time. The CLI exposes them via Server-Sent Events (SSE) — `zibby workflow logs <uuid> -t` is a thin client over that.
9
+
10
+ ## Tail live
11
+
12
+ ```bash
13
+ zibby workflow logs <uuid> -t
14
+ ```
15
+
16
+ What you see:
17
+
18
+ ```
19
+ Streaming logs for workflow 2b1ea07f-3ede-4bfd-a51d-431f0bab008e...
20
+ Press Ctrl+C to stop.
21
+
22
+ 2026-05-02 23:30:51.345 zibby v0.1.x
23
+ ────────────────────────────────────────────────────────────
24
+ Workflow: my-pipeline
25
+ Job: ee333411-...
26
+ Project: 6b60049d-...
27
+ Agent: cursor (model: auto)
28
+ ────────────────────────────────────────────────────────────
29
+ [setup] Bundle extracted (3.2s)
30
+ [setup] Loaded MyPipelineWorkflow
31
+ [setup] Registered 5 agent strategies (...)
32
+
33
+ ┌ example
34
+ │ ◆ Model: auto | key: ***bc97
35
+ │ Prompt sent to LLM:
36
+ │ ...
37
+ │ ◆ status: warn
38
+ └ done 19.4s
39
+ [done] my-pipeline completed in 19.4s
40
+ ```
41
+
42
+ ## Heroku-style follow
43
+
44
+ UUID is a *workflow* identifier, not an execution identifier. With `-t`, after one execution finishes the stream waits for the next trigger of the same workflow and auto-switches:
45
+
46
+ ```
47
+ Waiting for next execution...
48
+
49
+ ┌─ Execution: cd1f55d5...43d7 (task: 3b85ee3a)
50
+ └─ Streaming logs...
51
+
52
+ (streams the new execution)
53
+ ```
54
+
55
+ Ctrl+C to exit. There's no "exit on completion" mode — if you only want logs from one specific run, dump (without `-t`):
56
+
57
+ ```bash
58
+ zibby workflow logs <uuid>
59
+ ```
60
+
61
+ ## Reconnects
62
+
63
+ The SSE client reconnects automatically on transient errors. You'll see at most one `SSE Error:` + `Reconnecting...` per outage; once recovered, `Reconnected.` is printed once and the stream continues. No spam during cold-start flap.
64
+
65
+ ## Past runs
66
+
67
+ CloudWatch retains logs for 30 days by default. Beyond that, the per-run session folder (uploaded to S3 at the end of each execution) is the long-term archive — accessible via `zibby workflow download <uuid>`.
68
+
69
+ ## Programmatic access
70
+
71
+ The same SSE endpoint is consumable from your own code:
72
+
73
+ ```js
74
+ const eventSource = new EventSource(
75
+ `https://logs-stream.zibby.app/?jobId=${uuid}`,
76
+ { headers: { Authorization: `Bearer ${apiKey}` } }
77
+ );
78
+
79
+ eventSource.addEventListener('log', (e) => {
80
+ const { timestamp, message } = JSON.parse(e.data);
81
+ console.log(timestamp, message);
82
+ });
83
+
84
+ eventSource.addEventListener('complete', () => {
85
+ console.log('Run finished');
86
+ eventSource.close();
87
+ });
88
+ ```
89
+
90
+ Or use the polling endpoint for batch retrieval:
91
+
92
+ ```bash
93
+ GET /v1/workflows/<uuid>/logs?lines=1000&since=<unix-ms>
94
+ ```
95
+
96
+ ## Filtering by job ID
97
+
98
+ `uuid` matches the workflow. To pin to a specific execution, pass the job ID instead:
99
+
100
+ ```bash
101
+ zibby workflow logs <jobId>
102
+ ```
103
+
104
+ The CLI auto-detects: if it's an execution row, you stream that one. If it's a workflow row, you get follow-mode.
@@ -0,0 +1,114 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: Triggering programmatically
4
+ ---
5
+
6
+ # Triggering programmatically
7
+
8
+ The CLI is the public surface for triggering workflows. CI runners, cron hosts, webhook handlers — all of them shell out to the same command:
9
+
10
+ ```bash
11
+ zibby workflow trigger <uuid>
12
+ zibby workflow trigger <uuid> -p ticket=BUG-123
13
+ zibby workflow trigger <uuid> --input '{"ticket":"BUG-123","priority":"high"}'
14
+ zibby workflow trigger <uuid> --input-file payload.json
15
+ ```
16
+
17
+ Auth: set `ZIBBY_API_KEY` in the environment, or run `zibby login` once on a workstation. Either works; the CLI picks up whichever is available.
18
+
19
+ The flag surface is identical to `zibby workflow run` (local) — same `-p / --input / --input-file`, plus `--idempotency-key` for the cloud-only dedup case below. Flip the verb and the same call shape goes from local to remote.
20
+
21
+ ## CI / cron
22
+
23
+ Anywhere you can shell out, call the CLI. Don't hand-roll an HTTP client — you'll just rebuild what the CLI already does (project lookup from UUID, idempotency, quota error messages, retries).
24
+
25
+ ### GitHub Actions
26
+
27
+ ```yaml
28
+ - name: Trigger Zibby workflow
29
+ run: |
30
+ npm i -g @zibby/cli
31
+ zibby workflow trigger $WORKFLOW_UUID -p sha=$GITHUB_SHA -p pr=$PR_NUMBER
32
+ env:
33
+ WORKFLOW_UUID: 2b1ea07f-3ede-4bfd-a51d-431f0bab008e
34
+ ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
35
+ ```
36
+
37
+ ### Cron (any provider)
38
+
39
+ GitHub Actions schedule, Vercel Cron, EventBridge with a Lambda runner, fly.io machines — all the same pattern:
40
+
41
+ ```yaml
42
+ on:
43
+ schedule:
44
+ - cron: '0 9 * * 1' # every Monday 9am UTC
45
+ jobs:
46
+ triage:
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - run: npm i -g @zibby/cli
50
+ - run: zibby workflow trigger $UUID --input '{"weekly":true}'
51
+ env:
52
+ UUID: ${{ vars.WORKFLOW_UUID }}
53
+ ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
54
+ ```
55
+
56
+ ### Webhook handlers
57
+
58
+ Inside a Node/Python/Go server processing an inbound webhook (Stripe, GitHub, Linear), spawn the CLI from your handler. You inherit all of its behavior — auth, error handling, idempotency — and don't write any of it yourself.
59
+
60
+ ```js
61
+ import { execFileSync } from 'node:child_process';
62
+
63
+ app.post('/webhook', (req, res) => {
64
+ if (!verifySignature(req)) return res.status(401).end();
65
+
66
+ try {
67
+ execFileSync('zibby', [
68
+ 'workflow', 'trigger', process.env.WORKFLOW_UUID,
69
+ '--input', JSON.stringify(req.body),
70
+ '--idempotency-key', req.headers['x-event-id'],
71
+ ], { env: process.env, stdio: 'pipe' });
72
+ res.status(202).end();
73
+ } catch (err) {
74
+ res.status(502).end();
75
+ }
76
+ });
77
+ ```
78
+
79
+ If your runtime can't spawn a Node CLI (constrained Lambda layers, edge runtimes, non-Node servers without child_process), open an issue — that's the case worth a real SDK, not a documented HTTP surface.
80
+
81
+ ## Idempotency
82
+
83
+ Pass an idempotency key to deduplicate triggers within a 24-hour window:
84
+
85
+ ```bash
86
+ zibby workflow trigger <uuid> \
87
+ -p ticket=BUG-123 \
88
+ --idempotency-key webhook-2026-05-02-event-7
89
+ ```
90
+
91
+ Same key + same input within 24h returns the original `jobId` instead of starting a new run. Use the inbound event's ID (`X-Event-Id`, Stripe's `event.id`, GitHub's delivery ID) — that way a retry from the source automatically dedupes.
92
+
93
+ ## Tailing the result
94
+
95
+ After triggering, the CLI prints the `jobId`. To watch the execution:
96
+
97
+ ```bash
98
+ zibby workflow logs <uuid> -t
99
+ ```
100
+
101
+ See [`workflow logs` in the CLI Reference](../cli-reference#workflow-logs).
102
+
103
+ ## Per-workflow env vars
104
+
105
+ If your workflow needs credentials or config that's specific to it (different `ANTHROPIC_API_KEY` per pipeline, a workflow-only `DATABASE_URL`, etc.), set them via the env-var API — see [Per-workflow env vars](./env-vars). They get injected into the Fargate task at trigger time and override anything set on the project record.
106
+
107
+ ## Quotas
108
+
109
+ Per-project quota:
110
+ - Concurrent executions
111
+ - Total executions per day
112
+ - Per-execution wall-clock cap (default: 30 min)
113
+
114
+ Hit a quota and the trigger errors out with a readable message + retry hint. The CLI surfaces these directly; if you're shelling out from CI, the non-zero exit + stderr is enough to fail the job and have your retry logic kick in.
@@ -0,0 +1,112 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: Agent strategies
4
+ ---
5
+
6
+ # Agent strategies
7
+
8
+ A **strategy** is the bridge between a node and a real coding-agent CLI. The framework ships with five built-in strategies; you can also write your own.
9
+
10
+ ## Built-ins
11
+
12
+ | Strategy | Backed by | When to pick it |
13
+ |---|---|---|
14
+ | `cursor` | `cursor-agent` CLI | Fast, file-aware, great default for code tasks |
15
+ | `claude` | `@anthropic-ai/claude-agent-sdk` | Best reasoning, deep tool-use loops, large context |
16
+ | `codex` | `@openai/codex` CLI | Strong general-purpose, good for verification nodes |
17
+ | `gemini` | `@google/gemini-cli` | When you specifically want Gemini's behavior |
18
+ | `assistant` | OpenAI Assistants API | Stateful conversations, retrieval, file uploads |
19
+
20
+ ## Selecting per node
21
+
22
+ Two ways:
23
+
24
+ ```js
25
+ // 1. Per-node config — wins over everything else
26
+ graph.addNode('plan', { prompt, outputSchema, agent: 'claude' });
27
+
28
+ // 2. Project default — falls through if no per-node override
29
+ // .zibby.config.mjs
30
+ export default {
31
+ agent: { default: 'cursor' },
32
+ };
33
+ ```
34
+
35
+ The resolution order: `node.agent` → `state.agentType` → `process.env.AGENT_TYPE` → project config default.
36
+
37
+ ## Models
38
+
39
+ Each agent CLI has its own model selector. Override it via:
40
+
41
+ ```js
42
+ // Per-node model
43
+ graph.addNode('plan', {
44
+ prompt,
45
+ outputSchema,
46
+ agent: 'claude',
47
+ model: 'claude-opus-4-6',
48
+ });
49
+
50
+ // Or globally per-agent in .zibby.config.mjs
51
+ export default {
52
+ agent: {
53
+ default: 'cursor',
54
+ claude: { model: 'claude-opus-4-6' },
55
+ cursor: { model: 'auto' },
56
+ },
57
+ };
58
+ ```
59
+
60
+ `auto` (the default for cursor/claude/gemini) uses the agent CLI's own current default — which tracks the latest stable model.
61
+
62
+ ## Bring your own
63
+
64
+ The `AgentStrategy` base class is two methods:
65
+
66
+ ```js
67
+ import { AgentStrategy, registerStrategy } from '@zibby/agent-workflow';
68
+
69
+ class MyAgent extends AgentStrategy {
70
+ constructor() { super('mine', 'My custom agent', 100); }
71
+
72
+ canHandle(_context) {
73
+ return Boolean(process.env.MY_API_KEY);
74
+ }
75
+
76
+ async invoke(prompt, { schema, model }) {
77
+ const raw = await fetch('https://my.api/chat', {
78
+ method: 'POST',
79
+ body: JSON.stringify({ prompt, model: model ?? 'default' }),
80
+ }).then(r => r.text());
81
+
82
+ return { raw, structured: schema.parse(JSON.parse(raw)) };
83
+ }
84
+ }
85
+
86
+ registerStrategy(new MyAgent());
87
+ ```
88
+
89
+ Then a node can use it:
90
+
91
+ ```js
92
+ graph.addNode('plan', { prompt, outputSchema: Plan, agent: 'mine' });
93
+ ```
94
+
95
+ The framework ships **zero** agent strategies bundled — `@zibby/agent-workflow` is BYO. The five built-ins above live in `@zibby/core`, which is what `zibby workflow new` scaffolds and what the cloud runtime preloads.
96
+
97
+ ## Authentication
98
+
99
+ | Strategy | Env var | Alternative |
100
+ |---|---|---|
101
+ | `cursor` | `CURSOR_API_KEY` | `cursor-agent login` |
102
+ | `claude` | `ANTHROPIC_API_KEY` | — |
103
+ | `codex` | `OPENAI_API_KEY` | — |
104
+ | `gemini` | `GOOGLE_API_KEY` | — |
105
+ | `assistant` | `OPENAI_API_KEY` | — |
106
+
107
+ In Zibby Cloud, you have two options:
108
+
109
+ - **Project-wide credentials**: set once on the project record (dashboard → Project → Secrets) — every workflow in the project uses them.
110
+ - **Per-workflow overrides**: set on a single workflow via [`PUT /workflows/<uuid>/env`](../cloud/env-vars) — useful when one pipeline needs a different `ANTHROPIC_API_KEY` from the rest of the project, or when one workflow needs to talk to multiple agent vendors with their own keys.
111
+
112
+ Workflow env wins over project secrets on conflict (last-write-wins inside the Fargate task).