Commit Graph

1633 Commits

Author SHA1 Message Date
haoliangxu
06cba217c3 feat: track token usage per conversation turn (#1218)
* feat: track token usage per conversation turn

Add token usage tracking to the streaming API so consumers can monitor
cost per turn without additional API calls.

Changes:

1. _serialize_message now includes usage_metadata for AI messages in
   values events, exposing input_tokens/output_tokens/total_tokens
   from LangChain's native metadata.

2. stream() accumulates token usage across all AI messages in a turn
   and emits the cumulative totals in the end event:
   {usage: {input_tokens: N, output_tokens: N, total_tokens: N}}

3. Each messages-tuple AI event with text content now includes a
   per-message usage_metadata field for granular tracking.

This enables the frontend to display token consumption per turn,
support cost-aware UX, and let users monitor API spending.

10 tests added covering serialization passthrough and cumulative
aggregation logic.

Co-Authored-By: OpenClaw <noreply@openclaw.ai>

* fix: address Copilot review - use Mapping access for usage_metadata

- Replace getattr(usage, 'input_tokens', 0) with usage.get('input_tokens', 0)
  since LangChain usage_metadata is a dict, not an object
- Remove unused 'import pytest' (fixes Ruff F401)
- Add proper stream() integration tests for cumulative usage in end event
  and per-message usage_metadata in messages-tuple events

---------

Co-authored-by: Exploreunive <Exploreunive@users.noreply.github.com>
Co-authored-by: OpenClaw <noreply@openclaw.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-21 10:29:52 +08:00
Chetan Sharma
e69dc2961f refactor: add channel-based streaming capability check (#1214) 2026-03-20 23:44:09 +08:00
dependabot[bot]
9a99485905 build(deps): bump kysely from 0.28.11 to 0.28.13 in /frontend (#1211)
Bumps [kysely](https://github.com/kysely-org/kysely) from 0.28.11 to 0.28.13.
- [Release notes](https://github.com/kysely-org/kysely/releases)
- [Commits](https://github.com/kysely-org/kysely/compare/v0.28.11...v0.28.13)

---
updated-dependencies:
- dependency-name: kysely
  dependency-version: 0.28.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-20 17:29:01 +08:00
Simon Su
ceab7fac14 fix: improve MiniMax code plan integration (#1169)
This PR improves MiniMax Code Plan integration in DeerFlow by fixing three issues in the current flow: stream errors were not clearly surfaced in the UI, the frontend could not display the actual provider model ID, and MiniMax reasoning output could leak into final assistant content as inline <think>...</think>. The change adds a MiniMax-specific adapter, exposes real model IDs end-to-end, and adds a frontend fallback for historical messages.
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-20 17:18:59 +08:00
knukn
3b235fd182 fix(feishu): support @bot message in topic groups (#1206)
* fix(feishu): support @bot message in topic groups

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix(feishu): preserve rich-text formatting and add parser unit tests

* chore(test): remove unused import to fix ruff lint error

* style: auto-format imports to satisfy ruff

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-20 17:03:39 +08:00
JilongSun
c037ed6739 feat(manager): add bootstrap command to initialize soul.md in correct place (#1201)
* feat(manager): add bootstrap command to initialize soul.md in correct place

* feat(channels): add /bootstrap command to IM channels

Add a `/bootstrap` command that routes to the chat handler with
`is_bootstrap: True` in the run context, allowing the agent to invoke
its setup/initialization flow (e.g. `setup_agent`).

- The text after `/bootstrap` is forwarded as the chat message; when
  omitted a default "Initialize workspace" message is used.
- Feishu channels use the streaming path as with normal chat.
- No changes to ChannelStore — bootstrap is stateless and triggered
  purely by the command.
- Update /help output to include /bootstrap.
- Add 5 tests covering: text/no-text variants, Feishu streaming path,
  thread creation, and help text.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: accept copilot suggestion

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-20 16:54:11 +08:00
greatmengqi
accf5b5f8e fix: add sync after_model to TitleMiddleware (#1190) 2026-03-19 15:46:31 +08:00
Ryanba
f67c3d2c9e fix(harness): skip duplicate memory facts (#1193)
* fix(harness): skip duplicate memory facts

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs: note memory fact deduplication

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-18 22:41:13 +08:00
BillionToken
423ea59491 fix(scripts): handle docker-init failures gracefully for private registry (#1191)
* fix(scripts): handle docker-init failures gracefully for private registry

The make docker-init command was failing on Linux environments when users
could not access the private Volces container registry. This commonly
occurs in corporate intranet environments with proxies or for users
without registry credentials.

Changes:
- Detect sandbox mode from config.yaml before attempting image pull
- Skip image pull entirely for local sandbox mode (default)
- Gracefully handle pull failures with informative messages
- Update setup-sandbox Makefile target with same error handling

Fixes #1168

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: BillionClaw <billionclaw@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-18 22:06:35 +08:00
Ryanba
4c78188896 fix(gateway): remove generated markdown on upload delete (#1170)
* fix(gateway): remove generated markdown on upload delete

Keep thread upload storage consistent by deleting the generated markdown companion when the original convertible upload is removed.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-18 16:31:26 +08:00
Ryanba
f737fbeae8 fix(frontend): block duplicate sends during uploads (#1165)
* fix(frontend): block duplicate sends during uploads

Expose pre-submit upload work as a busy state so the chat input does not allow a second send while the first attachment is still uploading.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs(frontend): document upload and stream ownership

Record that thread hooks own upload-before-submit state while the chat page owns composer busy wiring, so future changes do not reintroduce duplicate socket or upload state handling.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix(frontend): separate upload busy state from streaming

Keep uploads from reusing the streaming stop state so duplicate submits are blocked without turning the composer into a stop button during file uploads.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-18 15:10:27 +08:00
dependabot[bot]
beb0eab711 build(deps): bump pyasn1 from 0.6.2 to 0.6.3 in /backend (#1185)
Bumps [pyasn1](https://github.com/pyasn1/pyasn1) from 0.6.2 to 0.6.3.
- [Release notes](https://github.com/pyasn1/pyasn1/releases)
- [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst)
- [Commits](https://github.com/pyasn1/pyasn1/compare/v0.6.2...v0.6.3)

---
updated-dependencies:
- dependency-name: pyasn1
  dependency-version: 0.6.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-18 08:05:16 +08:00
dependabot[bot]
4977c43974 build(deps): bump next from 16.1.6 to 16.1.7 in /frontend (#1186)
Bumps [next](https://github.com/vercel/next.js) from 16.1.6 to 16.1.7.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.6...v16.1.7)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.1.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-18 08:04:24 +08:00
dependabot[bot]
5b37de60b7 build(deps): bump flatted from 3.3.3 to 3.4.2 in /frontend (#1184)
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.2.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-18 07:50:32 +08:00
DanielWalnut
feac03ecbc fix(harness): allow agent read access to /mnt/skills in local sandbox (#1178)
* fix(harness): allow agent read access to /mnt/skills in local sandbox

Skill files under /mnt/skills/ were blocked by the path validator,
preventing agents from reading skill definitions. This change:

- Refactors `resolve_local_tool_path` into `validate_local_tool_path`,
  a pure security gate that no longer resolves paths (left to the sandbox)
- Permits read-only access to the skills container path (/mnt/skills by
  default, configurable via config.skills.container_path)
- Blocks write access to skills paths (PermissionError)
- Allows /mnt/skills in bash command path validation
- Adds `LocalSandbox.update_path_mappings` and injects per-thread
  user-data mappings into the sandbox so all virtual-path resolution
  is handled uniformly by the sandbox layer
- Covers all new behaviour with tests

Fixes #1177

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(sandbox): unify all virtual path resolution in tools.py

Move skills path resolution from LocalSandbox into tools.py so that all
virtual-to-host path translation (user-data and skills) lives in one
layer.  LocalSandbox becomes a pure execution layer that receives only
real host paths — no more path_mappings, _resolve_path, or reverse
resolve logic.

This addresses architecture feedback that path resolution was split
across two layers (tools.py for user-data, LocalSandbox for skills),
making the flow hard to follow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(sandbox): address Copilot review — cache-on-success and error path masking

- Replace @lru_cache with manual cache-on-success for _get_skills_container_path
  and _get_skills_host_path so transient failures at startup don't permanently
  disable skills access.
- Add _sanitize_error() helper that masks host filesystem paths in error
  messages via mask_local_paths_in_output before returning them to the agent.
- Apply _sanitize_error() to all catch-all (Exception/OSError) handlers in
  sandbox tool functions to prevent host path leakage in error output.
- Remove unused lru_cache import.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:44:36 +08:00
lhd
0091d9f071 feat(tools): add tool_search for deferred MCP tool loading (#1176)
* feat(tools): add tool_search for deferred MCP tool loading

When multiple MCP servers are enabled, total tool count can exceed 30-50,
causing context bloat and degraded tool selection accuracy. This adds a
deferred tool loading mechanism controlled by `tool_search.enabled` config.

- Add ToolSearchConfig with single `enabled` field
- Add DeferredToolRegistry with regex search (select:, +keyword, keyword)
- Add tool_search tool returning OpenAI-compatible function JSON
- Add DeferredToolFilterMiddleware to hide deferred schemas from bind_tools
- Add <available-deferred-tools> section to system prompt
- Enable MCP tool_name_prefix to prevent cross-server name collisions
- Add 34 unit tests covering registry, tool, prompt, and middleware

* fix: reset stale deferred registry and bump config_version

- Reset deferred registry upfront in get_available_tools() to prevent
  stale tool entries when MCP servers are disabled between calls
- Bump config_version to 2 for new tool_search config field

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tests): mock get_app_config in prompt section tests for CI

CI has no config.yaml, causing TestDeferredToolsPromptSection to fail
with FileNotFoundError. Add autouse fixture to mock get_app_config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 20:43:55 +08:00
Henry Li
f29db80be7 docs: add coding plan from ByteDance Volcengine (#1174)
* docs: add coding plan

* docs: add coding plan
2026-03-17 14:33:47 +08:00
Henry Li
cb4cae4064 docs: add README in Chinese (#1172)
Co-authored-by: Henry Li <lixin.henry@bytedance.com>
2026-03-17 13:51:01 +08:00
Karesansui
75c96300cf fix(scripts): add next-server to serve.sh cleanup trap (#1162)
The cleanup() trap kills "next dev" and "next start" but not
"next-server". Since "next start" forks a "next-server" child
process, killing the parent may leave the child running as a
zombie, holding port 3000. The startup teardown block (line 35)
already handles this, but the Ctrl+C / SIGTERM trap did not.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-17 10:07:16 +08:00
lailoo
9809af1f26 feat: add citation/reference support to deep research reports (#1143)
* feat: add citation/reference support to deep research reports (#1141)

- Enhance lead agent system prompt with mandatory citation requirements
  after web_search/web_fetch tool usage
- Add citation examples and best practices to GitHub Deep Research skill
- Add citation hints to report template (Executive Summary, Key Analysis)
- Style regular markdown links in frontend for visual distinction
  (color, underline, hover effect)
- Fix TitleMiddleware being registered when title generation is disabled

* fix: address PR review comments

- Revert TitleMiddleware conditional registration (agent.py) to avoid
  sync/async incompatibility with DeerFlowClient
- Fix markdown link rendering: merge classNames instead of overwriting,
  only set target=_blank for external http(s) URLs
- Remove unrelated package.json/pnpm-lock.yaml changes

* fix: use plain markdown links in Sources section for cleaner rendering

Inline citations in report body use [citation:Title](URL) for pill/badge style.
Sources section uses plain [Title](URL) for simple underlined link style.

* fix(frontend): render plain links as underlined text in artifact markdown

Only links with citation: prefix render as Badge pills.
Regular links in Sources section now render as underlined text links.

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-17 09:51:08 +08:00
Ryanba
b1913a1902 fix(harness): normalize structured content for titles (#1155)
* fix(harness): normalize structured content for titles

Flatten structured LangChain message content before prompting the title model so list/block payloads don't leak Python reprs into generated thread titles.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-17 09:10:09 +08:00
Karesansui
ab0c10f002 fix(makefile): correct docker-init help description (#1163)
The help text described docker-init as "Build the custom k3s image"
but the actual implementation (scripts/docker.sh init) only pulls
the sandbox image. Updated to match the real behavior.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-16 21:53:58 +08:00
Matt Van Horn
609ff5849f fix(frontend): gracefully handle missing WebGL context (#1147)
Wrap the OGL Renderer instantiation in a try-catch so the app does not
crash when WebGL is unavailable (e.g. hardware acceleration disabled).
The Galaxy background simply does not render instead of taking down the
entire page.

Fixes #1144

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-16 21:22:17 +08:00
Karesansui
3212c7c5a2 fix(scripts): correct Makefile target name in docker.sh restart message (#1161)
docker.sh restart() tells users to run `make docker-dev-logs`, but
this target does not exist. The correct target is `make docker-logs`.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 19:58:59 +08:00
-Astraia-
191b60a326 fix: issue 1138 windows encoding (#1139)
* fix(windows): use utf-8 for text file operations

* fix(windows): normalize sandbox path masking

* fix(windows): preserve utf-8 handling after backend split
2026-03-16 16:53:12 +08:00
DanielWalnut
76803b826f refactor: split backend into harness (deerflow.*) and app (app.*) (#1131)
* refactor: extract shared utils to break harness→app cross-layer imports

Move _validate_skill_frontmatter to src/skills/validation.py and
CONVERTIBLE_EXTENSIONS + convert_file_to_markdown to src/utils/file_conversion.py.
This eliminates the two reverse dependencies from client.py (harness layer)
into gateway/routers/ (app layer), preparing for the harness/app package split.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: split backend/src into harness (deerflow.*) and app (app.*)

Physically split the monolithic backend/src/ package into two layers:

- **Harness** (`packages/harness/deerflow/`): publishable agent framework
  package with import prefix `deerflow.*`. Contains agents, sandbox, tools,
  models, MCP, skills, config, and all core infrastructure.

- **App** (`app/`): unpublished application code with import prefix `app.*`.
  Contains gateway (FastAPI REST API) and channels (IM integrations).

Key changes:
- Move 13 harness modules to packages/harness/deerflow/ via git mv
- Move gateway + channels to app/ via git mv
- Rename all imports: src.* → deerflow.* (harness) / app.* (app layer)
- Set up uv workspace with deerflow-harness as workspace member
- Update langgraph.json, config.example.yaml, all scripts, Docker files
- Add build-system (hatchling) to harness pyproject.toml
- Add PYTHONPATH=. to gateway startup commands for app.* resolution
- Update ruff.toml with known-first-party for import sorting
- Update all documentation to reflect new directory structure

Boundary rule enforced: harness code never imports from app.
All 429 tests pass. Lint clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: add harness→app boundary check test and update docs

Add test_harness_boundary.py that scans all Python files in
packages/harness/deerflow/ and fails if any `from app.*` or
`import app.*` statement is found. This enforces the architectural
rule that the harness layer never depends on the app layer.

Update CLAUDE.md to document the harness/app split architecture,
import conventions, and the boundary enforcement test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add config versioning with auto-upgrade on startup

When config.example.yaml schema changes, developers' local config.yaml
files can silently become outdated. This adds a config_version field and
auto-upgrade mechanism so breaking changes (like src.* → deerflow.*
renames) are applied automatically before services start.

- Add config_version: 1 to config.example.yaml
- Add startup version check warning in AppConfig.from_file()
- Add scripts/config-upgrade.sh with migration registry for value replacements
- Add `make config-upgrade` target
- Auto-run config-upgrade in serve.sh and start-daemon.sh before starting services
- Add config error hints in service failure messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix comments

* fix: update src.* import in test_sandbox_tools_security to deerflow.*

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: handle empty config and search parent dirs for config.example.yaml

Address Copilot review comments on PR #1131:
- Guard against yaml.safe_load() returning None for empty config files
- Search parent directories for config.example.yaml instead of only
  looking next to config.yaml, fixing detection in common setups

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: correct skills root path depth and config_version type coercion

- loader.py: fix get_skills_root_path() to use 5 parent levels (was 3)
  after harness split, file lives at packages/harness/deerflow/skills/
  so parent×3 resolved to backend/packages/harness/ instead of backend/
- app_config.py: coerce config_version to int() before comparison in
  _check_config_version() to prevent TypeError when YAML stores value
  as string (e.g. config_version: "1")
- tests: add regression tests for both fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: update test imports from src.* to deerflow.*/app.* after harness refactor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:55:52 +08:00
YolenSong
9b49a80dda feat(feishu): stream updates on a single card (#1031)
* feat(feishu): stream updates on a single card

* fix(feishu): ensure final message on stream error and warn on missing card ID

- Wrap streaming loop in try/except/finally so a is_final=True outbound
  message is always published, even when the LangGraph stream breaks
  mid-way. This prevents _running_card_ids memory leaks and ensures the
  Feishu card shows a DONE reaction instead of hanging on "Working on it".
- Log a warning when _ensure_running_card gets no message_id back from
  the Feishu reply API, making silent fallback to new-card behavior
  visible in logs.
- Add test_handle_feishu_stream_error_still_sends_final to cover the
  error path.
- Reformat service.py dict comprehension (ruff format, no logic change).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Avoid blocking inbound on Feishu card creation

---------

Co-authored-by: songyaolun <songyaolun@bytedance.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-14 22:24:35 +08:00
virtaava
d18a9ae5aa feat: add LoopDetectionMiddleware to break repetitive tool call loops (#1056)
* feat: add LoopDetectionMiddleware to break repetitive tool call loops

Adds a new AgentMiddleware that detects when the agent is stuck calling
the same tools with the same arguments repeatedly, which currently runs
until the recursion limit kills the run.

Detection: per-thread sliding window of tool call hashes (name + args).
- Warn threshold (default 3): injects a "wrap up" system message
- Hard limit (default 5): strips tool_calls, forcing final text output

Includes 13 unit tests covering hashing, thresholds, window sliding,
reset, and edge cases.

Closes #1055

* fix: address PR #1056 review feedback for LoopDetectionMiddleware

- Remove unused imports (Awaitable, Callable, ModelCallResult,
  ModelRequest, ModelResponse, AIMessage) from loop_detection_middleware
- Remove unused pytest import from test file
- Fix _hash_tool_calls sort key: sort by (name, serialized args) for
  deterministic hashing when multiple calls share the same tool name
- Revert subagent_enabled default to False in agent.py to match
  DeerFlowClient and channel defaults
- Remove unrelated SearxNG tools and Next.js rewrite changes from PR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address 2nd round review feedback on PR #1056

- Inject loop warning only once per thread (prevents context bloat)
- Add threading.Lock for thread-safe history mutations
- Use runtime.context thread_id instead of workspace_path
- Add LRU eviction for per-thread history (max 100 threads)
- Add 5 new tests covering warn-once, LRU eviction, thread isolation,
  fallback thread_id, and lock presence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve lint errors in loop detection middleware tests

Sort imports (I001) and remove unused _WARNING_MSG import (F401)
to fix ruff lint failures in CI.

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-14 22:17:54 +08:00
Octopus
bbd87df6eb Add MiniMax as an OpenAI-compatible model provider (#1120)
* Add MiniMax as an OpenAI-compatible model provider

MiniMax offers high-performance LLMs (M2.5, M2.5-highspeed) with
204K context windows. This commit adds MiniMax as a selectable
provider in the configuration system.

Changes:
- Add MiniMax to SUPPORTED_MODELS with model definitions
- Add MiniMax provider configuration in conf/config.yaml
- Update documentation with MiniMax setup instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update README to remove MiniMax API details

Removed mention of MiniMax API usage and configuration examples.

---------

Co-authored-by: octo-patch <octo-patch@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-14 22:05:18 +08:00
dependabot[bot]
cc192a9846 build(deps): bump pyjwt from 2.10.1 to 2.12.0 in /backend (#1135)
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.10.1 to 2.12.0.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.10.1...2.12.0)

---
updated-dependencies:
- dependency-name: pyjwt
  dependency-version: 2.12.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-14 10:03:09 +08:00
dependabot[bot]
9983f9d296 build(deps): bump flatted from 3.3.3 to 3.4.1 in /frontend (#1134)
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.1.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.1)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-14 10:00:51 +08:00
Matt(허철진)
d197d50146 fix: preserve conversation context in Telegram private chats (#1105)
* fix: preserve conversation context in Telegram private chats

In private (1-on-1) chats, set topic_id=None so all messages map to a
single DeerFlow thread per chat instead of creating a new thread for
every message. Also fix _cmd_generic to use topic_id=None in private
chats so /new correctly targets the default thread.

Group chat behavior is unchanged (reply_to or msg_id as topic_id).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: preserve conversation context in Telegram private chats

Fixes #1101

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: mirror _on_text reply logic in _cmd_generic for group chats

_cmd_generic now prefers reply_to_message.message_id over msg_id in
group/supergroup chats, consistent with _on_text. This ensures commands
like /new and /status target the correct conversation thread when sent
as a reply in group chats.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: JeffJiang <for-eleven@hotmail.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-14 09:47:24 +08:00
dependabot[bot]
d6bfadab12 build(deps): bump orjson from 3.11.5 to 3.11.6 in /backend (#1133)
Bumps [orjson](https://github.com/ijl/orjson) from 3.11.5 to 3.11.6.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.11.5...3.11.6)

---
updated-dependencies:
- dependency-name: orjson
  dependency-version: 3.11.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com>
2026-03-13 23:03:23 +08:00
Willem Jiang
253fe4d87f feat(sandbox): harden local file access and mask host paths (#983)
* feat(sandbox): harden local file access and mask host paths

- enforce local sandbox file tools to only accept /mnt/user-data paths
- add path traversal checks against thread workspace/uploads/outputs roots
- preserve requested virtual paths in tool error messages (no host path leaks)
- mask local absolute paths in bash output back to virtual sandbox paths
- update bash tool guidance to prefer thread-local venv + python -m pip
- add regression tests for path mapping, masking, and access restrictions

Fixes #968

* feat(sandbox): restrict risky absolute paths in local bash commands

- validate absolute path usage in local-mode bash commands
- allow only /mnt/user-data virtual paths for user data access
- keep a small allowlist for system executable/device paths
- return clear permission errors for unsafe command paths
- add regression tests for bash path validation rules

* test(sandbox): add success path test for resolve_local_tool_path (#992)

* Initial plan

* test(sandbox): add success path test for resolve_local_tool_path

Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>

* fix(sandbox): reject bare virtual root early with clear error in resolve_local_tool_path (#991)

* Initial plan

* fix(sandbox): reject bare virtual root early with clear error in resolve_local_tool_path

Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-03-13 22:38:32 +08:00
Frank
918ba6b5bf docs: clarify OpenRouter configuration (#1123)
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-13 22:12:30 +08:00
Ryanba
5a8481416f fix(frontend): surface upload API error details (#1113)
Preserve backend upload/list/delete error details in the frontend API layer so users see the actual server failure instead of a generic message.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-13 21:55:33 +08:00
Willem Jiang
a79d414695 fix: make check/config cross-platform for Windows (#1080) (#1093)
* fix: make check/config cross-platform for Windows (#1080)

- replace shell-based check/config recipes with Python entrypoints
- add a cross-platform dependency checker script
- add a cross-platform config bootstrap script
- route make targets through a Python variable for consistent invocation
- preserve existing config-abort behavior when config file already exists

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-13 21:33:12 +08:00
Ryanba
b155923ab0 fix(gateway): ignore archive metadata wrappers (#1108)
* fix(gateway): ignore archive metadata wrappers

Treat top-level __MACOSX and dotfile entries as packaging metadata so valid .skill archives still resolve to their real skill directory.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-13 21:27:54 +08:00
Ryanba
cda9fb7bca fix(gateway): allow standard skill frontmatter metadata (#1103)
* fix(gateway): allow standard skill frontmatter metadata

Accept standard optional frontmatter fields during .skill installs so external skills with version, author, or compatibility metadata do not fail validation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs: sync skill installer metadata behavior

Document the skill install allowlist so user-facing and backend contributor docs match the gateway validation contract.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-13 21:23:35 +08:00
Ryanba
03cafea715 fix(gateway): normalize suggestion response content (#1098)
* fix(gateway): normalize suggestion response content

Handle list-style model content before JSON parsing so provider wrappers do not silently drop follow-up suggestions.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs: sync suggestions endpoint behavior

Document the rich-content normalization path so the README and backend gateway notes stay aligned with the current router contract.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-13 21:20:15 +08:00
Willem Jiang
b5fcb1334a fix(memory): inject stored facts into system prompt memory context (#1083)
* fix(memory): inject stored facts into system prompt memory context

- add Facts section rendering in format_memory_for_injection
- rank facts by confidence and coerce confidence values safely
- enforce max token budget while appending fact lines
- add regression tests for fact inclusion, ordering, and budget behavior

Fixes #1059

* Update the document with the latest status

* fix(memory): harden fact injection — NaN/inf confidence, None content, incremental token budget (#1090)

* Initial plan

* fix(memory): address review feedback on confidence coercion, None content, and token budget

Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: WillemJiang <219644+WillemJiang@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-03-13 14:37:40 +08:00
Liu Jice
3521cc2668 fix(middleware): degrade tool-call exceptions to error tool messages (#1110)
* fix(middleware): degrade tool-call exceptions to error tool messages

* update script

* fix(middleware): preserve LangGraph control-flow exceptions in tool error handling
2026-03-13 09:41:59 +08:00
JeffJiang
08ea9d3038 feat: enhance Docker support with production setup and deployment script (#1086)
* feat: add `make start` command for local previewing

* Update Makefile

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: update help text for `make dev` and `make start` commands

* feat: enhance Docker support with production setup and deployment script

* feat: add production commands to Makefile

* feat: remove PostgreSQL and Redis services from Docker Compose and update deploy script

* fix: address Copilot review suggestions from Docker production PR #1086 (#10)

* Initial plan

* fix: address all review suggestions from PR #1086

Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>

* Update docker/docker-compose.yaml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat: remove deprecated Dockerfile.langgraph to clean up repository

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-12 22:18:18 +08:00
JeffJiang
fdacb1c3a5 fix(chat): update navigation method to prevent state loss during thread remount (#1107) 2026-03-12 14:57:17 +08:00
Willem Jiang
e5a21b9ba0 fix(makefile):quick fix of the makefile formate error (#1085) 2026-03-11 16:00:40 +08:00
Ryanba
4bae3c724c fix(client): Harden upload validation and conversion flow (#989)
* fix(client): Harden upload validation and conversion flow

* test(client): cover event-loop upload conversion reuse

* test(client): remove unused import in upload regression coverage

* fix(client): load optional shared checkpointer fallback

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs(backend): document config preflight and IM channels

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-11 15:17:31 +08:00
Orion
a0c38a5cf3 feat: add dev-daemon target for background development mode (#1047)
* feat: add dev-daemon target for background development mode

Add a new make dev-daemon target that allows running DeerFlow services
in background mode without keeping the terminal connection.

Following the pattern of PR #1042, the implementation uses a dedicated
shell script (scripts/start-daemon.sh) for better maintainability.

- Create scripts/start-daemon.sh for daemon mode startup
- Add dev-daemon target to Makefile
- Each service writes logs to separate files (langgraph, gateway, frontend, nginx)
- Services can be stopped with make stop
- Use nohup for proper daemon process detachment
- Add cleanup on failure when services fail to start
- Use more specific pkill pattern to avoid killing unrelated nginx processes

* refactor: use wait-for-port.sh instead of hardcoded sleep in daemon script

* refactor: use specific nginx process pattern to avoid killing unrelated processes

* Revert "refactor: use specific nginx process pattern to avoid killing unrelated processes"

This reverts commit 4c369155bfc91ccce347876a8982f955fa039da8.

* refactor: use consistent nginx kill pattern across all scripts

* chore(daemon): add trap for cleanup on interrupt signals

* fix(daemon): pass repo root as positional argument to nginx command

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-03-11 15:10:40 +08:00
LofiSu
5d4fd9cf72 fix(frontend): fix new-chat navigation stale state issue (#1077)
- Use router.replace() instead of history.replaceState() so Next.js
  router's internal state is updated on chat start. This ensures
  subsequent "New Chat" clicks are treated as a real cross-route
  navigation (actual-id → "new") rather than a no-op same-path
  navigation, which was causing stale content to persist.

- In ChatLayout, increment the SubtasksProvider key only when
  navigating TO "new" from a non-"new" route. This forces a full
  remount for a fresh new-chat state without remounting when the URL
  transitions from "new" → actual-id (which would interrupt streaming).

Made-with: Cursor

Co-authored-by: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com>
2026-03-11 13:51:51 +08:00
JeffJiang
2e7964d0aa feat: add make start command for local previewing (#1078)
* feat: add `make start` command for local previewing

* Update Makefile

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update Makefile

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update scripts/check.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: update help text for `make dev` and `make start` commands

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-11 13:46:05 +08:00
Willem Jiang
06c4b0c828 chore(issue):create an issue template to provide runtime information (#1069) 2026-03-11 10:28:07 +08:00