Skip to main content

pulse_client/
lib.rs

1//! Official Rust client for [StreamFlow Pulse](https://github.com/olsisoft/pulse-rs)
2//! — the AI Agent Platform.
3//!
4//! # Quick start
5//!
6//! ```no_run
7//! use pulse_client::PulseClient;
8//!
9//! #[tokio::main]
10//! async fn main() -> Result<(), pulse_client::PulseError> {
11//!     let client = PulseClient::builder()
12//!         .base_url("http://localhost:9090")
13//!         .build()?;
14//!
15//!     client.auth().login("alice", "secret").await?;
16//!
17//!     for pipeline in client.pipelines().list().await? {
18//!         println!("{}", pipeline["name"]);
19//!     }
20//!     Ok(())
21//! }
22//! ```
23//!
24//! # Surface
25//!
26//! Mirrors the Python (`pulse-py`), JavaScript (`@olsisoft/pulse-client`),
27//! Java (`com.streamflow:pulse-client`) and Go (`github.com/olsisoft/pulse-go`)
28//! SDKs 1:1:
29//!
30//! - [`auth()`](PulseClient::auth) — login, refresh, organisations, switch org
31//! - [`pipelines()`](PulseClient::pipelines) — list, get, create, delete
32//! - [`agents()`](PulseClient::agents) — list, get
33//! - [`templates()`](PulseClient::templates) — list
34//! - [`users()`](PulseClient::users) — list (admin only)
35//! - [`events()`](PulseClient::events) — Server-Sent Events stream
36//! - [`iq()`](PulseClient::iq) — B-106 Interactive Queries on agent state
37//! - [`streams()`](PulseClient::streams) — B-107 Kafka-Streams-like DSL
38//! - [`version()`](PulseClient::version) — public, no JWT required
39//!
40//! # Wire format
41//!
42//! Every method corresponds 1:1 to an endpoint in the Pulse OpenAPI 3.1 spec
43//! (`streamflow-pulse/src/main/resources/openapi/openapi.yaml`). Drift caught
44//! at PR time by the in-tree spec invariant tests (B-103).
45
46#![doc(html_root_url = "https://docs.rs/pulse-client/2.6.1")]
47#![warn(missing_debug_implementations)]
48#![warn(rust_2018_idioms)]
49
50mod client;
51mod duplex;
52mod error;
53mod events;
54mod iq;
55mod resources;
56mod streams;
57
58pub use client::{PulseClient, PulseClientBuilder};
59pub use duplex::{derive_ws_url, DuplexChannel, DuplexOutput};
60pub use error::PulseError;
61pub use events::{EventsResource, EventsStream};
62pub use iq::{iq_and, iq_leaf, iq_not, iq_or, IQQueryOptions, IQResource, IQScanOptions};
63pub use resources::{
64    AgentsResource, AuthResource, ConnectorsResource, ModelUpload, ModelsResource,
65    PipelinesResource, TemplatesResource, UsersResource,
66};
67pub use streams::{
68    aggs, windows, BranchSpec, BroadcastJoinOptions, CdcJoinOptions, CepOptions,
69    EnrichAsyncOptions, ExtractOptions, MapLlmOptions, MapOptions, McpCallOptions,
70    MlPredictOptions, StreamBuilder, StreamsResource, WindowOptions, WindowSpec,
71};
72
73// Re-export serde_json::Value so callers don't need to add serde_json to
74// their direct dependencies just to inspect responses.
75pub use serde_json::Value;
76
77/// Current SDK version (matches `Cargo.toml` and the Pulse server it targets).
78pub const VERSION: &str = "2.6.1";
79
80impl std::fmt::Debug for PulseClient {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        f.debug_struct("PulseClient")
83            .field("base_url", &self.inner.base_url)
84            .field("token", &self.token().map(|_| "<set>"))
85            .finish()
86    }
87}
88
89impl<'c> std::fmt::Debug for AuthResource<'c> {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        f.debug_struct("AuthResource").finish()
92    }
93}
94
95impl<'c> std::fmt::Debug for PipelinesResource<'c> {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        f.debug_struct("PipelinesResource").finish()
98    }
99}
100
101impl<'c> std::fmt::Debug for AgentsResource<'c> {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        f.debug_struct("AgentsResource").finish()
104    }
105}
106
107impl<'c> std::fmt::Debug for TemplatesResource<'c> {
108    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109        f.debug_struct("TemplatesResource").finish()
110    }
111}
112
113impl<'c> std::fmt::Debug for UsersResource<'c> {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        f.debug_struct("UsersResource").finish()
116    }
117}
118
119impl<'c> std::fmt::Debug for ConnectorsResource<'c> {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        f.debug_struct("ConnectorsResource").finish()
122    }
123}
124
125impl<'c> std::fmt::Debug for ModelsResource<'c> {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        f.debug_struct("ModelsResource").finish()
128    }
129}