MTP tools & Centralizing

This commit is contained in:
Alex Emmet 2026-06-30 22:52:08 +02:00
commit 3e6fcec171
9 changed files with 1549 additions and 291 deletions

2
.cargo/config.toml Normal file
View file

@ -0,0 +1,2 @@
[env]
MTP_TYPE_MAPS = { value = "type-maps.yaml", relative = true }

1484
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@ chrono = { version = "0.4", features = ["serde"] }
thiserror = "2" thiserror = "2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
stp-core = { git = "https://git.methanium.net/shoal/stp.git" } mtp = { path = "../mtp-npm", features = [] }
tokio = "1" tokio = "1"
[dev-dependencies] [dev-dependencies]

View file

@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/* ExploreAgent is intentionally limited to read-only tools so it can be
dispatched without approval for safe, unrestricted codebase exploration. */
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum AgentType { pub enum AgentType {
@ -8,6 +10,8 @@ pub enum AgentType {
BuildAgent, BuildAgent,
ChatAgent, ChatAgent,
TestJudge, TestJudge,
/* Lightweight read-only agent for exploration tasks. Never mutates files. */
ExploreAgent,
} }
impl AgentType { impl AgentType {
@ -18,6 +22,7 @@ impl AgentType {
AgentType::BuildAgent => "build_agent", AgentType::BuildAgent => "build_agent",
AgentType::ChatAgent => "chat", AgentType::ChatAgent => "chat",
AgentType::TestJudge => "test_judge", AgentType::TestJudge => "test_judge",
AgentType::ExploreAgent => "explore_agent",
} }
} }
@ -28,6 +33,7 @@ impl AgentType {
"build_agent" => Some(AgentType::BuildAgent), "build_agent" => Some(AgentType::BuildAgent),
"chat" => Some(AgentType::ChatAgent), "chat" => Some(AgentType::ChatAgent),
"test_judge" => Some(AgentType::TestJudge), "test_judge" => Some(AgentType::TestJudge),
"explore_agent" => Some(AgentType::ExploreAgent),
_ => None, _ => None,
} }
} }
@ -119,6 +125,171 @@ impl AgentPolicy {
allowed_tools: vec![], allowed_tools: vec![],
forbidden_mutations: vec![], forbidden_mutations: vec![],
}, },
/* ExploreAgent: auto-approved, read-only tools only, short timeout.
Forbidden mutations set to wildcard to block all writes. */
AgentType::ExploreAgent => Self {
agent_type: agent_type.clone(),
auto_approve: true,
max_depth: 1,
require_preview: false,
timeout_seconds: 30,
max_tokens: 4096,
allowed_tools: vec![
"read_file".into(),
"list_directory".into(),
"search_files".into(),
"list_files".into(),
"web_search".into(),
"web_fetch".into(),
],
forbidden_mutations: vec!["*".into()],
},
} }
} }
} }
/* Per-agent prompt configuration. Stored in the DB and resolved on task
dispatch. Resolution order: task instructions > DB override > this config
> compiled-in default > tool protocol. */
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentPromptConfig {
pub agent_type: AgentType,
/* Replaces or extends the compiled-in default prompt when set. */
pub system_prompt: Option<String>,
/* Rules appended after the main prompt, one per item. */
pub append_rules: Vec<String>,
/* When true, system_prompt fully replaces the default rather than appending. */
pub override_defaults: bool,
}
impl AgentPromptConfig {
pub fn new(agent_type: AgentType) -> Self {
Self {
agent_type,
system_prompt: None,
append_rules: Vec::new(),
override_defaults: false,
}
}
/* Applies this config on top of a base prompt. Returns the merged result. */
pub fn apply(&self, base: &str) -> String {
let body = if self.override_defaults {
self.system_prompt.as_deref().unwrap_or(base).to_string()
} else {
match &self.system_prompt {
Some(p) => format!("{}\n\n{}", base, p),
None => base.to_string(),
}
};
if self.append_rules.is_empty() {
body
} else {
format!("{}\n\n{}", body, self.append_rules.join("\n"))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_agent_type_as_str_roundtrip() {
let types = [
AgentType::Planner,
AgentType::DocAgent,
AgentType::BuildAgent,
AgentType::ChatAgent,
AgentType::TestJudge,
AgentType::ExploreAgent,
];
for agent_type in &types {
let s = agent_type.as_str();
let parsed = AgentType::from_str(s);
assert_eq!(parsed.as_ref(), Some(agent_type), "roundtrip failed for {:?}", agent_type);
}
}
#[test]
fn test_agent_type_from_str_unknown() {
assert!(AgentType::from_str("unknown_agent").is_none());
assert!(AgentType::from_str("").is_none());
}
#[test]
fn test_defaults_for_all_types() {
let types = [
AgentType::Planner,
AgentType::DocAgent,
AgentType::BuildAgent,
AgentType::ChatAgent,
AgentType::TestJudge,
AgentType::ExploreAgent,
];
for agent_type in &types {
let policy = AgentPolicy::defaults_for(agent_type);
assert_eq!(&policy.agent_type, agent_type);
assert!(policy.timeout_seconds > 0);
assert!(policy.max_tokens > 0);
}
}
#[test]
fn test_explore_agent_is_auto_approved_read_only() {
let policy = AgentPolicy::defaults_for(&AgentType::ExploreAgent);
assert!(policy.auto_approve);
assert_eq!(policy.max_depth, 1);
assert!(policy.allowed_tools.contains(&"read_file".to_string()));
assert!(policy.allowed_tools.contains(&"search_files".to_string()));
assert!(!policy.allowed_tools.contains(&"write_file".to_string()));
assert!(!policy.allowed_tools.contains(&"edit_file".to_string()));
assert!(policy.forbidden_mutations.contains(&"*".to_string()));
}
#[test]
fn test_build_agent_requires_approval() {
let policy = AgentPolicy::defaults_for(&AgentType::BuildAgent);
assert!(!policy.auto_approve);
assert!(policy.max_tokens > 8192);
}
#[test]
fn test_agent_prompt_config_apply_override() {
let mut config = AgentPromptConfig::new(AgentType::BuildAgent);
config.system_prompt = Some("Custom prompt".to_string());
config.override_defaults = true;
let result = config.apply("Original base");
assert_eq!(result, "Custom prompt");
}
#[test]
fn test_agent_prompt_config_apply_append() {
let mut config = AgentPromptConfig::new(AgentType::DocAgent);
config.system_prompt = Some("Extension".to_string());
config.override_defaults = false;
let result = config.apply("Base prompt");
assert!(result.starts_with("Base prompt"));
assert!(result.contains("Extension"));
}
#[test]
fn test_agent_prompt_config_apply_rules() {
let mut config = AgentPromptConfig::new(AgentType::Planner);
config.append_rules = vec!["Rule 1".to_string(), "Rule 2".to_string()];
let result = config.apply("Base");
assert!(result.contains("Rule 1"));
assert!(result.contains("Rule 2"));
}
#[test]
fn test_agent_prompt_config_no_overrides() {
let config = AgentPromptConfig::new(AgentType::ChatAgent);
let result = config.apply("Base prompt");
assert_eq!(result, "Base prompt");
}
}

View file

@ -1,5 +1,6 @@
pub use chrono::{DateTime, Utc}; pub use chrono::{DateTime, Utc};
pub use stp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; pub use mtp::codec::{CommunicationValue, DataValue};
pub use mtp::type_map::{CommunicationType, DataType};
pub use uuid::Uuid; pub use uuid::Uuid;
pub mod agents; pub mod agents;
@ -15,7 +16,7 @@ pub mod task;
pub mod todo; pub mod todo;
pub mod tools; pub mod tools;
pub use agents::{AgentPolicy, AgentType, ApprovalMode, PlannedAction, SimulationResult}; pub use agents::{AgentPolicy, AgentPromptConfig, AgentType, ApprovalMode, PlannedAction, SimulationResult};
pub use ai_response::{Conversation, Message}; pub use ai_response::{Conversation, Message};
pub use conclusion::{ pub use conclusion::{
Artifact, ArtifactType, ConclusionCard, ConclusionMetrics, ConclusionTrigger, Artifact, ArtifactType, ConclusionCard, ConclusionMetrics, ConclusionTrigger,

View file

@ -209,6 +209,10 @@ pub struct AgentTaskSpec {
pub connector_config: Option<ConnectorConfig>, pub connector_config: Option<ConnectorConfig>,
#[serde(default)] #[serde(default)]
pub tools_json: Option<String>, pub tools_json: Option<String>,
/* Overrides the agent-type default system prompt when set. Takes highest
precedence in the resolution chain (above DB overrides and defaults). */
#[serde(default)]
pub system_prompt: Option<String>,
} }
impl AgentTaskSpec { impl AgentTaskSpec {
@ -239,6 +243,7 @@ impl AgentTaskSpec {
project_id: None, project_id: None,
connector_config: None, connector_config: None,
tools_json: None, tools_json: None,
system_prompt: None,
} }
} }
} }

View file

@ -4,7 +4,6 @@ use uuid::Uuid;
use crate::enums::{ToDoSource, ToDoStatus}; use crate::enums::{ToDoSource, ToDoStatus};
use crate::errors::ValidationError; use crate::errors::ValidationError;
use crate::{CommunicationType, CommunicationValue, DataTypes, DataValue};
use std::collections::HashSet; use std::collections::HashSet;
const MAX_TITLE_LENGTH: usize = 500; const MAX_TITLE_LENGTH: usize = 500;
@ -132,8 +131,8 @@ impl ToDo {
false false
} }
/// Performs full graph cycle detection given a map of todo_id -> dependencies. /* DFS cycle detection over a full dependency graph. Returns the first
/// Returns the ID of the first todo that would participate in a cycle, or None. todo_id found in a cycle, or None when the graph is acyclic. */
pub fn detect_cycle_in_graph(deps: &std::collections::HashMap<Uuid, Vec<Uuid>>) -> Option<Uuid> { pub fn detect_cycle_in_graph(deps: &std::collections::HashMap<Uuid, Vec<Uuid>>) -> Option<Uuid> {
let mut visited: HashSet<Uuid> = HashSet::new(); let mut visited: HashSet<Uuid> = HashSet::new();
let mut in_stack: HashSet<Uuid> = HashSet::new(); let mut in_stack: HashSet<Uuid> = HashSet::new();
@ -250,42 +249,6 @@ impl ToDo {
} }
} }
impl From<ToDo> for CommunicationValue {
fn from(todo: ToDo) -> Self {
let mut cv = CommunicationValue::new(CommunicationType::todo);
cv = cv.add_data(DataTypes::id, DataValue::Str(todo.id.to_string()));
cv = cv.add_data(DataTypes::title, DataValue::Str(todo.title));
cv = cv.add_data(DataTypes::description, DataValue::Str(todo.description));
cv = cv.add_data(DataTypes::status, DataValue::Str(todo.status.to_string()));
cv = cv.add_data(DataTypes::todo_id, DataValue::Number(todo.priority as i64));
let depends: Vec<DataValue> = todo
.depends_on
.iter()
.map(|u| DataValue::Str(u.to_string()))
.collect();
cv = cv.add_data(DataTypes::depends_on, DataValue::Array(depends));
cv = cv.add_data(
DataTypes::created_at,
DataValue::Str(todo.created_at.to_rfc3339()),
);
cv = cv.add_data(
DataTypes::updated_at,
DataValue::Str(todo.updated_at.to_rfc3339()),
);
cv = cv.add_data(
DataTypes::user_id,
DataValue::Str(todo.created_by.to_string()),
);
if let Some(pid) = todo.project_id {
cv = cv.add_data(DataTypes::project_id, DataValue::Str(pid.to_string()));
}
cv
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Context in which a tool should be available /* Context in which a tool should be available */
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ExecutionContext { pub enum ExecutionContext {
@ -165,7 +165,7 @@ impl ToolDefinition {
} }
} }
/// Simple semver comparison (major.minor.patch) /* Simple semver comparison (major.minor.patch) */
fn compare_versions(a: &str, b: &str) -> std::cmp::Ordering { fn compare_versions(a: &str, b: &str) -> std::cmp::Ordering {
let parse_version = |v: &str| -> Vec<u64> { let parse_version = |v: &str| -> Vec<u64> {
v.split('.') v.split('.')
@ -407,8 +407,8 @@ pub struct ToolErrorInfo {
pub message: String, pub message: String,
} }
/// Extended version tracking for tool definitions. /* Extended version tracking for tool definitions.
/// Provides schema versioning, deprecation notices, and migration guidance. Provides schema versioning, deprecation notices, and migration guidance. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolVersion { pub struct ToolVersion {
pub version: String, pub version: String,
@ -431,8 +431,8 @@ impl Default for ToolVersion {
} }
} }
/// Execution context for tool filtering. /* Execution context for tool filtering. Determines which tools are
/// Determines which tools are available in which execution environment. available in which execution environment (Reef vs. Krill vs. both). */
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ToolContext { pub enum ToolContext {
@ -447,7 +447,7 @@ impl Default for ToolContext {
} }
} }
/// Tool category classification for UI and filtering. /* Tool category classification for UI grouping and filtering. */
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ToolCategory { pub enum ToolCategory {
@ -482,8 +482,8 @@ impl ToolCategory {
} }
} }
/// A composed workflow of multiple tool steps executed in sequence /* A composed workflow of multiple tool steps executed in sequence
/// with dependency-based ordering. with dependency-based ordering. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolComposition { pub struct ToolComposition {
pub id: String, pub id: String,
@ -499,21 +499,20 @@ const fn default_composition_timeout_ms() -> u64 {
60000 60000
} }
/// A single step within a tool composition. /* A single step within a tool composition. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompositionStep { pub struct CompositionStep {
pub tool: String, pub tool: String,
pub arguments: serde_json::Value, pub arguments: serde_json::Value,
/// Indices of steps this step depends on (0-based). /* Indices (0-based) of steps this step depends on. None = no dependencies. */
/// If None, the step has no dependencies and can run immediately.
#[serde(default)] #[serde(default)]
pub depends_on: Option<Vec<usize>>, pub depends_on: Option<Vec<usize>>,
/// Optional label for referencing step outputs /* Optional label for referencing step outputs. */
#[serde(default)] #[serde(default)]
pub label: Option<String>, pub label: Option<String>,
} }
/// Declares a dependency of one tool on another tool version. /* Declares a dependency of one tool on another tool version. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDependency { pub struct ToolDependency {
pub tool: String, pub tool: String,
@ -587,17 +586,21 @@ macro_rules! tool {
}; };
} }
/// Trait for implementing custom tool plugins. /* Trait for implementing custom tool plugins.
/// Plugins can be registered at runtime to extend the tool ecosystem. Plugins register at runtime to extend the tool ecosystem. */
pub trait ToolPlugin: Send + Sync { pub trait ToolPlugin: Send + Sync {
fn name(&self) -> &str; fn name(&self) -> &str;
fn description(&self) -> &str; fn description(&self) -> &str;
fn category(&self) -> &str; fn category(&self) -> &str;
fn schema(&self) -> serde_json::Value; fn schema(&self) -> serde_json::Value;
fn execute(&self, args: serde_json::Value) -> Result<serde_json::Value, String>; fn execute(&self, args: serde_json::Value) -> Result<serde_json::Value, String>;
/* Defaults to true (dangerous) — safe default for unknown plugins. */
fn dangerous(&self) -> bool { true }
/* Defaults to true; callers must explicitly opt out of approval prompts. */
fn requires_approval(&self) -> bool { true }
} }
/// A marketplace listing for a published tool. /* A marketplace listing for a published tool. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolListing { pub struct ToolListing {
pub id: String, pub id: String,
@ -624,7 +627,7 @@ pub struct ToolListing {
pub published_at: String, pub published_at: String,
} }
/// Results from a marketplace search. /* Results from a marketplace search. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MarketplaceSearchResults { pub struct MarketplaceSearchResults {
pub listings: Vec<ToolListing>, pub listings: Vec<ToolListing>,
@ -633,7 +636,7 @@ pub struct MarketplaceSearchResults {
pub page_size: usize, pub page_size: usize,
} }
/// A documented example for a tool. /* A documented example for a tool. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolExample { pub struct ToolExample {
pub id: String, pub id: String,
@ -652,7 +655,7 @@ pub struct ToolExample {
pub author: String, pub author: String,
} }
/// A single test case for a tool. /* A single test case for a tool. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolTest { pub struct ToolTest {
pub name: String, pub name: String,
@ -669,7 +672,7 @@ const fn default_test_timeout() -> u64 {
30000 30000
} }
/// A suite of tests for a specific tool. /* A suite of tests for a specific tool. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolTestSuite { pub struct ToolTestSuite {
pub tool_name: String, pub tool_name: String,
@ -680,14 +683,14 @@ pub struct ToolTestSuite {
pub teardown_actions: Vec<TestAction>, pub teardown_actions: Vec<TestAction>,
} }
/// A setup or teardown action for a test suite. /* A setup or teardown action for a test suite. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TestAction { pub struct TestAction {
pub tool: String, pub tool: String,
pub arguments: serde_json::Value, pub arguments: serde_json::Value,
} }
/// Result of running a single tool test. /* Result of running a single tool test. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolTestResult { pub struct ToolTestResult {
pub test_name: String, pub test_name: String,
@ -699,7 +702,7 @@ pub struct ToolTestResult {
pub duration_ms: u64, pub duration_ms: u64,
} }
/// Results of running a full test suite. /* Results of running a full test suite. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolTestSuiteResult { pub struct ToolTestSuiteResult {
pub tool_name: String, pub tool_name: String,
@ -710,7 +713,7 @@ pub struct ToolTestSuiteResult {
pub total_duration_ms: u64, pub total_duration_ms: u64,
} }
/// Generated documentation for a tool. /* Generated documentation for a tool. */
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDocumentation { pub struct ToolDocumentation {
pub tool_name: String, pub tool_name: String,
@ -731,7 +734,7 @@ pub struct ToolDocumentation {
pub examples: Vec<ToolExample>, pub examples: Vec<ToolExample>,
} }
/// Returns all built-in tool definitions across all categories. /* Returns all built-in tool definitions across all categories. */
pub fn tool_definitions() -> Vec<ToolDefinition> { pub fn tool_definitions() -> Vec<ToolDefinition> {
vec![ vec![
// ======================== // ========================
@ -1534,8 +1537,8 @@ pub fn tool_definitions() -> Vec<ToolDefinition> {
] ]
} }
/// Returns the tool IDs appropriate for a given agent type. /* Returns the tool IDs appropriate for a given agent type.
/// Used by the dispatcher to embed tool definitions in task specs. Used by the dispatcher to embed tool definitions in task specs. */
pub fn tool_ids_for_agent_type(agent_type: &crate::agents::AgentType) -> Option<Vec<&'static str>> { pub fn tool_ids_for_agent_type(agent_type: &crate::agents::AgentType) -> Option<Vec<&'static str>> {
Some(match agent_type { Some(match agent_type {
crate::agents::AgentType::BuildAgent => vec![ crate::agents::AgentType::BuildAgent => vec![
@ -1565,10 +1568,15 @@ pub fn tool_ids_for_agent_type(agent_type: &crate::agents::AgentType) -> Option<
"store_file_doc", "read_file", "store_file_doc", "read_file",
], ],
crate::agents::AgentType::ChatAgent => return None, crate::agents::AgentType::ChatAgent => return None,
/* ExploreAgent only receives read-only tools — no write, edit, or bash. */
crate::agents::AgentType::ExploreAgent => vec![
"read_file", "list_directory", "search_files", "list_files",
"web_search", "web_fetch",
],
}) })
} }
/// Formats tool definitions as OpenAI-compatible tools JSON. /* Formats tool definitions as OpenAI-compatible function-calling JSON. */
pub fn format_tools_json(tools: &[ToolDefinition]) -> Option<String> { pub fn format_tools_json(tools: &[ToolDefinition]) -> Option<String> {
let formatted: Vec<serde_json::Value> = tools let formatted: Vec<serde_json::Value> = tools
.iter() .iter()

116
type-maps.yaml Normal file
View file

@ -0,0 +1,116 @@
protocol_version: "1.0"
type_maps:
"1.0":
CommunicationTypes:
ReservoirHeartbeat: 32
ReservoirRequest: 33
ReservoirStore: 34
AuthRequest: 35
AuthResponse: 36
ProjectRequest: 37
ProjectResponse: 38
KanbanRequest: 39
KanbanResponse: 40
DiscussRequest: 41
DiscussResponse: 42
DiscussStreamChunk: 43
DiscussStreamDone: 44
ToolRequest: 45
ToolResponse: 46
AgentRequest: 47
AgentResponse: 48
AdminRequest: 49
AdminResponse: 50
SyncRequest: 51
SyncResponse: 52
PodRequest: 53
PodResponse: 54
LookoutEvent: 55
EventBroadcast: 56
ErrorResponse: 57
KrillIoInitialize: 58
KrillIoInitialized: 59
KrillIoAdvertiseSkills: 60
KrillIoSkillsAdvertised: 61
KrillIoQuerySkills: 62
KrillIoQuerySkillsResponse: 63
KrillIoMessage: 64
KrillIoMessageResponse: 65
KrillIoToolCallRequest: 66
KrillIoToolCallResponse: 67
KrillIoListTools: 68
KrillIoListToolsResponse: 69
KrillIoPauseSession: 70
KrillIoResumeSession: 71
KrillIoTerminateSession: 72
KrillIoSessionStateChanged: 73
KrillIoHeartbeat: 74
KrillIoHeartbeatResponse: 75
KrillIoLoadModel: 76
KrillIoModelLoaded: 77
KrillIoUnloadModel: 78
KrillIoMemoryReport: 79
KrillIoImmediateKill: 80
KrillIoKilled: 81
DataTypes:
ProjectId: 32
RequestType: 33
ResponseData: 34
Data: 35
FilePath: 36
FileData: 37
SessionId: 38
KrillId: 39
KrillIoVersion: 40
MaxHistoryLength: 41
DefaultTimeoutMs: 42
Enabled: 43
ToolError: 44
SkillsJson: 45
Content: 46
MessageRole: 47
Response: 48
TokensUsed: 49
ToolId: 50
ToolCallId: 51
ToolArguments: 52
Timeout: 53
ToolSuccess: 54
ExecutionTimeMs: 55
ToolResult: 56
ToolDefinitionsList: 57
Graceful: 58
SessionState: 59
ModelPath: 60
LoadIntoVram: 61
WeightsPath: 62
Path: 63
RamUsageMb: 64
VramMb: 65
KillReason: 66
SaveCheckpoint: 67
AuthToken: 68
UserId: 69
Username: 70
Email: 71
Password: 72
BoardId: 73
TodoId: 74
TaskId: 75
TagId: 76
ChatId: 77
MessageId: 78
AgentRunId: 79
Payload: 80
EventType: 81
EventPayload: 82
StreamSessionId: 83
ContentChunk: 84
StreamComplete: 85
FileHash: 86
FileSize: 87
FileContent: 88
ErrorCode: 89
PageOffset: 90
PageLimit: 91