Skip to content

Feature: Web Search #1276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 112 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/q_chat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ fig_os_shim.workspace = true
fig_settings.workspace = true
fig_telemetry.workspace = true
fig_util.workspace = true
fig_request.workspace = true
futures.workspace = true
glob.workspace = true
htmd = "0.1"
mcp_client.workspace = true
rand.workspace = true
regex.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions crates/q_chat/src/tool_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use super::tools::{
};
use crate::tools::ToolSpec;
use crate::tools::custom_tool::CustomTool;
use crate::tools::web_search::WebSearch;

const NAMESPACE_DELIMITER: &str = "___";
// This applies for both mcp server and tool name since in the end the tool name as seen by the
Expand Down Expand Up @@ -671,6 +672,7 @@ impl ToolManager {
"execute_bash" => Tool::ExecuteBash(serde_json::from_value::<ExecuteBash>(value.args).map_err(map_err)?),
"use_aws" => Tool::UseAws(serde_json::from_value::<UseAws>(value.args).map_err(map_err)?),
"report_issue" => Tool::GhIssue(serde_json::from_value::<GhIssue>(value.args).map_err(map_err)?),
"web_search" => Tool::WebSearch(serde_json::from_value::<WebSearch>(value.args).map_err(map_err)?),
// Note that this name is namespaced with server_name{DELIMITER}tool_name
name => {
let name = self.tn_map.get(name).map_or(name, String::as_str);
Expand Down
9 changes: 9 additions & 0 deletions crates/q_chat/src/tools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod fs_read;
pub mod fs_write;
pub mod gh_issue;
pub mod use_aws;
pub mod web_search;

use std::collections::HashMap;
use std::io::Write;
Expand All @@ -29,6 +30,7 @@ use serde::{
Serialize,
};
use use_aws::UseAws;
use web_search::WebSearch;

use super::consts::MAX_TOOL_RESPONSE_SIZE;

Expand All @@ -41,6 +43,7 @@ pub enum Tool {
UseAws(UseAws),
Custom(CustomTool),
GhIssue(GhIssue),
WebSearch(WebSearch),
}

impl Tool {
Expand All @@ -53,6 +56,7 @@ impl Tool {
Tool::UseAws(_) => "use_aws",
Tool::Custom(custom_tool) => &custom_tool.name,
Tool::GhIssue(_) => "gh_issue",
Tool::WebSearch(_) => "web_search",
}
.to_owned()
}
Expand All @@ -66,6 +70,7 @@ impl Tool {
Tool::UseAws(use_aws) => use_aws.requires_acceptance(),
Tool::Custom(_) => true,
Tool::GhIssue(_) => false,
Tool::WebSearch(_) => false,
}
}

Expand All @@ -78,6 +83,7 @@ impl Tool {
Tool::UseAws(use_aws) => use_aws.invoke(context, updates).await,
Tool::Custom(custom_tool) => custom_tool.invoke(context, updates).await,
Tool::GhIssue(gh_issue) => gh_issue.invoke(updates).await,
Tool::WebSearch(web_search) => web_search.invoke(updates).await,
}
}

Expand All @@ -90,6 +96,7 @@ impl Tool {
Tool::UseAws(use_aws) => use_aws.queue_description(updates),
Tool::Custom(custom_tool) => custom_tool.queue_description(updates),
Tool::GhIssue(gh_issue) => gh_issue.queue_description(updates),
Tool::WebSearch(web_search) => web_search.queue_description(updates),
}
}

Expand All @@ -102,6 +109,7 @@ impl Tool {
Tool::UseAws(use_aws) => use_aws.validate(ctx).await,
Tool::Custom(custom_tool) => custom_tool.validate(ctx).await,
Tool::GhIssue(gh_issue) => gh_issue.validate(ctx).await,
Tool::WebSearch(web_search) => web_search.validate(ctx).await,
}
}
}
Expand Down Expand Up @@ -175,6 +183,7 @@ impl ToolPermissions {
"execute_bash" => "trust read-only commands".dark_grey(),
"use_aws" => "trust read-only commands".dark_grey(),
"report_issue" => "trusted".dark_green().bold(),
"web_search" => "trusted".dark_green().bold(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we should have this as trusted by default, the model could make requests to arbitrary websites that can track the user's activity in unwanted ways.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. For ref, Claude Code's similar WebFetch requires permissions instead of being trusted by default: https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview#tools-available-to-claude

_ => "not trusted".dark_grey(),
};

Expand Down
27 changes: 27 additions & 0 deletions crates/q_chat/src/tools/tool_index.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,33 @@
]
}
},
"web_search": {
"name": "web_search",
"description": "Search/retrieving the web for the specified query. Currently only supports retrieving.",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe hold off on including any search related functionality until it's supported? Model might hallucinate

"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query to use. This is optional when mode is set to Retrieve since the target_url will be used instead."
},
"mode": {
"type": "string",
"enum": [
"Retrieve"
],
"description": "Retrieve mode will return the markdown representation of the page. Search mode (not supported currently) will return the first x results from a search engine."
},
"target_url": {
"type": "string",
"description": "The web page to retrieve. This is only used in Retrieve mode."
}
},
"required": [
"mode"
]
}
},
"gh_issue": {
"name": "report_issue",
"description": "Opens the browser to a pre-filled gh (GitHub) issue template to report chat issues, bugs, or feature requests. Pre-filled information includes the conversation transcript, chat context, and chat request IDs from the service.",
Expand Down
Loading
Loading