protocol_droid/domain/ir/mod.rs
1//! The canonical, version-agnostic IR.
2//!
3//! # What this is for
4//!
5//! Application code and user handlers see these types. They do not see a
6//! revision's wire types, and they never choose a version at compile time. T08
7//! adds per-revision codecs that lift the wire into this IR and lower it back
8//! out, so the same handler serves every revision and the bridge between them
9//! is pure data.
10//!
11//! # The three properties everything here is built around
12//!
13//! **Superset.** Every revision's types are a subset of these. Fields a newer
14//! revision added are `Option` and absent on older ones, so a `2024-11-05`
15//! value and a `2026-07-28` value are both representable, and the difference is
16//! visible rather than typed away.
17//!
18//! **Self-describing requirements.** Every value can report what it needs to be
19//! expressed through `required_features()`. Lowering asks that question rather
20//! than pattern-matching on a version, so adding a revision does not mean
21//! touching every encoder — a new revision turns on the features it defines,
22//! and the existing gates do the rest.
23//!
24//! **Lossless.** Unmodelled fields land in an [`Extensions`] bag instead of
25//! being dropped, and an unparseable value lands as `Raw` rather than
26//! disappearing. The bridge's `lift(v, lower(v, ir)) == ir` claim is only
27//! meaningful because of this, and it is the property the crate exists for.
28//!
29//! # The layering
30//!
31//! ```text
32//! mod features; // FeatureSet — what a value needs
33//! mod json; // JsonObject — arbitrary JSON, validated once
34//! mod extensions; // Extensions — the passthrough bag
35//! mod content; // Content — content blocks
36//! mod message; // IrMessage — the envelope
37//! mod tool; // ToolResult — and the downgrade fallback
38//! ```
39//!
40//! Each file holds one concern, and the dependency direction is downward:
41//! `content`, `tool`, `codec` and `lower` use `features`, `json` and
42//! `extensions`, and nothing uses `content`. `message` sits above the rest
43//! and is the only place they are assembled. `codec` and `lower` are public
44//! because the adapter layer implements their traits and a bridge reads the
45//! reports those traits produce.
46
47mod codec;
48mod content;
49mod extensions;
50mod features;
51mod json;
52pub mod loglevel;
53pub mod lower;
54mod message;
55mod prompt;
56mod resource;
57mod tool;
58
59mod envelope;
60
61pub use codec::Codec;
62pub use content::{
63 Annotations, AudioContent, Content, EmbeddedResource, ImageContent, ResourceIcon,
64 ResourceLinkContent, Role, TextContent, UnknownContent, UnknownRole,
65};
66pub use envelope::{EnvelopeError, lift as lift_envelope, lower as lower_envelope};
67pub use extensions::{ExtensionValue, Extensions};
68pub use features::FeatureSet;
69pub use json::{JsonObject, JsonObjectError};
70pub use loglevel::{Level as LogLevel, LevelError as LogLevelError};
71pub use lower::{DegradeRule, Loss, LowerError, Lowering, TranslationReport, TranslationStep};
72pub use message::{
73 IrError, IrErrorCode, IrMessage, IrNotification, IrParams, IrRequest, IrResult, MethodName,
74 MethodNameError,
75};
76pub use prompt::{GetPromptResult, PromptMessage};
77pub use resource::{ResourceBody, ResourceContents};
78pub use tool::{Downgrade, ToolResult};