brokerd: memory calls to memoryd with the session's state; labels only stricter
Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
//! ```
|
||||
|
||||
use crate::args::{ToolArgs, ToolName};
|
||||
use crate::policy::Decision;
|
||||
use crate::policy::{Decision, Label, SessionState};
|
||||
use proto::{CallId, SessionId, ToolResponse};
|
||||
|
||||
/// A directory mounted for one call: a path and whether the runtime may write to it.
|
||||
@@ -42,6 +42,7 @@ pub struct RunSpec {
|
||||
arguments: ToolArgs,
|
||||
mounts: Vec<Mount>,
|
||||
egress: Option<Vec<String>>,
|
||||
state: SessionState,
|
||||
}
|
||||
|
||||
impl RunSpec {
|
||||
@@ -63,6 +64,10 @@ impl RunSpec {
|
||||
pub fn egress(&self) -> Option<&[String]> {
|
||||
self.egress.as_deref()
|
||||
}
|
||||
/// The session's state when the call was decided.
|
||||
pub fn state(&self) -> SessionState {
|
||||
self.state
|
||||
}
|
||||
}
|
||||
|
||||
/// A `Runtime`'s answer to one call. Its text reaches the model as a `failed` result labelled
|
||||
@@ -83,6 +88,13 @@ pub struct RunOutput {
|
||||
/// Runs one call. `Send + Sync` so one `Runtime` can serve several brokers at once.
|
||||
pub trait Runtime: Send + Sync {
|
||||
fn run(&self, spec: &RunSpec) -> Result<RunOutput, RunError>;
|
||||
|
||||
/// `run`, and a label for what came back when the runtime knows one (`memoryd` does: a
|
||||
/// `recall` hit from an untrusted session). The runner keeps the stricter of this and the
|
||||
/// grant's label. Container runtimes know none.
|
||||
fn run_labelled(&self, spec: &RunSpec) -> Result<(RunOutput, Option<Label>), RunError> {
|
||||
self.run(spec).map(|output| (output, None))
|
||||
}
|
||||
}
|
||||
|
||||
/// The production runtime for M3a. It runs nothing; every call is `Unavailable`.
|
||||
@@ -126,14 +138,25 @@ pub fn run(decision: Decision, runtime: &dyn Runtime) -> proto::ToolResponse {
|
||||
arguments: args.clone(),
|
||||
mounts,
|
||||
egress,
|
||||
state: decision.state(),
|
||||
};
|
||||
match runtime.run(&spec) {
|
||||
Ok(output) => ToolResponse::Result {
|
||||
content: output.content,
|
||||
class: label.class,
|
||||
untrusted: label.untrusted,
|
||||
truncated: output.truncated,
|
||||
},
|
||||
match runtime.run_labelled(&spec) {
|
||||
Ok((output, found)) => {
|
||||
// Labels only get stricter: the higher class, and untrusted if either says so.
|
||||
let (class, untrusted) = match found {
|
||||
Some(found) => (
|
||||
label.class.max(found.class),
|
||||
label.untrusted || found.untrusted,
|
||||
),
|
||||
None => (label.class, label.untrusted),
|
||||
};
|
||||
ToolResponse::Result {
|
||||
content: output.content,
|
||||
class,
|
||||
untrusted,
|
||||
truncated: output.truncated,
|
||||
}
|
||||
}
|
||||
Err(RunError::Failed(message) | RunError::Unavailable(message)) => {
|
||||
ToolResponse::Failed { message }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user