Skip to content

Commit

Permalink
Merge pull request #3 from AnswerDotAI/cleanup-for-claudette-integration
Browse files Browse the repository at this point in the history
convert `mk_msg` output to an `AttrDict`
  • Loading branch information
comhar authored Nov 22, 2024
2 parents fa3a567 + 8fef349 commit 1d0c221
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 22 deletions.
3 changes: 2 additions & 1 deletion msglm/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def mk_msg(content:Union[list,str], role:str="user", *args, api:str="openai", **
"Create an OpenAI/Anthropic compatible message."
text_only = isinstance(content, str) or (isinstance(content, list) and len(content) == 1 and isinstance(content[0], str))
m = OpenAiMsg if api == "openai" else AnthropicMsg
return m()(role, content, text_only=text_only, **kw)
msg = m()(role, content, text_only=text_only, **kw)
return dict2obj(msg, list_func=list)

# %% ../nbs/00_core.ipynb
def mk_msgs(msgs: list, *args, api:str="openai", **kw) -> list:
Expand Down
145 changes: 124 additions & 21 deletions nbs/00_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
{
"data": {
"text/plain": [
"ChatCompletion(id='chatcmpl-ALSvOrQd9kjBHIMESmqwGSFV3nkqI', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='Hello! How can I assist you today?', refusal=None, role='assistant', function_call=None, tool_calls=None))], created=1729679438, model='gpt-4o-mini-2024-07-18', object='chat.completion', service_tier=None, system_fingerprint='fp_482c22a7bc', usage=CompletionUsage(completion_tokens=9, prompt_tokens=11, total_tokens=20, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=0), prompt_tokens_details={'cached_tokens': 0}))"
"ChatCompletion(id='chatcmpl-AWXWdjz55mygQ0I8rOdnPj58BmM3E', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='Hello! How can I assist you today?', refusal=None, role='assistant', function_call=None, tool_calls=None))], created=1732318731, model='gpt-4o-mini-2024-07-18', object='chat.completion', service_tier=None, system_fingerprint='fp_0705bf87c0', usage=CompletionUsage(completion_tokens=9, prompt_tokens=11, total_tokens=20, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=0, audio_tokens=0, accepted_prediction_tokens=0, rejected_prediction_tokens=0), prompt_tokens_details={'cached_tokens': 0, 'audio_tokens': 0}))"
]
},
"execution_count": null,
Expand Down Expand Up @@ -119,7 +119,7 @@
{
"data": {
"text/plain": [
"Message(id='msg_01PkwhxFzFEwitg6CinErWNj', content=[TextBlock(text=\"Hello! It's nice to meet you. I'm an AI assistant created by Anthropic. I'm here to help with any questions or tasks you may have. Please let me know if there is anything I can assist you with.\", type='text')], model='claude-3-haiku-20240307', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(input_tokens=11, output_tokens=51))"
"Message(id='msg_01JAn3tJTJtuTL79eeDME2rr', content=[TextBlock(text=\"Hello! I'm Claude, an AI assistant created by Anthropic. It's nice to meet you. How can I help you today?\", type='text')], model='claude-3-haiku-20240307', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(input_tokens=11, output_tokens=32))"
]
},
"execution_count": null,
Expand Down Expand Up @@ -223,7 +223,7 @@
{
"data": {
"text/plain": [
"\"Hello! It's nice to meet you. I'm an AI assistant created by Anthropic. How can I help you today?\""
"\"Hello! I am Claude, an AI assistant created by Anthropic. It's nice to meet you. How can I assist you today?\""
]
},
"execution_count": null,
Expand Down Expand Up @@ -330,7 +330,7 @@
{
"data": {
"text/plain": [
"\"Hello! It's nice to meet you. How can I assist you today?\""
"\"Hello! It's nice to meet you. I'm an AI assistant created by Anthropic. I'm here to help with a variety of tasks - feel free to ask me anything!\""
]
},
"execution_count": null,
Expand Down Expand Up @@ -392,7 +392,7 @@
{
"data": {
"text/plain": [
"ChatCompletion(id='chatcmpl-ALSvUmpX7fRmFLad6TO2zQA85CkCL', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='The image features a small puppy with brown and white fur resting in a grassy area. It appears to be surrounded by purple flowers, which adds a vibrant touch to the scene. The puppy has a curious expression and looks comfortable in its setting.', refusal=None, role='assistant', function_call=None, tool_calls=None))], created=1729679444, model='gpt-4o-mini-2024-07-18', object='chat.completion', service_tier=None, system_fingerprint='fp_7693ae462b', usage=CompletionUsage(completion_tokens=48, prompt_tokens=8512, total_tokens=8560, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=0), prompt_tokens_details={'cached_tokens': 0}))"
"ChatCompletion(id='chatcmpl-AWXWjNJlLrQS8hECvDsOca0p00vqc', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='The image contains a small puppy resting on grass. The puppy has a brown and white coat and is positioned near some purple flowers. It looks curious and attentive.', refusal=None, role='assistant', function_call=None, tool_calls=None))], created=1732318737, model='gpt-4o-mini-2024-07-18', object='chat.completion', service_tier=None, system_fingerprint='fp_3de1288069', usage=CompletionUsage(completion_tokens=32, prompt_tokens=8512, total_tokens=8544, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=0, audio_tokens=0, accepted_prediction_tokens=0, rejected_prediction_tokens=0), prompt_tokens_details={'cached_tokens': 0, 'audio_tokens': 0}))"
]
},
"execution_count": null,
Expand Down Expand Up @@ -434,7 +434,7 @@
{
"data": {
"text/plain": [
"Message(id='msg_013qHicKR5GZLY2tqZxcRaLY', content=[TextBlock(text='This image shows a close-up of a cute puppy lying in the grass. The puppy appears to be a Cavalier King Charles Spaniel with a soft brown and white coat. The puppy has a friendly, inquisitive expression and is surrounded by purple daisy-like flowers in the background, creating a pleasant, natural setting.', type='text')], model='claude-3-haiku-20240307', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(input_tokens=104, output_tokens=75))"
"Message(id='msg_01A2qtvcrYZF6C22Jbujezuh', content=[TextBlock(text=\"This image shows a cute puppy lying in some grass and flowers. The puppy appears to be a Cavalier King Charles Spaniel, with its long, silky fur and floppy ears. The puppy has a friendly, sweet expression on its face as it looks directly at the camera. The background shows some purple flowers, creating a nice colorful contrast against the puppy's white and brown fur.\", type='text')], model='claude-3-haiku-20240307', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(input_tokens=104, output_tokens=89))"
]
},
"execution_count": null,
Expand Down Expand Up @@ -711,7 +711,7 @@
{
"data": {
"text/plain": [
"'The image features an adorable puppy lying on the grass, surrounded by small purple flowers. The puppy has a primarily white coat with brown patches on its ears and around its eyes, showcasing a playful and curious expression. The background includes greenery and a wooden structure, adding to the tranquil outdoor setting.'"
"'The picture features an adorable puppy lying on the grass. It has a fluffy white coat with brown patches, particularly around its ears and eyes. The puppy has large, expressive eyes and a curious expression. In the background, there are purple flowers blooming, adding a vibrant touch to the scene. The overall setting looks peaceful and natural, conveying a sense of tranquility and playfulness.'"
]
},
"execution_count": null,
Expand All @@ -733,7 +733,7 @@
{
"data": {
"text/plain": [
"\"The image shows a cute puppy lying on the grass surrounded by beautiful purple flowers. The puppy appears to be a Cavalier King Charles Spaniel, with its long silky fur and big, expressive eyes. The puppy has a friendly and playful expression, as if it's enjoying the warm, sunny day and the colorful flowers around it. The contrast between the vibrant purple blooms and the soft, fluffy puppy creates a delightful and serene scene.\""
"'The image shows a young puppy lying in a grassy area surrounded by purple daisy-like flowers. The puppy has a white and brown coat, with floppy ears and a friendly, alert expression on its face. The puppy appears to be relaxed and content, enjoying the warm, sunny environment. The vibrant colors of the flowers and the lush green grass create a charming, natural setting that complements the endearing presence of the puppy.'"
]
},
"execution_count": null,
Expand Down Expand Up @@ -808,7 +808,9 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "### PDFs"
"source": [
"### PDFs"
]
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -858,19 +860,25 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "As Claude PDF support is currently in beta, we need to update our default headers to include `pdfs-2024-09-25`. "
"source": [
"As Claude PDF support is currently in beta, we need to update our default headers to include `pdfs-2024-09-25`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "a_cli = Anthropic(default_headers={'anthropic-beta': 'pdfs-2024-09-25'})"
"source": [
"a_cli = Anthropic(default_headers={'anthropic-beta': 'pdfs-2024-09-25'})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": "PDF support is only available on Sonnet so we also need to update `anthropic_chat` to use `sonnet`"
"source": [
"PDF support is only available on Sonnet so we also need to update `anthropic_chat` to use `sonnet`"
]
},
{
"cell_type": "code",
Expand Down Expand Up @@ -906,7 +914,9 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "A PDF [file](https://docs.fileformat.com/pdf/#pdf-file-header) should start with `%PDF` followed by the pdf version `%PDF-1.1`"
"source": [
"A PDF [file](https://docs.fileformat.com/pdf/#pdf-file-header) should start with `%PDF` followed by the pdf version `%PDF-1.1`"
]
},
{
"cell_type": "code",
Expand All @@ -921,7 +931,9 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "Now, let's update `mk_content` to use these methods. Let's also add a `pdf_msg` method as well."
"source": [
"Now, let's update `mk_content` to use these methods. Let's also add a `pdf_msg` method as well."
]
},
{
"cell_type": "code",
Expand Down Expand Up @@ -960,7 +972,9 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "Next, let's create a method that converts a byte string to the base64 encoded string that Anthropic expects."
"source": [
"Next, let's create a method that converts a byte string to the base64 encoded string that Anthropic expects."
]
},
{
"cell_type": "code",
Expand All @@ -977,7 +991,9 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "Finally, let's add a `pdf_msg` method to `AnthropicMsg` that uses `_mk_pdf`."
"source": [
"Finally, let's add a `pdf_msg` method to `AnthropicMsg` that uses `_mk_pdf`."
]
},
{
"cell_type": "code",
Expand All @@ -1002,14 +1018,18 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "Let's test our changes on a financial report."
"source": [
"Let's test our changes on a financial report."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "from pathlib import Path"
"source": [
"from pathlib import Path"
]
},
{
"cell_type": "code",
Expand All @@ -1019,7 +1039,7 @@
{
"data": {
"text/plain": [
"'Let me calculate the average monthly revenue for Product D by adding all monthly values and dividing by 12.\\n\\nMonthly revenues for Product D:\\nJan: ~900\\nFeb: ~500\\nMar: ~400\\nApr: ~700\\nMay: ~800\\nJun: ~900\\nJul: ~1000\\nAug: ~1050\\nSep: ~1200\\nOct: ~1300\\nNov: ~1300\\nDec: ~1300\\n\\nTotal = 11,350 (approximately)\\nAverage = 11,350 ÷ 12 = 946 (rounded to nearest whole number)\\n\\nThe average monthly revenue for Product D was approximately $946.'"
"'Let me calculate the average monthly revenue for Product D by adding all monthly values and dividing by 12.\\n\\nMonthly revenues for Product D:\\nJan: ~900\\nFeb: ~500\\nMar: ~400\\nApr: ~700\\nMay: ~800\\nJun: ~900\\nJul: ~1000\\nAug: ~1050\\nSep: ~1200\\nOct: ~1300\\nNov: ~1300\\nDec: ~1300\\n\\nTotal = 11,350 (approximate)\\nAverage = 11,350 ÷ 12 = 946\\n\\nThe average monthly revenue for Product D was approximately $946 during fiscal year 2023.'"
]
},
"execution_count": null,
Expand Down Expand Up @@ -1190,7 +1210,6 @@
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def mk_msg(content:Union[list,str], role:str=\"user\", *args, api:str=\"openai\", **kw)->dict:\n",
" \"Create an OpenAI/Anthropic compatible message.\"\n",
" text_only = isinstance(content, str) or (isinstance(content, list) and len(content) == 1 and isinstance(content[0], str))\n",
Expand Down Expand Up @@ -1274,6 +1293,77 @@
"mk_msg([\"describe this picture\", \"and tell me a joke\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To make life a little easier, let's use fastcore's [dict2obj](https://fastcore.fast.ai/xtras.html#dict2obj) to convert the output of `mk_msg` to an `AttrDict`. This will allow us to use `msg.content` and `msg.role` instead of having to do lookups like `msg['content']` and `msg['role']`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def mk_msg(content:Union[list,str], role:str=\"user\", *args, api:str=\"openai\", **kw)->dict:\n",
" \"Create an OpenAI/Anthropic compatible message.\"\n",
" text_only = isinstance(content, str) or (isinstance(content, list) and len(content) == 1 and isinstance(content[0], str))\n",
" m = OpenAiMsg if api == \"openai\" else AnthropicMsg\n",
" msg = m()(role, content, text_only=text_only, **kw)\n",
" return dict2obj(msg, list_func=list)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"msg = mk_msg([\"describe this picture\"])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('user', 'describe this picture')"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"msg[\"role\"], msg[\"content\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('user', 'describe this picture')"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"msg.role, msg.content"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -1483,7 +1573,7 @@
{
"data": {
"text/plain": [
"'Why did the farmer get a promotion?\\n\\nBecause he was outstanding in his field too!'"
"\"Why don't skeletons fight each other? \\n\\nThey don't have the guts!\""
]
},
"execution_count": null,
Expand Down Expand Up @@ -1631,6 +1721,11 @@
"outputs": [
{
"data": {
"text/markdown": [
"```json\n",
"{'content': \"Don't cache my message\", 'role': 'user'}\n",
"```"
],
"text/plain": [
"{'role': 'user', 'content': \"Don't cache my message\"}"
]
Expand All @@ -1651,6 +1746,14 @@
"outputs": [
{
"data": {
"text/markdown": [
"```json\n",
"{ 'content': [ { 'cache_control': {'type': 'ephemeral'},\n",
" 'text': 'Please cache my message',\n",
" 'type': 'text'}],\n",
" 'role': 'user'}\n",
"```"
],
"text/plain": [
"{'role': 'user',\n",
" 'content': [{'type': 'text',\n",
Expand Down

0 comments on commit 1d0c221

Please sign in to comment.