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}