Skip to main content

systemprompt_models/services/agent_config/
card.rs

1//! Agent capability and skill descriptors plus the container
2//! [`AgentCardConfig`] published as the agent's public face.
3
4use serde::{Deserialize, Serialize};
5
6use crate::ai::ToolModelOverrides;
7use crate::auth::{JwtAudience, Permission};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct AgentCardConfig {
12    pub protocol_version: String,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub name: Option<String>,
15    pub display_name: String,
16    pub description: String,
17    pub version: String,
18    #[serde(default = "default_transport")]
19    pub preferred_transport: String,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub icon_url: Option<String>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub documentation_url: Option<String>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub provider: Option<AgentProviderInfo>,
26    #[serde(default)]
27    pub capabilities: CapabilitiesConfig,
28    #[serde(default = "default_input_modes")]
29    pub default_input_modes: Vec<String>,
30    #[serde(default = "default_output_modes")]
31    pub default_output_modes: Vec<String>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub security_schemes: Option<serde_json::Value>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub security: Option<Vec<serde_json::Value>>,
36    #[serde(default)]
37    pub skills: Vec<AgentSkillConfig>,
38    #[serde(default)]
39    pub supports_authenticated_extended_card: bool,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct AgentSkillConfig {
44    pub id: systemprompt_identifiers::SkillId,
45    pub name: String,
46    pub description: String,
47    #[serde(default)]
48    pub tags: Vec<String>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub examples: Option<Vec<String>>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub input_modes: Option<Vec<String>>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub output_modes: Option<Vec<String>>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub security: Option<Vec<serde_json::Value>>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct AgentProviderInfo {
61    pub organization: String,
62    pub url: String,
63}
64
65#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
66#[serde(rename_all = "camelCase")]
67pub struct CapabilitiesConfig {
68    #[serde(default = "default_true")]
69    pub streaming: bool,
70    #[serde(default)]
71    pub push_notifications: bool,
72    #[serde(default = "default_true")]
73    pub state_transition_history: bool,
74}
75
76#[derive(Debug, Clone, Default, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct AgentMetadataConfig {
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub system_prompt: Option<String>,
81    #[serde(default)]
82    pub mcp_servers: Vec<String>,
83    #[serde(default)]
84    pub skills: Vec<String>,
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub provider: Option<String>,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub model: Option<String>,
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub max_output_tokens: Option<u32>,
91    #[serde(default)]
92    pub tool_model_overrides: ToolModelOverrides,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct OAuthConfig {
97    #[serde(default)]
98    pub required: bool,
99    #[serde(default)]
100    pub scopes: Vec<Permission>,
101    #[serde(default = "default_audience")]
102    pub audience: JwtAudience,
103}
104
105impl Default for CapabilitiesConfig {
106    fn default() -> Self {
107        Self {
108            streaming: true,
109            push_notifications: false,
110            state_transition_history: true,
111        }
112    }
113}
114
115impl Default for OAuthConfig {
116    fn default() -> Self {
117        Self {
118            required: false,
119            scopes: Vec::new(),
120            audience: JwtAudience::A2a,
121        }
122    }
123}
124
125pub(super) fn default_transport() -> String {
126    "JSONRPC".to_string()
127}
128
129pub(super) fn default_input_modes() -> Vec<String> {
130    vec!["text/plain".to_string()]
131}
132
133pub(super) fn default_output_modes() -> Vec<String> {
134    vec!["text/plain".to_string()]
135}
136
137pub(super) const fn default_true() -> bool {
138    true
139}
140
141pub(super) const fn default_audience() -> JwtAudience {
142    JwtAudience::A2a
143}