Add 'apps/core/' from commit 'ea2a7395f4023f5b9fab03e6273db3b64a1181d5'

git-subtree-dir: apps/core
git-subtree-mainline: a8963e11e7a5a0059acbc849ce768e1eee80df61
git-subtree-split: ea2a7395f4023f5b9fab03e6273db3b64a1181d5
This commit is contained in:
Shubham Naik
2024-12-22 20:31:22 -08:00
commit 5a743d1dc4
478 changed files with 65642 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,239 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c015b59e-1187-4d45-b2af-7b4c5a9512e1",
"metadata": {},
"source": [
"# Letta Python Client \n",
"Welcome to the Letta tutorial! In this tutorial, we'll go through how to create a basic user-client for Letta and create a custom agent with long term memory. \n",
"\n",
"Letta runs *agents-as-a-service*, so agents can run independently on a server. For this tutorial, we will run a local version of the client which does not require a server, but still allows you to see some of Letta's capabilities. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a34fe313-f63e-4f36-9142-f681431bbb91",
"metadata": {},
"outputs": [],
"source": [
"!pip install git+https://github.com/cpacker/MemGPT.git@tutorials"
]
},
{
"cell_type": "markdown",
"id": "191c1cf1-03e6-411a-8409-003caa8530f5",
"metadata": {},
"source": [
"### Setup your OpenAI API key "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "23091690-bc50-4fbc-b48d-50b639453e36",
"metadata": {},
"outputs": [],
"source": [
"import os \n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
]
},
{
"cell_type": "markdown",
"id": "f20ad6c7-9066-45e0-88ac-40920c83cc39",
"metadata": {},
"source": [
"## Part 1: Connecting to the Letta Client \n",
"\n",
"We create a local client which creates a quickstart configuration for OpenAI using the provided `OPENAI_API_KEY`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9b0871a0-42af-4573-a8ba-efb4fe7e5e5a",
"metadata": {},
"outputs": [],
"source": [
"from letta.client.client import LocalClient\n",
"\n",
"client = LocalClient(quickstart_option=\"openai\") "
]
},
{
"cell_type": "markdown",
"id": "40666896-0fa2-465e-b51b-57719de30542",
"metadata": {},
"source": [
"## Part 2: Create an agent \n",
"We'll first start with creating a basic Letta agent. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb90f12b-acd7-4877-81e8-0e7b9eb4bd9b",
"metadata": {},
"outputs": [],
"source": [
"basic_agent = client.create_agent(\n",
" name=\"basic_agent\", \n",
")\n",
"print(f\"Created agent: {basic_agent.name}\")"
]
},
{
"cell_type": "markdown",
"id": "94d14102-3ef8-40fe-b32e-c77d0b8df311",
"metadata": {},
"source": [
"We can now send messages from the user to the agent by specifying the `agent_id`: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3cbfef36-76f0-4f0b-990a-5d8409a676d7",
"metadata": {},
"outputs": [],
"source": [
"from letta.client.utils import pprint \n",
"\n",
"response = client.user_message(agent_id=basic_agent.id, message=\"hello\") \n",
"pprint(response.messages)"
]
},
{
"cell_type": "markdown",
"id": "b24d048e-f3cc-4830-aaa2-5e590d652bd9",
"metadata": {},
"source": [
"### Adding Personalization\n",
"We can now create a more customized agent, but specifying a custom `human` and `persona` field. \n",
"* The *human* specifies the personalization information about the user interacting with the agent \n",
"* The *persona* specifies the behavior and personality of the event\n",
"\n",
"What makes Letta unique is that the starting *persona* and *human* can change over time as the agent gains new information, enabling it to have evolving memory. We'll see an example of this later in the tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ec35979-9102-4ea7-926e-ea7ccd501ceb",
"metadata": {},
"outputs": [],
"source": [
"# TODO: feel free to change the human and person to what you'd like \n",
"persona = \\\n",
"\"\"\"\n",
"You are a friendly and helpful agent!\n",
"\"\"\"\n",
"\n",
"human = \\\n",
"\"\"\"\n",
"I am an Accenture consultant with many specializations. My name is Sarah.\n",
"\"\"\"\n",
"\n",
"custom_agent = client.create_agent(\n",
" name=\"custom_agent\", \n",
" human=human, \n",
" persona=persona\n",
")"
]
},
{
"cell_type": "markdown",
"id": "63a9a61b-58c9-4d09-a4f7-48233c72c340",
"metadata": {},
"source": [
"### Viewing memory \n",
"You can access the agent's memories through the client. There are two type of memory, *core* and *archival* memory: \n",
"1. Core memory stores short-term memories in the LLM's context \n",
"2. Archival memory stores long term memories in a vector database\n",
"\n",
"Core memory is divided into a \"human\" and \"persona\" section. You can see the agent's memories about the human below: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0d1840a-05ee-47c1-b5f5-89faafd96e7c",
"metadata": {},
"outputs": [],
"source": [
"print(client.get_agent_memory(agent_id=custom_agent.id)[\"core_memory\"][\"human\"])"
]
},
{
"cell_type": "markdown",
"id": "95c8a058-5d67-45b7-814b-38bb67c9acf3",
"metadata": {},
"source": [
"### Evolving memory \n",
"Letta agents have long term memory, and can evolve what they store in their memory over time. In the example below, we make a correction to the previously provided information. See how the agent processes this new information. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7e58e685-579e-4a0d-bba7-41976ea7f469",
"metadata": {},
"outputs": [],
"source": [
"response = client.user_message(agent_id=custom_agent.id, message=\"Actually, my name is Charles\") \n",
"pprint(response.messages)"
]
},
{
"cell_type": "markdown",
"id": "af2a2dd6-925e-49b2-ab01-bf837f33b26c",
"metadata": {},
"source": [
"Now lets see what the agent's memory looks like again: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "41ef4aaa-4a48-44bb-8944-855f30725d6d",
"metadata": {},
"outputs": [],
"source": [
"print(client.get_agent_memory(agent_id=custom_agent.id)[\"core_memory\"][\"human\"])"
]
},
{
"cell_type": "markdown",
"id": "66da949b-1084-4b87-b77c-6cbd4a822b34",
"metadata": {},
"source": [
"## 🎉 Congrats, you're done with day 1 of Letta! \n",
"For day 2, we'll go over how to connect *data sources* to Letta to run RAG agents. "
]
}
],
"metadata": {
"kernelspec": {
"display_name": "letta",
"language": "python",
"name": "letta"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,50 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "fb13c7bc-fbb4-4ccd-897c-08995db258e8",
"metadata": {},
"outputs": [],
"source": [
"from letta import Admin \n",
"\n",
"base_url=\"letta.localhost\"\n",
"token=\"lettaadmin\" \n",
"\n",
"admin_client = Admin(base_url=base_url, token=\"lettaadmin\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "984b8249-a3f7-40d1-9691-4d128f9a90ff",
"metadata": {},
"outputs": [],
"source": [
"user = admin_client.create_user()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "letta",
"language": "python",
"name": "letta"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

Binary file not shown.

View File

@@ -0,0 +1,125 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "64fa991c-98e5-4be0-a838-06a4617d8be3",
"metadata": {},
"source": [
"## Part 4: Adding external data \n",
"In addition to short term, in-context memories, Letta agents also have a long term memory store called *archival memory*. We can enable agents to leverage external data (e.g. PDF files, database records, etc.) by inserting data into archival memory. In this example, we'll show how to load the Letta paper a *source*, which defines a set of data that can be attached to agents. "
]
},
{
"cell_type": "markdown",
"id": "c61ac9c3-cbea-47a5-a6a4-4133ffe5984e",
"metadata": {},
"source": [
"We first download a PDF file, the Letta paper: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f89e9156-3d2d-4ce6-b5e9-aeb4cdfd5657",
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"\n",
"url = \"https://arxiv.org/pdf/2310.08560\"\n",
"response = requests.get(url)\n",
"filename = \"letta_paper.pdf\"\n",
"\n",
"with open(filename, 'wb') as f:\n",
" f.write(response.content)"
]
},
{
"cell_type": "markdown",
"id": "bcfe3a48-cdb0-4843-9599-623753eb61b9",
"metadata": {},
"source": [
"Next, we create a Letta source to load data into: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7ccf21fb-5862-42c2-96ca-63e0ba2f48b5",
"metadata": {},
"outputs": [],
"source": [
"letta_paper = client.create_source(\n",
" name=\"letta_paper\", \n",
")"
]
},
{
"cell_type": "markdown",
"id": "f114bf0b-6a25-4dbf-9c2c-59271d46ebba",
"metadata": {},
"source": [
"Now that we have a source, we can load files into the source. Loading the file will take a bit of time, since the file needs to be parsed and stored as *embeddings* using an embedding model. The loading function returns a *job* which can be pinged for a status. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6fe624eb-bf08-4267-a849-06103c1ad5b6",
"metadata": {},
"outputs": [],
"source": [
"job = client.load_file_to_source(filename=filename, source_id=letta_paper.id)\n",
"job"
]
},
{
"cell_type": "markdown",
"id": "27ce13f5-d878-406d-9a5f-7e2335f2ef0d",
"metadata": {},
"source": [
"### Attaching data to an agent \n",
"To allow an agent to access data in a source, we need to *attach* it to the agent. This will load the source's data into the agent's archival memory. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5be91571-87ee-411a-8e79-25c56c414360",
"metadata": {},
"outputs": [],
"source": [
"client.attach_source_to_agent(source_id=letta_paper.id, agent_id=basic_agent.id)\n",
"# TODO: add system message saying that file has been attached \n",
"\n",
"from pprint import pprint\n",
"\n",
"# TODO: do soemthing accenture related \n",
"# TODO: brag about query rewriting -- hyde paper \n",
"response = client.user_message(agent_id=basic_agent.id, message=\"what is core memory? search your archival memory.\") \n",
"pprint(response.messages)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "letta",
"language": "python",
"name": "letta"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,319 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "6d3806ac-38f3-4999-bbed-953037bd0fd9",
"metadata": {},
"source": [
"# Letta Python Client \n",
"Welcome to the Letta tutorial! In this tutorial, we'll go through how to create a basic user-client for Letta and create a custom agent with long term memory. \n",
"\n",
"Letta runs *agents-as-a-service*, so agents can run independently on a server. For this tutorial, we will be connecting to an existing Letta server via the Python client and the UI console. If you don't have a running server, see the [documentation](https://letta.readme.io/docs/running-a-letta-server) for instructions on how to create one. "
]
},
{
"cell_type": "markdown",
"id": "7c0b6d6b-dbe6-412b-b129-6d7eb7d626a3",
"metadata": {},
"source": [
"## Part 0: Install Letta "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "481d0976-d26b-46d2-ba74-8f2bb5556387",
"metadata": {},
"outputs": [],
"source": [
"!pip install git+https://github.com/cpacker/MemGPT.git@tutorials"
]
},
{
"cell_type": "markdown",
"id": "a0484348-f7b2-48e3-9a2f-7d6495ef76e3",
"metadata": {},
"source": [
"## Part 1: Connecting to the Letta Client \n",
"\n",
"The Letta client connects to a running Letta service, specified by `base_url`. The client corresponds to a *single-user* (you), so requires an authentication token to let the service know who you are. \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "53ae2e1b-ad22-43c2-b3d8-92d591be8840",
"metadata": {},
"outputs": [],
"source": [
"from letta import create_client\n",
"\n",
"base_url = \"http://35.238.125.250:8083\"\n",
"\n",
"# TODO: replace with your token \n",
"my_token = \"sk-...\" \n",
"\n",
"client = create_client(base_url=base_url, token=my_token) "
]
},
{
"cell_type": "markdown",
"id": "3c5c8651-e8aa-4423-b2b8-284bf6a01577",
"metadata": {},
"source": [
"### Viewing the developer portal \n",
"Letta provides a portal interface for viewing and interacting with agents, data sources, tools, and more. You can enter `http://35.238.125.250:8083` into your browser to load the developer portal, and enter in `my_token` to log in. \n",
"\n",
"<img src=\"./developer_portal_login.png\" width=\"800\">"
]
},
{
"cell_type": "markdown",
"id": "66e47b34-5feb-4660-85f0-14b5ee7f62b9",
"metadata": {},
"source": [
"## Part 2: Create an agent \n",
"We'll first start with creating a basic Letta agent. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24745606-b0fb-4157-a5cd-82fd0c26711f",
"metadata": {},
"outputs": [],
"source": [
"basic_agent = client.create_agent(\n",
" name=\"basic_agent\", \n",
")\n",
"print(f\"Created agent: {basic_agent.name}\")"
]
},
{
"cell_type": "markdown",
"id": "fcfb0d7b-b260-4bc0-8db2-c65f40e4afd5",
"metadata": {},
"source": [
"We can now send messages from the user to the agent by specifying the `agent_id`: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a37bc9aa-4efb-4b4d-a6ce-f02505cb3240",
"metadata": {},
"outputs": [],
"source": [
"from letta.client.utils import pprint \n",
"\n",
"response = client.user_message(agent_id=basic_agent.id, message=\"hello\") \n",
"pprint(response.messages)"
]
},
{
"cell_type": "markdown",
"id": "9803140c-2b9d-426b-8812-9295806eb312",
"metadata": {},
"source": [
"### Chatting in the developer portal \n",
"You can also chat with the agent inside of the developer portal. Try clicking the chat button in the agent view. \n",
"\n",
"<img src=\"./dev_portal_agent_chat.png\" width=\"800\">"
]
},
{
"cell_type": "markdown",
"id": "99ae20ec-e92e-4480-a652-b4aea28a6199",
"metadata": {},
"source": [
"### Adding Personalization\n",
"We can now create a more customized agent, but specifying a custom `human` and `persona` field. \n",
"* The *human* specifies the personalization information about the user interacting with the agent \n",
"* The *persona* specifies the behavior and personality of the event\n",
"\n",
"What makes Letta unique is that the starting *persona* and *human* can change over time as the agent gains new information, enabling it to have evolving memory. We'll see an example of this later in the tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c0876410-4d70-490d-a798-39938b5ce941",
"metadata": {},
"outputs": [],
"source": [
"# TODO: feel free to change the human and person to what you'd like \n",
"persona = \\\n",
"\"\"\"\n",
"You are a friendly and helpful agent!\n",
"\"\"\"\n",
"\n",
"human = \\\n",
"\"\"\"\n",
"I am an Accenture consultant with many specializations. My name is Sarah.\n",
"\"\"\"\n",
"\n",
"custom_agent = client.create_agent(\n",
" name=\"custom_agent\", \n",
" human=human, \n",
" persona=persona\n",
")"
]
},
{
"cell_type": "markdown",
"id": "21293857-80e4-46e4-b628-3912fad038e9",
"metadata": {},
"source": [
"### Viewing memory \n",
"You can view and edit the agent's memory inside of the developer console. There are two type of memory, *core* and *archival* memory: \n",
"1. Core memory stores short-term memories in the LLM's context \n",
"2. Archival memory stores long term memories in a vector database\n",
"\n",
"In this example, we'll look at how the agent can modify its core memory with new information. To see the agent's memory, click the \"Core Memory\" section on the developer console. \n",
"\n",
"<img src=\"./dev_portal_memory.png\" width=\"800\">"
]
},
{
"cell_type": "markdown",
"id": "d8fa13eb-ce4b-4e4f-81b6-9d6ef6fa67c2",
"metadata": {},
"source": [
"### Referencing memory \n",
"Letta agents can customize their responses based on what memories they have stored. Try asking a question that related to the human and persona you provided. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fddbefe5-3b94-4a08-aa50-d80fb581c747",
"metadata": {},
"outputs": [],
"source": [
"response = client.user_message(agent_id=custom_agent.id, message=\"what do I work as?\") \n",
"pprint(response.messages)"
]
},
{
"cell_type": "markdown",
"id": "30497119-e208-4a4e-b482-e7cfff346263",
"metadata": {},
"source": [
"### Evolving memory \n",
"Letta agents have long term memory, and can evolve what they store in their memory over time. In the example below, we make a correction to the previously provided information. See how the agent processes this new information. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "679fa708-20ee-4e75-9222-b476f126bc6f",
"metadata": {},
"outputs": [],
"source": [
"response = client.user_message(agent_id=custom_agent.id, message=\"Actually, my name is Charles\") \n",
"pprint(response.messages)"
]
},
{
"cell_type": "markdown",
"id": "686ac5a3-be63-4afd-97ae-b7d05219dd60",
"metadata": {},
"source": [
"Now, look back at the developer portal and at the agent's *core memory*. Do you see a change in the *human* section of the memory? "
]
},
{
"cell_type": "markdown",
"id": "878d2f49-a5a6-4483-9f69-7436bcf00cfb",
"metadata": {},
"source": [
"## Part 3: Adding Tools \n",
"Letta agents can be connected to custom tools. Currently, tools must be created by service administrators. However, you can add additional tools provided by the service administrator to the agent you create. "
]
},
{
"cell_type": "markdown",
"id": "35785d36-2674-4a00-937b-4c747e0fb6bf",
"metadata": {},
"source": [
"### View Available Tools "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c307a6f7-276b-49f5-8d3d-48aaaea221a7",
"metadata": {},
"outputs": [],
"source": [
"tools = client.list_tools().tools\n",
"for tool in tools: \n",
" print(f\"Tool: {tool.name} - {tool.json_schema['description']}\")"
]
},
{
"cell_type": "markdown",
"id": "318d19dc-b9dd-448c-ab5c-9c9311d21fad",
"metadata": {},
"source": [
"### Create a tool using agent in the developer portal \n",
"Create an agent in the developer portal and toggle additional tools you want the agent to use. We recommend modifying the *persona* to notify the agent that it should be using the tools for certain tasks. \n",
"\n",
"\n",
"<img src=\"./dev_portal_tools.png\" width=\"800\">"
]
},
{
"cell_type": "markdown",
"id": "aecdaa70-861a-43d5-b006-fecd90a8ed19",
"metadata": {},
"source": [
"## Part 4: Cleanup (optional) \n",
"You can cleanup the agents you creating the following command to delete your agents: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1320d9c9-170b-48a8-b5e8-70737b1a8aac",
"metadata": {},
"outputs": [],
"source": [
"for agent in client.list_agents().agents: \n",
" client.delete_agent(agent[\"id\"])\n",
" print(f\"Deleted agent {agent['name']} with ID {agent['id']}\")"
]
},
{
"cell_type": "markdown",
"id": "510675a8-22bc-4f9f-9c79-91e2ffa9caf9",
"metadata": {},
"source": [
"## 🎉 Congrats, you're done with day 1 of Letta! \n",
"For day 2, we'll go over how to connect *data sources* to Letta to run RAG agents. "
]
}
],
"metadata": {
"kernelspec": {
"display_name": "letta",
"language": "python",
"name": "letta"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}