periplon_sdk/
options.rs

1use crate::domain::{
2    HookEvent, HookMatcher, PermissionMode, PermissionResult, Provider, ToolPermissionContext,
3};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::future::Future;
7use std::path::PathBuf;
8use std::pin::Pin;
9
10pub type SettingSource = String;
11
12#[derive(Clone, Default)]
13pub struct AgentOptions {
14    pub provider: Option<Provider>,
15    pub allowed_tools: Vec<String>,
16    pub disallowed_tools: Vec<String>,
17    pub system_prompt: Option<SystemPromptConfig>,
18    pub permission_mode: Option<PermissionMode>,
19    pub max_turns: Option<u32>,
20    pub model: Option<String>,
21    pub cwd: Option<PathBuf>,
22    pub create_cwd: bool,
23    pub cli_path: Option<PathBuf>,
24
25    // MCP Servers
26    pub mcp_servers: HashMap<String, McpServerConfig>,
27
28    // Advanced options
29    pub continue_conversation: bool,
30    pub resume: Option<String>,
31    pub permission_prompt_tool_name: Option<String>,
32    pub add_dirs: Vec<PathBuf>,
33    pub env: HashMap<String, String>,
34    pub extra_args: HashMap<String, Option<String>>,
35    pub max_buffer_size: Option<usize>,
36
37    // Callbacks
38    pub can_use_tool: Option<CanUseToolCallback>,
39    pub hooks: Option<HashMap<HookEvent, Vec<HookMatcher>>>,
40    pub stderr: Option<StderrCallback>,
41
42    // Session options
43    pub include_partial_messages: bool,
44    pub fork_session: bool,
45    pub agents: HashMap<String, AgentDefinition>,
46    pub setting_sources: Option<Vec<SettingSource>>,
47}
48
49#[derive(Debug, Clone)]
50pub enum SystemPromptConfig {
51    Text(String),
52    Preset {
53        preset: String,
54        append: Option<String>,
55    },
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct AgentDefinition {
60    pub description: String,
61    pub prompt: String,
62    pub tools: Option<Vec<String>>,
63    pub model: Option<String>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(tag = "type")]
68pub enum McpServerConfig {
69    #[serde(rename = "stdio")]
70    Stdio {
71        command: String,
72        #[serde(skip_serializing_if = "Option::is_none")]
73        args: Option<Vec<String>>,
74        #[serde(skip_serializing_if = "Option::is_none")]
75        env: Option<HashMap<String, String>>,
76    },
77
78    #[serde(rename = "sse")]
79    Sse {
80        url: String,
81        #[serde(skip_serializing_if = "Option::is_none")]
82        headers: Option<HashMap<String, String>>,
83    },
84
85    #[serde(rename = "http")]
86    Http {
87        url: String,
88        #[serde(skip_serializing_if = "Option::is_none")]
89        headers: Option<HashMap<String, String>>,
90    },
91
92    #[serde(rename = "sdk")]
93    Sdk { name: String },
94}
95
96pub type CanUseToolCallback = std::sync::Arc<
97    dyn Fn(
98            String,
99            serde_json::Value,
100            ToolPermissionContext,
101        ) -> Pin<Box<dyn Future<Output = PermissionResult> + Send>>
102        + Send
103        + Sync,
104>;
105
106pub type StderrCallback = std::sync::Arc<dyn Fn(String) + Send + Sync>;
107
108// Manual Debug implementation for AgentOptions since callbacks don't implement Debug
109impl std::fmt::Debug for AgentOptions {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        f.debug_struct("AgentOptions")
112            .field("provider", &self.provider)
113            .field("allowed_tools", &self.allowed_tools)
114            .field("disallowed_tools", &self.disallowed_tools)
115            .field("system_prompt", &self.system_prompt)
116            .field("permission_mode", &self.permission_mode)
117            .field("max_turns", &self.max_turns)
118            .field("model", &self.model)
119            .field("cwd", &self.cwd)
120            .field("create_cwd", &self.create_cwd)
121            .field("cli_path", &self.cli_path)
122            .field("mcp_servers", &self.mcp_servers)
123            .field("continue_conversation", &self.continue_conversation)
124            .field("resume", &self.resume)
125            .field(
126                "permission_prompt_tool_name",
127                &self.permission_prompt_tool_name,
128            )
129            .field("add_dirs", &self.add_dirs)
130            .field("env", &self.env)
131            .field("extra_args", &self.extra_args)
132            .field("max_buffer_size", &self.max_buffer_size)
133            .field(
134                "can_use_tool",
135                &self.can_use_tool.as_ref().map(|_| "<callback>"),
136            )
137            .field(
138                "hooks",
139                &self.hooks.as_ref().map(|h| format!("{} hooks", h.len())),
140            )
141            .field("stderr", &self.stderr.as_ref().map(|_| "<callback>"))
142            .field("include_partial_messages", &self.include_partial_messages)
143            .field("fork_session", &self.fork_session)
144            .field("agents", &self.agents)
145            .field("setting_sources", &self.setting_sources)
146            .finish()
147    }
148}