Update functions.md (#461)

This commit is contained in:
Charles Packer
2023-11-15 15:51:08 -08:00
committed by GitHub
parent f781d4426a
commit 40ecc8e7e7

View File

@@ -30,53 +30,79 @@ There are three steps to adding more MemGPT functions:
2. (Optional) Create a new system prompt that instructs MemGPT how to use these functions
3. Create a new preset that imports these functions (and optionally uses the new system prompt)
### Step 1: Writing the functions
### Example: giving MemGPT the ability to use the Jira API
!!! warning "Function requirements"
The functions you write MUST have proper docstrings and type hints - this is because MemGPT will use these docstrings and types to automatically create a JSON schema that is used in the LLM prompt. Use the docstrings and types annotations from the [example functions](https://github.com/cpacker/MemGPT/blob/main/memgpt/functions/function_sets/base.py) for guidance.
As an example, if you wanted to give MemGPT the ability to make HTTP requests, you would write the function in Python (you would save this python file inside `~/.memgpt/functions/your_new_functions.py`):
```python
import json
import requests
_Example taken from [this pull request](https://github.com/cpacker/MemGPT/pull/282) by @cevatkerim_
def http_request(self, method: str, url: str, payload_json: Optional[str] = None):
As an example, if you wanted to give MemGPT the ability to make calls to Jira Cloud, you would write the function in Python (you would save this python file inside `~/.memgpt/functions/jira_cloud.py`):
```python
import os
from jira import JIRA
from jira.exceptions import JIRAError
def get_jira(self, issue_key: str) -> dict:
"""
Generates an HTTP request and returns the response.
Makes a request to user's JIRA instance with the jira issue id that is provided and returns the issue details
Args:
method (str): The HTTP method (e.g., 'GET', 'POST').
url (str): The URL for the request.
payload_json (Optional[str]): A JSON string representing the request payload.
issue_key (str): the issue key (MAIN-1 for example).
Returns:
dict: The response from the HTTP request.
dict: The response from the JIRA request.
"""
if self.jira is None:
server = os.getenv("JIRA_SERVER")
username = os.getenv("JIRA_USER")
password = os.getenv("JIRA_KEY")
self.jira = JIRA({"server": server}, basic_auth=(username, password))
try:
headers = {"Content-Type": "application/json"}
issue = self.jira.issue(issue_key)
return {
"issue": {
"key": issue.key,
"summary": issue.fields.summary,
"description": issue.fields.description,
"created": issue.fields.created,
"assignee": issue.fields.creator.displayName,
"status": issue.fields.status.name,
"status_category": issue.fields.status.statusCategory.name,
}
}
except JIRAError as e:
print(f"Error: {e.text}")
return {"error": str(e.text)}
# For GET requests, ignore the payload
if method.upper() == "GET":
print(f"[HTTP] launching GET request to {url}")
response = requests.get(url, headers=headers)
else:
# Validate and convert the payload for other types of requests
if payload_json:
payload = json.loads(payload_json)
else:
payload = {}
print(f"[HTTP] launching {method} request to {url}, payload=\n{json.dumps(payload, indent=2)}")
response = requests.request(method, url, json=payload, headers=headers)
return {"status_code": response.status_code, "headers": dict(response.headers), "body": response.text}
except Exception as e:
return {"error": str(e)}
def run_jql(self, jql: str) -> dict:
"""
Makes a request to user's JIRA instance with the jql that is provided and returns the issues
Args:
jql (str): the JQL.
Returns:
dict: The response from the JIRA request.
"""
if self.jira is None:
server = os.getenv("JIRA_SERVER")
username = os.getenv("JIRA_USER")
password = os.getenv("JIRA_KEY")
self.jira = JIRA({"server": server}, basic_auth=(username, password))
try:
issues = self.jira.search_issues(jql)
return {"issues": [issue.key for issue in issues]}
except JIRAError as e:
print(f"Error: {e.text}")
return {"error": str(e.text)}
```
### Step 3: Create a new preset file
Now we need to create a new preset file, let's create one called `~/.memgpt/presets/memgpt_http.yaml`:
Now we need to create a new preset file, let's create one called `~/.memgpt/presets/memgpt_jira.yaml`:
```yaml
# if we had created a new system prompt, we would replace "memgpt_chat" with the new prompt filename (no .txt)
system_prompt: "memgpt_chat"
@@ -89,8 +115,23 @@ functions:
- "conversation_search_date"
- "archival_memory_insert"
- "archival_memory_search"
# internet access
- "http_request"
# Jira functions that we made inside of `~/.memgpt/functions/jira_cloud.py`
- "get_jira"
- "run_jql"
```
Now when we run `memgpt configure`, we should see the option to use `memgpt_http` as a preset.
Now when we run `memgpt configure`, we should see the option to use `memgpt_jira` as a preset:
```sh
memgpt configure
```
```text
...
? Select default preset: (Use arrow keys)
memgpt_extras
memgpt_docs
memgpt_chat
» memgpt_jira
```
Now, if we create a new MemGPT agent (with `memgpt run`) using this `memgpt_jira` preset, it will have the ability to call Jira cloud:
![image](https://github.com/cpacker/MemGPT/assets/1452094/618a3ec3-8d0c-46e9-8a2f-2dbfc3ec57ac)