Class OpenAiCompatibleModelMessage

All Implemented Interfaces:
PropertyChangeSource, Rebindable

public class OpenAiCompatibleModelMessage extends AbstractModelMessage<OpenAiCompatibleResponse>
Concrete model message implementation for OpenAI-compatible Chat Completion APIs. Handles content accumulation, finish reason mapping, and tool call streaming buffers.
Author:
anahata
  • Field Details

    • insideReasoningTags

      private boolean insideReasoningTags
      State flag indicating if the parser is currently inside a reasoning tag.
    • callArgsBuffers

      private transient Map<Integer, StringBuilder> callArgsBuffers
      Buffers for accumulating streaming tool call arguments, keyed by their index in the 'tool_calls' array.
    • callIds

      private transient Map<Integer,String> callIds
      Maps tool call indices to their stable API-provided unique IDs.
    • callNames

      private transient Map<Integer,String> callNames
      Maps tool call indices to the requested function name.
  • Constructor Details

    • OpenAiCompatibleModelMessage

      public OpenAiCompatibleModelMessage(Agi agi, String modelId)
      Constructs a new, empty compatible message for streaming.
      Parameters:
      agi - The parent session.
      modelId - The model ID.
    • OpenAiCompatibleModelMessage

      public OpenAiCompatibleModelMessage(Agi agi, String modelId, com.fasterxml.jackson.databind.JsonNode choiceNode, OpenAiCompatibleResponse response, OpenAiCompatibleReasoningStyle reasoningStyle, String reasoningFieldName, List<String> reasoningTags)
      Constructs a message from a final (non-streaming) choice node.
      Parameters:
      agi - The parent session.
      modelId - The model ID.
      choiceNode - The 'choice' node from the chat completion response.
      response - The parent response object.
      reasoningStyle - The strategy for thought extraction.
      reasoningFieldName - The field for thoughts (if using FIELD style).
      reasoningTags - The tags for thoughts (if using TAGS style).
  • Method Details

    • updateFromNode

      public void updateFromNode(com.fasterxml.jackson.databind.JsonNode choice, OpenAiCompatibleReasoningStyle reasoningStyle, String reasoningFieldName, List<String> reasoningTags)
      Updates the message content and state from a JSON node (choice, item, or event). Handles both streaming deltas and final message objects from the Chat Completions API.
      Parameters:
      choice - The JSON node to parse.
      reasoningStyle - The strategy for extracting thoughts.
      reasoningFieldName - The field name for reasoning content (if using FIELD style).
      reasoningTags - The tags for reasoning content (if using TAGS style).
    • updateToolCall

      public void updateToolCall(com.fasterxml.jackson.databind.JsonNode callNode)
      Updates a single tool call from a JSON node.
      Parameters:
      callNode - The JSON node containing the tool call (or delta).
    • flushToolCalls

      public void flushToolCalls()
      Flushes any buffered tool calls (used during streaming). This ensures that partial tool call arguments are fully assembled and registered in the tool manager.
    • setFinishReasonFromOpenAi

      public void setFinishReasonFromOpenAi(String fr)
      Sets the finish reason from a raw OpenAI string.
      Parameters:
      fr - The raw finish reason string (e.g., "stop", "length").
    • mapFinishReason

      private FinishReason mapFinishReason(String reason)
      Maps a standard OpenAI finish reason string to the Anahata enum.
      Parameters:
      reason - The raw string from the API.
      Returns:
      The corresponding FinishReason.
    • isEffectivelyPruned

      public boolean isEffectivelyPruned()
      Calculates the EFFECTIVE pruned state of this message. A message is effectively pruned ONLY if it contains no visible (un-pruned) parts. A model message is never effectively pruned while it is streaming.

      An actively streaming model message is never considered pruned, even if its parts list is temporarily empty while the first chunk is being parsed.

      Overrides:
      isEffectivelyPruned in class AbstractModelMessage<OpenAiCompatibleResponse>
      Returns:
      true if the message is effectively pruned.
    • appendContent

      public void appendContent(String text)
      Appends text to the main content part or creates a new one.
      Parameters:
      text - The text to append.
    • appendThoughts

      public void appendThoughts(String text)
      Appends text to the reasoning/thought part or creates a new one.
      Parameters:
      text - The thought text to append.
    • appendTaggedContent

      public void appendTaggedContent(String text, String startTag, String endTag)
      Appends text while detecting and extracting reasoning content wrapped in tags.
      Parameters:
      text - The text containing potential tags.
      startTag - The opening tag (e.g., <think>).
      endTag - The closing tag (e.g., </think>).