vv-agent 0.6.0

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
mod fallback;
mod local_rg;
mod request;
mod response;
mod types;

use std::sync::Arc;

use crate::tools::base::{ToolContext, ToolSpec};
use crate::tools::common::{path_escapes_workspace_error, tool_error_with_code};
use crate::types::{ToolArguments, ToolExecutionResult};
use crate::workspace::LocalWorkspaceBackend;

use request::FindFilesRequest;

use super::workspace_backend_error;

pub fn find_files(context: &mut ToolContext, arguments: &ToolArguments) -> ToolExecutionResult {
    let spec = find_files_tool();
    (spec.handler)(context, arguments)
}

pub(crate) fn find_files_tool() -> ToolSpec {
    let mut spec = ToolSpec::new(
        "find_files",
        "Find files in the current workspace.",
        Arc::new(handle_find_files),
    );
    if let Some(schema) = crate::tools::schemas::schema_for("find_files") {
        spec.schema = schema;
    }
    spec
}

fn handle_find_files(context: &mut ToolContext, arguments: &ToolArguments) -> ToolExecutionResult {
    let request = match FindFilesRequest::from_arguments(arguments) {
        Ok(request) => request,
        Err(error) => return tool_error_with_code(error.message(), "invalid_arguments"),
    };
    let resolved_path = match context.resolve_workspace_path(&request.path) {
        Ok(path) => path,
        Err(error) => return path_escapes_workspace_error(error),
    };

    let backend = context.effective_workspace_backend();
    let root_listing = request.is_workspace_root();
    let is_local_backend = backend.as_any().is::<LocalWorkspaceBackend>();
    let rg_outcome = backend
        .as_any()
        .downcast_ref::<LocalWorkspaceBackend>()
        .and_then(|_| {
            local_rg::find_files_with_rg(context, &resolved_path, root_listing, &request)
        });

    let outcome = if let Some(outcome) = rg_outcome {
        Ok(outcome)
    } else {
        fallback::find_files_with_backend(&backend, &request, is_local_backend, root_listing)
    };

    match outcome {
        Ok(outcome) => response::render_find_files(outcome, &request),
        Err(error) => workspace_backend_error(error),
    }
}