Skip to main content

WebSocketClient

Struct WebSocketClient 

Source
pub struct WebSocketClient { /* private fields */ }
Expand description

WebSocket client for real-time communication with persistent connection.

Uses a single dispatcher task that reads all incoming frames and routes them to the appropriate consumer (request-response, subscription, or chat stream). The writer is held in a separate mutex so sends never block on reads.

Implementations§

Source§

impl WebSocketClient

Source

pub fn new(ws_url: impl AsRef<str>, token: impl Into<String>) -> Result<Self>

Create a new WebSocket client

Source

pub async fn find_all(&self, collection: &str) -> Result<Vec<Record>>

Find all records in a collection via WebSocket

Source

pub async fn subscribe( &self, collection: &str, filter_field: Option<&str>, filter_value: Option<&str>, ) -> Result<Receiver<MutationNotificationPayload>>

Subscribe to collection changes with an optional field filter.

Returns a receiver that yields MutationNotificationPayload events.

Source

pub async fn unsubscribe(&self, collection: &str) -> Result<()>

Stop receiving mutation notifications for a collection.

This is an intentional teardown: it drops the local subscription sender(s) for collection (so dropped receivers stop being fed) and sends a best-effort Unsubscribe frame to the server so it stops streaming this collection on this connection. If the socket is already gone the local teardown suffices, since the server drops all subscriptions when the connection closes. Safe to call for a collection that is not currently subscribed (no-op).

A unique messageId is attached to the frame purely so the server’s ack carries a correlation id: Unsubscribe registers no pending request, so the dispatcher finds no match and silently discards the ack. The id stops that unmatched ack from being misrouted to an unrelated in-flight request.

Source

pub async fn chat_send( &self, chat_id: &str, message: &str, ) -> Result<Receiver<ChatStreamEvent>>

Send a chat message and receive streaming responses with client tool support.

Returns a receiver that yields ChatStreamEvent items:

  • Chunk(text) for each token/chunk from the LLM
  • ToolCall { call_id, tool_name, arguments } when ekoDB needs a client tool executed
  • End { ... } when the stream completes
  • Error(msg) if something goes wrong

When a ToolCall event is received, call send_tool_result() to return the result. ekoDB will feed the result back to the LLM and continue streaming.

Source

pub async fn chat_send_with_tools( &self, chat_id: &str, message: &str, client_tools: Option<Vec<ClientToolDefinition>>, max_iterations: Option<u32>, confirm_tools: Option<Vec<String>>, exclude_tools: Option<Vec<String>>, ) -> Result<Receiver<ChatStreamEvent>>

Send a chat message with client tool definitions.

Same as chat_send but includes client-side tool definitions that ekoDB merges with its built-in tools when calling the LLM.

Source

pub async fn register_client_tools( &self, chat_id: &str, tools: Vec<ClientToolDefinition>, ) -> Result<()>

Register client-side tools for a chat session.

These tools persist across messages within the session. When the LLM invokes one, ekoDB sends a ClientToolCall event back to the client.

Note: The WS protocol for RegisterClientTools does not include a messageId field, so we use a dedicated register_tools_ack slot in the dispatcher instead of pending_requests. This means only one registration can be in-flight at a time, which is fine since tool registration is typically done once before chat starts.

Source

pub async fn cancel_chat(&self, chat_id: &str) -> Result<()>

Cancel an in-flight chat stream by chat_id. Fires the server-side cancellation token, which aborts the LLM HTTP call AND skips persisting the assistant message. Use this instead of just dropping the receiver — pre-fix, dropping only halted chunk delivery; the LLM kept generating server-side and the assistant turn still landed in storage.

Connection: requires an active WS. If the client isn’t connected, this auto-reconnects via ensure_connected() (matching every other WS-RPC method on this client). Once delivered to the server, the cancel itself is a no-op when no in-flight stream matches chat_id — callers can fire it speculatively without checking.

Source

pub async fn send_tool_result( &self, chat_id: &str, call_id: &str, success: bool, result: Option<Value>, error: Option<String>, ) -> Result<()>

Send the result of a client-side tool execution back to ekoDB.

Call this after receiving a ChatStreamEvent::ToolCall event. ekoDB will feed the result back to the LLM and continue the conversation.

Source

pub async fn raw_completion( &self, request: &RawCompletionRequest, ) -> Result<RawCompletionResponse>

Stateless raw LLM completion via WebSocket.

Sends a RawComplete message and waits for the Success response. Preferred over HTTP for deployed instances: the persistent WSS connection is already authenticated and won’t be killed by reverse proxy timeouts.

Source

pub async fn close(&self) -> Result<()>

Close the WebSocket connection with a proper close frame.

Source

pub async fn set_schema_cache(&self, cache: Arc<SchemaCache>)

Attach a schema cache for automatic invalidation on SchemaChanged events.

Source

pub async fn send_crud(&self, msg_type: &str, payload: Value) -> Result<Value>

Helper: send a typed WS request as raw JSON and wait for response. Attaches messageId at the top level for concurrent correlation. Send a typed CRUD request as raw JSON and return the data from the response.

Source

pub async fn insert( &self, collection: &str, record: Value, bypass_ripple: Option<bool>, ) -> Result<Value>

Insert a single record into a collection via WebSocket.

Source

pub async fn query( &self, collection: &str, filter: Option<Value>, sort: Option<Value>, limit: Option<u64>, skip: Option<u64>, ) -> Result<Vec<Value>>

Query records from a collection via WebSocket.

Source

pub async fn find_by_id(&self, collection: &str, id: &str) -> Result<Value>

Find a record by ID via WebSocket.

Source

pub async fn update( &self, collection: &str, id: &str, record: Value, bypass_ripple: Option<bool>, ) -> Result<Value>

Update a record by ID via WebSocket.

Source

pub async fn delete( &self, collection: &str, id: &str, bypass_ripple: Option<bool>, ) -> Result<()>

Delete a record by ID via WebSocket.

Source

pub async fn batch_insert( &self, collection: &str, records: Vec<Value>, bypass_ripple: Option<bool>, ) -> Result<Value>

Batch insert multiple records via WebSocket.

Source

pub async fn batch_update( &self, collection: &str, updates: Vec<(String, Value)>, bypass_ripple: Option<bool>, ) -> Result<Value>

Batch update multiple records via WebSocket. Each update is a tuple of (id, record_data).

Source

pub async fn batch_delete( &self, collection: &str, ids: Vec<String>, bypass_ripple: Option<bool>, ) -> Result<()>

Batch delete multiple records by IDs via WebSocket.

Full-text search via WebSocket.

Source

pub async fn distinct_values( &self, collection: &str, field: &str, filter: Option<Value>, ) -> Result<Value>

Get distinct values for a field via WebSocket.

Source

pub async fn update_with_action( &self, collection: &str, id: &str, action: &str, field: &str, value: Option<Value>, ) -> Result<Value>

Apply an atomic field action to a record via WebSocket.

Source

pub async fn create_collection( &self, name: &str, schema: Option<Value>, ) -> Result<()>

Create a new collection with optional schema via WebSocket.

Source

pub async fn list_collections(&self) -> Result<Vec<String>>

List all collections via WebSocket.

Source

pub async fn delete_collection(&self, name: &str) -> Result<()>

Delete a collection via WebSocket.

Trait Implementations§

Source§

impl Clone for WebSocketClient

Source§

fn clone(&self) -> WebSocketClient

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more