Skip to content

Commit b3651e5

Browse files
committed
Use credentials tool to antropic computer
1 parent d40ddf4 commit b3651e5

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

llmstack/processors/providers/promptly/web_browser.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
import uuid
44
from typing import List, Literal, Optional, Union
5+
from urllib.parse import urlparse
56

67
import orjson as json
78
from asgiref.sync import async_to_sync
@@ -165,6 +166,24 @@
165166
},
166167
}
167168

169+
CREDENTIALS_TOOL_SCHEMA = {
170+
"type": "function",
171+
"function": {
172+
"name": "credentials",
173+
"description": "Get credentials for a given domain",
174+
"parameters": {
175+
"type": "object",
176+
"properties": {
177+
"domain": {
178+
"type": "string",
179+
"description": "Domain of the website to get credentials for",
180+
},
181+
},
182+
"required": ["domain"],
183+
},
184+
},
185+
}
186+
168187
TOOLS = [
169188
GOTO_TOOL_SCHEMA,
170189
COPY_TOOL_SCHEMA,
@@ -442,6 +461,10 @@ def _process_anthropic(self) -> dict:
442461
browser_downloads = []
443462
session_videos = []
444463

464+
credentials_tool_schema = CREDENTIALS_TOOL_SCHEMA["function"]
465+
credentials_tool_schema["input_schema"] = credentials_tool_schema["parameters"]
466+
del credentials_tool_schema["parameters"]
467+
445468
with WebBrowserClient(
446469
f"{settings.RUNNER_HOST}:{settings.RUNNER_PORT}",
447470
interactive=self._config.stream_video,
@@ -485,7 +508,12 @@ def _process_anthropic(self) -> dict:
485508
and isinstance(message.get("content"), list)
486509
and message.get("content")[0].get("type") == "tool_result"
487510
):
488-
message["content"][0]["content"] = []
511+
tool_result = message.get("content")[0]
512+
new_content = []
513+
for content in tool_result.get("content"):
514+
if content.get("type") != "image":
515+
new_content.append(content)
516+
tool_result["content"] = new_content
489517

490518
response = client.chat.completions.create(
491519
model=self._config.provider_config.model.model_name(),
@@ -499,6 +527,7 @@ def _process_anthropic(self) -> dict:
499527
"display_height_px": 720,
500528
"display_number": 1,
501529
},
530+
credentials_tool_schema,
502531
],
503532
stream=False,
504533
extra_headers={"anthropic-beta": "computer-use-2024-10-22"},
@@ -531,6 +560,43 @@ def _process_anthropic(self) -> dict:
531560
tool_responses = []
532561
for message_content in choice.message.content:
533562
if message_content.get("type") == "tool_use":
563+
if message_content.get("name") == "credentials":
564+
domain = message_content.get("input", {}).get("domain")
565+
if domain:
566+
credentials = self._env["connections"][self._config.connection_id]["configuration"][
567+
"credentials"
568+
]
569+
credentials_to_use = None
570+
for credential in credentials:
571+
credential_domain = urlparse(credential.get("domain")).netloc or credential.get(
572+
"domain"
573+
)
574+
input_domain = urlparse(domain).netloc or domain
575+
576+
# Compare the extracted domains
577+
if credential_domain in input_domain or input_domain in credential_domain:
578+
credentials_to_use = credential
579+
break
580+
if credentials_to_use:
581+
messages.append(
582+
{
583+
"role": "user",
584+
"content": [
585+
{
586+
"type": "tool_result",
587+
"content": [
588+
{
589+
"type": "text",
590+
"text": f"Credentials for {domain}: username: {credentials_to_use.get('username')}, password: {credentials_to_use.get('password')}",
591+
}
592+
],
593+
"tool_use_id": message_content["id"],
594+
}
595+
],
596+
}
597+
)
598+
continue
599+
534600
browser_response = self._execute_anthropic_instruction_in_browser(
535601
message_content.get("input", {}),
536602
web_browser=web_browser,

0 commit comments

Comments
 (0)