add devtools agent tools, fix search field mapping

7 gitea tools: list_repos, get_repo, list_issues, get_issue,
create_issue, list_pulls, get_file. all operate as the requesting
user via PAT impersonation.

tool registry conditionally includes gitea tools when configured.
dispatch uses prefix matching (gitea_*) for clean extension.

fixed search bug: room_name and sender_name filters used .keyword
subfield which doesn't exist on keyword-typed fields — queries
silently returned zero results for all room/sender-filtered searches.
This commit is contained in:
2026-03-22 15:00:06 +00:00
parent f479235a63
commit c9d4f7400d
3 changed files with 387 additions and 12 deletions

View File

@@ -1,4 +1,5 @@
pub mod bridge;
pub mod devtools;
pub mod room_history;
pub mod room_info;
pub mod script;
@@ -13,24 +14,36 @@ use serde_json::json;
use crate::config::Config;
use crate::context::ResponseContext;
use crate::sdk::gitea::GiteaClient;
pub struct ToolRegistry {
opensearch: OpenSearch,
matrix: MatrixClient,
config: Arc<Config>,
gitea: Option<Arc<GiteaClient>>,
}
impl ToolRegistry {
pub fn new(opensearch: OpenSearch, matrix: MatrixClient, config: Arc<Config>) -> Self {
pub fn new(
opensearch: OpenSearch,
matrix: MatrixClient,
config: Arc<Config>,
gitea: Option<Arc<GiteaClient>>,
) -> Self {
Self {
opensearch,
matrix,
config,
gitea,
}
}
pub fn tool_definitions() -> Vec<Tool> {
vec![
pub fn has_gitea(&self) -> bool {
self.gitea.is_some()
}
pub fn tool_definitions(gitea_enabled: bool) -> Vec<Tool> {
let mut tools = vec![
Tool::new(
"search_archive".into(),
"Search the message archive. Use this to find past conversations, \
@@ -154,13 +167,19 @@ impl ToolRegistry {
"required": ["code"]
}),
),
]
];
if gitea_enabled {
tools.extend(devtools::tool_definitions());
}
tools
}
/// Convert Sol's tool definitions to Mistral AgentTool format
/// for use with the Agents API (orchestrator agent creation).
pub fn agent_tool_definitions() -> Vec<mistralai_client::v1::agents::AgentTool> {
Self::tool_definitions()
pub fn agent_tool_definitions(gitea_enabled: bool) -> Vec<mistralai_client::v1::agents::AgentTool> {
Self::tool_definitions(gitea_enabled)
.into_iter()
.map(|t| {
mistralai_client::v1::agents::AgentTool::function(
@@ -207,6 +226,13 @@ impl ToolRegistry {
)
.await
}
name if name.starts_with("gitea_") => {
if let Some(ref gitea) = self.gitea {
devtools::execute(gitea, name, arguments, response_ctx).await
} else {
anyhow::bail!("Gitea integration not configured")
}
}
_ => anyhow::bail!("Unknown tool: {name}"),
}
}