fluers_core/request.rs
1//! Request-scoped tool construction.
2//!
3//! The dev server (and any host that serves many agent runs) must build some
4//! tools **per request** because they carry per-run state — most notably the
5//! built-in `task` tool ([`crate::subagent::TaskTool`]), which owns the run's
6//! cancellation token, event sink, and delegation budget. Reusing one across
7//! requests would cross-wire cancellation and events between concurrent runs.
8//!
9//! [`ToolRequestContext`] bundles exactly the per-run inputs a tool factory
10//! needs, and [`ToolFactory`] is the type-erased closure a host stores to turn
11//! that context into a concrete tool list. See `docs/DEV_CONFIG_UX_DESIGN.md`.
12
13use std::sync::Arc;
14
15use tokio_util::sync::CancellationToken;
16
17use crate::event::EventSink;
18use crate::model::{Model, ModelProvider};
19use crate::policy::ToolPolicy;
20use crate::runner::RunConfig;
21use crate::tool::Tool;
22
23/// Inputs needed to build a single request's tool list. Passed **by value**
24/// into a [`ToolFactory`] so the factory can construct request-local tools
25/// (e.g. a fresh top-level `TaskTool` bound to this run's cancel token + sink).
26///
27/// The `provider` / `parent_model` / `parent_config` are the agent's values
28/// (the same for every request of that agent); only `cancel` + `event_sink`
29/// vary per request. They are bundled together so the factory signature stays
30/// a single argument.
31#[derive(Clone)]
32pub struct ToolRequestContext {
33 /// The model provider (shared, stateless — safe to reuse across requests).
34 pub provider: Arc<dyn ModelProvider>,
35 /// The parent agent's model id. Inherited by subagents that omit their own.
36 pub parent_model: Model,
37 /// The parent agent's run config. Inherited by subagents that omit their own.
38 pub parent_config: RunConfig,
39 /// This run's cancellation token. Children inherit it via the `TaskTool`.
40 pub cancel: CancellationToken,
41 /// This run's event sink (OTel / tracing). Children emit to the same sink.
42 pub event_sink: Option<Arc<dyn EventSink>>,
43 /// This run's optional tool policy (Fae deviation; see the README).
44 /// Children inherit it via the `TaskTool` so a governance gate cannot be
45 /// bypassed by delegating to a subagent. `None` ⇒ allow-all.
46 pub policy: Option<Arc<dyn ToolPolicy>>,
47}
48
49/// Builds the full tool list for a single request.
50///
51/// Stored on a server's agent handle; when set, it takes precedence over any
52/// static tool list. The closure must be `Send + Sync` (called concurrently
53/// from many request tasks) and `Clone`-cheap (it is an `Arc`).
54pub type ToolFactory = Arc<dyn Fn(ToolRequestContext) -> Vec<Arc<dyn Tool>> + Send + Sync>;