Commit Graph

213 Commits

Author SHA1 Message Date
LoftyComet
b7f0f54aa0 feat: add citation support in research report block and markdown
* feat: add citation support in research report block and markdown

- Enhanced ResearchReportBlock to fetch citations based on researchId and pass them to the Markdown component.
- Introduced CitationLink component to display citation metadata on hover for links in markdown.
- Implemented CitationCard and CitationList components for displaying citation details and lists.
- Updated Markdown component to handle citation links and inline citations.
- Created HoverCard component for displaying citation information in a tooltip-like manner.
- Modified store to manage citations, including setting and retrieving citations for ongoing research.
- Added CitationsEvent type to handle citations in chat events and updated Message type to include citations.

* fix(log): Enable the logging level  when enabling the DEBUG environment variable (#793)

* fix(frontend): render all tool calls in the frontend #796 (#797)

* build(deps): bump jspdf from 3.0.4 to 4.0.0 in /web (#798)

Bumps [jspdf](https://github.com/parallax/jsPDF) from 3.0.4 to 4.0.0.
- [Release notes](https://github.com/parallax/jsPDF/releases)
- [Changelog](https://github.com/parallax/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/parallax/jsPDF/compare/v3.0.4...v4.0.0)

---
updated-dependencies:
- dependency-name: jspdf
  dependency-version: 4.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(frontend):added the display of the 'analyst' message #800 (#801)

* fix: migrate from deprecated create_react_agent to langchain.agents.create_agent (#802)

* fix: migrate from deprecated create_react_agent to langchain.agents.create_agent

Fixes #799

- Replace deprecated langgraph.prebuilt.create_react_agent with
  langchain.agents.create_agent (LangGraph 1.0 migration)
- Add DynamicPromptMiddleware to handle dynamic prompt templates
  (replaces the 'prompt' callable parameter)
- Add PreModelHookMiddleware to handle pre-model hooks
  (replaces the 'pre_model_hook' parameter)
- Update AgentState import from langchain.agents in template.py
- Update tests to use the new API

* fix:update the code with review comments

* fix: Add runtime parameter to compress_messages method(#803) 

* fix: Add runtime parameter to compress_messages method(#803)

    The compress_messages method was being called by PreModelHookMiddleware
    with both state and runtime parameters, but only accepted state parameter.
    This caused a TypeError when the middleware executed the pre_model_hook.

    Added optional runtime parameter to compress_messages signature to match
    the expected interface while maintaining backward compatibility.

* Update the code with the review comments

* fix: Refactor citation handling and add comprehensive tests for citation features

* refactor: Clean up imports and formatting across citation modules

* fix: Add monkeypatch to clear AGENT_RECURSION_LIMIT in recursion limit tests

* feat: Enhance citation link handling in Markdown component

* fix: Exclude citations from finish reason handling in mergeMessage function

* fix(nodes): update message handling

* fix(citations): improve citation extraction and handling in event processing

* feat(citations): enhance citation extraction and handling with improved merging and normalization

* fix(reporter): update citation formatting instructions for clarity and consistency

* fix(reporter): prioritize using Markdown tables for data presentation and comparison

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: LoftyComet <1277173875@qq。>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-24 17:49:13 +08:00
Willem Jiang
612bddd3fb feat(server): add MCP server configuration validation (#830)
* feat(server): add MCP server configuration validation

Add comprehensive validation for MCP server configurations,
inspired by Flowise's validateMCPServerConfig implementation.

MCPServerConfig checks implemented:
- Command allowlist validation (node, npx, python, docker, uvx, etc.)
- Path traversal prevention (blocks ../, absolute paths, ~/)
- Shell command injection prevention (blocks ; & | ` $ etc.)
- Dangerous environment variable blocking (PATH, LD_PRELOAD, etc.)
- URL validation for SSE/HTTP transports (scheme, credentials)
- HTTP header injection prevention (blocks newlines)

* fix the unit test error of test_chat_request

* Added the related path cases as reviewer commented

* Apply suggestions from code review

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

* 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-01-24 17:32:17 +08:00
Xun
c0849af37e feat(context): decrease token in web_search AIMessage (#827)
This PR addresses token limit issues when web_search is enabled with include_raw_content by implementing a two-pronged approach: changing the default behavior to exclude raw content and adding compression logic for when raw content is included.
2026-01-23 08:31:48 +08:00
YikB
7cd2265272 append messages to chat_streams table (#816)
* feat: Implement DeerFlow API server with chat streaming, Langgraph orchestration, and various content generation capabilities.

* Apply suggestions from code review

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

* - Use MongoDB `$push` with `$each` to append new messages to existing threads
- Use PostgreSQL jsonb concatenation operator to merge messages instead of overwriting
- Update comments to reflect append behavior in both database implementations

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-22 09:09:15 +08:00
Xun
6ec170cde5 fix: handle false values correctly in (#823)
Fixes a critical bug in the from_runnable_config() method where falsy values (like False, 0, and empty strings) were being incorrectly filtered out, causing configuration fields to revert to their default values. The fix changes the filter condition from if v to if v is not None, ensuring only None values are skipped.
2026-01-21 09:33:20 +08:00
Xun
0e64c52975 refactor: Refactors the retriever function to use async/await (#821)
* refactor: Refactors the retriever function to use async/await
2026-01-20 19:56:26 +08:00
Willem Jiang
6b73a53999 fix(config): Add support for MCP server configuration parameters (#812)
* fix(config): Add support for MCP server configuration parameters

* refact: rename the sse_readtimeout to sse_read_timeout

* update the code with review comments

* update the MCP document for the latest change
2026-01-10 15:59:49 +08:00
MirzaSamadAhmedBaig
8c59f63d1b Fix message validation JSON import (#809)
* Fix message validation JSON import

* Update src/utils/context_manager.py

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

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-09 22:38:19 +08:00
Willem Jiang
a376b0cb4e fix: Add runtime parameter to compress_messages method(#803)
* fix: Add runtime parameter to compress_messages method(#803)

    The compress_messages method was being called by PreModelHookMiddleware
    with both state and runtime parameters, but only accepted state parameter.
    This caused a TypeError when the middleware executed the pre_model_hook.

    Added optional runtime parameter to compress_messages signature to match
    the expected interface while maintaining backward compatibility.

* Update the code with the review comments
2026-01-07 20:36:15 +08:00
Willem Jiang
d4ab77de5c fix: migrate from deprecated create_react_agent to langchain.agents.create_agent (#802)
* fix: migrate from deprecated create_react_agent to langchain.agents.create_agent

Fixes #799

- Replace deprecated langgraph.prebuilt.create_react_agent with
  langchain.agents.create_agent (LangGraph 1.0 migration)
- Add DynamicPromptMiddleware to handle dynamic prompt templates
  (replaces the 'prompt' callable parameter)
- Add PreModelHookMiddleware to handle pre-model hooks
  (replaces the 'pre_model_hook' parameter)
- Update AgentState import from langchain.agents in template.py
- Update tests to use the new API

* fix:update the code with review comments
2026-01-07 09:06:16 +08:00
Willem Jiang
275aab9d42 fix(log): Enable the logging level when enabling the DEBUG environment variable (#793) 2026-01-01 09:32:42 +08:00
Willem Jiang
a71b6bc41f fix(main): Passing the local parameter from the main interactive mode (#791) 2025-12-30 10:41:29 +08:00
YMG001
893ff82a7f fix(workflow): resolve locale hardcoding in src/workflow.py for interactive mode (#789) 2025-12-30 09:47:39 +08:00
Willem Jiang
bab60e6e3d fix(podcast): add fallback for models without json_object support (#747) (#785)
* fix(podcast): add fallback for models without json_object support (#747)

Models like Kimi K2 don't support response_format.type: json_object.
Add try-except to fall back to regular prompting with JSON parsing
when BadRequestError mentions json_object not supported.

- Add fallback to prompting + repair_json_output parsing
- Re-raise other BadRequestError types
- Add unit tests for script_writer_node with 100% coverage

* Apply suggestions from code review

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

* fixes: the unit test error of test_script_writer_node.py

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-26 23:04:20 +08:00
Willem Jiang
5a79f896c4 fix(metrics): update the polynomial regular expression used on uncontrolled data (#784) 2025-12-26 10:10:12 +08:00
Willem Jiang
8d9d767051 feat(eval): add report quality evaluation module and UI integration (#776)
* feat(eval): add report quality evaluation module

Addresses issue #773 - How to evaluate generated report quality objectively.

This module provides two evaluation approaches:
1. Automated metrics (no LLM required):
   - Citation count and source diversity
   - Word count compliance per report style
   - Section structure validation
   - Image inclusion tracking

2. LLM-as-Judge evaluation:
   - Factual accuracy scoring
   - Completeness assessment
   - Coherence evaluation
   - Relevance and citation quality checks

The combined evaluator provides a final score (1-10) and letter grade (A+ to F).

Files added:
- src/eval/__init__.py
- src/eval/metrics.py
- src/eval/llm_judge.py
- src/eval/evaluator.py
- tests/unit/eval/test_metrics.py
- tests/unit/eval/test_evaluator.py

* feat(eval): integrate report evaluation with web UI

This commit adds the web UI integration for the evaluation module:

Backend:
- Add EvaluateReportRequest/Response models in src/server/eval_request.py
- Add /api/report/evaluate endpoint to src/server/app.py

Frontend:
- Add evaluateReport API function in web/src/core/api/evaluate.ts
- Create EvaluationDialog component with grade badge, metrics display,
  and optional LLM deep evaluation
- Add evaluation button (graduation cap icon) to research-block.tsx toolbar
- Add i18n translations for English and Chinese

The evaluation UI allows users to:
1. View quick metrics-only evaluation (instant)
2. Optionally run deep LLM-based evaluation for detailed analysis
3. See grade (A+ to F), score (1-10), and metric breakdown

* feat(eval): improve evaluation reliability and add LLM judge tests

- Extract MAX_REPORT_LENGTH constant in llm_judge.py for maintainability
- Add comprehensive unit tests for LLMJudge class (parse_response,
  calculate_weighted_score, evaluate with mocked LLM)
- Pass reportStyle prop to EvaluationDialog for accurate evaluation criteria
- Add researchQueries store map to reliably associate queries with research
- Add getResearchQuery helper to retrieve query by researchId
- Remove unused imports in test_metrics.py

* fix(eval): use resolveServiceURL for evaluate API endpoint

The evaluateReport function was using a relative URL '/api/report/evaluate'
which sent requests to the Next.js server instead of the FastAPI backend.
Changed to use resolveServiceURL() consistent with other API functions.

* fix: improve type accuracy and React hooks in evaluation components

- Fix get_word_count_target return type from Optional[Dict] to Dict since it always returns a value via default fallback
- Fix useEffect dependency issue in EvaluationDialog using useRef to prevent unwanted re-evaluations
- Add aria-label to GradeBadge for screen reader accessibility
2025-12-25 21:55:48 +08:00
geniusroad
84a7f7815c refactor(graph): Refactor tool loading logic within nodes (#782)
* refactor(graph): Optimize tool loading logic within nodes

- Pre-copy the default tool list during initialization
- Merge MCP server configuration with default tool handling
- Simplify conditional branches and unify agent creation logic
- Remove duplicated agent creation code blocks

* Apply suggestions from code review

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

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-25 21:10:04 +08:00
Willem Jiang
fb319aaa44 test: add unit tests for global connection pool (Issue #778) (#780)
* test: add unit tests for global connection pool (Issue #778)

- Add TestLifespanFunction class with 9 tests for lifespan management:
  - PostgreSQL/MongoDB pool initialization success/failure
  - Cleanup on shutdown
  - Skip initialization when not configured

- Add TestGlobalConnectionPoolUsage class with 4 tests:
  - Using global pools when available
  - Fallback to per-request connections

- Fix missing dict_row import in app.py (bug from PR #757)

* 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>
2025-12-23 23:06:39 +08:00
YikB
83e9d7c9e5 feat:Database connections use connection pools (#757)
* feat: Implement DeerFlow API server with chat streaming, Langgraph orchestration, and various content generation capabilities.

* Apply suggestions from code review

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

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-23 20:35:08 +08:00
Willem Jiang
04296cdf5a feat: add resource upload support for RAG (#768)
* feat: add resource upload support for RAG

- Backend: Added ingest_file method to Retriever and MilvusRetriever
- Backend: Added /api/rag/upload endpoint
- Frontend: Added RAGTab in settings for uploading resources
- Frontend: Updated translations and settings registration

* Apply suggestions from code review

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

* Apply suggestions from code review

* Apply suggestions from code review of src/rag/milvus.py

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-19 09:55:34 +08:00
Willem Jiang
2a97170b6c feat: add Serper search engine support (#762)
* 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
2025-12-15 23:04:26 +08:00
Jiahe Wu
93d81d450d feat: add enable_web_search config to disable web search (#681) (#760)
* 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
2025-12-15 19:17:24 +08:00
Jiahe Wu
c686ab7016 fix: handle greetings without triggering research workflow (#755)
* 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>
2025-12-13 20:25:46 +08:00
Willem Jiang
ec99338c9a fix(agents): patch _run in ToolInterceptor to ensure interrupt triggering (#753)
Fixes #752

* fix(agents): patch _run in ToolInterceptor to ensure interrupt triggering

* Update the code with review comments
2025-12-10 22:15:08 +08:00
Willem Jiang
84c449cf79 fix(checkpoint): clear in-memory store after successful persistence (#751)
* fix(checkpoint): clear in-memory store after successful persistence

* test(checkpoint): add unit test for memory leak check

* Update tests/unit/checkpoint/test_memory_leak.py

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-09 23:32:13 +08:00
Willem Jiang
3bf4e1defb fix: setup WindowsSelectorEventLoopPolicy in the first place #741 (#742)
* fix: setup WindowsSelectorEventLoopPolicy in the first place #741

* 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>
Co-authored-by: Willem Jiang <143703838+willem-bd@users.noreply.github.com>
2025-12-06 22:10:13 +08:00
Willem Jiang
3191e81939 fix: passing the locale to create_react_agent (#745) 2025-12-06 11:15:11 +08:00
zhangga
bd6c50de33 feat:Strip code blocks in plan data. (#738)
* feat:Strip code blocks in plan data.

* feat: add repair_json_output for current_plan_content

---------

Co-authored-by: ryan-gz <ryzhangga1991@gmail.com>
2025-12-04 23:04:29 +08:00
Willem Jiang
c36ab393f1 fix: update Interrupt object attribute access for LangGraph 1.0+ (#730) (#731)
* 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>
2025-12-02 11:16:00 +08:00
Willem Jiang
e1772d52a9 Clear-text logging of sensitive information (#732) 2025-12-02 09:58:28 +08:00
infoquest-byteplus
7ec9e45702 feat: support infoquest (#708)
* 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>
2025-12-02 08:16:35 +08:00
Willem Jiang
4a78cfe12a fix(llm): filter unexpected config keys to prevent LangChain warnings (#411) (#726)
* 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>
2025-11-29 16:13:05 +08:00
Willem Jiang
2e010a4619 feat: add analysis step type for non-code reasoning tasks (#677) (#723)
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>
2025-11-29 09:46:55 +08:00
Willem Jiang
170c4eb33c Upgrade langchain version to 1.x (#720)
* 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>
2025-11-28 22:09:13 +08:00
Willem Jiang
b24f4d3f38 fix: apply context compression to prevent token overflow (Issue #721) (#722)
* 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
2025-11-28 18:52:42 +08:00
Willem Jiang
223ec57fe4 fix: the frontend error when cancle the research plan (#719)
Co-authored-by: Willem Jiang <143703838+willem-bd@users.noreply.github.com>
2025-11-28 08:35:42 +08:00
Willem Jiang
4559197505 fix: revert the part of patch of issue-710 to extract the content from the plan (#718) 2025-11-27 23:59:31 +08:00
Willem Jiang
ca4ada5aa7 fix: multiple web_search ToolMessages only showing last result (#717)
* 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
2025-11-27 21:47:08 +08:00
Willem Jiang
667916959b fix: the exception of plan validation (#714)
* fix: Missing Required Fields in Plan Validation

* fix: the exception of plan validation

* Fixed the test errors

* Addressed the comments of the PR reviews
2025-11-27 19:39:25 +08:00
Willem Jiang
bec97f02ae fix: the crawling error when encountering PDF URLs (#707)
* 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
2025-11-25 09:24:52 +08:00
Willem Jiang
da514337da fix: the validation Error with qwen-max-latest Model (#706)
* 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
2025-11-24 21:13:15 +08:00
Willem Jiang
478291df07 fix: ensure researcher agent uses web search tool instead of generating URLs (#702) (#704)
* 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
2025-11-24 20:07:28 +08:00
pizzahan
1bfcf9f429 feat: enable ppt_composer.zh_CN.md with request.locale (#694)
* feat: enable ppt_composer.zh_CN.md with request.locale

* fix: GeneratePPTRequest miss locale field

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2025-11-22 16:56:18 +08:00
Zts0hg
2d1a0997eb feat: be compatible with case: json_object is not supported by used model (#673)
* 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>
2025-11-21 09:41:34 +08:00
Anush
aa027faf95 feat: Qdrant Vector Search Support (#684)
* feat: Qdrant vector search support

Signed-off-by: Anush008 <anushshetty90@gmail.com>

* chore: Review updates

Signed-off-by: Anush008 <anushshetty90@gmail.com>

---------

Signed-off-by: Anush008 <anushshetty90@gmail.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2025-11-11 19:35:00 +08:00
Willem Jiang
6ae4bc588a fix: remove the unnessary conditional edge. (#671) 2025-10-29 10:12:32 +08:00
Willem Jiang
0415f622da fix: presever the local setting between frontend and backend (#670)
* 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
2025-10-28 21:45:29 +08:00
Willem Jiang
b4c09aa4b1 security: add log injection attack prevention with input sanitization (#667)
* 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.
2025-10-27 20:57:23 +08:00
Willem Jiang
83f1334db0 feat: add comprehensive debug logging for issue #477 hanging/freezing diagnosis (#662)
* feat: add comprehensive debug logging for issue #477 hanging/freezing diagnosis
- Add debug logging to src/server/app.py for event streaming and message chunk processing
- Track graph event flow with thread IDs for correlation
- Add detailed logging in interrupt event processing
- Add debug logging to src/agents/tool_interceptor.py for tool execution and interrupt handling
- Log interrupt decision flow and user feedback processing
- Add debug logging to src/graph/nodes.py for agent node execution
- Track step execution progress and agent coordination in research_team_node
- Add debug logging to src/agents/agents.py for agent creation and tool wrapping
- Update server.py to enable debug logging when --log-level debug is specified
- Add thread ID correlation throughout for better diagnostics
- Helps diagnose hanging/freezing issues during workflow execution

* 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>
2025-10-27 08:21:30 +08:00
Willem Jiang
bcc403ecd3 feat: implement tool-specific interrupts for create_react_agent (#572) (#659)
* feat: implement tool-specific interrupts for create_react_agent (#572)

          Add selective tool interrupt capability allowing interrupts before specific tools
          rather than all tools. Users can now configure which tools trigger interrupts via
          the interrupt_before_tools parameter.

          Changes:
          - Create ToolInterceptor class to handle tool-specific interrupt logic
          - Add interrupt_before_tools parameter to create_agent() function
          - Extend Configuration with interrupt_before_tools field
          - Add interrupt_before_tools to ChatRequest API
          - Update nodes.py to pass interrupt configuration to agents
          - Update app.py workflow to support tool interrupt configuration
          - Add comprehensive unit tests for tool interceptor

          Features:
          - Selective tool interrupts: interrupt only specific tools by name
          - Approval keywords: recognize user approval (approved, proceed, accept, etc.)
          - Backward compatible: optional parameter, existing code unaffected
          - Flexible: works with default tools and MCP-powered tools
          - Works with existing resume mechanism for seamless workflow

          Example usage:
            request = ChatRequest(
              messages=[...],
              interrupt_before_tools=['db_tool', 'sensitive_api']
            )

* test: add comprehensive integration tests for tool-specific interrupts (#572)

Add 24 integration tests covering all aspects of the tool interceptor feature:

Test Coverage:
- Agent creation with tool interrupts
- Configuration support (with/without interrupts)
- ChatRequest API integration
- Multiple tools with selective interrupts
- User approval/rejection flows
- Tool wrapping and functionality preservation
- Error handling and edge cases
- Approval keyword recognition
- Complex tool inputs
- Logging and monitoring

All tests pass with 100% coverage of tool interceptor functionality.

Tests verify:
✓ Selective tool interrupts work correctly
✓ Only specified tools trigger interrupts
✓ Non-matching tools execute normally
✓ User feedback is properly parsed
✓ Tool functionality is preserved after wrapping
✓ Error handling works as expected
✓ Configuration options are properly respected
✓ Logging provides useful debugging info

* fix: mock get_llm_by_type in agent creation test

Fix test_agent_creation_with_tool_interrupts which was failing because
get_llm_by_type() was being called before create_react_agent was mocked.

Changes:
- Add mock for get_llm_by_type in test
- Use context manager composition for multiple patches
- Test now passes and validates tool wrapping correctly

All 24 integration tests now pass successfully.

* refactor: use mock assertion methods for consistent and clearer error messages

Update integration tests to use mock assertion methods instead of direct
attribute checking for consistency and clearer error messages:

Changes:
- Replace 'assert mock_interrupt.called' with 'mock_interrupt.assert_called()'
- Replace 'assert not mock_interrupt.called' with 'mock_interrupt.assert_not_called()'

Benefits:
- Consistent with pytest-mock and unittest.mock best practices
- Clearer error messages when assertions fail
- Better IDE autocompletion support
- More professional test code

All 42 tests pass with improved assertion patterns.

* refactor: use default_factory for interrupt_before_tools consistency

Improve consistency between ChatRequest and Configuration implementations:

Changes:
- ChatRequest.interrupt_before_tools: Use Field(default_factory=list) instead of Optional[None]
- Remove unnecessary 'or []' conversion in app.py line 505
- Aligns with Configuration.interrupt_before_tools implementation pattern
- No functional changes - all tests still pass

Benefits:
- Consistent field definition across codebase
- Simpler and cleaner code
- Reduced chance of None/empty list bugs
- Better alignment with Pydantic best practices

All 42 tests passing.

* refactor: improve tool input formatting in interrupt messages

Enhance tool input representation for better readability in interrupt messages:

Changes:
- Add json import for better formatting
- Create _format_tool_input() static method with JSON serialization
- Use JSON formatting for dicts, lists, tuples with indent=2
- Fall back to str() for non-serializable types
- Handle None input specially (returns 'No input')
- Improve interrupt message formatting with better spacing

Benefits:
- Complex tool inputs now display as readable JSON
- Nested structures are properly indented and visible
- Better user experience when reviewing tool inputs before approval
- Handles edge cases gracefully with fallbacks
- Improved logging output for debugging

Example improvements:
Before: {'query': 'SELECT...', 'limit': 10, 'nested': {'key': 'value'}}
After:
{
  "query": "SELECT...",
  "limit": 10,
  "nested": {
    "key": "value"
  }
}

All 42 tests still passing.

* test: add comprehensive unit tests for tool input formatting
2025-10-26 09:47:03 +08:00