

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# AGENTS.md23This file provides guidance to AI coding agents when working with code in this repository.45## Project Overview67Langflow is a visual workflow builder for AI-powered agents. It has a Python/FastAPI backend, React/TypeScript frontend, and a lightweight executor CLI (lfx).89## Prerequisites1011- **Python:** 3.10-3.1412- **uv:** >=0.4 (Python package manager)13- **Node.js:** >=20.19.0 (v22.12 LTS recommended)14- **npm:** v10.9+15- **make:** For build coordination1617## Common Commands1819### Development Setup20```bash21make init # Install all dependencies + pre-commit hooks22make run_cli # Build and run Langflow (http://localhost:7860)23make run_clic # Clean build and run (use when frontend issues occur)24```2526### Development Mode (Hot Reload)27```bash28make backend # FastAPI on port 7860 (terminal 1)29make frontend # Vite dev server on port 3000 (terminal 2)30```3132For component development, enable dynamic loading:33```bash34LFX_DEV=1 make backend # Load all components dynamically35LFX_DEV=mistral,openai make backend # Load only specific modules36```3738### Code Quality39```bash40make format_backend # Format Python (ruff) - run FIRST before lint41make format_frontend # Format TypeScript (biome)42make format # Both43make lint # mypy type checking44```4546### Testing47```bash48make unit_tests # Backend unit tests (pytest, parallel)49make unit_tests async=false # Sequential tests50uv run pytest path/to/test.py # Single test file51uv run pytest path/to/test.py::test_name # Single test5253make test_frontend # Jest unit tests54make tests_frontend # Playwright e2e tests55```5657### Database Migrations58```bash59make alembic-revision message="Description" # Create migration60make alembic-upgrade # Apply migrations61make alembic-downgrade # Rollback one version62```6364## Architecture6566### Monorepo Structure67```68src/69├── backend/70│ ├── base/langflow/ # Core backend package (langflow-base)71│ │ ├── api/ # FastAPI routes (v1/, v2/)72│ │ ├── components/ # Built-in Langflow components73│ │ ├── services/ # Service layer (auth, database, cache, etc.)74│ │ ├── graph/ # Flow graph execution engine75│ │ └── custom/ # Custom component framework76│ └── tests/ # Backend tests77├── frontend/ # React/TypeScript UI78│ └── src/79│ ├── components/ # UI components80│ ├── stores/ # Zustand state management81│ └── icons/ # Component icons82├── langflow-core/ # Usable provider-free Langflow distribution83├── bundles/ # Curated provider integrations84└── lfx/ # Lightweight executor and shared primitives85```8687### Key Packages88- **langflow**: Full end-user package; depends on `langflow-core` and curated provider bundles89- **langflow-core**: Service-complete, provider-bundle-free distribution; owns the `langflow` CLI90- **langflow-base**: Modular application platform (API, services, graph engine); extras add service integrations91- **lfx**: Shared execution primitives and standalone CLI (`lfx serve`, `lfx run`)9293The public dependency direction is `langflow → langflow-core → langflow-base → lfx`.94Provider packages under `src/bundles/` are added only by the full `langflow` distribution.9596### Service Layer97Backend services in `src/backend/base/langflow/services/`:98- `auth/` - Authentication99- `authorization/` - Authorization (RBAC) plugin layer — see below100- `database/` - SQLAlchemy models and migrations101- `cache/` - Caching layer102- `storage/` - File storage103- `tracing/` - Observability integrations104105### Authorization (RBAC)106107Authorization is a pluggable layer separate from authentication:108109- **OSS** ships the interface (`BaseAuthorizationService` in `lfx`) + a pass-through implementation (`LangflowAuthorizationService`) + the `authz_*` and `casbin_rule` DB schema + route guards.110- Implementations register via the `lfx.services` entry point `authorization_service` in `lfx.toml` (same pattern as the SSO `auth_service`). A registered plugin reads the `authz_*` admin tables and writes compiled rules to `casbin_rule`.111112Default is **off**: `LANGFLOW_AUTHZ_ENABLED=false`. When enabled with only the OSS stub registered, every check returns allow — the stub is a no-op so routes stay wired and audit rows still flow. Real allow/deny requires a registered authorization plugin.113114Route guards live in `langflow.services.authorization.guards` (the legacy `langflow.services.authorization.utils` path re-exports them for backward compatibility):115- `ensure_flow_permission(user, FlowAction.*, flow_id=..., flow_user_id=..., workspace_id=..., folder_id=...)` — single-flow CRUD + execute116- `ensure_deployment_permission(user, DeploymentAction.*, deployment_id=..., deployment_user_id=..., workspace_id=..., project_id=...)`117- `ensure_project_permission(user, ProjectAction.*, project_id=..., project_user_id=..., workspace_id=...)`118- `ensure_knowledge_base_permission(user, KnowledgeBaseAction.*, kb_name=..., kb_user_id=...)`119- `ensure_variable_permission(user, VariableAction.*, variable_id=..., variable_user_id=...)`120- `ensure_file_permission(user, FileAction.*, file_id=..., file_user_id=...)`121- `ensure_share_permission(user, ShareAction.*, share_id=..., share_user_id=...)`122- `filter_visible_resources(user, resource_type=..., candidates=..., act=...)` — list-endpoint filter; safe no-op in OSS123124The enforcement request shape is `(subject, domain, object, action)`:125- subject = `user:{uuid}`126- domain = `project:{uuid}` → `workspace:{uuid}` → `*` (resolved by `_resolve_flow_domain`; the more specific domain wins so project-scoped grants match directly while workspace-scoped grants still flow down via plugin-side role inheritance)127- object = `flow:{uuid}` / `deployment:{uuid}` / `project:{uuid}` / `flow:*` / etc.128- action = `read` / `write` / `create` / `delete` / `execute` / `deploy`129130**Share-aware fetch (Phase 3):** route fetch helpers (`_read_flow`, `get_flow_by_id_or_endpoint_name`, `get_deployment`, project reads in `projects.py`, v2 file fetcher, variable PATCH/DELETE in `variable.py`) branch on `BaseAuthorizationService.supports_cross_user_fetch()`. The OSS pass-through reports `False` so the existing owner-scoped queries are preserved — enabling `LANGFLOW_AUTHZ_ENABLED=true` without a registered plugin cannot widen visibility. Plugins set `SUPPORTS_CROSS_USER_FETCH=True` so resources load by id alone and `ensure_*_permission` decides access; route handlers can convert a plugin-deny `HTTPException(403)` to `HTTPException(404)` via `langflow.services.authorization.fetch.deny_to_404` to preserve UUID privacy.131132**Share CRUD API (Phase 3):** `/api/v1/authz/shares` provides POST / GET / PATCH / DELETE on `authz_share` rows. The handler enforces an OSS floor (resource owner or superuser may administer shares for that resource) so the OSS pass-through cannot let a non-owner mint share rows. Each write fires `BaseAuthorizationService.invalidate_user` / `invalidate_all` so a registered enforcer can drop cached policy. Audit rows are written via `audit_decision` with `share:create` / `share:update` / `share:delete` actions.133134**Audit query API (Phase 4):** `GET /api/v1/authz/audit` (superuser-only) exposes a paginated, filterable view of `authz_audit_log`. Supports `user_id`, `resource_type`, `resource_id`, `action`, `result`, `since`, `until` filters; page size capped at 200.135136**Default role catalog (Phase 4):** the consolidated foundations migration `7c8d9e0f1a2b_authz_foundations` seeds the three built-in `is_system=True` roles (viewer / developer / admin) with `"{resource}:{action}"` permission slugs. OSS does not interpret these — they exist so a registered plugin's policy sync has a stable bootstrap source.137138## Component Development139140Components live in `src/backend/base/langflow/components/`. To add a new component:1411421. Create component class inheriting from `Component`1432. Define `display_name`, `description`, `icon`, `inputs`, `outputs`1443. Add to `__init__.py` (alphabetical order)1454. Run with `LFX_DEV=1 make backend` for hot reload146147**IMPORTANT:** Changing a component's class name is a breaking change and should never be done. The class name serves as an identifier used to match components in saved flows and to flag them for updates in the UI. Renaming it will break existing flows that use that component.148149### Component Structure150```python151from langflow.custom import Component152from langflow.io import MessageTextInput, Output153154class MyComponent(Component):155 display_name = "My Component"156 description = "What it does"157 icon = "component-icon" # Lucide icon name or custom158159 inputs = [160 MessageTextInput(name="input_value", display_name="Input"),161 ]162 outputs = [163 Output(display_name="Output", name="output", method="process"),164 ]165166 def process(self) -> Message:167 # Component logic168 return Message(text=self.input_value)169```170171### Component Testing172Tests go in `src/backend/tests/unit/components/`. Use base classes:173- `ComponentTestBaseWithClient` - Components needing API access174- `ComponentTestBaseWithoutClient` - Pure logic components175176Required fixtures: `component_class`, `default_kwargs`, `file_names_mapping`177178## Frontend Development179180- **React 19** + TypeScript + Vite181- **Zustand** for state management182- **@xyflow/react** for graph visualization183- **Tailwind CSS** for styling184185### Custom Icons1861. Create SVG component in `src/frontend/src/icons/YourIcon/`1872. Export with `forwardRef` and `isDark` prop support1883. Add to `lazyIconImports.ts`1894. Set `icon = "YourIcon"` in Python component190191## Testing Notes192193- `@pytest.mark.api_key_required` - Tests requiring external API keys194- `@pytest.mark.no_blockbuster` - Skip blockbuster plugin195- Database tests may fail in batch but pass individually196- Pre-commit hooks require `uv run git commit`197- Always use `uv run` when running Python commands198- When running tests inside a sub-package (e.g. `langflow-base`, `lfx`), sync that package's dev group first: `uv sync --group dev --package langflow-base`. The default `uv sync` only resolves the top-level workspace and may leave dev-only test deps (e.g. `fakeredis`) uninstalled.199200### Graph Testing Pattern201202Proper Graph tests follow this pattern:2031. Build graph with connected components2042. Connect them via `.set()` calls2053. Call `async_start` and iterate over the results2064. Validate the results207208### Testing Best Practices209210- Avoid mocking in tests when possible211- Prefer real integrations for more reliable tests212213## Version Management214```bash215make patch v=1.5.0 # Update version across all packages216```217218This updates: `pyproject.toml`, `src/backend/base/pyproject.toml`, `src/frontend/package.json`219220## Pre-commit Workflow221222Pre-commit hooks run ruff and biome automatically on `git commit`, so manual223formatting is not required. To avoid an extra commit cycle when you have many224changes:2252261. Run `make format_backend` once before staging - fixes most ruff issues up front.2272. Run `uv run git commit` (the `uv run` ensures pre-commit finds the right Python).2283. If you touched backend code, run `make unit_tests` locally for faster feedback than CI.229230## Pull Request Guidelines231232- Follow [semantic commit conventions](https://www.conventionalcommits.org/)233- Reference any issues fixed (e.g., `Fixes #1234`)234- Ensure all tests pass before submitting235236## Documentation237238Documentation uses Docusaurus and lives in `docs/`:239```bash240cd docs241yarn install242yarn start # Dev server on port 3000 (prompts for 3001 if 3000 is in use)243```244
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| langflow-ai/langflowCLAUDE.md · 153k | CLAUDE.md | agent-behaviour | 16/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| vllm-project/vllmAGENTS.md · 89k | AGENTS.md | setuptestlint-formatstyle+5 | 100/100 | 14 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/langflow-ai-langflow-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.