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 errors;
pub mod krill;
pub mod mutations;
pub mod project;
pub mod sync;
pub mod task;
@ -25,6 +26,7 @@ pub use coral::{Coral, CoralId};
pub use enums::*;
pub use errors::{ShoalError, ValidationError};
pub use krill::{KrillConfig, KrillDescriptor, KrillId};
pub use mutations::FileMutation;
pub use project::{Project, ProjectFile, ProjectId, ProjectSettings};
pub use task::{Task, TaskResult};
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,
#[serde(default)]
pub version: String,
/// Whether this tool requires a project context to function.
/// Project-scoped tools are filtered out when no project is selected.
/* Whether this tool requires a project context to function.
Project-scoped tools are filtered out when no project is selected. */
#[serde(default)]
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")]
pub timeout_ms: u64,
/// Whether this tool version is deprecated
/* Whether this tool version is deprecated */
#[serde(default)]
pub deprecated: bool,
/// Message shown when tool is deprecated, explaining migration path
/* Message shown when tool is deprecated, explaining migration path */
#[serde(default)]
pub deprecation_message: String,
/// Execution context indicating where this tool should be available
/* Execution context indicating where this tool should be available */
#[serde(default)]
pub execution_context: ExecutionContext,
}
@ -89,9 +89,9 @@ impl ToolDefinition {
format!("- {}: {}\n", self.name, self.description)
}
/// Strip the project_id parameter from the tool's JSON schema.
/// This is used to hide the project context from agents that shouldn't
/// have to manage it manually.
/* Strip the project_id parameter from the tool's JSON schema.
This is used to hide the project context from agents that shouldn't
have to manage it manually. */
pub fn strip_project_id(&mut self) {
if let Some(obj) = self.parameters.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.
/// This is used to hide the board context from agents that shouldn't
/// have to manage it manually (similar to project_id).
/* Strip the board_id parameter from the tool's JSON schema.
This is used to hide the board context from agents that shouldn't
have to manage it manually (similar to project_id). */
pub fn strip_board_id(&mut self) {
if let Some(obj) = self.parameters.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 {
self.deprecated
}
/// Get deprecation message with migration guidance
/* Get deprecation message with migration guidance */
pub fn deprecation_notice(&self) -> Option<&str> {
if self.deprecated && !self.deprecation_message.is_empty() {
Some(&self.deprecation_message)
@ -131,13 +131,13 @@ impl ToolDefinition {
}
}
/// Compare tool versions. Returns true if self is newer than other.
/// Uses simple semver comparison (major.minor.patch).
/* Compare tool versions. Returns true if self is newer than other.
Uses simple semver comparison (major.minor.patch). */
pub fn is_newer_than(&self, other: &Self) -> bool {
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(
tools: &[ToolDefinition],
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> {
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 {
self.name == other.name && !self.deprecated && !other.deprecated
}
@ -1108,7 +1108,7 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
"properties": {
"project_id": { "type": "string", "description": "Project ID" },
"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" },
"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" },
"title": { "type": "string", "description": "New title" },
"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" }
},
"required": ["project_id", "todo_id"]
@ -1163,7 +1163,7 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
"properties": {
"project_id": { "type": "string", "description": "Project ID" },
"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" }
},
"required": ["project_id", "todo_id"]