Skip to main content

soothe_client/
lib.rs

1//! Soothe WebSocket client for talking to a running soothe-daemon.
2//!
3//! Public surface mirrors Python / Go / TypeScript RFC-629 tiers:
4//!
5//! ```text
6//! Need                         → Entry point
7//! One conversation, stream     → appkit::DaemonSession
8//! Jobs / cron one-shots        → CommandClient
9//! Raw protocol / custom        → Client
10//! Multi-user HTTP backend      → appkit::ConnectionPool + TurnRunner
11//! ```
12
13#![deny(missing_docs)]
14#![allow(clippy::result_large_err)]
15
16pub mod appkit;
17pub mod card_projection;
18pub mod client;
19pub mod command_client;
20pub mod config;
21pub mod errors;
22pub mod events;
23pub mod heartbeat;
24pub mod helpers;
25pub mod inbound_priority;
26pub mod intent_hints;
27pub mod protocol;
28pub mod send_methods;
29pub mod session;
30pub mod stream_terminal;
31pub mod turn_boundary;
32pub mod verbosity;
33
34pub use card_projection::{parse_card_custom_payload, CardProjection, ParsedCardFrame};
35pub use client::{Client, ClientConfig, SendInputOptions};
36pub use command_client::{AsyncCommandClient, CommandClient};
37pub use config::{load_config_from_env, Config};
38pub use errors::{
39    disconnect_cause_name, ConnectionError, DaemonError, DisconnectCause, HeartbeatError,
40    ReconnectError, StaleLoopError, TimeoutError,
41};
42pub use events::{
43    classify_event_verbosity, is_completion_event, is_subagent_progress_event, parse_namespace,
44    ParsedNamespace, EVENT_AUTOPILOT_DREAMING_ENTERED, EVENT_AUTOPILOT_DREAMING_EXITED,
45    EVENT_AUTOPILOT_GOAL_BLOCKED, EVENT_AUTOPILOT_GOAL_COMPLETED, EVENT_AUTOPILOT_GOAL_CREATED,
46    EVENT_AUTOPILOT_GOAL_PROGRESS, EVENT_AUTOPILOT_GOAL_SUSPENDED, EVENT_AUTOPILOT_STATUS_CHANGED,
47    EVENT_BRANCH_CREATED, EVENT_BRANCH_RETRY_STARTED, EVENT_CARD_CREATED, EVENT_CARD_FINALIZED,
48    EVENT_CARD_REPLAY_BEGIN, EVENT_CARD_REPLAY_END, EVENT_CARD_UPDATED,
49    EVENT_DEEP_RESEARCH_COMPLETED, EVENT_DEEP_RESEARCH_CRAWL_SUMMARY,
50    EVENT_DEEP_RESEARCH_GATHER_SUMMARY, EVENT_DEEP_RESEARCH_PROGRESS, EVENT_DEEP_RESEARCH_STARTED,
51    EVENT_DEEP_RESEARCH_STEP_COMPLETED, EVENT_FINAL_REPORT, EVENT_GENERAL_FAILED,
52    EVENT_GOAL_BATCH_STARTED, EVENT_GOAL_COMPLETED, EVENT_GOAL_CREATED, EVENT_GOAL_DEFERRED,
53    EVENT_GOAL_DIRECTIVES_APPLIED, EVENT_GOAL_FAILED, EVENT_GOAL_REPORTED,
54    EVENT_LOOP_REATTACHED_WIRE, EVENT_MESSAGE_RECEIVED, EVENT_MESSAGE_SENT,
55    EVENT_PLAN_BATCH_STARTED, EVENT_PLAN_CREATED, EVENT_PLAN_REFLECTED, EVENT_REPLAY_COMPLETE,
56    EVENT_STRANGE_LOOP_COMPLETED, EVENT_STRANGE_LOOP_CONTEXT_COMPACTED,
57    EVENT_STRANGE_LOOP_PLAN_DECISION, EVENT_STRANGE_LOOP_REASONED, EVENT_STRANGE_LOOP_STARTED,
58    EVENT_STRANGE_LOOP_STEP_COMPLETED, EVENT_STRANGE_LOOP_STEP_QUEUED,
59    EVENT_STRANGE_LOOP_STEP_STARTED, EVENT_STREAM_TOOL_CALL_UPDATE, EVENT_TOOL_CALL_UPDATES_BATCH,
60    EVENT_TOOL_COMPLETED, EVENT_TOOL_ERROR, EVENT_TOOL_STARTED,
61};
62pub use heartbeat::{DaemonHealth, HeartbeatTracker};
63pub use helpers::{
64    check_daemon_status, fetch_config_section, fetch_execution_state, fetch_loop_history,
65    fetch_skills_catalog, is_daemon_live, protocol1_rpc, request_auth, request_auth_refresh,
66    request_daemon_config_reload, request_daemon_shutdown, websocket_url_from_env,
67};
68pub use inbound_priority::{
69    inbound_frame_drop_priority, DEFAULT_INBOUND_MAX_SIZE, DROP_PRIORITY_CRITICAL,
70    DROP_PRIORITY_HIGH, DROP_PRIORITY_NORMAL,
71};
72pub use intent_hints::{DEFAULT_DELIVERABLE_PHASES, EMBED, IMAGE_TO_TEXT, OCR, TEXT_COMPLETION};
73pub use protocol::{
74    as_str, decode_message, decode_message_typed, expand_wire_messages, extract_soothe_loop_id,
75    is_loop_assistant_phase, new_connection_init, new_notification, new_ping, new_pong,
76    new_request, new_request_id, new_request_with_id, new_subscribe, new_unsubscribe,
77    next_to_event_message, params_map, split_wire_payload, BaseMessage, Envelope, ErrorObject,
78    EventMessage, LoopAIMessage, MessageType, StatusResponse, TypedMessage, CLIENT_VERSION,
79    DEFAULT_CLIENT_CAPABILITIES, PROTO_VERSION,
80};
81pub use session::{bootstrap_loop_session, connect_with_retries, BootstrapOptions};
82pub use stream_terminal::{
83    extract_loop_id_from_inbound, inbound_needs_delivery_ack, is_turn_end_custom_data,
84    is_turn_progress_chunk, stale_pending_frame_label, STREAM_END,
85};
86pub use turn_boundary::{
87    format_turn_id, frame_seq, frame_turn_id, is_idle_terminal_allowed, is_turn_terminal_allowed,
88    parse_turn_generation, turn_ids_match,
89};
90pub use verbosity::{
91    is_valid_verbosity_level, should_show, VerbosityTier, VERBOSITY_DEBUG, VERBOSITY_NORMAL,
92    VERBOSITY_QUIET,
93};
94
95/// Crate version reported in `connection_init`.
96pub const VERSION: &str = env!("CARGO_PKG_VERSION");