free-claude-code/tests/api
Ali Khokhar 755a3851f7
Use batch delete boundary for messaging (#996)
## Problem

Messaging cleanup had two public queued delete paths. Command code could
loop single-message deletes and bypass Telegram batch deletion.

## Changes

| Before | After |
| --- | --- |
| Workflow code could call `queue_delete_message` or
`queue_delete_messages`. | Workflow code calls only
`queue_delete_messages`. |
| Telegram `/clear` cleanup used one API request per message. | Telegram
`/clear` cleanup uses `deleteMessages` in chunks of 100. |
| The outbox dedupe key used Python process hashing. | The outbox dedupe
key uses a stable SHA-based digest. |
| Voice and smoke cleanup depended on the single-delete queue API. |
Voice and smoke cleanup pass one-item delete lists. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR moves messaging cleanup to a list-based delete boundary. The
main changes are:

- `/clear` now sends collected message IDs through
`queue_delete_messages`.
- Telegram deletion uses `deleteMessages` in 100-message chunks with
per-message fallback.
- Discord keeps per-message deletion behind the list-based outbound API.
- Delete-batch dedupe keys now use a stable SHA digest instead of Python
process hashing.
- Voice cleanup, smoke fakes, protocol tests, and messaging tests were
updated for the new delete boundary.
</details>

<h3>Confidence Score: 5/5</h3>

Safe to merge with minimal risk.

The change is well-scoped to the messaging delete boundary, keeps
platform-specific best-effort behavior, addresses the batch-fallback
concern, updates protocol consumers and tests, and includes the required
version and lockfile bump.

No files require special attention.

<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>

**What T-Rex did**
- No execution evidence is available for this session; no harness was
created, no tests were run, and no artifacts were produced.

<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>

<details open><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| messaging/commands.py | Routes `/clear` cleanup through
`queue_delete_messages` once per collected message set while preserving
best-effort state cleanup. |
| messaging/platforms/outbox.py | Removes single-delete queueing,
snapshots delete batches, and uses a stable SHA digest for delete dedupe
keys. |
| messaging/platforms/telegram_io.py | Adds Telegram `deleteMessages`
batching with 100-message chunks and per-message fallback when batch
deletion fails. |
| messaging/platforms/discord_io.py | Removes the public single
queued-delete wrapper and backs queued deletion with the list-based
outbox API. |
| messaging/platforms/voice_flow.py | Changes shared voice cleanup call
sites to submit one-item lists to the delete queue. |
| messaging/platforms/ports.py | Narrows the outbound protocol to the
list-based delete queue method. |
| tests/messaging/test_telegram.py | Adds Telegram batch delete,
chunking, and fallback coverage. |
| tests/messaging/test_platform_outbox.py | Covers stable delete-batch
dedupe keys and snapshotting mutable message ID lists before queueing. |
| pyproject.toml | Bumps the package patch version for the production
messaging changes. |
| uv.lock | Updates the editable package version in the lockfile to
match `pyproject.toml`. |

</details>

<details open><summary><h3>Sequence Diagram</h3></summary>

<a href="#gh-light-mode-only">

```mermaid
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Command as /clear or voice cleanup
participant Outbound as OutboundMessenger.queue_delete_messages
participant Outbox as PlatformOutbox
participant Telegram as TelegramMessenger
participant Discord as DiscordMessenger
participant API as Platform API

Command->>Outbound: queue_delete_messages(chat_id, message_ids)
Outbound->>Outbox: snapshot IDs and dedupe batch
alt Telegram
    Outbox->>Telegram: delete_messages(chat_id, ids)
    loop chunks of 100
        Telegram->>API: deleteMessages(chat_id, chunk)
        alt batch fails
            Telegram->>API: deleteMessage(chat_id, each id)
        end
    end
else Discord
    Outbox->>Discord: delete_messages(chat_id, ids)
    loop each id
        Discord->>API: fetch_message + delete
    end
end
```

</a>
<a href="#gh-dark-mode-only">

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Command as /clear or voice cleanup
participant Outbound as OutboundMessenger.queue_delete_messages
participant Outbox as PlatformOutbox
participant Telegram as TelegramMessenger
participant Discord as DiscordMessenger
participant API as Platform API

Command->>Outbound: queue_delete_messages(chat_id, message_ids)
Outbound->>Outbox: snapshot IDs and dedupe batch
alt Telegram
    Outbox->>Telegram: delete_messages(chat_id, ids)
    loop chunks of 100
        Telegram->>API: deleteMessages(chat_id, chunk)
        alt batch fails
            Telegram->>API: deleteMessage(chat_id, each id)
        end
    end
else Discord
    Outbox->>Discord: delete_messages(chat_id, ids)
    loop each id
        Discord->>API: fetch_message + delete
    end
end
```

</a>
</details>

<sub>Reviews (2): Last reviewed commit: ["Preserve Telegram batch delete
fallback"](87090edcd9)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=41993526)</sub>

<!-- /greptile_comment -->
2026-07-05 22:07:09 -07:00
..
test_admin.py add telegram proxy support (#988) 2026-07-05 20:59:23 -07:00
test_anthropic_request_passthrough.py Remove legacy future annotation imports (#982) 2026-07-04 21:41:51 -07:00
test_api.py Refactor provider runtime ownership (#925) 2026-06-27 15:04:34 -07:00
test_api_handlers.py Remove legacy future annotation imports (#982) 2026-07-04 21:41:51 -07:00
test_app_lifespan_and_errors.py Use batch delete boundary for messaging (#996) 2026-07-05 22:07:09 -07:00
test_auth.py fix: normalize proxy auth token whitespace 2026-06-03 23:48:29 -07:00
test_dependencies.py Add MiniMax provider (#980) 2026-07-04 19:28:59 -07:00
test_detection.py Fix Claude auto-mode classifier thinking policy (#865) 2026-06-19 12:24:56 -07:00
test_model_listing.py Refactor provider runtime ownership (#925) 2026-06-27 15:04:34 -07:00
test_model_router.py Add MiniMax provider (#980) 2026-07-04 19:28:59 -07:00
test_models_validators.py fix: accept system role messages 2026-05-29 16:16:48 -07:00
test_openai_responses.py Remove legacy future annotation imports (#982) 2026-07-04 21:41:51 -07:00
test_optimization_handlers.py Added optimization logging 2026-03-01 01:02:59 -08:00
test_request_utils.py fix: handle disallowed special tokens in tiktoken encoder (#382) 2026-05-10 17:30:24 -07:00
test_request_utils_filepaths_and_suggestions.py Improved optimizations to decrease llm calls further and increase throughput 2026-02-18 17:54:41 -08:00
test_response_models.py new linter rules and fixes 2026-02-18 04:13:41 -08:00
test_routes_optimizations.py Refactor messaging workflow architecture (#852) 2026-06-18 13:10:02 -07:00
test_runtime_safe_logging.py Refactor messaging around explicit ports (#878) 2026-06-20 09:35:38 -07:00
test_safe_logging.py Remove legacy future annotation imports (#982) 2026-07-04 21:41:51 -07:00
test_validation_log.py Major refactor: API, providers, messaging, and Anthropic protocol 2026-04-26 03:01:14 -07:00
test_web_server_tools.py Fix stream:false requests returning malformed response (matches #917, #868, #771, #497 symptom) (#977) 2026-07-04 20:47:41 -07:00