Skip to main content

embacle_server/uhp/
state.rs

1// ABOUTME: State shared by the UHP routes — provider runners plus the response/session store
2// ABOUTME: Kept separate from AppState so the OpenAI surface carries no protocol state
3//
4// SPDX-License-Identifier: Apache-2.0
5// Copyright (c) 2026 dravr.ai
6
7//! What the UHP routes share.
8//!
9//! The protocol needs something the `OpenAI` surface never did: a task, once
10//! run, must be readable back by id and must report the session it belongs to.
11//! That store lives here rather than in `AppState` so the surface beside it
12//! carries no protocol state it does not use.
13
14use std::sync::Arc;
15
16use axum::extract::FromRef;
17
18use super::manage::ConfiguredHarnesses;
19use super::share::Shares;
20use super::tasks::ResponseStore;
21use crate::state::SharedState;
22
23/// Provider runners plus retained responses.
24#[derive(Clone)]
25pub struct UhpState {
26    /// The runners this server can dispatch a task to.
27    pub shared: SharedState,
28    /// Responses this server has run and the sessions they belong to.
29    pub store: Arc<ResponseStore>,
30    /// Harnesses a client configured over the API, as opposed to the ones
31    /// discovery found by probing installed binaries.
32    pub configured: Arc<ConfiguredHarnesses>,
33    /// Public read-only views this server has published.
34    pub shares: Arc<Shares>,
35}
36
37impl UhpState {
38    /// Build state around the shared runner state, with an empty store.
39    pub fn new(shared: SharedState) -> Self {
40        Self {
41            shared,
42            store: Arc::new(ResponseStore::default()),
43            configured: Arc::new(ConfiguredHarnesses::default()),
44            shares: Arc::new(Shares::default()),
45        }
46    }
47}
48
49impl FromRef<UhpState> for SharedState {
50    fn from_ref(state: &UhpState) -> Self {
51        state.shared.clone()
52    }
53}