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 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 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 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}