From 6cc4c4c501279a7faa44be398a05d95cff9797f9 Mon Sep 17 00:00:00 2001 From: Lidia Date: Wed, 9 Apr 2025 15:48:59 +0200 Subject: [PATCH 1/6] FIX show pricing - calculate pricing --- src/cai/cli.py | 6 +-- src/cai/repl/commands/model.py | 5 +- src/cai/sdk/agents/models/openai_responses.py | 9 ++-- src/cai/util.py | 52 +++++++++++++++++-- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/cai/cli.py b/src/cai/cli.py index 3eb1fafd..677914db 100644 --- a/src/cai/cli.py +++ b/src/cai/cli.py @@ -107,7 +107,7 @@ from cai.sdk.agents import set_default_openai_client, set_tracing_disabled from openai.types.responses import ResponseTextDeltaEvent from rich.console import Console import asyncio -from cai.util import fix_litellm_transcription_annotations, color +from cai.util import fix_litellm_transcription_annotations, color, calculate_model_cost from cai.util import create_agent_streaming_context, update_agent_streaming_content, finish_agent_streaming # Import modules from cai.repl @@ -322,8 +322,8 @@ def run_cai_cli(starting_agent, context_variables=None, stream=False, max_turns= "total_input_tokens": getattr(model, 'total_input_tokens', interaction_input), "total_output_tokens": getattr(model, 'total_output_tokens', output_tokens), "total_reasoning_tokens": getattr(model, 'total_reasoning_tokens', 0), - "interaction_cost": None, - "total_cost": None + "interaction_cost": calculate_model_cost(str(model), interaction_input, output_tokens), + "total_cost": calculate_model_cost(str(model), getattr(model, 'total_input_tokens', interaction_input), getattr(model, 'total_output_tokens', output_tokens)) } finish_agent_streaming(current_streaming_context, token_stats) diff --git a/src/cai/repl/commands/model.py b/src/cai/repl/commands/model.py index 31cd8e9e..94baea75 100644 --- a/src/cai/repl/commands/model.py +++ b/src/cai/repl/commands/model.py @@ -201,7 +201,10 @@ class ModelCommand(Command): console.print( "[yellow]Warning: Could not fetch model pricing data[/yellow]" ) - + print("--------------------------------") + print(LITELLM_URL) + print(model_pricing_data) + print("--------------------------------") # Create a flat list of all models for numeric selection # pylint: disable=invalid-name ALL_MODELS = [] diff --git a/src/cai/sdk/agents/models/openai_responses.py b/src/cai/sdk/agents/models/openai_responses.py index ce587045..b25df689 100644 --- a/src/cai/sdk/agents/models/openai_responses.py +++ b/src/cai/sdk/agents/models/openai_responses.py @@ -28,6 +28,7 @@ from ..tracing import SpanError, response_span from ..usage import Usage from ..version import __version__ from .interface import Model, ModelTracing +from cai.util import calculate_model_cost if TYPE_CHECKING: from ..model_settings import ModelSettings @@ -153,8 +154,8 @@ class OpenAIResponsesModel(Model): total_input_tokens=getattr(self, 'total_input_tokens', 0), total_output_tokens=getattr(self, 'total_output_tokens', 0), total_reasoning_tokens=getattr(self, 'total_reasoning_tokens', 0), - interaction_cost=None, - total_cost=None, + interaction_cost=calculate_model_cost(str(self.model), usage.input_tokens, usage.output_tokens), + total_cost=calculate_model_cost(str(self.model), getattr(self, 'total_input_tokens', 0), getattr(self, 'total_output_tokens', 0)), ) # Update token totals @@ -254,8 +255,8 @@ class OpenAIResponsesModel(Model): total_input_tokens=getattr(self, 'total_input_tokens', 0), total_output_tokens=getattr(self, 'total_output_tokens', 0), total_reasoning_tokens=getattr(self, 'total_reasoning_tokens', 0), - interaction_cost=None, - total_cost=None, + interaction_cost=calculate_model_cost(str(self.model), final_response.usage.input_tokens, final_response.usage.output_tokens), + total_cost=calculate_model_cost(str(self.model), getattr(self, 'total_input_tokens', 0), getattr(self, 'total_output_tokens', 0)), ) # Update token totals diff --git a/src/cai/util.py b/src/cai/util.py index 1cdb95ed..33375956 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -339,7 +339,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals total_output_tokens, total_reasoning_tokens, model, - interaction_cost=0.0, + interaction_cost=None, # before 0.0 total_cost=None ) -> Text: # noqa: E501 """ @@ -357,7 +357,9 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals tokens_text.append(f"O:{interaction_output_tokens} ", style="red") tokens_text.append(f"R:{interaction_reasoning_tokens} ", style="yellow") - # Current cost + # Current cost - calculate if None + if interaction_cost is None: + interaction_cost = calculate_model_cost(model, interaction_input_tokens, interaction_output_tokens) current_cost = float(interaction_cost) if interaction_cost is not None else 0.0 tokens_text.append(f"(${current_cost:.4f}) ", style="bold") @@ -370,7 +372,9 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals tokens_text.append(f"O:{total_output_tokens} ", style="red") tokens_text.append(f"R:{total_reasoning_tokens} ", style="yellow") - # Total cost + # Total cost - calculate if None + if total_cost is None: + total_cost = calculate_model_cost(model, total_input_tokens, total_output_tokens) total_cost_value = float(total_cost) if total_cost is not None else 0.0 tokens_text.append(f"(${total_cost_value:.4f}) ", style="bold") @@ -615,4 +619,44 @@ def finish_agent_streaming(context, final_stats=None): time.sleep(0.5) # Stop the live display - context["live"].stop() \ No newline at end of file + context["live"].stop() + +def calculate_model_cost(model_name, input_tokens, output_tokens): + """ + Calculate the cost for a given model based on token usage. + + Args: + model_name: The name of the model being used + input_tokens: Number of input tokens used + output_tokens: Number of output tokens used + + Returns: + float: The calculated cost in dollars + """ + # Fetch model pricing data from LiteLLM GitHub repository + LITELLM_URL = ( + "https://raw.githubusercontent.com/BerriAI/litellm/main/" + "model_prices_and_context_window.json" + ) + + try: + import requests + response = requests.get(LITELLM_URL, timeout=2) + if response.status_code == 200: + model_pricing_data = response.json() + + # Get pricing info for the model + pricing_info = model_pricing_data.get(model_name, {}) + input_cost_per_token = pricing_info.get("input_cost_per_token", 0) + output_cost_per_token = pricing_info.get("output_cost_per_token", 0) + + # Calculate costs + input_cost = input_tokens * input_cost_per_token + output_cost = output_tokens * output_cost_per_token + + return input_cost + output_cost + except Exception: + # If we can't fetch pricing data, return 0 + pass + + return 0.0 \ No newline at end of file From 2cf6bc01c3c8af7e4a73a168ccd8ae5df68ab6d0 Mon Sep 17 00:00:00 2001 From: Lidia Date: Fri, 11 Apr 2025 09:53:51 +0200 Subject: [PATCH 2/6] undo changes in openai_responses.py and leave it as it was originally in v0.4.0 --- src/cai/sdk/agents/models/openai_responses.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cai/sdk/agents/models/openai_responses.py b/src/cai/sdk/agents/models/openai_responses.py index b25df689..ce587045 100644 --- a/src/cai/sdk/agents/models/openai_responses.py +++ b/src/cai/sdk/agents/models/openai_responses.py @@ -28,7 +28,6 @@ from ..tracing import SpanError, response_span from ..usage import Usage from ..version import __version__ from .interface import Model, ModelTracing -from cai.util import calculate_model_cost if TYPE_CHECKING: from ..model_settings import ModelSettings @@ -154,8 +153,8 @@ class OpenAIResponsesModel(Model): total_input_tokens=getattr(self, 'total_input_tokens', 0), total_output_tokens=getattr(self, 'total_output_tokens', 0), total_reasoning_tokens=getattr(self, 'total_reasoning_tokens', 0), - interaction_cost=calculate_model_cost(str(self.model), usage.input_tokens, usage.output_tokens), - total_cost=calculate_model_cost(str(self.model), getattr(self, 'total_input_tokens', 0), getattr(self, 'total_output_tokens', 0)), + interaction_cost=None, + total_cost=None, ) # Update token totals @@ -255,8 +254,8 @@ class OpenAIResponsesModel(Model): total_input_tokens=getattr(self, 'total_input_tokens', 0), total_output_tokens=getattr(self, 'total_output_tokens', 0), total_reasoning_tokens=getattr(self, 'total_reasoning_tokens', 0), - interaction_cost=calculate_model_cost(str(self.model), final_response.usage.input_tokens, final_response.usage.output_tokens), - total_cost=calculate_model_cost(str(self.model), getattr(self, 'total_input_tokens', 0), getattr(self, 'total_output_tokens', 0)), + interaction_cost=None, + total_cost=None, ) # Update token totals From d4909c5288b13e0a962358c0853945d53f377ea9 Mon Sep 17 00:00:00 2001 From: Lidia Date: Fri, 11 Apr 2025 11:02:30 +0200 Subject: [PATCH 3/6] FIX show pricing for CAI_STREAM=true --- .../agents/models/openai_chatcompletions.py | 80 +++++++++++++------ src/cai/util.py | 42 ++++++++-- 2 files changed, 90 insertions(+), 32 deletions(-) diff --git a/src/cai/sdk/agents/models/openai_chatcompletions.py b/src/cai/sdk/agents/models/openai_chatcompletions.py index 872f9069..d523ddb0 100644 --- a/src/cai/sdk/agents/models/openai_chatcompletions.py +++ b/src/cai/sdk/agents/models/openai_chatcompletions.py @@ -61,7 +61,7 @@ from openai.types.responses import ( ) from openai.types.responses.response_input_param import FunctionCallOutput, ItemReference, Message from openai.types.responses.response_usage import OutputTokensDetails - +from cai.util import calculate_model_cost # Create custom InputTokensDetails class since it's not available in current OpenAI version from openai._models import BaseModel class InputTokensDetails(BaseModel): @@ -358,11 +358,16 @@ class OpenAIChatCompletionsModel(Model): # Create streaming context if needed streaming_context = None if should_show_rich_stream: + print(f"\nDEBUG: Creating streaming context with initial stats:") + print(f"DEBUG: Model: {str(self.model)}") + print(f"DEBUG: Agent name: {self.agent_name}") + print(f"DEBUG: Counter: {self.interaction_counter}") streaming_context = create_agent_streaming_context( agent_name=self.agent_name, counter=self.interaction_counter, model=str(self.model) ) + print(f"DEBUG: Created streaming context: {streaming_context}") with generation_span( model=str(self.model), @@ -753,49 +758,74 @@ class OpenAIChatCompletionsModel(Model): self.total_reasoning_tokens += final_response.usage.output_tokens_details.reasoning_tokens # Prepare final statistics for display + interaction_input = final_response.usage.input_tokens if final_response.usage else 0 + interaction_output = final_response.usage.output_tokens if final_response.usage else 0 + total_input = getattr(self, 'total_input_tokens', 0) + total_output = getattr(self, 'total_output_tokens', 0) + + # Calculate costs using the same token counts - ensure model is a string + model_name = str(self.model) + interaction_cost = calculate_model_cost(model_name, interaction_input, interaction_output) + total_cost = calculate_model_cost(model_name, total_input, total_output) + + # Explicit conversion to float with fallback to ensure they're never None or 0 + interaction_cost = max(float(interaction_cost if interaction_cost is not None else 0.0), 0.00001) + total_cost = max(float(total_cost if total_cost is not None else 0.0), 0.00001) + + print(f"DEBUG: Final direct cost calculations - Interaction: ${interaction_cost:.6f}, Total: ${total_cost:.6f}") + + # Create final stats with explicit type conversion for all values final_stats = { - "interaction_input_tokens": final_response.usage.input_tokens if final_response.usage else 0, - "interaction_output_tokens": final_response.usage.output_tokens if final_response.usage else 0, - "interaction_reasoning_tokens": ( + "interaction_input_tokens": int(interaction_input), + "interaction_output_tokens": int(interaction_output), + "interaction_reasoning_tokens": int( final_response.usage.output_tokens_details.reasoning_tokens if final_response.usage and final_response.usage.output_tokens_details and hasattr(final_response.usage.output_tokens_details, 'reasoning_tokens') else 0 ), - "total_input_tokens": getattr(self, 'total_input_tokens', 0), - "total_output_tokens": getattr(self, 'total_output_tokens', 0), - "total_reasoning_tokens": getattr(self, 'total_reasoning_tokens', 0), - "interaction_cost": None, - "total_cost": None, + "total_input_tokens": int(total_input), + "total_output_tokens": int(total_output), + "total_reasoning_tokens": int(getattr(self, 'total_reasoning_tokens', 0)), + "interaction_cost": float(interaction_cost), + "total_cost": float(total_cost), } + print(f"DEBUG: Final stats costs (from dictionary) - Interaction: ${final_stats['interaction_cost']:.6f}, Total: ${final_stats['total_cost']:.6f}") + print(f"DEBUG: Cost types in dictionary - Interaction: {type(final_stats['interaction_cost'])}, Total: {type(final_stats['total_cost'])}") + # At the end of streaming, finish the streaming context if we were using it if streaming_context: - finish_agent_streaming(streaming_context, final_stats) + # Create a direct copy of the costs to ensure they remain as floats + direct_stats = final_stats.copy() + direct_stats["interaction_cost"] = float(interaction_cost) + direct_stats["total_cost"] = float(total_cost) + + print(f"\nDEBUG: Final stats before finish_agent_streaming:") + print(f"DEBUG: Direct stats costs - Interaction: ${direct_stats['interaction_cost']:.6f}, Total: ${direct_stats['total_cost']:.6f}") + print(f"DEBUG: Direct stats types - Interaction: {type(direct_stats['interaction_cost'])}, Total: {type(direct_stats['total_cost'])}") + + # Use the direct copy with guaranteed float costs + finish_agent_streaming(streaming_context, direct_stats) # If we're not using rich streaming and not suppressing output, use old method elif not self.suppress_final_output and final_response.output and any(isinstance(item, ResponseOutputMessage) for item in final_response.output): # Find the assistant message to print for item in final_response.output: if isinstance(item, ResponseOutputMessage) and item.role == 'assistant': cli_print_agent_messages( - agent_name=getattr(self, 'agent_name', 'Agent'), # Default to 'Agent' if not available + agent_name=getattr(self, 'agent_name', 'Agent'), message=item, - counter=getattr(self, 'interaction_counter', 0), # Default to 0 if not available + counter=getattr(self, 'interaction_counter', 0), model=str(self.model), debug=False, - interaction_input_tokens=final_response.usage.input_tokens if final_response.usage else 0, - interaction_output_tokens=final_response.usage.output_tokens if final_response.usage else 0, - interaction_reasoning_tokens=( - final_response.usage.output_tokens_details.reasoning_tokens - if final_response.usage and final_response.usage.output_tokens_details - and hasattr(final_response.usage.output_tokens_details, 'reasoning_tokens') - else 0 - ), - total_input_tokens=getattr(self, 'total_input_tokens', 0), - total_output_tokens=getattr(self, 'total_output_tokens', 0), - total_reasoning_tokens=getattr(self, 'total_reasoning_tokens', 0), - interaction_cost=None, - total_cost=None, + interaction_input_tokens=interaction_input, + interaction_output_tokens=interaction_output, + interaction_reasoning_tokens=final_stats["interaction_reasoning_tokens"], + total_input_tokens=total_input, + total_output_tokens=total_output, + total_reasoning_tokens=final_stats["total_reasoning_tokens"], + interaction_cost=interaction_cost, + total_cost=total_cost, ) break diff --git a/src/cai/util.py b/src/cai/util.py index 33375956..06acad1e 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -339,13 +339,15 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals total_output_tokens, total_reasoning_tokens, model, - interaction_cost=None, # before 0.0 + interaction_cost=None, total_cost=None ) -> Text: # noqa: E501 """ Create a Text object displaying token usage information with enhanced formatting. """ + print(f"\nDEBUG _create_token_display: Received costs - Interaction: {interaction_cost}, Total: {total_cost}") + tokens_text = Text(justify="left") # Create a more compact, horizontal display @@ -357,10 +359,15 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals tokens_text.append(f"O:{interaction_output_tokens} ", style="red") tokens_text.append(f"R:{interaction_reasoning_tokens} ", style="yellow") - # Current cost - calculate if None + # Current cost - only calculate if not provided if interaction_cost is None: interaction_cost = calculate_model_cost(model, interaction_input_tokens, interaction_output_tokens) - current_cost = float(interaction_cost) if interaction_cost is not None else 0.0 + # Ensure interaction_cost is a float + try: + current_cost = float(interaction_cost) if interaction_cost is not None else 0.0 + except (ValueError, TypeError): + current_cost = 0.0 + print(f"DEBUG _create_token_display: Current cost after conversion: {current_cost}") tokens_text.append(f"(${current_cost:.4f}) ", style="bold") # Separator @@ -372,10 +379,15 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals tokens_text.append(f"O:{total_output_tokens} ", style="red") tokens_text.append(f"R:{total_reasoning_tokens} ", style="yellow") - # Total cost - calculate if None + # Total cost - only calculate if not provided if total_cost is None: total_cost = calculate_model_cost(model, total_input_tokens, total_output_tokens) - total_cost_value = float(total_cost) if total_cost is not None else 0.0 + # Ensure total_cost is a float + try: + total_cost_value = float(total_cost) if total_cost is not None else 0.0 + except (ValueError, TypeError): + total_cost_value = 0.0 + print(f"DEBUG _create_token_display: Total cost after conversion: {total_cost_value}") tokens_text.append(f"(${total_cost_value:.4f}) ", style="bold") # Separator @@ -565,14 +577,21 @@ def finish_agent_streaming(context, final_stats=None): # If we have token stats, add them tokens_text = None if final_stats: + print(f"\nDEBUG finish_agent_streaming: Received final_stats: {final_stats}") + interaction_input_tokens = final_stats.get("interaction_input_tokens") interaction_output_tokens = final_stats.get("interaction_output_tokens") interaction_reasoning_tokens = final_stats.get("interaction_reasoning_tokens") total_input_tokens = final_stats.get("total_input_tokens") total_output_tokens = final_stats.get("total_output_tokens") total_reasoning_tokens = final_stats.get("total_reasoning_tokens") - interaction_cost = final_stats.get("interaction_cost") - total_cost = final_stats.get("total_cost") + + # CRITICAL FIX: Ensure costs are properly extracted and preserved as floats + interaction_cost = float(final_stats.get("interaction_cost", 0.0)) + total_cost = float(final_stats.get("total_cost", 0.0)) + + print(f"\nDEBUG finish_agent_streaming: Received costs from final_stats - Interaction: {interaction_cost}, Total: {total_cost}") + print(f"DEBUG finish_agent_streaming: Type of interaction_cost: {type(interaction_cost)}, Type of total_cost: {type(total_cost)}") if (interaction_input_tokens is not None and interaction_output_tokens is not None and @@ -581,6 +600,15 @@ def finish_agent_streaming(context, final_stats=None): total_output_tokens is not None and total_reasoning_tokens is not None): + # Only calculate costs if they weren't provided or are zero + if interaction_cost is None or interaction_cost == 0.0: + interaction_cost = calculate_model_cost(context["model"], interaction_input_tokens, interaction_output_tokens) + if total_cost is None or total_cost == 0.0: + total_cost = calculate_model_cost(context["model"], total_input_tokens, total_output_tokens) + + print(f"DEBUG finish_agent_streaming: Costs before passing to _create_token_display - Interaction: {interaction_cost}, Total: {total_cost}") + print(f"DEBUG finish_agent_streaming: Type of costs before passing - Interaction: {type(interaction_cost)}, Total: {type(total_cost)}") + tokens_text = _create_token_display( interaction_input_tokens, interaction_output_tokens, From 0bcd3fff0501472797e533a10bf57e19caabec4e Mon Sep 17 00:00:00 2001 From: Lidia Date: Fri, 11 Apr 2025 11:13:23 +0200 Subject: [PATCH 4/6] remove prints --- src/cai/util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cai/util.py b/src/cai/util.py index 06acad1e..ec26950c 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -346,7 +346,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals Create a Text object displaying token usage information with enhanced formatting. """ - print(f"\nDEBUG _create_token_display: Received costs - Interaction: {interaction_cost}, Total: {total_cost}") + # print(f"\nDEBUG _create_token_display: Received costs - Interaction: {interaction_cost}, Total: {total_cost}") tokens_text = Text(justify="left") @@ -367,7 +367,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals current_cost = float(interaction_cost) if interaction_cost is not None else 0.0 except (ValueError, TypeError): current_cost = 0.0 - print(f"DEBUG _create_token_display: Current cost after conversion: {current_cost}") + # print(f"DEBUG _create_token_display: Current cost after conversion: {current_cost}") tokens_text.append(f"(${current_cost:.4f}) ", style="bold") # Separator @@ -387,7 +387,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals total_cost_value = float(total_cost) if total_cost is not None else 0.0 except (ValueError, TypeError): total_cost_value = 0.0 - print(f"DEBUG _create_token_display: Total cost after conversion: {total_cost_value}") + # print(f"DEBUG _create_token_display: Total cost after conversion: {total_cost_value}") tokens_text.append(f"(${total_cost_value:.4f}) ", style="bold") # Separator From 2ba7c906939b57d57b392935aa6e6148fba0db58 Mon Sep 17 00:00:00 2001 From: Lidia Date: Fri, 11 Apr 2025 11:18:07 +0200 Subject: [PATCH 5/6] remove prints --- .../sdk/agents/models/openai_chatcompletions.py | 14 +++++++------- src/cai/util.py | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cai/sdk/agents/models/openai_chatcompletions.py b/src/cai/sdk/agents/models/openai_chatcompletions.py index d523ddb0..fb5c0b58 100644 --- a/src/cai/sdk/agents/models/openai_chatcompletions.py +++ b/src/cai/sdk/agents/models/openai_chatcompletions.py @@ -358,10 +358,10 @@ class OpenAIChatCompletionsModel(Model): # Create streaming context if needed streaming_context = None if should_show_rich_stream: - print(f"\nDEBUG: Creating streaming context with initial stats:") - print(f"DEBUG: Model: {str(self.model)}") - print(f"DEBUG: Agent name: {self.agent_name}") - print(f"DEBUG: Counter: {self.interaction_counter}") + #print(f"\nDEBUG: Creating streaming context with initial stats:") + #print(f"DEBUG: Model: {str(self.model)}") + #print(f"DEBUG: Agent name: {self.agent_name}") + #print(f"DEBUG: Counter: {self.interaction_counter}") streaming_context = create_agent_streaming_context( agent_name=self.agent_name, counter=self.interaction_counter, @@ -772,7 +772,7 @@ class OpenAIChatCompletionsModel(Model): interaction_cost = max(float(interaction_cost if interaction_cost is not None else 0.0), 0.00001) total_cost = max(float(total_cost if total_cost is not None else 0.0), 0.00001) - print(f"DEBUG: Final direct cost calculations - Interaction: ${interaction_cost:.6f}, Total: ${total_cost:.6f}") + #print(f"DEBUG: Final direct cost calculations - Interaction: ${interaction_cost:.6f}, Total: ${total_cost:.6f}") # Create final stats with explicit type conversion for all values final_stats = { @@ -791,8 +791,8 @@ class OpenAIChatCompletionsModel(Model): "total_cost": float(total_cost), } - print(f"DEBUG: Final stats costs (from dictionary) - Interaction: ${final_stats['interaction_cost']:.6f}, Total: ${final_stats['total_cost']:.6f}") - print(f"DEBUG: Cost types in dictionary - Interaction: {type(final_stats['interaction_cost'])}, Total: {type(final_stats['total_cost'])}") + #print(f"DEBUG: Final stats costs (from dictionary) - Interaction: ${final_stats['interaction_cost']:.6f}, Total: ${final_stats['total_cost']:.6f}") + #print(f"DEBUG: Cost types in dictionary - Interaction: {type(final_stats['interaction_cost'])}, Total: {type(final_stats['total_cost'])}") # At the end of streaming, finish the streaming context if we were using it if streaming_context: diff --git a/src/cai/util.py b/src/cai/util.py index ec26950c..7635ef5a 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -577,7 +577,7 @@ def finish_agent_streaming(context, final_stats=None): # If we have token stats, add them tokens_text = None if final_stats: - print(f"\nDEBUG finish_agent_streaming: Received final_stats: {final_stats}") + #print(f"\nDEBUG finish_agent_streaming: Received final_stats: {final_stats}") interaction_input_tokens = final_stats.get("interaction_input_tokens") interaction_output_tokens = final_stats.get("interaction_output_tokens") @@ -590,8 +590,8 @@ def finish_agent_streaming(context, final_stats=None): interaction_cost = float(final_stats.get("interaction_cost", 0.0)) total_cost = float(final_stats.get("total_cost", 0.0)) - print(f"\nDEBUG finish_agent_streaming: Received costs from final_stats - Interaction: {interaction_cost}, Total: {total_cost}") - print(f"DEBUG finish_agent_streaming: Type of interaction_cost: {type(interaction_cost)}, Type of total_cost: {type(total_cost)}") + #print(f"\nDEBUG finish_agent_streaming: Received costs from final_stats - Interaction: {interaction_cost}, Total: {total_cost}") + #print(f"DEBUG finish_agent_streaming: Type of interaction_cost: {type(interaction_cost)}, Type of total_cost: {type(total_cost)}") if (interaction_input_tokens is not None and interaction_output_tokens is not None and @@ -606,8 +606,8 @@ def finish_agent_streaming(context, final_stats=None): if total_cost is None or total_cost == 0.0: total_cost = calculate_model_cost(context["model"], total_input_tokens, total_output_tokens) - print(f"DEBUG finish_agent_streaming: Costs before passing to _create_token_display - Interaction: {interaction_cost}, Total: {total_cost}") - print(f"DEBUG finish_agent_streaming: Type of costs before passing - Interaction: {type(interaction_cost)}, Total: {type(total_cost)}") + #print(f"DEBUG finish_agent_streaming: Costs before passing to _create_token_display - Interaction: {interaction_cost}, Total: {total_cost}") + #print(f"DEBUG finish_agent_streaming: Type of costs before passing - Interaction: {type(interaction_cost)}, Total: {type(total_cost)}") tokens_text = _create_token_display( interaction_input_tokens, From 0bced4cbf347d8aabc529bd8edaaaccd590771d0 Mon Sep 17 00:00:00 2001 From: lidia9 Date: Tue, 22 Apr 2025 07:15:01 +0000 Subject: [PATCH 6/6] removing prints from pricing changes --- src/cai/repl/commands/model.py | 4 ---- .../sdk/agents/models/openai_chatcompletions.py | 14 -------------- src/cai/util.py | 12 +++--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/cai/repl/commands/model.py b/src/cai/repl/commands/model.py index 94baea75..8595ede7 100644 --- a/src/cai/repl/commands/model.py +++ b/src/cai/repl/commands/model.py @@ -201,10 +201,6 @@ class ModelCommand(Command): console.print( "[yellow]Warning: Could not fetch model pricing data[/yellow]" ) - print("--------------------------------") - print(LITELLM_URL) - print(model_pricing_data) - print("--------------------------------") # Create a flat list of all models for numeric selection # pylint: disable=invalid-name ALL_MODELS = [] diff --git a/src/cai/sdk/agents/models/openai_chatcompletions.py b/src/cai/sdk/agents/models/openai_chatcompletions.py index fb5c0b58..4031a7af 100644 --- a/src/cai/sdk/agents/models/openai_chatcompletions.py +++ b/src/cai/sdk/agents/models/openai_chatcompletions.py @@ -358,16 +358,11 @@ class OpenAIChatCompletionsModel(Model): # Create streaming context if needed streaming_context = None if should_show_rich_stream: - #print(f"\nDEBUG: Creating streaming context with initial stats:") - #print(f"DEBUG: Model: {str(self.model)}") - #print(f"DEBUG: Agent name: {self.agent_name}") - #print(f"DEBUG: Counter: {self.interaction_counter}") streaming_context = create_agent_streaming_context( agent_name=self.agent_name, counter=self.interaction_counter, model=str(self.model) ) - print(f"DEBUG: Created streaming context: {streaming_context}") with generation_span( model=str(self.model), @@ -772,7 +767,6 @@ class OpenAIChatCompletionsModel(Model): interaction_cost = max(float(interaction_cost if interaction_cost is not None else 0.0), 0.00001) total_cost = max(float(total_cost if total_cost is not None else 0.0), 0.00001) - #print(f"DEBUG: Final direct cost calculations - Interaction: ${interaction_cost:.6f}, Total: ${total_cost:.6f}") # Create final stats with explicit type conversion for all values final_stats = { @@ -791,20 +785,12 @@ class OpenAIChatCompletionsModel(Model): "total_cost": float(total_cost), } - #print(f"DEBUG: Final stats costs (from dictionary) - Interaction: ${final_stats['interaction_cost']:.6f}, Total: ${final_stats['total_cost']:.6f}") - #print(f"DEBUG: Cost types in dictionary - Interaction: {type(final_stats['interaction_cost'])}, Total: {type(final_stats['total_cost'])}") - # At the end of streaming, finish the streaming context if we were using it if streaming_context: # Create a direct copy of the costs to ensure they remain as floats direct_stats = final_stats.copy() direct_stats["interaction_cost"] = float(interaction_cost) direct_stats["total_cost"] = float(total_cost) - - print(f"\nDEBUG: Final stats before finish_agent_streaming:") - print(f"DEBUG: Direct stats costs - Interaction: ${direct_stats['interaction_cost']:.6f}, Total: ${direct_stats['total_cost']:.6f}") - print(f"DEBUG: Direct stats types - Interaction: {type(direct_stats['interaction_cost'])}, Total: {type(direct_stats['total_cost'])}") - # Use the direct copy with guaranteed float costs finish_agent_streaming(streaming_context, direct_stats) # If we're not using rich streaming and not suppressing output, use old method diff --git a/src/cai/util.py b/src/cai/util.py index 7635ef5a..4bab6da4 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -367,7 +367,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals current_cost = float(interaction_cost) if interaction_cost is not None else 0.0 except (ValueError, TypeError): current_cost = 0.0 - # print(f"DEBUG _create_token_display: Current cost after conversion: {current_cost}") + tokens_text.append(f"(${current_cost:.4f}) ", style="bold") # Separator @@ -387,7 +387,7 @@ def _create_token_display( # pylint: disable=too-many-arguments,too-many-locals total_cost_value = float(total_cost) if total_cost is not None else 0.0 except (ValueError, TypeError): total_cost_value = 0.0 - # print(f"DEBUG _create_token_display: Total cost after conversion: {total_cost_value}") + tokens_text.append(f"(${total_cost_value:.4f}) ", style="bold") # Separator @@ -586,13 +586,10 @@ def finish_agent_streaming(context, final_stats=None): total_output_tokens = final_stats.get("total_output_tokens") total_reasoning_tokens = final_stats.get("total_reasoning_tokens") - # CRITICAL FIX: Ensure costs are properly extracted and preserved as floats + # Ensure costs are properly extracted and preserved as floats interaction_cost = float(final_stats.get("interaction_cost", 0.0)) total_cost = float(final_stats.get("total_cost", 0.0)) - #print(f"\nDEBUG finish_agent_streaming: Received costs from final_stats - Interaction: {interaction_cost}, Total: {total_cost}") - #print(f"DEBUG finish_agent_streaming: Type of interaction_cost: {type(interaction_cost)}, Type of total_cost: {type(total_cost)}") - if (interaction_input_tokens is not None and interaction_output_tokens is not None and interaction_reasoning_tokens is not None and @@ -606,9 +603,6 @@ def finish_agent_streaming(context, final_stats=None): if total_cost is None or total_cost == 0.0: total_cost = calculate_model_cost(context["model"], total_input_tokens, total_output_tokens) - #print(f"DEBUG finish_agent_streaming: Costs before passing to _create_token_display - Interaction: {interaction_cost}, Total: {total_cost}") - #print(f"DEBUG finish_agent_streaming: Type of costs before passing - Interaction: {type(interaction_cost)}, Total: {type(total_cost)}") - tokens_text = _create_token_display( interaction_input_tokens, interaction_output_tokens,