Skip to content

Commit 904e31c

Browse files
authored
Merge branch 'main' into chore/Langchain-V1
2 parents 3f4a6b4 + 840d2ae commit 904e31c

26 files changed

Lines changed: 521 additions & 366 deletions

File tree

.github/workflows/docker-image-dockerhub.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ jobs:
2727
echo "tag_version=${{ github.event.inputs.tag_version || 'latest' }}" >> $GITHUB_OUTPUT
2828
2929
- name: Checkout
30-
uses: actions/checkout@v4.1.1
30+
uses: actions/checkout@v6.0.2
3131

3232
- name: Set up QEMU
33-
uses: docker/setup-qemu-action@v3.0.0
33+
uses: docker/setup-qemu-action@v4.0.0
3434

3535
- name: Set up Docker Buildx
36-
uses: docker/setup-buildx-action@v3.0.0
36+
uses: docker/setup-buildx-action@v4.0.0
3737

3838
- name: Login to Docker Hub
39-
uses: docker/login-action@v3
39+
uses: docker/login-action@v4
4040
with:
4141
username: ${{ secrets.DOCKERHUB_USERNAME }}
4242
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -45,7 +45,7 @@ jobs:
4545
# Build and push main image
4646
# -------------------------
4747
- name: Build and push main image
48-
uses: docker/build-push-action@v5.3.0
48+
uses: docker/build-push-action@v6.19.2
4949
with:
5050
context: .
5151
file: ./docker/Dockerfile
@@ -60,7 +60,7 @@ jobs:
6060
# Build and push worker image
6161
# -------------------------
6262
- name: Build and push worker image
63-
uses: docker/build-push-action@v5.3.0
63+
uses: docker/build-push-action@v6.19.2
6464
with:
6565
context: .
6666
file: docker/worker/Dockerfile

.github/workflows/docker-image-ecr.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ jobs:
4040
echo "tag_version=${{ github.event.inputs.tag_version || 'latest' }}" >> $GITHUB_OUTPUT
4141
4242
- name: Checkout
43-
uses: actions/checkout@v4.1.1
43+
uses: actions/checkout@v6.0.2
4444

4545
- name: Set up QEMU
46-
uses: docker/setup-qemu-action@v3.0.0
46+
uses: docker/setup-qemu-action@v4.0.0
4747

4848
- name: Set up Docker Buildx
49-
uses: docker/setup-buildx-action@v3.0.0
49+
uses: docker/setup-buildx-action@v4.0.0
5050

5151
- name: Configure AWS Credentials
5252
if: ${{ inputs.environment != 'prod' }}
53-
uses: aws-actions/configure-aws-credentials@v3
53+
uses: aws-actions/configure-aws-credentials@v6
5454
with:
5555
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
5656
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -66,13 +66,13 @@ jobs:
6666
unset-current-credentials: true
6767

6868
- name: Login to Amazon ECR
69-
uses: aws-actions/amazon-ecr-login@v1
69+
uses: aws-actions/amazon-ecr-login@v2
7070

7171
# -------------------------
7272
# Build and push main image
7373
# -------------------------
7474
- name: Build and push main image
75-
uses: docker/build-push-action@v5.3.0
75+
uses: docker/build-push-action@v6.19.2
7676
with:
7777
context: .
7878
file: Dockerfile

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ jobs:
1919
env:
2020
PUPPETEER_SKIP_DOWNLOAD: true
2121
steps:
22-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@v6
2323
- uses: pnpm/action-setup@v4
2424
with:
2525
version: 10.26.0
2626
- name: Use Node.js ${{ matrix.node-version }}
27-
uses: actions/setup-node@v4
27+
uses: actions/setup-node@v6
2828
with:
2929
node-version: ${{ matrix.node-version }}
3030
cache: 'pnpm'
@@ -38,12 +38,12 @@ jobs:
3838
- name: Cypress install
3939
run: pnpm cypress install
4040
- name: Install dependencies (Cypress Action)
41-
uses: cypress-io/github-action@v6
41+
uses: cypress-io/github-action@v7.1.5
4242
with:
4343
working-directory: ./
4444
runTests: false
4545
- name: Cypress test
46-
uses: cypress-io/github-action@v6
46+
uses: cypress-io/github-action@v7.1.5
4747
with:
4848
install: false
4949
working-directory: packages/server

.github/workflows/proprietary-path-guard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535

3636
steps:
3737
- name: Checkout repository
38-
uses: actions/checkout@v4
38+
uses: actions/checkout@v6
3939
with:
4040
fetch-depth: 0
4141

.github/workflows/test_docker_build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ jobs:
1515
env:
1616
PUPPETEER_SKIP_DOWNLOAD: true
1717
steps:
18-
- uses: actions/checkout@v4
18+
- uses: actions/checkout@v6
1919
- run: docker build --no-cache -t flowise .

packages/agentflow/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ export default function App() {
9898

9999
## Props
100100

101+
<!-- prettier-ignore -->
101102
| Prop | Type | Default | Description |
102103
| -------------------- | ------------------------------------------ | -------------- | --------------------------------------------------------------- |
103104
| `apiBaseUrl` | `string` | **(required)** | Flowise API server endpoint |
104105
| `token` | `string` || Authentication token for API calls |
106+
| `requestInterceptor` | `(config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig` || Customize outgoing API requests (e.g., set `withCredentials`, add headers). The callback receives the full Axios request config — only modify what you need. See [Security: requestInterceptor](#security-requestinterceptor) below. |
105107
| `initialFlow` | `FlowData` || Initial flow data to render (uncontrolled — only used on mount) |
106108
| `components` | `string[]` || Restrict which node types appear in the palette |
107109
| `onFlowChange` | `(flow: FlowData) => void` || Called when the flow changes (node/edge add, remove, move) |
@@ -127,6 +129,16 @@ export default function App() {
127129
| `addNode(nodeData)` | `void` | Add a node (`Partial<FlowNode>`) |
128130
| `getReactFlowInstance()` | `ReactFlowInstance\|null` | Get the underlying ReactFlow instance |
129131

132+
### Security: `requestInterceptor`
133+
134+
The `requestInterceptor` callback runs inside the Axios request pipeline and has access to the full request configuration, including authentication headers. This is the same trust model as any other callback prop (e.g., `onSave`, `renderHeader`) — the host application developer supplies the function and is responsible for its behavior.
135+
136+
**Guidelines for consumers:**
137+
138+
- Only pass **trusted, developer-authored** functions. Never use dynamically evaluated code (`eval`, `new Function`, etc.) or user-generated input as the interceptor.
139+
- Follow the **principle of least privilege** — only read or modify the specific config properties you need (e.g., `withCredentials`, custom headers).
140+
- If the interceptor throws, the error is caught, logged, and the **original unmodified config** is used so the request still proceeds safely.
141+
130142
### Design Note
131143

132144
`<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.

packages/agentflow/src/Agentflow.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ export const Agentflow = forwardRef<AgentFlowInstance, AgentflowProps>(function
322322
const {
323323
apiBaseUrl,
324324
token,
325+
requestInterceptor,
325326
initialFlow,
326327
components,
327328
onFlowChange,
@@ -340,6 +341,7 @@ export const Agentflow = forwardRef<AgentFlowInstance, AgentflowProps>(function
340341
<AgentflowProvider
341342
apiBaseUrl={apiBaseUrl}
342343
token={token}
344+
requestInterceptor={requestInterceptor}
343345
isDarkMode={isDarkMode}
344346
components={components}
345347
readOnly={readOnly}

packages/agentflow/src/AgentflowProvider.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import { ReactFlowProvider } from 'reactflow'
44
import { ThemeProvider } from '@mui/material/styles'
55

66
import { createAgentflowTheme, generateCSSVariables } from './core/theme'
7-
import type { FlowData } from './core/types'
7+
import type { FlowData, RequestInterceptor } from './core/types'
88
import { AgentflowStateProvider, ApiProvider, ConfigProvider } from './infrastructure/store'
99

1010
interface AgentflowProviderProps {
1111
/** Flowise API server endpoint */
1212
apiBaseUrl: string
1313
/** Authentication token for API calls */
1414
token?: string
15+
/**
16+
* Optional callback to customize outgoing API requests.
17+
* Has access to full request config including auth tokens — only pass trusted code.
18+
*/
19+
requestInterceptor?: RequestInterceptor
1520
/** Whether to use dark mode (default: false) */
1621
isDarkMode?: boolean
1722
/** Array of allowed node component names */
@@ -31,6 +36,7 @@ interface AgentflowProviderProps {
3136
export function AgentflowProvider({
3237
apiBaseUrl,
3338
token,
39+
requestInterceptor,
3440
isDarkMode = false,
3541
components,
3642
readOnly = false,
@@ -70,7 +76,7 @@ export function AgentflowProvider({
7076
return (
7177
<ReactFlowProvider>
7278
<ThemeProvider theme={theme}>
73-
<ApiProvider apiBaseUrl={apiBaseUrl} token={token}>
79+
<ApiProvider apiBaseUrl={apiBaseUrl} token={token} requestInterceptor={requestInterceptor}>
7480
<ConfigProvider isDarkMode={isDarkMode} components={components} readOnly={readOnly}>
7581
<AgentflowStateProvider initialFlow={initialFlow}>{children}</AgentflowStateProvider>
7682
</ConfigProvider>

packages/agentflow/src/core/theme/tokens.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ export const tokens = {
9797

9898
border: {
9999
default: { light: baseColors.gray300, dark: baseColors.darkGray500 },
100-
hover: { light: baseColors.gray400, dark: baseColors.darkGray600 }
100+
hover: { light: baseColors.gray400, dark: baseColors.darkGray600 },
101+
validation: baseColors.nodeCondition
101102
},
102103

103104
text: {
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// ============================================================================
2+
// Component Props & Hook Return Types
3+
// ============================================================================
4+
5+
import type { ReactNode } from 'react'
6+
import type { ReactFlowInstance } from 'reactflow'
7+
8+
import type { RequestInterceptor } from './api'
9+
import type { FlowData, FlowDataCallback, FlowNode } from './flow'
10+
import type { NodeData } from './node'
11+
import type { ValidationResult } from './validation'
12+
13+
// ============================================================================
14+
// Render Props Types
15+
// ============================================================================
16+
17+
export interface HeaderRenderProps {
18+
flowName: string
19+
isDirty: boolean
20+
onSave: () => void
21+
onExport: () => void
22+
onValidate: () => ValidationResult
23+
}
24+
25+
export interface PaletteRenderProps {
26+
availableNodes: NodeData[]
27+
onAddNode: (nodeType: string, position?: { x: number; y: number }) => void
28+
}
29+
30+
// ============================================================================
31+
// Component Props & Hook Return Types
32+
// ============================================================================
33+
34+
export interface AgentflowProps {
35+
/** Flowise API server endpoint (e.g., "https://flowise-url.com") */
36+
apiBaseUrl: string
37+
38+
/** Authentication token for API calls */
39+
token?: string
40+
41+
/** Initial flow data to render */
42+
initialFlow?: FlowData
43+
44+
/** Flow ID for loading existing flow */
45+
flowId?: string
46+
47+
/** Array of allowed node component names to show in palette */
48+
components?: string[]
49+
50+
/** Callback when flow changes */
51+
onFlowChange?: FlowDataCallback
52+
53+
/** Callback when flow is saved */
54+
onSave?: FlowDataCallback
55+
56+
/** Whether to use dark mode (default: false) */
57+
isDarkMode?: boolean
58+
59+
/** Whether the canvas is read-only */
60+
readOnly?: boolean
61+
62+
/** Custom header renderer - receives save/export handlers */
63+
renderHeader?: (props: HeaderRenderProps) => ReactNode
64+
65+
/** Custom node palette renderer - receives available nodes */
66+
renderNodePalette?: (props: PaletteRenderProps) => ReactNode
67+
68+
/** Whether to show default header (ignored if renderHeader provided) */
69+
showDefaultHeader?: boolean
70+
71+
/** Whether to show default node palette (ignored if renderNodePalette provided) */
72+
showDefaultPalette?: boolean
73+
74+
/** Enable the AI flow generator feature (default: true) */
75+
enableGenerator?: boolean
76+
77+
/** Callback when flow is generated via AI */
78+
onFlowGenerated?: FlowDataCallback
79+
80+
/**
81+
* Optional callback to customize outgoing API requests (e.g., set `withCredentials`, add headers).
82+
* Receives the full Axios request config including auth headers — only modify what you need.
83+
*
84+
* **Security:** This callback executes in the request pipeline with access to all request
85+
* data, including authentication tokens. Only pass trusted, developer-authored functions.
86+
* Never use dynamically evaluated or user-generated code as the interceptor.
87+
* If the interceptor throws, the error is caught and the original config is used.
88+
*/
89+
requestInterceptor?: RequestInterceptor
90+
}
91+
92+
export interface AgentFlowInstance {
93+
/** Get current flow data as serializable object */
94+
getFlow(): FlowData
95+
96+
/** Convert flow to JSON string */
97+
toJSON(): string
98+
99+
/** Validate the current flow */
100+
validate(): ValidationResult
101+
102+
/** Fit view to show all nodes */
103+
fitView(): void
104+
105+
/** Get the underlying ReactFlow instance */
106+
getReactFlowInstance(): ReactFlowInstance | null
107+
108+
/** Programmatically add a node */
109+
addNode(nodeData: Partial<FlowNode>): void
110+
111+
/** Clear all nodes and edges */
112+
clear(): void
113+
}

0 commit comments

Comments
 (0)