Normalized message utilities to operate on tinyagent dict messages (role + content[type]) only. Token estimation and resume sanitization no longer attempt to interpret legacy pydantic-ai message objects, aligning with the “full rip-out” direction.
Context
During the tun-1658 tinyagent migration, history is persisted as tinyagent dicts:
Older utilities still had defensive support for pydantic-ai style parts/part_kind shapes.
Root Cause
Utility modules (notably token counting and some sanitize logic) were written to accept polymorphic message inputs and silently “do something” for objects with .parts/.content. With tinyagent dict messages, this both (a) masked stale session formats and (b) caused unnecessary canonicalization overhead.
Changes
src/tunacode/utils/messaging/token_counter.py
Now supports only tinyagent dict messages and CanonicalMessage.
Token estimation runs via to_canonical() + canonical parts, and counts tool-call metadata (tool_name, tool_call_id, args) heuristically.
src/tunacode/core/agents/resume/sanitize.py
_is_request_message() is now role-based on dict messages (no canonical conversion).
Removed to_canonical dependency from sanitize (canonicalization remains in find_dangling_tool_calls() only).
src/tunacode/utils/messaging/adapter.py
Refactored to_canonical() / from_canonical() into smaller helpers to satisfy ruff complexity constraints (no behavior change intended).
Tests updated to use tinyagent message shapes:
tests/unit/utils/test_token_counter.py
tests/unit/test_sanitize_canonicalization.py
Behavioral Impact
Token estimation now fails loudly if non-tinyagent message objects appear in history.
Resume sanitization no longer performs redundant canonical conversions when scanning for consecutive request messages.
No user-facing UI rendering changes yet (handled in Phase 7).
Related Cards
[[tun-1658-phase5-cleanup]]
1---2name: 2795-tun-1658-phase6-messaging-normalization-a07396d73description: Summary4---56## Summary7Normalized message utilities to operate on tinyagent dict messages (role + content[type]) only. Token estimation and resume sanitization no longer attempt to interpret legacy pydantic-ai message objects, aligning with the “full rip-out” direction.89## Context10During the tun-1658 tinyagent migration, history is persisted as tinyagent dicts:11- assistant: `{role: "assistant", content: [{type: "text"|"thinking"|"tool_call"|"image", ...}]}`12- tool result: `{role: "tool_result", tool_call_id: "...", content: [...]}`1314Older utilities still had defensive support for pydantic-ai style `parts`/`part_kind` shapes.1516## Root Cause17Utility modules (notably token counting and some sanitize logic) were written to accept polymorphic message inputs and silently “do something” for objects with `.parts`/`.content`. With tinyagent dict messages, this both (a) masked stale session formats and (b) caused unnecessary canonicalization overhead.1819## Changes20- `src/tunacode/utils/messaging/token_counter.py`21 - Now supports **only** tinyagent dict messages and `CanonicalMessage`.22 - Token estimation runs via `to_canonical()` + canonical parts, and counts tool-call metadata (`tool_name`, `tool_call_id`, `args`) heuristically.23- `src/tunacode/core/agents/resume/sanitize.py`24 - `_is_request_message()` is now role-based on dict messages (no canonical conversion).25 - Removed `to_canonical` dependency from sanitize (canonicalization remains in `find_dangling_tool_calls()` only).26- `src/tunacode/utils/messaging/adapter.py`27 - Refactored `to_canonical()` / `from_canonical()` into smaller helpers to satisfy ruff complexity constraints (no behavior change intended).28- Tests updated to use tinyagent message shapes:29 - `tests/unit/utils/test_token_counter.py`30 - `tests/unit/test_sanitize_canonicalization.py`3132## Behavioral Impact33- Token estimation now fails loudly if non-tinyagent message objects appear in history.34- Resume sanitization no longer performs redundant canonical conversions when scanning for consecutive request messages.35- No user-facing UI rendering changes yet (handled in Phase 7).3637## Related Cards38- [[tun-1658-phase5-cleanup]]
Run npx skillmds@latest add tools-only/2795-tun-1658-phase6-messaging-normalization-a07396d7 in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Summary It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tools-only (@tools-only) published this skill. Their other Agent Skills are listed on their SkillMD profile.