Outcome: Vani now receives one writing instruction beside the existing
Surface: line in stable META. WhatsApp receives a short, single-message,
table-free contract. The ACP panel receives a markdown-and-tables contract with room for
a longer answer.
Surface: whatsapp. Writing surface: WhatsApp. Keep the answer short and in one message. Do not use tables. Surface: app. Writing surface: ACP panel. Markdown and tables render here; use them when helpful, and take the space the answer needs.
MiraConverseInput.channel_origin already defaults to app.
Pydantic records whether the caller actually supplied the field. Story-3115 adds writing
guidance only for an explicitly supplied app or whatsapp.
An omitted field keeps the exact pre-Story prompt, including the existing
Surface: app. line.
| Input | Prompt bytes | o200k tokens | Delta |
|---|---|---|---|
| channel omitted | 968 | 293 | 0 bytes · 0 tokens |
| explicit ACP/app | 1,090 | 318 | +122 bytes · +25 tokens |
| explicit WhatsApp | 1,062 | 313 | +94 bytes · +20 tokens |
The omitted full text prompt remains 12,438 UTF-8 bytes with SHA-256
fe20f5573221efda27fdecc28130b32dfc17dcd5be8e6c2a9cd27fe9c55745ad.
Explicit ACP and WhatsApp sessions deliberately occupy different stable cache entries;
turns on the same channel retain a byte-identical prefix.
| Requirement | Test |
|---|---|
| Omitted channel keeps the exact previous prompt | test_omitted_channel_prompt_is_byte_identical_to_pre_d16 |
| Distinct guidance reaches the real assembled request and streamed turn path | test_explicit_channel_guidance_reaches_the_model_request_and_stream
(deterministic model; assembly/wiring proof, not a live-seat quality score) |
Raw runtime input preserves omitted versus explicit channel_origin |
test_runtime_preserves_whether_channel_origin_was_supplied |
| Each explicit channel remains stable across turns | test_explicit_channel_prefix_is_stable_across_turns |
| The lab declares channel in live stable META | test_identity_declares_channel_as_stable_meta |
| No model-visible tool schema gains a channel field | test_converse_registers_the_exact_specced_tools_and_measured_schema_delta |
| A rejected UNAVAILABLE finding still never reaches a delta | test_rejected_unavailable_finding_never_reaches_the_delta_stream |
Focused converse + tools + runtime tests → 43 passed uv run ruff check . → All checks passed uv run pytest -q → 444 passed, 3 dependency warnings