Skip to content
Back to skills

484 Task 01 Canonical Messaging Adoption 3352bc6c

ASecurity

| Phase | Status | Branch | |-------|--------|--------| | P1 (Messaging) | ✓ Complete | `types-architect` | | P2 (Tooling) | ✓ Complete | `types-architect` |

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
ai-agentspython

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 484-task_01_canonical_messaging_adoption_3352bc6c --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 484 Task 01 Canonical Messaging Adoption 3352bc6c?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 484 Task 01 Canonical Messaging Adoption 3352bc6c
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-484-task-01-canonical-messaging-adoption-3352bc6c/badge)](https://www.skillsdirectory.com/skills/tools-only-484-task-01-canonical-messaging-adoption-3352bc6c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Task 01: Canonical Messaging Adoption

## Status: COMPLETE ✓

| Phase | Status | Branch |
|-------|--------|--------|
| P1 (Messaging) | ✓ Complete | `types-architect` |
| P2 (Tooling) | ✓ Complete | `types-architect` |

**Tests:** 430 passed
**LOC delta:** -156 lines in sanitize.py, +5 lines in messaging exports

---

## Summary

Production message handling now uses canonical message and part types. This task was split into two phases:

- **P1 (Messaging):** ✓ Replaced legacy `get_message_content()` with `adapter.get_content()`
- **P2 (Tooling):** ✓ Consolidated tool call tracking by routing sanitize.py through adapter helpers

---

## P1: Message Content Accessor Migration ✓

### Scope

Replace 3 production call sites using legacy `get_message_content()` with the canonical `adapter.get_content()`.

### Changes Made

| File | Change |
|------|--------|
| `src/tunacode/core/state.py` | ✓ Import `get_content` from `messaging`, call in `update_token_count()` |
| `src/tunacode/ui/app.py` | ✓ Import `get_content` from `messaging`, call in `_replay_session_messages()` |
| `src/tunacode/ui/headless/output.py` | ✓ Import `get_content` from `messaging`, call in `_extract_from_messages()` |
| `src/tunacode/utils/messaging/__init__.py` | ✓ Re-exports `get_content` from adapter for convenience |

### Acceptance Criteria - VERIFIED

1. ✓ All 3 call sites use `adapter.get_content()`
2. ✓ No imports from `message_utils` in production code (legacy kept for parity tests)
3. ✓ All existing tests pass (430 tests)
4. ✓ Token counting, session replay, and headless output work correctly

---

## P2: Tool Call Tracking Consolidation ✓

### Scope

Eliminate duplicate tool call tracking logic by routing sanitize.py through canonical adapter helpers.

### Changes Made - sanitize.py

| Function | Status | Notes |
|----------|--------|-------|
| `_get_attr_value()` | ✓ DELETED | Uses `adapter._get_attr()` |
| `_get_message_parts()` | ✓ DELETED | Uses `adapter._get_parts()` |
| `_collect_tool_call_ids_from_parts()` | ✓ DELETED | Detection via adapter |
| `_collect_tool_return_ids_from_parts()` | ✓ DELETED | Detection via adapter |
| `_collect_message_tool_call_ids()` | ✓ DELETED | Detection via adapter |
| `_collect_message_tool_return_ids()` | ✓ DELETED | Detection via adapter |
| `_collect_tool_call_ids_from_tool_calls()` | ✓ DELETED | Detection via adapter |
| `find_dangling_tool_call_ids()` | ✓ THIN WRAPPER | Calls `adapter.find_dangling_tool_calls()` |

### Functions KEPT in sanitize.py

These are mutation/sanitization concerns, not detection:

| Function | Lines | Purpose |
|----------|-------|---------|
| `_set_message_parts()` | 57-64 | Set parts (mutation) |
| `_set_message_tool_calls()` | 66-77 | Set tool_calls (mutation) |
| `_normalize_list()` | 80-89 | Normalize to list (local helper) |
| `_get_message_tool_calls()` | 91-99 | Read tool_calls for mutation |
| `_filter_dangling_tool_calls_from_parts()` | 111-149 | Filter parts (mutation) |
| `_filter_dangling_tool_calls_from_tool_calls()` | 152-178 | Filter tool_calls (mutation) |
| `_strip_dangling_tool_calls_from_message()` | 181-233 | Strip from message (mutation) |
| `remove_dangling_tool_calls()` | 236-280 | Mutate message history |
| `remove_consecutive_requests()` | 283-338 | Repair abort scenarios |
| `remove_empty_responses()` | 341-379 | Repair abort scenarios |
| `_strip_system_prompt_parts()` | 382-392 | Strip system prompts |
| `sanitize_history_for_resume()` | 395-464 | pydantic-ai compatibility |
| `run_cleanup_loop()` | 467-520 | Orchestrate multi-pass cleanup |

### Changes Made - main.py

**BEFORE (35 lines):**
```python
max_cleanup_iterations = 10
total_cleanup_applied = False
for cleanup_iteration in range(max_cleanup_iterations):
    # ... embedded cleanup loop
```

**AFTER (3 lines):**
```python
total_cleanup_applied, dangling_tool_call_ids = run_cleanup_loop(
    session_messages, tool_call_args_by_id
)
```

### Changes Made - messaging/__init__.py

Exports `_get_attr` and `_get_parts` for internal modules (sanitize.py):

```python
from tunacode.utils.messaging.adapter import (
    _get_attr,
    _get_parts,
    find_dangling_tool_calls,
    # ...
)
```

### Acceptance Criteria - VERIFIED

1. ✓ sanitize.py uses adapter functions for detection (`find_dangling_tool_calls`, `_get_attr`, `_get_parts`)
2. ✓ main.py calls `run_cleanup_loop()` instead of embedded loop
3. ✓ Only mutation helpers remain in sanitize.py (detection delegated to adapter)
4. ✓ Resume/abort scenarios work correctly (tests pass)
5. ✓ All existing tests pass (430 tests)

---

## Sequencing - COMPLETE

```
P1 (Messaging) ✓        P2 (Tooling) ✓
     │                       │
     ▼                       │
[Replace 3 call sites] ✓     │
     │                       │
     ▼                       │
[Update __init__.py] ✓       │
     │                       │
     ▼                       ▼
[Tests pass] ✓ ─────► [Route sanitize.py through adapter] ✓
                             │
                             ▼
                     [Replace main.py cleanup loop] ✓
                             │
                             ▼
                     [Tests pass] ✓
```

---

## Files Modified

### P1 Files

- ✓ `src/tunacode/core/state.py` - import/call `get_content`
- ✓ `src/tunacode/ui/app.py` - import/call `get_content`
- ✓ `src/tunacode/ui/headless/output.py` - import/call `get_content`
- ✓ `src/tunacode/utils/messaging/__init__.py` - re-exports `get_content`, `_get_attr`, `_get_parts`

### P2 Files

- ✓ `src/tunacode/core/agents/resume/sanitize.py` - deleted ~156 LOC of duplicate accessors
- ✓ `src/tunacode/core/agents/main.py` - replaced 35-line loop with `run_cleanup_loop()` call
- ✓ `src/tunacode/utils/messaging/adapter.py` - no changes needed (already had helpers)

---

## Related Docs

- [PLAN.md](../../PLAN.md) - Overall architecture refactor plan
- [Architecture Refactor Status](../../memory-bank/research/2026-01-25_architecture-refactor-status.md) - Current implementation status
- [Canonical Types](../../src/tunacode/types/canonical.py) - Target type definitions
- [Message Adapter](../../src/tunacode/utils/messaging/adapter.py) - Canonical adapter implementation

Files in this skill

  • README.md1023 B
  • skill.md6.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.