Skip to main content

agentkit_http/
client.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use http::Method;
5
6use crate::{HttpError, HttpRequest, HttpRequestBuilder, HttpResponse};
7
8/// Send a request, return a streaming response.
9///
10/// Contract:
11/// - [`HttpResponse::url`] must be the post-redirect URL — streamable-HTTP
12///   transports resolve relative endpoints against it.
13/// - The body must be surfaced as a stream, not buffered — SSE consumers
14///   pull chunks incrementally.
15/// - Use [`HttpError::Request`] for connect/transport failures,
16///   [`HttpError::Body`] for errors that surface mid-stream.
17#[async_trait]
18pub trait HttpClient: Send + Sync + 'static {
19    async fn execute(&self, request: HttpRequest) -> Result<HttpResponse, HttpError>;
20}
21
22/// Clone-cheap handle over an [`HttpClient`]. Methods mirror `reqwest::Client`.
23#[derive(Clone)]
24pub struct Http {
25    inner: Arc<dyn HttpClient>,
26}
27
28impl Http {
29    pub fn new<C: HttpClient>(client: C) -> Self {
30        Self {
31            inner: Arc::new(client),
32        }
33    }
34
35    pub fn from_arc(inner: Arc<dyn HttpClient>) -> Self {
36        Self { inner }
37    }
38
39    pub fn as_arc(&self) -> &Arc<dyn HttpClient> {
40        &self.inner
41    }
42
43    pub fn request(&self, method: Method, url: impl Into<String>) -> HttpRequestBuilder {
44        HttpRequestBuilder::new(self.inner.clone(), method, url)
45    }
46
47    pub fn get(&self, url: impl Into<String>) -> HttpRequestBuilder {
48        self.request(Method::GET, url)
49    }
50
51    pub fn post(&self, url: impl Into<String>) -> HttpRequestBuilder {
52        self.request(Method::POST, url)
53    }
54
55    pub fn put(&self, url: impl Into<String>) -> HttpRequestBuilder {
56        self.request(Method::PUT, url)
57    }
58
59    pub fn delete(&self, url: impl Into<String>) -> HttpRequestBuilder {
60        self.request(Method::DELETE, url)
61    }
62
63    pub fn patch(&self, url: impl Into<String>) -> HttpRequestBuilder {
64        self.request(Method::PATCH, url)
65    }
66
67    pub async fn execute(&self, request: HttpRequest) -> Result<HttpResponse, HttpError> {
68        self.inner.execute(request).await
69    }
70}
71
72impl std::fmt::Debug for Http {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        f.debug_struct("Http").finish_non_exhaustive()
75    }
76}