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

feat: Add orm for Tools and clean up Tool logic #1935

Merged
merged 36 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
de1bade
wip
mattzh72 Oct 24, 2024
7c373e9
wip
mattzh72 Oct 24, 2024
744f2ca
get unit tests working
mattzh72 Oct 24, 2024
2bb8631
Finish
mattzh72 Oct 24, 2024
136b932
Fix broken server tests
mattzh72 Oct 24, 2024
d119240
Merge main
mattzh72 Oct 24, 2024
66d320b
Add flag to initialize with default user
mattzh72 Oct 24, 2024
b65ea79
Fix cli tests
mattzh72 Oct 24, 2024
4c61b4b
Fix some more bugs
mattzh72 Oct 24, 2024
20bb95d
Reorganize tests and fix failing tests
mattzh72 Oct 24, 2024
82cc24d
Adjust cli test
mattzh72 Oct 24, 2024
0d1747a
Adjust timeout for cli tests
mattzh72 Oct 24, 2024
6dfbcb2
Separate out cli tests bc of env issues
mattzh72 Oct 24, 2024
32c3efd
Separate out cli tests bc of env issues
mattzh72 Oct 24, 2024
eb85ca7
Merge branch 'main' into matt-add-tool-orm
mattzh72 Oct 24, 2024
d8ba52c
Fix o1 agent test
mattzh72 Oct 24, 2024
334c5cc
Fix o1 agent test
mattzh72 Oct 24, 2024
6713b1e
fix tests
mattzh72 Oct 24, 2024
50b1229
rename and add to workflow step
mattzh72 Oct 24, 2024
3f33f30
Update examples
mattzh72 Oct 24, 2024
54fb2f3
rework default tool adding
mattzh72 Oct 24, 2024
8fcd25e
Modify test server
mattzh72 Oct 24, 2024
5928166
Reset tools
mattzh72 Oct 25, 2024
6ede837
Refactor
mattzh72 Oct 25, 2024
843e74c
Fix endpoints test
mattzh72 Oct 25, 2024
85b9f7d
Fix gpt4 test
mattzh72 Oct 25, 2024
b870ca4
Fix load default tool functions
mattzh72 Oct 25, 2024
392f020
Refactor out constants
mattzh72 Oct 25, 2024
75497d7
More refactor
mattzh72 Oct 25, 2024
54a9a2d
Remove hanging DEFAULT_USER_ID
mattzh72 Oct 25, 2024
4cec87e
Remove circular imports
mattzh72 Oct 25, 2024
ea7d247
Respond to comments
mattzh72 Oct 25, 2024
3fa34b4
Refactor hard to understand code
mattzh72 Oct 25, 2024
2f56d23
Add back admin user routes"
mattzh72 Oct 25, 2024
eb257e7
rename endpoint
mattzh72 Oct 25, 2024
7425513
rename endpoint pt2
mattzh72 Oct 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions .github/workflows/code_style_checks.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
name: Code Style Checks

on:
push:
branches: [ main ]
pull_request:
paths:
- '**.py'
pull_request_target:
types:
- opened
- edited
- synchronize
workflow_dispatch:

permissions:
pull-requests: read
branches: [ main ]

jobs:
validation-checks:
style-checks:
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_cli.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run CLI tests
name: Test CLI

env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Expand All @@ -10,7 +10,7 @@ on:
branches: [ main ]

jobs:
test:
test-cli:
runs-on: ubuntu-latest
timeout-minutes: 15

Expand Down
39 changes: 36 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run All pytest Tests
name: Unit Tests

env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Expand All @@ -13,7 +13,7 @@ on:
branches: [ main ]

jobs:
test:
unit-tests:
runs-on: ubuntu-latest
timeout-minutes: 15

Expand All @@ -37,6 +37,28 @@ jobs:
poetry-version: "1.8.2"
install-args: "-E dev -E postgres -E milvus -E external-tools -E tests"

- name: Run LocalClient tests
env:
LETTA_PG_PORT: 8888
LETTA_PG_USER: letta
LETTA_PG_PASSWORD: letta
LETTA_PG_DB: letta
LETTA_PG_HOST: localhost
LETTA_SERVER_PASS: test_server_token
run: |
poetry run pytest -s -vv tests/test_local_client.py

- name: Run RESTClient tests
env:
LETTA_PG_PORT: 8888
LETTA_PG_USER: letta
LETTA_PG_PASSWORD: letta
LETTA_PG_DB: letta
LETTA_PG_HOST: localhost
LETTA_SERVER_PASS: test_server_token
run: |
poetry run pytest -s -vv tests/test_client.py

- name: Run server tests
env:
LETTA_PG_PORT: 8888
Expand Down Expand Up @@ -70,6 +92,17 @@ jobs:
run: |
poetry run pytest -s -vv tests/test_tools.py

- name: Run o1 agent tests
env:
LETTA_PG_PORT: 8888
LETTA_PG_USER: letta
LETTA_PG_PASSWORD: letta
LETTA_PG_DB: letta
LETTA_PG_HOST: localhost
LETTA_SERVER_PASS: test_server_token
run: |
poetry run pytest -s -vv tests/test_o1_agent.py

- name: Run tests with pytest
env:
LETTA_PG_PORT: 8888
Expand All @@ -80,4 +113,4 @@ jobs:
LETTA_SERVER_PASS: test_server_token
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
run: |
poetry run pytest -s -vv -k "not test_cli.py and not test_tools.py and not test_concurrent_connections.py and not test_quickstart and not test_endpoints and not test_storage and not test_server and not test_openai_client and not test_providers" tests
poetry run pytest -s -vv -k "not test_local_client.py and not test_o1_agent.py and not test_cli.py and not test_tools.py and not test_concurrent_connections.py and not test_quickstart and not test_endpoints and not test_storage and not test_server and not test_openai_client and not test_providers and not test_client.py" tests
6 changes: 1 addition & 5 deletions examples/composio_tool_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from letta.schemas.embedding_config import EmbeddingConfig
from letta.schemas.llm_config import LLMConfig
from letta.schemas.memory import ChatMemory
from letta.schemas.tool import Tool

"""
Setup here.
Expand Down Expand Up @@ -46,13 +45,10 @@


def main():
from composio_langchain import Action

Check failure on line 48 in examples/composio_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "composio_langchain" could not be resolved (reportMissingImports)

Check failure on line 48 in examples/composio_tool_usage.py

View workflow job for this annotation

GitHub Actions / style-checks (3.12)

Import "composio_langchain" could not be resolved (reportMissingImports)

Check failure on line 48 in examples/composio_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "composio_langchain" could not be resolved (reportMissingImports)

# Add the composio tool
tool = Tool.get_composio_tool(action=Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER)

# create tool
client.add_tool(tool)
tool = client.load_composio_tool(action=Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER)

persona = f"""
My name is Letta.
Expand Down
11 changes: 6 additions & 5 deletions examples/crewai_tool_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import uuid

from letta import create_client
from letta.schemas.embedding_config import EmbeddingConfig
from letta.schemas.llm_config import LLMConfig
from letta.schemas.memory import ChatMemory
from letta.schemas.tool import Tool

"""
This example show how you can add CrewAI tools .
Expand All @@ -17,18 +18,18 @@


def main():
from crewai_tools import ScrapeWebsiteTool

Check failure on line 21 in examples/crewai_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "crewai_tools" could not be resolved (reportMissingImports)

Check failure on line 21 in examples/crewai_tool_usage.py

View workflow job for this annotation

GitHub Actions / style-checks (3.12)

Import "crewai_tools" could not be resolved (reportMissingImports)

Check failure on line 21 in examples/crewai_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "crewai_tools" could not be resolved (reportMissingImports)

crewai_tool = ScrapeWebsiteTool(website_url="https://www.example.com")

example_website_scrape_tool = Tool.from_crewai(crewai_tool)
tool_name = example_website_scrape_tool.name

# Create a `LocalClient` (you can also use a `RESTClient`, see the letta_rest_client.py example)
client = create_client()
client.set_default_llm_config(LLMConfig.default_config("gpt-4o-mini"))
client.set_default_embedding_config(EmbeddingConfig.default_config(provider="openai"))

# create tool
client.add_tool(example_website_scrape_tool)
example_website_scrape_tool = client.load_crewai_tool(crewai_tool)
tool_name = example_website_scrape_tool.name

# Confirm that the tool is in
tools = client.list_tools()
Expand Down
18 changes: 7 additions & 11 deletions examples/langchain_tool_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from letta.schemas.embedding_config import EmbeddingConfig
from letta.schemas.llm_config import LLMConfig
from letta.schemas.memory import ChatMemory
from letta.schemas.tool import Tool

"""
This example show how you can add LangChain tools .
Expand All @@ -20,32 +19,29 @@


def main():
from langchain_community.tools import WikipediaQueryRun

Check failure on line 22 in examples/langchain_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "langchain_community.tools" could not be resolved (reportMissingImports)

Check failure on line 22 in examples/langchain_tool_usage.py

View workflow job for this annotation

GitHub Actions / style-checks (3.12)

Import "langchain_community.tools" could not be resolved (reportMissingImports)

Check failure on line 22 in examples/langchain_tool_usage.py

View workflow job for this annotation

GitHub Actions / validation-checks (3.12)

Import "langchain_community.tools" could not be resolved (reportMissingImports)
from langchain_community.utilities import WikipediaAPIWrapper

api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=500)
langchain_tool = WikipediaQueryRun(api_wrapper=api_wrapper)

# Translate to memGPT Tool
# Create a `LocalClient` (you can also use a `RESTClient`, see the letta_rest_client.py example)
client = create_client()
client.set_default_llm_config(LLMConfig.default_config("gpt-4o-mini"))
client.set_default_embedding_config(EmbeddingConfig.default_config(provider="openai"))

# create tool
# Note the additional_imports_module_attr_map
# We need to pass in a map of all the additional imports necessary to run this tool
# Because an object of type WikipediaAPIWrapper is passed into WikipediaQueryRun to initialize langchain_tool,
# We need to also import WikipediaAPIWrapper
# The map is a mapping of the module name to the attribute name
# langchain_community.utilities.WikipediaAPIWrapper
wikipedia_query_tool = Tool.from_langchain(
wikipedia_query_tool = client.load_langchain_tool(
langchain_tool, additional_imports_module_attr_map={"langchain_community.utilities": "WikipediaAPIWrapper"}
)
tool_name = wikipedia_query_tool.name

# Create a `LocalClient` (you can also use a `RESTClient`, see the letta_rest_client.py example)
client = create_client()
client.set_default_llm_config(LLMConfig.default_config("gpt-4o-mini"))
client.set_default_embedding_config(EmbeddingConfig.default_config(provider="openai"))

# create tool
client.add_tool(wikipedia_query_tool)

# Confirm that the tool is in
tools = client.list_tools()
assert wikipedia_query_tool.name in [t.name for t in tools]
Expand Down
5 changes: 0 additions & 5 deletions letta/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ def __init__(
assert isinstance(self.agent_state.memory, Memory), f"Memory object is not of type Memory: {type(self.agent_state.memory)}"

# link tools
self.tools = tools
self.link_tools(tools)

# gpt-4, gpt-3.5-turbo, ...
Expand Down Expand Up @@ -1521,10 +1520,6 @@ def save_agent(agent: Agent, ms: MetadataStore):
else:
ms.create_agent(agent_state)

for tool in agent.tools:
if ms.get_tool(tool_name=tool.name, user_id=tool.user_id) is None:
ms.create_tool(tool)

agent.agent_state = ms.get_agent(agent_id=agent_id)
assert isinstance(agent.agent_state.memory, Memory), f"Memory is not a Memory object: {type(agent_state.memory)}"

Expand Down
7 changes: 5 additions & 2 deletions letta/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def run(
# read user id from config
ms = MetadataStore(config)
client = create_client()
server = client.server

# determine agent to use, if not provided
if not yes and not agent:
Expand Down Expand Up @@ -217,7 +218,9 @@ def run(
)

# create agent
tools = [ms.get_tool(tool_name, user_id=client.user_id) for tool_name in agent_state.tools]
tools = [
server.tool_manager.get_tool_by_name_and_user_id(tool_name=tool_name, user_id=client.user_id) for tool_name in agent_state.tools
]
letta_agent = Agent(agent_state=agent_state, interface=interface(), tools=tools)

else: # create new agent
Expand Down Expand Up @@ -297,7 +300,7 @@ def run(
)
assert isinstance(agent_state.memory, Memory), f"Expected Memory, got {type(agent_state.memory)}"
typer.secho(f"-> 🛠️ {len(agent_state.tools)} tools: {', '.join([t for t in agent_state.tools])}", fg=typer.colors.WHITE)
tools = [ms.get_tool(tool_name, user_id=client.user_id) for tool_name in agent_state.tools]
tools = [server.tool_manager.get_tool_by_name_and_user_id(tool_name, user_id=client.user_id) for tool_name in agent_state.tools]

letta_agent = Agent(
interface=interface(),
Expand Down
Loading
Loading