Skip to content

fix(runner): tolerate Pydantic tool_call objects in verbose logging#56

Open
Islam Assanov (islamborghini) wants to merge 1 commit into
dedalus-labs:mainfrom
islamborghini:fix/verbose-pydantic-tool-call
Open

fix(runner): tolerate Pydantic tool_call objects in verbose logging#56
Islam Assanov (islamborghini) wants to merge 1 commit into
dedalus-labs:mainfrom
islamborghini:fix/verbose-pydantic-tool-call

Conversation

@islamborghini
Copy link
Copy Markdown

What Changed

verbose=True crashed on any tool-calling response because seven verbose-print sites called tc.get(...) on ChatCompletionMessageToolCall Pydantic objects, which have no .get().

Two shape-tolerant helpers (_tc_name, _tc_id) consolidate the dict-or-Pydantic access already present at core.py:582 and core.py:1167 and replace the buggy sites in _execute_turns_{async,sync} and _execute_streaming_{async,sync}. Regression test pins the original bug shape.

No public-API change; no behaviour change with verbose=False.

Test Plan

Live reproducer (against main, fails before this patch):

from dedalus_labs import Dedalus
from dedalus_labs.lib.runner import DedalusRunner

def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

client = Dedalus()  # uses DEDALUS_API_KEY
runner = DedalusRunner(client, verbose=True)
runner.run(model="openai/gpt-5-nano",
           input="What is 3 + 4? You MUST call the add tool.",
           tools=[add])

Before: AttributeError: 'ChatCompletionMessageToolCall' object has no attribute 'get'.
After: prints 🔧 Tool calls in response: ['add'] and returns "3 + 4 equals 7.".

Automated:

  • uv run pytest tests/lib/test_runner_verbose.py — 4 tests (dict shape, Pydantic shape, defaults, pinned bug shape).
  • uv run pytest tests/ --ignore=tests/api_resources — 519 passed, 3 skipped.

Closes #54

@cursor
Copy link
Copy Markdown

cursor Bot commented May 13, 2026

PR Summary

Low Risk
Low risk: changes are limited to verbose logging paths and add a small regression test, with no effect when verbose=False. The main risk is minor formatting/diagnostics differences in verbose output.

Overview
Fixes verbose=True crashes when tool calls are returned as Pydantic objects by centralizing tool-call field access in _tc_name/_tc_id and using these helpers across runner verbose print sites.

Adds a regression test (tests/lib/test_runner_verbose.py) covering dict-shaped vs Pydantic-shaped tool calls, default handling, and the original failing .get() behavior.

Reviewed by Cursor Bugbot for commit 76bac15. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Reviewed by Cursor Bugbot for commit 0bb40be. Configure here.

Comment thread src/dedalus_labs/lib/runner/core.py
@islamborghini Islam Assanov (islamborghini) force-pushed the fix/verbose-pydantic-tool-call branch from 0bb40be to 76bac15 Compare May 13, 2026 07:26
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.

verbose=True crashes on any tool-calling response (AttributeError on ChatCompletionMessageToolCall)

1 participant