Skip to content

Commit

Permalink
Merge pull request #149 from OpenFn/feat/143-collections
Browse files Browse the repository at this point in the history
Job Chat: collections response update
  • Loading branch information
josephjclark authored Feb 12, 2025
2 parents 6dc2f07 + 960dffb commit 3ba91c7
Show file tree
Hide file tree
Showing 3 changed files with 321 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/spotty-planes-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"apollo": patch
---

job_chat: add basic prompt support for collections
313 changes: 313 additions & 0 deletions services/job_chat/evaluation/test_collections.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: python-dotenv in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (1.0.1)\n",
"Requirement already satisfied: anthropic in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (0.39.0)\n",
"Requirement already satisfied: anyio<5,>=3.5.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (4.6.2.post1)\n",
"Requirement already satisfied: distro<2,>=1.7.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (1.9.0)\n",
"Requirement already satisfied: httpx<1,>=0.23.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (0.27.2)\n",
"Requirement already satisfied: jiter<1,>=0.4.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (0.8.0)\n",
"Requirement already satisfied: pydantic<3,>=1.9.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (1.10.19)\n",
"Requirement already satisfied: sniffio in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (1.3.1)\n",
"Requirement already satisfied: typing-extensions<5,>=4.7 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anthropic) (4.12.2)\n",
"Requirement already satisfied: idna>=2.8 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from anyio<5,>=3.5.0->anthropic) (3.10)\n",
"Requirement already satisfied: certifi in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from httpx<1,>=0.23.0->anthropic) (2024.8.30)\n",
"Requirement already satisfied: httpcore==1.* in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from httpx<1,>=0.23.0->anthropic) (1.0.7)\n",
"Requirement already satisfied: h11<0.15,>=0.13 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->anthropic) (0.14.0)\n",
"Requirement already satisfied: tenacity in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (9.0.0)\n",
"Requirement already satisfied: apollo in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (4.2.13)\n",
"Requirement already satisfied: requests in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (2.32.3)\n",
"Requirement already satisfied: biopython>=1.77 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (1.84)\n",
"Requirement already satisfied: cachetools<4 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (3.1.1)\n",
"Requirement already satisfied: click>=6.7 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (8.1.7)\n",
"Requirement already satisfied: wrapt in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (1.17.0)\n",
"Requirement already satisfied: pyyaml in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (6.0.2)\n",
"Requirement already satisfied: decorator in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (5.1.1)\n",
"Requirement already satisfied: bcbio-gff>=0.6.6 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from apollo) (0.7.1)\n",
"Requirement already satisfied: six in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from bcbio-gff>=0.6.6->apollo) (1.16.0)\n",
"Requirement already satisfied: numpy in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from biopython>=1.77->apollo) (2.1.3)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from requests->apollo) (3.4.0)\n",
"Requirement already satisfied: idna<4,>=2.5 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from requests->apollo) (3.10)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from requests->apollo) (2.2.3)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from requests->apollo) (2024.8.30)\n",
"Requirement already satisfied: pandas in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (2.2.3)\n",
"Requirement already satisfied: numpy>=1.23.2 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from pandas) (2.1.3)\n",
"Requirement already satisfied: python-dateutil>=2.8.2 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from pandas) (2.9.0.post0)\n",
"Requirement already satisfied: pytz>=2020.1 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from pandas) (2024.2)\n",
"Requirement already satisfied: tzdata>=2022.7 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from pandas) (2024.2)\n",
"Requirement already satisfied: six>=1.5 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)\n",
"Requirement already satisfied: jsbeautifier in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (1.15.1)\n",
"Requirement already satisfied: six>=1.13.0 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from jsbeautifier) (1.16.0)\n",
"Requirement already satisfied: editorconfig>=0.12.2 in /opt/anaconda3/envs/apollo/lib/python3.11/site-packages (from jsbeautifier) (0.12.4)\n"
]
}
],
"source": [
"!pip install python-dotenv\n",
"!pip install anthropic\n",
"!pip install tenacity\n",
"!pip install apollo\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from dotenv import load_dotenv\n",
"import anthropic\n",
"\n",
"load_dotenv()\n",
"ANTHROPIC_API_KEY = os.getenv(\"ANTHROPIC_API_KEY\")\n",
"\n",
"client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/Users/hunter/apollo/services\n"
]
}
],
"source": [
"import sys\n",
"import os\n",
"\n",
"# Add the parent directory to sys.path\n",
"parent_dir = os.path.abspath(\"../../\")\n",
"print(parent_dir)\n",
"sys.path.append(parent_dir)\n",
"\n",
"\n",
"\n",
"from job_chat.prompt import job_writing_summary, system_role, build_prompt\n",
"from util import DictObj"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# Import tenacity to implement waiting after failed api calls\n",
"\n",
"from tenacity import (\n",
" retry,\n",
" stop_after_attempt,\n",
" wait_random_exponential,\n",
") "
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# @retry(wait=wait_random_exponential(multiplier=1, max=60), stop=stop_after_attempt(20))\n",
"def generate_apollo_format(content, history=\"\", adaptor=\"@openfn/[email protected]\", model=\"claude-3-5-sonnet-20240620\"):\n",
" \"\"\"Use Apollo prompt formatting templates to generate a Claude answer.\"\"\"\n",
"\n",
" context = {\n",
" \"expression\": \"// write your job code here\",\n",
" \"adaptor\": adaptor\n",
" }\n",
" print(content)\n",
" system_message, prompt = build_prompt(content, history, context)\n",
" # print(system_message)\n",
" # print(prompt)\n",
"\n",
" message = client.beta.prompt_caching.messages.create(\n",
" max_tokens=1024, messages=prompt, model=model, system=system_message\n",
" )\n",
" return message.content[0].text"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"What are collections in openFn?\n",
"INFO:httpx:HTTP Request: POST https://api.anthropic.com/v1/messages?beta=prompt_caching \"HTTP/1.1 200 OK\"\n"
]
},
{
"data": {
"text/plain": [
"\"Collections in OpenFn are a powerful feature for working with groups of data. They provide functions to manipulate and transform arrays of objects efficiently.\\n\\nFor working with collections, I recommend referring to the official documentation here: https://docs.openfn.org/adaptors/packages/collections-docs.\\n\\nThe documentation will provide the most up-to-date and accurate information on how to use collections in your OpenFn jobs.\\n\\nIs there a specific task you're trying to accomplish with collections? I'd be happy to provide general guidance on using them, but for code examples, it's best to consult the official docs.\""
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_apollo_format(\"What are collections in openFn?\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I have 1000 items like {id, value, source, date}. How do I add them to a collection called 'items-store-collection'?\n",
"INFO:httpx:HTTP Request: POST https://api.anthropic.com/v1/messages?beta=prompt_caching \"HTTP/1.1 200 OK\"\n"
]
},
{
"data": {
"text/plain": [
"\"To add 1000 items to a collection called 'items-store-collection' using OpenFn, you can use the `each` function to iterate over your data and the `createOrUpdateRecord` operation from the collections adaptor. Here's an example of how you could structure your job:\\n\\nFor working with collections, refer to the official documentation here: https://docs.openfn.org/adaptors/packages/collections-docs.\\n\\nThe collections adaptor provides operations specifically designed for working with collections, so it's best to use those rather than trying to implement the functionality yourself.\""
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_apollo_format(\"I have 1000 items like {id, value, source, date}. How do I add them to a collection called 'items-store-collection'?\")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"How do I retrieve items from a collection?\n",
"INFO:httpx:HTTP Request: POST https://api.anthropic.com/v1/messages?beta=prompt_caching \"HTTP/1.1 200 OK\"\n"
]
},
{
"data": {
"text/plain": [
"\"To retrieve items from a collection in OpenFn, you should refer to the official documentation for working with collections. You can find this information at:\\n\\nhttps://docs.openfn.org/adaptors/packages/collections-docs\\n\\nThe collections documentation will provide you with the specific functions and methods you need to retrieve items from a collection in your OpenFn job.\\n\\nIs there anything specific about collections you'd like to know that isn't covered in the documentation?\""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_apollo_format(\"How do I retrieve items from a collection?\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"How do I update items in a collection?\n",
"INFO:httpx:HTTP Request: POST https://api.anthropic.com/v1/messages?beta=prompt_caching \"HTTP/1.1 200 OK\"\n"
]
},
{
"data": {
"text/plain": [
"\"For working with collections, refer to the official documentation here: https://docs.openfn.org/adaptors/packages/collections-docs.\\n\\nI can't provide specific code examples for collections, but the documentation should give you detailed information on how to update items in a collection.\\n\\nIs there anything else I can help you with regarding OpenFn jobs or the HTTP adaptor?\""
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_apollo_format(\"How do I update items in a collection?\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"What are collections?\n",
"INFO:httpx:HTTP Request: POST https://api.anthropic.com/v1/messages?beta=prompt_caching \"HTTP/1.1 200 OK\"\n"
]
},
{
"data": {
"text/plain": [
"\"Collections in OpenFn are a set of utility functions for working with data collections (like arrays and objects) in your job code. They provide helpful methods for manipulating and transforming data structures.\\n\\nSome common use cases for collections include:\\n\\n1. Filtering arrays\\n2. Mapping over arrays to transform data\\n3. Reducing arrays to aggregate data\\n4. Finding specific elements in arrays or objects\\n5. Grouping data based on certain criteria\\n\\nHowever, I can't provide specific code examples for collections. For the most up-to-date and accurate information on how to use collections in your OpenFn jobs, I recommend referring to the official documentation:\\n\\nhttps://docs.openfn.org/adaptors/packages/collections-docs\\n\\nThis resource will give you detailed explanations and examples of how to use collections effectively in your OpenFn workflows.\""
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_apollo_format(\"What are collections?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "apollo",
"language": "python",
"name": "python3"
},
"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.11.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
3 changes: 3 additions & 0 deletions services/job_chat/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
Job code must only contain function calls at the top level.
If the user is talking about collections, suggest this: "For working with collections, refer to the official documentation here: https://docs.openfn.org/adaptors/packages/collections-docs.".
Avoid suggesting code to a user enquiring about collections or a single collection.
Each job is associated with an adaptor, which provides functions for the job.
All jobs have the fn() and each() function, which are very important.
Expand Down

0 comments on commit 3ba91c7

Please sign in to comment.