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//!
4//! Copyright (c) systemprompt.io — Business Source License 1.1.
5//! See <https://systemprompt.io> for licensing details.
6
7use std::collections::HashMap;
8
9use serde::{Deserialize, Serialize};
10
11use crate::a2a::SecurityScheme;
12use crate::ai::ToolModelOverrides;
13use crate::auth::{JwtAudience, Permission};
14use crate::services::plugin::PluginComponentRef;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct AgentCardConfig {
19    pub protocol_version: String,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub name: Option<String>,
22    pub display_name: String,
23    pub description: String,
24    pub version: String,
25    #[serde(default = "default_transport")]
26    pub preferred_transport: String,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub icon_url: Option<String>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub documentation_url: Option<String>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub provider: Option<AgentProviderInfo>,
33    #[serde(default)]
34    pub capabilities: CapabilitiesConfig,
35    #[serde(default = "default_input_modes")]
36    pub default_input_modes: Vec<String>,
37    #[serde(default = "default_output_modes")]
38    pub default_output_modes: Vec<String>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub security_schemes: Option<HashMap<String, SecurityScheme>>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub security: Option<Vec<HashMap<String, Vec<String>>>>,
43    #[serde(default)]
44    pub supports_authenticated_extended_card: bool,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct AgentProviderInfo {
49    pub organization: String,
50    pub url: String,
51}
52
53#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
54#[serde(rename_all = "camelCase")]
55pub struct CapabilitiesConfig {
56    #[serde(default = "default_true")]
57    pub streaming: bool,
58    #[serde(default)]
59    pub push_notifications: bool,
60    #[serde(default = "default_true")]
61    pub state_transition_history: bool,
62}
63
64#[derive(Debug, Clone, Default, Serialize, Deserialize)]
65#[serde(rename_all = "camelCase")]
66pub struct AgentMetadataConfig {
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub system_prompt: Option<String>,
69    #[serde(default)]
70    pub mcp_servers: PluginComponentRef,
71    #[serde(default)]
72    pub skills: PluginComponentRef,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub provider: Option<String>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub model: Option<String>,
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub max_output_tokens: Option<u32>,
79    #[serde(default)]
80    pub tool_model_overrides: ToolModelOverrides,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct OAuthConfig {
85    #[serde(default)]
86    pub required: bool,
87    #[serde(default)]
88    pub scopes: Vec<Permission>,
89    #[serde(default = "default_audience")]
90    pub audience: JwtAudience,
91}
92
93impl Default for CapabilitiesConfig {
94    fn default() -> Self {
95        Self {
96            streaming: true,
97            push_notifications: false,
98            state_transition_history: true,
99        }
100    }
101}
102
103impl Default for OAuthConfig {
104    fn default() -> Self {
105        Self {
106            required: false,
107            scopes: Vec::new(),
108            audience: JwtAudience::A2a,
109        }
110    }
111}
112
113pub(super) fn default_transport() -> String {
114    "JSONRPC".to_owned()
115}
116
117pub(super) fn default_input_modes() -> Vec<String> {
118    vec!["text/plain".to_owned()]
119}
120
121pub(super) fn default_output_modes() -> Vec<String> {
122    vec!["text/plain".to_owned()]
123}
124
125pub(super) const fn default_true() -> bool {
126    true
127}
128
129pub(super) const fn default_audience() -> JwtAudience {
130    JwtAudience::A2a
131}