# kcode-kennedy-sessions 0.1.1
`kcode-kennedy-sessions` owns the complete mechanical lifecycle of one Kennedy
logical session: Session History and Chatend projection, Kweb context and staged
writes, tool dispatch, object resolution, provider-loop hosting, recovery,
checkpoints, and final archive/commit mechanics. KennedyServer supplies a fully
composed prompt and selects roots, runtime, channel, and outer scheduling.
## Complete public API
```rust
pub use kcode_telegram_session_coordinator::validate_file_name
as validate_delivery_file_name;
#[derive(Clone)]
pub struct Service { /* private shared capability handles */ }
pub struct Capabilities {
pub kmap: kcode_kweb_manager::KwebManager,
pub intelligence: kcode_intelligence_router::Intelligence,
pub history: kcode_session_history::SessionHistory,
pub speech_classifier: Arc<kcode_speech_classification::SpeechClassifier>,
pub dev_tools: kcode_dev_tools::Service,
pub agents: kcode_agent_runtime::AgentRuntime,
pub telegram: kcode_telegram_session_coordinator::Service,
}
impl Service {
pub fn new(capabilities: Capabilities) -> Self;
}
pub struct RuntimeModel {
pub model: String,
pub reasoning_effort: String,
pub context_window_tokens: u64,
}
impl RuntimeModel {
pub fn from_intelligence(
runtime: kcode_intelligence_router::RuntimeModel,
) -> Self;
}
pub enum AgentMode {
Conversation,
FreeTime,
Wakeup,
Ingress { record_id: Option<String> },
}
pub struct SessionOptions {
pub session_type: String,
pub root_node_ids: Vec<String>,
pub reference_root_node_ids: Vec<String>,
pub channel: serde_json::Value,
pub free_time: serde_json::Value,
pub orchestration: serde_json::Value,
pub provenance_id: Option<String>,
pub mode: AgentMode,
pub source_session_type: Option<String>,
pub group_context: serde_json::Value,
pub rust_lib_session_id: Option<String>,
}
impl SessionOptions {
pub fn conversation(
session_type: impl Into<String>,
roots: Vec<String>,
) -> Self;
}
pub struct ResolvedObject {
pub object_id: String,
pub bytes: Vec<u8>,
pub file_name: String,
pub media_type: String,
pub transport_kind: Option<String>,
}
pub struct Session {
pub session_type: String,
pub channel: serde_json::Value,
pub free_time: serde_json::Value,
pub orchestration: serde_json::Value,
pub provenance_id: Option<String>,
pub rust_lib_session_id: String,
pub root_node_ids: Vec<String>,
pub reference_root_node_ids: Vec<String>,
pub started_at: String,
pub transcript: Vec<serde_json::Value>,
pub pending_turn: bool,
pub pending_external_event_id: Option<String>,
pub completed: bool,
pub rounds_used: u64,
// private runtime, journal, Kweb plan, mode, context, and commit state
}
impl Session {
pub async fn new(
service: Service,
system_prompt: String,
runtime: RuntimeModel,
options: SessionOptions,
restored: Option<&serde_json::Value>,
) -> anyhow::Result<Self>;
pub fn append_final_user_message(
&mut self,
text: &str,
metadata: &serde_json::Value,
) -> bool;
pub fn stage_source_message(
&mut self,
kennedy: bool,
text: &str,
metadata: serde_json::Value,
) -> anyhow::Result<()>;
pub fn answer_for_external_event(
&self,
id: &str,
) -> Option<&serde_json::Value>;
pub fn responses_for_external_event(
&self,
id: &str,
) -> Vec<&serde_json::Value>;
pub fn resolve_object(&mut self, object_id: &str)
-> anyhow::Result<ResolvedObject>;
pub fn requires_history_ingress(&self) -> bool;
pub fn stage_free_time_opening(&mut self) -> bool;
pub fn stage_wakeup_opening(&mut self) -> anyhow::Result<bool>;
pub fn begin_user_turn(
&mut self,
text: &str,
metadata: &serde_json::Value,
) -> bool;
pub fn reset_exhausted_turn_rounds_for_retry(&mut self);
pub fn interrupt_current_turn(&mut self) -> anyhow::Result<()>;
pub async fn run_pending_turn<C, F>(
&mut self,
operation_id: uuid::Uuid,
checkpoint: C,
) -> anyhow::Result<Option<String>>
where
C: FnMut(serde_json::Value) -> F + Send,
F: Future<Output = anyhow::Result<()>> + Send;
pub fn refresh_telegram_group_context(
&mut self,
group_context: &serde_json::Value,
current_message_id: Option<&str>,
) -> anyhow::Result<()>;
pub fn finalize_free_time(&mut self, reason: &str)
-> anyhow::Result<()>;
pub fn commit_current_write_session(&mut self)
-> anyhow::Result<()>;
pub fn snapshot(&self) -> anyhow::Result<serde_json::Value>;
pub async fn release_managed_sources(&self);
}
```
`Service` and `Capabilities` are public aliases of private-module concrete
types; callers do not receive the individual internal adapter methods. The
service is cheaply cloneable and shares the supplied typed capability handles.
## Construction and restoration
`SessionOptions::conversation` creates an idle conversation with the supplied
session type and ordered writable roots. Callers then set channel data,
reference roots, mode, free-time state, group context, provenance, or a stable
managed-source session ID as needed. Reference roots are sorted, deduplicated,
and removed when also present as writable roots.
`Session::new` creates or reopens the Session History journal, establishes the
system-prompt and Kweb projection, restores accepted state from `restored`, and
prepares history ingress when requested. `system_prompt` must already contain
the complete application-selected prompt; this crate does not read prompt
files or choose identity/channel layers. `RuntimeModel` carries the exact model,
reasoning effort, and verified context window used mechanically by the session.
`AgentMode` controls completion policy. Conversation sessions may remain open
and later require history ingress. Free-time, wakeup, and ingress sessions own
write-session finalization and become completed after their pending turn.
## Input and turn lifecycle
`begin_user_turn` rejects an already-pending turn or empty input, resets the
cumulative round count, records an optional `externalEventId`, and durably
stages text and attachments into Chatend. `append_final_user_message` stages a
last source message without opening a new model turn. `stage_source_message`
adds an explicitly user- or Kennedy-owned source message and runs ordinary
context recovery.
`stage_free_time_opening` and `stage_wakeup_opening` create the mode-specific
opening exactly once. Wakeup requires the acquired RFC 3339 `wakeupMarker` in
`channel`. `interrupt_current_turn` repairs unfinished tool records, adds the
durable user-stop notice, clears the pending turn, and returns orchestration to
idle. `reset_exhausted_turn_rounds_for_retry` resets only an exhausted ordinary
conversation.
`run_pending_turn` does nothing and returns `Ok(None)` when no turn is pending.
Otherwise it runs the `kcode-agent-runtime` primary-session loop and calls the
checkpoint callback with a complete `snapshot` after every durable semantic
transition. Callback failure aborts the run. A conversation returns
`Ok(Some(answer))` for a new terminal assistant answer; `Ok(None)` means no new
answer was required because an object/tool already supplied the response, the
source terminated, or a non-conversation mode completed. A conversation that
ends without any recoverable response is an error. The caller's operation ID
owns provider and descendant cancellation lineage.
## Objects, external events, and Telegram context
`resolve_object` accepts a pending Session History object ID or canonical Kweb
object ID. It returns exact decoded bytes and authoritative filename, media
type, and native transport hint; resolving canonical objects does not stage or
commit them. `validate_delivery_file_name` validates the same bounded,
path-free recipient-visible filename contract used by Telegram delivery.
`TranscribeAudio` requires `prompt` to be a string that is not blank after
trimming. The accepted prompt is passed onward unchanged, and this crate does
not impose an independent character ceiling; provider or context constraints
report their own real limits.
`answer_for_external_event` returns the newest terminal response for an exact
external event. `responses_for_external_event` returns all Kennedy/system
responses for that event in transcript order. `refresh_telegram_group_context`
is a no-op outside Telegram-group sessions; in a group it replaces current
channel context, adds one controller update box, and applies context recovery.
## Completion and snapshots
`requires_history_ingress` is true only for an ordinary conversation whose
source has terminated. `finalize_free_time` accepts exactly `tool`, `deadline`,
`hard-stop`, or `user-stop`, records the slice result, and clears the turn.
`commit_current_write_session` is valid only for free-time, wakeup, or ingress;
it atomically finalizes the session's staged Kweb transaction and marks the
session completed. `release_managed_sources` releases the session-scoped leases
held by managed development tools.
`snapshot` returns the complete versioned recovery/presentation value. It
contains format and state versions, session and Chatend metadata, channel and
orchestration state, roots, transcript and turn state, round count, completion
and commit facts, Kweb plan, boxes/events, the structured projection, exact
`chatendText`, and current session status. Callers persist this value as an
opaque complete checkpoint and pass it back to `Session::new`; they should not
independently edit the journal, Kweb plan, boxes, or events.
## Ownership boundary
This crate owns session mechanics, tool authorization/dispatch, Kweb staging
and revalidation, context recovery, accounting projection, and final commit.
Session History remains the durable journal/object/archive owner; Kweb Manager
remains the database owner; agent-runtime remains the provider-loop owner; and
the Telegram coordinator remains the delivery/context owner. KennedyServer
owns prompt composition, root/runtime selection, outer transport scheduling,
job retry policy, and persistence of the opaque snapshots supplied to its
checkpoint callback.