Skip to main content

act_types/
http.rs

1//! ACT-HTTP protocol types for request/response serialization.
2//!
3//! All types derive both `Serialize` and `Deserialize` so they can be used
4//! by servers (act-host), clients (act-bridge), and SDKs alike.
5
6use serde::{Deserialize, Serialize};
7
8/// ACT-HTTP protocol version.
9pub const PROTOCOL_VERSION: &str = "0.1";
10
11/// HTTP header name for the protocol version.
12pub const HEADER_PROTOCOL_VERSION: &str = "ACT-Protocol-Version";
13
14/// Server metadata returned by `GET /info`.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ServerInfo {
17    pub name: String,
18    pub version: String,
19    pub description: String,
20    pub default_language: String,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub capabilities: Option<Vec<Capability>>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub metadata: Option<serde_json::Value>,
25}
26
27/// A server capability declaration.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct Capability {
30    pub id: String,
31    pub required: bool,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub description: Option<String>,
34}
35
36/// Tool definition returned in `ListToolsResponse`.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct ToolDefinition {
39    pub name: String,
40    pub description: String,
41    pub parameters_schema: serde_json::Value,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub metadata: Option<serde_json::Value>,
44}
45
46/// Response from `POST /tools`.
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct ListToolsResponse {
49    pub tools: Vec<ToolDefinition>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub metadata: Option<serde_json::Value>,
52}
53
54/// Request body for `POST /tools` and `QUERY /tools` (config only).
55#[derive(Debug, Clone, Serialize, Deserialize, Default)]
56pub struct ConfigRequest {
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub config: Option<serde_json::Value>,
59}
60
61/// Request body for `POST /tools/{name}`.
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct ToolCallRequest {
64    pub arguments: serde_json::Value,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub config: Option<serde_json::Value>,
67}
68
69/// A content part in a tool response.
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ContentPart {
72    pub data: serde_json::Value,
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub mime_type: Option<String>,
75    #[serde(default, skip_serializing_if = "Option::is_none")]
76    pub metadata: Option<serde_json::Value>,
77}
78
79/// Response from `POST /tools/{name}`.
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct ToolCallResponse {
82    pub content: Vec<ContentPart>,
83    #[serde(default, skip_serializing_if = "Option::is_none")]
84    pub metadata: Option<serde_json::Value>,
85}
86
87/// Error object in error responses.
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct ToolError {
90    pub kind: String,
91    pub message: String,
92    #[serde(default, skip_serializing_if = "Option::is_none")]
93    pub metadata: Option<serde_json::Value>,
94}
95
96/// Wrapper for error responses (`{"error": ...}`).
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct ErrorResponse {
99    pub error: ToolError,
100}
101
102/// Resource info returned by `POST /resources`.
103#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct ResourceInfo {
105    pub uri: String,
106    #[serde(default, skip_serializing_if = "Option::is_none")]
107    pub mime_type: Option<String>,
108    pub description: String,
109    #[serde(default, skip_serializing_if = "Option::is_none")]
110    pub metadata: Option<serde_json::Value>,
111}
112
113/// Response from `POST /resources`.
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct ListResourcesResponse {
116    pub resources: Vec<ResourceInfo>,
117    #[serde(default, skip_serializing_if = "Option::is_none")]
118    pub metadata: Option<serde_json::Value>,
119}
120
121/// Map an ACT error kind to an HTTP status code per ACT-HTTP spec.
122pub fn error_kind_to_status(kind: &str) -> u16 {
123    use crate::constants::*;
124    match kind {
125        ERR_NOT_FOUND => 404,
126        ERR_INVALID_ARGS => 422,
127        ERR_TIMEOUT => 504,
128        ERR_CAPABILITY_DENIED => 403,
129        _ => 500,
130    }
131}