Skip to content
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

Merged
merged 6 commits into from
Oct 16, 2024
Merged

Add custom tool headers #2773

merged 6 commits into from
Oct 16, 2024

Conversation

pablonyx
Copy link
Contributor

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:

  • All of the automated tests pass
  • All PR comments are addressed and marked resolved
  • If there are migrations, they have been rebased to latest main
  • If there are new dependencies, they are added to the requirements
  • If there are new environment variables, they are added to all of the deployment methods
  • If there are new APIs that don't require auth, they are added to PUBLIC_ENDPOINT_SPECS
  • Docker images build and basic functionalities work
  • Author has done a final read through of the PR right before merge

Copy link

vercel bot commented Oct 12, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
internal-search ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 15, 2024 5:34pm

Copy link

@greptile-apps greptile-apps bot left a 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 in backend/danswer/configs/model_configs.py for managing custom tool headers
  • Implemented get_tool_headers function in new file backend/danswer/tools/headers.py to process and filter headers based on configuration
  • Modified CustomTool class in backend/danswer/tools/custom/custom_tool.py to incorporate tool_additional_headers in API requests
  • Updated handle_new_chat_message in backend/danswer/server/query_and_chat/chat_backend.py to include tool headers in chat processing
  • Added tool_additional_headers parameter to stream_chat_message_objects and stream_chat_message functions in backend/danswer/chat/process_message.py, though usage is not yet implemented

6 file(s) reviewed, 10 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines +279 to 280
tool_additional_headers: dict[str, str] | None = None,
is_connected: Callable[[], bool] | None = None,
Copy link

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
Copy link

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)
Copy link

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

backend/danswer/configs/model_configs.py Show resolved Hide resolved
@@ -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,
Copy link

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 {})
Copy link

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,
Copy link

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

Comment on lines 13 to 27
if key in headers:
pass_through_headers[key] = headers[key]
elif lowercase_key in headers:
pass_through_headers[lowercase_key] = headers[lowercase_key]
Copy link

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

Copy link
Contributor

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.

Copy link
Contributor Author

@pablonyx pablonyx Oct 12, 2024

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

Copy link
Contributor

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/configs/model_configs.py Show resolved Hide resolved
Comment on lines 13 to 27
if key in headers:
pass_through_headers[key] = headers[key]
elif lowercase_key in headers:
pass_through_headers[lowercase_key] = headers[lowercase_key]
Copy link
Contributor

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.

Comment on lines 13 to 27
if key in headers:
pass_through_headers[key] = headers[key]
elif lowercase_key in headers:
pass_through_headers[lowercase_key] = headers[lowercase_key]
Copy link
Contributor

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.

@rkuo-danswer rkuo-danswer added this pull request to the merge queue Oct 16, 2024
Merged via the queue into main with commit 11372aa Oct 16, 2024
7 checks passed
@pablonyx pablonyx deleted the tool_headers branch October 17, 2024 23:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants