-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add custom tool headers #2773
Add custom tool headers #2773
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
This pull request introduces custom tool headers functionality across the Danswer system, enhancing flexibility in API interactions and tool operations.
- Added
TOOL_PASS_THROUGH_HEADERS
configuration inbackend/danswer/configs/model_configs.py
for managing custom tool headers - Implemented
get_tool_headers
function in new filebackend/danswer/tools/headers.py
to process and filter headers based on configuration - Modified
CustomTool
class inbackend/danswer/tools/custom/custom_tool.py
to incorporatetool_additional_headers
in API requests - Updated
handle_new_chat_message
inbackend/danswer/server/query_and_chat/chat_backend.py
to include tool headers in chat processing - Added
tool_additional_headers
parameter tostream_chat_message_objects
andstream_chat_message
functions inbackend/danswer/chat/process_message.py
, though usage is not yet implemented
6 file(s) reviewed, 10 comment(s)
Edit PR Review Bot Settings | Greptile
tool_additional_headers: dict[str, str] | None = None, | ||
is_connected: Callable[[], bool] | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: New parameter tool_additional_headers
added but not used in the function body
@@ -119,3 +119,17 @@ | |||
logger.error( | |||
"Failed to parse LITELLM_PASS_THROUGH_HEADERS, must be a valid JSON object" | |||
) | |||
|
|||
|
|||
TOOL_PASS_THROUGH_HEADERS: list[str] | None = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider adding a comment explaining the purpose of TOOL_PASS_THROUGH_HEADERS
_TOOL_PASS_THROUGH_HEADERS_RAW = os.environ.get("TOOL_PASS_THROUGH_HEADERS") | ||
if _TOOL_PASS_THROUGH_HEADERS_RAW: | ||
try: | ||
TOOL_PASS_THROUGH_HEADERS = json.loads(_TOOL_PASS_THROUGH_HEADERS_RAW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Ensure TOOL_PASS_THROUGH_HEADERS is a list of strings after parsing
@@ -47,6 +47,7 @@ def __init__( | |||
method_spec: MethodSpec, | |||
base_url: str, | |||
custom_headers: list[dict[str, str]] | None = [], | |||
tool_additional_headers: dict[str, str] | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider adding type hints for the tool_additional_headers
parameter
@@ -59,6 +60,7 @@ def __init__( | |||
if custom_headers | |||
else {} | |||
) | |||
self.headers.update(tool_additional_headers or {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Use self.headers.update(tool_additional_headers or {})
for consistency with line 58
@@ -185,6 +187,7 @@ def final_result(self, *args: ToolResponse) -> JSON_ro: | |||
|
|||
def build_custom_tools_from_openapi_schema_and_headers( | |||
openapi_schema: dict[str, Any], | |||
tool_additional_headers: dict[str, str] | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Add a docstring explaining the purpose of tool_additional_headers
backend/danswer/tools/headers.py
Outdated
if key in headers: | ||
pass_through_headers[key] = headers[key] | ||
elif lowercase_key in headers: | ||
pass_through_headers[lowercase_key] = headers[lowercase_key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: This logic might lead to unexpected behavior if both original and lowercase keys exist in headers. Consider prioritizing or documenting the behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should write a docstring here to document what the inputs and outputs look like. then if we need to conform keys to lowercase to do the matching, then let's do that instead of matching twice, etc.
It's also unclear why this has to be an implementation specific function that knows what a "tool" is. If this is a function that passes through some headers based on a set of other headers, then perhaps we should write it that way with the appropriate params, and not access external state to make the function work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree re: a docstring– believe that would help make this clear- we do need the external config to be tool specific because it's specifically for passing headers through to the custom tool calls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understand the function is being used here for filtering tool headers, but it should be written more generically as an function of the form extract_headers(headers, TOOL_PASS_THROUGH_HEADERS) without accessing global state. This allows the function to be pure and gives us a utility function we can put somewhere in case we want to reuse it.
backend/danswer/tools/headers.py
Outdated
if key in headers: | ||
pass_through_headers[key] = headers[key] | ||
elif lowercase_key in headers: | ||
pass_through_headers[lowercase_key] = headers[lowercase_key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should write a docstring here to document what the inputs and outputs look like. then if we need to conform keys to lowercase to do the matching, then let's do that instead of matching twice, etc.
It's also unclear why this has to be an implementation specific function that knows what a "tool" is. If this is a function that passes through some headers based on a set of other headers, then perhaps we should write it that way with the appropriate params, and not access external state to make the function work.
1a059c8
to
6d9e151
Compare
backend/danswer/tools/headers.py
Outdated
if key in headers: | ||
pass_through_headers[key] = headers[key] | ||
elif lowercase_key in headers: | ||
pass_through_headers[lowercase_key] = headers[lowercase_key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understand the function is being used here for filtering tool headers, but it should be written more generically as an function of the form extract_headers(headers, TOOL_PASS_THROUGH_HEADERS) without accessing global state. This allows the function to be pure and gives us a utility function we can put somewhere in case we want to reuse it.
6d9e151
to
129d357
Compare
Description
[Provide a brief description of the changes in this PR]
How Has This Been Tested?
[Describe the tests you ran to verify your changes]
Accepted Risk
[Any know risks or failure modes to point out to reviewers]
Related Issue(s)
[If applicable, link to the issue(s) this PR addresses]
Checklist: