Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Enable Tool Permission HITL

Use this when tool calls must be allow / deny / ask with human approval.

Prerequisites

  • tirea-extension-permission is enabled.
  • Frontend can return approval decisions to run inputs.

Steps

  1. Register permission behaviors.
use std::sync::Arc;
use tirea::composition::{AgentDefinition, AgentDefinitionSpec, AgentOsBuilder};
use tirea::extensions::permission::{PermissionPlugin, ToolPolicyPlugin};

let os = AgentOsBuilder::new()
    .with_registered_behavior("tool_policy", Arc::new(ToolPolicyPlugin))
    .with_registered_behavior("permission", Arc::new(PermissionPlugin))
    .with_agent_spec(AgentDefinitionSpec::local_with_id(
        "assistant",
        AgentDefinition::new("deepseek-chat").with_behavior_ids(vec![
            "tool_policy".to_string(),
            "permission".to_string(),
        ]),
    ))
    .build()?;
  1. Configure permission policy state.
use tirea::extensions::permission::{
    permission_state_action, PermissionAction, ToolPermissionBehavior,
};

let set_default = permission_state_action(PermissionAction::SetDefault {
    behavior: ToolPermissionBehavior::Ask,
});

let allow_server_info = permission_state_action(PermissionAction::SetTool {
    tool_id: "serverInfo".to_string(),
    behavior: ToolPermissionBehavior::Allow,
});
  1. Optional: constrain tools per agent via AgentDefinition.
AgentDefinition::new("deepseek-chat")
    .with_allowed_tools(vec!["search".to_string()])
    .with_excluded_tools(vec!["dangerous_tool".to_string()])

These populate RunPolicy.allowed_tools / RunPolicy.excluded_tools, which are enforced by ToolPolicyPlugin before tool execution.

  1. Forward approval decisions from client to active run.
curl -X POST \
  -H 'content-type: application/json' \
  -d '{"decisions":[{"target_id":"fc_call_1","decision_id":"d1","action":"resume","result":{"approved":true},"updated_at":1760000000000}]}' \
  http://127.0.0.1:8080/v1/runs/<run_id>/inputs

Verify

  • allow: tool executes immediately.
  • deny: tool execution is rejected by policy.
  • ask: run suspends until decision is forwarded.

Common Errors

  • Registering plugin but forgetting to include behavior ids in agent definition.
  • Wrong behavior order (permission before tool_policy) makes out-of-scope checks less strict.
  • Missing target_id / malformed decisions prevents resume.
  • examples/copilotkit-starter/README.md is the most complete approval-focused frontend integration
  • examples/travel-ui/README.md shows approval-gated trip creation
  • examples/research-ui/README.md shows approval-gated resource deletion

Key Files

  • crates/tirea-extension-permission/src/plugin.rs
  • examples/src/starter_backend/mod.rs
  • examples/ai-sdk-starter/src/components/tools/permission-dialog.tsx
  • examples/travel-ui/hooks/useTripApproval.tsx
  • examples/research-ui/hooks/useDeleteApproval.tsx