Update AI agent, settings, and terminal modules
- Update AI agent conversation, task, and prompt builder - Add notebooks execution module for blocklist actions - Update Bedrock and OpenAI response translators - Refactor settings modules across multiple subsystems - Update terminal settings and window settings - Update drive settings and search command settings
This commit is contained in:
@@ -74,29 +74,30 @@ pub fn extract_new_input_messages(request: &api::Request) -> Vec<ConversationMes
|
||||
});
|
||||
}
|
||||
}
|
||||
Some(api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
)) => {
|
||||
Some(
|
||||
api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
),
|
||||
) => {
|
||||
if let Some(user_query) = &cli_query.user_query {
|
||||
if !user_query.query.is_empty() {
|
||||
let query_text = if let Some(running_cmd) = &cli_query.running_command {
|
||||
let mut context = format!(
|
||||
"[Running command: {}]\n",
|
||||
running_cmd.command
|
||||
);
|
||||
if let Some(snapshot) = &running_cmd.snapshot {
|
||||
if !snapshot.output.is_empty() {
|
||||
context.push_str(&format!(
|
||||
"[Terminal output:\n{}\n]\n",
|
||||
snapshot.output
|
||||
));
|
||||
let query_text =
|
||||
if let Some(running_cmd) = &cli_query.running_command {
|
||||
let mut context =
|
||||
format!("[Running command: {}]\n", running_cmd.command);
|
||||
if let Some(snapshot) = &running_cmd.snapshot {
|
||||
if !snapshot.output.is_empty() {
|
||||
context.push_str(&format!(
|
||||
"[Terminal output:\n{}\n]\n",
|
||||
snapshot.output
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
context.push_str(&user_query.query);
|
||||
context
|
||||
} else {
|
||||
user_query.query.clone()
|
||||
};
|
||||
context.push_str(&user_query.query);
|
||||
context
|
||||
} else {
|
||||
user_query.query.clone()
|
||||
};
|
||||
user_queries.push(ConversationMessage {
|
||||
role: MessageRole::User,
|
||||
content: MessageContent::Text(query_text),
|
||||
@@ -256,9 +257,11 @@ pub fn extract_user_query_text(request: &api::Request) -> Option<String> {
|
||||
return Some(query.query.clone());
|
||||
}
|
||||
}
|
||||
Some(api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
)) => {
|
||||
Some(
|
||||
api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
),
|
||||
) => {
|
||||
if let Some(user_query) = &cli_query.user_query {
|
||||
if !user_query.query.is_empty() {
|
||||
return Some(user_query.query.clone());
|
||||
@@ -388,29 +391,30 @@ fn extract_input_messages(request: &api::Request) -> Vec<api::Message> {
|
||||
});
|
||||
}
|
||||
}
|
||||
Some(api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
)) => {
|
||||
Some(
|
||||
api::request::input::user_inputs::user_input::Input::CliAgentUserQuery(
|
||||
cli_query,
|
||||
),
|
||||
) => {
|
||||
if let Some(user_query) = &cli_query.user_query {
|
||||
if !user_query.query.is_empty() {
|
||||
let query_text = if let Some(running_cmd) = &cli_query.running_command {
|
||||
let mut context = format!(
|
||||
"[Running command: {}]\n",
|
||||
running_cmd.command
|
||||
);
|
||||
if let Some(snapshot) = &running_cmd.snapshot {
|
||||
if !snapshot.output.is_empty() {
|
||||
context.push_str(&format!(
|
||||
"[Terminal output:\n{}\n]\n",
|
||||
snapshot.output
|
||||
));
|
||||
let query_text =
|
||||
if let Some(running_cmd) = &cli_query.running_command {
|
||||
let mut context =
|
||||
format!("[Running command: {}]\n", running_cmd.command);
|
||||
if let Some(snapshot) = &running_cmd.snapshot {
|
||||
if !snapshot.output.is_empty() {
|
||||
context.push_str(&format!(
|
||||
"[Terminal output:\n{}\n]\n",
|
||||
snapshot.output
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
context.push_str(&user_query.query);
|
||||
context
|
||||
} else {
|
||||
user_query.query.clone()
|
||||
};
|
||||
context.push_str(&user_query.query);
|
||||
context
|
||||
} else {
|
||||
user_query.query.clone()
|
||||
};
|
||||
results.push(api::Message {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
task_id: task_id.clone(),
|
||||
@@ -1189,34 +1193,67 @@ pub fn default_tool_definitions() -> Vec<ToolDefinition> {
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "read_documents".to_string(),
|
||||
description: "Read the contents of one or more Galaxy notebook documents by their IDs.".to_string(),
|
||||
name: "read_plan".to_string(),
|
||||
description: "Read the contents of one or more Galaxy plan documents by their IDs. Plans are rich-text documents that appear in the Plans folder of Galaxy Drive.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"document_ids": { "type": "array", "items": { "type": "string" }, "description": "Document IDs to read" }
|
||||
"document_ids": { "type": "array", "items": { "type": "string" }, "description": "Plan document IDs to read" }
|
||||
},
|
||||
"required": ["document_ids"]
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "create_documents".to_string(),
|
||||
description: "Create new Galaxy notebook documents with the specified title and content.".to_string(),
|
||||
name: "create_plan".to_string(),
|
||||
description: "Create a new plan document in Galaxy Drive's Plans folder. Plans are rich-text documents for tracking tasks, architecture decisions, and project notes.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documents": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" } }, "required": ["title", "content"] }, "description": "Documents to create" }
|
||||
"documents": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" } }, "required": ["title", "content"] }, "description": "Plan documents to create" }
|
||||
},
|
||||
"required": ["documents"]
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "edit_documents".to_string(),
|
||||
description: "Edit existing Galaxy notebook documents using search/replace diffs.".to_string(),
|
||||
name: "edit_plan".to_string(),
|
||||
description: "Edit an existing plan document in Galaxy Drive using search/replace diffs.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"diffs": { "type": "array", "items": { "type": "object", "properties": { "document_id": { "type": "string" }, "search": { "type": "string" }, "replace": { "type": "string" } }, "required": ["document_id", "search", "replace"] }, "description": "Edits to apply to documents" }
|
||||
"diffs": { "type": "array", "items": { "type": "object", "properties": { "document_id": { "type": "string" }, "search": { "type": "string" }, "replace": { "type": "string" } }, "required": ["document_id", "search", "replace"] }, "description": "Edits to apply to plan documents" }
|
||||
},
|
||||
"required": ["diffs"]
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "read_notebook".to_string(),
|
||||
description: "Read the contents of one or more Galaxy Drive notebooks by their IDs. Notebooks are user-created rich-text documents stored in Galaxy Drive.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"document_ids": { "type": "array", "items": { "type": "string" }, "description": "Notebook IDs to read" }
|
||||
},
|
||||
"required": ["document_ids"]
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "create_notebook".to_string(),
|
||||
description: "Create a new notebook in Galaxy Drive. Notebooks are rich-text documents for general notes, documentation, and reference material.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documents": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" } }, "required": ["title", "content"] }, "description": "Notebooks to create" }
|
||||
},
|
||||
"required": ["documents"]
|
||||
}),
|
||||
},
|
||||
ToolDefinition {
|
||||
name: "edit_notebook".to_string(),
|
||||
description: "Edit an existing Galaxy Drive notebook using search/replace diffs.".to_string(),
|
||||
input_schema: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"diffs": { "type": "array", "items": { "type": "object", "properties": { "document_id": { "type": "string" }, "search": { "type": "string" }, "replace": { "type": "string" } }, "required": ["document_id", "search", "replace"] }, "description": "Edits to apply to notebooks" }
|
||||
},
|
||||
"required": ["diffs"]
|
||||
}),
|
||||
|
||||
@@ -998,7 +998,7 @@ pub fn build_tool_call_message(
|
||||
api::message::tool_call::ReadMcpResource { uri, server_id },
|
||||
))
|
||||
}
|
||||
"read_documents" => {
|
||||
"read_plan" | "read_documents" | "read_notebook" => {
|
||||
let documents = input
|
||||
.get("document_ids")
|
||||
.and_then(|v| v.as_array())
|
||||
@@ -1016,7 +1016,7 @@ pub fn build_tool_call_message(
|
||||
api::message::tool_call::ReadDocuments { documents },
|
||||
))
|
||||
}
|
||||
"create_documents" => {
|
||||
"create_plan" | "create_documents" | "create_notebook" => {
|
||||
let new_documents = input
|
||||
.get("documents")
|
||||
.and_then(|v| v.as_array())
|
||||
@@ -1035,7 +1035,7 @@ pub fn build_tool_call_message(
|
||||
api::message::tool_call::CreateDocuments { new_documents },
|
||||
))
|
||||
}
|
||||
"edit_documents" => {
|
||||
"edit_plan" | "edit_documents" | "edit_notebook" => {
|
||||
let diffs = input
|
||||
.get("diffs")
|
||||
.and_then(|v| v.as_array())
|
||||
@@ -1211,16 +1211,24 @@ pub fn build_tool_call_message(
|
||||
}
|
||||
};
|
||||
|
||||
// For notebook tools, encode the tool name into the tool_call_id so that
|
||||
// the conversion layer can route them to the notebook executor.
|
||||
let effective_tool_call_id = if is_notebook_tool(tool_name) {
|
||||
format!("notebook::{tool_use_id}")
|
||||
} else {
|
||||
tool_use_id.to_string()
|
||||
};
|
||||
|
||||
let message = if let Some(tool_variant) = tool {
|
||||
api::Message {
|
||||
id: tool_use_id.to_string(),
|
||||
id: effective_tool_call_id.clone(),
|
||||
task_id: task_id.to_string(),
|
||||
request_id: String::new(),
|
||||
timestamp: None,
|
||||
server_message_data: String::new(),
|
||||
citations: vec![],
|
||||
message: Some(api::message::Message::ToolCall(api::message::ToolCall {
|
||||
tool_call_id: tool_use_id.to_string(),
|
||||
tool_call_id: effective_tool_call_id,
|
||||
tool: Some(tool_variant),
|
||||
})),
|
||||
}
|
||||
@@ -1275,6 +1283,13 @@ const KNOWN_TOOLS: &[&str] = &[
|
||||
"write_to_long_running_shell_command",
|
||||
"read_shell_command_output",
|
||||
"read_mcp_resource",
|
||||
"read_plan",
|
||||
"create_plan",
|
||||
"edit_plan",
|
||||
"read_notebook",
|
||||
"create_notebook",
|
||||
"edit_notebook",
|
||||
// Legacy aliases — accept old names so in-flight conversations don't break.
|
||||
"read_documents",
|
||||
"create_documents",
|
||||
"edit_documents",
|
||||
@@ -1291,6 +1306,10 @@ fn is_known_tool(name: &str) -> bool {
|
||||
KNOWN_TOOLS.contains(&name) || name.starts_with("mcp__")
|
||||
}
|
||||
|
||||
fn is_notebook_tool(name: &str) -> bool {
|
||||
matches!(name, "create_notebook" | "read_notebook" | "edit_notebook")
|
||||
}
|
||||
|
||||
/// Searches conversation message history for tool call results matching the given criteria.
|
||||
fn recall_from_history(
|
||||
messages: &[ConversationMessage],
|
||||
|
||||
Reference in New Issue
Block a user