MTP tools & Centralizing

This commit is contained in:
Alex Emmet 2026-07-03 06:14:01 +02:00
commit 89e939d50f
4 changed files with 36 additions and 22 deletions

View file

@ -10,6 +10,7 @@ pub mod coral;
pub mod enums; pub mod enums;
pub mod errors; pub mod errors;
pub mod krill; pub mod krill;
pub mod mutations;
pub mod project; pub mod project;
pub mod sync; pub mod sync;
pub mod task; pub mod task;
@ -25,6 +26,7 @@ pub use coral::{Coral, CoralId};
pub use enums::*; pub use enums::*;
pub use errors::{ShoalError, ValidationError}; pub use errors::{ShoalError, ValidationError};
pub use krill::{KrillConfig, KrillDescriptor, KrillId}; pub use krill::{KrillConfig, KrillDescriptor, KrillId};
pub use mutations::FileMutation;
pub use project::{Project, ProjectFile, ProjectId, ProjectSettings}; pub use project::{Project, ProjectFile, ProjectId, ProjectSettings};
pub use task::{Task, TaskResult}; pub use task::{Task, TaskResult};
pub use todo::{Dependency, ToDo}; pub use todo::{Dependency, ToDo};

10
src/mutations.rs Normal file
View file

@ -0,0 +1,10 @@
use serde::{Deserialize, Serialize};
/// A single file change inferred from a sandbox diff: `hash_before` absent means the file
/// was created, `hash_after` absent means it was deleted, both present means it was modified.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileMutation {
pub file: String,
pub hash_before: Option<String>,
pub hash_after: Option<String>,
}

View file

@ -31,20 +31,20 @@ pub struct ToolDefinition {
pub requires_approval: bool, pub requires_approval: bool,
#[serde(default)] #[serde(default)]
pub version: String, pub version: String,
/// Whether this tool requires a project context to function. /* Whether this tool requires a project context to function.
/// Project-scoped tools are filtered out when no project is selected. Project-scoped tools are filtered out when no project is selected. */
#[serde(default)] #[serde(default)]
pub project_scoped: bool, pub project_scoped: bool,
/// Maximum execution time in milliseconds. Defaults to 30000 (30s). /* Maximum execution time in milliseconds. Defaults to 30000 (30s). */
#[serde(default = "default_timeout_ms")] #[serde(default = "default_timeout_ms")]
pub timeout_ms: u64, pub timeout_ms: u64,
/// Whether this tool version is deprecated /* Whether this tool version is deprecated */
#[serde(default)] #[serde(default)]
pub deprecated: bool, pub deprecated: bool,
/// Message shown when tool is deprecated, explaining migration path /* Message shown when tool is deprecated, explaining migration path */
#[serde(default)] #[serde(default)]
pub deprecation_message: String, pub deprecation_message: String,
/// Execution context indicating where this tool should be available /* Execution context indicating where this tool should be available */
#[serde(default)] #[serde(default)]
pub execution_context: ExecutionContext, pub execution_context: ExecutionContext,
} }
@ -89,9 +89,9 @@ impl ToolDefinition {
format!("- {}: {}\n", self.name, self.description) format!("- {}: {}\n", self.name, self.description)
} }
/// Strip the project_id parameter from the tool's JSON schema. /* Strip the project_id parameter from the tool's JSON schema.
/// This is used to hide the project context from agents that shouldn't This is used to hide the project context from agents that shouldn't
/// have to manage it manually. have to manage it manually. */
pub fn strip_project_id(&mut self) { pub fn strip_project_id(&mut self) {
if let Some(obj) = self.parameters.as_object_mut() { if let Some(obj) = self.parameters.as_object_mut() {
if let Some(properties) = obj.get_mut("properties").and_then(|p| p.as_object_mut()) { if let Some(properties) = obj.get_mut("properties").and_then(|p| p.as_object_mut()) {
@ -103,9 +103,9 @@ impl ToolDefinition {
} }
} }
/// Strip the board_id parameter from the tool's JSON schema. /* Strip the board_id parameter from the tool's JSON schema.
/// This is used to hide the board context from agents that shouldn't This is used to hide the board context from agents that shouldn't
/// have to manage it manually (similar to project_id). have to manage it manually (similar to project_id). */
pub fn strip_board_id(&mut self) { pub fn strip_board_id(&mut self) {
if let Some(obj) = self.parameters.as_object_mut() { if let Some(obj) = self.parameters.as_object_mut() {
if let Some(properties) = obj.get_mut("properties").and_then(|p| p.as_object_mut()) { if let Some(properties) = obj.get_mut("properties").and_then(|p| p.as_object_mut()) {
@ -117,12 +117,12 @@ impl ToolDefinition {
} }
} }
/// Check if this tool version is deprecated /* Check if this tool version is deprecated */
pub fn is_deprecated(&self) -> bool { pub fn is_deprecated(&self) -> bool {
self.deprecated self.deprecated
} }
/// Get deprecation message with migration guidance /* Get deprecation message with migration guidance */
pub fn deprecation_notice(&self) -> Option<&str> { pub fn deprecation_notice(&self) -> Option<&str> {
if self.deprecated && !self.deprecation_message.is_empty() { if self.deprecated && !self.deprecation_message.is_empty() {
Some(&self.deprecation_message) Some(&self.deprecation_message)
@ -131,13 +131,13 @@ impl ToolDefinition {
} }
} }
/// Compare tool versions. Returns true if self is newer than other. /* Compare tool versions. Returns true if self is newer than other.
/// Uses simple semver comparison (major.minor.patch). Uses simple semver comparison (major.minor.patch). */
pub fn is_newer_than(&self, other: &Self) -> bool { pub fn is_newer_than(&self, other: &Self) -> bool {
compare_versions(&self.version, &other.version) == std::cmp::Ordering::Greater compare_versions(&self.version, &other.version) == std::cmp::Ordering::Greater
} }
/// Filter tools by execution context /* Filter tools by execution context */
pub fn filter_by_context( pub fn filter_by_context(
tools: &[ToolDefinition], tools: &[ToolDefinition],
context: ExecutionContext, context: ExecutionContext,
@ -154,12 +154,12 @@ impl ToolDefinition {
} }
} }
/// Filter tools to only include non-deprecated ones /* Filter tools to only include non-deprecated ones */
pub fn filter_active(tools: &[ToolDefinition]) -> Vec<ToolDefinition> { pub fn filter_active(tools: &[ToolDefinition]) -> Vec<ToolDefinition> {
tools.iter().filter(|t| !t.deprecated).cloned().collect() tools.iter().filter(|t| !t.deprecated).cloned().collect()
} }
/// Check compatibility with another tool definition /* Check compatibility with another tool definition */
pub fn is_compatible_with(&self, other: &Self) -> bool { pub fn is_compatible_with(&self, other: &Self) -> bool {
self.name == other.name && !self.deprecated && !other.deprecated self.name == other.name && !self.deprecated && !other.deprecated
} }
@ -1108,7 +1108,7 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
"properties": { "properties": {
"project_id": { "type": "string", "description": "Project ID" }, "project_id": { "type": "string", "description": "Project ID" },
"board_id": { "type": "string", "description": "Board ID (defaults to project's primary board)" }, "board_id": { "type": "string", "description": "Board ID (defaults to project's primary board)" },
"status": { "type": "string", "enum": ["Ready","InProgress","Done","Blocked","Delegated","Failed","PendingApproval"], "description": "Initial status of the todo" }, "status": { "type": "string", "enum": ["pending","in_progress","completed","blocked","ready_for_agent","delegated","failed","pending_approval"], "description": "Initial status of the todo" },
"title": { "type": "string", "description": "Title of the todo" }, "title": { "type": "string", "description": "Title of the todo" },
"description": { "type": "string", "description": "Optional description" }, "description": { "type": "string", "description": "Optional description" },
@ -1133,7 +1133,7 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
"todo_id": { "type": "string", "description": "ID of the todo to update" }, "todo_id": { "type": "string", "description": "ID of the todo to update" },
"title": { "type": "string", "description": "New title" }, "title": { "type": "string", "description": "New title" },
"description": { "type": "string", "description": "New description" }, "description": { "type": "string", "description": "New description" },
"status": { "type": "string", "enum": ["backlog","in_progress","in_review","done","blocked","delegated","failed"], "description": "New status" }, "status": { "type": "string", "enum": ["pending","in_progress","completed","blocked","ready_for_agent","delegated","failed","pending_approval"], "description": "New status" },
"priority": { "type": "number", "description": "New priority" } "priority": { "type": "number", "description": "New priority" }
}, },
"required": ["project_id", "todo_id"] "required": ["project_id", "todo_id"]
@ -1163,7 +1163,7 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
"properties": { "properties": {
"project_id": { "type": "string", "description": "Project ID" }, "project_id": { "type": "string", "description": "Project ID" },
"todo_id": { "type": "string", "description": "ID of the todo to move" }, "todo_id": { "type": "string", "description": "ID of the todo to move" },
"status": { "type": "string", "enum": ["Ready","InProgress","Done","Blocked","Delegated","Failed","PendingApproval"], "description": "Target status" }, "status": { "type": "string", "enum": ["pending","in_progress","completed","blocked","ready_for_agent","delegated","failed","pending_approval"], "description": "Target status" },
"task_order": { "type": "number", "description": "New order position" } "task_order": { "type": "number", "description": "New order position" }
}, },
"required": ["project_id", "todo_id"] "required": ["project_id", "todo_id"]

View file

@ -53,6 +53,8 @@ type_maps:
KrillIoMemoryReport: 79 KrillIoMemoryReport: 79
KrillIoImmediateKill: 80 KrillIoImmediateKill: 80
KrillIoKilled: 81 KrillIoKilled: 81
PodTaskAvailable: 82
PodDiscussAbort: 83
DataTypes: DataTypes:
ProjectId: 32 ProjectId: 32
RequestType: 33 RequestType: 33