Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6978ebf
Migrate Custom Assistants to Agents with single-table architecture
HenryHengZJ Apr 6, 2026
6ef68b3
- Add down() rollback logic to all 4 DB migration files to reverse ag…
HenryHengZJ Apr 6, 2026
f93ce86
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
HenryHengZJ Apr 6, 2026
8f2c1fc
implement pagination for agents list
HenryHengZJ Apr 7, 2026
6befe25
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
yau-wd Apr 7, 2026
fa9f0ff
Merge branch 'feature/Migrate-Custom-Assistants-to-Agents' of https:/…
HenryHengZJ Apr 11, 2026
07cf359
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
HenryHengZJ Apr 11, 2026
d1a7566
Bugfix/add compact table transformer for NotionAPILoader (#6187)
HenryHengZJ Apr 11, 2026
4c0223a
Bugfix/add groq sdk (#6194)
HenryHengZJ Apr 11, 2026
38e7e49
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
HenryHengZJ Apr 11, 2026
6ba035c
Chore/include action metadata from API responses (#6204)
HenryHengZJ Apr 13, 2026
0e52877
Bugfix/Silent fallback to vm2 for sandbox execution (#6206)
HenryHengZJ Apr 13, 2026
b27e889
feat(components): improve Baidu Wenxin chat model configuration (#6140)
jimmyzhuu Apr 13, 2026
faaaa11
feat(components): add Baidu Qianfan embeddings node (#6147)
jimmyzhuu Apr 13, 2026
7de9e3e
fix/agentflow: Update default values and auto-add Start node for empt…
jocelynlin-wd Apr 13, 2026
4114b3b
Release/3.1.2 (#6215)
HenryHengZJ Apr 14, 2026
311a3f4
Fix clickjacking (#6185)
yau-wd Apr 14, 2026
32232c0
fix(agentflow): add onFlowChange notifications for deleteNode, delete…
jocelynlin-wd Apr 14, 2026
04b897a
Fix: Clean and Nuke Script (#6213)
abdullah-workday Apr 14, 2026
96fca43
feat(agentflow): add client filtering for form input options in Start…
jocelynlin-wd Apr 14, 2026
62a5d1d
feat: turn chatflow into MCP server (#5930)
prd-hoang-doan Apr 15, 2026
a77194c
feat(agentflow): optional cavasActions to allow additional buttons ne…
jocelynlin-wd Apr 15, 2026
65f6805
chore: bump @flowiseai/agentflow to 0.0.0-dev.11 (#6216)
github-actions[bot] Apr 15, 2026
73d57db
chore: bump @flowiseai/agentflow to 0.0.0-dev.12 (#6225)
github-actions[bot] Apr 15, 2026
85df44b
Feat/FlowConfigDialog UI Redesign (#6229)
HenryHengZJ Apr 16, 2026
63ea77c
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
HenryHengZJ Apr 16, 2026
be37e73
feat(agentflow): make client-specific knowledge fields for agent node…
jocelynlin-wd Apr 16, 2026
11a9c92
Fix/agentflow Fixed theming for dark mode in agentflow (#6234)
j-sanaa Apr 16, 2026
1194c97
Bring canvas buttons to same z-index level (#6235)
VaidikFlow Apr 16, 2026
0fc44e6
Fix(agentflow) - Fix z-index for validation button (#6238)
j-sanaa Apr 16, 2026
19b64e5
chore: bump @flowiseai/agentflow to 0.0.0-dev.13 (#6244)
github-actions[bot] Apr 17, 2026
42b9157
fix(mcp): guard malformed form option metadata in chatflow MCP schema…
shaun0927 Apr 17, 2026
e10a4ca
bugfix: message panel crashes via large chat volume (#6191)
jchui-wd Apr 17, 2026
b0cb4b0
- revamp agents and agentflows view pages
HenryHengZJ Apr 18, 2026
62b56d0
Bugfix/Missing Reasoning Item (#6237)
HenryHengZJ Apr 20, 2026
674bfc7
feat(components): Add support for Anthropic Claude Opus 4.7 (#6247)
AbdulSamad94 Apr 20, 2026
9032c7d
Enhance Agentflows and Agents views with version toggle buttons and r…
HenryHengZJ Apr 20, 2026
3542a04
fix(agentflow): fix variable resolution, credential sync, and add E2E…
jocelynlin-wd Apr 20, 2026
f4b1e5b
fefactored various views to ensure consistent UI and UX across the ap…
HenryHengZJ Apr 21, 2026
1e21e61
fix(server): preserve custom iframe allowlists in frame headers (#6232)
shaun0927 Apr 21, 2026
ea68f9a
fix(mcp): preserve tool input schema types and required fields (#6248)
HenryHengZJ Apr 21, 2026
8eda562
Merge branch 'main' into feature/Migrate-Custom-Assistants-to-Agents
HenryHengZJ Apr 21, 2026
ac3f5f7
Enhance agentflows and marketplaces views by adding agent-specific da…
HenryHengZJ Apr 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,5 @@ apps/*/
# Claude - session/user specific files
.claude/plans/
.claude/settings.local.json
.claude/agent-memory/*
.claude/agent-memory/*
.claude/launch.json
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Flowise support different environment variables to configure your instance. You
| PORT | The HTTP port Flowise runs on | Number | 3000 |
| CORS_ALLOW_CREDENTIALS | Enables CORS `Access-Control-Allow-Credentials` when `true` | Boolean | false |
| CORS_ORIGINS | The allowed origins for all cross-origin HTTP calls | String | |
| MCP_CORS_ORIGINS | The allowed origins for MCP endpoint cross-origin calls. If unset, only non-browser (no Origin header) requests are allowed. Set to `*` to allow all origins. | String | |
| IFRAME_ORIGINS | The allowed origins for iframe src embedding | String | |
| FLOWISE_FILE_SIZE_LIMIT | Upload File Size Limit | String | 50mb |
| DEBUG | Print logs from components | Boolean | |
Expand Down
1 change: 1 addition & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ PORT=3000
# NUMBER_OF_PROXIES= 1
# CORS_ALLOW_CREDENTIALS=false
# CORS_ORIGINS=*
# MCP_CORS_ORIGINS=*
# IFRAME_ORIGINS=*
# FLOWISE_FILE_SIZE_LIMIT=50mb
# SHOW_COMMUNITY_NODES=true
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose-queue-prebuilt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ services:
# SETTINGS
- NUMBER_OF_PROXIES=${NUMBER_OF_PROXIES}
- CORS_ORIGINS=${CORS_ORIGINS}
- MCP_CORS_ORIGINS=${MCP_CORS_ORIGINS}
- IFRAME_ORIGINS=${IFRAME_ORIGINS}
- FLOWISE_FILE_SIZE_LIMIT=${FLOWISE_FILE_SIZE_LIMIT}
- SHOW_COMMUNITY_NODES=${SHOW_COMMUNITY_NODES}
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ services:
# SETTINGS
- NUMBER_OF_PROXIES=${NUMBER_OF_PROXIES}
- CORS_ORIGINS=${CORS_ORIGINS}
- MCP_CORS_ORIGINS=${MCP_CORS_ORIGINS}
- IFRAME_ORIGINS=${IFRAME_ORIGINS}
- FLOWISE_FILE_SIZE_LIMIT=${FLOWISE_FILE_SIZE_LIMIT}
- SHOW_COMMUNITY_NODES=${SHOW_COMMUNITY_NODES}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flowise",
"version": "3.1.1",
"version": "3.1.2",
"private": true,
"homepage": "https://flowiseai.com",
"workspaces": [
Expand All @@ -25,8 +25,8 @@
"user:default": "cd packages/server/bin && ./run user",
"test": "turbo run test",
"test:coverage": "turbo run test:coverage",
"clean": "pnpm --filter \"./packages/**\" clean",
"nuke": "pnpm --filter \"./packages/**\" nuke && rimraf node_modules .turbo",
"clean": "pnpm -r clean",
"nuke": "pnpm -r nuke && rimraf node_modules .turbo",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"lint": "eslint \"**/*.{js,jsx,ts,tsx,json,md}\"",
"lint-fix": "pnpm lint --fix",
Expand Down
6 changes: 6 additions & 0 deletions packages/agentflow/examples/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ VITE_INSTANCE_URL=http://localhost:3000
# Important: Use an API Key, NOT a user authentication token
# Get this from: Flowise UI → Settings → API Keys → Create New Key
VITE_API_TOKEN=

# (Optional) Agentflow ID to load on startup
# When set, the canvas loads the saved flow from the database and enables
# Test Run and Run Status polling without needing to save first.
# Get this from the URL when editing a flow in Flowise: /agentflows/<id>
VITE_FLOW_ID=
33 changes: 25 additions & 8 deletions packages/agentflow/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ The examples app uses environment variables for configuration. To set up:

**Environment Variables:**

- `VITE_INSTANCE_URL`: Flowise API server endpoint (maps to `apiBaseUrl` prop, default: `http://localhost:3000`)
- `VITE_API_TOKEN`: Flowise API Key for programmatic access (required for authenticated endpoints)
| Variable | Required | Description |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VITE_INSTANCE_URL` | No | Flowise API server endpoint (default: `http://localhost:3000`) |
| `VITE_API_TOKEN` | Yes (authenticated) | Flowise API Key — get from Settings → API Keys |
| `VITE_FLOW_ID` | No | Agentflow ID to load on startup. When set, the canvas loads the saved flow from the database and enables Test Run and Run Status polling without saving first. Copy the ID from the Flowise URL: `/agentflows/<id>` |

**Note**: The `.env` file is gitignored and will not be committed to version control. Add your actual API key to `.env`, not `.env.example`.

Expand All @@ -81,7 +84,6 @@ Common causes:
2. **Token not loaded**

- Restart dev server after editing `.env`: `pnpm dev`
- Check browser console for: `[BasicExample] Environment check`

3. **Invalid API Key**

Expand All @@ -94,14 +96,29 @@ Common causes:

## Examples

The app opens to the **E2E (Live Instance)** example when `VITE_FLOW_ID` is set, and falls back to **Basic Usage** otherwise.

### Basic Usage (`BasicExample.tsx`)

Demonstrates core usage:
Minimal canvas integration — no database calls:

- Rendering the canvas with a hardcoded `initialFlow`
- Tracking flow changes via `onFlowChange`
- Local-only save via `onSave`
- Imperative `fitView` / `clear` via ref

### E2E — Live Instance (`E2eExample.tsx`)

Full integration with a running Flowise instance. Requires `VITE_FLOW_ID` for the best experience:

- Loads the saved flow from the database on startup (`VITE_FLOW_ID`)
- Editable flow title synced to the database on save
- Save to DB — prompts to create a new chatflow when no ID is configured
- Delete chatflow from the database
- Test Run via `POST /api/v1/internal-prediction` with markdown-rendered response (disabled when flow has validation errors)
- Run Status panel showing per-node execution results (manual refresh)

- Basic canvas rendering with `<Agentflow>` component
- Passing `apiBaseUrl` and `initialFlow` props
- Using the `ref` to access imperative methods (`validate`, `fitView`, `getFlow`, `clear`)
- Handling `onFlowChange` and `onSave` callbacks
> **API Token permissions required:** The `VITE_API_TOKEN` used for the E2E example must have **Create**, **Update**, and **Delete** permissions for Agentflows. A read-only key is not sufficient — save, rename, and delete operations will return 403.

### Additional Examples

Expand Down
22 changes: 19 additions & 3 deletions packages/agentflow/examples/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@

import { type ComponentType, lazy, Suspense, useState } from 'react'

import { apiBaseUrl, token } from './config'
import { agentflowId, apiBaseUrl, token } from './config'
import {
AllNodeTypesExampleProps,
BasicExampleProps,
CustomNodeExampleProps,
CustomUIExampleProps,
DarkModeExampleProps,
E2eExampleProps,
FilteredComponentsExampleProps,
MultiNodeFlowProps,
StatusIndicatorsExampleProps
StatusIndicatorsExampleProps,
ValidationActionsExampleProps
} from './demos'
import { PropsDisplay } from './PropsDisplay'

Expand All @@ -33,6 +35,13 @@ const examples: Array<{
props: BasicExampleProps,
component: lazy(() => import('./demos/BasicExample').then((m) => ({ default: m.BasicExample })))
},
{
id: 'e2e',
name: 'E2E (Live Instance)',
description: 'Full integration: load/save/delete flow, test run, run status — requires VITE_FLOW_ID',
props: E2eExampleProps,
component: lazy(() => import('./demos/E2eExample').then((m) => ({ default: m.E2eExample })))
},
{
id: 'multi-node',
name: 'Multi-Node Flow',
Expand Down Expand Up @@ -81,6 +90,13 @@ const examples: Array<{
description: 'Restrict available nodes with presets',
props: FilteredComponentsExampleProps,
component: lazy(() => import('./demos/FilteredComponentsExample').then((m) => ({ default: m.FilteredComponentsExample })))
},
{
id: 'canvas-actions',
name: 'Canvas Actions',
description: 'Custom FABs alongside the validation button via canvasActions',
props: ValidationActionsExampleProps,
component: lazy(() => import('./demos/ValidationActionsExample').then((m) => ({ default: m.ValidationActionsExample })))
}
]

Expand All @@ -107,7 +123,7 @@ function LoadingFallback() {
}

export default function App() {
const [selectedExample, setSelectedExample] = useState<ExampleId>('basic')
const [selectedExample, setSelectedExample] = useState<ExampleId>(agentflowId ? 'e2e' : 'basic')
const [showProps, setShowProps] = useState(false)
// Config loaded from environment variables

Expand Down
122 changes: 122 additions & 0 deletions packages/agentflow/examples/src/SaveToDbDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* SaveToDbDialog
*
* Shown when the user clicks Save and no VITE_FLOW_ID is configured.
* Creates a new agentflow via POST /api/v1/chatflows and reports the new ID.
*/

import { useState } from 'react'

import type { FlowData } from '@flowiseai/agentflow'

import { apiBaseUrl, token } from './config'

interface SaveToDbDialogProps {
flow: FlowData
flowName: string
onSaved: (agentflowId: string) => void
onCancel: () => void
}

export function SaveToDbDialog({ flow, flowName, onSaved, onCancel }: SaveToDbDialogProps) {
const [saving, setSaving] = useState(false)
const [error, setError] = useState<string | null>(null)

const authHeaders: Record<string, string> = { 'Content-Type': 'application/json' }
if (token) authHeaders['Authorization'] = `Bearer ${token}`

const handleConfirm = async () => {
setSaving(true)
setError(null)
try {
const body = {
name: flowName,
type: 'AGENTFLOW',
flowData: JSON.stringify({ nodes: flow.nodes, edges: flow.edges, viewport: flow.viewport })
}
const res = await fetch(`${apiBaseUrl}/api/v1/chatflows`, {
method: 'POST',
headers: authHeaders,
credentials: token ? 'omit' : 'include',
body: JSON.stringify(body)
})
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const created = await res.json()
onSaved(created.id)
} catch (e) {
setError(e instanceof Error ? e.message : 'Save failed')
setSaving(false)
}
}

return (
<div
style={{
position: 'fixed',
inset: 0,
background: 'rgba(0,0,0,0.55)',
zIndex: 1000,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<div
style={{
background: '#1e1e2e',
border: '1px solid #313244',
borderRadius: '8px',
padding: '24px 28px',
maxWidth: '400px',
width: '90%',
fontFamily: 'monospace',
color: '#cdd6f4'
}}
>
<div style={{ fontWeight: 700, fontSize: '14px', marginBottom: '12px', color: '#f9e2af' }}>Save flow to database?</div>
<div style={{ fontSize: '13px', color: '#a6adc8', marginBottom: '20px', lineHeight: 1.6 }}>
No <span style={{ color: '#f9e2af' }}>VITE_FLOW_ID</span> is configured. The current flow will be saved to the database
as a new agentflow.
</div>
{error && <div style={{ color: '#f38ba8', fontSize: '12px', marginBottom: '12px' }}>Error: {error}</div>}
<div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end' }}>
<button
onClick={onCancel}
disabled={saving}
style={{
padding: '6px 16px',
background: '#45475a',
color: '#cdd6f4',
border: 'none',
borderRadius: '4px',
cursor: saving ? 'not-allowed' : 'pointer',
fontFamily: 'monospace',
fontSize: '12px',
opacity: saving ? 0.5 : 1
}}
>
Cancel
</button>
<button
onClick={handleConfirm}
disabled={saving}
style={{
padding: '6px 16px',
background: '#a6e3a1',
color: '#1e1e2e',
border: 'none',
borderRadius: '4px',
cursor: saving ? 'not-allowed' : 'pointer',
fontFamily: 'monospace',
fontSize: '12px',
fontWeight: 700,
opacity: saving ? 0.7 : 1
}}
>
{saving ? 'Saving…' : 'Save to DB'}
</button>
</div>
</div>
</div>
)
}
Loading