kcode-kennedy-session-presentation 0.1.0

Deterministic rendering for Kennedy session tools and controllers
Documentation
# kcode-kennedy-session-presentation 0.1.0

Deterministic, effect-free rendering for Kennedy session tool results, controller prompts, runtime text, costs, and provider continuations.

## Public API

```rust
pub enum RenderRequest<'a> {
    LoadNodes { changed_box_ids: &'a [String], projected_boxes: &'a [(String, String)] },
    ProviderFooter { result: &'a str, footer: &'a str },
    SlowTool { text: &'a str, elapsed: std::time::Duration },
    WebSearch { answer: &'a str, sources: &'a [(String, String)] },
    WebFetch { url: &'a str, title: Option<&'a str>, content_type: &'a str, truncated: bool, content: &'a str },
    MediaAnnotation { object_id: &'a str, file_name: &'a str, content_type: &'a str, model: &'a str, complete: bool, incomplete_reason: Option<&'a str>, text: &'a str },
    AudioTranscription { object_id: &'a str, file_name: &'a str, content_type: &'a str, model: &'a str, text: &'a str },
    DocumentExtraction { object_id: &'a str, file_name: &'a str, format: &'a str, characters: usize, truncated: bool, text: &'a str },
    UserFileMetadata { ordinal: usize, object_id: &'a str, file_name: &'a str, media_type: &'a str, size_bytes: u64 },
    StagedTelegramMedia { pending_id: &'a str, kind: &'a str, file_name: &'a str, media_type: &'a str, size_bytes: u64, message_id: i64, reused: bool },
    CostSummary { label: &'a str, estimated_cost_usd_nanos: u64, unpriced_calls: u64 },
    RuntimeDescription { model: &'a str, reasoning_effort: &'a str, current_time: chrono::DateTime<chrono::Utc> },
    FreeTimeOpening { free_time: &'a serde_json::Value },
    WakeupOpening { marker: chrono::DateTime<chrono::Utc> },
    ControllerMessage { mode: &'a str, free_time: &'a serde_json::Value },
    CallKtoolDescription,
}

pub fn render(request: RenderRequest<'_>) -> anyhow::Result<String>;
```

`render` performs no I/O and reads no session state. Inputs must already contain authoritative values. It preserves caller text except where a specific rendering contract normalizes MIME types, derives a filename extension, or intentionally trims only to decide whether optional text is blank.

`LoadNodes` preserves `changed_box_ids` order and fails when a requested box is absent. `SlowTool` appends duration only above three seconds. Media annotation and transcription fail on blank provider text. `ControllerMessage` accepts exactly `conversation`, `free-time`, `wakeup`, or `ingress`. Exact output strings are compatibility-sensitive.