Extract message content from direct_response tool call args
and display it as the message content when tool call completes.
Note: This is a workaround. The message is not streamed because
direct_response uses tool calling mechanism where args are JSON,
not natural language text that can be streamed directly.
* feat(web): add multi-format report export (Markdown, HTML, PDF, Word, Image)
* fix: correct import order for docx (lint error)
* fix(web): address Copilot review comments for multi-format export
- Add i18n support for dropdown menu items (en/zh)
- Add DOMPurify for HTML sanitization (XSS protection)
- Fix async handling for canvas.toBlob with Promise wrapper
- Add toast notifications for export errors
- Fix Tooltip + DropdownMenuTrigger nesting (accessibility)
- Ensure container cleanup in finally block
* fix(web): enhance markdown parsing for PDF and Word export
- Add list support (bullet and numbered) for PDF export
- Add parseInlineMarkdown helper for Word export to handle bold, italic, code, links
- Add list support for Word export (bullet and numbered)
- Address Copilot review comments from PR #756
* fix(web): address PR review feedback for multi-format export
- Extract PDF formatting magic numbers into PDF_CONSTANTS
- Add Tooltip wrapper for download dropdown button
- Reduce triggerDownload cleanup timeout from 1000ms to 100ms
- Use marked.Lexer.lexInline for robust markdown parsing
- Add console.warn for image export cleanup errors
- Add numbering config for Word document ordered lists
- Fix CSS class typo: px-5pb-20 -> px-5 pb-20
- Remove unreachable dead code in parseInlineMarkdown
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* feat: add Serper search engine support
* docs: update configuration guide and env example for Serper
* test: add test case for Serper with missing API key
* feat: add enable_web_search config to disable web search (#681)
* fix: skip enforce_researcher_search validation when web search is disabled
- Return json.dumps([]) instead of empty string for consistency in background_investigation_node
- Add enable_web_search check to skip validation warning when user intentionally disabled web search
- Add warning log when researcher has no tools available
- Update tests to include new enable_web_search parameter
* fix: address Copilot review feedback
- Coordinate enforce_web_search with enable_web_search in validate_and_fix_plan
- Fix misleading comment in background_investigation_node
* docs: add warning about local RAG setup when disabling web search
* docs: add web search toggle section to configuration guide
* fix: handle greetings without triggering research workflow (#733)
* test: update tests for direct_response tool behavior
* fix: address Copilot review comments for coordinator_node - Extract locale from direct_response tool_args - Fix import sorting (ruff I001)
* fix: remove locale extraction from tool_args in direct_response
Use locale from state instead of tool_args to avoid potential side effects. The locale is already properly passed from frontend via state.
* fix: only fallback to planner when clarification is enabled
In legacy mode (BRANCH 1), no tool calls should end the workflow gracefully instead of falling back to planner. This fixes the test_coordinator_node_no_tool_calls integration test.
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* Update uv.lock to sync with pyproject.toml
* fix: update Interrupt object attribute access for LangGraph 1.0+ (#730)
The Interrupt class in LangGraph 1.0 no longer has the 'ns' attribute.
This change updates _create_interrupt_event() to use the new 'id'
attribute instead, with a fallback to thread_id for compatibility.
Changes:
- Replace event_data["__interrupt__"][0].ns[0] with interrupt.id
- Use getattr() with fallback for backward compatibility
- Update debug log message from 'ns=' to 'id='
- Add unit tests for _create_interrupt_event function
* fix the unit test error and address review comment
---------
Co-authored-by: Willem Jiang <143703838+willem-bd@users.noreply.github.com>
* support infoquest
* support html checker
* support html checker
* change line break format
* change line break format
* change line break format
* change line break format
* change line break format
* change line break format
* change line break format
* change line break format
* Fix several critical issues in the codebase
- Resolve crawler panic by improving error handling
- Fix plan validation to prevent invalid configurations
- Correct InfoQuest crawler JSON conversion logic
* add test for infoquest
* add test for infoquest
* Add InfoQuest introduction to the README
* add test for infoquest
* fix readme for infoquest
* fix readme for infoquest
* resolve the conflict
* resolve the conflict
* resolve the conflict
* Fix formatting of INFOQUEST in SearchEngine enum
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Willem Jiang <143703838+willem-bd@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(web): handle incomplete JSON in MCP tool call arguments (#528)
When using stream_mode=["messages", "updates"] with MCP tools, tool call
arguments arrive in chunks that may be incomplete JSON (missing closing
braces). This caused JSON.parse() to throw errors in the frontend.
Changes:
- Add safeParseToolArgs() function using best-effort-json-parser to
gracefully handle incomplete JSON from streaming
- Replace direct JSON.parse() with safe parser in mergeMessage()
- Add comprehensive tests for tool call argument parsing scenarios
* Address the code review comments
* fix(llm): filter unexpected config keys to prevent LangChain warnings (#411)
Add allowlist validation for LLM configuration keys to prevent unexpected
parameters like SEARCH_ENGINE from being passed to LLM constructors.
Changes:
- Add ALLOWED_LLM_CONFIG_KEYS set with valid LLM configuration parameters
- Filter out unexpected keys before creating LLM instances
- Log clear warning messages when unexpected keys are removed
- Add unit test for configuration key filtering
This fixes the confusing LangChain warning "WARNING! SEARCH_ENGINE is not
default parameter. SEARCH_ENGINE was transferred to model_kwargs" that
occurred when users accidentally placed configuration keys in wrong sections
of conf.yaml.
* 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>
Add a new "analysis" step type to handle reasoning and synthesis tasks
that don't require code execution, addressing the concern that routing
all non-search tasks to the coder agent was inappropriate.
Changes:
- Add ANALYSIS enum value to StepType in planner_model.py
- Create analyst_node for pure LLM reasoning without tools
- Update graph routing to route analysis steps to analyst agent
- Add analyst agent to AGENT_LLM_MAP configuration
- Create analyst prompts (English and Chinese)
- Update planner prompts with guidance on choosing between
analysis (reasoning/synthesis) and processing (code execution)
- Change default step_type inference from "processing" to "analysis"
when need_search=false
Co-authored-by: Willem Jiang <143703838+willem-bd@users.noreply.github.com>
* fix: revert the part of patch of issue-710 to extract the content from the plan
* Upgrade the ddgs for the new compatible version
* Upgraded langchain to 1.1.0
updated langchain related package to the new compatable version
* Update pyproject.toml
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: apply context compression to prevent token overflow (Issue #721)
- Add token_limit configuration to conf.yaml.example for BASIC_MODEL and REASONING_MODEL
- Implement context compression in _execute_agent_step() before agent invocation
- Preserve first 3 messages (system prompt + context) during compression
- Enhance ContextManager logging with better token count reporting
- Prevent 400 Input tokens exceeded errors by automatically compressing message history
* feat: add model-based token limit inference for Issue #721
- Add smart default token limits based on common LLM models
- Support model name inference when token_limit not explicitly configured
- Models include: OpenAI (GPT-4o, GPT-4, etc.), Claude, Gemini, Doubao, DeepSeek, etc.
- Conservative defaults prevent token overflow even without explicit configuration
- Priority: explicit config > model inference > safe default (100,000 tokens)
- Ensures Issue #721 protection for all users, not just those with token_limit set
* fix: Missing Required Fields in Plan Validation
* fix: the exception of plan validation
* Fixed the test errors
* Addressed the comments of the PR reviews
* fix: multiple web_search ToolMessages only showing last result
* fix: Missing Required Fields in Plan Validation
* fix: the exception of plan validation
* Fixed the test errors
* Addressed the comments of the PR reviews
* fix: the crawling error when encountering PDF URLs
* Added the unit test for the new feature of crawl tool
* fix: address the code review problems
* fix: address the code review problems
* fix: the validation Error with qwen-max-latest Model
- Added comprehensive unit tests in tests/unit/graph/test_nodes.py for the new extract_plan_content function
- Tests cover various input types: string, AIMessage, dictionary, other types
- Includes a specific test case for issue #703 with the qwen-max-latest model
- All tests pass successfully, confirming the function handles different input types correctly
* feat: address the code review concerns
* fix: ensure researcher agent uses web search tool instead of generating URLs (#702)
- Add enforce_researcher_search configuration option (default: True) to control web search requirement
- Strengthen researcher prompts in both English and Chinese with explicit instructions to use web_search tool
- Implement validate_web_search_usage function to detect if web search tool was used during research
- Add validation logic that warns when researcher doesn't use web search tool
- Enhance logging for web search tools with special markers for easy tracking
- Skip validation during unit tests to avoid test failures
- Update _execute_agent_step to accept config parameter for proper configuration access
This addresses issue #702 where the researcher agent was generating URLs on its own instead of using the web search tool.
* fix: addressed the code review comment
* fix the unit test error and update the code
* feat: enable ppt_composer.zh_CN.md with request.locale
* fix: GeneratePPTRequest miss locale field
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* feat: 兼容使用的模型不支持json结构化输出的情况
* fix: add explicit validation that the response content is valid JSON before proceeding to parse it
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* refactor: Welcome layout and conditional rendering
Improves flex layout and spacing in ConversationStarter, and updates MessagesBlock to conditionally render ConversationStarter or MessageListView based on chat state. This streamlines the UI and removes redundant rendering logic.
* fix: replay mode
* fix: Remove unnecessary inset-0
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit addresses issue #682 by providing clear documentation on how to view complete model output and debug DeerFlow workflows.
Changes:
- Add new DEBUGGING.md guide with detailed instructions for:
- Viewing complete model output
- Enabling debug logging
- Configuring LangChain verbose logging
- Setting up LangSmith tracing
- Docker Compose debugging tips
- Common troubleshooting scenarios
- Update .env.example with:
- Clearer comments for DEBUG setting
- Documentation for LANGCHAIN_VERBOSE and LANGCHAIN_DEBUG options
- Improved LangSmith configuration guidance
- Enhance docs/FAQ.md with:
- How to view complete model output
- How to enable debug logging
- How to troubleshoot common issues
- Links to the new debugging guide
These documentation improvements make it easier for users to:
- Debug workflow issues
- View LLM prompts and responses
- Troubleshoot deployment problems
- Monitor performance with LangSmith
Fixes#682
* feat: add edit and refresh functionality for MCP servers in settings tab
* feat: fix lint error and enhance MCP server dialog with validation and error handling
* fix: add missing newline at the end of en.json file
* feat: only refreshing specific servers
* feat: add validation messages for MCP server configuration and improve server update logic
Add defensive checks before removeChild to prevent 'Failed to execute removeChild' error when the element has already been removed from DOM. Wrap URL.revokeObjectURL in finally block to ensure proper resource cleanup.
* fix: presever the local setting between frontend and backend
* Added unit test for the state preservation
* fix: passing the locale to the agent call
* fix: apply the fix after code review
* security: add log injection attack prevention with input sanitization
- Created src/utils/log_sanitizer.py to sanitize user-controlled input before logging
- Prevents log injection attacks using newlines, tabs, carriage returns, etc.
- Escapes dangerous characters: \n, \r, \t, \0, \x1b
- Provides specialized functions for different input types:
- sanitize_log_input: general purpose sanitization
- sanitize_thread_id: for user-provided thread IDs
- sanitize_user_content: for user messages (more aggressive truncation)
- sanitize_agent_name: for agent identifiers
- sanitize_tool_name: for tool names
- sanitize_feedback: for user interrupt feedback
- create_safe_log_message: template-based safe message creation
- Updated src/server/app.py to sanitize all user input in logging:
- Thread IDs from request parameter
- Message content from user
- Agent names and node information
- Tool names and feedback
- Updated src/agents/tool_interceptor.py to sanitize:
- Tool names during execution
- User feedback during interrupt handling
- Tool input data
- Added 29 comprehensive unit tests covering:
- Classic newline injection attacks
- Carriage return injection
- Tab and null character injection
- HTML/ANSI escape sequence injection
- Combined multi-character attacks
- Truncation and length limits
Fixes potential log forgery vulnerability where malicious users could inject
fake log entries via unsanitized input containing control characters.
* fix: make SSE buffer size configurable to prevent overflow during multi-round searches (Issue #664)
- Add NEXT_PUBLIC_MAX_STREAM_BUFFER_SIZE environment variable for frontend SSE stream buffer
- Default to 1MB for backward compatibility, users can increase to 5-10MB for large searches
- Enhance error message with actual buffer sizes and guidance on configuration
- Add validation schema in env.js with positive integer requirement
- Document configuration in .env.example with clear examples and use cases
* 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>
- Add unescape for \{ and \} characters in unescapeMarkdownSpecialChars()
- These are commonly used in LaTeX commands like \mathcal{F}
- Add test cases for Fourier transform notation and mixed escape scenarios
- All 118 tests pass including 4 new edge case tests for issue #608