feat(agentflow): update agentflow sdk contract and fix lint configs (#5752)

This commit is contained in:
Jocelyn Lin
2026-02-17 10:38:00 -08:00
committed by GitHub
parent d63a814cd9
commit 3b9d912675
25 changed files with 170 additions and 87 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ module.exports = {
}
},
parser: '@typescript-eslint/parser',
ignorePatterns: ['**/node_modules', '**/dist', '**/build', '**/package-lock.json'],
ignorePatterns: ['**/node_modules', '**/dist', '**/build', '**/coverage', '**/package-lock.json'],
plugins: ['unused-imports'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
+1 -1
View File
@@ -137,7 +137,7 @@ module.exports = {
},
overrides: [
{
files: ['examples/**/*.{js,jsx,ts,tsx}'],
files: ['examples/**/*.{js,jsx,ts,tsx}', '**/*.md/**'],
rules: {
'no-console': 'off',
'@typescript-eslint/no-non-null-assertion': 'off'
+83 -1
View File
@@ -43,12 +43,94 @@ import '@flowise/agentflow/flowise.css'
export default function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Agentflow instanceUrl='http://localhost:3000' token='your-api-key' />
<Agentflow apiBaseUrl='http://localhost:3000' token='your-api-key' />
</div>
)
}
```
### With Initial Flow Data and Callbacks
```tsx
import { useRef } from 'react'
import { Agentflow, type AgentFlowInstance, type FlowData } from '@flowise/agentflow'
import '@flowise/agentflow/flowise.css'
export default function App() {
const ref = useRef<AgentFlowInstance>(null)
const initialFlow: FlowData = {
nodes: [
{
id: 'startAgentflow_0',
type: 'agentflowNode',
position: { x: 100, y: 100 },
data: {
id: 'startAgentflow_0',
name: 'startAgentflow',
label: 'Start',
color: '#7EE787',
hideInput: true,
outputAnchors: [{ id: 'startAgentflow_0-output-0', name: 'start', label: 'Start', type: 'start' }]
}
}
],
edges: [],
viewport: { x: 0, y: 0, zoom: 1 }
}
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Agentflow
ref={ref}
apiBaseUrl='http://localhost:3000'
token='your-api-key'
initialFlow={initialFlow}
onFlowChange={(flow) => console.log('Flow changed:', flow)}
onSave={(flow) => console.log('Flow saved:', flow)}
/>
</div>
)
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `apiBaseUrl` | `string` | **(required)** | Flowise API server endpoint |
| `token` | `string` | — | Authentication token for API calls |
| `initialFlow` | `FlowData` | — | Initial flow data to render (uncontrolled — only used on mount) |
| `flowId` | `string` | — | Flow ID for loading an existing flow from the API |
| `components` | `string[]` | — | Restrict which node types appear in the palette |
| `onFlowChange` | `(flow: FlowData) => void` | — | Called when the flow changes (node/edge add, remove, move) |
| `onSave` | `(flow: FlowData) => void` | — | Called when the user triggers a save |
| `onFlowGenerated` | `(flow: FlowData) => void` | — | Called when a flow is generated via AI |
| `theme` | `'light' \| 'dark' \| 'system'` | `'system'` | Theme override |
| `readOnly` | `boolean` | `false` | Disable editing (nodes not draggable/connectable) |
| `showDefaultHeader` | `boolean` | `true` | Show built-in header (ignored if `renderHeader` provided) |
| `showDefaultPalette` | `boolean` | `true` | Show built-in node palette |
| `enableGenerator` | `boolean` | `true` | Show the AI flow generator button |
| `renderHeader` | `(props: HeaderRenderProps) => ReactNode` | — | Custom header renderer |
| `renderNodePalette` | `(props: PaletteRenderProps) => ReactNode` | — | Custom node palette renderer |
### Imperative Methods (via `ref`)
| Method | Return Type | Description |
|--------|-------------|-------------|
| `getFlow()` | `FlowData` | Get current flow data |
| `toJSON()` | `string` | Export flow as JSON string |
| `validate()` | `ValidationResult` | Validate the current flow |
| `fitView()` | `void` | Fit all nodes into view |
| `clear()` | `void` | Remove all nodes and edges |
| `addNode(name)` | `void` | Add a node by component name |
### Design Note
`<Agentflow>` is an **uncontrolled component**. The `initialFlow` prop seeds the canvas state on mount, but the component owns its own state afterward. Use the `ref` for imperative access and `onFlowChange` to observe changes.
## Development
```bash
+6 -5
View File
@@ -36,10 +36,10 @@ The examples app uses environment variables for configuration. To set up:
cp .env.example .env
```
2. Edit `.env` to configure your Flowise instance:
2. Edit `.env` to configure your Flowise API server:
```bash
# Flowise Instance Configuration
# Flowise API Base URL
VITE_INSTANCE_URL=http://localhost:3000
# API Key (required for authenticated endpoints)
@@ -62,7 +62,7 @@ The examples app uses environment variables for configuration. To set up:
**Environment Variables:**
- `VITE_INSTANCE_URL`: Base URL of your Flowise instance (default: `http://localhost:3000`)
- `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)
**Note**: The `.env` file is gitignored and will not be committed to version control. Add your actual API key to `.env`, not `.env.example`.
@@ -94,11 +94,12 @@ Common causes:
## Examples
### Basic Usage (`App.tsx`)
### Basic Usage (`BasicExample.tsx`)
The default export shows:
Demonstrates core usage:
- 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
+5 -5
View File
@@ -6,7 +6,7 @@
import { type ComponentType, lazy, Suspense, useState } from 'react'
import { instanceUrl, token } from './config'
import { apiBaseUrl, token } from './config'
import {
AllNodeTypesExampleProps,
BasicExampleProps,
@@ -108,8 +108,8 @@ export default function App() {
const actualProps = currentExample?.props
? Object.fromEntries(
Object.entries(currentExample.props).map(([key, value]) => {
if (key === 'instanceUrl' && typeof value === 'string' && value.includes('environment variables')) {
return [key, instanceUrl]
if (key === 'apiBaseUrl' && typeof value === 'string' && value.includes('environment variables')) {
return [key, apiBaseUrl]
}
if (key === 'token' && typeof value === 'string' && value.includes('environment variables')) {
return [key, token ? `${token.substring(0, 20)}...` : 'undefined']
@@ -163,9 +163,9 @@ export default function App() {
</select>
{currentExample && <span style={{ color: '#666', fontSize: '13px' }}>{currentExample.description}</span>}
{/* Instance URL Display */}
{/* API Base URL Display */}
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: '12px' }}>
<span style={{ fontSize: '12px', color: '#999' }}>{instanceUrl}</span>
<span style={{ fontSize: '12px', color: '#999' }}>{apiBaseUrl}</span>
</div>
</div>
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Application configuration from environment variables
*/
export const instanceUrl = import.meta.env.VITE_INSTANCE_URL || 'http://localhost:3000'
export const apiBaseUrl = import.meta.env.VITE_INSTANCE_URL || 'http://localhost:3000'
export const token = import.meta.env.VITE_API_TOKEN || undefined
@@ -10,7 +10,7 @@ import { useRef } from 'react'
import type { AgentFlowInstance, FlowData } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
// Showcase all node types in a grid layout
const allNodesFlow: FlowData = {
@@ -238,9 +238,9 @@ export function AllNodeTypesExample() {
<div style={{ flex: 1 }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={allNodesFlow}
initialFlow={allNodesFlow}
showDefaultHeader={false}
readOnly={true}
/>
@@ -250,9 +250,9 @@ export function AllNodeTypesExample() {
}
export const AllNodeTypesExampleProps = {
instanceUrl: instanceUrl,
apiBaseUrl: apiBaseUrl,
token: token,
flow: 'FlowData (15 node types)',
initialFlow: 'FlowData (15 node types)',
readOnly: true,
showDefaultHeader: false,
enableGenerator: false
@@ -9,7 +9,7 @@ import { useRef, useState } from 'react'
import type { AgentFlowInstance, FlowData, ValidationResult } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
// Example flow data
const initialFlow: FlowData = {
@@ -102,9 +102,9 @@ export function BasicExample() {
<div style={{ flex: 1 }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={initialFlow}
initialFlow={initialFlow}
onFlowChange={handleFlowChange}
onSave={handleSave}
showDefaultHeader={true}
@@ -115,9 +115,9 @@ export function BasicExample() {
}
export const BasicExampleProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData',
initialFlow: 'FlowData',
onFlowChange: '(flow: FlowData) => void',
onSave: '(flow: FlowData) => void',
showDefaultHeader: true
@@ -10,7 +10,7 @@ import { useRef, useState } from 'react'
import type { AgentFlowInstance, FlowData, HeaderRenderProps, PaletteRenderProps } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
const initialFlow: FlowData = {
nodes: [
@@ -256,9 +256,9 @@ export function CustomUIExample() {
<div style={{ width: '100%', height: '100vh' }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={initialFlow}
initialFlow={initialFlow}
renderHeader={(props) => <CustomHeader {...props} />}
renderNodePalette={(props) => <CustomPalette {...props} />}
showDefaultHeader={false}
@@ -273,9 +273,9 @@ export function CustomUIExample() {
}
export const CustomUIExampleProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData',
initialFlow: 'FlowData',
renderHeader: '(props: HeaderRenderProps) => ReactNode',
renderNodePalette: '(props: PaletteRenderProps) => ReactNode',
showDefaultHeader: false,
@@ -12,7 +12,7 @@ import { Agentflow } from '@flowise/agentflow'
import CssBaseline from '@mui/material/CssBaseline'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
const sampleFlow: FlowData = {
nodes: [
@@ -137,9 +137,9 @@ export function DarkModeExample() {
<div style={{ flex: 1 }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={sampleFlow}
initialFlow={sampleFlow}
theme={isDark ? 'dark' : 'light'}
showDefaultHeader={false}
/>
@@ -150,9 +150,9 @@ export function DarkModeExample() {
}
export const DarkModeExampleProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData (sample flow)',
initialFlow: 'FlowData (sample flow)',
theme: '{isDark ? "dark" : "light"}',
showDefaultHeader: false
}
@@ -10,7 +10,7 @@ import { useRef, useState } from 'react'
import type { AgentFlowInstance, FlowData } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
const initialFlow: FlowData = {
nodes: [
@@ -142,9 +142,9 @@ export function FilteredComponentsExample() {
<div style={{ flex: 1 }} key={key}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={initialFlow}
initialFlow={initialFlow}
components={currentPreset.components}
showDefaultHeader={false}
/>
@@ -154,9 +154,9 @@ export function FilteredComponentsExample() {
}
export const FilteredComponentsExampleProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData',
initialFlow: 'FlowData',
components: 'string[] (preset-based)',
showDefaultHeader: false
}
@@ -10,7 +10,7 @@ import { useRef } from 'react'
import type { AgentFlowInstance, FlowData } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
// A complete translation agent flow
const translationFlow: FlowData = {
@@ -152,9 +152,9 @@ export function MultiNodeFlow() {
<div style={{ width: '100%', height: '100vh' }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={translationFlow}
initialFlow={translationFlow}
showDefaultHeader={true}
onFlowChange={(flow) => console.log('Flow changed:', flow.nodes.length, 'nodes')}
/>
@@ -163,9 +163,9 @@ export function MultiNodeFlow() {
}
export const MultiNodeFlowProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData (multiple nodes)',
initialFlow: 'FlowData (multiple nodes)',
showDefaultHeader: true,
onFlowChange: '(flow: FlowData) => void'
}
@@ -13,7 +13,7 @@ import { useRef, useState } from 'react'
import type { AgentFlowInstance, FlowData, FlowNode } from '@flowise/agentflow'
import { Agentflow } from '@flowise/agentflow'
import { instanceUrl, token } from '../config'
import { apiBaseUrl, token } from '../config'
const createFlowWithStatuses = (): FlowData => ({
nodes: [
@@ -237,9 +237,9 @@ export function StatusIndicatorsExample() {
<div style={{ flex: 1 }}>
<Agentflow
ref={agentflowRef}
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token ?? undefined}
flow={flow}
initialFlow={flow}
showDefaultHeader={false}
readOnly={true}
/>
@@ -249,9 +249,9 @@ export function StatusIndicatorsExample() {
}
export const StatusIndicatorsExampleProps = {
instanceUrl: '{from environment variables}',
apiBaseUrl: '{from environment variables}',
token: '{from environment variables}',
flow: 'FlowData (status indicators)',
initialFlow: 'FlowData (status indicators)',
showDefaultHeader: false,
readOnly: true
}
+2 -2
View File
@@ -27,8 +27,8 @@
"dev:example": "vite --config examples/vite.config.ts",
"format": "prettier --write \"{src,examples}/**/*.{ts,tsx,js,jsx,json,css,md}\"",
"format:check": "prettier --check \"{src,examples}/**/*.{ts,tsx,js,jsx,json,css,md}\"",
"lint": "eslint \"{src,examples/src}/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "eslint \"{src,examples/src}/**/*.{js,jsx,ts,tsx}\" --fix",
"lint": "eslint \"{src,examples/src}/**/*.{js,jsx,ts,tsx,json,md}\"",
"lint:fix": "eslint \"{src,examples/src}/**/*.{js,jsx,ts,tsx,json,md}\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
+6 -6
View File
@@ -203,7 +203,7 @@ function AgentflowCanvas({
* function App() {
* return (
* <Agentflow
* instanceUrl="https://flowise-url.com"
* apiBaseUrl="https://flowise-url.com"
* token="your-auth-token"
* components={['agentAgentflow', 'llmAgentflow']}
* />
@@ -213,9 +213,9 @@ function AgentflowCanvas({
*/
export const Agentflow = forwardRef<AgentFlowInstance, AgentflowProps>(function Agentflow(props, ref) {
const {
instanceUrl,
apiBaseUrl,
token,
flow,
initialFlow,
components,
onFlowChange,
onSave,
@@ -231,17 +231,17 @@ export const Agentflow = forwardRef<AgentFlowInstance, AgentflowProps>(function
return (
<AgentflowProvider
instanceUrl={instanceUrl}
apiBaseUrl={apiBaseUrl}
token={token}
theme={theme}
components={components}
readOnly={readOnly}
initialFlow={flow}
initialFlow={initialFlow}
>
<ReactFlowProvider>
<AgentflowCanvasWithRef
ref={ref}
initialFlow={flow}
initialFlow={initialFlow}
readOnly={readOnly}
onFlowChange={onFlowChange}
onSave={onSave}
+4 -4
View File
@@ -5,8 +5,8 @@ import type { FlowData } from './core/types'
import { AgentflowStateProvider, ApiProvider, ConfigProvider } from './infrastructure/store'
interface AgentflowProviderProps {
/** Base URL of the Flowise server */
instanceUrl: string
/** Flowise API server endpoint */
apiBaseUrl: string
/** Authentication token for API calls */
token?: string
/** Theme override */
@@ -26,7 +26,7 @@ interface AgentflowProviderProps {
* Sets up all required contexts for API access, configuration, and state management.
*/
export function AgentflowProvider({
instanceUrl,
apiBaseUrl,
token,
theme = 'system',
components,
@@ -36,7 +36,7 @@ export function AgentflowProvider({
}: AgentflowProviderProps) {
return (
<ReactFlowProvider>
<ApiProvider instanceUrl={instanceUrl} token={token}>
<ApiProvider apiBaseUrl={apiBaseUrl} token={token}>
<ConfigProvider theme={theme} components={components} readOnly={readOnly}>
<AgentflowStateProvider initialFlow={initialFlow}>{children}</AgentflowStateProvider>
</ConfigProvider>
+4 -4
View File
@@ -174,14 +174,14 @@ export interface PaletteRenderProps {
// ============================================================================
export interface AgentflowProps {
/** Base URL of the Flowise server (e.g., "https://flowise-url.com") */
instanceUrl: string
/** Flowise API server endpoint (e.g., "https://flowise-url.com") */
apiBaseUrl: string
/** Authentication token for API calls */
token?: string
/** Initial flow data to render */
flow?: FlowData
initialFlow?: FlowData
/** Flow ID for loading existing flow */
flowId?: string
@@ -253,7 +253,7 @@ export interface AgentFlowInstance {
export interface ApiContextValue {
client: AxiosInstance
instanceUrl: string
apiBaseUrl: string
}
export interface ConfigContextValue {
@@ -5,10 +5,10 @@ import { renderNodeIcon } from '../nodeIcons'
export interface NodeIconProps {
data: NodeData
instanceUrl: string
apiBaseUrl: string
}
function NodeIconComponent({ data, instanceUrl }: NodeIconProps) {
function NodeIconComponent({ data, apiBaseUrl }: NodeIconProps) {
if (data.color && !data.icon) {
return (
<div
@@ -41,7 +41,7 @@ function NodeIconComponent({ data, instanceUrl }: NodeIconProps) {
>
<img
style={{ width: '100%', height: '100%', padding: 5, objectFit: 'contain' }}
src={`${instanceUrl}/api/v1/node-icon/${data.name}`}
src={`${apiBaseUrl}/api/v1/node-icon/${data.name}`}
alt={data.name}
/>
</div>
@@ -17,7 +17,7 @@ export interface NodeModelConfigsProps {
* Displays model configuration badges on a node
*/
function NodeModelConfigsComponent({ inputs }: NodeModelConfigsProps) {
const { instanceUrl } = useApiContext()
const { apiBaseUrl } = useApiContext()
const { isDarkMode } = useConfigContext()
if (!inputs) return null
@@ -51,7 +51,7 @@ function NodeModelConfigsComponent({ inputs }: NodeModelConfigsProps) {
>
<img
style={{ width: 20, height: 20, objectFit: 'contain' }}
src={`${instanceUrl}/api/v1/node-icon/${item.model}`}
src={`${apiBaseUrl}/api/v1/node-icon/${item.model}`}
alt={item.model as string}
/>
<Typography sx={{ fontSize: '0.7rem', ml: 0.5 }}>{item.config?.modelName || item.config?.model}</Typography>
@@ -24,7 +24,7 @@ export interface AgentFlowNodeProps {
*/
function AgentFlowNodeComponent({ data }: AgentFlowNodeProps) {
const { isDarkMode } = useConfigContext()
const { instanceUrl } = useApiContext()
const { apiBaseUrl } = useApiContext()
const ref = useRef<HTMLDivElement>(null)
const updateNodeInternals = useUpdateNodeInternals()
@@ -99,7 +99,7 @@ function AgentFlowNodeComponent({ data }: AgentFlowNodeProps) {
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
<Box style={{ padding: 10 }}>
<NodeIcon data={data} instanceUrl={instanceUrl} />
<NodeIcon data={data} apiBaseUrl={apiBaseUrl} />
</Box>
<Box>
<Typography
@@ -25,7 +25,7 @@ export interface IterationNodeProps {
function IterationNodeComponent({ data }: IterationNodeProps) {
const theme = useTheme()
const { isDarkMode } = useConfigContext()
const { instanceUrl } = useApiContext()
const { apiBaseUrl } = useApiContext()
const { state } = useAgentflowContext()
const ref = useRef<HTMLDivElement>(null)
const reactFlowWrapper = useRef<HTMLDivElement>(null)
@@ -83,7 +83,7 @@ function IterationNodeComponent({ data }: IterationNodeProps) {
<div ref={ref} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
<NodeToolbar align='start' isVisible={true}>
<Box style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
<NodeIcon data={data} instanceUrl={instanceUrl} />
<NodeIcon data={data} apiBaseUrl={apiBaseUrl} />
<Typography
sx={{
fontSize: '0.85rem',
@@ -44,7 +44,7 @@ interface ChatModel {
*/
function GenerateFlowDialogComponent({ open, onClose, onGenerated }: GenerateFlowDialogProps) {
const theme = useTheme()
const { chatflowsApi, instanceUrl } = useApiContext()
const { chatflowsApi, apiBaseUrl } = useApiContext()
const { isDarkMode: _isDarkMode } = useConfigContext()
const [prompt, setPrompt] = useState('')
@@ -235,7 +235,7 @@ function GenerateFlowDialogComponent({ open, onClose, onGenerated }: GenerateFlo
<MenuItem key={model.name} value={model.name}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<img
src={`${instanceUrl}/api/v1/node-icon/${model.name}`}
src={`${apiBaseUrl}/api/v1/node-icon/${model.name}`}
alt={model.label}
style={{ width: 24, height: 24, borderRadius: '50%' }}
onError={(e) => {
@@ -47,7 +47,7 @@ export interface AddNodesDrawerProps {
*/
function AddNodesDrawerComponent({ nodes, onDragStart, onNodeClick }: AddNodesDrawerProps) {
const theme = useTheme()
const { instanceUrl } = useApiContext()
const { apiBaseUrl } = useApiContext()
const { isDarkMode: _isDarkMode } = useConfigContext()
const [searchValue, setSearchValue] = useState('')
@@ -331,7 +331,7 @@ function AddNodesDrawerComponent({ nodes, onDragStart, onNodeClick }: AddNodesDr
objectFit: 'contain'
}}
alt={node.name}
src={`${instanceUrl}/api/v1/node-icon/${node.name}`}
src={`${apiBaseUrl}/api/v1/node-icon/${node.name}`}
/>
</div>
</ListItemAvatar>
@@ -2,10 +2,10 @@ import axios, { AxiosInstance } from 'axios'
/**
* Creates a configured axios client for API calls
* @param instanceUrl - Base URL of the Flowise server
* @param apiBaseUrl - Base URL of the Flowise server
* @param token - Authentication token (optional)
*/
export function createApiClient(instanceUrl: string, token?: string): AxiosInstance {
export function createApiClient(apiBaseUrl: string, token?: string): AxiosInstance {
const headers: Record<string, string> = {
'Content-Type': 'application/json'
}
@@ -15,7 +15,7 @@ export function createApiClient(instanceUrl: string, token?: string): AxiosInsta
}
const client = axios.create({
baseURL: `${instanceUrl}/api/v1`,
baseURL: `${apiBaseUrl}/api/v1`,
headers
})
@@ -6,7 +6,7 @@ import { type ChatflowsApi, createApiClient, createChatflowsApi, createNodesApi,
interface ApiContextValue {
client: AxiosInstance
instanceUrl: string
apiBaseUrl: string
nodesApi: NodesApi
chatflowsApi: ChatflowsApi
}
@@ -14,24 +14,24 @@ interface ApiContextValue {
const ApiContext = createContext<ApiContextValue | null>(null)
interface ApiProviderProps {
instanceUrl: string
apiBaseUrl: string
token?: string
children: ReactNode
}
export function ApiProvider({ instanceUrl, token, children }: ApiProviderProps) {
export function ApiProvider({ apiBaseUrl, token, children }: ApiProviderProps) {
const value = useMemo(() => {
const client = createApiClient(instanceUrl, token)
const client = createApiClient(apiBaseUrl, token)
const nodesApi = createNodesApi(client)
const chatflowsApi = createChatflowsApi(client)
return {
client,
instanceUrl,
apiBaseUrl,
nodesApi,
chatflowsApi
}
}, [instanceUrl, token])
}, [apiBaseUrl, token])
return <ApiContext.Provider value={value}>{children}</ApiContext.Provider>
}