Skip to main content

agent_diva_manager/
state.rs

1use agent_diva_agent::AgentEvent;
2use agent_diva_core::bus::{InboundMessage, MessageBus};
3use agent_diva_core::config::schema::{
4    ChannelsConfig, MCPServerConfig, WebFetchConfig, WebSearchConfig, WebToolsConfig,
5};
6use agent_diva_core::cron::{CreateCronJobRequest, CronJobDto, UpdateCronJobRequest};
7use agent_diva_providers::{CustomProviderUpsert, ProviderModelCatalogView, ProviderView};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use tokio::sync::{mpsc, oneshot};
11
12use crate::mcp_service::{McpServerDto, McpServerUpsert};
13use crate::skill_service::SkillDto;
14
15#[derive(Clone)]
16pub struct AppState {
17    pub api_tx: mpsc::Sender<ManagerCommand>,
18    pub bus: MessageBus,
19}
20
21pub enum ProviderCommand {
22    GetProviders(oneshot::Sender<Vec<ProviderView>>),
23    GetProvider(
24        String,
25        oneshot::Sender<Result<Option<ProviderView>, String>>,
26    ),
27    GetProviderModels(String, bool, oneshot::Sender<ProviderModelCatalogView>),
28    ResolveProvider(String, Option<String>, oneshot::Sender<Option<String>>),
29    AddProviderModel(String, String, oneshot::Sender<Result<(), String>>),
30    DeleteProviderModel(String, String, oneshot::Sender<Result<(), String>>),
31    CreateProvider(
32        CustomProviderUpsert,
33        oneshot::Sender<Result<Option<ProviderView>, String>>,
34    ),
35    UpdateProvider(
36        String,
37        CustomProviderUpsert,
38        oneshot::Sender<Result<Option<ProviderView>, String>>,
39    ),
40    DeleteProvider(String, oneshot::Sender<Result<(), String>>),
41}
42
43pub enum ManagerCommand {
44    // Core runtime control plane used by the formal CLI runtime.
45    Chat(ApiRequest),
46    StopChat(StopChatRequest, oneshot::Sender<Result<bool, String>>),
47    ResetSession(ResetSessionRequest, oneshot::Sender<Result<bool, String>>),
48    UpdateConfig(ConfigUpdate),
49    UpdateChannel(ChannelUpdate),
50    GetConfig(oneshot::Sender<ConfigResponse>),
51    GetChannels(oneshot::Sender<ChannelsConfig>),
52    GetTools(oneshot::Sender<ToolsConfigResponse>),
53    UpdateTools(ToolsConfigUpdate),
54    GetMcps(oneshot::Sender<Result<Vec<McpServerDto>, String>>),
55    CreateMcp(
56        McpServerUpsert,
57        oneshot::Sender<Result<McpServerDto, String>>,
58    ),
59    UpdateMcp(
60        String,
61        McpServerUpsert,
62        oneshot::Sender<Result<McpServerDto, String>>,
63    ),
64    DeleteMcp(String, oneshot::Sender<Result<(), String>>),
65    SetMcpEnabled(String, bool, oneshot::Sender<Result<McpServerDto, String>>),
66    RefreshMcpStatus(String, oneshot::Sender<Result<McpServerDto, String>>),
67    GetSkills(oneshot::Sender<Result<Vec<SkillDto>, String>>),
68    UploadSkill(
69        SkillUploadRequest,
70        oneshot::Sender<Result<SkillDto, String>>,
71    ),
72    DeleteSkill(String, oneshot::Sender<Result<(), String>>),
73    GetSessions(oneshot::Sender<Result<Vec<agent_diva_core::session::SessionInfo>, String>>),
74    GetSessionHistory(
75        String,
76        oneshot::Sender<Result<Option<agent_diva_core::session::store::Session>, String>>,
77    ),
78    DeleteSession(String, oneshot::Sender<Result<bool, String>>),
79    ListCronJobs(oneshot::Sender<Result<Vec<CronJobDto>, String>>),
80    GetCronJob(String, oneshot::Sender<Result<Option<CronJobDto>, String>>),
81    CreateCronJob(
82        CreateCronJobRequest,
83        oneshot::Sender<Result<CronJobDto, String>>,
84    ),
85    UpdateCronJob(
86        String,
87        UpdateCronJobRequest,
88        oneshot::Sender<Result<CronJobDto, String>>,
89    ),
90    DeleteCronJob(String, oneshot::Sender<Result<(), String>>),
91    SetCronJobEnabled(String, bool, oneshot::Sender<Result<CronJobDto, String>>),
92    RunCronJobNow(String, bool, oneshot::Sender<Result<CronJobDto, String>>),
93    StopCronJobRun(
94        String,
95        oneshot::Sender<Result<agent_diva_core::cron::CronRunSnapshot, String>>,
96    ),
97    UploadFile(
98        FileUploadRequest,
99        oneshot::Sender<Result<agent_diva_core::attachment::FileAttachment, String>>,
100    ),
101    // Companion / HTTP management plane for GUI and remote administration.
102    Provider(ProviderCommand),
103}
104
105pub struct ApiRequest {
106    pub msg: InboundMessage,
107    pub event_tx: mpsc::UnboundedSender<AgentEvent>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct StopChatRequest {
112    pub channel: Option<String>,
113    pub chat_id: Option<String>,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct ResetSessionRequest {
118    pub channel: Option<String>,
119    pub chat_id: Option<String>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct ConfigUpdate {
124    pub api_base: Option<String>,
125    pub api_key: Option<String>,
126    pub provider: Option<String>,
127    pub model: Option<String>,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct ChannelUpdate {
132    pub name: String,
133    pub enabled: Option<bool>,
134    pub config: serde_json::Value,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct SetCronJobEnabledRequest {
139    pub enabled: bool,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct RunCronJobRequest {
144    #[serde(default)]
145    pub force: bool,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct ConfigResponse {
150    pub provider: Option<String>,
151    pub api_base: Option<String>,
152    pub model: String,
153    // Don't return API key for security, or maybe masked
154    pub has_api_key: bool,
155}
156
157#[derive(Debug, Clone)]
158pub struct SkillUploadRequest {
159    pub file_name: String,
160    pub bytes: Vec<u8>,
161}
162
163#[derive(Debug, Clone)]
164pub struct FileUploadRequest {
165    pub file_name: String,
166    pub bytes: Vec<u8>,
167    pub channel: String,
168    pub message_id: Option<String>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct ToolsConfigResponse {
173    pub web: WebToolsConfigResponse,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct WebToolsConfigResponse {
178    pub search: WebSearchConfig,
179    pub fetch: WebFetchConfig,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct ToolsConfigUpdate {
184    pub web: WebToolsConfigUpdate,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct SetMcpEnabledRequest {
189    pub enabled: bool,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct McpRefreshRequest {
194    #[serde(default)]
195    pub reapply: bool,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct WebToolsConfigUpdate {
200    pub search: WebSearchConfig,
201    pub fetch: WebFetchConfig,
202}
203
204impl From<WebToolsConfig> for WebToolsConfigResponse {
205    fn from(value: WebToolsConfig) -> Self {
206        Self {
207            search: value.search,
208            fetch: value.fetch,
209        }
210    }
211}
212
213pub fn active_mcp_servers(
214    config: &agent_diva_core::config::schema::Config,
215) -> HashMap<String, MCPServerConfig> {
216    config.tools.active_mcp_servers()
217}