Build one durable serve session under the explicit `session_id` (`schedule: `), injecting the agent dir's prompt slots, skills, and `tools/`. Rehydrate-on-boot: if a `SessionStore` is configured (via `extra`) and already holds `session_id`, RESUME it so prior context is restored; otherwise create a fresh session. Resume re-applies the freshly loaded prompt slots / skills / tools (it restores
(
agent: &Agent,
agent_dir: &AgentDir,
session_id: String,
workspace: impl Into<String>,
extra: &SessionOptions,
)
| 103 | /// The caller owns the id; a host-set `extra.session_id` is intentionally ignored |
| 104 | /// (it would collide every schedule onto one shared, store-clobbering id). |
| 105 | async fn build_session( |
| 106 | agent: &Agent, |
| 107 | agent_dir: &AgentDir, |
| 108 | session_id: String, |
| 109 | workspace: impl Into<String>, |
| 110 | extra: &SessionOptions, |
| 111 | ) -> Result<AgentSession> { |
| 112 | let mut opts = extra.clone(); |
| 113 | if opts.prompt_slots.is_none() { |
| 114 | opts.prompt_slots = Some(agent_dir.prompt_slots.clone()); |
| 115 | } |
| 116 | opts.skill_dirs |
| 117 | .extend(agent_dir.config.skill_dirs.iter().cloned()); |
| 118 | opts.session_id = Some(session_id.clone()); |
| 119 | |
| 120 | // Resume only when the store already has this session; the borrow of |
| 121 | // `opts.session_store` is released before `opts` is moved into the chosen |
| 122 | // builder. `exists` returns the crate Result, so `?` propagates cleanly. |
| 123 | let resume = match &opts.session_store { |
| 124 | Some(store) => store.exists(&session_id).await?, |
| 125 | None => false, |
| 126 | }; |
| 127 | let session = if resume { |
| 128 | agent.resume_session(&session_id, opts)? |
| 129 | } else { |
| 130 | agent.session(workspace, Some(opts))? |
| 131 | }; |
| 132 | |
| 133 | // Install the agent dir's tools/ (MCP servers + sandboxed scripts) into the |
| 134 | // session, so a triggered turn can call them. Connection is fallible and |
| 135 | // surfaces here (fail at startup, not at first call). Done for both fresh and |
| 136 | // resumed sessions — tools are not persisted, they are re-installed each boot. |
| 137 | super::tools::install_agent_dir_tools(&session, &agent_dir.tools).await?; |
| 138 | Ok(session) |
| 139 | } |
| 140 | |
| 141 | #[cfg(test)] |
| 142 | mod tests { |
no test coverage detected