pub trait WorkspaceBackend:
Send
+ Sync
+ 'static {
type Conversation: ConversationBackend;
// Required methods
fn id(&self) -> WorkspaceId;
fn info(
&self,
) -> impl Future<Output = Result<WorkspaceInfo, KitError>> + Send + '_;
fn new_conversation(
&self,
request: NewConversation,
) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_;
fn list_conversations(
&self,
) -> impl Future<Output = Result<Vec<ConversationInfo>, KitError>> + Send + '_;
fn conversation_info(
&self,
id: ConversationId,
) -> impl Future<Output = Result<ConversationInfo, KitError>> + Send + '_;
fn get_conversation(
&self,
id: ConversationId,
) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_;
fn list_tools(
&self,
) -> impl Future<Output = Result<Vec<ToolInfo>, KitError>> + Send + '_;
fn ingest_knowledge(
&self,
request: IngestKnowledgeRequest,
) -> impl Future<Output = Result<(), KitError>> + Send + '_;
fn close(self) -> impl Future<Output = Result<(), KitError>> + Send
where Self: Sized;
}Expand description
Public implementation contract for one live portable workspace.
A caller agent returns its own concrete workspace implementation through
AgentBackend::Workspace, and this workspace
returns its own concrete Conversation implementation.
Runtime composition can instead use a caller-owned exhaustive enum hierarchy.
Closing consumes the implementation, seals new work, and invalidates live
conversations after accepted cleanup settles. Drop alone carries no
asynchronous cleanup guarantee.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
assert!(workspace.list_conversations().await?.is_empty());
assert_eq!(workspace.info().await?.id(), &workspace.id());
workspace.close().await?;Required Associated Types§
Sourcetype Conversation: ConversationBackend
type Conversation: ConversationBackend
Concrete conversation implementation produced by this workspace.
Required Methods§
Sourcefn id(&self) -> WorkspaceId
fn id(&self) -> WorkspaceId
Returns the durable portable workspace identity.
This is the durable workspace identity. A handle also carries a runtime revision binding, so a stable id does not make an old handle current.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
let id = workspace.id();
assert_eq!(workspace.info().await?.id(), &id);Sourcefn info(
&self,
) -> impl Future<Output = Result<WorkspaceInfo, KitError>> + Send + '_
fn info( &self, ) -> impl Future<Output = Result<WorkspaceInfo, KitError>> + Send + '_
Reads the current committed workspace information.
The result contains the complete committed context/defaults and revision. It does not refresh this handle after a concurrent revision change.
§Errors
Returns KitError for a closed parent/workspace, stale revision,
state-read failure, inconsistent durable state, or deadline expiry.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
let info = workspace.info().await?;
assert_eq!(info.name(), "review");
assert_eq!(info.revision(), 1);Sourcefn new_conversation(
&self,
request: NewConversation,
) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_
fn new_conversation( &self, request: NewConversation, ) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_
Creates and publishes one conversation under this workspace.
The returned associated child is published only after resolved defaults, initial knowledge, backend attachment, and durable ownership agree.
§Errors
Returns KitError for closed or stale runtime, busy admission, invalid
input or unsupported policy/integrations, and dependency/deadline failures.
Accepted native setup remains durably attached or recovery-owned on failure.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
use agents_kit::ConversationBackend;
use agents_kit::conversation::NewConversation;
let conversation = workspace.new_conversation(NewConversation::new(
Some("Review".into()), None, Vec::new(),
)?).await?;
assert_eq!(conversation.info().await?.title(), Some("Review"));
// Parent close preserves this quiescent durable conversation for reopen.
workspace.close().await?;Sourcefn list_conversations(
&self,
) -> impl Future<Output = Result<Vec<ConversationInfo>, KitError>> + Send + '_
fn list_conversations( &self, ) -> impl Future<Output = Result<Vec<ConversationInfo>, KitError>> + Send + '_
Lists live or reopenable conversations in deterministic identity order.
Inventory comes from ownership-valid durable records; it is not limited to handles currently open in this process. Terminally closed conversations are excluded. Listing does not claim live handles.
§Errors
Returns KitError for closed or stale runtime, state/dependency read
failures, inconsistent inventory, or deadline expiry.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
assert!(workspace.list_conversations().await?.is_empty());Sourcefn conversation_info(
&self,
id: ConversationId,
) -> impl Future<Output = Result<ConversationInfo, KitError>> + Send + '_
fn conversation_info( &self, id: ConversationId, ) -> impl Future<Output = Result<ConversationInfo, KitError>> + Send + '_
Reads committed information for one conversation identity.
This reads committed metadata without claiming a live child handle. Missing and foreign identities do not reveal a foreign owner.
§Errors
Returns crate::error::ErrorKind::NotFound for an unavailable or foreign
conversation, or the owning closed/stale runtime, state-read, integrity, or
deadline error.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
use agents_kit::ConversationBackend;
use agents_kit::conversation::NewConversation;
let conversation = workspace.new_conversation(NewConversation::new(
Some("Review".into()), None, Vec::new(),
)?).await?;
let info = workspace.conversation_info(conversation.id()).await?;
assert_eq!(info.id(), &conversation.id());
assert_eq!(info.title(), Some("Review"));Sourcefn get_conversation(
&self,
id: ConversationId,
) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_
fn get_conversation( &self, id: ConversationId, ) -> impl Future<Output = Result<Self::Conversation, KitError>> + Send + '_
Opens the current live handle for one conversation identity.
A current conversation has at most one live public handle; repeated lookup is busy until its claim is released. Reopen verifies the current workspace revision, defaults, attachments, tools, knowledge, and recovery state. It does not create a replacement session for a missing identity.
§Errors
Returns KitError for a missing/foreign or terminal conversation, an
existing live claim, closed or stale runtime, incompatible reopen state,
or dependency/deadline failure.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
use agents_kit::ConversationBackend;
use agents_kit::conversation::NewConversation;
let conversation = workspace.new_conversation(NewConversation::new(None, None, Vec::new())?).await?;
let id = conversation.id();
let workspace_id = workspace.id();
workspace.close().await?;
let workspace = agent.get_workspace(workspace_id).await?;
let reopened = workspace.get_conversation(id.clone()).await?;
assert_eq!(reopened.id(), id);
workspace.close().await?;Sourcefn list_tools(
&self,
) -> impl Future<Output = Result<Vec<ToolInfo>, KitError>> + Send + '_
fn list_tools( &self, ) -> impl Future<Output = Result<Vec<ToolInfo>, KitError>> + Send + '_
Lists agents-kit-managed tools installed for this workspace.
Returns the complete source-neutral catalog the Agent owns and can expose in this workspace, subject to its execution policy. An unavailable source must not be silently omitted from a purportedly complete result.
§Errors
Returns KitError for closed or stale runtime, unsupported or incomplete
catalog exposure, malformed source data, or dependency/deadline failure.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
// This Agent was constructed without Toolsets.
assert!(workspace.list_tools().await?.is_empty());Sourcefn ingest_knowledge(
&self,
request: IngestKnowledgeRequest,
) -> impl Future<Output = Result<(), KitError>> + Send + '_
fn ingest_knowledge( &self, request: IngestKnowledgeRequest, ) -> impl Future<Output = Result<(), KitError>> + Send + '_
Atomically replaces managed knowledge from this workspace.
An omitted scope selects this Workspace. Explicit Agent or Database scope
is validated under the shared knowledge rules; Conversation scope is not
accepted here. Empty sources are a no-op after scope validation, not deletion.
Updating workspace context/defaults does not move sources. See crate::knowledge
for local ingestion and policy examples.
§Errors
Returns KitError for invalid sources or scope, missing/incompatible
knowledge integrations, closed or stale runtime, busy admission, or
dependency/deadline failure. Unsupported semantics fail explicitly.
§Examples
This example requires a live Workspace under an open Agent, with configured backend and storage integrations. It is compiled without starting services.
use agents_kit::{WorkspaceBackend, KitError};
use agents_kit::knowledge::IngestKnowledgeRequest;
async fn replace_sources<W: WorkspaceBackend>(workspace: &W, request: IngestKnowledgeRequest)
-> Result<(), KitError>
{
workspace.ingest_knowledge(request).await
}Sourcefn close(self) -> impl Future<Output = Result<(), KitError>> + Sendwhere
Self: Sized,
fn close(self) -> impl Future<Output = Result<(), KitError>> + Sendwhere
Self: Sized,
Consumes the implementation, seals its runtime, and settles accepted work.
Close cascade-invalidates live descendants after accepted work and interactions settle. Quiescent durable conversations, notifications, and knowledge remain for reopen. This does not terminally close conversations or acknowledge caller events. Drop alone provides no async cleanup guarantee.
§Errors
Returns KitError when an owned cleanup responsibility fails or cannot
settle within the lifecycle deadline. The consumed handle is not restored;
durable recovery owns later reconciliation and supplementary failures do
not replace the primary error.
§Examples
This local Custom agent uses in-memory Lance and sends no network requests.
let id = workspace.id();
workspace.close().await?;
// Runtime closure does not delete the durable workspace.
assert_eq!(agent.workspace_info(id).await?.name(), "review");Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".