@@ -387,6 +387,30 @@ void LlmInterface::handleApiResponse(const std::string& response) {
387387 try {
388388 json responseJson = json::parse (response);
389389
390+ // Parse and accumulate token usage information if available
391+ if (responseJson.contains (" usage" ) && m_history && !m_currentConversationId.empty ()) {
392+ const auto & usage = responseJson[" usage" ];
393+
394+ std::optional<int > promptTokens, completionTokens, totalTokens;
395+ if (usage.contains (" prompt_tokens" ) && usage[" prompt_tokens" ].is_number ())
396+ promptTokens = usage[" prompt_tokens" ].get <int >();
397+ if (usage.contains (" completion_tokens" ) && usage[" completion_tokens" ].is_number ())
398+ completionTokens = usage[" completion_tokens" ].get <int >();
399+ if (usage.contains (" total_tokens" ) && usage[" total_tokens" ].is_number ())
400+ totalTokens = usage[" total_tokens" ].get <int >();
401+
402+ // Accumulate token usage for this conversation
403+ m_history->addTokenUsage (m_currentConversationId, promptTokens, completionTokens, totalTokens);
404+
405+ if (completionTokens.has_value ()) {
406+ cout << " === Token Usage This Call ===" << endl;
407+ cout << " Prompt tokens: " << (promptTokens.has_value () ? std::to_string (promptTokens.value ()) : " N/A" ) << endl;
408+ cout << " Completion tokens: " << completionTokens.value () << endl;
409+ cout << " Total tokens: " << (totalTokens.has_value () ? std::to_string (totalTokens.value ()) : " N/A" ) << endl;
410+ cout << " =============================" << endl;
411+ }
412+ }
413+
390414 if (responseJson.contains (" choices" ) && !responseJson[" choices" ].empty ()) {
391415 json choice = responseJson[" choices" ][0 ];
392416 if (choice.contains (" message" )) {
@@ -396,23 +420,15 @@ void LlmInterface::handleApiResponse(const std::string& response) {
396420 if ( message.contains (" content" ) && message[" content" ].is_string () )
397421 content = message[" content" ];
398422
399-
400423 if (role == " assistant" ) {
401424 // Extract thinking content and clean content
402425 auto [cleanContent, thinkingContent] = extractThinkingAndContent (content);
403-
404- cout
405- << " === Start Cleaned Response Content ===" << endl
406- << cleanContent
407- << " \n === End Cleaned Response Content ===" << endl
408- << endl;
409-
426+
410427 // Add assistant message to history with thinking content
411428 m_history->addAssistantMessageWithThinking (cleanContent, thinkingContent, m_currentConversationId);
412429
413430 // Handle structured tool calls first (OpenAI format)
414431 if (message.contains (" tool_calls" )) {
415- cout << " Found structured tool_calls" << endl;
416432 executeToolCalls (message[" tool_calls" ]);
417433 } else {
418434 // Parse content for text-based tool requests (use cleaned content)
@@ -668,7 +684,15 @@ nlohmann::json LlmInterface::buildMessagesArray(const std::string& userMessage,
668684
669685 json request;
670686 request[" model" ] = m_config->llmApi .model ;
671- request[" max_tokens" ] = m_config->llmApi .maxTokens ;
687+
688+ // Use max_completion_tokens for newer OpenAI models, max_tokens for others
689+ string modelName = m_config->llmApi .model ;
690+ if (modelName.find (" gpt-4" ) != string::npos || modelName.find (" gpt-3.5" ) != string::npos ||
691+ modelName.find (" o1" ) != string::npos || modelName.find (" gpt-5" ) != string::npos) {
692+ request[" max_completion_tokens" ] = m_config->llmApi .maxTokens ;
693+ } else {
694+ request[" max_tokens" ] = m_config->llmApi .maxTokens ;
695+ }
672696
673697 json messages = json::array ();
674698
@@ -684,8 +708,10 @@ nlohmann::json LlmInterface::buildMessagesArray(const std::string& userMessage,
684708 if (!m_history->isEmpty ()) {
685709 json historyMessages = m_history->toApiFormat ();
686710 cout << " === Including " << historyMessages.size () << " history messages in request ===" << endl;
711+
687712 for (size_t i = 0 ; i < historyMessages.size (); ++i) {
688713 const auto & msg = historyMessages[i];
714+
689715 cout << " " << i << " . " << msg[" role" ].get <string>() << " : "
690716 << (msg.contains (" content" ) ? msg[" content" ].get <string>().substr (0 , 50 ) + " ..." : " tool_call" ) << endl;
691717 messages.push_back (msg);
@@ -754,7 +780,7 @@ void LlmInterface::setupJavaScriptBridge() {
754780 // Set up the JavaScript function to handle HTTP requests
755781 string jsCode = R"(
756782 window.llmHttpRequest = function(endpoint, requestJsonString, bearerToken, requestId) {
757- console.log('LLM HTTP Request to:', endpoint, 'For requestID', requestId);
783+ // console.log('LLM HTTP Request to:', endpoint, 'For requestID', requestId);
758784 //console.log('Request data:', requestJsonString);
759785
760786 var headers = {
@@ -779,12 +805,12 @@ void LlmInterface::setupJavaScriptBridge() {
779805 signal: controller.signal
780806 })
781807 .then(function(response) {
782- console.log('LLM Response status:', response.status);
808+ // console.log('LLM Response status:', response.status);
783809 return response.text();
784810 })
785811 .then(function(responseText) {
786812 //console.log('LLM Response:', responseText);
787- console.log( 'Got LLM Response text' );
813+ // console.log( 'Got LLM Response text', responseText );
788814
789815 // Clear the timeout since we got a response
790816 clearTimeout(timeoutId);
@@ -820,7 +846,7 @@ void LlmInterface::setupJavaScriptBridge() {
820846 // Set up the response callback using JSignal to emit signal to C++
821847 string callbackJs =
822848 " window.llmResponseCallback = function(response, requestId) { "
823- " console.log('Emitting signal to C++ with response length:', response.length, 'requestId:', requestId); "
849+ // "console.log('Emitting signal to C++ with response length:', response.length, 'requestId:', requestId); "
824850 " " + m_responseSignal->createCall (" response" , " requestId" ) + " ;"
825851 " };" ;
826852
@@ -830,6 +856,8 @@ void LlmInterface::setupJavaScriptBridge() {
830856}
831857
832858void LlmInterface::handleJavaScriptResponse (std::string response, int requestId) {
859+
860+ cout << " :handleJavaScriptResponse: " << response << endl << endl << endl;
833861 try {
834862 // Find and remove the pending request
835863 PendingRequest pendingRequest;
@@ -842,7 +870,7 @@ void LlmInterface::handleJavaScriptResponse(std::string response, int requestId)
842870
843871 // Check for errors first
844872 json responseJson = json::parse (response);
845- if (responseJson.contains (" error" )) {
873+ if (responseJson.contains (" error" ) && !responseJson[ " error " ]. is_null () ) {
846874 string errorMsg = " LLM API Error: " + responseJson[" error" ].dump (2 );
847875 cout << errorMsg << endl;
848876
0 commit comments