Awaken Agents has one tool-call pipeline. A model-emitted batch is first committed as
Requested; each call then passes the permission gate and reaches the resolved
executor only on Allow. Results stay behind the batch publication barrier
until every call is terminal.
ToolExecutionTarget is a trusted property of an executable RawTool, not an
agent-authored execution-mode selector:
pub enum ToolExecutionTarget {
Brain, // default: run beside the model/runtime
Sandbox, // run through the configured sandbox executor
}
The host still owns where a ToolExecutor physically runs. The execution core does not
choose a transport, sandbox tier, or fleet topology from model-authored input.
Static structure
flowchart LR
C[ToolCall batch] --> B[durable ToolBatch]
B --> G[ToolGateHook]
G --> O{GateOutcome}
O -->|Allow| T{ToolExecutionTarget}
T -->|Brain| E[ToolExecutor / RawTool]
T -->|Sandbox| S[Sandbox executor]
O -->|Block / SetResult| R[terminal ToolOutput]
O -->|RequireConfirmation / Schedule| W[ResumeTicket]
E --> R
S --> R
R --> P[batch publication barrier]
The core contracts live in awaken_runtime_contract::tool:
pub struct ToolOutput {
pub call_id: String,
pub content: Vec<ContentBlock>,
pub is_error: bool,
pub state: Vec<Command>,
}
#[async_trait]
pub trait ToolExecutor: Send + Sync {
fn recovery_capability(&self, tool_id: &str) -> ToolRecoveryCapability;
async fn invoke(&self, call: &ToolCall) -> Result<ToolOutput, ToolError>;
}
ToolOutput::text() is only a derived plain-text view. Structured content blocks
are the stored and projected result. State commands are staged and validated at
the commit boundary; tools never write committed state directly.
Dynamic behavior
- Persist the complete
ToolBatchand assistant tool-use blocks before entering an executor. - Process calls in model order. The one optimized exception is a batch made
entirely of delegation calls whose executor explicitly supports parallel
completion; all gates must return
Allowbefore that parallel branch starts. - Resolve the gate outcome:
Allowvalidates recovery policy, recordsExecuting, and invokes the Brain or Sandbox executor.BlockandSetResultproduce an immediate terminal result.RequireConfirmationandSchedulecommit an awaiting ticket and park the Run.
- Commit each call’s execution outcome independently. Do not publish partial batch results to the model transcript.
- Once every call is
CompletedorIndeterminate, validate and finalize the batch, then publish ordered result messages and staged state.
Recovery uses the durable call phase plus the pinned ToolRecoveryPolicy.
UnavailableBeforeDispatch proves the external dispatch boundary was not
crossed; failures after dispatch remain Execution and cannot be replayed unless
the executable capability and pinned policy permit it.
Projection contract
awaken_agent_contract::event::ToolDisposition describes a committed tool call
to protocol consumers:
pub enum ToolDisposition {
Executed,
PendingClient,
PendingBuiltin,
}
This is a read projection, not an execution-placement selector. PendingClient
means a client-executed tool is awaiting an external result; PendingBuiltin
means a built-in tool is awaiting a permission decision.
Key files
crates/runtime/awaken-runtime-contract/src/tool.rs— tool, output, target, recovery, and executor contractscrates/runtime/awaken-runtime-contract/src/tool_batch.rs— durable batch state machine and publication barriercrates/runtime/awaken-runtime-contract/src/permission.rs— gate outcomescrates/runtime/awaken-runtime/src/engine/dispatch.rs— ordered dispatch and the bounded parallel-delegation branchcrates/contract/awaken-agent-contract/src/event/agent.rs— protocol projection disposition