22from typing import List , Dict , Any , Generator
33from utils .database import get_db , close_db
44from flask import current_app as app
5+ from datetime import datetime , date
56from config import Config
67from openai import OpenAI
78import json
@@ -29,20 +30,27 @@ def _build_tools_schema() -> List[Dict[str, Any]]:
2930 })
3031 return out_tools
3132
33+ class DateTimeEncoder (json .JSONEncoder ):
34+ """Custom JSON encoder that handles datetime objects."""
35+ def default (self , obj ):
36+ if isinstance (obj , (datetime , date )):
37+ return obj .isoformat ()
38+ return super ().default (obj )
39+
3240def _execute_tool (name : str , arguments : Dict [str , Any ]) -> str :
3341 """Execute MCP tool and return JSON result."""
3442 db = None
3543 try :
3644 db = get_db ()
37- rows = mcp_run_tool (name , arguments or {}, db )
38- return json .dumps ({ 'rows' : rows } )
45+ result = mcp_run_tool (name , arguments or {}, db )
46+ return json .dumps (result , cls = DateTimeEncoder )
3947 except Exception as e :
4048 app .logger .error ('Tool execution failed: %s' , str (e ), exc_info = True )
41- return json .dumps ({'error' : str (e )})
49+ return json .dumps ({'error' : str (e )}, cls = DateTimeEncoder )
4250 finally :
4351 close_db (db )
4452
45- def chat (messages : List [Dict [str , str ]], model : str = None ) -> Generator [Dict [str , Any ], None , None ]:
53+ def chat (messages : List [Dict [str , str ]], model : str = "openrouter/auto" ) -> Generator [Dict [str , Any ], None , None ]:
4654 """
4755 Stream chat with OpenAI models using function calling.
4856 Let the LLM handle its own thinking process.
@@ -71,8 +79,9 @@ def chat(messages: List[Dict[str, str]], model: str = None) -> Generator[Dict[st
7179 tools = tools ,
7280 tool_choice = 'auto' ,
7381 temperature = 0.2 ,
74- max_tokens = 2000 ,
75- stream = True
82+ max_tokens = 5000 ,
83+ stream = True ,
84+ stream_options = {"include_usage" : True },
7685 )
7786
7887 # Process streaming response
@@ -83,6 +92,10 @@ def chat(messages: List[Dict[str, str]], model: str = None) -> Generator[Dict[st
8392 for chunk in response :
8493 if not chunk .choices :
8594 continue
95+
96+ # Handle usage data from streaming response
97+ if hasattr (chunk , 'usage' ) and chunk .usage :
98+ yield {'type' : 'token_usage' , 'tokens' : chunk .usage .total_tokens , 'model' : model }
8699
87100 delta = chunk .choices [0 ].delta
88101
@@ -142,12 +155,13 @@ def chat(messages: List[Dict[str, str]], model: str = None) -> Generator[Dict[st
142155 yield {'type' : 'tool_result' , 'name' : name , 'output' : output }
143156
144157 # Add tool result to conversation
145- conversation . append ( {
158+ tool_message = {
146159 'role' : 'tool' ,
147160 'tool_call_id' : tool_call ['id' ],
148161 'name' : name ,
149162 'content' : output
150- })
163+ }
164+ conversation .append (tool_message )
151165
152166 # Continue to next round for tool calling
153167 continue
0 commit comments