mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-20 21:08:04 -05:00
Compare commits
7 Commits
js-sdk-doc
...
demo-inclu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f6b2f11a4 | ||
|
|
fd9b0ea55b | ||
|
|
f4ddd194dc | ||
|
|
114a0c91d8 | ||
|
|
5f1e4b940c | ||
|
|
e0b6d2d26b | ||
|
|
590bfaf4d3 |
49
.hugo/layouts/shortcodes/snippet.html
Normal file
49
.hugo/layouts/shortcodes/snippet.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{{/*
|
||||||
|
snippet.html
|
||||||
|
Usage:
|
||||||
|
{{< snippet "filename.md" "region_name" >}}
|
||||||
|
{{< snippet "filename.python" "region_name" "python" >}}
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{ $file := .Get 0 }}
|
||||||
|
{{ $region := .Get 1 }}
|
||||||
|
{{ $lang := .Get 2 | default "text" }}
|
||||||
|
{{ $path := printf "%s%s" .Page.File.Dir $file }}
|
||||||
|
|
||||||
|
{{ if or (not $file) (eq $file "") }}
|
||||||
|
{{ errorf "The file parameter (first argument) is required and must be non-empty in %s" .Page.File.Path }}
|
||||||
|
{{ end }}
|
||||||
|
{{ if or (not $region) (eq $region "") }}
|
||||||
|
{{ errorf "The region parameter (second argument) is required and must be non-empty in %s" .Page.File.Path }}
|
||||||
|
{{ end }}
|
||||||
|
{{ if not (fileExists $path) }}
|
||||||
|
{{ errorf "File %q not found (referenced in %s)" $path .Page.File.Path }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $content := readFile $path }}
|
||||||
|
{{ $start_tag := printf "[START %s]" $region }}
|
||||||
|
{{ $end_tag := printf "[END %s]" $region }}
|
||||||
|
|
||||||
|
{{ $snippet := "" }}
|
||||||
|
{{ $in_snippet := false }}
|
||||||
|
{{ range split $content "\n" }}
|
||||||
|
{{ if $in_snippet }}
|
||||||
|
{{ if in . $end_tag }}
|
||||||
|
{{ $in_snippet = false }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $snippet = printf "%s%s\n" $snippet . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ else if in . $start_tag }}
|
||||||
|
{{ $in_snippet = true }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if eq (trim $snippet "") "" }}
|
||||||
|
{{ errorf "Region %q not found or empty in file %s (referenced in %s)" $region $file .Page.File.Path }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if eq $lang "text" }}
|
||||||
|
{{ $snippet | markdownify }}
|
||||||
|
{{ else }}
|
||||||
|
{{ highlight (trim $snippet "\n") $lang "" }}
|
||||||
|
{{ end }}
|
||||||
@@ -18,6 +18,7 @@ This guide assumes you have already done the following:
|
|||||||
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
||||||
|
|
||||||
### Cloud Setup (Optional)
|
### Cloud Setup (Optional)
|
||||||
|
<!-- [START cloud_setup] -->
|
||||||
|
|
||||||
If you plan to use **Google Cloud’s Vertex AI** with your agent (e.g., using
|
If you plan to use **Google Cloud’s Vertex AI** with your agent (e.g., using
|
||||||
`vertexai=True` or a Google GenAI model), follow these one-time setup steps for
|
`vertexai=True` or a Google GenAI model), follow these one-time setup steps for
|
||||||
@@ -36,8 +37,10 @@ local development:
|
|||||||
[install-pip]: https://pip.pypa.io/en/stable/installation/
|
[install-pip]: https://pip.pypa.io/en/stable/installation/
|
||||||
[install-venv]: https://packaging.python.org/en/latest/tutorials/installing-packages/#creating-virtual-environments
|
[install-venv]: https://packaging.python.org/en/latest/tutorials/installing-packages/#creating-virtual-environments
|
||||||
[install-postgres]: https://www.postgresql.org/download/
|
[install-postgres]: https://www.postgresql.org/download/
|
||||||
|
<!-- [END cloud_setup] -->
|
||||||
|
|
||||||
## Step 1: Set up your database
|
## Step 1: Set up your database
|
||||||
|
<!-- [START database_setup] -->
|
||||||
|
|
||||||
In this section, we will create a database, insert some data that needs to be
|
In this section, we will create a database, insert some data that needs to be
|
||||||
accessed by our agent, and create a database user for Toolbox to connect with.
|
accessed by our agent, and create a database user for Toolbox to connect with.
|
||||||
@@ -155,8 +158,11 @@ postgres` and a password next time.
|
|||||||
```bash
|
```bash
|
||||||
\q
|
\q
|
||||||
```
|
```
|
||||||
|
<!-- [END database_setup] -->
|
||||||
|
|
||||||
|
|
||||||
## Step 2: Install and configure Toolbox
|
## Step 2: Install and configure Toolbox
|
||||||
|
<!-- [START configure_toolbox] -->
|
||||||
|
|
||||||
In this section, we will download Toolbox, configure our tools in a
|
In this section, we will download Toolbox, configure our tools in a
|
||||||
`tools.yaml`, and then run the Toolbox server.
|
`tools.yaml`, and then run the Toolbox server.
|
||||||
@@ -278,6 +284,8 @@ In this section, we will download Toolbox, configure our tools in a
|
|||||||
`--disable-reload` flag.
|
`--disable-reload` flag.
|
||||||
{{< /notice >}}
|
{{< /notice >}}
|
||||||
|
|
||||||
|
<!-- [END configure_toolbox] -->
|
||||||
|
|
||||||
## Step 3: Connect your agent to Toolbox
|
## Step 3: Connect your agent to Toolbox
|
||||||
|
|
||||||
In this section, we will write and run an agent that will load the Tools
|
In this section, we will write and run an agent that will load the Tools
|
||||||
@@ -346,306 +354,16 @@ pip install google-genai
|
|||||||
code to create an agent:
|
code to create an agent:
|
||||||
{{< tabpane persist=header >}}
|
{{< tabpane persist=header >}}
|
||||||
{{< tab header="ADK" lang="python" >}}
|
{{< tab header="ADK" lang="python" >}}
|
||||||
from google.adk.agents import Agent
|
{{< include "quickstart/python/adk/quickstart.py" >}}
|
||||||
from google.adk.runners import Runner
|
|
||||||
from google.adk.sessions import InMemorySessionService
|
|
||||||
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
|
|
||||||
from google.genai import types
|
|
||||||
from toolbox_core import ToolboxSyncClient
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import os
|
|
||||||
|
|
||||||
# TODO(developer): replace this with your Google API key
|
|
||||||
|
|
||||||
os.environ['GOOGLE_API_KEY'] = 'your-api-key'
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
with ToolboxSyncClient("<http://127.0.0.1:5000>") as toolbox_client:
|
|
||||||
|
|
||||||
prompt = """
|
|
||||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
|
||||||
cancellations. When the user searches for a hotel, mention it's name, id,
|
|
||||||
location and price tier. Always mention hotel ids while performing any
|
|
||||||
searches. This is very important for any operations. For any bookings or
|
|
||||||
cancellations, please provide the appropriate confirmation. Be sure to
|
|
||||||
update checkin or checkout dates if mentioned by the user.
|
|
||||||
Don't ask for confirmations from the user.
|
|
||||||
"""
|
|
||||||
|
|
||||||
root_agent = Agent(
|
|
||||||
model='gemini-2.0-flash-001',
|
|
||||||
name='hotel_agent',
|
|
||||||
description='A helpful AI assistant.',
|
|
||||||
instruction=prompt,
|
|
||||||
tools=toolbox_client.load_toolset("my-toolset"),
|
|
||||||
)
|
|
||||||
|
|
||||||
session_service = InMemorySessionService()
|
|
||||||
artifacts_service = InMemoryArtifactService()
|
|
||||||
session = await session_service.create_session(
|
|
||||||
state={}, app_name='hotel_agent', user_id='123'
|
|
||||||
)
|
|
||||||
runner = Runner(
|
|
||||||
app_name='hotel_agent',
|
|
||||||
agent=root_agent,
|
|
||||||
artifact_service=artifacts_service,
|
|
||||||
session_service=session_service,
|
|
||||||
)
|
|
||||||
|
|
||||||
queries = [
|
|
||||||
"Find hotels in Basel with Basel in its name.",
|
|
||||||
"Can you book the Hilton Basel for me?",
|
|
||||||
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
|
||||||
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
|
||||||
]
|
|
||||||
|
|
||||||
for query in queries:
|
|
||||||
content = types.Content(role='user', parts=[types.Part(text=query)])
|
|
||||||
events = runner.run(session_id=session.id,
|
|
||||||
user_id='123', new_message=content)
|
|
||||||
|
|
||||||
responses = (
|
|
||||||
part.text
|
|
||||||
for event in events
|
|
||||||
for part in event.content.parts
|
|
||||||
if part.text is not None
|
|
||||||
)
|
|
||||||
|
|
||||||
for text in responses:
|
|
||||||
print(text)
|
|
||||||
|
|
||||||
asyncio.run(main())
|
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab header="LangChain" lang="python" >}}
|
{{< tab header="LangChain" lang="python" >}}
|
||||||
import asyncio
|
{{< include "quickstart/python/langchain/quickstart.py" >}}
|
||||||
|
|
||||||
from langgraph.prebuilt import create_react_agent
|
|
||||||
|
|
||||||
# TODO(developer): replace this with another import if needed
|
|
||||||
|
|
||||||
from langchain_google_vertexai import ChatVertexAI
|
|
||||||
|
|
||||||
# from langchain_google_genai import ChatGoogleGenerativeAI
|
|
||||||
|
|
||||||
# from langchain_anthropic import ChatAnthropic
|
|
||||||
|
|
||||||
from langgraph.checkpoint.memory import MemorySaver
|
|
||||||
|
|
||||||
from toolbox_langchain import ToolboxClient
|
|
||||||
|
|
||||||
prompt = """
|
|
||||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
|
||||||
cancellations. When the user searches for a hotel, mention it's name, id,
|
|
||||||
location and price tier. Always mention hotel ids while performing any
|
|
||||||
searches. This is very important for any operations. For any bookings or
|
|
||||||
cancellations, please provide the appropriate confirmation. Be sure to
|
|
||||||
update checkin or checkout dates if mentioned by the user.
|
|
||||||
Don't ask for confirmations from the user.
|
|
||||||
"""
|
|
||||||
|
|
||||||
queries = [
|
|
||||||
"Find hotels in Basel with Basel in its name.",
|
|
||||||
"Can you book the Hilton Basel for me?",
|
|
||||||
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
|
||||||
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
|
||||||
]
|
|
||||||
|
|
||||||
async def run_application():
|
|
||||||
# TODO(developer): replace this with another model if needed
|
|
||||||
model = ChatVertexAI(model_name="gemini-2.0-flash-001")
|
|
||||||
# model = ChatGoogleGenerativeAI(model="gemini-2.0-flash-001")
|
|
||||||
# model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
|
|
||||||
|
|
||||||
# Load the tools from the Toolbox server
|
|
||||||
async with ToolboxClient("http://127.0.0.1:5000") as client:
|
|
||||||
tools = await client.aload_toolset()
|
|
||||||
|
|
||||||
agent = create_react_agent(model, tools, checkpointer=MemorySaver())
|
|
||||||
|
|
||||||
config = {"configurable": {"thread_id": "thread-1"}}
|
|
||||||
for query in queries:
|
|
||||||
inputs = {"messages": [("user", prompt + query)]}
|
|
||||||
response = agent.invoke(inputs, stream_mode="values", config=config)
|
|
||||||
print(response["messages"][-1].content)
|
|
||||||
|
|
||||||
asyncio.run(run_application())
|
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab header="LlamaIndex" lang="python" >}}
|
{{< tab header="LlamaIndex" lang="python" >}}
|
||||||
import asyncio
|
{{< include "quickstart/python/llamaindex/quickstart.py" >}}
|
||||||
import os
|
|
||||||
|
|
||||||
from llama_index.core.agent.workflow import AgentWorkflow
|
|
||||||
|
|
||||||
from llama_index.core.workflow import Context
|
|
||||||
|
|
||||||
# TODO(developer): replace this with another import if needed
|
|
||||||
|
|
||||||
from llama_index.llms.google_genai import GoogleGenAI
|
|
||||||
|
|
||||||
# from llama_index.llms.anthropic import Anthropic
|
|
||||||
|
|
||||||
from toolbox_llamaindex import ToolboxClient
|
|
||||||
|
|
||||||
prompt = """
|
|
||||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
|
||||||
cancellations. When the user searches for a hotel, mention it's name, id,
|
|
||||||
location and price tier. Always mention hotel ids while performing any
|
|
||||||
searches. This is very important for any operations. For any bookings or
|
|
||||||
cancellations, please provide the appropriate confirmation. Be sure to
|
|
||||||
update checkin or checkout dates if mentioned by the user.
|
|
||||||
Don't ask for confirmations from the user.
|
|
||||||
"""
|
|
||||||
|
|
||||||
queries = [
|
|
||||||
"Find hotels in Basel with Basel in its name.",
|
|
||||||
"Can you book the Hilton Basel for me?",
|
|
||||||
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
|
||||||
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
|
||||||
]
|
|
||||||
|
|
||||||
async def run_application():
|
|
||||||
# TODO(developer): replace this with another model if needed
|
|
||||||
llm = GoogleGenAI(
|
|
||||||
model="gemini-2.0-flash-001",
|
|
||||||
vertexai_config={"project": "project-id", "location": "us-central1"},
|
|
||||||
)
|
|
||||||
# llm = GoogleGenAI(
|
|
||||||
# api_key=os.getenv("GOOGLE_API_KEY"),
|
|
||||||
# model="gemini-2.0-flash-001",
|
|
||||||
# )
|
|
||||||
# llm = Anthropic(
|
|
||||||
# model="claude-3-7-sonnet-latest",
|
|
||||||
# api_key=os.getenv("ANTHROPIC_API_KEY")
|
|
||||||
# )
|
|
||||||
|
|
||||||
# Load the tools from the Toolbox server
|
|
||||||
async with ToolboxClient("http://127.0.0.1:5000") as client:
|
|
||||||
tools = await client.aload_toolset()
|
|
||||||
|
|
||||||
agent = AgentWorkflow.from_tools_or_functions(
|
|
||||||
tools,
|
|
||||||
llm=llm,
|
|
||||||
system_prompt=prompt,
|
|
||||||
)
|
|
||||||
ctx = Context(agent)
|
|
||||||
for query in queries:
|
|
||||||
response = await agent.run(user_msg=query, ctx=ctx)
|
|
||||||
print(f"---- {query} ----")
|
|
||||||
print(str(response))
|
|
||||||
|
|
||||||
asyncio.run(run_application())
|
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab header="Core" lang="python" >}}
|
{{< tab header="Core" lang="python" >}}
|
||||||
import asyncio
|
{{< include "quickstart/python/core/quickstart.py" >}}
|
||||||
|
|
||||||
from google import genai
|
|
||||||
from google.genai.types import (
|
|
||||||
Content,
|
|
||||||
FunctionDeclaration,
|
|
||||||
GenerateContentConfig,
|
|
||||||
Part,
|
|
||||||
Tool,
|
|
||||||
)
|
|
||||||
|
|
||||||
from toolbox_core import ToolboxClient
|
|
||||||
|
|
||||||
prompt = """
|
|
||||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
|
||||||
cancellations. When the user searches for a hotel, mention it's name, id,
|
|
||||||
location and price tier. Always mention hotel id while performing any
|
|
||||||
searches. This is very important for any operations. For any bookings or
|
|
||||||
cancellations, please provide the appropriate confirmation. Be sure to
|
|
||||||
update checkin or checkout dates if mentioned by the user.
|
|
||||||
Don't ask for confirmations from the user.
|
|
||||||
"""
|
|
||||||
|
|
||||||
queries = [
|
|
||||||
"Find hotels in Basel with Basel in its name.",
|
|
||||||
"Please book the hotel Hilton Basel for me.",
|
|
||||||
"This is too expensive. Please cancel it.",
|
|
||||||
"Please book Hyatt Regency for me",
|
|
||||||
"My check in dates for my booking would be from April 10, 2024 to April 19, 2024.",
|
|
||||||
]
|
|
||||||
|
|
||||||
async def run_application():
|
|
||||||
async with ToolboxClient("<http://127.0.0.1:5000>") as toolbox_client:
|
|
||||||
|
|
||||||
# The toolbox_tools list contains Python callables (functions/methods) designed for LLM tool-use
|
|
||||||
# integration. While this example uses Google's genai client, these callables can be adapted for
|
|
||||||
# various function-calling or agent frameworks. For easier integration with supported frameworks
|
|
||||||
# (https://github.com/googleapis/mcp-toolbox-python-sdk/tree/main/packages), use the
|
|
||||||
# provided wrapper packages, which handle framework-specific boilerplate.
|
|
||||||
toolbox_tools = await toolbox_client.load_toolset("my-toolset")
|
|
||||||
genai_client = genai.Client(
|
|
||||||
vertexai=True, project="project-id", location="us-central1"
|
|
||||||
)
|
|
||||||
|
|
||||||
genai_tools = [
|
|
||||||
Tool(
|
|
||||||
function_declarations=[
|
|
||||||
FunctionDeclaration.from_callable_with_api_option(callable=tool)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
for tool in toolbox_tools
|
|
||||||
]
|
|
||||||
history = []
|
|
||||||
for query in queries:
|
|
||||||
user_prompt_content = Content(
|
|
||||||
role="user",
|
|
||||||
parts=[Part.from_text(text=query)],
|
|
||||||
)
|
|
||||||
history.append(user_prompt_content)
|
|
||||||
|
|
||||||
response = genai_client.models.generate_content(
|
|
||||||
model="gemini-2.0-flash-001",
|
|
||||||
contents=history,
|
|
||||||
config=GenerateContentConfig(
|
|
||||||
system_instruction=prompt,
|
|
||||||
tools=genai_tools,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
history.append(response.candidates[0].content)
|
|
||||||
function_response_parts = []
|
|
||||||
for function_call in response.function_calls:
|
|
||||||
fn_name = function_call.name
|
|
||||||
# The tools are sorted alphabetically
|
|
||||||
if fn_name == "search-hotels-by-name":
|
|
||||||
function_result = await toolbox_tools[3](**function_call.args)
|
|
||||||
elif fn_name == "search-hotels-by-location":
|
|
||||||
function_result = await toolbox_tools[2](**function_call.args)
|
|
||||||
elif fn_name == "book-hotel":
|
|
||||||
function_result = await toolbox_tools[0](**function_call.args)
|
|
||||||
elif fn_name == "update-hotel":
|
|
||||||
function_result = await toolbox_tools[4](**function_call.args)
|
|
||||||
elif fn_name == "cancel-hotel":
|
|
||||||
function_result = await toolbox_tools[1](**function_call.args)
|
|
||||||
else:
|
|
||||||
raise ValueError("Function name not present.")
|
|
||||||
function_response = {"result": function_result}
|
|
||||||
function_response_part = Part.from_function_response(
|
|
||||||
name=function_call.name,
|
|
||||||
response=function_response,
|
|
||||||
)
|
|
||||||
function_response_parts.append(function_response_part)
|
|
||||||
|
|
||||||
if function_response_parts:
|
|
||||||
tool_response_content = Content(role="tool", parts=function_response_parts)
|
|
||||||
history.append(tool_response_content)
|
|
||||||
|
|
||||||
response2 = genai_client.models.generate_content(
|
|
||||||
model="gemini-2.0-flash-001",
|
|
||||||
contents=history,
|
|
||||||
config=GenerateContentConfig(
|
|
||||||
tools=genai_tools,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_model_response_content = response2.candidates[0].content
|
|
||||||
history.append(final_model_response_content)
|
|
||||||
print(response2.text)
|
|
||||||
|
|
||||||
asyncio.run(run_application())
|
|
||||||
|
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< /tabpane >}}
|
{{< /tabpane >}}
|
||||||
|
|
||||||
|
|||||||
@@ -13,266 +13,17 @@ This guide assumes you have already done the following:
|
|||||||
1. Installed [Go (v1.24.2 or higher)].
|
1. Installed [Go (v1.24.2 or higher)].
|
||||||
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
||||||
|
|
||||||
### Cloud Setup (Optional)
|
|
||||||
|
|
||||||
If you plan to use **Google Cloud’s Vertex AI** with your agent (e.g., using
|
|
||||||
Gemini or PaLM models), follow these one-time setup steps:
|
|
||||||
|
|
||||||
1. [Install the Google Cloud CLI]
|
|
||||||
1. [Set up Application Default Credentials (ADC)]
|
|
||||||
1. Set your project and enable Vertex AI
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gcloud config set project YOUR_PROJECT_ID
|
|
||||||
gcloud services enable aiplatform.googleapis.com
|
|
||||||
```
|
|
||||||
|
|
||||||
[Go (v1.24.2 or higher)]: https://go.dev/doc/install
|
[Go (v1.24.2 or higher)]: https://go.dev/doc/install
|
||||||
[install-postgres]: https://www.postgresql.org/download/
|
[install-postgres]: https://www.postgresql.org/download/
|
||||||
[Install the Google Cloud CLI]: https://cloud.google.com/sdk/docs/install
|
|
||||||
[Set up Application Default Credentials (ADC)]:
|
### Cloud Setup (Optional)
|
||||||
https://cloud.google.com/docs/authentication/set-up-adc-local-dev-environment
|
{{< snippet "local_quickstart.md" "cloud_setup" >}}
|
||||||
|
|
||||||
## Step 1: Set up your database
|
## Step 1: Set up your database
|
||||||
|
{{< snippet "local_quickstart.md" "database_setup" >}}
|
||||||
In this section, we will create a database, insert some data that needs to be
|
|
||||||
accessed by our agent, and create a database user for Toolbox to connect with.
|
|
||||||
|
|
||||||
1. Connect to postgres using the `psql` command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
psql -h 127.0.0.1 -U postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `postgres` denotes the default postgres superuser.
|
|
||||||
|
|
||||||
{{< notice info >}}
|
|
||||||
|
|
||||||
#### **Having trouble connecting?**
|
|
||||||
|
|
||||||
* **Password Prompt:** If you are prompted for a password for the `postgres`
|
|
||||||
user and do not know it (or a blank password doesn't work), your PostgreSQL
|
|
||||||
installation might require a password or a different authentication method.
|
|
||||||
* **`FATAL: role "postgres" does not exist`:** This error means the default
|
|
||||||
`postgres` superuser role isn't available under that name on your system.
|
|
||||||
* **`Connection refused`:** Ensure your PostgreSQL server is actually running.
|
|
||||||
You can typically check with `sudo systemctl status postgresql` and start it
|
|
||||||
with `sudo systemctl start postgresql` on Linux systems.
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
#### **Common Solution**
|
|
||||||
|
|
||||||
For password issues or if the `postgres` role seems inaccessible directly, try
|
|
||||||
switching to the `postgres` operating system user first. This user often has
|
|
||||||
permission to connect without a password for local connections (this is called
|
|
||||||
peer authentication).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo -i -u postgres
|
|
||||||
psql -h 127.0.0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you are in the `psql` shell using this method, you can proceed with the
|
|
||||||
database creation steps below. Afterwards, type `\q` to exit `psql`, and then
|
|
||||||
`exit` to return to your normal user shell.
|
|
||||||
|
|
||||||
If desired, once connected to `psql` as the `postgres` OS user, you can set a
|
|
||||||
password for the `postgres` *database* user using: `ALTER USER postgres WITH
|
|
||||||
PASSWORD 'your_chosen_password';`. This would allow direct connection with `-U
|
|
||||||
postgres` and a password next time.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
1. Create a new database and a new user:
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
For a real application, it's best to follow the principle of least permission
|
|
||||||
and only grant the privileges your application needs.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE USER toolbox_user WITH PASSWORD 'my-password';
|
|
||||||
|
|
||||||
CREATE DATABASE toolbox_db;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE toolbox_db TO toolbox_user;
|
|
||||||
|
|
||||||
ALTER DATABASE toolbox_db OWNER TO toolbox_user;
|
|
||||||
```
|
|
||||||
|
|
||||||
1. End the database session:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
(If you used `sudo -i -u postgres` and then `psql`, remember you might also
|
|
||||||
need to type `exit` after `\q` to leave the `postgres` user's shell
|
|
||||||
session.)
|
|
||||||
|
|
||||||
1. Connect to your database with your new user:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
psql -h 127.0.0.1 -U toolbox_user -d toolbox_db
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Create a table using the following command:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE hotels(
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
name VARCHAR NOT NULL,
|
|
||||||
location VARCHAR NOT NULL,
|
|
||||||
price_tier VARCHAR NOT NULL,
|
|
||||||
checkin_date DATE NOT NULL,
|
|
||||||
checkout_date DATE NOT NULL,
|
|
||||||
booked BIT NOT NULL
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Insert data into the table.
|
|
||||||
|
|
||||||
```sql
|
|
||||||
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
|
|
||||||
VALUES
|
|
||||||
(1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-22', '2024-04-20', B'0'),
|
|
||||||
(2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', B'0'),
|
|
||||||
(3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', B'0'),
|
|
||||||
(4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-24', '2024-04-05', B'0'),
|
|
||||||
(5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-23', '2024-04-01', B'0'),
|
|
||||||
(6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', B'0'),
|
|
||||||
(7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-27', '2024-04-02', B'0'),
|
|
||||||
(8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-24', '2024-04-09', B'0'),
|
|
||||||
(9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', B'0'),
|
|
||||||
(10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', B'0');
|
|
||||||
```
|
|
||||||
|
|
||||||
1. End the database session:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 2: Install and configure Toolbox
|
## Step 2: Install and configure Toolbox
|
||||||
|
{{< snippet "local_quickstart.md" "configure_toolbox" >}}
|
||||||
In this section, we will download Toolbox, configure our tools in a
|
|
||||||
`tools.yaml`, and then run the Toolbox server.
|
|
||||||
|
|
||||||
1. Download the latest version of Toolbox as a binary:
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
Select the
|
|
||||||
[correct binary](https://github.com/googleapis/genai-toolbox/releases)
|
|
||||||
corresponding to your OS and CPU architecture.
|
|
||||||
{{< /notice >}}
|
|
||||||
<!-- {x-release-please-start-version} -->
|
|
||||||
```bash
|
|
||||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
|
||||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.12.0/$OS/toolbox
|
|
||||||
```
|
|
||||||
<!-- {x-release-please-end} -->
|
|
||||||
|
|
||||||
1. Make the binary executable:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x toolbox
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Write the following into a `tools.yaml` file. Be sure to update any fields
|
|
||||||
such as `user`, `password`, or `database` that you may have customized in the
|
|
||||||
previous step.
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
In practice, use environment variable replacement with the format ${ENV_NAME}
|
|
||||||
instead of hardcoding your secrets into the configuration file.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
sources:
|
|
||||||
my-pg-source:
|
|
||||||
kind: postgres
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 5432
|
|
||||||
database: toolbox_db
|
|
||||||
user: ${USER_NAME}
|
|
||||||
password: ${PASSWORD}
|
|
||||||
tools:
|
|
||||||
search-hotels-by-name:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on name.
|
|
||||||
parameters:
|
|
||||||
- name: name
|
|
||||||
type: string
|
|
||||||
description: The name of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
|
||||||
search-hotels-by-location:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on location.
|
|
||||||
parameters:
|
|
||||||
- name: location
|
|
||||||
type: string
|
|
||||||
description: The location of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
|
||||||
book-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to book.
|
|
||||||
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
|
||||||
update-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
|
||||||
indicating whether the hotel was successfully updated or not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to update.
|
|
||||||
- name: checkin_date
|
|
||||||
type: string
|
|
||||||
description: The new check-in date of the hotel.
|
|
||||||
- name: checkout_date
|
|
||||||
type: string
|
|
||||||
description: The new check-out date of the hotel.
|
|
||||||
statement: >-
|
|
||||||
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
|
||||||
as date) WHERE id = $1;
|
|
||||||
cancel-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Cancel a hotel by its ID.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to cancel.
|
|
||||||
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
|
||||||
toolsets:
|
|
||||||
my-toolset:
|
|
||||||
- search-hotels-by-name
|
|
||||||
- search-hotels-by-location
|
|
||||||
- book-hotel
|
|
||||||
- update-hotel
|
|
||||||
- cancel-hotel
|
|
||||||
```
|
|
||||||
|
|
||||||
For more info on tools, check out the `Resources` section of the docs.
|
|
||||||
|
|
||||||
1. Run the Toolbox server, pointing to the `tools.yaml` file created earlier:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./toolbox --tools-file "tools.yaml"
|
|
||||||
```
|
|
||||||
|
|
||||||
{{< notice note >}}
|
|
||||||
Toolbox enables dynamic reloading by default. To disable, use the
|
|
||||||
`--disable-reload` flag.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
## Step 3: Connect your agent to Toolbox
|
## Step 3: Connect your agent to Toolbox
|
||||||
|
|
||||||
|
|||||||
@@ -13,265 +13,19 @@ This guide assumes you have already done the following:
|
|||||||
1. Installed [Node.js (v18 or higher)].
|
1. Installed [Node.js (v18 or higher)].
|
||||||
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
||||||
|
|
||||||
### Cloud Setup (Optional)
|
|
||||||
|
|
||||||
If you plan to use **Google Cloud’s Vertex AI** with your agent (e.g., using
|
|
||||||
Gemini or PaLM models), follow these one-time setup steps:
|
|
||||||
|
|
||||||
1. [Install the Google Cloud CLI]
|
|
||||||
1. [Set up Application Default Credentials (ADC)]
|
|
||||||
1. Set your project and enable Vertex AI
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gcloud config set project YOUR_PROJECT_ID
|
|
||||||
gcloud services enable aiplatform.googleapis.com
|
|
||||||
```
|
|
||||||
|
|
||||||
[Node.js (v18 or higher)]: https://nodejs.org/
|
[Node.js (v18 or higher)]: https://nodejs.org/
|
||||||
[install-postgres]: https://www.postgresql.org/download/
|
[install-postgres]: https://www.postgresql.org/download/
|
||||||
[Install the Google Cloud CLI]: https://cloud.google.com/sdk/docs/install
|
|
||||||
[Set up Application Default Credentials (ADC)]:
|
### Cloud Setup (Optional)
|
||||||
https://cloud.google.com/docs/authentication/set-up-adc-local-dev-environment
|
{{< snippet "local_quickstart.md" "cloud_setup" >}}
|
||||||
|
|
||||||
|
{{< snippet "test.py" "demo" "py" >}}
|
||||||
|
|
||||||
## Step 1: Set up your database
|
## Step 1: Set up your database
|
||||||
|
{{< snippet "local_quickstart.md" "database_setup" >}}
|
||||||
In this section, we will create a database, insert some data that needs to be
|
|
||||||
accessed by our agent, and create a database user for Toolbox to connect with.
|
|
||||||
|
|
||||||
1. Connect to postgres using the `psql` command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
psql -h 127.0.0.1 -U postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `postgres` denotes the default postgres superuser.
|
|
||||||
|
|
||||||
{{< notice info >}}
|
|
||||||
|
|
||||||
#### **Having trouble connecting?**
|
|
||||||
|
|
||||||
* **Password Prompt:** If you are prompted for a password for the `postgres`
|
|
||||||
user and do not know it (or a blank password doesn't work), your PostgreSQL
|
|
||||||
installation might require a password or a different authentication method.
|
|
||||||
* **`FATAL: role "postgres" does not exist`:** This error means the default
|
|
||||||
`postgres` superuser role isn't available under that name on your system.
|
|
||||||
* **`Connection refused`:** Ensure your PostgreSQL server is actually running.
|
|
||||||
You can typically check with `sudo systemctl status postgresql` and start it
|
|
||||||
with `sudo systemctl start postgresql` on Linux systems.
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
#### **Common Solution**
|
|
||||||
|
|
||||||
For password issues or if the `postgres` role seems inaccessible directly, try
|
|
||||||
switching to the `postgres` operating system user first. This user often has
|
|
||||||
permission to connect without a password for local connections (this is called
|
|
||||||
peer authentication).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo -i -u postgres
|
|
||||||
psql -h 127.0.0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you are in the `psql` shell using this method, you can proceed with the
|
|
||||||
database creation steps below. Afterwards, type `\q` to exit `psql`, and then
|
|
||||||
`exit` to return to your normal user shell.
|
|
||||||
|
|
||||||
If desired, once connected to `psql` as the `postgres` OS user, you can set a
|
|
||||||
password for the `postgres` *database* user using: `ALTER USER postgres WITH
|
|
||||||
PASSWORD 'your_chosen_password';`. This would allow direct connection with `-U
|
|
||||||
postgres` and a password next time.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
1. Create a new database and a new user:
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
For a real application, it's best to follow the principle of least permission
|
|
||||||
and only grant the privileges your application needs.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE USER toolbox_user WITH PASSWORD 'my-password';
|
|
||||||
|
|
||||||
CREATE DATABASE toolbox_db;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE toolbox_db TO toolbox_user;
|
|
||||||
|
|
||||||
ALTER DATABASE toolbox_db OWNER TO toolbox_user;
|
|
||||||
```
|
|
||||||
|
|
||||||
1. End the database session:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
(If you used `sudo -i -u postgres` and then `psql`, remember you might also
|
|
||||||
need to type `exit` after `\q` to leave the `postgres` user's shell
|
|
||||||
session.)
|
|
||||||
|
|
||||||
1. Connect to your database with your new user:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
psql -h 127.0.0.1 -U toolbox_user -d toolbox_db
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Create a table using the following command:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE hotels(
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
name VARCHAR NOT NULL,
|
|
||||||
location VARCHAR NOT NULL,
|
|
||||||
price_tier VARCHAR NOT NULL,
|
|
||||||
checkin_date DATE NOT NULL,
|
|
||||||
checkout_date DATE NOT NULL,
|
|
||||||
booked BIT NOT NULL
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Insert data into the table.
|
|
||||||
|
|
||||||
```sql
|
|
||||||
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
|
|
||||||
VALUES
|
|
||||||
(1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-22', '2024-04-20', B'0'),
|
|
||||||
(2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', B'0'),
|
|
||||||
(3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', B'0'),
|
|
||||||
(4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-24', '2024-04-05', B'0'),
|
|
||||||
(5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-23', '2024-04-01', B'0'),
|
|
||||||
(6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', B'0'),
|
|
||||||
(7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-27', '2024-04-02', B'0'),
|
|
||||||
(8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-24', '2024-04-09', B'0'),
|
|
||||||
(9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', B'0'),
|
|
||||||
(10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', B'0');
|
|
||||||
```
|
|
||||||
|
|
||||||
1. End the database session:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 2: Install and configure Toolbox
|
## Step 2: Install and configure Toolbox
|
||||||
|
{{< snippet "local_quickstart.md" "configure_toolbox" >}}
|
||||||
In this section, we will download Toolbox, configure our tools in a
|
|
||||||
`tools.yaml`, and then run the Toolbox server.
|
|
||||||
|
|
||||||
1. Download the latest version of Toolbox as a binary:
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
Select the
|
|
||||||
[correct binary](https://github.com/googleapis/genai-toolbox/releases)
|
|
||||||
corresponding to your OS and CPU architecture.
|
|
||||||
{{< /notice >}}
|
|
||||||
<!-- {x-release-please-start-version} -->
|
|
||||||
```bash
|
|
||||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
|
||||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.12.0/$OS/toolbox
|
|
||||||
```
|
|
||||||
<!-- {x-release-please-end} -->
|
|
||||||
|
|
||||||
1. Make the binary executable:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x toolbox
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Write the following into a `tools.yaml` file. Be sure to update any fields
|
|
||||||
such as `user`, `password`, or `database` that you may have customized in the
|
|
||||||
previous step.
|
|
||||||
|
|
||||||
{{< notice tip >}}
|
|
||||||
In practice, use environment variable replacement with the format ${ENV_NAME}
|
|
||||||
instead of hardcoding your secrets into the configuration file.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
sources:
|
|
||||||
my-pg-source:
|
|
||||||
kind: postgres
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 5432
|
|
||||||
database: toolbox_db
|
|
||||||
user: ${USER_NAME}
|
|
||||||
password: ${PASSWORD}
|
|
||||||
tools:
|
|
||||||
search-hotels-by-name:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on name.
|
|
||||||
parameters:
|
|
||||||
- name: name
|
|
||||||
type: string
|
|
||||||
description: The name of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
|
||||||
search-hotels-by-location:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on location.
|
|
||||||
parameters:
|
|
||||||
- name: location
|
|
||||||
type: string
|
|
||||||
description: The location of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
|
||||||
book-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to book.
|
|
||||||
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
|
||||||
update-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
|
||||||
indicating whether the hotel was successfully updated or not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to update.
|
|
||||||
- name: checkin_date
|
|
||||||
type: string
|
|
||||||
description: The new check-in date of the hotel.
|
|
||||||
- name: checkout_date
|
|
||||||
type: string
|
|
||||||
description: The new check-out date of the hotel.
|
|
||||||
statement: >-
|
|
||||||
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
|
||||||
as date) WHERE id = $1;
|
|
||||||
cancel-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Cancel a hotel by its ID.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to cancel.
|
|
||||||
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
|
||||||
toolsets:
|
|
||||||
my-toolset:
|
|
||||||
- search-hotels-by-name
|
|
||||||
- search-hotels-by-location
|
|
||||||
- book-hotel
|
|
||||||
- update-hotel
|
|
||||||
- cancel-hotel
|
|
||||||
```
|
|
||||||
|
|
||||||
For more info on tools, check out the `Resources` section of the docs.
|
|
||||||
|
|
||||||
1. Run the Toolbox server, pointing to the `tools.yaml` file created earlier:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./toolbox --tools-file "tools.yaml"
|
|
||||||
```
|
|
||||||
|
|
||||||
{{< notice note >}}
|
|
||||||
Toolbox enables dynamic reloading by default. To disable, use the `--disable-reload` flag.
|
|
||||||
{{< /notice >}}
|
|
||||||
|
|
||||||
## Step 3: Connect your agent to Toolbox
|
## Step 3: Connect your agent to Toolbox
|
||||||
|
|
||||||
|
|||||||
70
docs/en/getting-started/quickstart/python/adk/quickstart.py
Normal file
70
docs/en/getting-started/quickstart/python/adk/quickstart.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
from google.adk.agents import Agent
|
||||||
|
from google.adk.runners import Runner
|
||||||
|
from google.adk.sessions import InMemorySessionService
|
||||||
|
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
|
||||||
|
from google.genai import types
|
||||||
|
from toolbox_core import ToolboxSyncClient
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
|
||||||
|
# TODO(developer): replace this with your Google API key
|
||||||
|
|
||||||
|
os.environ['GOOGLE_API_KEY'] = 'your-api-key'
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
with ToolboxSyncClient("<http://127.0.0.1:5000>") as toolbox_client:
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||||
|
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||||
|
location and price tier. Always mention hotel ids while performing any
|
||||||
|
searches. This is very important for any operations. For any bookings or
|
||||||
|
cancellations, please provide the appropriate confirmation. Be sure to
|
||||||
|
update checkin or checkout dates if mentioned by the user.
|
||||||
|
Don't ask for confirmations from the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
root_agent = Agent(
|
||||||
|
model='gemini-2.0-flash-001',
|
||||||
|
name='hotel_agent',
|
||||||
|
description='A helpful AI assistant.',
|
||||||
|
instruction=prompt,
|
||||||
|
tools=toolbox_client.load_toolset("my-toolset"),
|
||||||
|
)
|
||||||
|
|
||||||
|
session_service = InMemorySessionService()
|
||||||
|
artifacts_service = InMemoryArtifactService()
|
||||||
|
session = await session_service.create_session(
|
||||||
|
state={}, app_name='hotel_agent', user_id='123'
|
||||||
|
)
|
||||||
|
runner = Runner(
|
||||||
|
app_name='hotel_agent',
|
||||||
|
agent=root_agent,
|
||||||
|
artifact_service=artifacts_service,
|
||||||
|
session_service=session_service,
|
||||||
|
)
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
"Find hotels in Basel with Basel in its name.",
|
||||||
|
"Can you book the Hilton Basel for me?",
|
||||||
|
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
||||||
|
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
||||||
|
]
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
content = types.Content(role='user', parts=[types.Part(text=query)])
|
||||||
|
events = runner.run(session_id=session.id,
|
||||||
|
user_id='123', new_message=content)
|
||||||
|
|
||||||
|
responses = (
|
||||||
|
part.text
|
||||||
|
for event in events
|
||||||
|
for part in event.content.parts
|
||||||
|
if part.text is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
for text in responses:
|
||||||
|
print(text)
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
108
docs/en/getting-started/quickstart/python/core/quickstart.py
Normal file
108
docs/en/getting-started/quickstart/python/core/quickstart.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
from google import genai
|
||||||
|
from google.genai.types import (
|
||||||
|
Content,
|
||||||
|
FunctionDeclaration,
|
||||||
|
GenerateContentConfig,
|
||||||
|
Part,
|
||||||
|
Tool,
|
||||||
|
)
|
||||||
|
|
||||||
|
from toolbox_core import ToolboxClient
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||||
|
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||||
|
location and price tier. Always mention hotel id while performing any
|
||||||
|
searches. This is very important for any operations. For any bookings or
|
||||||
|
cancellations, please provide the appropriate confirmation. Be sure to
|
||||||
|
update checkin or checkout dates if mentioned by the user.
|
||||||
|
Don't ask for confirmations from the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
"Find hotels in Basel with Basel in its name.",
|
||||||
|
"Please book the hotel Hilton Basel for me.",
|
||||||
|
"This is too expensive. Please cancel it.",
|
||||||
|
"Please book Hyatt Regency for me",
|
||||||
|
"My check in dates for my booking would be from April 10, 2024 to April 19, 2024.",
|
||||||
|
]
|
||||||
|
|
||||||
|
async def run_application():
|
||||||
|
async with ToolboxClient("<http://127.0.0.1:5000>") as toolbox_client:
|
||||||
|
|
||||||
|
# The toolbox_tools list contains Python callables (functions/methods) designed for LLM tool-use
|
||||||
|
# integration. While this example uses Google's genai client, these callables can be adapted for
|
||||||
|
# various function-calling or agent frameworks. For easier integration with supported frameworks
|
||||||
|
# (https://github.com/googleapis/mcp-toolbox-python-sdk/tree/main/packages), use the
|
||||||
|
# provided wrapper packages, which handle framework-specific boilerplate.
|
||||||
|
toolbox_tools = await toolbox_client.load_toolset("my-toolset")
|
||||||
|
genai_client = genai.Client(
|
||||||
|
vertexai=True, project="project-id", location="us-central1"
|
||||||
|
)
|
||||||
|
|
||||||
|
genai_tools = [
|
||||||
|
Tool(
|
||||||
|
function_declarations=[
|
||||||
|
FunctionDeclaration.from_callable_with_api_option(callable=tool)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for tool in toolbox_tools
|
||||||
|
]
|
||||||
|
history = []
|
||||||
|
for query in queries:
|
||||||
|
user_prompt_content = Content(
|
||||||
|
role="user",
|
||||||
|
parts=[Part.from_text(text=query)],
|
||||||
|
)
|
||||||
|
history.append(user_prompt_content)
|
||||||
|
|
||||||
|
response = genai_client.models.generate_content(
|
||||||
|
model="gemini-2.0-flash-001",
|
||||||
|
contents=history,
|
||||||
|
config=GenerateContentConfig(
|
||||||
|
system_instruction=prompt,
|
||||||
|
tools=genai_tools,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
history.append(response.candidates[0].content)
|
||||||
|
function_response_parts = []
|
||||||
|
for function_call in response.function_calls:
|
||||||
|
fn_name = function_call.name
|
||||||
|
# The tools are sorted alphabetically
|
||||||
|
if fn_name == "search-hotels-by-name":
|
||||||
|
function_result = await toolbox_tools[3](**function_call.args)
|
||||||
|
elif fn_name == "search-hotels-by-location":
|
||||||
|
function_result = await toolbox_tools[2](**function_call.args)
|
||||||
|
elif fn_name == "book-hotel":
|
||||||
|
function_result = await toolbox_tools[0](**function_call.args)
|
||||||
|
elif fn_name == "update-hotel":
|
||||||
|
function_result = await toolbox_tools[4](**function_call.args)
|
||||||
|
elif fn_name == "cancel-hotel":
|
||||||
|
function_result = await toolbox_tools[1](**function_call.args)
|
||||||
|
else:
|
||||||
|
raise ValueError("Function name not present.")
|
||||||
|
function_response = {"result": function_result}
|
||||||
|
function_response_part = Part.from_function_response(
|
||||||
|
name=function_call.name,
|
||||||
|
response=function_response,
|
||||||
|
)
|
||||||
|
function_response_parts.append(function_response_part)
|
||||||
|
|
||||||
|
if function_response_parts:
|
||||||
|
tool_response_content = Content(role="tool", parts=function_response_parts)
|
||||||
|
history.append(tool_response_content)
|
||||||
|
|
||||||
|
response2 = genai_client.models.generate_content(
|
||||||
|
model="gemini-2.0-flash-001",
|
||||||
|
contents=history,
|
||||||
|
config=GenerateContentConfig(
|
||||||
|
tools=genai_tools,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
final_model_response_content = response2.candidates[0].content
|
||||||
|
history.append(final_model_response_content)
|
||||||
|
print(response2.text)
|
||||||
|
|
||||||
|
asyncio.run(run_application())
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
from langgraph.prebuilt import create_react_agent
|
||||||
|
|
||||||
|
# TODO(developer): replace this with another import if needed
|
||||||
|
|
||||||
|
from langchain_google_vertexai import ChatVertexAI
|
||||||
|
|
||||||
|
# from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
|
|
||||||
|
# from langchain_anthropic import ChatAnthropic
|
||||||
|
|
||||||
|
from langgraph.checkpoint.memory import MemorySaver
|
||||||
|
|
||||||
|
from toolbox_langchain import ToolboxClient
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||||
|
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||||
|
location and price tier. Always mention hotel ids while performing any
|
||||||
|
searches. This is very important for any operations. For any bookings or
|
||||||
|
cancellations, please provide the appropriate confirmation. Be sure to
|
||||||
|
update checkin or checkout dates if mentioned by the user.
|
||||||
|
Don't ask for confirmations from the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
"Find hotels in Basel with Basel in its name.",
|
||||||
|
"Can you book the Hilton Basel for me?",
|
||||||
|
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
||||||
|
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
||||||
|
]
|
||||||
|
|
||||||
|
async def run_application():
|
||||||
|
# TODO(developer): replace this with another model if needed
|
||||||
|
model = ChatVertexAI(model_name="gemini-2.0-flash-001")
|
||||||
|
# model = ChatGoogleGenerativeAI(model="gemini-2.0-flash-001")
|
||||||
|
# model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
|
||||||
|
|
||||||
|
# Load the tools from the Toolbox server
|
||||||
|
async with ToolboxClient("http://127.0.0.1:5000") as client:
|
||||||
|
tools = await client.aload_toolset()
|
||||||
|
|
||||||
|
agent = create_react_agent(model, tools, checkpointer=MemorySaver())
|
||||||
|
|
||||||
|
config = {"configurable": {"thread_id": "thread-1"}}
|
||||||
|
for query in queries:
|
||||||
|
inputs = {"messages": [("user", prompt + query)]}
|
||||||
|
response = agent.invoke(inputs, stream_mode="values", config=config)
|
||||||
|
print(response["messages"][-1].content)
|
||||||
|
|
||||||
|
asyncio.run(run_application())
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
|
||||||
|
from llama_index.core.agent.workflow import AgentWorkflow
|
||||||
|
|
||||||
|
from llama_index.core.workflow import Context
|
||||||
|
|
||||||
|
# TODO(developer): replace this with another import if needed
|
||||||
|
|
||||||
|
from llama_index.llms.google_genai import GoogleGenAI
|
||||||
|
|
||||||
|
# from llama_index.llms.anthropic import Anthropic
|
||||||
|
|
||||||
|
from toolbox_llamaindex import ToolboxClient
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||||
|
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||||
|
location and price tier. Always mention hotel ids while performing any
|
||||||
|
searches. This is very important for any operations. For any bookings or
|
||||||
|
cancellations, please provide the appropriate confirmation. Be sure to
|
||||||
|
update checkin or checkout dates if mentioned by the user.
|
||||||
|
Don't ask for confirmations from the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
"Find hotels in Basel with Basel in its name.",
|
||||||
|
"Can you book the Hilton Basel for me?",
|
||||||
|
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
||||||
|
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
||||||
|
]
|
||||||
|
|
||||||
|
async def run_application():
|
||||||
|
# TODO(developer): replace this with another model if needed
|
||||||
|
llm = GoogleGenAI(
|
||||||
|
model="gemini-2.0-flash-001",
|
||||||
|
vertexai_config={"project": "project-id", "location": "us-central1"},
|
||||||
|
)
|
||||||
|
# llm = GoogleGenAI(
|
||||||
|
# api_key=os.getenv("GOOGLE_API_KEY"),
|
||||||
|
# model="gemini-2.0-flash-001",
|
||||||
|
# )
|
||||||
|
# llm = Anthropic(
|
||||||
|
# model="claude-3-7-sonnet-latest",
|
||||||
|
# api_key=os.getenv("ANTHROPIC_API_KEY")
|
||||||
|
# )
|
||||||
|
|
||||||
|
# Load the tools from the Toolbox server
|
||||||
|
async with ToolboxClient("http://127.0.0.1:5000") as client:
|
||||||
|
tools = await client.aload_toolset()
|
||||||
|
|
||||||
|
agent = AgentWorkflow.from_tools_or_functions(
|
||||||
|
tools,
|
||||||
|
llm=llm,
|
||||||
|
system_prompt=prompt,
|
||||||
|
)
|
||||||
|
ctx = Context(agent)
|
||||||
|
for query in queries:
|
||||||
|
response = await agent.run(user_msg=query, ctx=ctx)
|
||||||
|
print(f"---- {query} ----")
|
||||||
|
print(str(response))
|
||||||
|
|
||||||
|
asyncio.run(run_application())
|
||||||
8
docs/en/getting-started/test.py
Normal file
8
docs/en/getting-started/test.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# [START demo]
|
||||||
|
a = 5
|
||||||
|
b = 6
|
||||||
|
# print('hello' + c)
|
||||||
|
print ('This file is used for demo of include shortcodes')
|
||||||
|
# [END demo]
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user