From 46e26f74dd8493539da6fe03ee49bcc32fb3e3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Galv=C3=A3o?= Date: Fri, 27 Feb 2026 10:56:52 -0300 Subject: [PATCH 1/3] docs: refactor documentation and rebrand project to AgentFlow --- AGENTS.md | 90 +++++++++------ CLAUDE.md | 148 ++++++++++++------------- LICENSE | 93 ---------------- README.md | 152 +++++++++++--------------- apps/web/docs/run-readiness.md | 76 ++++++++----- apps/web/index.html | 2 +- apps/web/src/app/workflow-editor.ts | 4 +- docs/README.md | 9 ++ docs/api.md | 147 +++++++++++++++++++++++++ docs/architecture.md | 95 ++++++++++++++++ docs/configuration.md | 71 ++++++++++++ docs/run-persistence.md | 85 ++++++++++++++ docs/troubleshooting.md | 81 ++++++++++++++ docs/workflow-semantics.md | 110 +++++++++++++++++++ package-lock.json | 9 +- package.json | 5 +- packages/types/package.json | 4 +- packages/workflow-engine/package.json | 2 - 18 files changed, 847 insertions(+), 336 deletions(-) delete mode 100644 LICENSE create mode 100644 docs/README.md create mode 100644 docs/api.md create mode 100644 docs/architecture.md create mode 100644 docs/configuration.md create mode 100644 docs/run-persistence.md create mode 100644 docs/troubleshooting.md create mode 100644 docs/workflow-semantics.md diff --git a/AGENTS.md b/AGENTS.md index e20232d..45cf8be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,54 +1,82 @@ # Repository Guidelines ## Project Structure & Module Organization + This repository is an npm workspace monorepo: -- `apps/server`: Express API + Vite middleware integration (`src/index.ts`). Routes: `POST /api/run-stream` (SSE, primary), `POST /api/run` (batch JSON), `POST /api/resume` (approval resumption), `GET /api/config` (provider/model config), `GET /api/default-workflow` (optional startup workflow). -- `apps/web`: Vite frontend for the workflow editor (`src/app/workflow-editor.ts`). -- `packages/types`: Shared TypeScript contracts used by server, web, and engine. -- `packages/workflow-engine`: Reusable workflow execution runtime. -- `design-system/`: Git submodule with UI tokens/components consumed by the web app. -- `data/runs/`: Runtime run snapshots (gitignored artifacts). -- `.config/config.json`: Provider and model definitions served via `/api/config` (committed). `.config/default-workflow.json`: Optional startup workflow loaded by the editor on init (gitignored). + +- `apps/server`: Express API + Vite middleware integration (`src/index.ts`). +- `apps/web`: Vite frontend workflow editor (`src/app/workflow-editor.ts`). +- `packages/types`: Shared TypeScript contracts. +- `packages/workflow-engine`: Reusable workflow runtime. +- `design-system/`: Git submodule with UI tokens/components. +- `data/runs/`: Runtime run snapshots (gitignored). +- `.config/config.json`: Provider/model definitions (committed). +- `.config/default-workflow.json`: Optional startup workflow (gitignored). + +Server routes: + +- `POST /api/run-stream` (SSE run, primary) +- `POST /api/run` (batch JSON run) +- `POST /api/resume-stream` (SSE resume, primary) +- `POST /api/resume` (batch JSON resume) +- `GET /api/run/:runId` (active/persisted run fetch) +- `GET /api/config` (provider/model config) +- `GET /api/default-workflow` (optional startup workflow) ## Build, Test, and Development Commands + - `npm install`: Install all workspace dependencies. - `npm run dev`: Start integrated server + UI on `http://localhost:3000`. - `npm run dev:web`: Run frontend-only Vite dev server. -- `npm run build`: Build shared packages, server, and web app. -- `npm run lint`: Run ESLint for all TypeScript files. -- `npm run typecheck`: Type-check server and web workspaces. -- `npm test`: Run current repo test gate (`workflow-engine` + server typecheck scripts). +- `npm run build`: Build server and web app. +- `npm run build:packages`: Build shared packages. +- `npm run lint`: Run ESLint. +- `npm run typecheck`: Typecheck server and web workspaces. +- `npm test`: Run repo test gate (`workflow-engine` + server typecheck scripts). ## Coding Style & Naming Conventions -- Language: TypeScript across apps/packages, with `strict` mode enabled. -- Use `import type` where applicable (`@typescript-eslint/consistent-type-imports` is enforced). -- Keep unused parameters/locals prefixed with `_` to satisfy lint rules. -- Match existing file naming patterns: kebab-case files (`openai-agents-llm.ts`), PascalCase classes, UPPER_SNAKE_CASE constants. -- Follow existing indentation/style in each file; do not reformat unrelated code. + +- Language: TypeScript with `strict` mode. +- Use `import type` where applicable (`@typescript-eslint/consistent-type-imports`). +- Prefix unused parameters/locals with `_`. +- Naming patterns: kebab-case files, PascalCase classes, UPPER_SNAKE_CASE constants. +- Avoid reformatting unrelated code. ## Testing Guidelines -- Current CI checks in `.github/workflows/pr.yml`: `lint`, `build:packages`, `typecheck`, and `build`. + +- CI checks in `.github/workflows/pr.yml`: `lint`, `build:packages`, `typecheck`, `build`. - Web workspace uses Vitest (`npm --workspace apps/web run test`). -- When adding tests, prefer `*.test.ts` near the feature being tested. -- No coverage threshold is currently enforced; focus on targeted tests for changed behavior. +- Prefer targeted `*.test.ts` files near changed behavior. ## Commit & Pull Request Guidelines -- Prefer short, imperative commit subjects. Existing history favors Conventional Commit prefixes like `feat(web): ...` and `fix: ...`. + +- Prefer short, imperative commit subjects. +- Conventional prefixes are common (`feat(web):`, `fix:`, `chore:`). - Keep commits scoped to one logical change. -- PRs should include: purpose, risk/impact, linked issue (if any), and validation steps run locally. -- For UI changes in `apps/web`, include screenshots or short recordings. +- PRs should include purpose, risk/impact, and validation steps. +- For UI changes in `apps/web`, include screenshots or recordings. ## Security & Configuration Tips -- Set `OPENAI_API_KEY` in your shell before running agent workflows. -- Never commit secrets, `.env` files, or generated run data from `data/runs/`. + +- Set `OPENAI_API_KEY` before running agent workflows. +- Never commit secrets, `.env` files, or generated data from `data/runs/`. ## Design System Policy -- Treat `design-system/` (git submodule) as the source of truth for UI primitives. -- Prefer existing tokens/components from the submodule before building custom UI in `apps/web`. -- If a needed component does not exist in `design-system/`, pause and consult the user before adding a new component or introducing a non-design-system alternative. -- In a brand new git worktree, initialize submodules before development (`git submodule update --init --recursive`), or the design-system assets will be missing. + +- Treat `design-system/` as source of truth for UI primitives. +- Prefer submodule tokens/components over custom alternatives. +- If a needed component is missing in `design-system/`, consult user before adding alternatives. +- In fresh worktrees, run `git submodule update --init --recursive`. ## Subagent Graph Rules -- Subagent links are tool-delegation edges and do not represent execution flow edges. -- Subagent hierarchies must remain acyclic (for example, `A -> B -> A` is invalid). -- Subagent targets are tool-only nodes and cannot participate in regular execution edges. + +- Subagent links are tool-delegation edges, not execution edges. +- Subagent hierarchies must remain acyclic. +- Subagent targets are tool-only and cannot participate in regular execution edges. + +## Additional Documentation + +- `docs/README.md` +- `docs/api.md` +- `docs/workflow-semantics.md` +- `apps/web/docs/run-readiness.md` diff --git a/CLAUDE.md b/CLAUDE.md index 1e0792e..762201f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,113 +1,105 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code when working in this repository. ## Project Overview -Visual workflow builder for agentic LLM pipelines. Users drag-and-drop nodes (Start, Agent, If/Else, Approval) onto a canvas, connect them, configure LLM prompts and branching logic, then execute workflows server-side against OpenAI. Run results are persisted as JSON audit trails. +AgentFlow is a visual workflow editor and runtime for LLM pipelines. -## Monorepo Layout +Users compose workflows with `Start`, `Agent`, `Condition`, and `Approval` nodes, then execute server-side with persisted run records. -npm workspace monorepo: +## Monorepo Layout | Package | Purpose | -|---------|---------| -| `packages/types` | Shared TypeScript contracts (`WorkflowNode`, `WorkflowGraph`, `WorkflowRunResult`, etc.) | -| `packages/workflow-engine` | Pure runtime executor (`WorkflowEngine` class, `WorkflowLLM` interface) — no OpenAI dependency | -| `apps/server` | Express API + Vite dev middleware. Routes: `POST /api/run`, `POST /api/run-stream`, `POST /api/resume`, `GET /api/config`, `GET /api/default-workflow` | -| `apps/web` | Vite SPA — `WorkflowEditor` class handles canvas, node palette, and run console | -| `design-system/` | Git submodule (CodeSignal DS) — CSS tokens and components consumed by web app | +| --- | --- | +| `packages/types` | Shared TypeScript contracts (`WorkflowGraph`, `WorkflowRunResult`, etc.) | +| `packages/workflow-engine` | Runtime executor (`WorkflowEngine`, `WorkflowLLM`) | +| `apps/server` | Express API + Vite middleware/static hosting | +| `apps/web` | Vite SPA editor (`WorkflowEditor`) | +| `design-system/` | Git submodule for UI foundations/components | + +## API Surface + +- `POST /api/run-stream` +- `POST /api/run` +- `POST /api/resume-stream` +- `POST /api/resume` +- `GET /api/run/:runId` +- `GET /api/config` +- `GET /api/default-workflow` ## Common Commands ```bash -npm install # Install all workspace deps -npm run dev # Start integrated server+UI on http://localhost:3000 -npm run build # Build packages → server → web (production) -npm run lint # ESLint across all TypeScript -npm run typecheck # tsc --noEmit for server and web -npm test # Run workflow-engine + server tests - -# Workspace-specific -npm --workspace apps/web run test # Vitest for web -npm --workspace packages/workflow-engine run test # Engine tests -npm run build:packages # Build only shared packages (types + engine) +npm install +npm run dev +npm run build +npm run build:packages +npm run lint +npm run typecheck +npm test + +npm --workspace apps/web run test ``` -## Architecture - -**Request flow (streaming):** Browser (`api.ts` `runWorkflowStream`) → `POST /api/run-stream` → `WorkflowEngine.run()` with `onLog` callback → each `WorkflowLogEntry` is streamed to the client as an SSE event → final result persisted to `data/runs/run_.json` → `done` event sent to close stream. This is the primary run path — the UI renders agent responses progressively as they arrive. - -**Request flow (batch):** `POST /api/run` runs the same engine synchronously and returns the full `WorkflowRunResult` as JSON. Still available but not used by the default UI. - -**Approval/pause flow:** When engine hits an Approval node, it sets `waitingForInput=true` and the engine instance is stored in an in-memory `Map` (`store/active-workflows.ts`). Client calls `POST /api/resume` with user input to continue. +## Architecture Notes -**Agent backend:** Server agent execution is implemented through OpenAI Agents SDK (`apps/server/src/services/openai-agents-llm.ts`). Agent runs are capped with `maxTurns: 20` to bound loop iterations. +## Execution path -**Subagent hierarchy:** Agent nodes may expose other agent nodes as tools through subagent links. These links are not execution-flow edges. The subagent graph must be acyclic, and subagent targets are tool-only (no regular execution edges). +Primary path is streaming: -**Build dependency chain:** `packages/types` → `packages/workflow-engine` → `apps/server` / `apps/web`. Always run `build:packages` before typechecking or building apps. +`apps/web` -> `POST /api/run-stream` -> `WorkflowEngine.run()` -> SSE log events -> persisted run record -> final `done` event. -## Design System (Git Submodule) +Resume follows equivalent streaming path through `POST /api/resume-stream`. -`design-system/` is a CodeSignal design system git submodule. It is the **source of truth** for all UI primitives — always prefer existing DS tokens and components over custom CSS or new UI elements. If a needed component doesn't exist in the DS, consult the user before adding alternatives. +## Persistence -### Token layers +Each run/resume operation persists `data/runs/run_.json` with: -Tokens live in three foundation files linked as static CSS in `apps/web/index.html`: +- workflow graph +- logs +- status +- state snapshot +- `currentNodeId` +- `waitingForInput` -- **Colors** (`colors/colors.css`): Two-tier system — base scales (`--Colors-Base-Primary-700`) and semantic names (`--Colors-Backgrounds-Main-Default`, `--Colors-Text-Body-Strong`, `--Colors-Stroke-Default`, etc.). Dark mode is automatic via `@media (prefers-color-scheme: dark)`. -- **Spacing** (`spacing/spacing.css`): Spacing scale `--UI-Spacing-spacing-{none|min|xxs|xs|s|mxs|ms|m|ml|mxl|l|xl|xxl|xxxl|4xl|max}`, border radii `--UI-Radius-radius-{size}`, and input heights `--UI-Input-{min|xs|sm|md|lg}`. -- **Typography** (`typography/typography.css`): Font families (`--body-family`, `--heading-family`, `--code-family`), size variables (`--Fonts-Body-Default-md`), and utility classes (`.body-small`, `.heading-xxxsmall`, `.label-small`, `.code`). +## Paused-run restoration -### Component CSS + JS +On server startup, paused runs are rehydrated into in-memory active workflow map when restore fields are present. -Component CSS is loaded statically in `index.html` (button, boxes, dropdown, icons, input, modal, split-panel, tags). Interactive components with JS (Dropdown, Modal, SplitPanel) are **lazy-loaded at runtime** via dynamic `import()` from the submodule path: +## Subagent hierarchy -```typescript -// Pattern used in workflow-editor.ts -const mod = await import(`${origin}/design-system/components/dropdown/dropdown.js`); -const DropdownCtor = mod.default; -const dropdown = new DropdownCtor(container, { items, selectedValue, onSelect }); -``` - -Components currently used in the web app: -- **SplitPanel** — main layout (canvas left, run console right). Constructor: `new SplitPanel(el, { initialSplit, minLeft, minRight })`. -- **Dropdown** — model and reasoning-effort selectors. Constructor: `new Dropdown(el, { items, selectedValue, placeholder, width, onSelect })`. -- **Modal** — help dialog, confirmation prompts. Constructor: `new Modal({ size, title, content, footerButtons })`. Also `Modal.createHelpModal()` factory. -- **Button** — pure CSS (`.button .button-primary`, `.button-secondary`, `.button-danger`, sizes via `.button-small`/`.button-xsmall`). -- **Input** — pure CSS (`.input` for text/number, `.input-checkbox` / `.input-radio` with wrapper structure). - -### Styling rules for the web app +Subagent links are tool-delegation edges (`sourceHandle: "subagent"`), not execution edges. Hierarchy must be acyclic and subagent targets are tool-only nodes. -`apps/web/src/workflow-editor.css` consumes DS tokens throughout. When writing new CSS: -- Use semantic color tokens (`--Colors-Backgrounds-Main-Top`, `--Colors-Stroke-Default`) rather than base scales or raw hex values. -- Use spacing tokens (`--UI-Spacing-spacing-s`) instead of hardcoded pixel values. -- Use radius tokens (`--UI-Radius-radius-xs`) for border-radius. -- Use typography variables/classes (`--body-family`, `.body-small`) for font styling. +## Design System -## Coding Conventions +`design-system/` is a git submodule and source of truth for UI primitives. -- TypeScript strict mode everywhere. Use `import type` (enforced by `@typescript-eslint/consistent-type-imports`). -- File naming: kebab-case. Classes: PascalCase. Constants: UPPER_SNAKE_CASE. -- Prefix unused parameters with `_`. -- Tests: `*.test.ts` co-located near the feature. Vitest for web, CI runs lint → build:packages → typecheck → build. -- Commits: short imperative subjects, Conventional Commit prefixes (`feat(web):`, `fix:`, `chore:`). +- CSS tokens/components are linked in `apps/web/index.html`. +- Interactive DS components are dynamically imported in `workflow-editor.ts`. +- `apps/web/public/design-system` is a symlink to root submodule. -## Local Configuration (`.config/`) +Initialize submodule in fresh worktrees: -The `.config/` directory holds developer-local files that are partially gitignored: +```bash +git submodule update --init --recursive +``` -- **`config.json`** *(committed)* — provider and model definitions. The server serves this via `GET /api/config`; the web app loads it on startup to populate the model and reasoning-effort dropdowns. Structure: `{ providers: [{ id, name, enabled, models: [{ id, name, reasoningEfforts[] }] }] }`. -- **`default-workflow.json`** *(gitignored)* — optional startup workflow. If present, the editor loads it instead of the blank Start node. Same `{ nodes, connections }` shape as a run record's `workflow` field. +## Configuration -Agent node `userPrompt` fields support `{{PREVIOUS_OUTPUT}}` as a template token, which is substituted with the previous node's output before the LLM is called. +- `OPENAI_API_KEY`: required for agent-node execution. +- `PORT`: server port (default `3000`). +- `PROJECT_ROOT`: optional root override. +- `.config/config.json`: provider/model config served by API. +- `.config/default-workflow.json`: optional startup workflow (gitignored). -## Environment +## References -- Requires Node.js 20+. -- `OPENAI_API_KEY` must be exported in your shell for Agent node execution. -- `data/runs/` is gitignored — created automatically at runtime. -- `.config/default-workflow.json` is gitignored — create it locally to preload a workflow on startup. -- Clone with `--recurse-submodules` to pull the design-system submodule. -- In a brand new git worktree, run `git submodule update --init --recursive` before development so the design-system submodule is available. +- `docs/README.md` +- `docs/architecture.md` +- `docs/api.md` +- `docs/workflow-semantics.md` +- `docs/run-persistence.md` +- `docs/configuration.md` +- `docs/troubleshooting.md` +- `apps/web/docs/run-readiness.md` diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 809108b..0000000 --- a/LICENSE +++ /dev/null @@ -1,93 +0,0 @@ -Elastic License 2.0 - -URL: https://www.elastic.co/licensing/elastic-license - -## Acceptance - -By using the software, you agree to all of the terms and conditions below. - -## Copyright License - -The licensor grants you a non-exclusive, royalty-free, worldwide, -non-sublicensable, non-transferable license to use, copy, distribute, make -available, and prepare derivative works of the software, in each case subject to -the limitations and conditions below. - -## Limitations - -You may not provide the software to third parties as a hosted or managed -service, where the service provides users with access to any substantial set of -the features or functionality of the software. - -You may not move, change, disable, or circumvent the license key functionality -in the software, and you may not remove or obscure any functionality in the -software that is protected by the license key. - -You may not alter, remove, or obscure any licensing, copyright, or other notices -of the licensor in the software. Any use of the licensor’s trademarks is subject -to applicable law. - -## Patents - -The licensor grants you a license, under any patent claims the licensor can -license, or becomes able to license, to make, have made, use, sell, offer for -sale, import and have imported the software, in each case subject to the -limitations and conditions in this license. This license does not cover any -patent claims that you cause to be infringed by modifications or additions to -the software. If you or your company make any written claim that the software -infringes or contributes to infringement of any patent, your patent license for -the software granted under these terms ends immediately. If your company makes -such a claim, your patent license ends immediately for work on behalf of your -company. - -## Notices - -You must ensure that anyone who gets a copy of any part of the software from you -also gets a copy of these terms. - -If you modify the software, you must include in any modified copies of the -software prominent notices stating that you have modified the software. - -## No Other Rights - -These terms do not imply any licenses other than those expressly granted in -these terms. - -## Termination - -If you use the software in violation of these terms, such use is not licensed, -and your licenses will automatically terminate. If the licensor provides you -with a notice of your violation, and you cease all violation of this license no -later than 30 days after you receive that notice, your licenses will be -reinstated retroactively. However, if you violate these terms after such -reinstatement, any additional violation of these terms will cause your licenses -to terminate automatically and permanently. - -## No Liability - -*As far as the law allows, the software comes as is, without any warranty or -condition, and the licensor will not be liable to you for any damages arising -out of these terms or the use or nature of the software, under any kind of -legal claim.* - -## Definitions - -The **licensor** is the entity offering these terms, and the **software** is the -software the licensor makes available under these terms, including any portion -of it. - -**you** refers to the individual or entity agreeing to these terms. - -**your company** is any legal entity, sole proprietorship, or other kind of -organization that you work for, plus all organizations that have control over, -are under the control of, or are under common control with that -organization. **control** means ownership of substantially all the assets of an -entity, or the power to direct its management and policies by vote, contract, or -otherwise. Control can be direct or indirect. - -**your licenses** are all the licenses granted to you for the software under -these terms. - -**use** means anything you do with the software requiring one of your licenses. - -**trademark** means trademarks, service marks, and similar rights. diff --git a/README.md b/README.md index ec55175..1be0848 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,78 @@ -# Agentic Workflow Builder +# AgentFlow -Agentic Workflow Builder is a web app for visually composing, executing, and auditing LLM workflows. Drag Start, Agent, If/Else, and Approval nodes onto the canvas, connect them with Bezier edges, configure prompts inline, and run the flow through a server-side engine that records every step for later review. +Visual editor + runtime for building, executing, and auditing agentic LLM workflows. -## Repository Layout +## What It Does +- Build workflows on a canvas with `Start`, `Agent`, `Condition`, and `Approval` nodes. +- Run workflows through a server-side engine (streaming by default). +- Pause on approval nodes and resume with user decisions. +- Persist full run records for replay/audit in `data/runs/`. +- Support nested agent delegation through subagent tool links. + +## Quick Start + +1. Install dependencies: + +```bash +npm install ``` -apps/ - server/ # Express + Vite middleware; REST API + static delivery - web/ # Vite UI (TypeScript + CodeSignal design system) -packages/ - types/ # Shared TypeScript contracts (nodes, graphs, run logs) - workflow-engine/ # Reusable workflow executor w/ pluggable LLM interface -.config/ - config.json # Provider + model definitions (committed) - default-workflow.json # Optional startup workflow (gitignored) -data/ - runs/ # JSON snapshots of each workflow execution + +2. Configure environment: + +```bash +export OPENAI_API_KEY="sk-..." ``` -## Key Features +3. Start integrated dev server: + +```bash +npm run dev +``` -- **Visual Editor** – Canvas, floating palette, zoom controls, and inline node forms for prompts, branching rules, and approval copy. -- **Run Console** – Chat-style panel that renders agent responses progressively as they arrive via SSE, with per-agent labels, spinner states, and approval requests. -- **Workflow Engine** – Handles graph traversal, approvals, and LLM invocation (OpenAI Agents SDK). -- **Subagent Tools** – Agent nodes can expose connected agent nodes as nested subagent tools; these links are tool-delegation edges, not workflow execution edges. -- **Persistent Audit Trail** – Every run writes `data/runs/run_.json` containing the workflow graph plus raw execution logs, independent of what the UI chooses to display. +4. Open `http://localhost:3000`. -## Getting Started +## Core Commands -1. Install dependencies: - ```bash - npm install - ``` -2. Export your OpenAI API key in the shell: - ```bash - export OPENAI_API_KEY="sk-..." - ``` -3. Start the integrated dev server (Express + embedded Vite middleware on one port): - ```bash - npm run dev - ``` - Open `http://localhost:3000` for the UI; APIs live under `/api`. -4. Production build: - ```bash - npm run build - ``` - -### Script Reference - -| Script | Purpose | +| Command | Purpose | | --- | --- | -| `npm run dev` | Express server with Vite middleware (single origin on port 3000). | -| `npm run dev:server` | Same as `dev`; useful if you only need the backend. | -| `npm run dev:web` | Standalone Vite dev server on 5173 (talks to `/api` proxy). | -| `npm run build` | Build shared packages, server, and web bundle. | -| `npm run build:packages` | Rebuild `packages/types` and `packages/workflow-engine`. | -| `npm run build:server` / `npm run build:web` | Targeted builds. | -| `npm run lint` | ESLint via the repo-level config. | -| `npm run typecheck` | TypeScript in both apps. | - -## Run Readiness - -Workflow run preflight rules and blocking conditions are documented in `apps/web/docs/run-readiness.md`. - -## Architecture Notes - -- **`@agentic/workflow-engine`**: Pure TypeScript package that normalizes graphs, manages state, pauses for approvals, and calls an injected `WorkflowLLM`. It now exposes `getGraph()` so callers can persist what actually ran. -- **Subagent hierarchy**: Subagent connectors form an acyclic parent/child graph among Agent nodes (`A -> B -> C` allowed, `A -> B -> A` blocked). Subagent targets are tool-only and excluded from execution-flow traversal. -- **Server (`apps/server`)**: Five Express routes. `/api/run-stream` is the primary execution path — streams each `WorkflowLogEntry` as an SSE event so the UI renders progressively. `/api/run` is the same execution as a single JSON response. `/api/resume` continues paused approval workflows. `/api/config` serves `.config/config.json` (provider/model definitions). `/api/default-workflow` serves `.config/default-workflow.json` if present. -- **Web (`apps/web`)**: Vite SPA using the CodeSignal design system. Core UI logic lives in `src/app/workflow-editor.ts`; shared helpers (help modal, API client, etc.) live under `src/`. -- **Shared contracts**: `packages/types` keeps node shapes, graph schemas, log formats, and run-record definitions in sync across the stack. - -## Design System Usage (web) - -- The CodeSignal design system lives as a git submodule at `design-system/` and is served statically at `/design-system/*` via the `apps/web/public/design-system` symlink. -- Foundations and components are linked in `apps/web/index.html` (colors, spacing, typography, buttons, icons, inputs, dropdowns). -- Dropdowns in the editor use the design-system JS component, dynamically imported from `/design-system/components/dropdown/dropdown.js`. -- All bespoke CSS has been removed; remaining styling in `apps/web/src/workflow-editor.css` uses design-system tokens and classes. - -## Run Records - -Every successful or paused execution produces: - -```json -{ - "runId": "1763679127679", - "workflow": { "nodes": [...], "connections": [...] }, - "logs": [ - { "timestamp": "...", "nodeId": "node_agent", "type": "llm_response", "content": "..." } - ], - "status": "completed" -} -``` +| `npm run dev` | Server + web via Vite middleware on port `3000`. | +| `npm run dev:web` | Web-only dev server on `5173` (proxying `/api`). | +| `npm run build` | Build server and web app. | +| `npm run build:packages` | Build `packages/types` and `packages/workflow-engine`. | +| `npm run typecheck` | Typecheck server and web workspaces. | +| `npm run lint` | ESLint across repo TypeScript files. | +| `npm test` | Current test gate (`workflow-engine` + server typecheck script). | + +## Repository Structure + +- `apps/server`: Express API + dev/prod web hosting behavior. +- `apps/web`: Vite SPA workflow editor and run console. +- `packages/types`: shared TypeScript contracts. +- `packages/workflow-engine`: reusable runtime executor. +- `design-system/`: UI submodule used by web app. +- `.config/config.json`: provider/model config served by API. +- `.config/default-workflow.json`: optional startup workflow (gitignored). + +## Documentation -Files live in `data/runs/` and can be used for grading, replay, or export pipelines. These are intentionally more detailed than the UI console (which may apply formatting or filtering). +- [Documentation Map](./docs/README.md) +- [Architecture](./docs/architecture.md) +- [API Reference](./docs/api.md) +- [Workflow Semantics](./docs/workflow-semantics.md) +- [Run Persistence and Recovery](./docs/run-persistence.md) +- [Configuration](./docs/configuration.md) +- [Troubleshooting](./docs/troubleshooting.md) +- [Web Run Readiness Rules](./apps/web/docs/run-readiness.md) -## License +## Design System -This repository ships under the **Elastic License 2.0** (see `LICENSE`). You must comply with its terms—MIT references elsewhere were outdated and have been corrected. +The UI depends on the `design-system/` git submodule, exposed to the web app through: + +- `apps/web/public/design-system -> ../../../design-system` + +In fresh clones/worktrees, initialize submodules before running: + +```bash +git submodule update --init --recursive +``` diff --git a/apps/web/docs/run-readiness.md b/apps/web/docs/run-readiness.md index f429ad2..2846101 100644 --- a/apps/web/docs/run-readiness.md +++ b/apps/web/docs/run-readiness.md @@ -1,46 +1,62 @@ # Run Readiness Rules (Web UI) -This document defines when the **Run Workflow** button is enabled or disabled in the web editor. +This document defines exactly when the **Run Workflow** button is enabled in the web editor. + +Code source of truth: -Source of truth: - `apps/web/src/app/workflow-editor.ts` - `getRunDisableReason()` - `updateRunButton()` +Related docs: + +- [`docs/workflow-semantics.md`](../../../docs/workflow-semantics.md) +- [`docs/api.md`](../../../docs/api.md) + ## UI State Rules -The run button is disabled when the editor is not idle: -- `running`: button label is `Running...` -- `paused`: button label is `Paused` +Run button is disabled when editor state is not `idle`: -The cancel button is shown only while state is `running`. +- `running`: label is `Running...` +- `paused`: label is `Paused` + +Cancel button is only shown while state is `running`. ## Graph Validation Rules (Idle State) -The run button is disabled if any of these are true: +Run button is disabled when any condition below is true: + - No `Start` node exists. - More than one `Start` node exists. - Any connection references a missing source or target node. -- Any subagent link is invalid (source/target must both be Agent nodes, source must have Subagents tool enabled, and target must use the input handle). -- Any agent is targeted as subagent by more than one parent. -- Any subagent target participates in regular execution edges (subagent targets are tool-only). -- Any subagent cycle exists (`A -> B -> A`, including longer loops). -- The `Start` node has no outgoing connection. -- Nothing is reachable after `Start` (for example only `Start`, or `Start` not connected to any executable node). -- A reachable `Condition` node has neither a condition branch nor a `false` fallback branch. -- A reachable `Approval` node has neither an `approve` nor a `reject` outgoing branch. - -## Explicitly Allowed - -These cases are currently allowed and do not block run: -- Circular execution connections (non-subagent loops). -- Unreachable/disconnected nodes not on the reachable path from `Start`. -- `Condition` with only one branch connected (at least one is required). -- `Approval` with only one branch connected (at least one is required). -- Nested subagent chains (`A -> B -> C`) as long as they remain acyclic and tool-only. - -## Backend Runtime Constraint (Not a UI Preflight Rule) - -Even if UI preflight passes, backend can still reject a run: -- Workflows containing `Agent` nodes require an OpenAI-backed LLM configuration (`OPENAI_API_KEY` in environment). -- If unavailable, the backend returns an error and the UI shows it in chat. +- Any subagent link is invalid: + - source/target are not both `agent` + - source does not have `tools.subagents` + - target handle is not input +- Any subagent target has more than one parent. +- Any subagent target participates in regular execution edges. +- Any subagent cycle exists. +- `Start` node has no outgoing execution connection. +- Nothing is reachable after `Start`. +- A reachable `Condition` node has neither condition branch nor fallback (`false`) branch. +- A reachable `Approval` node has neither `approve` nor `reject` outgoing branch. + +## Explicitly Allowed (Does Not Block Run) + +- Circular regular execution connections (non-subagent loops). +- Unreachable/disconnected nodes outside `Start`-reachable path. +- `Condition` node with only one connected branch. +- `Approval` node with only one connected branch. +- Nested subagent chains (`A -> B -> C`) when acyclic and tool-only. + +## Runtime Constraints Outside UI Preflight + +Even when UI preflight passes, backend can still reject execution: + +- Workflows containing `agent` nodes require `OPENAI_API_KEY`. +- Server can return runtime validation/execution errors. + +Run and resume are executed through streaming endpoints: + +- `POST /api/run-stream` +- `POST /api/resume-stream` diff --git a/apps/web/index.html b/apps/web/index.html index 6b6164e..eafe352 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -4,7 +4,7 @@ - Agentic Workflow Builder + AgentFlow `): + +- `{"type":"start","runId":"..."}` +- `{"type":"log","entry": WorkflowLogEntry}` +- `{"type":"done","result": WorkflowRunResult}` +- `{"type":"error","message":"..."}` + +Errors: + +- `400`: invalid graph payload +- `503`: missing LLM backend for agent nodes + +## `POST /api/resume` + +Resumes a paused workflow and returns one JSON result. + +Request body: + +```json +{ "runId": "1772024622098", "input": { "decision": "approve", "note": "optional" } } +``` + +Responses: + +- `200`: updated `WorkflowRunResult` +- `400`: missing `runId` +- `404`: run not found in active in-memory workflows +- `409`: run already being resumed through another resume endpoint +- `500`: resume failure + +## `POST /api/resume-stream` + +Resumes a paused workflow and streams progress as SSE. + +Request body is same as `/api/resume`. + +SSE payloads are same shape as `/api/run-stream`. + +Responses: + +- `400`: missing `runId` +- `404`: run not found +- `409`: concurrent resume lock conflict + +## `GET /api/run/:runId` + +Returns current state for a run. + +Behavior: + +1. Validates `runId` is numeric-only. +2. Checks in-memory active runs first (running or paused). +3. Falls back to persisted `data/runs/run_.json`. + +Responses: + +- `200`: `WorkflowRunResult` +- `400`: invalid `runId` +- `404`: run not found in memory or disk +- `500`: read/parse failure + +## `GET /api/default-workflow` + +Returns `.config/default-workflow.json` if present and valid. + +Responses: + +- `200`: `WorkflowGraph` +- `404`: file missing +- `400`: file exists but invalid graph shape +- `500`: read/parse failure + +## `GET /api/config` + +Returns provider/model config from `.config/config.json`. + +Responses: + +- `200`: app config JSON +- `404`: config missing +- `500`: read/parse failure + +## Persistence and Lifecycle Notes + +- All run and resume endpoints persist run records via `saveRunRecord`. +- Non-paused runs are removed from in-memory active map after completion/failure. +- Paused runs remain active and resumable until completed/failed. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..0120b19 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,95 @@ +# Architecture + +This project is an npm workspace monorepo for building, running, and reviewing agentic workflows. + +## Monorepo Layout + +- `apps/server`: Express API server and Vite middleware integration. +- `apps/web`: Vite SPA workflow editor and run console. +- `packages/types`: Shared TypeScript contracts used by server, web, and engine. +- `packages/workflow-engine`: Pure workflow runtime with pluggable LLM adapter. +- `design-system/`: Git submodule for UI tokens and components. +- `data/runs/`: Persisted run records (`run_.json`). +- `.config/config.json`: Provider/model config served by API. +- `.config/default-workflow.json`: Optional startup workflow (gitignored). + +## Request Flows + +## Streaming run (primary path) + +1. Web app calls `POST /api/run-stream`. +2. Server creates a `WorkflowEngine`, attaches `onLog`, and streams SSE events. +3. Engine emits `WorkflowLogEntry` events as nodes execute. +4. Server persists final result to `data/runs/run_.json`. +5. Server sends a final `done` event and closes the stream. + +## Streaming resume (primary resume path) + +1. Web app calls `POST /api/resume-stream` with `runId` and approval input. +2. Server resumes an in-memory paused engine. +3. Server streams log events and final result. +4. Server persists updated run record. + +A per-run resume lock prevents concurrent resume calls (`409` if duplicated). + +## Batch paths + +- `POST /api/run`: same execution model as stream, returned as one JSON response. +- `POST /api/resume`: same resume model as stream, returned as one JSON response. + +## Runtime Model + +The workflow engine supports: + +- Node types: `start`, `agent`, `if`, `approval`. +- Branching with condition handles (`condition-`) and fallback (`false`). +- Approval pause/resume semantics with `waitingForInput` and `currentNodeId`. +- Subagent tool-delegation edges (`sourceHandle: "subagent"`) separate from execution edges. +- Deferred downstream execution queues when a pause occurs mid-branch. + +## Subagent Model + +Subagent links are validated as a strict DAG of agent-to-agent tool relationships: + +- Source must be an `agent` with `tools.subagents = true`. +- Target must be an `agent` connected on input handle. +- Target cannot be part of normal execution edges. +- A target can have only one subagent parent. +- Cycles are rejected. + +During agent execution, subagent calls are logged as runtime events: + +- `subagent_call_start` +- `subagent_call_end` +- `subagent_call_error` + +## Paused Run Restore on Server Start + +At startup, server scans `data/runs/` and rehydrates paused runs into memory when all are true: + +- `status === "paused"` +- `waitingForInput === true` +- `state` exists +- `currentNodeId` is not null + +This enables resume endpoints to keep working after restart. + +## Frontend Runtime and Recovery + +The web editor: + +- Persists canvas graph in localStorage key `agentflow-workflow`. +- Persists active run ID in localStorage key `agentflow-run-id`. +- On load, restores graph from localStorage first, then falls back to `/api/default-workflow`. +- On load, attempts run recovery via `GET /api/run/:runId`. +- Polls every 2s while recovered run status is `running`. + +## Build Dependency Order + +Build/type dependencies flow from shared packages to apps: + +1. `packages/types` +2. `packages/workflow-engine` +3. `apps/server` and `apps/web` + +Use `npm run build:packages` before server/app typecheck or build when running targeted commands. diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..a4cfc19 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,71 @@ +# Configuration + +## Environment Variables + +## `OPENAI_API_KEY` + +- Required to execute workflows containing `agent` nodes. +- When missing, server starts but agent runs are rejected with `503`. + +## `PORT` + +- Server port. +- Default: `3000`. + +## `PROJECT_ROOT` + +- Optional override for project root resolution. +- Controls where server reads: + - `.config/config.json` + - `.config/default-workflow.json` + - `data/runs/` + +## `NODE_ENV` + +- `production`: server serves built web assets from `apps/web/dist`. +- any other value: server attaches Vite middleware for development. + +## Config Files + +## `.config/config.json` (committed) + +Served by `GET /api/config` and used by web app to populate model dropdowns. + +Current structure: + +```json +{ + "providers": [ + { + "id": "openai", + "name": "OpenAI", + "enabled": true, + "models": [ + { "id": "gpt-5", "name": "GPT-5", "reasoningEfforts": ["minimal", "low", "medium", "high"] } + ] + } + ] +} +``` + +## `.config/default-workflow.json` (gitignored) + +Optional startup graph served by `GET /api/default-workflow`. + +Load precedence in web app: + +1. localStorage graph (`agentflow-workflow`) if available and valid. +2. `default-workflow.json` if available and valid. +3. fallback: generated single Start node. + +## Design System Submodule + +`design-system/` must be initialized for the web app to load design-system CSS/JS. + +Required in fresh clones/worktrees: + +```bash +git submodule update --init --recursive +``` + +`apps/web/public/design-system` is a symlink to the root submodule directory. diff --git a/docs/run-persistence.md b/docs/run-persistence.md new file mode 100644 index 0000000..5e136fe --- /dev/null +++ b/docs/run-persistence.md @@ -0,0 +1,85 @@ +# Run Persistence and Recovery + +Runs are persisted as JSON records in `data/runs/`. + +## File Naming + +- Pattern: `run_.json` +- `runId` is generated from `Date.now().toString()`. + +## Persisted Record Shape + +```json +{ + "runId": "1772129193363", + "workflow": { "nodes": [], "connections": [] }, + "logs": [], + "status": "completed", + "state": {}, + "currentNodeId": null, + "waitingForInput": false +} +``` + +Fields: + +- `workflow`: graph that actually ran. +- `logs`: ordered runtime log entries. +- `status`: current/terminal status. +- `state`: engine internal state snapshot. +- `currentNodeId`: active node when paused/running. +- `waitingForInput`: approval wait flag. + +## When Records Are Written + +Records are saved after: + +- `POST /api/run` +- `POST /api/run-stream` +- `POST /api/resume` +- `POST /api/resume-stream` + +Persistence is best-effort; save failures are logged server-side. + +## Active In-memory Runs + +Server keeps a map of active `WorkflowEngine` instances. + +- Paused runs remain in memory. +- Completed/failed runs are removed from memory. +- Persisted records remain on disk. + +## Fetching a Run + +`GET /api/run/:runId` lookup order: + +1. In-memory active run (if still running/paused). +2. Persisted file from `data/runs/`. + +If both missing, API returns `404`. + +## Startup Restore for Paused Runs + +On server startup, persisted records are scanned and restored to active memory only if: + +- `status === "paused"` +- `waitingForInput === true` +- `state` exists +- `currentNodeId != null` + +This allows paused approval runs to survive restarts. + +## Frontend Recovery Flow + +Web app stores active run ID in localStorage (`agentflow-run-id`) and on load: + +1. Calls `GET /api/run/:runId`. +2. If `status === running`, renders partial logs and polls every 2 seconds. +3. If `status === paused && waitingForInput`, re-shows approval UI. +4. If run missing (`404`), clears stored run ID. + +## Data Hygiene + +- `data/runs/` is gitignored and can grow quickly. +- Remove stale run files periodically in local environments. +- Do not commit run data to source control. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..3ebebca --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,81 @@ +# Troubleshooting + +## `OPENAI_API_KEY is required to run workflows with Agent nodes` + +Cause: Server started without `OPENAI_API_KEY`. + +Fix: + +1. Export key in shell. +2. Restart `npm run dev`. + +## Run button disabled unexpectedly + +Check run-readiness rules in [`apps/web/docs/run-readiness.md`](../apps/web/docs/run-readiness.md). + +Common causes: + +- Missing or duplicate Start nodes. +- Broken connections. +- Invalid subagent graph. +- Missing outgoing branch for reachable `if`/`approval` nodes. + +## Resume returns `Run ID not found` + +Cause: paused engine not currently in server memory. + +Possible reasons: + +- Server restarted before paused state was persisted with full restore fields. +- Run ID is stale/invalid. + +Fix: + +1. Use `GET /api/run/:runId` to inspect status. +2. If not recoverable, re-run workflow. + +## Resume returns `409` conflict + +Cause: same run is being resumed concurrently (`/resume` and `/resume-stream` lock conflict). + +Fix: resume from only one client path at a time. + +## `default-workflow.json` not loading + +Checklist: + +1. File exists at `.config/default-workflow.json`. +2. Shape is `{ "nodes": [], "connections": [] }`. +3. localStorage `agentflow-workflow` is not overriding it. + +## UI styles/components missing + +Cause: design-system submodule not initialized. + +Fix: + +```bash +git submodule update --init --recursive +``` + +Also verify symlink: + +- `apps/web/public/design-system -> ../../../design-system` + +## Build fails after shared package changes + +Cause: apps depend on built outputs of shared packages. + +Fix: + +```bash +npm run build:packages +npm run typecheck +npm run build +``` + +## `GET /api/run/:runId` returns `400 Invalid runId` + +Cause: route only accepts numeric `runId` to prevent path traversal. + +Fix: pass raw numeric run ID (timestamp string), no prefixes or suffixes. diff --git a/docs/workflow-semantics.md b/docs/workflow-semantics.md new file mode 100644 index 0000000..21bfe4d --- /dev/null +++ b/docs/workflow-semantics.md @@ -0,0 +1,110 @@ +# Workflow Semantics + +This document describes what each node and connection means at runtime. + +## Node Types + +## `start` + +- Entry point for execution. +- Output value is `node.data.initialInput` or empty string. +- Must exist exactly once for a runnable graph. + +## `agent` + +- Invokes configured LLM backend. +- Reads: + - `systemPrompt` + - `userPrompt` + - `model` + - `reasoningEffort` + - `tools` (`web_search`, `subagents`) +- `{{PREVIOUS_OUTPUT}}` is replaced with prior node output. +- If `userPrompt` is empty, engine falls back to previous output text. + +## `if` + +- Evaluates conditions against previous output (stringified/lowercased). +- Supported operators: `equal`, `contains`. +- First matching condition wins. +- Connection handles: + - `condition-` for condition branches + - `false` for fallback branch +- Legacy compatibility: condition index `0` also accepts old handle `true`. + +## `approval` + +- Pauses execution with `status = paused`, `waitingForInput = true`, `currentNodeId = node.id`. +- Resume input is normalized to: + +```json +{ "decision": "approve" | "reject", "note": "" } +``` + +- Resume follows outgoing branch where `sourceHandle === decision`. + +## Connection Types + +## Execution edges + +Regular workflow edges that advance execution. + +Examples: + +- `start(output) -> agent(input)` +- `if(condition-0) -> agent(input)` +- `approval(approve) -> agent(input)` + +## Subagent edges + +Tool-delegation edges only, not execution flow edges. + +- Marked by `sourceHandle: "subagent"`. +- Used to build nested agent-tool trees for agent nodes. + +## Subagent Constraints + +A subagent graph is valid only when: + +- Source and target are both `agent` nodes. +- Source has `tools.subagents = true`. +- Target handle is input (`targetHandle` omitted or `input`). +- No self-reference. +- No cycles. +- A target has at most one subagent parent. +- Subagent targets do not appear in regular execution edges. + +Invalid subagent structures are rejected by both UI preflight and runtime validation. + +## Execution and Branching Behavior + +- Multiple outgoing execution branches run concurrently (`Promise.all`). +- If execution pauses while other branches remain, downstream nodes are queued and resumed later. +- After resume, engine drains deferred queue while status remains `running`. + +## Log Event Semantics + +Typical log types include: + +- `step_start` +- `start_prompt` +- `logic_check` +- `wait_input` +- `input_received` +- `llm_response` +- `llm_error` +- `error` + +Subagent runtime events are logged as JSON payloads in `content` with types: + +- `subagent_call_start` +- `subagent_call_end` +- `subagent_call_error` + +## Backward Compatibility Rules + +Engine normalizes legacy data: + +- Node type `input` is mapped to `approval`. +- Legacy `if.data.condition` is mapped to `if.data.conditions`. +- Legacy `true` connection handle remains supported for first condition branch. diff --git a/package-lock.json b/package-lock.json index 672a5ee..17a60b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,12 @@ { - "name": "learn_agentic-workflows", + "name": "agentflow", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "learn_agentic-workflows", + "name": "agentflow", "version": "1.0.0", - "license": "MIT", "workspaces": [ "apps/*", "packages/*" @@ -5643,13 +5642,11 @@ }, "packages/types": { "name": "@agentic/types", - "version": "1.0.0", - "license": "MIT" + "version": "1.0.0" }, "packages/workflow-engine": { "name": "@agentic/workflow-engine", "version": "1.0.0", - "license": "MIT", "dependencies": { "@agentic/types": "file:../types" } diff --git a/package.json b/package.json index df3d11d..54b4fab 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,8 @@ { - "name": "learn_agentic-workflows", + "name": "agentflow", "version": "1.0.0", "private": true, - "description": "Agentic Workflow Builder monorepo (web + server + shared packages)", - "license": "MIT", + "description": "AgentFlow monorepo (web + server + shared packages)", "workspaces": [ "apps/*", "packages/*" diff --git a/packages/types/package.json b/packages/types/package.json index 9b9d3a5..ebe7bc8 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -13,7 +13,5 @@ "dev": "tsc -w -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "npm run typecheck" - }, - "license": "MIT" + } } - diff --git a/packages/workflow-engine/package.json b/packages/workflow-engine/package.json index dace1ca..a0b6959 100644 --- a/packages/workflow-engine/package.json +++ b/packages/workflow-engine/package.json @@ -14,9 +14,7 @@ "test": "npm run typecheck", "typecheck": "tsc -p tsconfig.json --noEmit" }, - "license": "MIT", "dependencies": { "@agentic/types": "file:../types" } } - From fd2e07ac1090826bcf39a20882791405ac53f23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Galv=C3=A3o?= Date: Fri, 27 Feb 2026 11:00:37 -0300 Subject: [PATCH 2/3] docs(web): rewrite help modal for end users --- apps/web/src/data/help-content.ts | 81 +++++++++++++++++++------------ 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/apps/web/src/data/help-content.ts b/apps/web/src/data/help-content.ts index 82f1a24..3e8a54a 100644 --- a/apps/web/src/data/help-content.ts +++ b/apps/web/src/data/help-content.ts @@ -3,53 +3,72 @@ export const helpContent = ` Contents

Overview

-

The Agentic Workflow Builder lets you compose agent flows with Start, Agent, Condition, and Approval nodes. Drag nodes, connect them, configure prompts, and run against the server-side workflow engine.

+

AgentFlow helps you design step-by-step AI workflows visually. Add nodes, connect them, run the flow, and review each response in the Run Console.

-
-

Getting Started

+
+

Build a Workflow

    -
  1. Drag a Start node (auto-added) and at least one Agent node onto the canvas.
  2. -
  3. Connect nodes by dragging from an output port to an input port.
  4. -
  5. Open node settings (gear icon) to configure prompts, models, and approvals.
  6. -
  7. Enter the initial user prompt in the Run Console and click Run Workflow.
  8. +
  9. Keep one Start node as your entry point.
  10. +
  11. Add nodes from the left palette and connect them in order.
  12. +
  13. Open each node to fill in prompts or rules.
  14. +
  15. Enter your Initial Prompt and click Run Workflow.
-
-

Key Features

-

Visual Canvas

-

Pannable/zoomable canvas with SVG connections, floating palette, and snap-friendly controls.

-

Inline Node Editing

-

Expand a node to edit prompts, branching conditions, approval text, and tool toggles.

-

Run Console

-

Chat-style log with status indicator, agent spinner, and approval prompts when workflows pause for review.

+
+

Node Guide

+
    +
  • Start: Begins the workflow with your initial input.
  • +
  • Agent: Generates a response based on your prompt and settings.
  • +
  • Condition: Sends the flow down different paths based on match rules.
  • +
  • Approval: Pauses the flow so you can choose Approve or Reject.
  • +
-
-

Workflow

-
    -
  1. Design: Add nodes, wire edges, and double-check that the Start node connects to your flow.
  2. -
  3. Configure: Provide model settings, prompts, and optional tools per agent node.
  4. -
  5. Run: Click Run Workflow. The console streams logs from the server.
  6. -
  7. Approve: When approval nodes are reached, respond with Approve or Reject to continue.
  8. -
+
+

Run and Review

+

While running, results appear in real time in the Run Console.

+
    +
  • Agent replies appear as they complete.
  • +
  • If an Approval node is reached, the flow pauses until you decide.
  • +
  • You can cancel a running flow at any time with the cancel button.
  • +
+
+ +
+

Helpful Tips

+
    +
  • Start simple: Start → Agent, then add branching.
  • +
  • Give each Agent a clear role in its system prompt.
  • +
  • Use Condition nodes to control routing explicitly.
  • +
  • If you refresh during a run, AgentFlow will try to recover it automatically.
  • +
-
-

FAQ

+
+

Common Issues

+
+ Run button is disabled +

Make sure your Start node is connected, links are valid, and branch nodes (Condition/Approval) have at least one outgoing path.

+
+
+ Flow pauses and does not continue +

An Approval node is waiting for your decision. Click Approve or Reject in the Run Console.

+
- Why does a workflow pause? -

Approval nodes intentionally pause execution until you make a decision in the Run Console.

+ Run did not recover after refresh +

If recovery is not available, run the workflow again from the canvas.

`; From f3bda0fb2a8e38386a68e7af8a5fa64c13d32257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Galv=C3=A3o?= Date: Fri, 27 Feb 2026 11:14:40 -0300 Subject: [PATCH 3/3] docs: address CodeRabbit documentation follow-ups --- AGENTS.md | 6 +++--- CLAUDE.md | 1 + docs/troubleshooting.md | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 45cf8be..3d3cdc9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -70,9 +70,9 @@ Server routes: ## Subagent Graph Rules -- Subagent links are tool-delegation edges, not execution edges. -- Subagent hierarchies must remain acyclic. -- Subagent targets are tool-only and cannot participate in regular execution edges. +- Links between agents and subagents are tool-delegation edges, not execution edges. +- Hierarchies of subagents must remain acyclic. +- Targets of subagent links are tool-only and cannot participate in regular execution edges. ## Additional Documentation diff --git a/CLAUDE.md b/CLAUDE.md index 762201f..2365ca8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,6 +7,7 @@ This file provides guidance to Claude Code when working in this repository. AgentFlow is a visual workflow editor and runtime for LLM pipelines. Users compose workflows with `Start`, `Agent`, `Condition`, and `Approval` nodes, then execute server-side with persisted run records. +In the UI, `Condition` maps to runtime node type `"if"` in workflow JSON and persisted run records. ## Monorepo Layout diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 3ebebca..d77f4b2 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -36,9 +36,9 @@ Fix: ## Resume returns `409` conflict -Cause: same run is being resumed concurrently (`/resume` and `/resume-stream` lock conflict). +Cause: same run is being resumed concurrently (`/api/resume` and `/api/resume-stream` lock conflict). -Fix: resume from only one client path at a time. +Fix: resume from only one `/api` client path at a time. ## `default-workflow.json` not loading