99
1010from application .flow .i_step_node import NodeResult , INode
1111from application .flow .step_node .video_understand_step_node .i_video_understand_node import IVideoUnderstandNode
12+ from application .flow .tools import Reasoning
1213from knowledge .models import File
1314from models_provider .tools import get_model_instance_by_model_workspace_id
1415
1516
16- def _write_context (node_variable : Dict , workflow_variable : Dict , node : INode , workflow , answer : str ):
17+ def _write_context (node_variable : Dict , workflow_variable : Dict , node : INode , workflow , answer : str ,
18+ reasoning_content : str ):
1719 chat_model = node_variable .get ('chat_model' )
1820 message_tokens = node_variable ['usage_metadata' ]['output_tokens' ] if 'usage_metadata' in node_variable else 0
1921 answer_tokens = chat_model .get_num_tokens (answer )
@@ -23,6 +25,7 @@ def _write_context(node_variable: Dict, workflow_variable: Dict, node: INode, wo
2325 node .context ['history_message' ] = node_variable ['history_message' ]
2426 node .context ['question' ] = node_variable ['question' ]
2527 node .context ['run_time' ] = time .time () - node .context ['start_time' ]
28+ node .context ['reasoning_content' ] = reasoning_content
2629 if workflow .is_result (node , NodeResult (node_variable , workflow_variable )):
2730 node .answer_text = answer
2831
@@ -37,10 +40,55 @@ def write_context_stream(node_variable: Dict, workflow_variable: Dict, node: INo
3740 """
3841 response = node_variable .get ('result' )
3942 answer = ''
43+ reasoning_content = ''
44+ model_setting = node .context .get ('model_setting' ,
45+ {'reasoning_content_enable' : False , 'reasoning_content_end' : '</think>' ,
46+ 'reasoning_content_start' : '<think>' })
47+ reasoning = Reasoning (model_setting .get ('reasoning_content_start' , '<think>' ),
48+ model_setting .get ('reasoning_content_end' , '</think>' ))
49+ response_reasoning_content = False
50+
4051 for chunk in response :
41- answer += chunk .content
42- yield chunk .content
43- _write_context (node_variable , workflow_variable , node , workflow , answer )
52+ if workflow .is_the_task_interrupted ():
53+ break
54+
55+ # 处理 reasoning content
56+ reasoning_chunk = reasoning .get_reasoning_content (chunk )
57+ content_chunk = reasoning_chunk .get ('content' )
58+ if 'reasoning_content' in chunk .additional_kwargs :
59+ response_reasoning_content = True
60+ reasoning_content_chunk = chunk .additional_kwargs .get ('reasoning_content' , '' )
61+ else :
62+ reasoning_content_chunk = reasoning_chunk .get ('reasoning_content' )
63+
64+ answer += content_chunk
65+ if reasoning_content_chunk is None :
66+ reasoning_content_chunk = ''
67+ reasoning_content += reasoning_content_chunk
68+
69+ # 处理 chunk.content 为 list 的情况
70+ if isinstance (chunk .content , list ):
71+ for chunk_item in chunk .content :
72+ text = chunk_item .get ("text" , "" )
73+ yield {'content' : text ,
74+ 'reasoning_content' : reasoning_content_chunk if model_setting .get ('reasoning_content_enable' ,
75+ False ) else '' }
76+ else :
77+ text = chunk .content or ""
78+ yield {'content' : text ,
79+ 'reasoning_content' : reasoning_content_chunk if model_setting .get ('reasoning_content_enable' ,
80+ False ) else '' }
81+
82+ reasoning_chunk = reasoning .get_end_reasoning_content ()
83+ answer += reasoning_chunk .get ('content' )
84+ reasoning_content_chunk = ""
85+ if not response_reasoning_content :
86+ reasoning_content_chunk = reasoning_chunk .get (
87+ 'reasoning_content' )
88+ yield {'content' : reasoning_chunk .get ('content' ),
89+ 'reasoning_content' : reasoning_content_chunk if model_setting .get ('reasoning_content_enable' ,
90+ False ) else '' }
91+ _write_context (node_variable , workflow_variable , node , workflow , answer , reasoning_content )
4492
4593
4694def write_context (node_variable : Dict , workflow_variable : Dict , node : INode , workflow ):
@@ -52,8 +100,20 @@ def write_context(node_variable: Dict, workflow_variable: Dict, node: INode, wor
52100 @param workflow: 工作流管理器
53101 """
54102 response = node_variable .get ('result' )
55- answer = response .content
56- _write_context (node_variable , workflow_variable , node , workflow , answer )
103+ model_setting = node .context .get ('model_setting' ,
104+ {'reasoning_content_enable' : False , 'reasoning_content_end' : '</think>' ,
105+ 'reasoning_content_start' : '<think>' })
106+ reasoning = Reasoning (model_setting .get ('reasoning_content_start' ), model_setting .get ('reasoning_content_end' ))
107+ reasoning_result = reasoning .get_reasoning_content (response )
108+ reasoning_result_end = reasoning .get_end_reasoning_content ()
109+ content = reasoning_result .get ('content' ) + reasoning_result_end .get ('content' )
110+ meta = {** response .response_metadata , ** response .additional_kwargs }
111+ if 'reasoning_content' in meta :
112+ reasoning_content = (meta .get ('reasoning_content' , '' ) or '' )
113+ else :
114+ reasoning_content = (reasoning_result .get ('reasoning_content' ) or '' ) + (
115+ reasoning_result_end .get ('reasoning_content' ) or '' )
116+ _write_context (node_variable , workflow_variable , node , workflow , content , reasoning_content )
57117
58118
59119def file_id_to_base64 (file_id : str , video_model ):
@@ -76,6 +136,7 @@ def execute(self, model_id, system, prompt, dialogue_number, dialogue_type, hist
76136 chat_record_id ,
77137 video ,
78138 model_id_type = None , model_id_reference = None ,
139+ model_setting = None ,
79140 ** kwargs ) -> NodeResult :
80141 # 处理引用类型
81142 if model_id_type == 'reference' and model_id_reference :
@@ -88,6 +149,10 @@ def execute(self, model_id, system, prompt, dialogue_number, dialogue_type, hist
88149 model_params_setting = reference_data .get ('model_params_setting' )
89150
90151 workspace_id = self .workflow_manage .get_body ().get ('workspace_id' )
152+ if model_setting is None :
153+ model_setting = {'reasoning_content_enable' : False , 'reasoning_content_end' : '</think>' ,
154+ 'reasoning_content_start' : '<think>' }
155+ self .context ['model_setting' ] = model_setting
91156 video_model = get_model_instance_by_model_workspace_id (model_id , workspace_id ,
92157 ** (model_params_setting or {}))
93158 # 执行详情中的历史消息不需要图片内容
@@ -251,6 +316,7 @@ def get_details(self, index: int, **kwargs):
251316 'history_message' ) is not None else [])],
252317 'question' : self .context .get ('question' ),
253318 'answer' : self .context .get ('answer' ),
319+ 'reasoning_content' : self .context .get ('reasoning_content' ),
254320 'type' : self .node .type ,
255321 'message_tokens' : self .context .get ('message_tokens' ),
256322 'answer_tokens' : self .context .get ('answer_tokens' ),
0 commit comments