UNPKG

@agentled/cli

Version:

CLI for Agentled — manage workflows, apps, and knowledge from the command line. Zero context-window cost for AI agents.

478 lines (363 loc) 32.1 kB
--- name: agentled version: 0.7.2 description: Build, manage, and execute Agentled AI workflows via MCP tools. Use when the user asks to create workflows, automate tasks, enrich leads, scrape websites, find emails, manage executions, or interact with any Agentled workspace capability. user-invocable: false --- # Agentled Workflow Automation You have access to the Agentled MCP server which lets you create, manage, and execute AI-powered workflows. Use these tools to help the user automate business processes. This file is a **router**. It carries the always-needed core (orientation, the closed list of step types, the invalid-pattern guards, the build loop). The deep reference material lives in `references/` and the tactical playbooks in the pattern library — load them on demand rather than reading everything up front. ## Reference index — load on demand When a task matches a row below, read that file before authoring. Don't preload them; that defeats the point. | When you're… | Read | |--------------|------| | Writing any step's JSON (field shapes, model IDs, loop/entry-condition syntax) | `references/step-schemas.md` (or `get_step_schema`) | | Editing an existing/live workflow (merge model, `update_step` / `update_workflow_context`, drafts) | `references/editing-workflows.md` | | Building anything that reads or sends email | `references/email-workflows.md` | | Configuring a provider write, its approval flow, or a provider status receipt | `docs/PROVIDER_WRITE_POLICY.md` | | Sourcing/collecting entities to act on later | `references/entity-pipeline.md` | | Adding cross-execution memory | `references/persistent-memory.md` | | Designing outbound / sales / investor / lead-gen at scale | `references/outreach-and-scale.md` | | Designing a saved view of a list, funnel, queue, approvals surface, or multi-source workspace cockpit | `docs/WORKSPACE_VIEWS.md` | | Producing local artifacts, or seeding a templated workspace's sidebar | `references/workspace-folder.md` | | Picking apps, testing credit-efficiently, decoding a validation error | `references/credits-apps-and-errors.md` | Tactical, shape-specific playbooks (triggers, dedup, loops, routing, reports, workflow groups, …) live in the **pattern library** — list with `agentled examples` and print one with `agentled examples <name>`. The "which pattern to read" table is below under *Before you build*. ## Goal and bottleneck first Before designing any workflow, determine what the user is actually trying to achieve and where the real bottleneck is. Agents that skip this step build the wrong system. **Two common failure modes:** - Building a full operating system when the user needed one workflow (wrong scope). - Optimizing for theme curation or content quality when the bottleneck is paid conversion or reply handling (wrong objective). **The design loop:** 1. Orient — inspect the workspace (identity, KG lists, connected apps, existing workflows, existing agents). 2. Infer — determine the likely goal and bottleneck from workspace context. 3. Ask — if the business direction is genuinely ambiguous, ask a few targeted questions (see `references/outreach-and-scale.md` for what to ask and what not to). 4. Brief — produce a short build brief (goal, assumptions, assets to reuse, KG lists, workflow group, risks, cost hotspots, build order). 5. Build — create workflows incrementally from the brief. > For multi-workflow systems, produce a group manifest before touching live workflow state. See `agentled group-manifest --help` and `docs/GROUP_MANIFEST.md`. ## Orient Before Designing Before helping with any request, inspect the workspace. Use `agentled workspace inspect` (CLI) or call these MCP tools individually: 1. **`get_workspace`** — Confirm workspace identity (name, ID), team members, pending invitations, and knowledge-list schemas. 2. **`get_workspace_company_profile`** — Business context: ICP, industry, target personas, saved preferences that should shape workflow design. 3. **`list_workflows`** — Existing automations: avoid recreating, identify reuse opportunities, note gaps. 4. **`list_knowledge_lists`** — KG lists: contacts, companies, scored leads, status machines. Shapes what a new workflow reads from or writes to. 5. **`list_connections`** — Connected apps and integrations: know which enrichment, CRM, or email providers are already authed before designing steps that depend on them. 6. **`list_agents`** — Existing agents and routines: understand what is already running autonomously before adding new agents. 7. **`list_workspace_views`** — Saved operating surfaces: reuse or update a view before creating another dashboard/list/queue. The workspace inspection directly informs which integrations are connected, what KG lists exist, whether new workflows should chain from or replace existing ones, and what existing agents already cover. When referring to KG lists or text entries in user-facing replies, include both the human-readable name/title and the stable key/id, not just the id. Example: `VC Contacts (gtm_vc_contacts)`. For existing workflow work, map the workflow back to its use case before making claims or edits: run `agentled workflows get <workflowId> --format json`, inspect `useCaseContext`, then run `agentled use-cases get <key-or-workflowGraphId> --format json` and read each `operatingGuides` knowledge text with the provided read command. If `agentGuidance.warnings` includes `MISSING_USE_CASE_OPERATING_GUIDE`, say the use-case README is missing and create/update the linked knowledge text before treating the context as complete. When the use case has `config.onboardingGoal`, inspect and mutate its typed contract through the dedicated surface: | Operation | CLI | MCP | |---|---|---| | Read normalized goal + live safeguards | `agentled use-cases goal get <id>` | `get_use_case_goal({ id })` | | Set desired policy | `agentled use-cases goal set-policy <id> --requirement <reqId> --desired <automatic\|approval_required\|disabled> [--confirm]` | `set_use_case_goal_policy({ id, requirementId, desired, confirm? })` | | Add enforcement pointer | `agentled use-cases goal bind <id> --requirement <reqId> --kind <kind> <kind flags>` | `bind_use_case_goal_requirement({ id, requirementId, binding })` | | Remove enforcement pointer | `agentled use-cases goal unbind <id> --requirement <reqId> --kind <kind> <kind flags> [--confirm]` | `unbind_use_case_goal_requirement({ id, requirementId, binding, confirm? })` | | Set declared finish line | `agentled use-cases goal set-finish-line <id> --milestone <find\|qualify\|prepare\|operate>` | `set_use_case_goal_finish_line({ id, milestone })` | | Set Goal Brief pointer | `agentled use-cases goal set-goal-brief <id> --key <knowledgeTextKey>` | `set_use_case_goal_brief({ id, goalBriefKey })` | | Bind skill reference | `agentled use-cases goal bind-skill <id> --skill-id <skillId> --agent-id <agentId> --role <role>` | `bind_use_case_goal_skill({ id, binding })` | | Remove skill reference | `agentled use-cases goal unbind-skill <id> --skill-id <skillId> --agent-id <agentId>` | `unbind_use_case_goal_skill({ id, skillId, agentId })` | | Set primary CRM reference | `agentled use-cases goal set-primary-crm <id> --app-id <appId> --label <label>` | `set_use_case_goal_primary_crm({ id, appId, label })` | Binding kinds and flags are: `workflow-step` with `--workflow-id` and `--step-id`; `agent-action` with `--agent-id`, `--app-id`, and `--action-id`; `workspace-channel` with `--channel <email|linkedin|whatsapp>`; and `routine-action` with `--routine-id`, `--app-id`, and `--action-id`. MCP passes the same fields inside `binding`. Never patch `config.onboardingGoal.approvalRequirements` through raw `use-cases update` / `update_use_case`; the server rejects it so all typed writes reuse the Safeguards UI validator. Weakening a `send`, `write`, or `delete` policy, or unbinding one of its paths, requires CLI `--confirm` or MCP `confirm: true`. Every successful mutation returns an actor-attributed audit ID. Goal mutations change desired config only: they do not change live enforcement, decide approvals, advance runtime evidence, run workflows/routines, call providers, spend credits, send messages, or write CRM data. Re-read the goal afterward and trust `approvalResolutions`, not desired policy text, for effective enforcement. Setting the Goal Brief changes only its Knowledge Text pointer. Skill bindings do not assign skills or grant tools/app permissions, and the primary CRM reference does not connect credentials or write CRM data. > **Shortcut:** `agentled workspace inspect --json` returns all six contexts as one consolidated response. Use it at session start to load the full picture in a single call. ### Workspace views When the user asks for a reusable view of a KG list, funnel, action queue, approval inbox, workflow report, agent/routine state, or combined operating surface, use `WorkspaceView`. It is a saved manifest over live workspace data, not a KG-only report and not an action executor. - Inspect existing views first: `list_workspace_views` or `agentled views list`. - Create/update only the manifest: data sources, filters/transforms, `ConfigLayout` layout, actions, refresh/safety metadata. - Use `name` for the full view page title and `navLabel` for short sidebar copy. Use `placement` to attach pinned views to a use case or workflow group. - Creating a view must not read providers, run workflows, mutate KG rows, send messages, make approval decisions, or spend credits. - Mark write/send/destructive actions with `approvalRequired: true` and use the normal approval-aware tool when the user later asks to execute them. - Prefer `draft` unless the user clearly approved the view becoming active or pinned. ### MCP-connected but no local scaffold: expected behavior If MCP tools are already connected and working, **do not block** on missing local folders. - Continue with MCP operations immediately. - Add a brief, non-blocking hint once per session: `You're connected via MCP. If you want local drafts/fixtures/tests, run "agentled init" in your project directory (or "agentled setup" for full onboarding).` - Do **not** imply setup is required for read/write API operations through MCP. `agentled setup` is the full first-run path (auth, workspace folder scaffold, MCP config, skill install, knowledge probe). `agentled init` is the targeted local scaffold when they only want the local workspace folder and cache. ### CLI freshness Use the latest `@agentled/cli` for setup, local scaffolds, fixtures, tests, and builder-work CLI commands. Prefer `npx -y @agentled/cli@latest ...` for one-off setup commands. If using a global `agentled` install, run `agentled --version` or any CLI command and follow the update notice when it reports a newer version. Do not block a working MCP-only task just because the local CLI is absent or old. Only update/install the CLI when the task needs CLI-backed setup, local files, fixtures, tests, or builder-work commands. ### Tool discovery and multi-workspace use Codex does not always preload the full Agentled MCP surface. If a tool seems "missing", search for the exact tool name before assuming the server or plugin is missing it. Common examples: - `get_knowledge_rows` - `get_knowledge_rows_by_ids` - `query_kg_edges` When this repo is used against multiple workspaces, prefer the workspace-specific MCP namespace for live work, for example `mcp__agentled_angelhive.*`, instead of relying on the generic `mcp__agentled` namespace. The generic stdio MCP server follows the CLI's active workspace from `~/.agentled/config.json`, and the current MCP session may cache that client. If you switch with `agentled auth use <workspace>`, reconnect or restart the AI client before expecting `mcp__agentled.*` to point at the new workspace. For CLI commands, make workspace targeting explicit when needed: ```bash agentled auth current agentled auth use angelhive agentled --workspace angelhive workspace inspect AGENTLED_WORKSPACE=angelhive agentled workflows list ``` ### CLI chat workflow handoffs The web UI can call `monitorWorkflowExecution`, poll the resulting job, and continue the assistant turn after the workflow becomes terminal. A CLI agent must perform that continuation itself. If `agentled chat` or `agentled chat-result` says a workflow was started, do not treat the completed chat turn as the completed user request. Capture the returned `sessionId`, `workflowId`, `executionId` or `executionInputId`, then: 1. Resolve the execution with `agentled executions list <workflowId>` when necessary. 2. Poll `agentled executions get <workflowId> <executionId>` until `completed`, `failed`, `stopped`, or `canceled`. 3. Inspect the relevant output using `agentled executions step-output`. 4. Continue the original conversation with `agentled chat --session-id <sessionId> "...terminal result context..."` so the assistant reports the verified result and does not restart the workflow. Never resend the original request while its durable chat turn or workflow is still running. A response such as `Run started` is a workflow handoff, not the final answer. ### External builder setup When this session is acting as an external AI builder for Agentled work items, register or refresh the builder identity before listing, claiming, or submitting builder work. This links the current API key to a visible builder profile in Developer settings and lets business agents attribute work correctly. - If MCP is available, call `upsert_ai_builder_profile` once per API key with the provider (`codex`, `claude`, `openclaw`, `herms`, or `custom`), a clear display name, and optional metadata such as capabilities or setup state. - If only shell/CLI access is available, run: ```bash agentled builders profile upsert --provider codex --name "Codex" ``` After the profile exists, use `list_builder_work_items` / `agentled builders work-items list` according to the polling cadence in the MCP tool description. If a builder-work command returns `Call upsert_ai_builder_profile...`, do that setup step and retry; do not ask the user to create the profile manually. ### First-run setup: choose the target AI client When helping a user connect Agentled to a specific AI client, tell the CLI which client to configure. Do this even if auto-detection would probably work; many developer machines have several clients installed and the wrong MCP config can be updated. Use the matching command: ```bash npx -y @agentled/cli setup --mcp-client codex npx -y @agentled/cli setup --mcp-client claude-code npx -y @agentled/cli setup --mcp-client cursor npx -y @agentled/cli setup --mcp-client windsurf npx -y @agentled/cli setup --mcp-client claude-desktop ``` OpenClaw and Hermes are skill-install targets, not MCP auto-config targets yet. For those clients, authenticate once, install the matching skill bundle, then configure MCP in the client's native MCP settings: ```bash npx -y @agentled/cli auth login npx -y @agentled/cli skills install --target openclaw npx -y @agentled/cli skills install --target hermes ``` For workspace switching or failed browser auth recovery, add `--reauth`, for example: ```bash npx -y @agentled/cli setup --reauth --mcp-client codex ``` After successful setup, restart or reconnect the AI client so it launches a new Agentled MCP server process with the new credentials. If the browser step fails, record whether the failing page is `https://www.agentled.app/en/cli/authorize...` or `http://127.0.0.1:<port>/callback...`; those indicate different failure surfaces. ## Valid step types (closed list) Every pipeline step **must** set `type` to one of these values. Any other value is silently normalised/rejected and the step won't execute. For full input/output schemas call `get_step_schema`. <!-- agentled-step-types:start --> | `type` | Purpose | Minimal shape | |--------|---------|---------------| | `trigger` | Entry point (manual / schedule / webhook / app event) | `{ id, type: "trigger", name, pipelineStepStartConditions: { trigger: { type: "manual" } }, next: { stepId } }` | | `appAction` | Call an app/integration action (LinkedIn, Gmail, KG, HTTP, …) | `{ id, type: "appAction", name, app: { id, actionId, source: "native" }, stepInputData: {…}, next: { stepId } }` | | `aiAction` | LLM prompt → structured JSON output | `{ id, type: "aiAction", name, pipelineStepPrompt: { template, responseStructure }, creditCost, next: { stepId } }` | | `aiActionWithTools` | LLM agent that can invoke runtime tools (web_search, workspace_memory, app actions) | `{ id, type: "aiActionWithTools", name, tools: [{ builtinType }], pipelineStepPrompt: {…}, next: { stepId } }` | | `toolAction` | Direct tool/webhook invocation (no LLM) | `{ id, type: "toolAction", name, tool: {…}, next: { stepId } }` | | `code` | Run JS/Python in a sandbox | `{ id, type: "code", name, codeConfig: { language: "javascript", code: "…", responseStructure?: { field: "type" } }, next: { stepId } }` | | `setVariables` | Deterministic expression → named output mapping (branch convergence, no LLM/credits) | `{ id, type: "setVariables", name, setVariablesConfig: { variables: [{ name, expression }] }, next: { stepId } }` | | `knowledgeSync` | Deterministic KG field mapping & link writing | `{ id, type: "knowledgeSync", name, knowledgeSync: { source, listKey, fieldMapping }, next: { stepId } }` | | `return` | Terminal step for **child** workflows — returns data to the caller | `{ id, type: "return", name, returnConfig: { fields: [{ name, stepId, field }] } }` | | `milestone` | Terminal step for **top-level** workflows | `{ id, type: "milestone", name }` | | `share` | Create a public share URL for prior step output | `{ id, type: "share", name, shareConfig: { outputSteps, visibility }, next: { stepId } }` | | `wait` | Delay / pause between steps | `{ id, type: "wait", name, waitConfig: { durationMs } | { untilISO }, next: { stepId } }` | | `branch` | Conditional routing to one of several paths | `{ id, type: "branch", name, branchConfig: { branches: [...] }, next: [...] }` | | `parallel` | Fan-out to parallel branches | `{ id, type: "parallel", name, parallelConfig: { branches: [...] }, next: { stepId } }` | | `loop` | Iterate over a collection as a first-class step (prefer `loopConfig` on an action step for most cases) | `{ id, type: "loop", name, loopConfig: {…}, next: { stepId } }` | | `end_if` | Conditional gate that stops the pipeline when criteria fail | `{ id, type: "end_if", name, entryConditions: {…} }` | | `agentOrchestrator` | Multi-agent orchestration (supervisor / debate / parallel) | `{ id, type: "agentOrchestrator", name, orchestratorConfig: {…}, next: { stepId } }` | | `manualAction` | Legacy — kept for backward compatibility; prefer `aiAction` or `appAction` | | | `systemAction` | Legacy — kept for backward compatibility; prefer `appAction` | | <!-- agentled-step-types:end --> > Use `get_step_schema` to retrieve the authoritative input/output schema for any step type. Common shapes and template-variable syntax are in `references/step-schemas.md`. ## Before you build: read the schema and the patterns Before writing pipeline JSON, pull the canonical field schema and the matching best-practice pattern. This is **mandatory** when authoring any new step type, trigger, or routing pattern — skipping it is how agents end up inventing `type: "ai"` or `knowledge_graph_query`. **Via MCP (in-session):** - `get_step_schema` — authoritative list of valid fields per step type. - `list_apps` / `get_app_actions` — exact `app.id` + `actionId` values and their input schemas. **Via CLI (shell access):** ``` agentled schema --step-type aiAction # fields valid on an aiAction step agentled schema --context # valid input-page / context field types (MCP-029) agentled tools builtins # valid aiActionWithTools builtinType values (MCP-030) agentled examples # list all patterns agentled examples trigger-design # print the full pattern agentled workflows scaffold --list # list working pipeline skeletons agentled workflows scaffold lead-scoring-kg --out pipeline.json agentled workflows scaffold ai-with-tools --out pipeline.json # aiActionWithTools starter agentled workflows validate --file pipeline.json # fast client-side preflight (no API) agentled workflows create --file pipeline.json # full server validation on save agentled best-practices # summary + link to agentic-ops repo ``` > **Silent-strip failures caught by preflight:** invalid `type` on a context / input-page field (e.g. `"multi-select"`, `"checkbox"`, `"number"`) and invalid `builtinType` on an `aiActionWithTools` tool (e.g. `"web-search"`, `"memory"`) both get silently stripped by the runtime — `workflows validate` now flags them with a "did you mean" fix. ### Prompt caching for repeated AI steps Provider prompt caching reduces cost/latency by reusing the identical prompt prefix; it does not cache or replay the AI answer. For high-volume `aiAction`, `aiActionWithTools`, and looped AI steps, put stable role, task, rubric, examples, output schema, and formatting rules before the first `{{...}}` variable. Use this layout: ```text [stable role and task] [stable rubric / scoring dimensions] [stable output JSON schema] [stable examples or decision rules] Runtime inputs: {{currentItem}} {{steps.previous.output}} {{input.field}} ``` Avoid starting prompts with `INPUTS`, `{{currentItem}}`, `{{steps.*}}`, `{{input.*}}`, `{{execution.id}}`, `{{now}}`, or `{{today}}`. In batch workflows like investor matching, keep the long scoring rubric first and put the startup/investor payload at the end so OpenAI/Anthropic can cache the shared prefix. **Which pattern to read, by task:** | You're building… | Read pattern | Scaffold | |------------------|--------------|----------| | Anything triggered by email, schedule, webhook, or app event | `01-trigger-design` (polling vs events) | `email-polling-dedup` | | Any email/intake workflow that must not double-process | `02-dedup-gates` (label-based idempotency) | `email-polling-dedup` | | A workflow that calls LLMs, scraping, or paid app actions | `03-credit-efficiency` (caching, retry, mocks) | — | | Anything using `loopConfig` or iterating a list | `04-loop-patterns` | `lead-scoring-kg` | | A child workflow called via `call-workflow` | `05-child-workflow-contracts` (use `return`, not `milestone`) | — | | Multi-path routing by score / category / condition | `06-conditional-routing` (`entryConditions.criteria`, not `conditions`) | `extract-threshold-alert` | | Anything that can fail on upstream provider errors | `07-error-handling` (`failureHandling`, retries) | — | | **Outreach** — personalized email with user approval | `08-composed-email-approval` (outreachProfile + `pipelineStepPrompt.type: "email"` + `schedule-email`) | `list-match-email` | | **Report / dashboard** — structured output + sharing + KPI history | `09-reports-and-knowledge-storage` (Config renderer + share step + `knowledgeSync`) | `lead-scoring-kg`, `extract-threshold-alert` | | **Multi-workflow system** — workflows sharing KG state and status transitions | `12-event-driven-workflow-groups` (group manifest, state machines, build order) | — | | **Entity pipeline group** — sourcing → score/qualify → find contact → outreach → scheduled orchestrator | `13-entity-pipeline-lifecycle` | `source-from-platform`, `lead-scoring-kg`, `list-match-email`, `funnel-orchestrator` | Full patterns are maintained publicly at https://github.com/agentled/agentic-ops — the CLI ships a mirrored copy, see `agentled examples`. Scaffolds are preflight-clean pipeline JSON skeletons; start from one instead of writing from scratch. For delegated agent approval on outreach, use the composed email approval pattern plus `approvalPolicy.mode: "agent-delegated"` and read `docs/DELEGATED_APPROVAL.md` in the main repo before editing. The draft step must emit top-level `recipient.email` and `delegatedApprovalReview.reviewerAgentEntityId` with the literal AgentEntity id. Daily caps, first-human gates, deterministic audit sampling, and the `disabled` kill switch are enforced by the runtime; sampled or capped drafts stay pending for human review. ## Common invalid patterns to avoid Agents routinely invent step types that sound plausible. The API **silently strips unknown top-level fields** and stores the step, so you get a 201 Created on a workflow that will never execute. Watch for these: | ❌ Wrong | ✅ Right | Why | |---------|---------|-----| | `type: "ai"` | `type: "aiAction"` | There is no generic `ai` type. Use `aiAction` for LLM prompts, `aiActionWithTools` for agentic steps. | | `type: "integration"` | `type: "appAction"` | Integrations are app actions. Set `app: { id, actionId }` to pick the integration. | | `type: "conditional_integration"` | `type: "appAction"` + `entryConditions` | Conditions are configured per-step via `entryConditions`, not a separate type. | | `type: "knowledge_graph_query"` / `knowledge_graph_upsert` / `knowledge_graph` | `type: "appAction"` with `app.id: "kg"` | KG reads/writes go through the `kg` app (`read-list`, `read-text`, `add-rows`, `update-rows`, `get-rows-by-ids`, `traverse-edges`, `store-insight`). | | `type: "slack"` / `"webhook"` / `"gmail"` | `type: "appAction"` with the right `app.id` | Apps are never types. `webhook` and `schedule` go in `pipelineStepStartConditions.trigger.type` on a `trigger` step, not as step types. | ### Top-level fields that are silently stripped Unknown fields at the step root are dropped. The most common mistakes (put them inside the right sub-object instead): | ❌ At step root | ✅ Correct location | |----------------|--------------------| | `prompt: "…"` | `pipelineStepPrompt.template` | | `responseStructure: {…}` | `pipelineStepPrompt.responseStructure` | | `appId: "gmail"`, `actionId: "send"` | `app: { id: "gmail", actionId: "send", source: "native" }` | | `listKey: "leads"` | `knowledgeSync.listKey` (for `knowledgeSync` steps) or inside `stepInputData` (for `kg` app actions) | | `channel: "#alerts"`, `webhookUrl: "…"` | `stepInputData.channel`, `stepInputData.webhookUrl` on an `appAction` | | `condition: "…"` | `entryConditions: { criteria: [{ variable, operator, value }] }` | | `triggerType: "manual"` (on a `trigger` step) | `pipelineStepStartConditions: { trigger: { type: "manual" } }` | | `note: "…"` | Step `description`, or a comment in the pipeline JSON (not persisted) | | `enabled: false` | `entryConditions.onCriteriaFail: "skip"` with a falsy criterion, or remove the step | > After `create_workflow` always call `validate_workflow` (or run `agentled workflows validate <id>`) — the CLI v0.2+ does this automatically and exits non-zero on error. Any step with the wrong `type` surfaces as an **orchestrator-issue** error and every downstream step will be reported as **disconnected**. ## Incremental Authoring (recommended) Build workflows **one step at a time**. This catches errors per-step instead of dumping a full JSON blob and getting 10+ errors at once. ### Via MCP tools ``` create_workflow({ name, goal }) → empty shell, returns workflowId add_step({ workflowId, step: { type: "trigger", ... } }) → returns validation per-step add_step({ workflowId, step: { type: "aiAction", ... }, insertAfter: "trigger-id" }) → validates template variables, model IDs, app action inputs immediately ... repeat for each step ... validate_workflow(workflowId) → full graph-level check (reachability, cycles) publish_workflow(workflowId, "live") ``` ### Via CLI ```bash agentled wf create --pipeline '{"name":"My Workflow","goal":"..."}' --skip-validate # → returns workflowId (no steps yet) agentled wf add-step <wfId> --step '{"id":"start","type":"trigger","name":"Start",...}' # → returns per-step validation agentled wf add-step <wfId> --insert-after start --rewire-next \ --step '{"id":"extract","type":"aiAction","name":"Extract",...}' # → bad variable refs, wrong model ID, or unknown app action caught HERE # ... repeat ... agentled wf validate <wfId> # full graph check agentled wf publish <wfId> --status live ``` ### Why not bulk JSON? The full-pipeline `steps` array on `create_workflow` / `update_workflow` is supported for **imports, templates, and export→edit→re-import round-trips**. Agents authoring from scratch should not use it: - No per-step feedback — a bad `type`, model ID, or variable ref on step 2 cascades into 10+ errors on steps 3-8. - No variable discovery — `{{input.X}}` vs `{{steps.trigger-id.X}}` is a common agent mistake that only surfaces after the full blob is submitted. - Agents invent step types (`"ai"`, `"integration"`, `"knowledge_graph_query"`) that are silently accepted but never execute. Internal testing: **0 errors with incremental vs 13 errors with bulk JSON** on the same pipeline. > **Editing an existing or live workflow?** The per-step merge model (`update_step` / `update_workflow_context`, the read-before-write rule for dictionary fields, drafts and staleness) is its own topic — read `references/editing-workflows.md` before touching a live workflow. ## Business metrics vs ROI (must not be conflated) Treat these as **two separate surfaces**: - **Business metrics (`pipeline.analyticsConfig`)** = customer/workflow outcome stats extracted from step outputs (volume, conversions, approvals, rates, SLA-ish KPIs), aggregated into dashboard business-metric snapshots. - **ROI (`pipeline.metadata.roi`)** = economic assumptions + rollups (minutes saved per unit, hourly rate, benchmark units/week, measured vs benchmark mode) used for ROI/time-saved reporting. **Required wording for agent outputs:** - If only `analyticsConfig` changes: say **"business metrics configured"**. - If only `metadata.roi` changes: say **"ROI assumptions configured"**. - If both change: report each section separately; never label analytics metrics as ROI metrics. This distinction applies to MCP and CLI users equally because both surfaces call the same external workflow API and return the same pipeline shape. ## Platform Skills And Guarantees (background) Agentled provides caching per step, automatic retry with backoff, a persistent Knowledge Graph, scoped permissions, and a unified credit system across 100+ integrations. For the full rationale, see `WHY-AGENTLED.md` (in this skill folder). **Practical implication:** "retry failed enrichment" and "avoid re-fetching already processed companies" are platform features. Use `retry_execution` to resume from a failed step; per-step caching is automatic. For cross-run row dedup, use `kg.upsert-rows` with a `userKey`. ## Workspace Awareness Be explicit about which Agentled workspace you are operating on. - When multiple Agentled MCP servers are registered, use the server-specific namespace directly instead of assuming a default. - The standalone CLI can store multiple saved workspace profiles. Check the active one with `agentled auth current`; switch with `agentled auth use <workspace>`; override a single command with `agentled --workspace <workspace> ...` or `AGENTLED_WORKSPACE=<workspace> ...`. - Before making destructive or customer-visible changes, confirm the target workspace via `get_workspace` or `agentled auth current`. For organizing local artifacts (drafts, decisions, debug bundles) under a per-workspace folder, see `references/workspace-folder.md`. ## Conversational Building For complex workflows, use the `chat` tool to design workflows through natural language conversation. It supports multi-turn via `session_id`. ``` chat("Build a workflow that takes a LinkedIn URL, enriches the company, finds decision-maker emails, and scores by ICP fit") ```