fix(runtime): isolate agent state by project (#101)

This commit is contained in:
2026-07-25 22:14:02 +02:00
parent 6a87c4635f
commit 6e98fd89f7
52 changed files with 1894 additions and 805 deletions

View File

@ -30,7 +30,7 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use crate::conversation::ConversationId;
use crate::ids::AgentId;
use crate::ids::{AgentId, RuntimeAgentKey};
use crate::input::InputSource;
/// A read-only, cloned view of one queued [`Ticket`] in a target agent's FIFO.
@ -71,7 +71,7 @@ pub trait AgentQueueSnapshot: Send + Sync {
///
/// An agent with no queue yields an empty `Vec`. Positions are recomputed from
/// the current order (`0` = head). Pure read: the queue is left untouched.
fn queue_for(&self, agent: AgentId) -> Vec<QueuedTicketSnapshot>;
fn queue_for(&self, agent: RuntimeAgentKey) -> Vec<QueuedTicketSnapshot>;
}
/// Identifies one queued [`Ticket`] within a target agent's mailbox.
@ -283,7 +283,7 @@ pub trait AgentMailbox: Send + Sync {
/// The returned [`PendingReply`] resolves when a later [`AgentMailbox::resolve`]
/// feeds a result to this ticket (once it reaches the head and is answered), or
/// to [`MailboxError::Cancelled`] if the reply channel closes first.
fn enqueue(&self, agent: AgentId, ticket: Ticket) -> PendingReply;
fn enqueue(&self, agent: RuntimeAgentKey, ticket: Ticket) -> PendingReply;
/// Resolves the request at the **head** of `agent`'s FIFO with `result`,
/// waking its awaiting [`PendingReply`] and removing it from the queue.
@ -294,7 +294,7 @@ pub trait AgentMailbox: Send + Sync {
/// # Errors
/// [`MailboxError::NoPendingRequest`] when `agent` has no queued ticket (an
/// `idea_reply` with no matching ask in flight).
fn resolve(&self, agent: AgentId, result: String) -> Result<(), MailboxError>;
fn resolve(&self, agent: RuntimeAgentKey, result: String) -> Result<(), MailboxError>;
/// Resolves the request identified by `ticket_id` **anywhere** in `agent`'s FIFO
/// with `result`, waking its awaiting [`PendingReply`] and removing it from the
@ -314,7 +314,7 @@ pub trait AgentMailbox: Send + Sync {
/// (and, for the default, when `agent`'s queue is empty).
fn resolve_ticket(
&self,
agent: AgentId,
agent: RuntimeAgentKey,
_ticket_id: TicketId,
result: String,
) -> Result<(), MailboxError> {
@ -326,7 +326,7 @@ pub trait AgentMailbox: Send + Sync {
///
/// A no-op when the head is a different ticket (the timed-out one was already
/// resolved, or another caller's ticket is now in front) — idempotent and safe.
fn cancel_head(&self, agent: AgentId, ticket_id: TicketId);
fn cancel_head(&self, agent: RuntimeAgentKey, ticket_id: TicketId);
/// Completes the turn of the ticket `ticket_id` **without** a reply, waking its
/// awaiting [`PendingReply`] with [`TurnResolution::ReturnedToPromptNoReply`].
@ -346,7 +346,7 @@ pub trait AgentMailbox: Send + Sync {
///
/// The default is a no-op: a mailbox that cannot wake a pending caller early simply
/// falls back to the caller's timeout net (no behavioural change for it).
fn complete_without_reply(&self, agent: AgentId, ticket_id: TicketId) {
fn complete_without_reply(&self, agent: RuntimeAgentKey, ticket_id: TicketId) {
let _ = (agent, ticket_id);
}
}