feat(dialect): own the native replay envelopes and image marker codec - #40
Conversation
When the native dialect receives an envelope with an empty body, the parser now returns an empty string instead of failing. This allows the system to gracefully process messages that contain only metadata without a payload, matching the behavior of other dialects. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Move the {content,tool_calls} / {tool_call_id,content} envelope encode and parse
and the [OH_IMAGE:] marker split/join into tinytools-agent so hosts and durable
transcript writers share one definition. Canonical parsers only accept values
that re-encode byte-identically. NativeDialect now encodes through them (output
unchanged).
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Tiny Sweeper reviewTiny Sweeper reviewed this change across 6 lane(s) and found 0 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below. State: Incomplete Review snapshot
Completeness: Incomplete What changedThe review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below. FeaturesNone identified with supported citations. TestsNo supported feature-to-test mapping was produced. Test execution is not inferred. FindingsNo active actionable findings. Could not review: crates/tinytools-agent/src/dialect/envelope.rs, crates/tinytools-agent/src/dialect/mod.rs, crates/tinytools-agent/src/dialect/native.rs Before merge
How this fits togetherflowchart LR
n0["NativeDialect<br/>changed"]:::changed
n1["ToolDialect"]:::impacted
n2["assistant_envelope_round_trips_byte_exact"]:::impacted
n3["encode_assistant_envelope"]:::impacted
n4["call"]:::impacted
n5["parse_assistant_envelope"]:::impacted
n6["parse_canonical_assistant_envelope"]:::impacted
n0 -->|implements| n1
n2 -->|calls| n3
n2 -->|tests| n3
n2 -->|calls| n4
n2 -->|tests| n4
n2 -->|calls| n6
n2 -->|tests| n6
n6 -->|calls| n3
n6 -->|calls| n5
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (1)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe dialect adds assistant and tool JSON envelope encoders and parsers, canonical parsing, and image-marker splitting and joining. The native dialect uses the new encoders when building provider messages. ChangesDialect envelope support
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Feature Merge Risk: ⚪ Minimal · up to The shared codecs retain the described native message behavior, with no concrete merge-blocking issue identified. The change is mergeable subject to normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The examined implementation centralizes message encoding without adding tool execution or image retrieval. No introduced security flaw was established, but the exported parsers create a contract that future transcript consumers must use without treating decoded content as authorization. Those downstream consumers were not available for verification. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
A rabbit packed tool calls with care, Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e4eda5cfd0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| #[cfg(test)] | ||
| #[allow(clippy::unwrap_used)] | ||
| mod tests { |
There was a problem hiding this comment.
Move envelope tests into a dedicated test file
Keeping this new test module inline in envelope.rs violates the repository’s required module layout and causes implementation files to accumulate test code. Move these tests to the dialect’s dedicated test.rs structure and wire them from the module root.
AGENTS.md reference: AGENTS.md:L76-L88
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| #[cfg(test)] | ||
| #[allow(clippy::unwrap_used)] |
There was a problem hiding this comment.
Remove the module-wide lint suppression
This module-level allow disables unwrap_used for every test in the module, including future additions, rather than addressing the individual assertions. Rewrite the affected assertions without unwrap() instead of weakening the configured guardrail for the entire test module.
AGENTS.md reference: AGENTS.md:L283-L285
Useful? React with 👍 / 👎.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinytools-agent/src/dialect/envelope.rs, crates/tinytools-agent/src/dialect/mod.rs, crates/tinytools-agent/src/dialect/native.rs.
$0.0042 · 36,112 in / 11,662 out · 0 cached (0%) · ladder/vectors, deepseek/deepseek-v4-flash · 664 embedded
tests: $0.0022 · 19,452 in / 2,640 out · 0 cached (0%) · deepseek/deepseek-v4-flash
description: $0.0010 · 10,655 in / 6,989 out · 0 cached (0%) · deepseek/deepseek-v4-flash
Design note
Current state. The native replay envelopes (
{"content","tool_calls"}for an assistant turn that made calls,{"tool_call_id","content"}for a tool result) were encoded inNativeDialect::to_provider_messagesand parsed/re-encoded separately by OpenHuman'smessage_convert.rsand by tinyagents-session's view/writer code. The[OH_IMAGE:<url>]inline-image marker was split/joined only in the host.Target. One owner for these encodings:
tinytools_agent::dialect::{encode_assistant_envelope, encode_tool_envelope, parse_assistant_envelope, parse_tool_envelope, split_image_parts, join_image_parts, IMAGE_MARKER_PREFIX}plusparse_canonical_*variants that accept a string only when re-encoding it reproduces it byte for byte. That is what lets a durable transcript lift an envelope into typed fields and rebuild the identical string on read (tinyagents-session PR, stacked on this one), falling back to opaque text for anything non-canonical.Compatibility.
NativeDialectnow encodes through the shared functions; its output is unchanged (existing dialect tests pass). Additive API only.Proof. 10 new envelope tests (round trip, non-canonical rejection, split/join identity incl. unterminated markers); all 383 crate tests pass; clippy
-D warningsand fmt clean.Part of the OpenHuman typed-transcript follow-up to #6872.
Summary by CodeRabbit