Add examples (#136)
## PR Description This PR adds 7 examples. * `call_a_tool_directly_with_auth.py` - Simple example that uses Arcade client to execute a tool that lists Gmail emails * `call_a_tool_directly.py` - Simple example that uses Arcade client to execute a tool that adds two numbers together * `call_a_tool_with_llm.py` - Simple example that uses the LLM api to star the arcade-ai repository * `get_auth_token.py` - Simple example that gets a Google auth token and then calls the Google API * `call_multiple_tools_directly_with_auth.py` - A more involved example that directly calls multiple spotify tools sequentially * `call_multiple_tools_with_llm.py` - A more involved example that uses an llm to call multiple spotify tools sequentially * `simple_chatbot.py` - Simple chatbot that uses arcade tools and has history --------- Co-authored-by: Nate Barbettini <nathanaelb@gmail.com>
This commit is contained in:
parent
6d1bc6c084
commit
081865733a
12 changed files with 546 additions and 60 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -8,6 +8,11 @@
|
|||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"[python]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit",
|
||||
"source.organizeImports": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "charliermarsh.ruff"
|
||||
},
|
||||
"[jsonc]": {
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
from arcadepy import Arcade
|
||||
|
||||
client = Arcade(
|
||||
base_url="http://localhost:9099",
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
|
||||
# Start the authorization process
|
||||
auth_response = client.tools.authorize(
|
||||
tool_name="Google.ListEmails",
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
if auth_response.status != "completed":
|
||||
print(f"Click this link to authorize: {auth_response.authorization_url}")
|
||||
input("After you have authorized, press Enter to continue...")
|
||||
|
||||
inputs = {"n_emails": 5}
|
||||
|
||||
response = client.tools.execute(
|
||||
tool_name="Google.ListEmails",
|
||||
inputs=inputs,
|
||||
user_id=user_id,
|
||||
)
|
||||
print(response)
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
from arcadepy import Arcade
|
||||
from arcadepy.types.auth_authorize_params import AuthRequirement, AuthRequirementOauth2
|
||||
from google.oauth2.credentials import Credentials
|
||||
from googleapiclient.discovery import build
|
||||
|
||||
client = Arcade(
|
||||
base_url="http://localhost:9099",
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
|
||||
# Start the authorization process
|
||||
auth_response = client.auth.authorize(
|
||||
auth_requirement=AuthRequirement(
|
||||
provider_id="google",
|
||||
oauth2=AuthRequirementOauth2(
|
||||
scopes=["https://www.googleapis.com/auth/gmail.readonly"],
|
||||
),
|
||||
),
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
if auth_response.status != "completed":
|
||||
print(f"Click this link to authorize: {auth_response.authorization_url}")
|
||||
input("After you have authorized, press Enter to continue...")
|
||||
|
||||
# Use the token from the authorization response
|
||||
creds = Credentials(auth_response.context.token)
|
||||
service = build("gmail", "v1", credentials=creds)
|
||||
|
||||
# Now you can use the Google API
|
||||
results = service.users().labels().list(userId="me").execute()
|
||||
labels = results.get("labels", [])
|
||||
print("Labels:", labels)
|
||||
40
examples/call_a_tool_directly.py
Normal file
40
examples/call_a_tool_directly.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"""
|
||||
This example demonstrates how to directly call a tool that does not require authorization.
|
||||
"""
|
||||
|
||||
from arcadepy import Arcade # pip install arcade-py
|
||||
|
||||
|
||||
def call_non_auth_tool(client: Arcade, user_id: str) -> None:
|
||||
"""Directly call a prebuilt tool that does not require authorization.
|
||||
|
||||
In this example, we are
|
||||
1. Preparing the inputs to the Math.Add tool
|
||||
2. Executing the tool
|
||||
3. Printing the output of the tool's execution, i.e., the result of adding 9001 and 42
|
||||
|
||||
This is a simple example of calling a non-auth tool. Next, try writing your own non-auth tool for your own use case.
|
||||
"""
|
||||
# Prepare the inputs to the tool as a dictionary where keys are the names of the parameters expected by the tool and the values are the actual values to pass to the tool
|
||||
inputs = {"a": 9001, "b": 42}
|
||||
|
||||
# Execute the tool
|
||||
response = client.tools.execute(
|
||||
tool_name="Math.Add",
|
||||
inputs=inputs,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
# Print the output of the tool execution
|
||||
print(response.output.value)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cloud_host = "https://api.arcade-ai.com"
|
||||
|
||||
client = Arcade(
|
||||
base_url=cloud_host, # Alternatively, use http://localhost:9099 if you are running Arcade Engine locally, or any base_url if you're hosting elsewhere
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
call_non_auth_tool(client, user_id)
|
||||
51
examples/call_a_tool_directly_with_auth.py
Normal file
51
examples/call_a_tool_directly_with_auth.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
"""
|
||||
This example demonstrates how to directly call a tool that requires authorization.
|
||||
"""
|
||||
|
||||
from arcadepy import Arcade # pip install arcade-py
|
||||
|
||||
|
||||
def call_auth_tool(client: Arcade, user_id: str) -> None:
|
||||
"""Directly call a prebuilt tool that requires authorization.
|
||||
|
||||
In this example, we are
|
||||
1. Authorizing Arcade to read emails from the user's Gmail account with the user's permission to do so
|
||||
2. Reading 5 emails from the user's Gmail account
|
||||
3. Printing the emails
|
||||
|
||||
Try altering this example to call a tool that requires a different authorization.
|
||||
"""
|
||||
# Start the authorization process
|
||||
auth_response = client.tools.authorize(
|
||||
tool_name="Google.ListEmails",
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
# If not already authorized, then wait for the user to authorize the permissions required by the tool
|
||||
if auth_response.status != "completed":
|
||||
print(f"Click this link to authorize: {auth_response.authorization_url}")
|
||||
|
||||
# Wait for the user to complete the auth flow, if necessary
|
||||
client.auth.wait_for_completion(auth_response)
|
||||
|
||||
# Prepare the inputs to the tool as a dictionary where keys are the names of the parameters expected by the tool and the values are the actual values to pass to the tool
|
||||
inputs = {"n_emails": 5}
|
||||
|
||||
# Execute the tool
|
||||
response = client.tools.execute(
|
||||
tool_name="Google.ListEmails",
|
||||
inputs=inputs,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
# Print the output of the tool execution.
|
||||
print(response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
client = Arcade(
|
||||
base_url="https://api.arcade-ai.com", # Alternatively, use http://localhost:9099 if you are running Arcade Engine locally, or any base_url if you're hosting elsewhere
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
call_auth_tool(client, user_id)
|
||||
45
examples/call_a_tool_with_llm.py
Normal file
45
examples/call_a_tool_with_llm.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
This example shows how to call a tool that requires authorization with an LLM using the OpenAI Python client.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
|
||||
def call_tool_with_openai(client: OpenAI) -> dict:
|
||||
response = client.chat.completions.create(
|
||||
messages=[
|
||||
{"role": "user", "content": "Star the ArcadeAI/arcade-ai repository."},
|
||||
],
|
||||
model="gpt-4o-mini", # TODO: Try "claude-3-5-sonnet-20240620" or other models from our supported model providers. Checkout out our docs for a full list: https://docs.arcade-ai.com/integrations
|
||||
user="you@example.com",
|
||||
tools=["Github.SetStarred"],
|
||||
tool_choice="generate", # TODO: Try "execute" and note any differences
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
arcade_api_key = os.environ.get(
|
||||
"ARCADE_API_KEY"
|
||||
) # If you forget your Arcade API key, it is stored at ~/.arcade/credentials.yaml on `arcade login`
|
||||
cloud_host = "https://api.arcade-ai.com" + "/v1"
|
||||
|
||||
openai_client = OpenAI(
|
||||
api_key=arcade_api_key,
|
||||
base_url=cloud_host, # Alternatively, use http://localhost:9099/v1 if you are running Arcade Engine locally
|
||||
)
|
||||
|
||||
chat_result = call_tool_with_openai(openai_client)
|
||||
# If the tool call requires authorization, then wait for the user to authorize and then call the tool again
|
||||
if (
|
||||
chat_result.choices[0].tool_authorizations
|
||||
and chat_result.choices[0].tool_authorizations[0].get("status") == "pending"
|
||||
):
|
||||
print(chat_result.choices[0].message.content)
|
||||
input("After you have authorized, press Enter to continue...")
|
||||
chat_result = call_tool_with_openai(openai_client)
|
||||
|
||||
print(chat_result.choices[0].message.content)
|
||||
178
examples/call_multiple_tools_directly_with_auth.py
Normal file
178
examples/call_multiple_tools_directly_with_auth.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
"""Example script demonstrating how to call multiple tools directly with authentication.
|
||||
|
||||
For this example, we are using the prebuilt Spotify toolkit to start playing similar songs to the currently playing song.
|
||||
|
||||
Steps:
|
||||
1. Get the currently playing song
|
||||
2. Get audio features for the currently playing song
|
||||
3. Get song recommendations that are similar to the currently playing song
|
||||
4. Start playing the recommended songs
|
||||
5. Inform the user which recommended song is now playing
|
||||
"""
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from arcadepy import Arcade # pip install arcade-py
|
||||
|
||||
|
||||
# Need to click on a link for every provider
|
||||
def get_permissions(client: Arcade, provider_to_scopes: dict, user_id: str) -> None:
|
||||
"""Prompt the user to authorize necessary permissions for each provider."""
|
||||
for provider, scopes in provider_to_scopes.items():
|
||||
auth_response = client.auth.start(
|
||||
user_id=user_id,
|
||||
provider=provider,
|
||||
scopes=scopes,
|
||||
)
|
||||
|
||||
if auth_response.status != "completed":
|
||||
print(f"Click this link to authorize: {auth_response.authorization_url}")
|
||||
input("After you have authorized, press Enter to continue...")
|
||||
|
||||
|
||||
def call_tool(client: Arcade, tool_name: str, user_id: str, inputs: Optional[dict] = None) -> Any:
|
||||
"""Call a single tool."""
|
||||
if inputs is None:
|
||||
inputs = {}
|
||||
|
||||
response = client.tools.execute(
|
||||
tool_name=tool_name,
|
||||
inputs=inputs,
|
||||
user_id=user_id,
|
||||
)
|
||||
return response.output.value
|
||||
|
||||
|
||||
def recommend_similar_songs(
|
||||
client: Arcade, provider_to_scopes: dict, tools: list[str], user_id: str, user_country_code: str
|
||||
) -> None:
|
||||
"""Execute the sequence of tools to get recommendations and start playback."""
|
||||
get_permissions(client, provider_to_scopes, user_id)
|
||||
|
||||
recommendation_params = {"seed_genres": []}
|
||||
|
||||
(
|
||||
get_currently_playing_tool,
|
||||
get_tracks_audio_features_tool,
|
||||
get_recommendations_tool,
|
||||
start_tracks_playback_tool,
|
||||
) = tools
|
||||
|
||||
# Step 1: Get the currently playing song
|
||||
while True:
|
||||
response = call_tool(client, get_currently_playing_tool, user_id)
|
||||
|
||||
if response["is_playing"]:
|
||||
break
|
||||
|
||||
print("Nothing is playing right now. Press Enter once you start playing a song...")
|
||||
input()
|
||||
|
||||
# Step 1.5: Use the previous tool output to construct the inputs for the following tool calls
|
||||
current_track_name = response["track_name"]
|
||||
current_track_artists = response["track_artists"]
|
||||
current_track_id = response["track_id"]
|
||||
current_track_spotify_url = response["track_spotify_url"]
|
||||
current_track_artists_ids = response["track_artists_ids"]
|
||||
print(
|
||||
f"\nYou are currently listening to '{current_track_name}' by {', '.join(current_track_artists)}"
|
||||
)
|
||||
recommendation_params.update({
|
||||
"seed_tracks": [current_track_id],
|
||||
"seed_artists": current_track_artists_ids,
|
||||
})
|
||||
|
||||
# Step 2:Get audio features for the currently playing song
|
||||
response = call_tool(
|
||||
client,
|
||||
get_tracks_audio_features_tool,
|
||||
user_id,
|
||||
inputs={"track_ids": [current_track_id]},
|
||||
)
|
||||
|
||||
# Step 2.5: Use the previous tool output to construct the inputs for the following tool calls
|
||||
audio_features = response["audio_features"][0]
|
||||
recommendation_params.update({
|
||||
"target_acousticness": float(audio_features["acousticness"]),
|
||||
"target_danceability": float(audio_features["danceability"]),
|
||||
"target_energy": float(audio_features["energy"]),
|
||||
"target_instrumentalness": float(audio_features["instrumentalness"]),
|
||||
"target_key": int(audio_features["key"]),
|
||||
"target_liveness": float(audio_features["liveness"]),
|
||||
"target_loudness": float(audio_features["loudness"]),
|
||||
"target_mode": int(audio_features["mode"]),
|
||||
"target_speechiness": float(audio_features["speechiness"]),
|
||||
"target_tempo": float(audio_features["tempo"]),
|
||||
"target_time_signature": int(audio_features["time_signature"]),
|
||||
"target_valence": float(audio_features["valence"]),
|
||||
})
|
||||
|
||||
# Step 3: Get song recommendations that are similar to the currently playingsong
|
||||
print(
|
||||
f"Getting recommendations similar to '{current_track_name}' by {', '.join(current_track_artists)} - {current_track_spotify_url}"
|
||||
)
|
||||
response = call_tool(client, get_recommendations_tool, user_id, inputs=recommendation_params)
|
||||
|
||||
# Step 3.5: Use the previous tool output to construct the inputs for the following tool calls
|
||||
# Filter out remixes and the same song from the recommendations
|
||||
tracks = [
|
||||
track for track in response["tracks"] if not track["name"].startswith(current_track_name)
|
||||
]
|
||||
track_ids = [
|
||||
track["id"] for track in tracks if (user_country_code in track["available_markets"])
|
||||
]
|
||||
track_names = [track["name"] for track in tracks]
|
||||
tracks_artists = [[artist["name"] for artist in track["artists"]] for track in tracks]
|
||||
track_spotify_urls = [track["external_urls"]["spotify"] for track in tracks]
|
||||
|
||||
if not track_ids:
|
||||
print("I couldn't find any similar songs that are available in your country.")
|
||||
return
|
||||
|
||||
print("\nHere are some recommendations:")
|
||||
for track_name, track_artists, track_spotify_url in zip(
|
||||
track_names, tracks_artists, track_spotify_urls
|
||||
):
|
||||
print(f"\t{track_name} by {', '.join(track_artists)} - {track_spotify_url}")
|
||||
|
||||
# Step 4: Start playing the recommended songs
|
||||
response = call_tool(
|
||||
client,
|
||||
start_tracks_playback_tool,
|
||||
user_id,
|
||||
inputs={"track_ids": track_ids},
|
||||
)
|
||||
|
||||
# Step 5: Inform the user which recommended song is now playing
|
||||
response = call_tool(client, get_currently_playing_tool, user_id)
|
||||
print(
|
||||
f"\nNow playing: {response['track_name']} by {', '.join(response['track_artists'])} - {response['track_spotify_url']}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
client = Arcade(base_url="https://api.arcade-ai.com")
|
||||
|
||||
# Necessary scopes for the tools we are calling:
|
||||
provider_to_scopes = {
|
||||
"spotify": [
|
||||
"user-read-currently-playing",
|
||||
"user-read-playback-state",
|
||||
"user-modify-playback-state",
|
||||
],
|
||||
}
|
||||
|
||||
tools = [
|
||||
"Spotify.GetCurrentlyPlaying", # Get info about the current song
|
||||
"Spotify.GetTracksAudioFeatures", # Get audio features for the current song
|
||||
"Spotify.GetRecommendations", # Get recommendations similar to the current song
|
||||
"Spotify.StartTracksPlaybackById", # Start playing the recommended songs
|
||||
]
|
||||
|
||||
user_id = "you@example.com"
|
||||
user_country_code = "US"
|
||||
|
||||
while True:
|
||||
recommend_similar_songs(client, provider_to_scopes, tools, user_id, user_country_code)
|
||||
print("\nPress Enter to get more recommendations...")
|
||||
input()
|
||||
91
examples/call_multiple_tools_with_llm.py
Normal file
91
examples/call_multiple_tools_with_llm.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
"""
|
||||
Example script demonstrating how to call multiple tools (sequentially) using an LLM with authentication.
|
||||
|
||||
For this example, we are using the prebuilt Spotify toolkit to start playing similar songs to the currently playing song.
|
||||
|
||||
Steps:
|
||||
1. Get the currently playing song
|
||||
2. Get audio features for the currently playing song
|
||||
3. Get song recommendations that are similar to the currently playing song
|
||||
4. Start playing the recommended songs
|
||||
5. Inform the user which recommended song is now playing
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
|
||||
def call_tool(client: OpenAI, user_id: str, tool: str, message: dict, history: list[dict]) -> str:
|
||||
"""Make a tool call with a specific tool and message."""
|
||||
response = client.chat.completions.create(
|
||||
messages=[
|
||||
*history,
|
||||
message,
|
||||
],
|
||||
model="gpt-4o",
|
||||
user=user_id,
|
||||
tools=[tool],
|
||||
tool_choice="generate",
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
def call_tools_with_llm(client: OpenAI, user_id: str, user_country_code: str) -> list[dict]:
|
||||
"""Use an LLM to execute the sequence of tools to get recommendations and start playback."""
|
||||
tools = [
|
||||
"Spotify.GetCurrentlyPlaying",
|
||||
"Spotify.GetTracksAudioFeatures",
|
||||
"Spotify.GetRecommendations",
|
||||
"Spotify.StartTracksPlaybackById",
|
||||
"Spotify.GetCurrentlyPlaying",
|
||||
]
|
||||
|
||||
messages = [
|
||||
{"role": "user", "content": "Get the currently playing song."},
|
||||
{"role": "user", "content": "Retrieve its audio features."},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Get song recommendations similar to it. "
|
||||
"Do not include the currently playing song in the recommendations "
|
||||
"or any remixed versions of the song. "
|
||||
"Also only include tracks that are available in the user's country. "
|
||||
f"The current user resides in {user_country_code}.",
|
||||
},
|
||||
{"role": "user", "content": "Start playing the recommended songs. Just one tool call."},
|
||||
{"role": "user", "content": "Get the currently playing song."},
|
||||
]
|
||||
|
||||
history = []
|
||||
for i in range(len(messages)):
|
||||
response = call_tool(client, user_id, tools[i], messages[i], history)
|
||||
print("\n\n", response.choices[0].message.content)
|
||||
if (
|
||||
response.choices[0].tool_authorizations
|
||||
and response.choices[0].tool_authorizations[0].get("status") == "pending"
|
||||
):
|
||||
input("\nPress Enter once you have authorized...")
|
||||
response = call_tool(client, user_id, tools[i], messages[i], history)
|
||||
history.append(messages[i])
|
||||
history.append({"role": "assistant", "content": response.choices[0].message.content})
|
||||
|
||||
return history
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
arcade_api_key = os.environ.get("ARCADE_API_KEY")
|
||||
cloud_host = "https://api.arcade-ai.com/v1"
|
||||
|
||||
openai_client = OpenAI(
|
||||
api_key=arcade_api_key,
|
||||
base_url=cloud_host,
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
user_country_code = "US"
|
||||
|
||||
while True:
|
||||
history = call_tools_with_llm(openai_client, user_id, user_country_code)
|
||||
|
||||
print("\nPress Enter to get more recommendations...")
|
||||
input()
|
||||
58
examples/get_auth_token.py
Normal file
58
examples/get_auth_token.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
This example demonstrates how to get an authorization token for a user and then use it to make a request to the Google API on behalf of the user.
|
||||
"""
|
||||
|
||||
from arcadepy import Arcade
|
||||
from google.oauth2.credentials import Credentials # pip install google-auth
|
||||
from googleapiclient.discovery import build # pip install google-api-python-client
|
||||
|
||||
|
||||
def get_auth_token(client: Arcade, user_id: str) -> str:
|
||||
"""Get an authorization token for a user.
|
||||
|
||||
In this example, we are
|
||||
1. Starting the authorization process for the Gmail Readonly scope
|
||||
2. Waiting for the user to authorize the scope
|
||||
3. Getting the authorization token
|
||||
4. Using the authorization token to make a request to the Google API on behalf of the user
|
||||
"""
|
||||
# Start the authorization process
|
||||
auth_response = client.auth.start(
|
||||
user_id, "google", scopes=["https://www.googleapis.com/auth/gmail.readonly"]
|
||||
)
|
||||
|
||||
if auth_response.status != "completed":
|
||||
print(f"Click this link to authorize: {auth_response.authorization_url}")
|
||||
auth_response = client.auth.wait_for_completion(auth_response)
|
||||
|
||||
return auth_response.context.token
|
||||
|
||||
|
||||
def use_auth_token(token: str) -> None:
|
||||
"""Use an authorization token to make a request to the Google API on behalf of a user.
|
||||
|
||||
In this example, we are
|
||||
1. Using the authorization token that we got from the authorization process to make a request to the Google API
|
||||
client.auth.wait_for_completion(auth_response)
|
||||
"""
|
||||
# Use the token from the authorization response
|
||||
creds = Credentials(token)
|
||||
service = build("gmail", "v1", credentials=creds)
|
||||
|
||||
# Now you can use the Google API
|
||||
results = service.users().labels().list(userId="me").execute()
|
||||
labels = results.get("labels", [])
|
||||
print("Labels:", labels)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cloud_host = "https://api.arcade-ai.com"
|
||||
|
||||
client = Arcade(
|
||||
base_url=cloud_host, # Alternatively, use http://localhost:9099 if you are running Arcade locally, or any base_url if you're hosting elsewhere
|
||||
)
|
||||
|
||||
user_id = "you@example.com"
|
||||
|
||||
token = get_auth_token(client, user_id)
|
||||
use_auth_token(token)
|
||||
74
examples/simple_chatbot.py
Normal file
74
examples/simple_chatbot.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"""
|
||||
Example script demonstrating how to build a simple chatbot with Arcade AI.
|
||||
|
||||
For this example, we are using the prebuilt Google Docs toolkit to create and edit documents.
|
||||
|
||||
Try asking questions like:
|
||||
- "Create a document with the title 'My New Document' and content 'Hello, World!'"
|
||||
- "List my 2 most recently modified documents and tell me the title, document id, and document URL of each one and summarize them."
|
||||
- "Edit the second document from the list you just returned and add the text 'Hello, World!' to the end of it."
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
|
||||
def chat(openai_client: OpenAI, tool_names: list[str], user_id: str) -> None:
|
||||
history = []
|
||||
|
||||
print("Hello! How can I help you today?")
|
||||
while True:
|
||||
message = {"role": "user", "content": input(">")}
|
||||
history.append(message)
|
||||
chat_result = call_tool_with_openai(openai_client, tool_names, user_id, history)
|
||||
|
||||
# If the tool call requires authorization, then wait for the user to authorize and then call the tool again
|
||||
if (
|
||||
chat_result.choices[0].tool_authorizations
|
||||
and chat_result.choices[0].tool_authorizations[0].get("status") == "pending"
|
||||
):
|
||||
print("\n" + chat_result.choices[0].message.content)
|
||||
input("\nAfter you have authorized, press Enter to continue...")
|
||||
chat_result = call_tool_with_openai(openai_client, tool_names, user_id, history)
|
||||
|
||||
history.append({"role": "assistant", "content": chat_result.choices[0].message.content})
|
||||
|
||||
print(chat_result.choices[0].message.content)
|
||||
|
||||
|
||||
def call_tool_with_openai(
|
||||
client: OpenAI, tool_names: list[str], user_id: str, messages: list[dict]
|
||||
) -> dict:
|
||||
response = client.chat.completions.create(
|
||||
messages=messages,
|
||||
model="gpt-4o-mini",
|
||||
user=user_id,
|
||||
tools=tool_names,
|
||||
tool_choice="generate",
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
arcade_api_key = os.environ.get(
|
||||
"ARCADE_API_KEY"
|
||||
) # If you forget your Arcade API key, it is stored at ~/.arcade/credentials.yaml on `arcade login`
|
||||
local_host = "http://localhost:9099/v1"
|
||||
user_id = "user@example.com"
|
||||
|
||||
openai_client = OpenAI(
|
||||
api_key=arcade_api_key,
|
||||
base_url=local_host,
|
||||
)
|
||||
|
||||
tool_names = [
|
||||
"Google.GetDocumentById",
|
||||
"Google.InsertTextAtEndOfDocument",
|
||||
"Google.CreateBlankDocument",
|
||||
"Google.CreateDocumentFromText",
|
||||
"Google.ListDocuments",
|
||||
]
|
||||
|
||||
chat(openai_client, tool_names, user_id)
|
||||
|
|
@ -18,7 +18,9 @@ class PlaybackState:
|
|||
album_spotify_url: Optional[str] = None
|
||||
track_id: Optional[str] = None
|
||||
track_name: Optional[str] = None
|
||||
track_spotify_url: Optional[str] = None
|
||||
track_artists: list[str] = field(default_factory=list)
|
||||
track_artists_ids: list[str] = field(default_factory=list)
|
||||
show_id: Optional[str] = None
|
||||
show_spotify_url: Optional[str] = None
|
||||
episode_name: Optional[str] = None
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ def convert_to_playback_state(data: dict) -> PlaybackState:
|
|||
playback_state.album_spotify_url = album.get("external_urls", {}).get("spotify")
|
||||
playback_state.track_name = item.get("name")
|
||||
playback_state.track_id = item.get("id")
|
||||
playback_state.track_spotify_url = item.get("external_urls").get("spotify")
|
||||
playback_state.track_artists = [artist.get("name") for artist in item.get("artists", [])]
|
||||
playback_state.track_artists_ids = [artist.get("id") for artist in item.get("artists", [])]
|
||||
elif data.get("currently_playing_type") == "episode":
|
||||
item = data.get("item", {})
|
||||
show = item.get("show", {})
|
||||
|
|
|
|||
Loading…
Reference in a new issue