Skip to content

fix(session): expand tool_call_id field limit & preserve tool function name in transcript - #95

Open
nipunanr wants to merge 3 commits into
frappe:developfrom
MISL-Holdings:fix/flow-session-bugs
Open

fix(session): expand tool_call_id field limit & preserve tool function name in transcript#95
nipunanr wants to merge 3 commits into
frappe:developfrom
MISL-Holdings:fix/flow-session-bugs

Conversation

@nipunanr

Copy link
Copy Markdown

Summary

This PR resolves two critical issues in Flow session message persistence and LiteLLM/Gemini API integration:

  1. Tool Call ID Truncation Error: Prevents CharacterLengthExceededError when models (such as Google Gemini, Antigravity, or deep-thinking models) generate long thought tool call IDs (>140 characters).
  2. Missing Tool Call ID Exception in LiteLLM: Ensures role: "tool" messages include their corresponding function name both during execution loops and when reconstructing conversation transcripts from stored DB session messages.

Problem & Root Cause

1. tool_call_id Truncation (CharacterLengthExceededError)

  • Symptom:
    Error: Flow Session Message, Row 16: 'Tool Call ID' (call_046343...) will get truncated, as max characters allowed is 140
    
  • Root Cause: In Flow Session Message (flow_session_message.json), tool_call_id was defined as Data (mapping to VARCHAR(140)). When advanced LLMs emitted long thought/tool call IDs (>140 chars), Frappe raised a validation error during session.save(), causing the Flow run to fail.

2. LiteLLM / Gemini Tool Matching Error

  • Symptom:
    litellm.APIConnectionError: Missing corresponding tool call for tool response message. Received - message={'role': 'tool', 'toolcallid': '...'}, last_message_with_tool_calls={...}
    
  • Root Cause: LiteLLM's Gemini transformer requires every role: "tool" response message to specify its function name. If name is omitted, LiteLLM attempts to match tool_call_id against last_message_with_tool_calls. In multi-turn sessions or resumed runs with ID sanitization/mismatches, LiteLLM failed to resolve the name and threw an API error.

Proposed Changes

flow/flow/doctype/flow_session_message/flow_session_message.json & .py

  • Changed tool_call_id fieldtype from Data to Small Text (text in MariaDB).
  • Updated type annotations in flow_session_message.py to DF.SmallText | None.
  • Benefit: Removes string length truncation checks while supporting IDs up to 65,535 characters.

flow/lib/agent.py

  • Updated tool message construction in _loop() and _resume_loop() to explicitly attach "name": call.name to all role: "tool" messages.

flow/flow/doctype/flow_session/flow_session.py

  • Enhanced _row_to_message() and transcript() to map preceding assistant tool_calls to their function names when reading stored transcript rows.
  • Attached "name" to role: "tool" messages in transcript outputs.

How Has This Been Tested?

  1. Database Schema Verification:
    • Ran bench migrate and verified that tabFlow Session Message.tool_call_id column successfully converted to text.
  2. Unit & Integration Tests:
    • Executed bench run-tests --app flow. All 98 core agent unit tests passed cleanly (OK).

Copilot AI lite review requested due to automatic review settings August 10, 2026 10:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

The PR is not yet safe to merge because subsequent and resumed prompts still omit persisted tool function names.

_build_prompt_messages() continues reconstructing rows without the ID-to-name map, leaving the previously reported LiteLLM/Gemini failure reachable.

Files Needing Attention: flow/flow/doctype/flow_session/flow_session.py

Reviews (2): Last reviewed commit: "docs: update PR_DESCRIPTION.md with erro..." | Re-trigger Greptile

Comment on lines +106 to +107
tool_call_id_to_name: dict[str, str] = {}
return [_row_to_message(row, tool_call_id_to_name) for row in self.messages]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Model prompts still lose tool names

When a persisted session is resumed or receives another turn, _build_prompt_messages() reconstructs rows without the ID-to-name map, so tool responses sent through LiteLLM still omit their function names and the targeted Gemini matching error remains reachable.

Fix in Claude Code Fix in Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants