use std::collections::HashMap;
use std::time::Duration;
use super::SubAgentManager;
use crate::error::SubAgentError;
use crate::grants::SecretRequest;
pub(crate) fn make_hook_env(
task_id: &str,
agent_name: &str,
tool_name: &str,
) -> HashMap<String, String> {
let mut env = HashMap::new();
env.insert("ZEPH_AGENT_ID".to_owned(), task_id.to_owned());
env.insert("ZEPH_AGENT_NAME".to_owned(), agent_name.to_owned());
env.insert("ZEPH_AGENT_TYPE".to_owned(), "subagent".to_owned());
env.insert("ZEPH_TOOL_NAME".to_owned(), tool_name.to_owned());
env
}
impl SubAgentManager {
pub fn approve_secret(
&mut self,
task_id: &str,
secret_key: &str,
ttl: Duration,
) -> Result<(), SubAgentError> {
let handle = self
.agents
.get_mut(task_id)
.ok_or_else(|| SubAgentError::NotFound(task_id.to_owned()))?;
handle.grants.sweep_expired();
if !handle
.def
.permissions
.secrets
.iter()
.any(|k| k == secret_key)
{
tracing::warn!(task_id, "secret request denied: key not in allowed list");
return Err(SubAgentError::Invalid(format!(
"secret is not in the allowed secrets list for '{}'",
handle.def.name
)));
}
handle.grants.grant_secret(secret_key, ttl);
Ok(())
}
pub fn deliver_secret(&mut self, task_id: &str, key: String) -> Result<(), SubAgentError> {
let handle = self
.agents
.get_mut(task_id)
.ok_or_else(|| SubAgentError::NotFound(task_id.to_owned()))?;
handle
.secret_tx
.try_send(Some(key))
.map_err(|e| SubAgentError::Channel(e.to_string()))
}
pub fn deny_secret(&mut self, task_id: &str) -> Result<(), SubAgentError> {
let handle = self
.agents
.get_mut(task_id)
.ok_or_else(|| SubAgentError::NotFound(task_id.to_owned()))?;
handle
.secret_tx
.try_send(None)
.map_err(|e| SubAgentError::Channel(e.to_string()))
}
pub fn try_recv_secret_request(&mut self) -> Option<(String, SecretRequest)> {
for handle in self.agents.values_mut() {
if let Ok(req) = handle.pending_secret_rx.try_recv() {
return Some((handle.task_id.clone(), req));
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::make_hook_env;
#[test]
fn make_hook_env_sets_agent_type_subagent() {
let env = make_hook_env("task-42", "my-agent", "Shell");
assert_eq!(
env.get("ZEPH_AGENT_TYPE").map(String::as_str),
Some("subagent")
);
assert_eq!(
env.get("ZEPH_AGENT_ID").map(String::as_str),
Some("task-42")
);
assert_eq!(
env.get("ZEPH_AGENT_NAME").map(String::as_str),
Some("my-agent")
);
assert_eq!(env.get("ZEPH_TOOL_NAME").map(String::as_str), Some("Shell"));
}
}