Mixins

This file contains the mixins for the provider model.

class smarter.apps.provider.services.text_completion.lib.mixins.ChatDbMixin(*args, **kwargs)[source]

Bases: AccountMixin

Mixin for database-related methods for provider models.

This mixin provides database access and persistence logic for chat provider models, including management of chat sessions, chat history, plugin/tool usage, and charge records. It is intended to be used as a base class for provider implementations that require integration with the Smarter database models. This provides layers of abstraction for asynchronously creating history and charge records resulting from provider requests.

Key Features:

  • Manages retrieval and caching of chat, chat history, tool calls, plugin usage, and charge records.

  • Provides properties for accessing and updating chat-related data.

  • Supports insertion of new tool call, plugin usage, and charge records via asynchronous tasks.

  • Aggregates token usage statistics for billing and analytics.

Usage:

Inherit from this mixin in a provider class to enable database-backed chat session and usage tracking.

Example:
class MyProvider(ChatDbMixin):
    def custom_method(self):
        # Access chat history
        history = self.chat_history
        # Insert a charge
        self.db_insert_charge(...)
__init__(*args, **kwargs)[source]

Initialize the ChatDbMixin.

This constructor sets up the database-related attributes for the provider model, including chat session, tool call, plugin usage, charge, and chat history references. It attempts to retrieve the current chat session using a session key if provided, or falls back to a chat object in kwargs.

Parameters:
  • *args (tuple) – Positional arguments passed to the superclass constructor.

  • **kwargs (dict) –

    Keyword arguments passed to the superclass constructor. Recognized keys:
    • SMARTER_CHAT_SESSION_KEY_NAME (str): Default is ‘session_key’. Session key for the chat session.

    • chat (Chat): Chat instance to use if session key is not provided.

Example

mixin = ChatDbMixin(chat=my_chat)
# or
mixin = ChatDbMixin(session_key="abc123")
property chat: Chat | None

Get the current chat session instance.

This property returns the active Chat object associated with the provider, or None if no chat session is set. It is used to access chat-specific data and operations throughout the provider’s logic.

Returns:

The current chat session instance, or None if not set.

Return type:

Chat or None

Example

chat = provider.chat
if chat is not None:
    print(chat.session_key)
property chat_history: QuerySet | None

Get the chat history queryset for the current chat session.

This property returns a Django QuerySet of ChatHistory objects associated with the current chat session. If no chat is set, or if there is no history, returns None. The queryset is cached for efficiency.

Returns:

QuerySet of chat history records for the current chat, or None if unavailable.

Return type:

QuerySet[ChatHistory] or None

Example

history_qs = provider.chat_history
if history_qs is not None:
    for record in history_qs:
        print(record.created_at, record.messages)
property db_charges: QuerySet

Get the queryset of charge records for the current chat session and UserProfile.

This property returns a Django QuerySet of Charge objects filtered by the current user profile and chat session key. If either the user profile or chat is not set, returns None. The queryset is cached for efficiency.

Each Charge record typically contains fields such as:
  • prompt_tokens (int): Number of prompt tokens used.

  • completion_tokens (int): Number of completion tokens used.

  • total_tokens (int): Total tokens used.

Returns:

QuerySet of charge records for the current session, or None if unavailable.

Return type:

QuerySet[Charge] or None

Example

charges = provider.db_charges
if charges is not None:
    for charge in charges:
        print(charge.prompt_tokens, charge.completion_tokens, charge.total_tokens)
property db_chat_plugin_usage: QuerySet

Get the chat plugin usage instance for the current chat session.

This property returns the ChatPluginUsage object associated with the current chat session, if available. The result is cached for efficiency. If no chat is set or no plugin usage exists, returns None.

Returns:

The chat plugin usage instance for the current chat, or None if unavailable.

Return type:

ChatPluginUsage or None

Example

plugin_usage = provider.db_chat_plugin_usage
if plugin_usage is not None:
    print(plugin_usage.plugin, plugin_usage.input_text)
property db_chat_tool_call: QuerySet

Get the queryset of chat tool call records for the current chat session.

This property returns a Django QuerySet of ChatToolCall objects associated with the current chat session. If no chat is set, returns an empty queryset. The queryset is cached for efficiency.

Returns:

QuerySet of chat tool call records for the current chat session, or an empty queryset if unavailable.

Return type:

QuerySet[ChatToolCall]

Example

tool_calls = provider.db_chat_tool_call
for tool_call in tool_calls:
    print(tool_call.function_name, tool_call.created_at)
db_insert_charge(provider, charge_type, completion_tokens, prompt_tokens, total_tokens, model, reference)[source]

Insert a new charge record for the current account and chat session.

This method asynchronously creates a new Charge record associated with the current account, user, and chat session. It is typically used to persist billing or usage information for a model completion or related operation.

Parameters:
  • provider (str) – The name of the provider (e.g., “openai”, “anthropic”).

  • charge_type (str) – The type of charge (e.g., “completion”, “plugin”).

  • completion_tokens (int) – The number of completion tokens used.

  • prompt_tokens (int) – The number of prompt tokens used.

  • total_tokens (int) – The total number of tokens used.

  • model (str) – The model name or identifier (e.g., “gpt-4”).

  • reference (str) – An external reference or identifier for the charge (e.g., request ID).

Raises:

SmarterValueError – If the account or chat is not set.

Example

provider.db_insert_charge(
    provider="openai",
    charge_type="completion",
    completion_tokens=42,
    prompt_tokens=58,
    total_tokens=100,
    model="gpt-4",
    reference="req-12345"
)
db_insert_chat_plugin_usage(*args, **kwargs)[source]

Insert a chat plugin usage record for the specified chat session.

This method creates a new ChatPluginUsage record associated with the given chat session. The insertion is performed asynchronously using a background task. If no chat is provided, the method logs a warning and returns without action.

Parameters:
  • chat (Chat, required) – The chat instance for which to record plugin usage.

  • plugin (Plugin, optional) – The plugin instance used in the chat (default: None).

  • input_text (str, optional) – The input text sent to the plugin (default: None).

Example

provider.db_insert_chat_plugin_usage(
    chat=my_chat,
    plugin=my_plugin,
    input_text="search for weather"
)
db_insert_chat_tool_call(*args, **kwargs)[source]

Insert a chat tool call record for the current chat session.

This method creates a new ChatToolCall record associated with the current chat session. The insertion is performed asynchronously using a background task. If no chat is set, the method returns without action.

Parameters:
  • plugin (Plugin, optional) – The plugin instance associated with the tool call (default: None).

  • function_name (str, optional) – The name of the function called (default: None).

  • function_args (dict or str, optional) – Arguments passed to the function (default: None).

  • request (dict or str, optional) – The request payload (default: None).

  • response (dict or str, optional) – The response payload (default: None).

Example

provider.db_insert_chat_tool_call(
    plugin=my_plugin,
    function_name="my_function",
    function_args={"arg1": 123},
    request={"input": "foo"},
    response={"output": "bar"}
)
property db_message_history: list[dict] | None

Get the most recently persisted messages in the chat history.

This property returns the latest list of messages stored in the chat history for the current chat session. If no messages are available, returns None. The result is cached for efficiency.

Returns:

The most recent list of message dictionaries from chat history, or None if unavailable.

Return type:

list[dict] or None

Example

messages = provider.db_message_history
if messages:
    for msg in messages:
        print(msg['role'], msg['content'])
db_refresh()[source]

Refresh the provider instance and its cached database attributes.

This method refreshes the chat instance from the database and resets the cached charges queryset. Use this method to ensure the provider has the latest data after external changes to the chat or related records.

Example

provider.db_refresh()
# Now provider.db_charges and related properties are up to date
property db_total_completion_tokens: int

Get the total number of completion tokens used in the current chat session.

This property aggregates the completion_tokens field across all charge records for the current chat session and account. If no charges are available, returns 0.

Returns:

The total number of completion tokens used, or 0 if unavailable.

Return type:

int

Example

total_completion = provider.db_total_completion_tokens
print(f"Completion tokens used: {total_completion}")
property db_total_prompt_tokens: int

Get the total number of prompt tokens used in the current chat session.

This property aggregates the prompt_tokens field across all charge records for the current chat session and account. If no charges are available, returns 0.

Returns:

The total number of prompt tokens used, or 0 if unavailable.

Return type:

int

Example

total_prompt = provider.db_total_prompt_tokens
print(f"Prompt tokens used: {total_prompt}")
property db_total_tokens: dict | None

Get a dictionary containing the total prompt, completion, and overall tokens used.

This property returns a dictionary with the total number of prompt tokens, completion tokens, and overall tokens used in the current chat session. The values are aggregated from all charge records for the session.

Returns:

A dictionary with keys ‘prompt_tokens’, ‘completion_tokens’, and ‘total_tokens’, or None if no charge data is available.

Return type:

dict or None

Example

totals = provider.db_total_tokens
if totals:
    print(f"Prompt: {totals['prompt_tokens']}, Completion: {totals['completion_tokens']}, Total: {totals['total_tokens']}")
property db_total_total_tokens: int

Get the total number of tokens used in the current chat session.

This property aggregates the total_tokens field across all charge records for the current chat session and account. If no charges are available, returns 0.

Returns:

The total number of tokens used, or 0 if unavailable.

Return type:

int

Example

total_tokens = provider.db_total_total_tokens
print(f"Total tokens used: {total_tokens}")
property provider: Provider | None

Get the Provider instance associated with this provider model.

This property returns the Provider object that represents the provider configuration for this model. It is typically used to access provider-specific settings and information.

Returns:

The Provider instance associated with this model, or None if not set.

Return type:

Provider or None

Example

provider_instance = provider.provider
if provider_instance:
    print(provider_instance.name)
property provider_name: str | None

Get the provider name associated with this provider model.

This property returns the name of the provider that this model is configured to use. It is typically used to determine which provider’s handler to invoke for chat completions.

Returns:

The name of the provider, or None if not set.

Return type:

str or None

Example

print(provider.provider_name)
property ready: bool

Indicates whether the mixin and its dependencies are ready for use.

This property checks if both the superclass and the chat instance are ready. It is useful for determining if the provider is fully initialized and can interact with the database and chat session.

Returns:

True if both the superclass and chat are ready, False otherwise.

Return type:

bool

Example

if provider.ready:
    # Safe to proceed with database operations
    ...