@@ -143,6 +143,8 @@ class ChatRequest:
143143 cancel_token : CancelToken = None
144144 # NEW: Add context for rule evaluation
145145 rule_context : Optional [RuleContext ] = None
146+ # Internal conversation id for persistence backends
147+ conversation_id : str = None
146148
147149@dataclass
148150class ResponseStreamData :
@@ -312,6 +314,9 @@ def message_id(self) -> str:
312314
313315 def stream (self , data : ResponseStreamData , finish : bool = False ) -> None :
314316 raise NotImplementedError
317+
318+ def append_tool_calls (self , tool_calls : list [dict ] | None ) -> None :
319+ return None
315320
316321 def finish (self ) -> None :
317322 raise NotImplementedError
@@ -636,6 +641,7 @@ async def _tool_call_loop(tool_call_rounds: list):
636641
637642 for choice in tool_response ['choices' ]:
638643 message = choice ['message' ]
644+ response .append_tool_calls (message .get ('tool_calls' ))
639645 # Some models use 'reasoning', some use 'reasoning_content'
640646 raw_reasoning = message .get ('reasoning' ) or message .get ('reasoning_content' ) or ''
641647
@@ -687,6 +693,12 @@ async def _tool_call_loop(tool_call_rounds: list):
687693 args = tool_call ['function' ]['arguments' ]
688694 else :
689695 args = fuzzy_json_loads (tool_call ['function' ]['arguments' ])
696+
697+ # Persist tool execution START (initial record).
698+ if request .conversation_id :
699+ request .host .history_persistence .log_tool_execution (
700+ tool_call ['id' ], request .conversation_id , tool_name , args , ""
701+ )
690702
691703 tool_properties = tool_to_call .schema ["function" ]["parameters" ]["properties" ]
692704 if type (args ) is str :
@@ -713,6 +725,17 @@ async def _tool_call_loop(tool_call_rounds: list):
713725 return
714726
715727 tool_call_response = await tool_to_call .handle_tool_call (request , response , tool_context , args )
728+
729+ # Persist tool execution result.
730+ if request .conversation_id :
731+ request .host .history_persistence .log_tool_execution (
732+ tool_call ['id' ], request .conversation_id , tool_name , args , str (tool_call_response )
733+ )
734+ # Also log the tool message itself
735+ msg_id = str (uuid .uuid4 ())
736+ request .host .history_persistence .add_message (
737+ msg_id , request .conversation_id , "tool" , str (tool_call_response ), tool_call_id = tool_call ['id' ]
738+ )
716739
717740 function_call_result_message = {
718741 "role" : "tool" ,
@@ -915,6 +938,9 @@ def register_telemetry_listener(self, listener: TelemetryListener) -> None:
915938 def register_toolset (self , toolset : Toolset ) -> None :
916939 raise NotImplementedError
917940
941+ def register_history_persistence_backend (self , backend ) -> None :
942+ raise NotImplementedError
943+
918944 @property
919945 def nbi_config (self ) -> NBIConfig :
920946 raise NotImplementedError
@@ -971,6 +997,10 @@ def get_skill_manager(self):
971997 def websocket_connector (self ) -> ThreadSafeWebSocketConnector :
972998 raise NotImplementedError
973999
1000+ @property
1001+ def history_persistence (self ) -> Any :
1002+ return NotImplementedError
1003+
9741004
9751005class NotebookIntelligenceExtension :
9761006 @property
0 commit comments