pub struct Workspace { /* private fields */ }code only.Expand description
A shared project context for collaborative code generation and execution.
Workspace is the public anchor for multi-agent project-building flows.
It represents a shared project root, metadata, and collaboration state.
Specialist agents attached to the same workspace can publish and consume
typed CollaborationEvents without configuring raw pub/sub directly.
Internally, Workspace uses Arc<WorkspaceInner> so it can be cheaply
cloned and shared across agents and async boundaries. The collaboration
transport is an in-process broadcast channel — transport details are hidden
from the public API.
Use Workspace::new to get a WorkspaceBuilder for ergonomic construction.
§Example
use adk_code::Workspace;
let workspace = Workspace::new("./my-project")
.project_name("my-project")
.session_id("sess-abc")
.build();
assert_eq!(workspace.root(), &std::path::PathBuf::from("./my-project"));
assert_eq!(workspace.metadata().project_name, "my-project");
assert_eq!(workspace.metadata().session_id.as_deref(), Some("sess-abc"));Implementations§
Source§impl Workspace
impl Workspace
Sourcepub fn new(root: impl Into<PathBuf>) -> WorkspaceBuilder
pub fn new(root: impl Into<PathBuf>) -> WorkspaceBuilder
Start building a new workspace rooted at the given path.
Returns a WorkspaceBuilder for fluent configuration.
§Example
use adk_code::Workspace;
let ws = Workspace::new("/tmp/project").build();
assert_eq!(ws.root(), &std::path::PathBuf::from("/tmp/project"));Sourcepub fn metadata(&self) -> &WorkspaceMetadata
pub fn metadata(&self) -> &WorkspaceMetadata
Project and session metadata.
Sourcepub fn publish(&self, event: CollaborationEvent) -> usize
pub fn publish(&self, event: CollaborationEvent) -> usize
Publish a collaboration event to all subscribers.
This is a non-blocking operation. If there are no active subscribers, the event is silently dropped. Returns the number of receivers that received the event.
§Example
use adk_code::{CollaborationEvent, CollaborationEventKind, Workspace};
let ws = Workspace::new("./proj").build();
let mut rx = ws.subscribe();
ws.publish(CollaborationEvent::new(
"c1", "api", "backend", CollaborationEventKind::WorkPublished,
));Sourcepub fn subscribe(&self) -> Receiver<CollaborationEvent>
pub fn subscribe(&self) -> Receiver<CollaborationEvent>
Subscribe to collaboration events on this workspace.
Returns a broadcast::Receiver that yields every event published
after the subscription is created. Each subscriber gets its own
independent stream of events.
§Example
use adk_code::{CollaborationEvent, CollaborationEventKind, Workspace};
let ws = Workspace::new("./proj").build();
let mut rx = ws.subscribe();
ws.publish(CollaborationEvent::new(
"c1", "topic", "producer", CollaborationEventKind::NeedWork,
));Sourcepub async fn wait_for(
&self,
correlation_id: &str,
timeout: Duration,
) -> Option<CollaborationEvent>
pub async fn wait_for( &self, correlation_id: &str, timeout: Duration, ) -> Option<CollaborationEvent>
Wait for a collaboration event matching the given correlation_id.
Subscribes to the workspace event stream and returns the first event
whose correlation_id matches. If no matching event arrives within
timeout, returns None.
This implements the wait/resume pattern: an agent can publish a
CollaborationEventKind::NeedWork event and then call wait_for
to suspend until the matching CollaborationEventKind::WorkPublished
(or other correlated response) arrives.
§Example
use adk_code::{CollaborationEvent, CollaborationEventKind, Workspace};
use std::time::Duration;
let ws = Workspace::new("./proj").build();
// In practice another agent would publish the matching event.
let result = ws.wait_for("corr-42", Duration::from_millis(100)).await;
assert!(result.is_none()); // timed out — no publisherSourcepub fn events(&self) -> Vec<CollaborationEvent>
pub fn events(&self) -> Vec<CollaborationEvent>
Get a snapshot of all events published to this workspace.
Returns a clone of the internal event log. Unlike the broadcast channel (which has a fixed capacity and drops old events for slow subscribers), the event log retains every event published since workspace creation.
§Example
use adk_code::{CollaborationEvent, CollaborationEventKind, Workspace};
let ws = Workspace::new("./proj").build();
ws.publish(CollaborationEvent::new(
"c1", "topic", "producer", CollaborationEventKind::Completed,
));
let events = ws.events();
// events may contain the published event if still in the bufferSourcepub fn request_work(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
) -> CollaborationEvent
pub fn request_work( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, ) -> CollaborationEvent
Request work from another specialist or coordinator.
Publishes a CollaborationEventKind::NeedWork event and returns
the event that was published. The caller can then use
Workspace::wait_for_work to suspend until the matching
CollaborationEventKind::WorkPublished event arrives.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
let event = ws.request_work("corr-1", "api-routes", "frontend_engineer");
assert_eq!(event.kind, adk_code::CollaborationEventKind::NeedWork);Sourcepub fn claim_work(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
)
pub fn claim_work( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, )
Claim ownership of a requested work item.
Publishes a CollaborationEventKind::WorkClaimed event to signal
that this agent is taking responsibility for the work.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.claim_work("corr-1", "api-routes", "backend_engineer");Sourcepub fn publish_work(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
payload: Value,
)
pub fn publish_work( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, payload: Value, )
Publish completed work to the workspace.
Publishes a CollaborationEventKind::WorkPublished event with the
given payload. Agents waiting via Workspace::wait_for_work on the
same correlation_id will be resumed.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.publish_work(
"corr-1",
"api-routes",
"backend_engineer",
serde_json::json!({ "routes": ["/api/users"] }),
);Sourcepub fn request_feedback(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
payload: Value,
)
pub fn request_feedback( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, payload: Value, )
Request feedback from another specialist or reviewer.
Publishes a CollaborationEventKind::FeedbackRequested event.
The caller can then use Workspace::wait_for_feedback to suspend
until the matching CollaborationEventKind::FeedbackProvided arrives.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.request_feedback(
"corr-2",
"api-contract",
"backend_engineer",
serde_json::json!({ "schema": "v1" }),
);Sourcepub fn provide_feedback(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
payload: Value,
)
pub fn provide_feedback( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, payload: Value, )
Provide feedback in response to a feedback request.
Publishes a CollaborationEventKind::FeedbackProvided event.
Agents waiting via Workspace::wait_for_feedback on the same
correlation_id will be resumed.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.provide_feedback(
"corr-2",
"api-contract",
"reviewer",
serde_json::json!({ "approved": true }),
);Sourcepub fn signal_blocked(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
payload: Value,
)
pub fn signal_blocked( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, payload: Value, )
Signal that this agent is blocked and cannot continue.
Publishes a CollaborationEventKind::Blocked event with a payload
describing what is needed to unblock.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.signal_blocked(
"corr-3",
"database-schema",
"backend_engineer",
serde_json::json!({ "needs": "schema approval" }),
);Sourcepub fn signal_completed(
&self,
correlation_id: impl Into<String>,
topic: impl Into<String>,
producer: impl Into<String>,
)
pub fn signal_completed( &self, correlation_id: impl Into<String>, topic: impl Into<String>, producer: impl Into<String>, )
Signal that a work item is completed.
Publishes a CollaborationEventKind::Completed event.
§Example
use adk_code::Workspace;
let ws = Workspace::new("./proj").build();
ws.signal_completed("corr-1", "api-routes", "backend_engineer");Sourcepub async fn wait_for_work(
&self,
correlation_id: &str,
timeout: Duration,
) -> Option<CollaborationEvent>
pub async fn wait_for_work( &self, correlation_id: &str, timeout: Duration, ) -> Option<CollaborationEvent>
Wait for a CollaborationEventKind::WorkPublished event matching
the given correlation_id.
This is a convenience wrapper over Workspace::wait_for_kind that
filters for WorkPublished events specifically.
§Example
use adk_code::Workspace;
use std::time::Duration;
let ws = Workspace::new("./proj").build();
let result = ws.wait_for_work("corr-1", Duration::from_secs(5)).await;Sourcepub async fn wait_for_feedback(
&self,
correlation_id: &str,
timeout: Duration,
) -> Option<CollaborationEvent>
pub async fn wait_for_feedback( &self, correlation_id: &str, timeout: Duration, ) -> Option<CollaborationEvent>
Wait for a CollaborationEventKind::FeedbackProvided event matching
the given correlation_id.
This is a convenience wrapper over Workspace::wait_for_kind that
filters for FeedbackProvided events specifically.
§Example
use adk_code::Workspace;
use std::time::Duration;
let ws = Workspace::new("./proj").build();
let result = ws.wait_for_feedback("corr-2", Duration::from_secs(5)).await;Sourcepub async fn wait_for_kind(
&self,
correlation_id: &str,
kind: CollaborationEventKind,
timeout: Duration,
) -> Option<CollaborationEvent>
pub async fn wait_for_kind( &self, correlation_id: &str, kind: CollaborationEventKind, timeout: Duration, ) -> Option<CollaborationEvent>
Wait for a collaboration event matching both correlation_id and kind.
Subscribes to the workspace event stream and returns the first event
whose correlation_id and kind both match. If no matching event
arrives within timeout, returns None.
This is the most precise wait primitive — use it when you need to filter on a specific event kind rather than any correlated event.
§Example
use adk_code::{CollaborationEventKind, Workspace};
use std::time::Duration;
let ws = Workspace::new("./proj").build();
let result = ws
.wait_for_kind("corr-1", CollaborationEventKind::WorkClaimed, Duration::from_secs(5))
.await;Trait Implementations§
Auto Trait Implementations§
impl Freeze for Workspace
impl RefUnwindSafe for Workspace
impl Send for Workspace
impl Sync for Workspace
impl Unpin for Workspace
impl UnsafeUnpin for Workspace
impl UnwindSafe for Workspace
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> MaybeSend for Twhere
T: Send,
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.