Skip to main content

writ_client/
lib.rs

1//! # writ-client
2//!
3//! Official Rust SDK for the **Writ local agent** (`writ-agentd`) — the loopback
4//! HTTP API on `127.0.0.1:8131` (see `sdks/DESIGN.md` and
5//! `sdks/openapi/writ-agent.yaml` in the Writ repository).
6//!
7//! ```no_run
8//! use writ_client::{WritAgent, RunOptions};
9//!
10//! # async fn demo() -> Result<(), writ_client::WritError> {
11//! let agent = WritAgent::discover().await?; // env → ~/.writ/runtime.json → probe
12//! let workflows = agent.workflows().list().await?;
13//! let first = &workflows.data[0];
14//! let outcome = agent
15//!     .workflows()
16//!     .run_and_wait(first.id, &RunOptions::default())
17//!     .await?;
18//! println!("{} → {}", first.name, outcome.run.status);
19//! # Ok(())
20//! # }
21//! ```
22//!
23//! ## Design notes
24//! - **Async-only**, built on `reqwest`; the library itself has no tokio
25//!   dependency (any reqwest-compatible runtime works).
26//! - Every list method returns a uniform [`Page`], whatever envelope the daemon
27//!   used on the wire.
28//! - Errors are the three-kind model of DESIGN.md §5: [`WritError::Api`],
29//!   [`WritError::Connection`], [`WritError::Discovery`]. No automatic retries.
30//! - Models type the stable scalar fields and keep everything else in an
31//!   `extra` map, so a newer daemon never breaks deserialization.
32
33// [`WritError`] is a deliberately flat, public error enum: every non-2xx shape
34// (including the cloud-tier `RateLimited`/`ApiKeyRequired`/`InsufficientCredits`
35// variants) carries its parsed `body` and fields inline rather than behind a
36// `Box`, so callers can match on them without indirection. That makes the enum
37// wider than clippy's `result_large_err` threshold — an accepted trade-off for an
38// SDK error type; boxing would only muddy the public API.
39#![allow(clippy::result_large_err)]
40
41mod client;
42mod cloud;
43mod discovery;
44mod error;
45mod models;
46mod page;
47mod resources;
48mod sse;
49mod util;
50
51pub use bytes::Bytes;
52pub use client::{WritAgent, WritAgentBuilder};
53pub use cloud::{
54    CloudClient, CloudClientBuilder, CloudTier, KeylessQuota, MapCounts, MapEntry, MapOptions,
55    MapResult, ScrapeResult,
56};
57pub use error::{Result, WritError};
58pub use models::{
59    AgentStatus, ApiKey, Automation, CancelOutcome, CrawlCancel, CrawlJob, CrawlList,
60    CrawlStartParams, Dataset, DatasetFormat, DatasetList, DatasetMeta, DatasetRef,
61    DatasetSearchHit, DatasetSearchResult, Extra, Extractor, Health, Monitor, MonitorHistory,
62    Persona, RunCompleted, RunData, RunEvent, RunFeedItem, RunOutcome, RunResults, RunStarted,
63    SecretMeta, Selector, StoredFile, VaultStatus, Workflow, WsTicket,
64};
65pub use page::Page;
66pub use resources::{
67    Agent, Automations, Crawl, Data, Datasets, Extractors, Files, Keys, Monitors, Personas,
68    RunEventStream, RunOptions, Runs, Secrets, Selectors, Vault, Workflows,
69};