Commit Graph

482 Commits

Author SHA1 Message Date
balibabu
999eb533a9 Feat: Adjust the color and size of the graph based on the data. (#16868) 2026-07-14 10:20:31 +08:00
euvre
3bfad1f00e fix: correct model type mappings and improve system setting persistence (#16501) 2026-07-13 16:42:55 +08:00
Lynn
b0cac0ac9d Fix: Align part of Go provider APIs with Python APIs (#16823) 2026-07-13 11:20:02 +08:00
chanx
ea9b3789ce fix(prompt-editor): prevent premature variable path merge during typing (#16811)
### Summary

fix(prompt-editor): prevent premature variable path merge during typing

---------

Co-authored-by: Jin Hai <haijin.chn@gmail.com>
2026-07-10 20:57:59 +08:00
chanx
868e524f29 fix: pass ownerTenantId to LLMLabel and related components for improved model fetching (#16800) 2026-07-10 13:27:14 +08:00
chanx
8236f2cabb Fix: update LayoutRecognizeFormField to accept ownerTenantId and refactor model handling in LLM requests (#16781) 2026-07-10 09:36:25 +08:00
balibabu
0083ad0deb Feat: Add a data compilation layer. (#16777)
### Summary

Feat: Add a data compilation layer.
2026-07-09 17:49:16 +08:00
chanx
a9420a7832 Fix: resolve shared embedding/LLM model selection errors (#16773) 2026-07-09 15:17:49 +08:00
balibabu
575984877f Fix: Rapid clicking results in multiple message requests being sent. (#16739) 2026-07-09 09:57:54 +08:00
Wang Qi
a0bda639e0 Fix Agent Chat not working (#16688)
Follow on this PR: #15484 it break the Agent chat
2026-07-07 12:10:52 +08:00
天海蒼灆
318045dda5 feat(agent): support JSON object input on begin node (#16685)
### Summary

Add object as a begin-node parameter type with JSON editor UI, webhook
schema support, and backend parsing in UserFillUp.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:40:57 +08:00
Hz_
863b35db7f fix(go-agent-web): correct BGPT canvas form watcher usage (#16682)
## Summary

Fixes a page crash when opening the BGPT node configuration in the
canvas.

## Root Cause

BGPT was using the tool-form watcher call pattern in a normal canvas
component form.

Tool forms use:

useWatchFormChange(form)

Canvas component forms use:

useWatchFormChange(node?.id, form)

Tool is not equal to component. The BGPT canvas component imported the
component-level hook but called it like a tool-form hook, so the form
argument became undefined and React Hook Form tried to read control from
a null context.

## Change

Updated the BGPT canvas form to pass the node id and form instance
correctly.

## Validation

Ran ESLint for the changed file:
npx eslint src/pages/agent/form/bgpt-form/index.tsx

<img width="1369" height="1184" alt="image"
src="https://github.com/user-attachments/assets/a40c5202-7394-4f26-9da2-08329dcc7fbf"
/>
2026-07-07 11:08:50 +08:00
balibabu
290ab557a5 Fix: Layout of the agent prompt dropdown menu is messed up. (#16653) 2026-07-06 14:48:42 +08:00
euvre
4effd057f0 i18n: localize visual input file label in agent form (#16594) 2026-07-03 15:31:27 +08:00
chanx
c44d56f1bb Fix: enhance reference handling in SessionChat component (#16571) 2026-07-02 17:48:48 +08:00
connerlambden
9bf57600cf feat(agent): add BGPT structured literature evidence search tool (#16050)
## Summary

Adds a first-class **BGPT** Agent tool (backend + UI) in response to
[#15997](https://github.com/infiniflow/ragflow/issues/15997#issuecomment-4703864227).

BGPT calls `POST https://bgpt.pro/api/mcp-search` and returns structured
study evidence from full-text papers — not just titles/abstracts. Each
result is formatted for RAGFlow citations with:

- methods
- sample size / population
- results
- limitations
- conflicts of interest
- data availability
- study blind spots
- `how_to_falsify`

## Why this shape

- Mirrors existing literature tools (`PubMed`, `ArXiv`) and HTTP tools
(`SearXNG`).
- Works on the free tier (no API key required for first 50 results).
- Optional `api_key` and `days_back` in the node/tool config.
- Surfaces both `formalized_content` and raw `json` outputs (like
SearXNG).

## Files

- `agent/tools/bgpt.py` — REST client + evidence formatter
- Frontend: Operator enum, forms, tool picker, canvas accordion, en/zh
locales, icon

## Demo / docs

Runnable claim-interrogation demo:
https://github.com/connerlambden/bgpt-mcp/blob/main/EVIDENCE_DEMO.md

## Test plan

- [ ] Add BGPT node on Agent canvas, run query `GLP-1 alcohol craving`,
verify `formalized_content` includes limitations/COI fields
- [ ] Add BGPT as Agent sub-tool under Search, verify tool-calling works
- [ ] Confirm empty query / try-run returns gracefully
- [ ] Optional: paid-tier `api_key` path

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Zhichang Yu <yuzhichang@gmail.com>
2026-07-01 13:52:24 +08:00
Rene Arredondo
dc8b6d767c fix(agent): inject uploaded attachments into LLM context (#15215) (#15220)
## Summary

Fixes #15215 — attachments uploaded to an agent were not reaching the
LLM.

When a user uploads a file in an agent chat, `canvas.run` parses it into
the `sys.files` global (text content for documents, `data:image/...`
URIs
for images — see `agent/canvas.py:752-768`). But the LLM/Agent
component's
`_prepare_prompt_variables` only substitutes variables the user's prompt
template explicitly references via `{var}` placeholders. The default
prompt is `[{"role": "user", "content": "{sys.query}"}]` with no
`{sys.files}`, so the parsed attachment content never reaches the model.

In the reporter's logs, this is why the agent saw only the bare query
`附件 摘要 attachment summary` and went searching the dataset instead of
reading the uploaded PDF.

## Fix

`agent/component/llm.py` — added `_collect_sys_files()` and an
auto-injection step in `_prepare_prompt_variables`:

- If `sys.files` is non-empty **and** neither `sys_prompt` nor any entry
  in `prompts` already contains `{sys.files}` (no double-injection),
  split the entries into text vs. `data:image/...` URIs.
- Image URIs are merged into `self.imgs`, which the existing logic uses
  to switch the chat model to `IMAGE2TEXT` and pass `images=...` to
  `async_chat`.
- Text content is appended to the last `user` role message in `msg`,
  mirroring how `dialog_service.async_chat_solo` handles attachments for
  the non-agent chat path (`api/db/services/dialog_service.py:318-321`).

Both `LLM._invoke_async` and `Agent._invoke_async` (tool-using) go
through `_prepare_prompt_variables`, so plain LLM nodes and Agent nodes
are fixed in both streaming and non-streaming paths.

## Test plan

- [ ] Upload a PDF attachment to an agent with the default `{sys.query}`
prompt and ask "summarize the attachment" — the model should answer
      from the file content rather than searching the knowledge base.
- [ ] Upload an image attachment to an agent and ask about its contents
—
      the model should switch to the vision-capable LLM and answer from
      the image.
- [ ] Verify that an agent whose prompt **does** include `{sys.files}`
      still works and does **not** include the file content twice.
- [ ] Verify that an agent run with no attachments behaves unchanged.
- [ ] Run `uv run pytest` to make sure no existing tests regress.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [ ] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):

---------

Co-authored-by: yzc <yuzhichang@gmail.com>
2026-06-30 15:48:59 +08:00
vincimirror
9f6f0c5582 Fix: clean up iteration child nodes and edges on delete (#13889) (#14033)
### What problem does this PR solve?

Fixes a workflow editor bug where deleting an Iteration Box could leave
orphan child nodes and dangling edges in client state. Those stale
references could be exported with the workflow and later cause rendering
errors, broken connections, and unstable editing behavior.

### Root Cause

Iteration deletion logic only removed the container, its direct
children, and some internal edges. It did not consistently remove the
full descendant subtree or all edges connected to deleted child nodes,
and the keyboard delete path was not expanded to include Iteration
descendants.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [ ] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):

---------

Co-authored-by: Zhichang Yu <yuzhichang@gmail.com>
2026-06-29 09:45:17 +08:00
Tim Wang
f0f10b6092 Fix: UserFillUp interactive forms not working in agent explore mode (#14589)
## Summary

- **Backend**: `_iter_session_completion_events` in `agent_api.py` was
filtering out `user_inputs` and `workflow_finished` SSE events, causing
agents with UserFillUp components to silently fail in explore mode — the
interactive form never appeared, while the same agent worked correctly
in run (editor) mode.
- **Frontend**: `SessionChat` component in explore mode was missing
`DebugContent` children rendering inside `MessageItem`, so even if the
backend forwarded the events, the form UI would not render. Added
`DebugContent`, `MarkdownContent`, `useAwaitCompentData` hook, and
input-disabling logic to match the run mode's `chat/box.tsx` behavior.

## What was changed

### Backend (`api/apps/restful_apis/agent_api.py`)
- Line 266: Added `"user_inputs"` and `"workflow_finished"` to the
allowed event filter in `_iter_session_completion_events`

### Frontend (`web/src/pages/agent/explore/components/session-chat.tsx`)
- Added imports: `DebugContent`, `MarkdownContent`,
`useAwaitCompentData`, `useParams`
- Added `sendFormMessage` from `useSendSessionMessage()` hook
- Added `useAwaitCompentData` hook for form state management
- Added `DebugContent` as `MessageItem` children for the latest
assistant message (renders UserFillUp form)
- Added `MarkdownContent` + submitted values display for previous
assistant messages
- Updated `NextMessageInput` disabled states to respect `isWaitting`
(form submission in progress)

## Test plan

- [x] Agent with UserFillUp component (e.g., email draft with
send/edit/cancel options) shows interactive form in **explore mode**
- [x] Same agent continues to work correctly in **run (editor) mode**
- [x] Form submission sends data back to the agent and workflow
continues
- [x] Input field is disabled while waiting for form submission
- [ ] Agents without UserFillUp components are unaffected in explore
mode

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Zhichang Yu <yuzhichang@gmail.com>
2026-06-29 09:45:17 +08:00
Renzo
6079ded70b fix: require explicit anonymous webhook access (#14890)
### What problem does this PR solve?

Fixes #14882

Agent webhook execution currently fails open when the saved webhook
`security` block is missing/empty, or when `auth_type` is set to `none`.
This allows unauthenticated webhook invocation without an explicit
operator opt-in.

This PR makes anonymous webhook access explicit:
- Rejects missing or empty webhook security config.
- Requires `allow_anonymous: true` when `auth_type` is `none`.
- Preserves explicit anonymous webhooks by having the frontend serialize
`allow_anonymous: true` when the user selects `None` auth.
- Updates webhook unit tests to cover both denied implicit-anonymous
configs and allowed explicit-anonymous configs.

### Type of change

- [x] Bug Fix
- [x] Security hardening
- [x] Test

### Tests

- [x] `ZHIPU_AI_API_KEY=dummy uv run python -m pytest
--confcutdir=test/testcases/test_web_api/test_agent_app
test/testcases/test_web_api/test_agent_app/test_agents_webhook_unit.py`
- [x] `uv run ruff check api/apps/restful_apis/agent_api.py
test/testcases/test_web_api/test_agent_app/test_agents_webhook_unit.py`
- [x] `npm exec eslint src/pages/agent/utils.ts
src/pages/agent/form/begin-form/schema.ts`

---------

Co-authored-by: Zhichang Yu <yuzhichang@gmail.com>
2026-06-29 09:45:16 +08:00
Rene Arredondo
7ecc0908ef fix(agent): authenticate "Thinking" button in shared/embedded chat via beta token (#14985) (#15238)
## Summary

Fixes #14985 — clicking the **Thinking** button in a shared/embedded
chat returns 401 and bounces the user to the login page, even though
the same share page can chat with the agent just fine.

## Root cause

In shared chat, `useGetSharedChatSearchParams` binds `conversationId`
to the URL's `shared_id` query param — which is the **beta APIToken**,
not the real agent id. That `conversationId` propagates through the
component tree:

```tsx
<WorkFlowTimeline canvasId={conversationId}>
  → useFetchMessageTrace(canvasId)
  → GET /api/v1/agents/<sharedId>/logs/<messageId>
```

But `/agents/<agent_id>/logs/<message_id>` is decorated with
`@login_required` (`api/apps/restful_apis/agent_api.py:842-846`).
The share page only holds the beta token — there is no session JWT
— so the request 401s and quart-auth redirects to the login page.
The reporter's server log matches exactly:

```
load_user from jwt got exception No b'.' found in value
load_user: No APIToken found for token=ULG10SWG3E...
Unauthorized request (quart_auth)
GET /api/v1/agents/394013f8d42211f0bad6123fa55e8ed9/logs/96fd72e2-... 1.1 401
```

The `394013f8...` segment in the URL is the `shared_id` (beta
token), not an actual agent id. `_load_user` already accepts the
regular `APIToken.token` field, but not `APIToken.beta`, by design
— beta is a much weaker share-link credential than a personal API
key.

The sibling endpoints `/agentbots/<id>/completions` and
`/agentbots/<id>/inputs` already use the right auth pattern for
this scope (beta-token via `_get_sdk_authorization_token` →
`APIToken.query(beta=token)`). Trace just didn't have a parallel.

## Fix

### Backend (`api/apps/restful_apis/bot_api.py`)

Added a beta-token sibling endpoint:

```
GET /api/v1/agentbots/<shared_id>/logs/<message_id>
```

- Same auth shape as the existing `agentbots` endpoints.
- The `<shared_id>` path segment is a client-supplied label only.
  The real `agent_id` used to build the Redis key
  (`<agent_id>-<message_id>-logs`) is taken from
  `APIToken.dialog_id` on the looked-up token, so the endpoint
  never trusts client-supplied identifiers for the data lookup.
- Returns the same `{data: ...}` shape as the existing
  `/agents/<id>/logs/<message_id>` endpoint, so the frontend
  doesn't need to reshape the response.

### Frontend

- `web/src/utils/api.ts`: added `sharedTrace(sharedId, messageId)`
  URL builder.
- `web/src/services/agent-service.ts`: added
  `fetchSharedTrace({ shared_id, message_id })`.
- `web/src/hooks/use-agent-request.ts`: `useFetchMessageTrace`
  takes an optional `isShare` argument. When set, it calls
  `fetchSharedTrace`; `isShare` is also folded into the
  `queryKey` so the two modes never share cached results.
- `web/src/pages/agent/log-sheet/workflow-timeline.tsx`:
  forwards the already-existing `isShare` prop into the hook.

All other existing call sites of `useFetchMessageTrace` (webhook
timeline, pipeline log, dataflow result) pass no `isShare`
argument → undefined → falsy → unchanged behavior.

## Test plan

- [ ] In the regular Agent UI (logged-in user): open the trace /
      log sheet for any message and click into "Thinking" — the
      timeline should still load via `/agents/<id>/logs/<msg>`,
      same as before.
- [ ] From the Agent page, click **Chat in new tab** to open
      `/chat/share?shared_id=<token>&from=agent`. Send a message,
      wait for a response, then click **Thinking** on the
      assistant turn. The trace panel should load instead of
      redirecting to the login page.
- [ ] Same flow but with the agent embedded in an iframe ("Embed
      into webpage") — confirm there is no login redirect.
- [ ] In DevTools → Network, confirm the share-chat trace request
      goes to `/api/v1/agentbots/<sharedId>/logs/<msgId>` and
      returns 200 with the same JSON shape as the logged-in path.
- [ ] Confirm the chat completions, inputs, and upload flows in
      the share page still work — they were not touched.
- [ ] Send a bogus / expired beta token to the new endpoint and
      confirm it returns the standard "Authentication error: API
      key is invalid!" response (no traceback, no 500).
- [ ] Run `uv run pytest` to make sure no existing tests regress.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [ ] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):

---------

Co-authored-by: Zhichang Yu <yuzhichang@gmail.com>
2026-06-29 09:45:16 +08:00
balibabu
d14d2068c4 Fix: If the type of the loop variable in the Loop operator is set to object, an error occurs when clicking the Variable Replicator operator inside it. (#16388) 2026-06-26 18:44:56 +08:00
balibabu
1dfc24003b Fix: An empty message notification pops up at the top of the agent conversation. (#16353) 2026-06-25 17:32:24 +08:00
Ilya Bogin
10d02e54a8 Add Keenable web search tool to the agent (#16233)
Adds Keenable as a web search tool in the agent, alongside the existing
Tavily/DuckDuckGo/SearXNG/Google tools.

The main difference from the other search tools is that it doesn't
require an
API key. By default it uses Keenable's keyless public endpoint, so it
works out
of the box. Providing a key (in the tool config) switches to the
authenticated
endpoint and lifts the rate limits.

### Changes

- Backend: `agent/tools/keenable.py` — `KeenableSearch`, follows the
  Tavily/DuckDuckGo tool shape (results go through `_retrieve_chunks`).
  Auto-registered by `agent/tools/__init__.py`.
- Frontend: wired into the agent builder — operator + icon, config form
(optional API key, search mode, site filter, top N), the search tool
menu,
  and the existing api_key export sanitizer.

### Config

- API key: optional. Blank = keyless free tier; set it to lift limits /
enable
  `realtime` mode.
- `site`: restrict to a single domain.
- `mode`: `pro` (default) or `realtime`.

### Notes

`KEENABLE_API_URL` can override the API base (HTTPS enforced; defaults
to
`https://api.keenable.ai`). The tool only sends the query (no URL
fetch), so
there's no SSRF surface. Verified the frontend with `vite build` and the
backend search path against the public endpoint.
2026-06-25 12:12:28 +08:00
buua436
8d4f4a093b fix: restore dataflow defaults and SSE response (#16290) 2026-06-24 11:51:24 +08:00
Yoorim Choi
6a8281721f fix(i18n): fix missing i18n coverage and refine Korean translations (#16203)
### What problem does this PR solve?

This PR follows up on
[#15863](https://github.com/infiniflow/ragflow/pull/15863) (Korean i18n)
with translation refinements and i18n coverage for hardcoded strings
found in the UI.

- Refine awkward Korean phrasing (e.g. 'Chunk 만들기' → 'Chunk 생성', '유형' →
'타입', etc.)
- Apply i18n to hardcoded strings in `message-item`,
`next-message-item`, `multi-select`, `chat-prompt-engine`, and various
filter hooks
- Rename `use-selelct-filters.ts` → `use-select-filters.ts` (typo fix)

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-24 10:14:19 +08:00
balibabu
d8ee1ffaad Fix: When re-entering the agent page, the data from the previous session flashes briefly. (#16251)
Fix: When re-entering the agent page, the data from the previous session flashes briefly.
2026-06-23 14:13:47 +08:00
Zhichang Yu
3f805a64f1 feat(agent): align Go agent behavior with Python (except retrieval component) (#16225)
## Summary

Aligns the **Go agent runtime/canvas/components/tools** behavior with
the **Python `agent/` implementation** so the same stored canvas DSL
produces the same execution result on either side. Every component,
tool, and runtime primitive in `internal/agent/` is now driven by the
same semantics as its Python counterpart — variable resolution, template
substitution, control flow, error reporting, retry/cancel, and stream
event shapes.

The **retrieval component is the one explicit exception** in this PR. It
is being reworked in a separate change and is excluded from this
alignment pass; the wrapper slot (`universe_a_wrappers.go →
newRetrievalComponent`) is preserved.

## Scope of alignment

### Components (all aligned with `agent/component/`)
`Begin` · `Message` · `LLM` (incl. ChatTemplateKwargs,
MessageHistoryWindowSize, VisualFiles, Cite, OutputStructure,
JSONOutput, TopP, MaxRetries, DelayAfterError, credentials) · `Agent`
(react + tool artifact capture + `Reset()` interface-assert) · `Switch`
(12/12 operators, Python-equivalent semantics) · `Categorize` · `Invoke`
· `Iteration` · `Loop` (macro-expansion through `workflowx.AddLoopNode`)
· `UserFillUp` (Python-equivalent interrupt/resume via eino
`compose.Interrupt`/`ResumeWithData`) · `FillUp` · `DataOperations` ·
`ListOperations` · `StringTransform` · `VariableAggregator` ·
`VariableAssigner` · `Browser` (full stagehand runtime parity) ·
`DocsGenerator` · `ExcelProcessor`.

### Tools (all aligned with `agent/tools/`)
`Retrieval` (wrapper slot only — logic out of scope) · `MCPToolAdapter`
(streamable-HTTP) · `CodeExec` (sandbox bridge with
`code_exec_contract.go` matching Python contract) · `AkShare` · `ArXiv`
· `Crawler` · `DeepL` · `DuckDuckGo` · `Email` · `ExeSQL` · `GitHub` ·
`Google` · `GoogleScholar` · `Jin10` · `PubMed` · `QWeather` · `SearXNG`
· `Tavily` · `Tushare` · `Wencai` · `Wikipedia` · `YahooFinance` —
uniform `eino tool.InvokableTool` interface, SSRF protection, shared
HTTP client.

### Canvas execution engine (`internal/agent/canvas/`)
Aligned with Python's `agent/canvas.py`:
- **Scheduler** (`scheduler.go`): state pre/post handlers, node lambdas,
per-component timeout resolver (4-level: per-class env → per-class table
→ uniform env → 600s fallback), `legacyNoOpNames`.
- **Loop subgraph** (`loop_subgraph.go`): Python-equivalent
`AddLoopNode` macro expansion + condition translation.
- **Multibranch** (`multibranch.go`): `Switch` / `Categorize` routing
via `compose.NewGraphMultiBranch` — same branch selection semantics as
Python.
- **Parallel subgraph** (`parallel_subgraph.go`): matches Python's
parallel fan-out contract.
- **Interrupt/Resume** (`interrupt_resume.go`): `UserFillUpNodeBody` /
`IsInterruptError` / `ExtractInterruptContexts` — replaces the
deprecated Python sentinel chain with eino's native interrupt API,
preserving the same external behavior.
- **Checkpoint** (`checkpoint_store.go`): `RedisCheckPointStore`
Get/Set/Delete, with business metadata (status / canvas_id /
parent_run_id) on a parallel Redis Hash.
- **RunTracker** (`run_tracker.go`): Start / MarkSucceeded / MarkFailed
/ MarkCancelled / AttachCheckpoint — same lifecycle as the Python run
record.
- **Cancel** (`cancel.go`): Redis pub/sub watch.
- **Stream** (`stream.go`): SSE channel with `messages` / `waiting` /
`errors` / `done` events, same shape as Python's `agent.canvas.RunEvent`
payload.

### DSL bridge (`internal/agent/dsl/`)
- `normalize.go`: v1↔v2 collapsed into a single wire format — Python and
Go consume the same stored JSON.
- `reset.go`: per-run state reset matches Python's `Canvas.reset()`
semantics.
- Testdata mirrors Python's `agent_msg.json` / `all.json` / etc.

### Runtime (`internal/agent/runtime/`)
- `CanvasState` / `NewCanvasState` / `GetVar` / `SetVar` / `ReadVars`:
same `{{cpn_id@param}}` resolution model.
- `ResolveTemplate` (regex fast path + gonja fallback) — Python
Jinja-style semantics.
- `selector.go`, `metrics.go`, `component.go`: shared runtime contracts.

## Out of scope (intentionally)

- **`Retrieval` component logic** — wrapped only; full parity lands in a
follow-up PR.
- **Frontend** — only minor dsl-bridge / canvas UX fixes ride along.
- **CLI / admin / model registry** — orthogonal to agent behavior.

## How alignment is verified

`internal/service/agent_run_e2e_test.go` exercises the **full production
chain** against real Python-shaped DSL fixtures:
```
loadCanvasForUser → versionDAO.GetLatest → decodeCanvasFromDSL →
canvas.Compile → cc.Workflow.Invoke → answer extraction
```
using in-memory SQLite + miniredis (no Docker). Covers:
- `TestRunAgent_RealCanvas_BeginMessage` — happy path, `{{sys.query}}`
resolution
- `TestRunAgent_RealCanvas_WaitForUserResume` — two-run resume cycle
(Python-equivalent)
- `TestRunAgent_RealCanvas_CompileFails` — unknown component name →
sanitized error (Python-equivalent)
- `TestRunAgent_RealCanvas_InvokeFails` — unresolvable template ref
(Python-equivalent)
- `TestRunAgent_RunTracker_AttachCheckpoint_CallSequence` —
Start→AttachCheckpoint→MarkSucceeded lifecycle

`internal/handler/agent_test.go` — SSE streaming parity (`Content-Type:
text/event-stream`, `data: {…}\n\n`, trailing `data: [DONE]\n\n`,
OpenAI-compatible non-stream `choices`).

`internal/agent/canvas/fixture_compile_test.go` + per-component tests
pin the Python-equivalent outputs.

```
go test -count=1 -v -run 'TestRunAgent_RealCanvas|TestRunAgent_RunTracker' ./internal/service/
```

## Design reference

`docs/develop/agent-go-port-design.md` (1329 lines, last cross-checked
2026-06-17) — module layout, per-component / per-tool inventory,
corner-case catalogue, and the actionable backlog (Section 14, including
the retrieval alignment follow-up).

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 11:58:29 +08:00
balibabu
a9021528c3 Fix: Lint error. (#16172)
### What problem does this PR solve?

Fix: Lint error.
### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-18 13:14:18 +08:00
balibabu
cf7b06c0f3 Fix: A pipeline created from a template fails immediately upon execution with a "hierarchy does not exist" error. (#16151)
### What problem does this PR solve?

Fix: A pipeline created from a template fails immediately upon execution
with a "hierarchy does not exist" error.
2026-06-17 19:07:04 +08:00
balibabu
70f319c536 Fix: The pipeline created from the template fails immediately upon execution. (#16149)
### What problem does this PR solve?

Fix: The pipeline created from the template fails immediately upon
execution.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-17 17:03:17 +08:00
balibabu
3247e353c7 Fix: The .docx file is not displaying fully; the hierarchy of the pipeline created from the template is missing. (#16134)
### What problem does this PR solve?

Fix: The .docx file is not displaying fully; the hierarchy of the
pipeline created from the template is missing.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-17 16:18:47 +08:00
Zhichang Yu
e45659868a feat(agent): ship the Go agent canvas port — eino interrupt/resume + Redis check-pointing (#16035)
Replaces the Python agent canvas runtime with a Go implementation that
runs inside `cmd/server_main`.

The canvas compiles into an eino Workflow that pauses on wait-for-user
via native Interrupt/Resume (no sentinel flag) and resumes from a
Redis-backed CheckPointStore.

All 21 Python agent components and ~35 tools are ported with functional
parity.

Sandbox providers now read their JSON config from the admin-panel
system_settings table with env fallback.

234 files / +35,413 / -6,111. All Go files are gofmt-clean (CI gate
added); drops the v2 DSL E2E step and the gap-analysis plan (both
redundant after the port ships).

## Type of change

- [x] Refactoring
- [x] New feature
- [x] Bug fix

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-17 13:24:03 +08:00
balibabu
ba93ac3bd7 Feat: Move less important chat settings into a collapsible panel. (#16024)
### What problem does this PR solve?

Feat: Move less important chat settings into a collapsible panel.

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
2026-06-15 19:09:19 +08:00
balibabu
5d3f8bbf32 Fix: The regular expression configuration for pipeline header-based chunking will be reset. (#15935)
### What problem does this PR solve?

Fix: The regular expression configuration for pipeline header-based
chunking will be reset.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-11 14:12:24 +08:00
balibabu
10bbe6b5d4 Fix: The variables in the Visual Input File of the agent operator are not displayed. (#15856)
### What problem does this PR solve?

Fix: The variables in the Visual Input File of the agent operator are
not displayed.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-09 19:41:22 +08:00
balibabu
9c14e3f377 Fix: When adding a chat in the main interface, a warning will automatically pop up (#15685)
### What problem does this PR solve?

Fix: When adding a chat in the main interface, a warning will
automatically pop up (even if embedding and LLM model have already been
configured).
### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-06-05 19:09:22 +08:00
Lynn
dc4b82523b Feat: tenant llm provider (#14595)
### What problem does this PR solve?

Python implementation of the Go-based model_provider API suite.

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: bill <yibie_jingnian@163.com>
2026-05-29 17:39:41 +08:00
balibabu
ed179ce684 Fix: The prompt variable for the agent operator disappears after input. (#15218)
### What problem does this PR solve?

Fix: The prompt variable for the agent operator disappears after input.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-05-25 20:36:51 +08:00
nickmopen
e7d45dd645 Feat: Expose Doc Generator file metadata as discrete outputs (#15080)
Declare doc_id, filename, mime_type, and size as separate outputs on the
Document Generation component so downstream nodes (e.g., the Code
component) can consume them via the variable picker. The existing
download JSON blob is preserved unchanged for the Message component's
download-chip rendering.

### What problem does this PR solve?

The Document Generation component previously exposed only a single
`download` output —
a JSON-encoded blob containing the file's `doc_id`, `filename`,
`mime_type`, `size`,
and base64 payload. On top of that, the variable picker actively hides
this `download`
entry from every consumer except the Message component (because the
embedded base64 is
  too heavy to splat into arbitrary downstream nodes).

The combined effect: users wiring the Doc Generator's output into a Code
component had
no way to retrieve basic file info such as `file_name` or `doc_id` from
the picker,
blocking workflows that need to post-process the generated file (e.g.,
registering it
  elsewhere, custom delivery, follow-up API calls).

This PR declares `doc_id`, `filename`, `mime_type`, and `size` as
**discrete outputs**
on the Document Generation component, alongside the existing `download`
blob. The new
  fields:

- Appear in the variable picker for **all** downstream nodes, including
the Code
  component, so users can bind them directly to script arguments.
- Are cheap scalars only — no base64 payload leaks into other
components.
- Leave the existing `download` JSON blob completely untouched, so the
Message
component's download-chip rendering (which parses that blob via
`_is_download_info`)
  keeps working with no behavior change.

  Changes:
- `agent/component/docs_generator.py` — declare the four new outputs in
  `DocGeneratorParam` and emit them via `set_output(...)` in `_invoke`.
- `web/src/pages/agent/constant/index.tsx` — extend
`initialDocGeneratorValues.outputs`
   with the new keys.
- `web/src/pages/agent/form/doc-generator-form/index.tsx` — mirror the
new outputs in
  the zod schema so the form is valid.

No changes needed to the picker's existing `download`-hiding filter — it
matches only
on the literal output name `download`, so the new metadata entries fall
through
  naturally.

  Reported in: https://github.com/infiniflow/ragflow/issues/14461.
  ### Type of change

  - [x] New Feature (non-breaking change which adds functionality)
2026-05-25 16:05:00 +08:00
天海蒼灆
3e5b11a523 Feat(browser control):Add new agent component 'browser' to control browser by AI (#14888)
### What problem does this PR solve?
This PR adds a new `Browser` operator to Agent workflows, enabling
prompt-driven browser automation in RAGFlow.Technically based
‘Browser-Use’

It includes:
- Backend browser component execution with tenant LLM integration
- Upload source support (file IDs, URLs, variables, CSV/JSON array)
- Downloaded file persistence to RAGFlow storage
- Frontend node/operator integration, form config, icon, and i18n
updates
- Unit tests for upload/download and ID parsing logic
- Dependency and Docker updates for browser-use runtime support

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
2026-05-21 15:32:32 +08:00
yingjianzh
4c68a6b86c fix(agent): pass top_k and fix similarity weight slider behavior (#14760)
### What problem does this PR solve?

This PR fixes two issues in Agent Retrieval behavior and configuration
UX:

1. `top_k` configured in Agent Retrieval was not passed down to the
backend retriever call, so retrieval could ignore the configured vector
recall limit.
2. Similarity weight slider semantics were confusing in Agent forms
because the Agent field stores `keywords_similarity_weight` while UI
interactions were interpreted as vector weight. This could cause
displayed values and actual behavior to diverge.

This PR ensures Agent retrieval uses configured `top_k`, and makes the
slider behavior consistent and explicit for both vector and keyword
weight modes.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-05-15 10:49:14 +08:00
47NoahThompson
9e0f976729 Add widget customization and persistence (#14603)
Introduce comprehensive floating widget customization: add new widget
settings (title, subtitle, footer, colors, mute, streaming) with types
and defaults, and expose them via EmbedDialog UI (split into Embed Setup
and Widget Customization tabs). Persist and load settings through Agent
page by reading/writing globals and wiring an onSaveWidgetSettings
handler to setAgent; show a loading ButtonLoading for saving. Update
embed iframe query params and FloatingChatWidget to honor URL params
(colors, text, mute/streaming) with validation/normalization, color
darkening for gradients, footer link normalization, and improved
styling. Also add copy-to-clipboard in message toolbar, adjust syntax
highlighter layout and Copy button, and add i18n key for muteWidget.

### What problem does this PR solve?

Adds a few fields to the embed widget modal to customize the appearance
of the floating widget when embedded into a page.

### Type of change


- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: Noah <Noah.Thompson@ecn.forces.gc.ca>
2026-05-13 21:13:11 +08:00
Ahmad Intisar
e994051eb9 Feature/generic api connector (#13545)
# feat: Add Generic REST API Connector

## What problem does this PR solve?

RAGFlow supports many specific data source connectors (MySQL, Slack,
Google Drive, etc.), but there was no way to connect an arbitrary REST
API as a data source. Users with custom or third-party APIs had to write
a new connector class for each one.

This PR adds a **generic, configuration-driven REST API connector** that
lets users connect any REST API as a data source entirely through the UI
— no code changes needed per API.

---

## Features

### Core Connector (`common/data_source/rest_api_connector.py`)

- Implements `LoadConnector` and `PollConnector` interfaces for full and
incremental sync
- **Configurable authentication:** None, API Key (custom header), Bearer
Token, Basic Auth
- **Pluggable pagination:** Page-based, Offset-based, Cursor-based, or
None
- Smart page-size inference from user's query parameters to avoid
duplicate/conflicting params
- Configurable request delay between pages to prevent API rate limiting
- Auto-detection of the items array in JSON responses (`items`,
`results`, `data`, `records`, or first list found)
- **Advanced field mapping** with dot-notation (`country.name`), array
wildcards (`newsType[*].name`), type hints, and default values
- Optional content template rendering (`"Title: {title}\nBody: {body}"`)
- HTML stripping for content fields
- Stable document IDs via `hash128` from a configurable ID field or
auto-generated from item content
- Pydantic configuration schema with automatic coercion of UI string
inputs to dicts/lists

### Backend Registration (`rag/svr/sync_data_source.py`,
`common/constants.py`, `common/data_source/config.py`)

- `REST_API` sync class wired into RAGFlow's `func_factory`
- Full sync (`load_from_state`) and incremental polling (`poll_source`)
support
- Credentials and config passed from task to connector following
existing patterns (MySQL, SeaFile, etc.)

### Test Connection Endpoint (`api/apps/connector_app.py`)

- `POST /v1/connector/<id>/test` validates config schema,
authentication, and API connectivity without triggering a sync
- Clear error messages for auth failures vs. config issues

### Frontend UI (`web/src/pages/user-setting/data-source/constant/`)

- **Postman-style configuration:** Base URL, Query Parameters (key=value
per line), Auth, Content Fields, Metadata Fields, Pagination Type
- Auth-type-aware form: fields for API key header/value, Bearer token,
or Basic username/password appear only when relevant
- **Advanced Settings** toggle for: Custom Headers, Max Pages, Request
Delay, Poll Timestamp Field, Request Body (POST)
- Connector icon (SVG) and i18n strings (English)
- **"Test Connection"** button to validate before syncing

---

## Controls & Safety

- Configurable max pages safety cap (default: 1000, adjustable in UI)
- Configurable request delay between pages (default: 0.5s, adjustable in
UI)
- Auth errors (401/403) fail immediately without retries; transient
errors retry with exponential backoff
- Diagnostic logging: auth setup confirmation, request details on
failure, content field extraction status

---

## Type of change

- [x] New Feature (non-breaking change which adds functionality)


##Visual Screenshots of Features
<img width="482" height="510" alt="Screenshot 2026-03-11 at 5 19 52 PM"
src="https://github.com/user-attachments/assets/dcb7ab4a-1622-44f3-bb02-d6f0527314c4"
/>
(Connector can be configured within the external data sources tab)

Configuration Parameters:
<img width="661" height="682" alt="Screenshot 2026-03-11 at 5 20 46 PM"
src="https://github.com/user-attachments/assets/5e154e71-4ab5-4872-bfb2-04f02b73c18a"
/>
<img width="661" height="682" alt="Screenshot 2026-03-11 at 5 20 54 PM"
src="https://github.com/user-attachments/assets/00cb14b7-0bcf-4b94-9d71-34e93369ecb2"
/>

Connection can be tested before attaching to dataset:
<img width="981" height="681" alt="Screenshot 2026-03-11 at 5 21 40 PM"
src="https://github.com/user-attachments/assets/aaa6eeeb-89a7-4349-bc34-2423bf8be9ee"
/>

Ingestion tested with API connector (works perfectly fine):
<img width="1062" height="705" alt="Screenshot 2026-03-11 at 5 22 30 PM"
src="https://github.com/user-attachments/assets/afcd0d58-cadd-4152-badc-d2f14d96fbec"
/>

Search & Retrieval works as well with metadata flow:
<img width="1062" height="705" alt="Screenshot 2026-03-11 at 5 23 05 PM"
src="https://github.com/user-attachments/assets/d41ee935-dcf7-4456-b317-22a76ca032c0"
/>

---------

Co-authored-by: Ahmad Intisar <ahmadintisar@Ahmads-MacBook-M4-Pro.local>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-13 20:35:01 +08:00
balibabu
3f41f8cfae Feat: When a Wait Node precedes a Message Node within a Loop Node, the outgoing message is split into two separate messages. (#14839)
### What problem does this PR solve?

Feat: When a Wait Node precedes a Message Node within a Loop Node, the
outgoing message is split into two separate messages.

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
2026-05-12 18:48:44 +08:00
Magicbook1108
f85e18afbc Refact: sandbox quickstart.md & add tutorial for code exec component (#14786)
### What problem does this PR solve?

Refact: sandbox quickstart.md && add tutorial for code exec component

### Type of change

- [x] Refactoring


<img width="700" alt="img_v3_0211j_dcff835b-e3bb-4c77-9bc5-3b31a983229g"
src="https://github.com/user-attachments/assets/7842fc0f-639a-458f-b164-bc81a99ce4a5"
/>

---------

Co-authored-by: writinwaters <93570324+writinwaters@users.noreply.github.com>
2026-05-12 14:42:20 +08:00
buua436
e8adc977bd Fix: some agent bug (#14829)
### What problem does this PR solve?

fix: 
update null checks to use 'is None' for better clarity
replace RAGFlowSelect with SelectWithSearch in DebugContent
add max height and overflow to DialogContent in ParameterDialog
 remove unused types from DataOperationsForm

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-05-12 14:41:49 +08:00
buua436
daf8a58c4b Fix: add codeexec attachments output (#14787)
### What problem does this PR solve?

add codeexec attachments output

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-05-11 19:16:33 +08:00
buua436
5b162a0c46 Fix: preserve doc generator download metadata in message (#14626)
### What problem does this PR solve?

preserve doc generator download metadata

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
2026-05-07 15:48:36 +08:00
Attili-sys
24af0875e5 Feat/configurable metadata display (#13464)
### What problem does this PR solve?

Currently, RAGFlow's Search and Chat interfaces display only raw
vectorized text chunks during retrieval, without contextual information
about their source documents. Users cannot see document titles, page
numbers, upload dates, or custom metadata fields that would help them
understand and trust the retrieved results.

This PR introduces an **optional metadata display feature** that
enriches retrieved chunks with document-level metadata in both the
Search tab and Chatbot interface.

**Key improvements:**
- **Search results**: Display document metadata as styled badges beneath
chunk snippets
- **Chat citations**: Show metadata in citation popovers and reference
lists for better source context
- **LLM context**: Metadata is injected into the LLM prompt to enable
more accurate, citation-aware responses
- **External API support**: Applications using RAGFlow's SDK retrieval
endpoints (`/v1/retrieval`, `/v1/searchbots/retrieval_test`) can opt-in
via request parameters
- **User control**: Multi-select dropdown UI allows users to choose
which metadata fields to display

**Implementation approach:**
-  Reuses existing `DocMetadataService` infrastructure (no new database
tables or indices)
-  Settings stored in existing JSON configuration fields
(`search_config.reference_metadata`, `prompt_config.reference_metadata`)
-  No database migrations required
-  Disabled by default (fully opt-in and backward-compatible)
-  Dynamic metadata field selection populated from actual document
metadata keys
-  Fixed critical bug where Python's builtin `set()` was shadowed by a
route handler function

**Modified endpoints (all backward-compatible):**
- `POST /v1/retrieval` (Public SDK)
- `POST /v1/searchbots/retrieval_test` (Searchbots)
- `POST /v1/chunk/retrieval_test` (UI/Internal)
- Chat completions endpoints (via `extra_body.reference_metadata` or
`prompt_config`)

### Type of change

- [x] New Feature (non-breaking change which adds functionality)


###Images
-
<img width="879" height="1275" alt="image"
src="https://github.com/user-attachments/assets/95b2d731-31ae-45a1-b081-bf5893f52aeb"
/>
<br><br>
<br><br>

<img width="1532" height="362" alt="image"
src="https://github.com/user-attachments/assets/9cebc65b-b7a7-459f-b25e-3b13fa9b638e"
/>
<br><br>
<br><br>

<img width="2586" height="1320" alt="image"
src="https://github.com/user-attachments/assets/2153d493-d899-461f-a7a9-041391e07776"
/>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Attili-sys <Attili-sys@users.noreply.github.com>
Co-authored-by: Ahmad Intisar <ahmadintisar@Ahmads-MacBook-M4-Pro.local>
2026-04-30 23:13:27 +08:00