use std::fmt;
use async_trait::async_trait;
use forge_core_utils::approvals::ApprovalStatus;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ExecutorApprovalError {
#[error("executor approval session not registered")]
SessionNotRegistered,
#[error("executor approval request failed: {0}")]
RequestFailed(String),
#[error("executor approval service unavailable")]
ServiceUnavailable,
}
impl ExecutorApprovalError {
pub fn request_failed<E: fmt::Display>(err: E) -> Self {
Self::RequestFailed(err.to_string())
}
}
#[async_trait]
pub trait ExecutorApprovalService: Send + Sync {
async fn request_tool_approval(
&self,
tool_name: &str,
tool_input: Value,
tool_call_id: &str,
) -> Result<ApprovalStatus, ExecutorApprovalError>;
}
#[derive(Debug, Default)]
pub struct NoopExecutorApprovalService;
#[async_trait]
impl ExecutorApprovalService for NoopExecutorApprovalService {
async fn request_tool_approval(
&self,
_tool_name: &str,
_tool_input: Value,
_tool_call_id: &str,
) -> Result<ApprovalStatus, ExecutorApprovalError> {
Ok(ApprovalStatus::Approved)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ToolCallMetadata {
pub tool_call_id: String,
}