openjiuwen_deepsearch.framework.openjiuwen.agent.main_graph_nodes
Main-graph and key subgraph nodes (aligned with current code).
Main graph nodes
StartNode
class StartNode(Start)
Workflow entry: validate/default inputs, init SearchContext (query, session_id, messages, search_mode, report_template), merge agent_config + service_config into runtime config, set thread_id and interrupt_feedback.
EntryNode
class EntryNode(BaseNode)
Language detection/routing via classify_query, normalize locale (zh-CN / en-US); on failure set final_result.exception_info and stop.
GenerateQuestionsNode
class GenerateQuestionsNode(BaseNode)
HITL clarifying questions via query_interpreter with workflow_max_gen_question_retry_num retries; success → search_context.questions; failure → exception_info.
FeedbackHandlerNode
class FeedbackHandlerNode(BaseNode)
Reads user feedback (workflow_feedback_mode cmd/web); FINISH_TASK ends run; invalid input → exception_info.
OutlineNode
class OutlineNode(BaseNode)
Outline generation: report_template present uses outliner_template prompt else outliner; retries via outliner_max_generate_outline_retry_num; streams outline to search_context.current_outline.
DependencyOutlineNode
class DependencyOutlineNode(OutlineNode)
Dependency-aware outline via dep_driving_outliner; same retry/stream behavior as OutlineNode.
OutlineInteractionNode
class OutlineInteractionNode(BaseNode)
Outline HITL: if outline_interaction_enabled is off → EditorTeamNode; if rounds ≥ outline_interaction_max_rounds → notify and continue; reads feedback (cmd/web) as JSON:
{
"interrupt_feedback": "accepted/revise_comment/revise_outline",
"feedback": "User text: comments for revise_comment, or new outline for revise_outline"
}
Actions: accepted → EditorTeamNode; revise_comment / revise_outline → OutlineNode; history in search_context.outline_interactions.
DependencyOutlineInteractionNode
class DependencyOutlineInteractionNode(OutlineInteractionNode)
Same as parent; on accepted routes to DependencyEditorTeamNode instead of EditorTeamNode.
EditorTeamNode
class EditorTeamNode(BaseNode)
(editor_team_manager_node.py) Runs concurrent sub-workflows and forwards streamed subgraph output.
DependencyEditorTeamNode
class DependencyEditorTeamNode(EditorTeamNode)
Dependency-layer pipeline: per layer, parallelize previous-layer writing with current-layer reasoning; merges subgraph streams.
ReporterNode
class ReporterNode(BaseNode)
Final report via Reporter.generate_report; failures → exception_info; success → search_context.report and all_classified_contents.
VLMChartGeneratorNode
class VLMChartGeneratorNode(BaseNode)
VLMChartGeneratorNode handles VLM iterative chart generation.
Functions:
- If
vlm_chart_generator_enableis disabled, skip this node. - If
vlm_chart_generator_enableis enabled:- If
vlm_chart_generator_max_iterationsequals 0, only execute VLM chart generation process without VLM iterative optimization. - If
vlm_chart_generator_max_iterationsis greater than 0, VLM model configuration must be provided; otherwise the system disables this module and skips it.
- If
- The system selects chart insertion positions, generates charts, and performs corresponding chart optimization.
- Writes to
final_result.chart_messages. - Chart generation errors are written to
exception_info.
SourceTracerNode
class SourceTracerNode(BaseNode)
SourceTracerNode handles provenance tracing and verification.
Functions:
- Skip when
source_tracer_research_trace_source_switchis disabled. - Run citation verification after preprocessing and generate citation information.
- Write results into
final_result.response_contentandcitation_messages. - Insert stable
[checked_citation:id]markers into the report body and return matching citation metadata, so the frontend can render and continue interaction based on the latestfinal_result. - Write failures into
exception_info.
UserFeedbackProcessorNode
class UserFeedbackProcessorNode(BaseNode)
UserFeedbackProcessorNode handles iterative local rewrite requests after report generation is complete.
Functions:
- Decide whether to enable post-report local editing based on
user_feedback_processor_enable. - On first entry, send a full
final_resultsnapshot to the frontend and usesearch_context.feedback_snapshot_sentto ensure it is sent only once. - Read JSON user feedback and support
expand,shorten,polish,supplementary_search,new_task,sync, andfinish. - Parse and validate rewrite payload fields such as
action,rewrite_scope,selected_text, and offsets. - Support both
selected_onlyandselected_and_relatedas rewrite scopes forsupplementary_search. - Return a lightweight ack for
sync, without consumingfeedback_interaction_count; successful sync appends a rewrite-history record only when the full report content actually changes. - Call
UserFeedbackProcessorto complete the local rewrite and update onlyfinal_result.response_content. - For normal rewrite and
supplementary_searchactions, maintainsearch_context.feedback_interaction_countandsearch_context.rewrite_history, including action type, rewrite scope, and actual replacement range. - Keep the existing citation / infer metadata unchanged during the rewrite path, without maintaining extra frontend offset mappings.
- Keep only the latest 10
synchistory records; unchangedsyncrequests do not create history records. - Apply
user_feedback_processor_max_interactionsonly to non-syncactions; end the flow after receivingfinish.
SourceTracerInferNode
class SourceTracerInferNode(BaseNode):
Skips if source_tracer_infer_switch is off; builds provenance reasoning artifacts → final_result.infer_messages; failures → exception_info.
EndNode
class EndNode(End)
Emits final_result JSON and "ALL END".
Editor-team subgraph (reasoning_writing_graph/editor_team_nodes.py)
SectionStartNode → ResearchPlanReasoningNode → (InfoCollectorNode → ResearchPlanReasoningNode)* → SubReporterNode → SubSourceTracerNode → SectionEndNode.
Collector subgraph (collector_graph/)
StartNode → GenerateQueryNode → InfoRetrievalNode → SupervisorNode → (loop)* → SummaryNode → GraphEndNode → End.
Dependency reasoning subgraph (dependency_reasoning_team_nodes.py)
SectionReasoningStartNode → DependencyPlanReasoningNode → (DependencyInfoCollectorNode → DependencyPlanReasoningNode)* → SectionReasoningEndNode.
Dependency writing subgraph (dependency_writing_team_nodes.py)
SectionWritingStartNode → SubReporterNode → SubSourceTracerNode → SectionEndNode.
Execution sketches
Parallel main graph
StartNode -> EntryNode -> [GenerateQuestionsNode -> FeedbackHandlerNode] -> OutlineNode
-> [OutlineInteractionNode -> OutlineNode]* -> EditorTeamNode -> ReporterNode -> SourceTracerNode -> EndNode
-> SourceTracerInferNode -> UserFeedbackProcessorNode -> EndNode
Dependency-driven main graph
StartNode -> EntryNode -> [GenerateQuestionsNode -> FeedbackHandlerNode] -> DependencyOutlineNode
-> [DependencyOutlineInteractionNode -> DependencyOutlineNode]*
-> DependencyEditorTeamNode -> ReporterNode -> SourceTracerNode
-> SourceTracerInferNode -> UserFeedbackProcessorNode -> EndNode
DependencyEditorTeamNode pipelines dependency layers (“previous writing + current reasoning” in parallel per layer).
Editor-team subgraph
SectionStartNode -> ResearchPlanReasoningNode -> [InfoCollectorNode -> ResearchPlanReasoningNode]*
-> SubReporterNode -> SubSourceTracerNode -> SectionEndNode
Collector subgraph
StartNode -> GenerateQueryNode -> InfoRetrievalNode -> SupervisorNode
-> [InfoRetrievalNode -> SupervisorNode]* -> SummaryNode -> GraphEndNode -> End
Dependency reasoning subgraph
SectionReasoningStartNode -> DependencyPlanReasoningNode -> [DependencyInfoCollectorNode -> DependencyPlanReasoningNode]*
-> SectionReasoningEndNode
Dependency writing subgraph
SectionWritingStartNode -> SubReporterNode -> SubSourceTracerNode -> SectionEndNode