use anyhow::Result;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::{
runtime::RuntimeHandle,
tool::spec::typed_spec,
types::{CallbackDeliveryMode, ToolCapabilityFamily, TrustLevel},
};
use super::{serialize_success, BuiltinToolDefinition};
use crate::tool::helpers::parse_tool_args;
pub(crate) const NAME: &str = "CreateExternalTrigger";
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[allow(dead_code)]
pub(crate) enum CallbackDeliveryModeArgs {
EnqueueMessage,
#[serde(alias = "wake_only")]
WakeHint,
}
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub(crate) struct CreateExternalTriggerArgs {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub(crate) description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub(crate) source: Option<String>,
pub(crate) delivery_mode: CallbackDeliveryModeArgs,
}
#[allow(dead_code)]
pub(crate) fn definition() -> Result<BuiltinToolDefinition> {
Ok(BuiltinToolDefinition {
family: ToolCapabilityFamily::ExternalTrigger,
spec: typed_spec::<CreateExternalTriggerArgs>(
NAME,
"Return the default external ingress capability for this agent and delivery mode.",
)?,
})
}
pub(crate) async fn execute(
runtime: &RuntimeHandle,
_agent_id: &str,
_trust: &TrustLevel,
input: &Value,
) -> Result<crate::tool::ToolResult> {
let args: CreateExternalTriggerArgs = parse_tool_args(NAME, input)?;
let delivery_mode = match args.delivery_mode {
CallbackDeliveryModeArgs::EnqueueMessage => CallbackDeliveryMode::EnqueueMessage,
CallbackDeliveryModeArgs::WakeHint => CallbackDeliveryMode::WakeHint,
};
let capability = runtime.default_external_trigger(delivery_mode).await?;
serialize_success(NAME, &capability)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn delivery_mode_accepts_legacy_wake_only_alias() {
let args: CreateExternalTriggerArgs = serde_json::from_value(serde_json::json!({
"description": "Check external queue",
"source": "test",
"delivery_mode": "wake_only"
}))
.expect("legacy wake_only alias should deserialize");
assert!(matches!(
args.delivery_mode,
CallbackDeliveryModeArgs::WakeHint
));
}
}