package com.example.aiapp /** * Where one transcript lives: a session's own, or one of its subagents'. * * The single mechanism [fetchTranscript], [EventStream], [TranscriptSource] and * [TranscriptCache.session] all take, rather than each growing its own branch between a session and * a subagent -- see SUBAGENTS.md's "Phone" and "Wire shape". A caller that has only a session id * builds one with the one-argument constructor; a subagent's screen supplies both ids. */ data class TranscriptAddress(val sessionId: String, val subagentId: String? = null) { /** The URL segment naming this transcript, before `/transcript` or `/events`. */ val urlPath: String get() = if (subagentId == null) "sessions/$sessionId" else "sessions/$sessionId/subagents/$subagentId" /** * Where this transcript's cache lives on the phone, relative to the cache root. * * A subagent's nests under its session's directory rather than sitting beside it, so deleting a * session's cache directory takes its subagents' with it -- the same one-way door the server's * own storage describes. */ val cachePath: String get() = if (subagentId == null) sessionId else "$sessionId/subagents/$subagentId" }