# claudette
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
> **NB**: If you are reading this in GitHub’s readme, we recommend you
> instead read the much more nicely formatted [documentation
> format](https://claudette.answer.ai/) of this tutorial.
*Claudette* is a wrapper for Anthropic’s [Python
SDK](https://github.com/anthropics/anthropic-sdk-python).
The SDK works well, but it is quite low level – it leaves the developer
to do a lot of stuff manually. That’s a lot of extra work and
boilerplate! Claudette automates pretty much everything that can be
automated, whilst providing full control. Amongst the features provided:
- A [`Chat`](https://claudette.answer.ai/core.html#chat) class that
creates stateful dialogs
- Support for *prefill*, which tells Claude what to use as the first few
words of its response
- Convenient image support
- Simple and convenient support for Claude’s new Tool Use API.
You’ll need to set the `ANTHROPIC_API_KEY` environment variable to the
key provided to you by Anthropic in order to use this library.
Note that this library is the first ever “literate nbdev” project. That
means that the actual source code for the library is a rendered Jupyter
Notebook which includes callout notes and tips, HTML tables and images,
detailed explanations, and teaches *how* and *why* the code is written
the way it is. Even if you’ve never used the Anthropic Python SDK or
Claude API before, you should be able to read the source code. Click
[Claudette’s Source](https://claudette.answer.ai/core.html) to read it,
or clone the git repo and execute the notebook yourself to see every
step of the creation process in action. The tutorial below includes
links to API details which will take you to relevant parts of the
source. The reason this project is a new kind of literal program is
because we take seriously Knuth’s call to action, that we have a “*moral
commitment*” to never write an “*illiterate program*” – and so we have a
commitment to making literate programming an easy and pleasant
experience. (For more on this, see [this
talk](https://www.youtube.com/watch?v=rX1yGxJijsI) from Hamel Husain.)
> “*Let us change our traditional attitude to the construction of
> programs: Instead of imagining that our main task is to instruct a
> **computer** what to do, let us concentrate rather on explaining to
> **human beings** what we want a computer to do.*” Donald E. Knuth,
> [Literate
> Programming](https://www.cs.tufts.edu/~nr/cs257/archive/literate-programming/01-knuth-lp.pdf)
> (1984)
## Install
``` sh
pip install claudette
```
## Getting started
Anthropic’s Python SDK will automatically be installed with Claudette,
if you don’t already have it.
``` python
import os
# os.environ['ANTHROPIC_LOG'] = 'debug'
```
To print every HTTP request and response in full, uncomment the above
line.
``` python
from claudette import *
```
Claudette only exports the symbols that are needed to use the library,
so you can use `import *` to import them. Alternatively, just use:
``` python
import claudette
```
…and then add the prefix `claudette.` to any usages of the module.
Claudette provides `models`, which is a list of models currently
available from the SDK.
``` python
models
```
['claude-opus-4-20250514',
'claude-sonnet-4-20250514',
'claude-3-opus-20240229',
'claude-3-7-sonnet-20250219',
'claude-3-5-sonnet-20241022']
For these examples, we’ll use Sonnet 4, since it’s awesome!
``` python
model = models[1]
model
```
'claude-sonnet-4-20250514'
## Chat
The main interface to Claudette is the
[`Chat`](https://claudette.answer.ai/core.html#chat) class, which
provides a stateful interface to Claude:
``` python
chat = Chat(model, sp="""You are a helpful and concise assistant.""")
chat("I'm Jeremy")
```
Hello Jeremy! Nice to meet you. How can I help you today?
<details>
- id: `msg_01NNfbziMKnAULhH72Upzpzg`
- content:
`[{'citations': None, 'text': 'Hello Jeremy! Nice to meet you. How can I help you today?', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 19, 'output_tokens': 18, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` python
r = chat("What's my name?")
r
```
Your name is Jeremy.
<details>
- id: `msg_01HoboBZtq6dtocz2UWht9ia`
- content:
`[{'citations': None, 'text': 'Your name is Jeremy.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 45, 'output_tokens': 8, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` python
r = chat("What's my name?")
r
```
Your name is Jeremy.
<details>
- id: `msg_01SUAYui6JS3Jf65KYfsGWhU`
- content:
`[{'citations': None, 'text': 'Your name is Jeremy.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 61, 'output_tokens': 8, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
As you see above, displaying the results of a call in a notebook shows
just the message contents, with the other details hidden behind a
collapsible section. Alternatively you can `print` the details:
``` python
print(r)
```
Message(id='msg_01SUAYui6JS3Jf65KYfsGWhU', content=[TextBlock(citations=None, text='Your name is Jeremy.', type='text')], model='claude-sonnet-4-20250514', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 61; Out: 8; Cache create: 0; Cache read: 0; Total Tokens: 69; Search: 0)
Claude supports adding an extra `assistant` message at the end, which
contains the *prefill* – i.e. the text we want Claude to assume the
response starts with. Let’s try it out:
``` python
chat("Concisely, what is the meaning of life?",
prefill='According to Douglas Adams,')
```
According to Douglas Adams,it’s 42. More seriously, many find meaning
through relationships, personal growth, contributing to others, and
pursuing what brings fulfillment.
<details>
- id: `msg_01UkHn37YePdXg8NVrXk9Qu3`
- content:
`[{'citations': None, 'text': "According to Douglas Adams,it's 42. More seriously, many find meaning through relationships, personal growth, contributing to others, and pursuing what brings fulfillment.", 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 89, 'output_tokens': 32, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
You can add `stream=True` to stream the results as soon as they arrive
(although you will only see the gradual generation if you execute the
notebook yourself, of course!)
``` python
for o in chat("Concisely, what book was that in?", prefill='It was in', stream=True):
print(o, end='')
```
It was in "The Hitchhiker's Guide to the Galaxy."
### Async
Alternatively, you can use
[`AsyncChat`](https://claudette.answer.ai/async.html#asyncchat) (or
[`AsyncClient`](https://claudette.answer.ai/async.html#asyncclient)) for
the async versions, e.g:
``` python
chat = AsyncChat(model)
await chat("I'm Jeremy")
```
Nice to meet you, Jeremy! How are you doing today? Is there anything I
can help you with?
<details>
- id: `msg_01HyDqMjwcKEc2V39xLWTwFf`
- content:
`[{'citations': None, 'text': 'Nice to meet you, Jeremy! How are you doing today? Is there anything I can help you with?', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 10, 'output_tokens': 25, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Remember to use `async for` when streaming in this case:
``` python
async for o in await chat("Concisely, what is the meaning of life?",
prefill='According to Douglas Adams,', stream=True):
print(o, end='')
```
According to Douglas Adams,it's 42. But more seriously, the meaning of life is likely something you create through your relationships, contributions, growth, and what brings you fulfillment - rather than something you discover pre-made.
## Prompt caching
Claude supports [prompt
caching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching),
which can significantly reduce token usage costs when working with large
contexts or repetitive elements. When you use `mk_msg(msg, cache=True)`,
Claudette adds the necessary cache control headers to make that message
cacheable.
Prompt caching works by marking segments of your prompt for efficient
reuse. When a cached segment is encountered again, Claude reads it from
the cache rather than processing the full content, resulting in a 90%
reduction in token costs for those segments.
Some key points about prompt caching: - Cache writes cost 25% more than
normal input tokens - Cache reads cost 90% less than normal input
tokens - Minimum cacheable length is model-dependent (1024-2048
tokens) - Cached segments must be completely identical to be reused -
Works well for system prompts, tool definitions, and large context
blocks
For instance, here we use caching when asking about Claudette’s readme
file:
``` python
chat = Chat(model, sp="""You are a helpful and concise assistant.""")
```
``` python
nbtxt = Path('README.txt').read_text()
msg = f'''<README>
{nbtxt}
</README>
In brief, what is the purpose of this project based on the readme?'''
r = chat(mk_msg(msg, cache=True))
r
```
Based on the README, Claudette is a high-level wrapper for Anthropic’s
Python SDK that aims to simplify and automate working with Claude’s API.
Its main purposes are:
1. **Reduce boilerplate and manual work** - It automates tasks that
would otherwise require manual handling with the base SDK
2. **Provide convenient features** like:
- Stateful chat dialogs via the
[`Chat`](https://claudette.answer.ai/core.html#chat) class
- Support for prefill (controlling Claude’s response start)
- Easy image handling
- Simplified tool use API
- Prompt caching support
3. **Maintain full control** while providing automation - you get
convenience without losing flexibility
4. **Educational value** - It’s the first “literate nbdev” project,
meaning the source code is written as a readable Jupyter Notebook
with detailed explanations, making it both functional software and a
teaching resource
The project essentially makes Claude’s API more ergonomic and
user-friendly while preserving all the underlying capabilities.
<details>
- id: `msg_011SNy9u95nspNq6PSnQuwBF`
- content:
`[{'citations': None, 'text': 'Based on the README, Claudette is a high-level wrapper for Anthropic\'s Python SDK that aims to simplify and automate working with Claude\'s API. Its main purposes are:\n\n1. **Reduce boilerplate and manual work** - It automates tasks that would otherwise require manual handling with the base SDK\n2. **Provide convenient features** like:\n - Stateful chat dialogs via the [`Chat`](https://claudette.answer.ai/core.html#chat) class\n - Support for prefill (controlling Claude\'s response start)\n - Easy image handling\n - Simplified tool use API\n - Prompt caching support\n\n3. **Maintain full control** while providing automation - you get convenience without losing flexibility\n\n4. **Educational value** - It\'s the first "literate nbdev" project, meaning the source code is written as a readable Jupyter Notebook with detailed explanations, making it both functional software and a teaching resource\n\nThe project essentially makes Claude\'s API more ergonomic and user-friendly while preserving all the underlying capabilities.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 9287, 'input_tokens': 4, 'output_tokens': 223, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
The response records the a cache has been created using these input
tokens:
``` python
print(r.usage)
```
Usage(cache_creation_input_tokens=0, cache_read_input_tokens=9287, input_tokens=4, output_tokens=223, server_tool_use=None, service_tier='standard')
We can now ask a followup question in this chat:
``` python
r = chat('How does it make tool use more ergonomic?')
r
```
Based on the README, Claudette makes tool use more ergonomic in several
key ways:
## 1. **Simplified Function Definitions**
Uses docments to make Python function definitions more user-friendly -
you just need type hints and comments:
``` python
def sums(
a:int, # First thing to sum
b:int=1 # Second thing to sum
) -> int: # The sum of the inputs
"Adds a + b."
return a + b
```
## 2. **Automatic Tool Execution**
Handles the tool calling process automatically. When Claude returns a
`tool_use` message, you just call `chat()` again and Claudette: - Calls
the tool with the provided parameters - Passes the result back to
Claude - Returns Claude’s final response
No manual parameter extraction or result handling needed.
## 3. **Multi-step Tool Workflows**
The `toolloop` method can handle multiple tool calls in sequence to
solve complex problems. For example, calculating `(a+b)*2` automatically
uses both addition and multiplication tools in the right order.
## 4. **Easy Tool Integration**
- Pass tools as a simple list to the
[`Chat`](https://claudette.answer.ai/core.html#chat) constructor
- Optionally force tool usage with `tool_choice` parameter
- Get structured data directly with
[`Client.structured()`](https://claudette.answer.ai/core.html#client.structured)
## 5. **Reduced Complexity**
Instead of manually handling tool use messages, parameter parsing,
function calls, and result formatting that the base SDK requires,
Claudette abstracts all of this away while maintaining full
functionality.
This makes tool use feel more like natural function calling rather than
complex API orchestration.
<details>
- id: `msg_01XDJNpxiTkhTY9kbu17Q73L`
- content:
```` [{'citations': None, 'text': 'Based on the README, Claudette makes tool use more ergonomic in several key ways:\n\n## 1. **Simplified Function Definitions**\nUses docments to make Python function definitions more user-friendly - you just need type hints and comments:\n\n```python\ndef sums(\n a:int, # First thing to sum\n b:int=1 # Second thing to sum\n) -> int: # The sum of the inputs\n "Adds a + b."\n return a + b\n```\n\n## 2. **Automatic Tool Execution**\nHandles the tool calling process automatically. When Claude returns a ````tool_use`message, you just call`chat()`again and Claudette:\n- Calls the tool with the provided parameters\n- Passes the result back to Claude\n- Returns Claude\'s final response\n\nNo manual parameter extraction or result handling needed.\n\n## 3. **Multi-step Tool Workflows**\nThe`toolloop`method can handle multiple tool calls in sequence to solve complex problems. For example, calculating`(a+b)\*2`automatically uses both addition and multiplication tools in the right order.\n\n## 4. **Easy Tool Integration**\n- Pass tools as a simple list to the [`Chat`](https://claudette.answer.ai/core.html#chat) constructor\n- Optionally force tool usage with`tool_choice`parameter\n- Get structured data directly with [`Client.structured()`](https://claudette.answer.ai/core.html#client.structured)\n\n## 5. **Reduced Complexity**\nInstead of manually handling tool use messages, parameter parsing, function calls, and result formatting that the base SDK requires, Claudette abstracts all of this away while maintaining full functionality.\n\nThis makes tool use feel more like natural function calling rather than complex API orchestration.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 9287, 'input_tokens': 241, 'output_tokens': 374, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
We can see that this only used ~200 regular input tokens – the 7000+
context tokens have been read from cache.
``` python
print(r.usage)
```
Usage(cache_creation_input_tokens=0, cache_read_input_tokens=9287, input_tokens=241, output_tokens=374, server_tool_use=None, service_tier='standard')
``` python
chat.use
```
In: 245; Out: 597; Cache create: 0; Cache read: 18574; Total Tokens: 19416; Search: 0
## Tool use
[Tool use](https://docs.anthropic.com/claude/docs/tool-use) lets Claude
use external tools.
We use [docments](https://fastcore.fast.ai/docments.html) to make
defining Python functions as ergonomic as possible. Each parameter (and
the return value) should have a type, and a docments comment with the
description of what it is. As an example we’ll write a simple function
that adds numbers together, and will tell us when it’s being called:
``` python
def sums(
a:int, # First thing to sum
b:int=1 # Second thing to sum
) -> int: # The sum of the inputs
"Adds a + b."
print(f"Finding the sum of {a} and {b}")
return a + b
```
Sometimes Claude will try to add stuff up “in its head”, so we’ll use a
system prompt to ask it not to.
``` python
sp = "Always use tools if math ops are needed."
```
We’ll get Claude to add up some long numbers:
``` python
a,b = 604542,6458932
pr = f"What is {a}+{b}?"
pr
```
'What is 604542+6458932?'
To use tools, pass a list of them to
[`Chat`](https://claudette.answer.ai/core.html#chat):
``` python
chat = Chat(model, sp=sp, tools=[sums])
```
To force Claude to always answer using a tool, set `tool_choice` to that
function name. When Claude needs to use a tool, it doesn’t return the
answer, but instead returns a `tool_use` message, which means we have to
call the named tool with the provided parameters.
``` python
r = chat(pr, tool_choice='sums')
r
```
Finding the sum of 604542 and 6458932
ToolUseBlock(id=‘toolu_01UUWNqtkMHQss345r1ir17q’, input={‘a’: 604542,
‘b’: 6458932}, name=‘sums’, type=‘tool_use’)
<details>
- id: `msg_0199dXeVq11rc2veGNJVWc4k`
- content:
`[{'id': 'toolu_01UUWNqtkMHQss345r1ir17q', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 445, 'output_tokens': 53, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Claudette handles all that for us – we just call it again, and it all
happens automatically:
``` python
chat()
```
604542 + 6458932 = 7,063,474
<details>
- id: `msg_014wmCxnwQpgvnqKKto3RrxA`
- content:
`[{'citations': None, 'text': '604542 + 6458932 = 7,063,474', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 527, 'output_tokens': 19, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
You can see how many tokens have been used at any time by checking the
`use` property. Note that (as of May 2024) tool use in Claude uses a
*lot* of tokens, since it automatically adds a large system prompt.
``` python
chat.use
```
In: 972; Out: 72; Cache create: 0; Cache read: 0; Total Tokens: 1044; Search: 0
We can do everything needed to use tools in a single step, by using
[`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop).
This can even call multiple tools as needed solve a problem. For
example, let’s define a tool to handle multiplication:
``` python
def mults(
a:int, # First thing to multiply
b:int=1 # Second thing to multiply
) -> int: # The product of the inputs
"Multiplies a * b."
print(f"Finding the product of {a} and {b}")
return a * b
```
Now with a single call we can calculate `(a+b)*2` – by passing
`show_trace` we can see each response from Claude in the process:
``` python
chat = Chat(model, sp=sp, tools=[sums,mults])
pr = f'Calculate ({a}+{b})*2'
pr
```
'Calculate (604542+6458932)*2'
``` python
for o in chat.toolloop(pr): display(o)
```
Finding the sum of 604542 and 6458932
I’ll help you calculate (604542+6458932)\*2. I need to first add the two
numbers, then multiply the result by 2.
<details>
- id: `msg_019DZznw7qiEM2uEEcpNTnKs`
- content:
`[{'citations': None, 'text': "I'll help you calculate (604542+6458932)*2. I need to first add the two numbers, then multiply the result by 2.", 'type': 'text'}, {'id': 'toolu_016NZ7MtE8oWHs5BSkxMcAN7', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 539, 'output_tokens': 105, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` json
{ 'content': [ { 'content': '7063474',
'tool_use_id': 'toolu_016NZ7MtE8oWHs5BSkxMcAN7',
'type': 'tool_result'}],
'role': 'user'}
```
Finding the product of 7063474 and 2
Now I’ll multiply that result by 2:
<details>
- id: `msg_01LmQiMRWAtTQz6sChqsbtMy`
- content:
`[{'citations': None, 'text': "Now I'll multiply that result by 2:", 'type': 'text'}, {'id': 'toolu_019BQuhBzEkCWC1JMp6VtcfD', 'input': {'a': 7063474, 'b': 2}, 'name': 'mults', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 659, 'output_tokens': 82, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` json
{ 'content': [ { 'content': '14126948',
'tool_use_id': 'toolu_019BQuhBzEkCWC1JMp6VtcfD',
'type': 'tool_result'}],
'role': 'user'}
```
The answer is **14,126,948**.
To break it down: - 604,542 + 6,458,932 = 7,063,474 - 7,063,474 × 2 =
14,126,948
<details>
- id: `msg_0119DdeQ2goLFwGkXTXHFDsv`
- content:
`[{'citations': None, 'text': 'The answer is **14,126,948**.\n\nTo break it down:\n- 604,542 + 6,458,932 = 7,063,474\n- 7,063,474 × 2 = 14,126,948', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 756, 'output_tokens': 61, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
## Structured data
If you just want the immediate result from a single tool, use
[`Client.structured`](https://claudette.answer.ai/core.html#client.structured).
``` python
cli = Client(model)
```
``` python
def sums(
a:int, # First thing to sum
b:int=1 # Second thing to sum
) -> int: # The sum of the inputs
"Adds a + b."
print(f"Finding the sum of {a} and {b}")
return a + b
```
``` python
cli.structured("What is 604542+6458932", sums)
```
Finding the sum of 604542 and 6458932
[7063474]
This is particularly useful for getting back structured information,
e.g:
``` python
class President:
"Information about a president of the United States"
def __init__(self,
first:str, # first name
last:str, # last name
spouse:str, # name of spouse
years_in_office:str, # format: "{start_year}-{end_year}"
birthplace:str, # name of city
birth_year:int # year of birth, `0` if unknown
):
assert re.match(r'\d{4}-\d{4}', years_in_office), "Invalid format: `years_in_office`"
store_attr()
__repr__ = basic_repr('first, last, spouse, years_in_office, birthplace, birth_year')
```
``` python
cli.structured("Provide key information about the 3rd President of the United States", President)
```
[President(first='Thomas', last='Jefferson', spouse='Martha Wayles Skelton Jefferson', years_in_office='1801-1809', birthplace='Shadwell, Virginia', birth_year=1743)]
## Images
Claude can handle image data as well. As everyone knows, when testing
image APIs you have to use a cute puppy.
``` python
fn = Path('samples/puppy.jpg')
Image(filename=fn, width=200)
```
<img src="index_files/figure-commonmark/cell-35-output-1.jpeg"
width="200" />
We create a [`Chat`](https://claudette.answer.ai/core.html#chat) object
as before:
``` python
chat = Chat(model)
```
Claudette expects images as a list of bytes, so we read in the file:
``` python
img = fn.read_bytes()
```
Prompts to Claudette can be lists, containing text, images, or both, eg:
``` python
chat([img, "In brief, what color flowers are in this image?"])
```
The flowers in this image are purple.
<details>
- id: `msg_01N2NCd5JW3gNsGysgmyMx9F`
- content:
`[{'citations': None, 'text': 'The flowers in this image are purple.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 110, 'output_tokens': 11, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
The image is included as input tokens.
``` python
chat.use
```
In: 110; Out: 11; Cache create: 0; Cache read: 0; Total Tokens: 121; Search: 0
Alternatively, Claudette supports creating a multi-stage chat with
separate image and text prompts. For instance, you can pass just the
image as the initial prompt (in which case Claude will make some general
comments about what it sees), and then follow up with questions in
additional prompts:
``` python
chat = Chat(model)
chat(img)
```
What an adorable puppy! This looks like a Cavalier King Charles Spaniel
puppy with the classic Blenheim coloring (chestnut and white markings).
The puppy has those characteristic sweet, gentle eyes and silky coat
that the breed is known for. The setting with the purple flowers in the
background makes for a lovely portrait - it really highlights the
puppy’s beautiful coloring and sweet expression. Cavalier King Charles
Spaniels are known for being friendly, affectionate companions. Is this
your puppy?
<details>
- id: `msg_01Jat1obwo79eEz5JMFAF4Mh`
- content:
`[{'citations': None, 'text': "What an adorable puppy! This looks like a Cavalier King Charles Spaniel puppy with the classic Blenheim coloring (chestnut and white markings). The puppy has those characteristic sweet, gentle eyes and silky coat that the breed is known for. The setting with the purple flowers in the background makes for a lovely portrait - it really highlights the puppy's beautiful coloring and sweet expression. Cavalier King Charles Spaniels are known for being friendly, affectionate companions. Is this your puppy?", 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 98, 'output_tokens': 118, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` python
chat('What direction is the puppy facing?')
```
The puppy is facing toward the camera/viewer. You can see the puppy’s
face straight-on, with both eyes visible and looking directly at the
camera. The puppy appears to be lying down with its head up and oriented
forward, giving us a clear frontal view of its sweet face.
<details>
- id: `msg_018EqaD7EFveLCzSPbQmMMuE`
- content:
`[{'citations': None, 'text': "The puppy is facing toward the camera/viewer. You can see the puppy's face straight-on, with both eyes visible and looking directly at the camera. The puppy appears to be lying down with its head up and oriented forward, giving us a clear frontal view of its sweet face.", 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 227, 'output_tokens': 65, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` python
chat('What color is it?')
```
The puppy has a chestnut (reddish-brown) and white coat. The ears and
patches around the eyes are a rich chestnut or reddish-brown color,
while the face has a white blaze down the center and the chest/front
appears to be white as well. This is the classic “Blenheim” color
pattern that’s common in Cavalier King Charles Spaniels - the
combination of chestnut and white markings.
<details>
- id: `msg_01HzUTvRziMrSfdEjbo1kHnh`
- content:
`[{'citations': None, 'text': 'The puppy has a chestnut (reddish-brown) and white coat. The ears and patches around the eyes are a rich chestnut or reddish-brown color, while the face has a white blaze down the center and the chest/front appears to be white as well. This is the classic "Blenheim" color pattern that\'s common in Cavalier King Charles Spaniels - the combination of chestnut and white markings.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 300, 'output_tokens': 103, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Note that the image is passed in again for every input in the dialog, so
that number of input tokens increases quickly with this kind of chat.
(For large images, using prompt caching might be a good idea.)
``` python
chat.use
```
In: 625; Out: 286; Cache create: 0; Cache read: 0; Total Tokens: 911; Search: 0
## Extended Thinking
Claude \>=3.7 Sonnet and Opus have enhanced reasoning capabilities
through [extended
thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking).
This feature allows Claude to think through complex problems
step-by-step, making its reasoning process transparent and its final
answers more reliable.
To enable extended thinking, simply specify the number of thinking
tokens using the `maxthinktok` parameter when making a call to Chat. The
thinking process will appear in a collapsible section in the response.
Some important notes about extended thinking:
- Only available with select models
- Automatically sets `temperature=1` when enabled (required for thinking
to work)
- Cannot be used with `prefill` (these features are incompatible)
- Thinking is presented in a separate collapsible block in the response
- The thinking tokens count toward your usage but help with complex
reasoning
To access models that support extended thinking, you can use
`has_extended_thinking_models`.
``` python
has_extended_thinking_models
```
{'claude-3-7-sonnet-20250219',
'claude-opus-4-20250514',
'claude-sonnet-4-20250514'}
``` python
chat = Chat(model)
```
``` python
chat('Write a sentence about Python!', maxthinktok=1024)
```
Python is a versatile, high-level programming language known for its
readable syntax and extensive libraries, making it popular for
everything from web development to data science and machine learning.
<details>
<summary>
Thinking
</summary>
The user is asking for a sentence about Python. Since they didn’t
specify, this could refer to either: 1. Python the programming language
2. Python the snake
Given the context and common usage, they’re most likely referring to the
programming language Python. I’ll write a sentence about Python the
programming language that’s informative and concise.
</details>
<details>
- id: `msg_017EgYhUjsQxWkXN1zrRjFxK`
- content:
`[{'signature': 'EokECkYIBBgCKkDNuftW7kYi6z6RSuzj4DNdtNRxcj486/U8U2NJHg51M+vGmQ1eN7ypz+w4/tpZCFHgWR9KFPXElnHrp3SkoWJrEgzJthIeSKqmoUbrP5YaDKGgUdib0TYhZriKcCIwDrQ2GTZ3D7zE0RVouKJLbzyRl+sQ6FQ+NwNQb5qrHw5Ylmzqxxk4Sa4GuzOEY8zVKvAC+7LfNqCd7jBjPVqaoSRmCubkKuWWeg60G39UCYm/W9VUsrDT1IHLTvOuK3KOYTQL1zqWt1XlBFj52haZIWRmjVU1w2S8EyKIJIThNRYFfT9CDuAeCYwUae8BFL4wm/MEUw+2tDNH3ei7JUvb4sk17cTrePvzpiQNtmHN8TctDBP2RgD7PpTUbjNUsvoRJFBSLLfNsd8wlvAkcph96fDV5dUJ/W3mkluG4XbTTY3ns/rlikAFLTphaoXeqM6buvm889Sep8BQdHuujHcuKWD3auTusayXE5O/9yYcWrU9qPxZ2bxF72tZ1Y65bTBYzhm9ohtB1LTy0x0XvOS76gfGZ8XaJ4vj3OMz1Cn5GSTCNbELTHHVBh5azPSCI9Qu44/ZBE2ZsFA0mtPCiP8cyhZmzAaHFnz2QaKwuTlfz5VnDPmNSNy8rqHywWlkMMA4g9+0SDZSxYJkCYBO+OUs1gNqlwwJQUyYOc1SEmpBkVQee2kYAQ==', 'thinking': "The user is asking for a sentence about Python. Since they didn't specify, this could refer to either:\n1. Python the programming language\n2. Python the snake\n\nGiven the context and common usage, they're most likely referring to the programming language Python. I'll write a sentence about Python the programming language that's informative and concise.", 'type': 'thinking'}, {'citations': None, 'text': 'Python is a versatile, high-level programming language known for its readable syntax and extensive libraries, making it popular for everything from web development to data science and machine learning.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 41, 'output_tokens': 119, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
## Web Search and Server Tools
Claude supports server-side tools that run on Anthropic’s
infrastructure. The flagship example is the web search tool, which
allows Claude to search the web for up-to-date information to answer
questions.
Unlike client-side tools (where you provide functionality), server-side
tools are managed by Anthropic. Claudette makes these easy to use with
helper functions like
[`search_conf()`](https://claudette.answer.ai/core.html#search_conf).
``` python
chat = Chat(model, sp='Be concise in your responses.', tools=[search_conf()])
pr = 'What is the current weather in San Diego?'
r = chat(pr)
r
```
Based on the search results, here’s the current weather information for
San Diego:
Today (Saturday, June 21st) has a high of 67°F [^1] [^2] with cloudy
conditions early with partial sunshine expected later [^3]. Winds are
from the SSW at 10 to 15 mph [^4].
Tonight’s low will be around 62°F with overcast conditions and SSW winds
at 10 to 15 mph [^5].
Temperatures are running about 4-7 degrees below normal for most areas
[^6], making it a cooler day than typical for this time of year in San
Diego.
Air quality is currently at an unhealthy level for sensitive groups, so
those with breathing sensitivities should reduce outdoor time if
experiencing symptoms [^7].
<details>
- id: `msg_01Kg3aNFF7ibUcWZxPpFNmu8`
- content:
`[{'id': 'srvtoolu_01YazfLE5GfK4ET2Z4rsfcuz', 'input': {'query': 'San Diego weather today'}, 'name': 'web_search', 'type': 'server_tool_use'}, {'content': [{'encrypted_content': 'EqcCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDF5HWNC1GnRw10SRnBoMsafoy8BqdMy4chO3IjALzgdeA/d4dT1Qx7JKFu6XeXmrHYIe2lxVFl7TqZkRDnKmPpA6mnvpkwGh9eW8RJgqqgGtR4kEv8KoMeWf9VHjh1oYyscLkN5LJq00R4X3C/Cfw9oLLdIAiN9tvq9g2Rzm0Qb/IP5GcdVfiwx7w5dRfL67oaWQ5IFIXSvv9ByLW/ERFI30UKhhKFYumApVuZEIge6CL0j56OQFXAkPVENWIlSnro+9BIKgf866WWvRo0kx2d+SiX9p3ainG+Zqbl55Bq+mvyOUgVabtSEfr+oY6FQPJYYT9ad0QxYUOxgD', 'page_age': '3 days ago', 'title': '10-Day Weather Forecast for San Diego, CA - The Weather Channel | weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/tenday/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': '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', 'page_age': '3 days ago', 'title': 'San Diego, CA Weather Forecast | AccuWeather', 'type': 'web_search_result', 'url': 'https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628'}, {'encrypted_content': 'Er0ECioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDBGutrl0Yo/Ph3ytgxoMmv0PMZzhuX1bUMAaIjB8A47OiTekaB3+wTaHtqniXxv1Syc6JTwDJgaWgpy/MxfY+iOIS58xXsHOd7d/vrUqwAOQc9TMOqSb0LGZCGaGxIwiXICeBOu9KYGmqzNtUJm31yQlCGwdOFeznCgec0B2/jhLUZMpoDuoL3ayVUeBYC7IlyW4Lrh7DR8+MUOf27YxozzhkdWKDDDqCf0hN40Qn69bGemDOFejCWrTyCj8ffYa29MAKRcAvQv0TQUehsNOy0xKYzeBA2z9zjzZp9GOesvqBv5/2AxQrVwygU31bLYEeiqHqLrfeQ798HK9oDFlAiHaS/gWmpK1+0d3UA+Y5KCKipBmUxy15LkEmoG0MoG3/OEDZ7mOGuuY5RqCW4hkdT4dzm6OsKfmiLoDG/XI2HNkpcTnCd3tO0yUZdwY3lX4vSjAS2wvFxNsl7b8YbaKM/U8H3JaTVntwyh7GHWYezHYaYXNiMK05KcQMKJlP/bZx82sQkq83jl15k55Nf5NR/R/1PHi/fqzLDwPOSug5RJ8dwdduWd1SF4qcfStBaOZ4fRdTwbxJgiAC6gmxWMAGfXg29iVSNsTBYVaGk+GPrUSIFxU0x36xejO0Vaz7wHL6XPwjvXMhVrWbuf5xMXKRNW3XG3X0AEB7h40x+0MN23BmmJ9G6+JQ5Ngog6z2An4GAM=', 'page_age': '3 days ago', 'title': 'San Diego weather forecast – NBC 7 San Diego', 'type': 'web_search_result', 'url': 'https://www.nbcsandiego.com/weather/'}, {'encrypted_content': 'EpcCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDGlljWS7qosG4mSt3BoM6gy+Gh0f2zdXJ8kAIjAL5PfnNZR7Vex2zcFoqLody/xA+Yyoob62LVGMQ4+EhXd4CKgvxQEfpQLQgVvIH3UqmgGByQGU45dvgEJrKexyCEvra2CIAoYOTUiKNt6p7dVfp8++dfq28UU2mt5h10bL8ul8y0xeBu6new/tfwFJ6+GS/Bh6p+M+p87Jy65QQ/dgMhV+M7q3EAQUZjh642YMayI4nimm2yIwbLzNRXEszsp2kdmKKhxDpO3C5wp8fWLy5UpWvimjh5WSMnAzEpMoVDqD99FavgHvaPF7GAM=', 'page_age': '3 days ago', 'title': 'Weather Forecast and Conditions for San Diego, CA - The Weather Channel | Weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/today/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': 'ErEDCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKDodoc/BpOij6btVBoMdtlDIIQ1rjzAl3XyIjAUXhC+GWPaQwx74WpJR7Xo+cVP0RjwhWd5LPSL+skOIE8sHVqz0Ry9jmq5jGri3wcqtAJrH5qNCAGieGFHQijAS1lfA2rn0EDH/tLBmC4nKW0MGQz/NLn49FuAcJuEZrw2149zcJ88XQ18hVEhWTkZ/BNEBujb9+M+QthIUUOPf6RplEX+DThq1KIuqbR0XBh71qThLM5ZfBjcvYS4429hpEP5DJo2FP0nqr9Ps8GX/hvIik33EXc4X3x16d649qqcRFwByb1DhE+NZVTiuu4WfljWXWBs+17ezkxxWazj3E9GtLBIL98fnMoOf4p9oTI8EgWe4RjcGqEaI6DWqlGquNgkc4IeqlzVkjWP4v90HoI7oegcDKtK/n+8pNaGqyBQizgf1NglM2gRBj3cZ9kt7cDX8p1KpmXrGsOSEK3mn6RAnjlsFQ2x7UjM7l980KCVKnqeguR0ZkCsvB+KM0AputjxlU+KrBgD', 'page_age': '3 days ago', 'title': 'San Diego, CA', 'type': 'web_search_result', 'url': 'https://www.weather.gov/sgx/'}, {'encrypted_content': 'EpkCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDLXJ+1Ii8XIJ7AwW/xoMMbTKEdT8hw2J9bdSIjBYWJur7pQQqNijCyZjeN+VSYcaZe7xE/09hGS23TOjFLdvrOhGAMVSd3e2IDGUHCEqnAG6GJZO/sDcDEeEn/sobNJbNjM9VfNoJZEg+f/lZ+KXtMJELQ2Q14ot0iqQ0qKEjDxz3OMLkAYJg3uqeVMOq5QLgz6MNANEoCU+koTqIiYGZ++8Y0tKdtVD/Xrm0QW0fFkdJcN1PVt+6fN8aDJ5+95phOw5vEmRS9FRWg6aLDIwpxaNJ6z+Wbpff8zoSGUcPZFaFIUjAAU6qnx8kRoYAw==', 'page_age': None, 'title': 'San Diego, CA Weather Forecast | KGTV | kgtv.com', 'type': 'web_search_result', 'url': 'https://www.10news.com/weather'}, {'encrypted_content': 'EpQCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDHL0i7qnzUCM4zRRAhoMAv3yQhl4BrqFyb0nIjBsyvNyrS90lUKCO/9admV9eU8x96+nDdrodoVAe9lpT2fNstMu4pS2Aer192MKKnwqlwGnu1DfFtpu/sSeugS3SUtYxT+ulZYw+ZQwhqLMOf+UadP2PrCAEDh5CM2pF4fMHRdt9GBYTgOA/3ug6W2Ci30q5QXwdiNC/7X2KQV6QrU83m//vy92K8PO9dwqv4B0T8uCSY18O+BtHHlZrzmzPgIWm4OTP2+Blh+f3X+yRubR9JiBehxtgS/IGmdWhzv6QjIbcFy5bhNDGAM=', 'page_age': '1 week ago', 'title': 'Hourly Weather Forecast for San Diego, CA - The Weather Channel | Weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/hourbyhour/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': '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', 'page_age': None, 'title': 'San Diego, CA 10-Day Weather Forecast | Weather Underground', 'type': 'web_search_result', 'url': 'https://www.wunderground.com/forecast/us/ca/san-diego'}, {'encrypted_content': 'Ev0ECioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDFqrWvXcDBaRhAEIERoMEMwkIlYRNrbpob8qIjAGpulVwN56DZ4z4+PuEB3gdYm6QZ5Qvq+6RFvOLnEGDg+mpsIvb2TL4iauDizcEsUqgAT3/Sza241GQ6OmRz38xfUdXYqE5zatMSVDZ8Pzsd11fgBJg8voUcxKfPRPQWlA8FYW8+K4vDvv5cahR9rbVN829R/VQxq7YdcMsD9D5pbk9WButOmQLwI5/MsvnKo0MJ2e6kVcI1DVTwwHxoF0AJdkXUm/9x5danZ35QmA3FIR+7AOBCgtlOmwwIO1nTB+x6+8gf8DB0Jsgv6scqI/PqYxTYH8pZUEs3sA0pXQWJIcbtbWPRqxvfr6KYTtBAKJcr4XmsOMdi4OhVxzXhed1OjB1Jvebhi7Z+CbOOEZBuL2T7inzxoNlHvd3rhuZoDzpb9IWEMx/29fjwWhy+ztWi4Fdl25QgpWokl9cjDtq+6DEkf97+5ks6oVZU1dKoKq2y6S7cT3SL30IOzpdNox9Nh9FrOZeui/aT2zD7imuB+dyx9ffHi07Ulje7R9UWwBvDzRPMP4Ilwe4nrcQWWloso80KTfIixUTmel1bPKxVdrag/2+4kD6ahHpm2cLazWqTc+GvVY5+IRb2C5Y6pve4tWPVZC584151GHbdDZB2FamZJsdBlVL5VAF7Cz2U2mukxcuFF7Vwh3lpvpuqkldp4yWf2UJVpGMOOgDMgRi9qn+fAqE9jEIKoqXRhrVnKlgAlMGpnFfxu1IvxOLQQRqCNRltm5whIy5YhZa+7bllx+NRgD', 'page_age': '3 days ago', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}, {'encrypted_content': 'Ev8CCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDOOoeUPUoDED8O83ZhoM30uUue3UQ1WQ6At6IjD+k7S7lYoiPFc5urIX1kWyFxcLj14bmNmI9YackQTQAU27o6IGbFdwaU+40URG2xQqggLYvUzF4uC9bk9e+C5CbKLU1WAsE7Nsb3YpFYsFiwMKqPamqEVSZE/xxUGQZ9w5tbtftdchhIs0bupnPj+G3BgO+ivdO9VcHBrqJwOk+hQ+XhQp3kLRubgZ9ozPpTZDK0xhpuFh18mFwsHgi/dIH478C1yYA50B0d/qL5C4V6NdYfDYsOXL0Ce1y4L8JxlUi//BPq23m1FfJeVo0vPYKTWm0D2TGTEnLygV9ZI9/wUF5H+gDYimj/QJZW1MWWf7bUQl85I1AyroDE2h8pae6FT0VTVWWIUJiBOWr48xbjieS+LHRxP7/XhpZpI2x0zz3WLi1BYdxHH04yxnjxLcQILrOuoYAw==', 'page_age': '5 days ago', 'title': 'National Weather Service', 'type': 'web_search_result', 'url': 'https://forecast.weather.gov/zipcity.php?inputstring=San+Diego,CA/'}], 'tool_use_id': 'srvtoolu_01YazfLE5GfK4ET2Z4rsfcuz', 'type': 'web_search_tool_result'}, {'citations': None, 'text': "Based on the search results, here's the current weather information for San Diego:\n\n", 'type': 'text'}, {'citations': [{'cited_text': 'TomorrowSat 06/21 High · 67 °F · 14% Precip. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKwATF21Da6JaeprrRoMR4n2dYDzq6Grz6kOIjDubzeZ5yWRJE4JTY/En0I9Ue7hW3xNHVY1Nb651cmT84e3E/CK5IihYjOjT0ri+bMqEzkJobhLc+mcf18NFKDVD/eXWJkYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}, {'cited_text': 'High 67F. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDBZRJenhcEsF45RP3hoM9byW9q+/yaWr+G32IjAOpd1oMmv1j3abI8JHjvI1b5ZvEPvFR0RzxtY1jsxEyRv9IJkysuqnmbSwH3g32TgqE+VO+8ZZPNjG9foScv6WV79YDUAYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'Today (Saturday, June 21st) has a high of 67°F', 'type': 'text'}, {'citations': None, 'text': ' with ', 'type': 'text'}, {'citations': [{'cited_text': '/ 0.00 °in Cloudy early with partial sunshine expected late. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDB4nMEZc/F7OchMulRoMGN8vERmCYSPIeM52IjBEWjKA8pyazlviIcAv3VdKXXstJzWI89Lth9GVQTgJe+aHBo6Z9RixGwe9H65I4iEqE6r+cdWvSki3A5y7liT1a2+EuPgYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'cloudy conditions early with partial sunshine expected later', 'type': 'text'}, {'citations': None, 'text': '. ', 'type': 'text'}, {'citations': [{'cited_text': 'Winds SSW at 10 to 15 mph. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDB45Fg4fI2lZagCjPRoM44KF0iEojWBopwrHIjBhn7dgVM1Ff/cqtJ/lTjfQ/jwVGUPTMJqvlWxrNi2vlcn6nHSZw+cUefs/Ruz/GNgqE6jMHyEpfOkI5cEy1xxL1qwAZvIYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'Winds are from the SSW at 10 to 15 mph', 'type': 'text'}, {'citations': None, 'text': '.\n\n', 'type': 'text'}, {'citations': [{'cited_text': 'Low 62F. Winds SSW at 10 to 15 mph. ', 'encrypted_index': 'EpEBCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDGs1z0BKFApU+3H2sxoMHemxpcDkrIGd4oSRIjAWWpByOKdjFHplptGY/sqWHuZVPAxLushiCw0j+aLQ3+bpwzSikTDw6Eb075la0fYqFeOQNDFP6pV830agKs390gtIQ9hn2RgE', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': "Tonight's low will be around 62°F with overcast conditions and SSW winds at 10 to 15 mph", 'type': 'text'}, {'citations': None, 'text': '.\n\n', 'type': 'text'}, {'citations': [{'cited_text': 'Cooler today with highs around 4-7 degrees below normal for most areas, still slightly above normal in the lower deserts. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKmS4xmv51SRhiupjBoM1jB2H6k2FU08pQ3GIjAV+DJ6rRuV2b6Q7ignq8PgwpnBySIrcI0FjJyUkxWXMUqYQYSPaTtiNLaSUJi1kh4qE+SXxbI2WryAsUjDE9uQS3F/91QYBA==', 'title': 'San Diego, CA', 'type': 'web_search_result_location', 'url': 'https://www.weather.gov/sgx/'}], 'text': 'Temperatures are running about 4-7 degrees below normal for most areas', 'type': 'text'}, {'citations': None, 'text': ', making it a cooler day than typical for this time of year in San Diego.\n\n', 'type': 'text'}, {'citations': [{'cited_text': 'The air has reached a high level of pollution and is unhealthy for sensitive groups. Reduce time spent outside if you are feeling symptoms such as dif...', 'encrypted_index': 'EpEBCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDK8D4vc8KfCrlx9emxoMMLnROCL/VkErH3i/IjA/9/wpz9prNlBSXXcsTY2S+xdsPRDTNhPl7sYwMQoZ1OAvK8zbv5m0QT4Z0rVOkO8qFX/4Kq1l4tkCVlYlPmm9TE6ED9r0ABgE', 'title': 'San Diego, CA Weather Forecast | AccuWeather', 'type': 'web_search_result_location', 'url': 'https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628'}], 'text': 'Air quality is currently at an unhealthy level for sensitive groups, so those with breathing sensitivities should reduce outdoor time if experiencing symptoms', 'type': 'text'}, {'citations': None, 'text': '.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 7302, 'output_tokens': 325, 'server_tool_use': {'web_search_requests': 1}, 'service_tier': 'standard'}`
</details>
The [`search_conf()`](https://claudette.answer.ai/core.html#search_conf)
function creates the necessary configuration for the web search tool.
You can customize it with several parameters:
``` python
search_conf(
max_uses=None, # Maximum number of searches Claude can perform
allowed_domains=None, # List of domains to search within (e.g., ['wikipedia.org'])
blocked_domains=None, # List of domains to exclude (e.g., ['twitter.com'])
user_location=None # Location context for search
)
```
When Claude uses the web search tool, the response includes citations
linking to the source information. Claudette automatically formats these
citations and provides them as footnotes in the response.
Web search usage is tracked separately from normal token usage in the
[`usage`](https://claudette.answer.ai/core.html#usage) statistics:
``` python
chat.use
```
In: 7302; Out: 325; Cache create: 0; Cache read: 0; Total Tokens: 7627; Search: 1
Web search requests have their own pricing. As of May 2024, web searches
cost \$10 per 1,000 requests.
## Text Editor Tool
Claudette provides support for Anthropic’s special Text Editor Tool,
which allows Claude to view and modify files directly. Unlike regular
function-calling tools, the text editor tool uses a predefined schema
built into Claude’s model.
Important notes about the text editor tool:
- It’s schema-less - you provide a configuration but not a schema
- It uses type identifiers like “text_editor_20250124” specific to
Claude models
- You must implement a dispatcher function (in Claudette, it’s
[`str_replace_based_edit_tool`](https://claudette.answer.ai/text_editor.html#str_replace_based_edit_tool))
- Different commands route through this single dispatcher function
The text editor tool allows Claude to:
- View file or directory contents
- Create new files
- Insert text at specific line numbers
- Replace text within files
``` python
from claudette.text_editor import text_editor_conf, str_replace_based_edit_tool
from toolslm.funccall import mk_ns
# Create a chat with the text editor tool
chat = Chat(model, sp='Be concise in your responses.',
tools=[text_editor_conf['sonnet']], ns=mk_ns(str_replace_based_edit_tool))
# Now Claude can explore files
for o in chat.toolloop('Please explain concisely what my _quarto.yml does. Use your tools, and explain before each usage what you are doing.'):
if not isinstance(o,dict): display(o)
```
I’ll examine your \_quarto.yml file to explain what it does. Let me
start by looking at the current directory to locate the file.
<details>
- id: `msg_01S59jijaZGLN9jq525KoDRu`
- content:
`[{'citations': None, 'text': "I'll examine your _quarto.yml file to explain what it does. Let me start by looking at the current directory to locate the file.", 'type': 'text'}, {'id': 'toolu_01NxKxWNHFroLYxTULzFnBAp', 'input': {'command': 'view', 'path': '.'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 1120, 'output_tokens': 106, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Now I can see the \_quarto.yml file exists. Let me examine its contents
to understand what it configures.
<details>
- id: `msg_015w8s5yw4RBs4dXgfLx2CDS`
- content:
`[{'citations': None, 'text': 'Now I can see the _quarto.yml file exists. Let me examine its contents to understand what it configures.', 'type': 'text'}, {'id': 'toolu_01ToUv8CSQH69Kx2ahBSwcGf', 'input': {'command': 'view', 'path': '/_Users/jhoward/aai-ws/claudette/_quarto.yml'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 2738, 'output_tokens': 120, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Let me use the correct path:
<details>
- id: `msg_01Baaa1otgra5CHimvP9Ja5s`
- content:
`[{'citations': None, 'text': 'Let me use the correct path:', 'type': 'text'}, {'id': 'toolu_01FTCbeJLRdAyfqqnq3pAQFa', 'input': {'command': 'view', 'path': '/Users/jhoward/aai-ws/claudette/_quarto.yml'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 2896, 'output_tokens': 102, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
Your `_quarto.yml` file configures a Quarto website project with the
following key settings:
**Project Configuration:** - Sets up a website project type - Includes
all `.txt` files as resources - Configures preview server on port 3000
without auto-opening browser
**HTML Formatting:** - Uses the “cosmo” theme with custom CSS from
`styles.css` - Enables table of contents, code tools, and syntax
highlighting - Sets a custom layout with wider body (1800px) and
narrower sidebar (180px) - Uses “arrow” highlight style with custom code
block styling - Keeps markdown files during rendering
**Website Features:** - Enables social media cards (Twitter and Open
Graph) - Adds a search-enabled navbar with primary background - Uses a
floating sidebar style - Links to GitHub issues via repo-actions
**Metadata Sources:** - Pulls additional configuration from `nbdev.yml`
and `sidebar.yml` files
This appears to be set up for a documentation website, likely for a
Python package using nbdev (given the nbdev.yml reference), with a focus
on displaying code and technical content with good readability and
navigation.
<details>
- id: `msg_01Ba23FNyw6xy7KdtTVnBdk6`
- content:
`[{'citations': None, 'text': 'Your`\_quarto.yml`file configures a Quarto website project with the following key settings:\n\n**Project Configuration:**\n- Sets up a website project type\n- Includes all`.txt`files as resources\n- Configures preview server on port 3000 without auto-opening browser\n\n**HTML Formatting:**\n- Uses the "cosmo" theme with custom CSS from`styles.css`\n- Enables table of contents, code tools, and syntax highlighting\n- Sets a custom layout with wider body (1800px) and narrower sidebar (180px)\n- Uses "arrow" highlight style with custom code block styling\n- Keeps markdown files during rendering\n\n**Website Features:**\n- Enables social media cards (Twitter and Open Graph)\n- Adds a search-enabled navbar with primary background\n- Uses a floating sidebar style\n- Links to GitHub issues via repo-actions\n\n**Metadata Sources:**\n- Pulls additional configuration from`nbdev.yml`and`sidebar.yml`files\n\nThis appears to be set up for a documentation website, likely for a Python package using nbdev (given the nbdev.yml reference), with a focus on displaying code and technical content with good readability and navigation.', 'type': 'text'}]`
- model: `claude-sonnet-4-20250514`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 3235, 'output_tokens': 267, 'server_tool_use': None, 'service_tier': 'standard'}`
</details>
``` python
chat.use
```
In: 9989; Out: 595; Cache create: 0; Cache read: 0; Total Tokens: 10584; Search: 0
## Other model providers
You can also use 3rd party providers of Anthropic models, as shown here.
### Amazon Bedrock
These are the models available through Bedrock:
``` python
models_aws
```
['anthropic.claude-sonnet-4-20250514-v1:0',
'claude-3-5-haiku-20241022',
'claude-3-7-sonnet-20250219',
'anthropic.claude-3-opus-20240229-v1:0',
'anthropic.claude-3-5-sonnet-20241022-v2:0']
To use them, call `AnthropicBedrock` with your access details, and pass
that to [`Client`](https://claudette.answer.ai/core.html#client):
``` python
from anthropic import AnthropicBedrock
```
``` python
ab = AnthropicBedrock(
aws_access_key=os.environ['AWS_ACCESS_KEY'],
aws_secret_key=os.environ['AWS_SECRET_KEY'],
)
client = Client(models_aws[-1], ab)
```
Now create your [`Chat`](https://claudette.answer.ai/core.html#chat)
object passing this client to the `cli` parameter – and from then on,
everything is identical to the previous examples.
``` python
chat = Chat(cli=client)
chat("I'm Jeremy")
```
### Google Vertex
These are the models available through Vertex:
``` python
models_goog
```
To use them, call `AnthropicVertex` with your access details, and pass
that to [`Client`](https://claudette.answer.ai/core.html#client):
``` python
from anthropic import AnthropicVertex
import google.auth
```
``` python
# project_id = google.auth.default()[1]
# gv = AnthropicVertex(project_id=project_id, region="us-east5")
# client = Client(models_goog[-1], gv)
```
``` python
chat = Chat(cli=client)
chat("I'm Jeremy")
```
## Extensions
- [Pydantic Structured
Ouput](https://github.com/tom-pollak/claudette-pydantic)
[^1]: https://www.wunderground.com/weather/us/ca/san-diego “TomorrowSat
06/21 High · 67 °F · 14% Precip.”
[^2]: https://www.wunderground.com/weather/us/ca/san-diego “High 67F.”
[^3]: https://www.wunderground.com/weather/us/ca/san-diego “/ 0.00 °in
Cloudy early with partial sunshine expected late.”
[^4]: https://www.wunderground.com/weather/us/ca/san-diego “Winds SSW at
10 to 15 mph.”
[^5]: https://www.wunderground.com/weather/us/ca/san-diego “Low 62F.
Winds SSW at 10 to 15 mph.”
[^6]: https://www.weather.gov/sgx/ “Cooler today with highs around 4-7
degrees below normal for most areas, still slightly above normal in
the lower deserts.”
[^7]: https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628
“The air has reached a high level of pollution and is unhealthy for
sensitive groups. Reduce time spent outside if you are feeling
symptoms such as dif…”
Raw data
{
"_id": null,
"home_page": "https://github.com/AnswerDotAI/claudette",
"name": "claudette",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "nbdev jupyter notebook python",
"author": "Jeremy Howard",
"author_email": "j@fast.ai",
"download_url": "https://files.pythonhosted.org/packages/7c/57/fe4d22acdc8920293b1eedc308ded6e56761f7b05813ce3e2a5c202d3038/claudette-0.3.1.tar.gz",
"platform": null,
"description": "# claudette\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n> **NB**: If you are reading this in GitHub\u2019s readme, we recommend you\n> instead read the much more nicely formatted [documentation\n> format](https://claudette.answer.ai/) of this tutorial.\n\n*Claudette* is a wrapper for Anthropic\u2019s [Python\nSDK](https://github.com/anthropics/anthropic-sdk-python).\n\nThe SDK works well, but it is quite low level \u2013 it leaves the developer\nto do a lot of stuff manually. That\u2019s a lot of extra work and\nboilerplate! Claudette automates pretty much everything that can be\nautomated, whilst providing full control. Amongst the features provided:\n\n- A [`Chat`](https://claudette.answer.ai/core.html#chat) class that\n creates stateful dialogs\n- Support for *prefill*, which tells Claude what to use as the first few\n words of its response\n- Convenient image support\n- Simple and convenient support for Claude\u2019s new Tool Use API.\n\nYou\u2019ll need to set the `ANTHROPIC_API_KEY` environment variable to the\nkey provided to you by Anthropic in order to use this library.\n\nNote that this library is the first ever \u201cliterate nbdev\u201d project. That\nmeans that the actual source code for the library is a rendered Jupyter\nNotebook which includes callout notes and tips, HTML tables and images,\ndetailed explanations, and teaches *how* and *why* the code is written\nthe way it is. Even if you\u2019ve never used the Anthropic Python SDK or\nClaude API before, you should be able to read the source code. Click\n[Claudette\u2019s Source](https://claudette.answer.ai/core.html) to read it,\nor clone the git repo and execute the notebook yourself to see every\nstep of the creation process in action. The tutorial below includes\nlinks to API details which will take you to relevant parts of the\nsource. The reason this project is a new kind of literal program is\nbecause we take seriously Knuth\u2019s call to action, that we have a \u201c*moral\ncommitment*\u201d to never write an \u201c*illiterate program*\u201d \u2013 and so we have a\ncommitment to making literate programming an easy and pleasant\nexperience. (For more on this, see [this\ntalk](https://www.youtube.com/watch?v=rX1yGxJijsI) from Hamel Husain.)\n\n> \u201c*Let us change our traditional attitude to the construction of\n> programs: Instead of imagining that our main task is to instruct a\n> **computer** what to do, let us concentrate rather on explaining to\n> **human beings** what we want a computer to do.*\u201d Donald E. Knuth,\n> [Literate\n> Programming](https://www.cs.tufts.edu/~nr/cs257/archive/literate-programming/01-knuth-lp.pdf)\n> (1984)\n\n## Install\n\n``` sh\npip install claudette\n```\n\n## Getting started\n\nAnthropic\u2019s Python SDK will automatically be installed with Claudette,\nif you don\u2019t already have it.\n\n``` python\nimport os\n# os.environ['ANTHROPIC_LOG'] = 'debug'\n```\n\nTo print every HTTP request and response in full, uncomment the above\nline.\n\n``` python\nfrom claudette import *\n```\n\nClaudette only exports the symbols that are needed to use the library,\nso you can use `import *` to import them. Alternatively, just use:\n\n``` python\nimport claudette\n```\n\n\u2026and then add the prefix `claudette.` to any usages of the module.\n\nClaudette provides `models`, which is a list of models currently\navailable from the SDK.\n\n``` python\nmodels\n```\n\n ['claude-opus-4-20250514',\n 'claude-sonnet-4-20250514',\n 'claude-3-opus-20240229',\n 'claude-3-7-sonnet-20250219',\n 'claude-3-5-sonnet-20241022']\n\nFor these examples, we\u2019ll use Sonnet 4, since it\u2019s awesome!\n\n``` python\nmodel = models[1]\nmodel\n```\n\n 'claude-sonnet-4-20250514'\n\n## Chat\n\nThe main interface to Claudette is the\n[`Chat`](https://claudette.answer.ai/core.html#chat) class, which\nprovides a stateful interface to Claude:\n\n``` python\nchat = Chat(model, sp=\"\"\"You are a helpful and concise assistant.\"\"\")\nchat(\"I'm Jeremy\")\n```\n\nHello Jeremy! Nice to meet you. How can I help you today?\n\n<details>\n\n- id: `msg_01NNfbziMKnAULhH72Upzpzg`\n- content:\n `[{'citations': None, 'text': 'Hello Jeremy! Nice to meet you. How can I help you today?', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 19, 'output_tokens': 18, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` python\nr = chat(\"What's my name?\")\nr\n```\n\nYour name is Jeremy.\n\n<details>\n\n- id: `msg_01HoboBZtq6dtocz2UWht9ia`\n- content:\n `[{'citations': None, 'text': 'Your name is Jeremy.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 45, 'output_tokens': 8, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` python\nr = chat(\"What's my name?\")\nr\n```\n\nYour name is Jeremy.\n\n<details>\n\n- id: `msg_01SUAYui6JS3Jf65KYfsGWhU`\n- content:\n `[{'citations': None, 'text': 'Your name is Jeremy.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 61, 'output_tokens': 8, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nAs you see above, displaying the results of a call in a notebook shows\njust the message contents, with the other details hidden behind a\ncollapsible section. Alternatively you can `print` the details:\n\n``` python\nprint(r)\n```\n\n Message(id='msg_01SUAYui6JS3Jf65KYfsGWhU', content=[TextBlock(citations=None, text='Your name is Jeremy.', type='text')], model='claude-sonnet-4-20250514', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 61; Out: 8; Cache create: 0; Cache read: 0; Total Tokens: 69; Search: 0)\n\nClaude supports adding an extra `assistant` message at the end, which\ncontains the *prefill* \u2013 i.e.\u00a0the text we want Claude to assume the\nresponse starts with. Let\u2019s try it out:\n\n``` python\nchat(\"Concisely, what is the meaning of life?\",\n prefill='According to Douglas Adams,')\n```\n\nAccording to Douglas Adams,it\u2019s 42. More seriously, many find meaning\nthrough relationships, personal growth, contributing to others, and\npursuing what brings fulfillment.\n\n<details>\n\n- id: `msg_01UkHn37YePdXg8NVrXk9Qu3`\n- content:\n `[{'citations': None, 'text': \"According to Douglas Adams,it's 42. More seriously, many find meaning through relationships, personal growth, contributing to others, and pursuing what brings fulfillment.\", 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 89, 'output_tokens': 32, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nYou can add `stream=True` to stream the results as soon as they arrive\n(although you will only see the gradual generation if you execute the\nnotebook yourself, of course!)\n\n``` python\nfor o in chat(\"Concisely, what book was that in?\", prefill='It was in', stream=True):\n print(o, end='')\n```\n\n It was in \"The Hitchhiker's Guide to the Galaxy.\"\n\n### Async\n\nAlternatively, you can use\n[`AsyncChat`](https://claudette.answer.ai/async.html#asyncchat) (or\n[`AsyncClient`](https://claudette.answer.ai/async.html#asyncclient)) for\nthe async versions, e.g:\n\n``` python\nchat = AsyncChat(model)\nawait chat(\"I'm Jeremy\")\n```\n\nNice to meet you, Jeremy! How are you doing today? Is there anything I\ncan help you with?\n\n<details>\n\n- id: `msg_01HyDqMjwcKEc2V39xLWTwFf`\n- content:\n `[{'citations': None, 'text': 'Nice to meet you, Jeremy! How are you doing today? Is there anything I can help you with?', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 10, 'output_tokens': 25, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nRemember to use `async for` when streaming in this case:\n\n``` python\nasync for o in await chat(\"Concisely, what is the meaning of life?\",\n prefill='According to Douglas Adams,', stream=True):\n print(o, end='')\n```\n\n According to Douglas Adams,it's 42. But more seriously, the meaning of life is likely something you create through your relationships, contributions, growth, and what brings you fulfillment - rather than something you discover pre-made.\n\n## Prompt caching\n\nClaude supports [prompt\ncaching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching),\nwhich can significantly reduce token usage costs when working with large\ncontexts or repetitive elements. When you use `mk_msg(msg, cache=True)`,\nClaudette adds the necessary cache control headers to make that message\ncacheable.\n\nPrompt caching works by marking segments of your prompt for efficient\nreuse. When a cached segment is encountered again, Claude reads it from\nthe cache rather than processing the full content, resulting in a 90%\nreduction in token costs for those segments.\n\nSome key points about prompt caching: - Cache writes cost 25% more than\nnormal input tokens - Cache reads cost 90% less than normal input\ntokens - Minimum cacheable length is model-dependent (1024-2048\ntokens) - Cached segments must be completely identical to be reused -\nWorks well for system prompts, tool definitions, and large context\nblocks\n\nFor instance, here we use caching when asking about Claudette\u2019s readme\nfile:\n\n``` python\nchat = Chat(model, sp=\"\"\"You are a helpful and concise assistant.\"\"\")\n```\n\n``` python\nnbtxt = Path('README.txt').read_text()\nmsg = f'''<README>\n{nbtxt}\n</README>\nIn brief, what is the purpose of this project based on the readme?'''\nr = chat(mk_msg(msg, cache=True))\nr\n```\n\nBased on the README, Claudette is a high-level wrapper for Anthropic\u2019s\nPython SDK that aims to simplify and automate working with Claude\u2019s API.\nIts main purposes are:\n\n1. **Reduce boilerplate and manual work** - It automates tasks that\n would otherwise require manual handling with the base SDK\n\n2. **Provide convenient features** like:\n\n - Stateful chat dialogs via the\n [`Chat`](https://claudette.answer.ai/core.html#chat) class\n - Support for prefill (controlling Claude\u2019s response start)\n - Easy image handling\n - Simplified tool use API\n - Prompt caching support\n\n3. **Maintain full control** while providing automation - you get\n convenience without losing flexibility\n\n4. **Educational value** - It\u2019s the first \u201cliterate nbdev\u201d project,\n meaning the source code is written as a readable Jupyter Notebook\n with detailed explanations, making it both functional software and a\n teaching resource\n\nThe project essentially makes Claude\u2019s API more ergonomic and\nuser-friendly while preserving all the underlying capabilities.\n\n<details>\n\n- id: `msg_011SNy9u95nspNq6PSnQuwBF`\n- content:\n `[{'citations': None, 'text': 'Based on the README, Claudette is a high-level wrapper for Anthropic\\'s Python SDK that aims to simplify and automate working with Claude\\'s API. Its main purposes are:\\n\\n1. **Reduce boilerplate and manual work** - It automates tasks that would otherwise require manual handling with the base SDK\\n2. **Provide convenient features** like:\\n - Stateful chat dialogs via the [`Chat`](https://claudette.answer.ai/core.html#chat) class\\n - Support for prefill (controlling Claude\\'s response start)\\n - Easy image handling\\n - Simplified tool use API\\n - Prompt caching support\\n\\n3. **Maintain full control** while providing automation - you get convenience without losing flexibility\\n\\n4. **Educational value** - It\\'s the first \"literate nbdev\" project, meaning the source code is written as a readable Jupyter Notebook with detailed explanations, making it both functional software and a teaching resource\\n\\nThe project essentially makes Claude\\'s API more ergonomic and user-friendly while preserving all the underlying capabilities.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 9287, 'input_tokens': 4, 'output_tokens': 223, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nThe response records the a cache has been created using these input\ntokens:\n\n``` python\nprint(r.usage)\n```\n\n Usage(cache_creation_input_tokens=0, cache_read_input_tokens=9287, input_tokens=4, output_tokens=223, server_tool_use=None, service_tier='standard')\n\nWe can now ask a followup question in this chat:\n\n``` python\nr = chat('How does it make tool use more ergonomic?')\nr\n```\n\nBased on the README, Claudette makes tool use more ergonomic in several\nkey ways:\n\n## 1. **Simplified Function Definitions**\n\nUses docments to make Python function definitions more user-friendly -\nyou just need type hints and comments:\n\n``` python\ndef sums(\n a:int, # First thing to sum\n b:int=1 # Second thing to sum\n) -> int: # The sum of the inputs\n \"Adds a + b.\"\n return a + b\n```\n\n## 2. **Automatic Tool Execution**\n\nHandles the tool calling process automatically. When Claude returns a\n`tool_use` message, you just call `chat()` again and Claudette: - Calls\nthe tool with the provided parameters - Passes the result back to\nClaude - Returns Claude\u2019s final response\n\nNo manual parameter extraction or result handling needed.\n\n## 3. **Multi-step Tool Workflows**\n\nThe `toolloop` method can handle multiple tool calls in sequence to\nsolve complex problems. For example, calculating `(a+b)*2` automatically\nuses both addition and multiplication tools in the right order.\n\n## 4. **Easy Tool Integration**\n\n- Pass tools as a simple list to the\n [`Chat`](https://claudette.answer.ai/core.html#chat) constructor\n- Optionally force tool usage with `tool_choice` parameter\n- Get structured data directly with\n [`Client.structured()`](https://claudette.answer.ai/core.html#client.structured)\n\n## 5. **Reduced Complexity**\n\nInstead of manually handling tool use messages, parameter parsing,\nfunction calls, and result formatting that the base SDK requires,\nClaudette abstracts all of this away while maintaining full\nfunctionality.\n\nThis makes tool use feel more like natural function calling rather than\ncomplex API orchestration.\n\n<details>\n\n- id: `msg_01XDJNpxiTkhTY9kbu17Q73L`\n- content:\n ```` [{'citations': None, 'text': 'Based on the README, Claudette makes tool use more ergonomic in several key ways:\\n\\n## 1. **Simplified Function Definitions**\\nUses docments to make Python function definitions more user-friendly - you just need type hints and comments:\\n\\n```python\\ndef sums(\\n a:int, # First thing to sum\\n b:int=1 # Second thing to sum\\n) -> int: # The sum of the inputs\\n \"Adds a + b.\"\\n return a + b\\n```\\n\\n## 2. **Automatic Tool Execution**\\nHandles the tool calling process automatically. When Claude returns a ````tool_use`message, you just call`chat()`again and Claudette:\\n- Calls the tool with the provided parameters\\n- Passes the result back to Claude\\n- Returns Claude\\'s final response\\n\\nNo manual parameter extraction or result handling needed.\\n\\n## 3. **Multi-step Tool Workflows**\\nThe`toolloop`method can handle multiple tool calls in sequence to solve complex problems. For example, calculating`(a+b)\\*2`automatically uses both addition and multiplication tools in the right order.\\n\\n## 4. **Easy Tool Integration**\\n- Pass tools as a simple list to the [`Chat`](https://claudette.answer.ai/core.html#chat) constructor\\n- Optionally force tool usage with`tool_choice`parameter\\n- Get structured data directly with [`Client.structured()`](https://claudette.answer.ai/core.html#client.structured)\\n\\n## 5. **Reduced Complexity**\\nInstead of manually handling tool use messages, parameter parsing, function calls, and result formatting that the base SDK requires, Claudette abstracts all of this away while maintaining full functionality.\\n\\nThis makes tool use feel more like natural function calling rather than complex API orchestration.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 9287, 'input_tokens': 241, 'output_tokens': 374, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nWe can see that this only used ~200 regular input tokens \u2013 the 7000+\ncontext tokens have been read from cache.\n\n``` python\nprint(r.usage)\n```\n\n Usage(cache_creation_input_tokens=0, cache_read_input_tokens=9287, input_tokens=241, output_tokens=374, server_tool_use=None, service_tier='standard')\n\n``` python\nchat.use\n```\n\n In: 245; Out: 597; Cache create: 0; Cache read: 18574; Total Tokens: 19416; Search: 0\n\n## Tool use\n\n[Tool use](https://docs.anthropic.com/claude/docs/tool-use) lets Claude\nuse external tools.\n\nWe use [docments](https://fastcore.fast.ai/docments.html) to make\ndefining Python functions as ergonomic as possible. Each parameter (and\nthe return value) should have a type, and a docments comment with the\ndescription of what it is. As an example we\u2019ll write a simple function\nthat adds numbers together, and will tell us when it\u2019s being called:\n\n``` python\ndef sums(\n a:int, # First thing to sum\n b:int=1 # Second thing to sum\n) -> int: # The sum of the inputs\n \"Adds a + b.\"\n print(f\"Finding the sum of {a} and {b}\")\n return a + b\n```\n\nSometimes Claude will try to add stuff up \u201cin its head\u201d, so we\u2019ll use a\nsystem prompt to ask it not to.\n\n``` python\nsp = \"Always use tools if math ops are needed.\"\n```\n\nWe\u2019ll get Claude to add up some long numbers:\n\n``` python\na,b = 604542,6458932\npr = f\"What is {a}+{b}?\"\npr\n```\n\n 'What is 604542+6458932?'\n\nTo use tools, pass a list of them to\n[`Chat`](https://claudette.answer.ai/core.html#chat):\n\n``` python\nchat = Chat(model, sp=sp, tools=[sums])\n```\n\nTo force Claude to always answer using a tool, set `tool_choice` to that\nfunction name. When Claude needs to use a tool, it doesn\u2019t return the\nanswer, but instead returns a `tool_use` message, which means we have to\ncall the named tool with the provided parameters.\n\n``` python\nr = chat(pr, tool_choice='sums')\nr\n```\n\n Finding the sum of 604542 and 6458932\n\nToolUseBlock(id=\u2018toolu_01UUWNqtkMHQss345r1ir17q\u2019, input={\u2018a\u2019: 604542,\n\u2018b\u2019: 6458932}, name=\u2018sums\u2019, type=\u2018tool_use\u2019)\n\n<details>\n\n- id: `msg_0199dXeVq11rc2veGNJVWc4k`\n- content:\n `[{'id': 'toolu_01UUWNqtkMHQss345r1ir17q', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 445, 'output_tokens': 53, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nClaudette handles all that for us \u2013 we just call it again, and it all\nhappens automatically:\n\n``` python\nchat()\n```\n\n604542 + 6458932 = 7,063,474\n\n<details>\n\n- id: `msg_014wmCxnwQpgvnqKKto3RrxA`\n- content:\n `[{'citations': None, 'text': '604542 + 6458932 = 7,063,474', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 527, 'output_tokens': 19, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nYou can see how many tokens have been used at any time by checking the\n`use` property. Note that (as of May 2024) tool use in Claude uses a\n*lot* of tokens, since it automatically adds a large system prompt.\n\n``` python\nchat.use\n```\n\n In: 972; Out: 72; Cache create: 0; Cache read: 0; Total Tokens: 1044; Search: 0\n\nWe can do everything needed to use tools in a single step, by using\n[`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop).\nThis can even call multiple tools as needed solve a problem. For\nexample, let\u2019s define a tool to handle multiplication:\n\n``` python\ndef mults(\n a:int, # First thing to multiply\n b:int=1 # Second thing to multiply\n) -> int: # The product of the inputs\n \"Multiplies a * b.\"\n print(f\"Finding the product of {a} and {b}\")\n return a * b\n```\n\nNow with a single call we can calculate `(a+b)*2` \u2013 by passing\n`show_trace` we can see each response from Claude in the process:\n\n``` python\nchat = Chat(model, sp=sp, tools=[sums,mults])\npr = f'Calculate ({a}+{b})*2'\npr\n```\n\n 'Calculate (604542+6458932)*2'\n\n``` python\nfor o in chat.toolloop(pr): display(o)\n```\n\n Finding the sum of 604542 and 6458932\n\nI\u2019ll help you calculate (604542+6458932)\\*2. I need to first add the two\nnumbers, then multiply the result by 2.\n\n<details>\n\n- id: `msg_019DZznw7qiEM2uEEcpNTnKs`\n- content:\n `[{'citations': None, 'text': \"I'll help you calculate (604542+6458932)*2. I need to first add the two numbers, then multiply the result by 2.\", 'type': 'text'}, {'id': 'toolu_016NZ7MtE8oWHs5BSkxMcAN7', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 539, 'output_tokens': 105, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` json\n{ 'content': [ { 'content': '7063474',\n 'tool_use_id': 'toolu_016NZ7MtE8oWHs5BSkxMcAN7',\n 'type': 'tool_result'}],\n 'role': 'user'}\n```\n\n Finding the product of 7063474 and 2\n\nNow I\u2019ll multiply that result by 2:\n\n<details>\n\n- id: `msg_01LmQiMRWAtTQz6sChqsbtMy`\n- content:\n `[{'citations': None, 'text': \"Now I'll multiply that result by 2:\", 'type': 'text'}, {'id': 'toolu_019BQuhBzEkCWC1JMp6VtcfD', 'input': {'a': 7063474, 'b': 2}, 'name': 'mults', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 659, 'output_tokens': 82, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` json\n{ 'content': [ { 'content': '14126948',\n 'tool_use_id': 'toolu_019BQuhBzEkCWC1JMp6VtcfD',\n 'type': 'tool_result'}],\n 'role': 'user'}\n```\n\nThe answer is **14,126,948**.\n\nTo break it down: - 604,542 + 6,458,932 = 7,063,474 - 7,063,474 \u00d7 2 =\n14,126,948\n\n<details>\n\n- id: `msg_0119DdeQ2goLFwGkXTXHFDsv`\n- content:\n `[{'citations': None, 'text': 'The answer is **14,126,948**.\\n\\nTo break it down:\\n- 604,542 + 6,458,932 = 7,063,474\\n- 7,063,474 \u00d7 2 = 14,126,948', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 756, 'output_tokens': 61, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n## Structured data\n\nIf you just want the immediate result from a single tool, use\n[`Client.structured`](https://claudette.answer.ai/core.html#client.structured).\n\n``` python\ncli = Client(model)\n```\n\n``` python\ndef sums(\n a:int, # First thing to sum\n b:int=1 # Second thing to sum\n) -> int: # The sum of the inputs\n \"Adds a + b.\"\n print(f\"Finding the sum of {a} and {b}\")\n return a + b\n```\n\n``` python\ncli.structured(\"What is 604542+6458932\", sums)\n```\n\n Finding the sum of 604542 and 6458932\n\n [7063474]\n\nThis is particularly useful for getting back structured information,\ne.g:\n\n``` python\nclass President:\n \"Information about a president of the United States\"\n def __init__(self, \n first:str, # first name\n last:str, # last name\n spouse:str, # name of spouse\n years_in_office:str, # format: \"{start_year}-{end_year}\"\n birthplace:str, # name of city\n birth_year:int # year of birth, `0` if unknown\n ):\n assert re.match(r'\\d{4}-\\d{4}', years_in_office), \"Invalid format: `years_in_office`\"\n store_attr()\n\n __repr__ = basic_repr('first, last, spouse, years_in_office, birthplace, birth_year')\n```\n\n``` python\ncli.structured(\"Provide key information about the 3rd President of the United States\", President)\n```\n\n [President(first='Thomas', last='Jefferson', spouse='Martha Wayles Skelton Jefferson', years_in_office='1801-1809', birthplace='Shadwell, Virginia', birth_year=1743)]\n\n## Images\n\nClaude can handle image data as well. As everyone knows, when testing\nimage APIs you have to use a cute puppy.\n\n``` python\nfn = Path('samples/puppy.jpg')\nImage(filename=fn, width=200)\n```\n\n<img src=\"index_files/figure-commonmark/cell-35-output-1.jpeg\"\nwidth=\"200\" />\n\nWe create a [`Chat`](https://claudette.answer.ai/core.html#chat) object\nas before:\n\n``` python\nchat = Chat(model)\n```\n\nClaudette expects images as a list of bytes, so we read in the file:\n\n``` python\nimg = fn.read_bytes()\n```\n\nPrompts to Claudette can be lists, containing text, images, or both, eg:\n\n``` python\nchat([img, \"In brief, what color flowers are in this image?\"])\n```\n\nThe flowers in this image are purple.\n\n<details>\n\n- id: `msg_01N2NCd5JW3gNsGysgmyMx9F`\n- content:\n `[{'citations': None, 'text': 'The flowers in this image are purple.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 110, 'output_tokens': 11, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nThe image is included as input tokens.\n\n``` python\nchat.use\n```\n\n In: 110; Out: 11; Cache create: 0; Cache read: 0; Total Tokens: 121; Search: 0\n\nAlternatively, Claudette supports creating a multi-stage chat with\nseparate image and text prompts. For instance, you can pass just the\nimage as the initial prompt (in which case Claude will make some general\ncomments about what it sees), and then follow up with questions in\nadditional prompts:\n\n``` python\nchat = Chat(model)\nchat(img)\n```\n\nWhat an adorable puppy! This looks like a Cavalier King Charles Spaniel\npuppy with the classic Blenheim coloring (chestnut and white markings).\nThe puppy has those characteristic sweet, gentle eyes and silky coat\nthat the breed is known for. The setting with the purple flowers in the\nbackground makes for a lovely portrait - it really highlights the\npuppy\u2019s beautiful coloring and sweet expression. Cavalier King Charles\nSpaniels are known for being friendly, affectionate companions. Is this\nyour puppy?\n\n<details>\n\n- id: `msg_01Jat1obwo79eEz5JMFAF4Mh`\n- content:\n `[{'citations': None, 'text': \"What an adorable puppy! This looks like a Cavalier King Charles Spaniel puppy with the classic Blenheim coloring (chestnut and white markings). The puppy has those characteristic sweet, gentle eyes and silky coat that the breed is known for. The setting with the purple flowers in the background makes for a lovely portrait - it really highlights the puppy's beautiful coloring and sweet expression. Cavalier King Charles Spaniels are known for being friendly, affectionate companions. Is this your puppy?\", 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 98, 'output_tokens': 118, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` python\nchat('What direction is the puppy facing?')\n```\n\nThe puppy is facing toward the camera/viewer. You can see the puppy\u2019s\nface straight-on, with both eyes visible and looking directly at the\ncamera. The puppy appears to be lying down with its head up and oriented\nforward, giving us a clear frontal view of its sweet face.\n\n<details>\n\n- id: `msg_018EqaD7EFveLCzSPbQmMMuE`\n- content:\n `[{'citations': None, 'text': \"The puppy is facing toward the camera/viewer. You can see the puppy's face straight-on, with both eyes visible and looking directly at the camera. The puppy appears to be lying down with its head up and oriented forward, giving us a clear frontal view of its sweet face.\", 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 227, 'output_tokens': 65, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` python\nchat('What color is it?')\n```\n\nThe puppy has a chestnut (reddish-brown) and white coat. The ears and\npatches around the eyes are a rich chestnut or reddish-brown color,\nwhile the face has a white blaze down the center and the chest/front\nappears to be white as well. This is the classic \u201cBlenheim\u201d color\npattern that\u2019s common in Cavalier King Charles Spaniels - the\ncombination of chestnut and white markings.\n\n<details>\n\n- id: `msg_01HzUTvRziMrSfdEjbo1kHnh`\n- content:\n `[{'citations': None, 'text': 'The puppy has a chestnut (reddish-brown) and white coat. The ears and patches around the eyes are a rich chestnut or reddish-brown color, while the face has a white blaze down the center and the chest/front appears to be white as well. This is the classic \"Blenheim\" color pattern that\\'s common in Cavalier King Charles Spaniels - the combination of chestnut and white markings.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 300, 'output_tokens': 103, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nNote that the image is passed in again for every input in the dialog, so\nthat number of input tokens increases quickly with this kind of chat.\n(For large images, using prompt caching might be a good idea.)\n\n``` python\nchat.use\n```\n\n In: 625; Out: 286; Cache create: 0; Cache read: 0; Total Tokens: 911; Search: 0\n\n## Extended Thinking\n\nClaude \\>=3.7 Sonnet and Opus have enhanced reasoning capabilities\nthrough [extended\nthinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking).\nThis feature allows Claude to think through complex problems\nstep-by-step, making its reasoning process transparent and its final\nanswers more reliable.\n\nTo enable extended thinking, simply specify the number of thinking\ntokens using the `maxthinktok` parameter when making a call to Chat. The\nthinking process will appear in a collapsible section in the response.\n\nSome important notes about extended thinking:\n\n- Only available with select models\n- Automatically sets `temperature=1` when enabled (required for thinking\n to work)\n- Cannot be used with `prefill` (these features are incompatible)\n- Thinking is presented in a separate collapsible block in the response\n- The thinking tokens count toward your usage but help with complex\n reasoning\n\nTo access models that support extended thinking, you can use\n`has_extended_thinking_models`.\n\n``` python\nhas_extended_thinking_models\n```\n\n {'claude-3-7-sonnet-20250219',\n 'claude-opus-4-20250514',\n 'claude-sonnet-4-20250514'}\n\n``` python\nchat = Chat(model)\n```\n\n``` python\nchat('Write a sentence about Python!', maxthinktok=1024)\n```\n\nPython is a versatile, high-level programming language known for its\nreadable syntax and extensive libraries, making it popular for\neverything from web development to data science and machine learning.\n\n<details>\n\n<summary>\n\nThinking\n</summary>\n\nThe user is asking for a sentence about Python. Since they didn\u2019t\nspecify, this could refer to either: 1. Python the programming language\n2. Python the snake\n\nGiven the context and common usage, they\u2019re most likely referring to the\nprogramming language Python. I\u2019ll write a sentence about Python the\nprogramming language that\u2019s informative and concise.\n</details>\n\n<details>\n\n- id: `msg_017EgYhUjsQxWkXN1zrRjFxK`\n- content:\n `[{'signature': 'EokECkYIBBgCKkDNuftW7kYi6z6RSuzj4DNdtNRxcj486/U8U2NJHg51M+vGmQ1eN7ypz+w4/tpZCFHgWR9KFPXElnHrp3SkoWJrEgzJthIeSKqmoUbrP5YaDKGgUdib0TYhZriKcCIwDrQ2GTZ3D7zE0RVouKJLbzyRl+sQ6FQ+NwNQb5qrHw5Ylmzqxxk4Sa4GuzOEY8zVKvAC+7LfNqCd7jBjPVqaoSRmCubkKuWWeg60G39UCYm/W9VUsrDT1IHLTvOuK3KOYTQL1zqWt1XlBFj52haZIWRmjVU1w2S8EyKIJIThNRYFfT9CDuAeCYwUae8BFL4wm/MEUw+2tDNH3ei7JUvb4sk17cTrePvzpiQNtmHN8TctDBP2RgD7PpTUbjNUsvoRJFBSLLfNsd8wlvAkcph96fDV5dUJ/W3mkluG4XbTTY3ns/rlikAFLTphaoXeqM6buvm889Sep8BQdHuujHcuKWD3auTusayXE5O/9yYcWrU9qPxZ2bxF72tZ1Y65bTBYzhm9ohtB1LTy0x0XvOS76gfGZ8XaJ4vj3OMz1Cn5GSTCNbELTHHVBh5azPSCI9Qu44/ZBE2ZsFA0mtPCiP8cyhZmzAaHFnz2QaKwuTlfz5VnDPmNSNy8rqHywWlkMMA4g9+0SDZSxYJkCYBO+OUs1gNqlwwJQUyYOc1SEmpBkVQee2kYAQ==', 'thinking': \"The user is asking for a sentence about Python. Since they didn't specify, this could refer to either:\\n1. Python the programming language\\n2. Python the snake\\n\\nGiven the context and common usage, they're most likely referring to the programming language Python. I'll write a sentence about Python the programming language that's informative and concise.\", 'type': 'thinking'}, {'citations': None, 'text': 'Python is a versatile, high-level programming language known for its readable syntax and extensive libraries, making it popular for everything from web development to data science and machine learning.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 41, 'output_tokens': 119, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n## Web Search and Server Tools\n\nClaude supports server-side tools that run on Anthropic\u2019s\ninfrastructure. The flagship example is the web search tool, which\nallows Claude to search the web for up-to-date information to answer\nquestions.\n\nUnlike client-side tools (where you provide functionality), server-side\ntools are managed by Anthropic. Claudette makes these easy to use with\nhelper functions like\n[`search_conf()`](https://claudette.answer.ai/core.html#search_conf).\n\n``` python\nchat = Chat(model, sp='Be concise in your responses.', tools=[search_conf()])\npr = 'What is the current weather in San Diego?'\nr = chat(pr)\nr\n```\n\nBased on the search results, here\u2019s the current weather information for\nSan Diego:\n\nToday (Saturday, June 21st) has a high of 67\u00b0F [^1] [^2] with cloudy\nconditions early with partial sunshine expected later [^3]. Winds are\nfrom the SSW at 10 to 15 mph [^4].\n\nTonight\u2019s low will be around 62\u00b0F with overcast conditions and SSW winds\nat 10 to 15 mph [^5].\n\nTemperatures are running about 4-7 degrees below normal for most areas\n[^6], making it a cooler day than typical for this time of year in San\nDiego.\n\nAir quality is currently at an unhealthy level for sensitive groups, so\nthose with breathing sensitivities should reduce outdoor time if\nexperiencing symptoms [^7].\n\n<details>\n\n- id: `msg_01Kg3aNFF7ibUcWZxPpFNmu8`\n- content:\n `[{'id': 'srvtoolu_01YazfLE5GfK4ET2Z4rsfcuz', 'input': {'query': 'San Diego weather today'}, 'name': 'web_search', 'type': 'server_tool_use'}, {'content': [{'encrypted_content': 'EqcCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDF5HWNC1GnRw10SRnBoMsafoy8BqdMy4chO3IjALzgdeA/d4dT1Qx7JKFu6XeXmrHYIe2lxVFl7TqZkRDnKmPpA6mnvpkwGh9eW8RJgqqgGtR4kEv8KoMeWf9VHjh1oYyscLkN5LJq00R4X3C/Cfw9oLLdIAiN9tvq9g2Rzm0Qb/IP5GcdVfiwx7w5dRfL67oaWQ5IFIXSvv9ByLW/ERFI30UKhhKFYumApVuZEIge6CL0j56OQFXAkPVENWIlSnro+9BIKgf866WWvRo0kx2d+SiX9p3ainG+Zqbl55Bq+mvyOUgVabtSEfr+oY6FQPJYYT9ad0QxYUOxgD', 'page_age': '3 days ago', 'title': '10-Day Weather Forecast for San Diego, CA - The Weather Channel | weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/tenday/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': 'EroMCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKBkST0tPvpOGw/SWxoMgJ/iK5dTJy/vMfmsIjAfH72hWmf/naqyXr46jfw0V/iSDaZJPzeQlCOJvENkQwXPp1sup75iYszy/zgR/YMqvQuXXkSUyo9y/bG3wdm4EkiaXeXkz5QSx0o2/SrZPqhOL9EXrQZAdEPo6KZZQeQdLKkwuEeoNj7vHE55EFXmwTLkN+QTPBsZ4mJ9gC/+3SGgbAMGdubcNnzUIlty+u0wAGTLDaJGeKlkIreF1znKqB9RefmQrpaErVDj7za3noPpsqUFRfDzTPfDUzOsRBKo3DNA2f86rYA1V6ot9qpSNOi1WFTnne5tMl68x/QTEXdgVpxolLK243bkcW1lBdAhwHdik+B/z1RHIXpyJWOLZgUwUtlGYm7jqacVVVF7rut/OlppO7+RA5mgpVjx47J40MUq7rmrcn+e9dXSUWduDPgsSCGtyM5jn0WgUgYyNRccdRPhLAeYcqa4xFYUmpbkGn5o7JrtkiU/OzS1pCeKfFRcjEtdCYeOHkj1FXsAJj31/qAlTZcWE3x4DuQbVt+yqpK4BXkpqTqd6ML3SaMm3/ac9TIaAz6Ob/ThK+A5qypeCB4YW9fyL5xG0oyHEKTefh+5If1nF23IW9Kbze5wZVTMobdolFr3uhS547DV2lngv0wEoTpOyADO6bz3qj0w2pB5DAxLPaW+4YPPRz8bKJEwMgLuDH+EP4wiUKpVrSjmBspXwM1WUSxD4X2lh7r6S4Jo7HUHTravhHuzuODKQ9fLCz2xnwto0fGs2uYQ9sQjIXOAYCBRpFfdYVYE68Br+7Ply0pD6J+Xix2NGHSYHpjMUbtCaYqvqwDO8UmlYA7YNyLs9Q/oFAcRXDqtUEZYD0d0h0mOS3zFYMySD9SfYNVx4SX1g3i6f+xCKfgdDMQ5B+jERSzkcHgR4jRifKE89qxfUCd4j72LhmJp8FJYxe993mqa7TXgm/SHe8AJrnG0EIo2dbWrTzn9SeQmZQzCvl0dpE79Qkgfb8j9BXQvmSfF2f8UOcymWo6vjPBCuPc1lvpvISLjcVIY06pAvh9zp3KUMxhc+K9qmyDTlglwj6feZZw/uyNux21y6CpSSITbEv+KuEJd5WaWphw5bqel0B/u/bwV/G2jkgbcwrb75HPGeJt+eNjyClvvJSsu6IgtkchIabdxo2zedcrilzAU9arLRJlcFNANSB0WilNrmmbc3jk+7RUmnc782nB1fz92JI6Cb7dvbncG1m4HHJy3Mh60ednlMO5GXTTnvIjAF2FaQp+MivMCin2YVwOn3N0GyKhVrbcD7EDrsXWA6yFls+AWAubYMJUS9ll/HeJhfSqD1zHyYQZ4Twic+W5kj4QCWYa0EWtnYs6NO76aRHOPSwbF8+/9XQmCUb4rHTXuPjxEL/uXktDE7K52sEq9v81wKz54urHiSGV1/TmARD6KSLhEejlrS5ydv4Du3YOdEXE5G2e4xPDQ1C1pwTEYKyLf/yrdeeKST9TiOxoj+bMIpwfyEq86+C4eajyNWZYnpx8IZviEo3jWOdiXFb53zyl7fIOeWBhWbrWmPjCazjSGofKGbFOz8jGTUOFqIpf94sqT1ent5X+nQTJ5rlrQPLXDfZbTrgP9pTZtZLlvezsYlIuqIFVWnnBOd0Y4IUqOw8e/3WYThftfGW5OkEp4sLMFd/4QnmoXqBtjf87fZLLkLV6ZZv26catrYFdv68doNSO6oTr7Gb1TtgrCJAgRhRarm/4MI3NpYD7D6oxspLjwPp85mND2g9jVtilz51L7NXpbGKcCc5o+e1MbpzZbKvzF6xSAtk2qKZ/i6P9p2tW/BMYG9O7wRDwRENWOwqA41BNdQpJ18a+emVgn5795o1AfLQVlm99so8izdz0sA8+fp1OjT9ziuRgsk9bOH1QhPYovNql0nQwulZJwYfQLz9okhXtM36aC2SGtNrE8IMbPdCIUdMQ0PznqgI17UPXjILvfdXBXCmbRT+CVbOHeeAx1juxSMwML9pWcymLRsAKowOPMj4meHF4relkA72QKR1uGEVIB/Wvl66WBDAcQyRgD', 'page_age': '3 days ago', 'title': 'San Diego, CA Weather Forecast | AccuWeather', 'type': 'web_search_result', 'url': 'https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628'}, {'encrypted_content': 'Er0ECioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDBGutrl0Yo/Ph3ytgxoMmv0PMZzhuX1bUMAaIjB8A47OiTekaB3+wTaHtqniXxv1Syc6JTwDJgaWgpy/MxfY+iOIS58xXsHOd7d/vrUqwAOQc9TMOqSb0LGZCGaGxIwiXICeBOu9KYGmqzNtUJm31yQlCGwdOFeznCgec0B2/jhLUZMpoDuoL3ayVUeBYC7IlyW4Lrh7DR8+MUOf27YxozzhkdWKDDDqCf0hN40Qn69bGemDOFejCWrTyCj8ffYa29MAKRcAvQv0TQUehsNOy0xKYzeBA2z9zjzZp9GOesvqBv5/2AxQrVwygU31bLYEeiqHqLrfeQ798HK9oDFlAiHaS/gWmpK1+0d3UA+Y5KCKipBmUxy15LkEmoG0MoG3/OEDZ7mOGuuY5RqCW4hkdT4dzm6OsKfmiLoDG/XI2HNkpcTnCd3tO0yUZdwY3lX4vSjAS2wvFxNsl7b8YbaKM/U8H3JaTVntwyh7GHWYezHYaYXNiMK05KcQMKJlP/bZx82sQkq83jl15k55Nf5NR/R/1PHi/fqzLDwPOSug5RJ8dwdduWd1SF4qcfStBaOZ4fRdTwbxJgiAC6gmxWMAGfXg29iVSNsTBYVaGk+GPrUSIFxU0x36xejO0Vaz7wHL6XPwjvXMhVrWbuf5xMXKRNW3XG3X0AEB7h40x+0MN23BmmJ9G6+JQ5Ngog6z2An4GAM=', 'page_age': '3 days ago', 'title': 'San Diego weather forecast \u2013 NBC 7 San Diego', 'type': 'web_search_result', 'url': 'https://www.nbcsandiego.com/weather/'}, {'encrypted_content': 'EpcCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDGlljWS7qosG4mSt3BoM6gy+Gh0f2zdXJ8kAIjAL5PfnNZR7Vex2zcFoqLody/xA+Yyoob62LVGMQ4+EhXd4CKgvxQEfpQLQgVvIH3UqmgGByQGU45dvgEJrKexyCEvra2CIAoYOTUiKNt6p7dVfp8++dfq28UU2mt5h10bL8ul8y0xeBu6new/tfwFJ6+GS/Bh6p+M+p87Jy65QQ/dgMhV+M7q3EAQUZjh642YMayI4nimm2yIwbLzNRXEszsp2kdmKKhxDpO3C5wp8fWLy5UpWvimjh5WSMnAzEpMoVDqD99FavgHvaPF7GAM=', 'page_age': '3 days ago', 'title': 'Weather Forecast and Conditions for San Diego, CA - The Weather Channel | Weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/today/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': 'ErEDCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKDodoc/BpOij6btVBoMdtlDIIQ1rjzAl3XyIjAUXhC+GWPaQwx74WpJR7Xo+cVP0RjwhWd5LPSL+skOIE8sHVqz0Ry9jmq5jGri3wcqtAJrH5qNCAGieGFHQijAS1lfA2rn0EDH/tLBmC4nKW0MGQz/NLn49FuAcJuEZrw2149zcJ88XQ18hVEhWTkZ/BNEBujb9+M+QthIUUOPf6RplEX+DThq1KIuqbR0XBh71qThLM5ZfBjcvYS4429hpEP5DJo2FP0nqr9Ps8GX/hvIik33EXc4X3x16d649qqcRFwByb1DhE+NZVTiuu4WfljWXWBs+17ezkxxWazj3E9GtLBIL98fnMoOf4p9oTI8EgWe4RjcGqEaI6DWqlGquNgkc4IeqlzVkjWP4v90HoI7oegcDKtK/n+8pNaGqyBQizgf1NglM2gRBj3cZ9kt7cDX8p1KpmXrGsOSEK3mn6RAnjlsFQ2x7UjM7l980KCVKnqeguR0ZkCsvB+KM0AputjxlU+KrBgD', 'page_age': '3 days ago', 'title': 'San Diego, CA', 'type': 'web_search_result', 'url': 'https://www.weather.gov/sgx/'}, {'encrypted_content': 'EpkCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDLXJ+1Ii8XIJ7AwW/xoMMbTKEdT8hw2J9bdSIjBYWJur7pQQqNijCyZjeN+VSYcaZe7xE/09hGS23TOjFLdvrOhGAMVSd3e2IDGUHCEqnAG6GJZO/sDcDEeEn/sobNJbNjM9VfNoJZEg+f/lZ+KXtMJELQ2Q14ot0iqQ0qKEjDxz3OMLkAYJg3uqeVMOq5QLgz6MNANEoCU+koTqIiYGZ++8Y0tKdtVD/Xrm0QW0fFkdJcN1PVt+6fN8aDJ5+95phOw5vEmRS9FRWg6aLDIwpxaNJ6z+Wbpff8zoSGUcPZFaFIUjAAU6qnx8kRoYAw==', 'page_age': None, 'title': 'San Diego, CA Weather Forecast | KGTV | kgtv.com', 'type': 'web_search_result', 'url': 'https://www.10news.com/weather'}, {'encrypted_content': 'EpQCCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDHL0i7qnzUCM4zRRAhoMAv3yQhl4BrqFyb0nIjBsyvNyrS90lUKCO/9admV9eU8x96+nDdrodoVAe9lpT2fNstMu4pS2Aer192MKKnwqlwGnu1DfFtpu/sSeugS3SUtYxT+ulZYw+ZQwhqLMOf+UadP2PrCAEDh5CM2pF4fMHRdt9GBYTgOA/3ug6W2Ci30q5QXwdiNC/7X2KQV6QrU83m//vy92K8PO9dwqv4B0T8uCSY18O+BtHHlZrzmzPgIWm4OTP2+Blh+f3X+yRubR9JiBehxtgS/IGmdWhzv6QjIbcFy5bhNDGAM=', 'page_age': '1 week ago', 'title': 'Hourly Weather Forecast for San Diego, CA - The Weather Channel | Weather.com', 'type': 'web_search_result', 'url': 'https://weather.com/weather/hourbyhour/l/San+Diego+CA?canonicalCityId=3b2b39ed755b459b725bf2a29c71d678'}, {'encrypted_content': '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', 'page_age': None, 'title': 'San Diego, CA 10-Day Weather Forecast | Weather Underground', 'type': 'web_search_result', 'url': 'https://www.wunderground.com/forecast/us/ca/san-diego'}, {'encrypted_content': 'Ev0ECioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDFqrWvXcDBaRhAEIERoMEMwkIlYRNrbpob8qIjAGpulVwN56DZ4z4+PuEB3gdYm6QZ5Qvq+6RFvOLnEGDg+mpsIvb2TL4iauDizcEsUqgAT3/Sza241GQ6OmRz38xfUdXYqE5zatMSVDZ8Pzsd11fgBJg8voUcxKfPRPQWlA8FYW8+K4vDvv5cahR9rbVN829R/VQxq7YdcMsD9D5pbk9WButOmQLwI5/MsvnKo0MJ2e6kVcI1DVTwwHxoF0AJdkXUm/9x5danZ35QmA3FIR+7AOBCgtlOmwwIO1nTB+x6+8gf8DB0Jsgv6scqI/PqYxTYH8pZUEs3sA0pXQWJIcbtbWPRqxvfr6KYTtBAKJcr4XmsOMdi4OhVxzXhed1OjB1Jvebhi7Z+CbOOEZBuL2T7inzxoNlHvd3rhuZoDzpb9IWEMx/29fjwWhy+ztWi4Fdl25QgpWokl9cjDtq+6DEkf97+5ks6oVZU1dKoKq2y6S7cT3SL30IOzpdNox9Nh9FrOZeui/aT2zD7imuB+dyx9ffHi07Ulje7R9UWwBvDzRPMP4Ilwe4nrcQWWloso80KTfIixUTmel1bPKxVdrag/2+4kD6ahHpm2cLazWqTc+GvVY5+IRb2C5Y6pve4tWPVZC584151GHbdDZB2FamZJsdBlVL5VAF7Cz2U2mukxcuFF7Vwh3lpvpuqkldp4yWf2UJVpGMOOgDMgRi9qn+fAqE9jEIKoqXRhrVnKlgAlMGpnFfxu1IvxOLQQRqCNRltm5whIy5YhZa+7bllx+NRgD', 'page_age': '3 days ago', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}, {'encrypted_content': 'Ev8CCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDOOoeUPUoDED8O83ZhoM30uUue3UQ1WQ6At6IjD+k7S7lYoiPFc5urIX1kWyFxcLj14bmNmI9YackQTQAU27o6IGbFdwaU+40URG2xQqggLYvUzF4uC9bk9e+C5CbKLU1WAsE7Nsb3YpFYsFiwMKqPamqEVSZE/xxUGQZ9w5tbtftdchhIs0bupnPj+G3BgO+ivdO9VcHBrqJwOk+hQ+XhQp3kLRubgZ9ozPpTZDK0xhpuFh18mFwsHgi/dIH478C1yYA50B0d/qL5C4V6NdYfDYsOXL0Ce1y4L8JxlUi//BPq23m1FfJeVo0vPYKTWm0D2TGTEnLygV9ZI9/wUF5H+gDYimj/QJZW1MWWf7bUQl85I1AyroDE2h8pae6FT0VTVWWIUJiBOWr48xbjieS+LHRxP7/XhpZpI2x0zz3WLi1BYdxHH04yxnjxLcQILrOuoYAw==', 'page_age': '5 days ago', 'title': 'National Weather Service', 'type': 'web_search_result', 'url': 'https://forecast.weather.gov/zipcity.php?inputstring=San+Diego,CA/'}], 'tool_use_id': 'srvtoolu_01YazfLE5GfK4ET2Z4rsfcuz', 'type': 'web_search_tool_result'}, {'citations': None, 'text': \"Based on the search results, here's the current weather information for San Diego:\\n\\n\", 'type': 'text'}, {'citations': [{'cited_text': 'TomorrowSat 06/21 High \u00b7 67 \u00b0F \u00b7 14% Precip. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKwATF21Da6JaeprrRoMR4n2dYDzq6Grz6kOIjDubzeZ5yWRJE4JTY/En0I9Ue7hW3xNHVY1Nb651cmT84e3E/CK5IihYjOjT0ri+bMqEzkJobhLc+mcf18NFKDVD/eXWJkYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}, {'cited_text': 'High 67F. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDBZRJenhcEsF45RP3hoM9byW9q+/yaWr+G32IjAOpd1oMmv1j3abI8JHjvI1b5ZvEPvFR0RzxtY1jsxEyRv9IJkysuqnmbSwH3g32TgqE+VO+8ZZPNjG9foScv6WV79YDUAYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'Today (Saturday, June 21st) has a high of 67\u00b0F', 'type': 'text'}, {'citations': None, 'text': ' with ', 'type': 'text'}, {'citations': [{'cited_text': '/ 0.00 \u00b0in Cloudy early with partial sunshine expected late. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDB4nMEZc/F7OchMulRoMGN8vERmCYSPIeM52IjBEWjKA8pyazlviIcAv3VdKXXstJzWI89Lth9GVQTgJe+aHBo6Z9RixGwe9H65I4iEqE6r+cdWvSki3A5y7liT1a2+EuPgYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'cloudy conditions early with partial sunshine expected later', 'type': 'text'}, {'citations': None, 'text': '. ', 'type': 'text'}, {'citations': [{'cited_text': 'Winds SSW at 10 to 15 mph. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDB45Fg4fI2lZagCjPRoM44KF0iEojWBopwrHIjBhn7dgVM1Ff/cqtJ/lTjfQ/jwVGUPTMJqvlWxrNi2vlcn6nHSZw+cUefs/Ruz/GNgqE6jMHyEpfOkI5cEy1xxL1qwAZvIYBA==', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': 'Winds are from the SSW at 10 to 15 mph', 'type': 'text'}, {'citations': None, 'text': '.\\n\\n', 'type': 'text'}, {'citations': [{'cited_text': 'Low 62F. Winds SSW at 10 to 15 mph. ', 'encrypted_index': 'EpEBCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDGs1z0BKFApU+3H2sxoMHemxpcDkrIGd4oSRIjAWWpByOKdjFHplptGY/sqWHuZVPAxLushiCw0j+aLQ3+bpwzSikTDw6Eb075la0fYqFeOQNDFP6pV830agKs390gtIQ9hn2RgE', 'title': 'San Diego, CA Weather Conditions | Weather Underground', 'type': 'web_search_result_location', 'url': 'https://www.wunderground.com/weather/us/ca/san-diego'}], 'text': \"Tonight's low will be around 62\u00b0F with overcast conditions and SSW winds at 10 to 15 mph\", 'type': 'text'}, {'citations': None, 'text': '.\\n\\n', 'type': 'text'}, {'citations': [{'cited_text': 'Cooler today with highs around 4-7 degrees below normal for most areas, still slightly above normal in the lower deserts. ', 'encrypted_index': 'Eo8BCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDKmS4xmv51SRhiupjBoM1jB2H6k2FU08pQ3GIjAV+DJ6rRuV2b6Q7ignq8PgwpnBySIrcI0FjJyUkxWXMUqYQYSPaTtiNLaSUJi1kh4qE+SXxbI2WryAsUjDE9uQS3F/91QYBA==', 'title': 'San Diego, CA', 'type': 'web_search_result_location', 'url': 'https://www.weather.gov/sgx/'}], 'text': 'Temperatures are running about 4-7 degrees below normal for most areas', 'type': 'text'}, {'citations': None, 'text': ', making it a cooler day than typical for this time of year in San Diego.\\n\\n', 'type': 'text'}, {'citations': [{'cited_text': 'The air has reached a high level of pollution and is unhealthy for sensitive groups. Reduce time spent outside if you are feeling symptoms such as dif...', 'encrypted_index': 'EpEBCioIBBgCIiQ4ODk4YTFkYy0yMTNkLTRhNmYtOTljYi03ZTBlNTUzZDc0NWISDK8D4vc8KfCrlx9emxoMMLnROCL/VkErH3i/IjA/9/wpz9prNlBSXXcsTY2S+xdsPRDTNhPl7sYwMQoZ1OAvK8zbv5m0QT4Z0rVOkO8qFX/4Kq1l4tkCVlYlPmm9TE6ED9r0ABgE', 'title': 'San Diego, CA Weather Forecast | AccuWeather', 'type': 'web_search_result_location', 'url': 'https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628'}], 'text': 'Air quality is currently at an unhealthy level for sensitive groups, so those with breathing sensitivities should reduce outdoor time if experiencing symptoms', 'type': 'text'}, {'citations': None, 'text': '.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 7302, 'output_tokens': 325, 'server_tool_use': {'web_search_requests': 1}, 'service_tier': 'standard'}`\n\n</details>\n\nThe [`search_conf()`](https://claudette.answer.ai/core.html#search_conf)\nfunction creates the necessary configuration for the web search tool.\nYou can customize it with several parameters:\n\n``` python\nsearch_conf(\n max_uses=None, # Maximum number of searches Claude can perform\n allowed_domains=None, # List of domains to search within (e.g., ['wikipedia.org'])\n blocked_domains=None, # List of domains to exclude (e.g., ['twitter.com'])\n user_location=None # Location context for search\n)\n```\n\nWhen Claude uses the web search tool, the response includes citations\nlinking to the source information. Claudette automatically formats these\ncitations and provides them as footnotes in the response.\n\nWeb search usage is tracked separately from normal token usage in the\n[`usage`](https://claudette.answer.ai/core.html#usage) statistics:\n\n``` python\nchat.use\n```\n\n In: 7302; Out: 325; Cache create: 0; Cache read: 0; Total Tokens: 7627; Search: 1\n\nWeb search requests have their own pricing. As of May 2024, web searches\ncost \\$10 per 1,000 requests.\n\n## Text Editor Tool\n\nClaudette provides support for Anthropic\u2019s special Text Editor Tool,\nwhich allows Claude to view and modify files directly. Unlike regular\nfunction-calling tools, the text editor tool uses a predefined schema\nbuilt into Claude\u2019s model.\n\nImportant notes about the text editor tool:\n\n- It\u2019s schema-less - you provide a configuration but not a schema\n- It uses type identifiers like \u201ctext_editor_20250124\u201d specific to\n Claude models\n- You must implement a dispatcher function (in Claudette, it\u2019s\n [`str_replace_based_edit_tool`](https://claudette.answer.ai/text_editor.html#str_replace_based_edit_tool))\n- Different commands route through this single dispatcher function\n\nThe text editor tool allows Claude to:\n\n- View file or directory contents\n- Create new files\n- Insert text at specific line numbers\n- Replace text within files\n\n``` python\nfrom claudette.text_editor import text_editor_conf, str_replace_based_edit_tool\nfrom toolslm.funccall import mk_ns\n\n# Create a chat with the text editor tool\nchat = Chat(model, sp='Be concise in your responses.',\n tools=[text_editor_conf['sonnet']], ns=mk_ns(str_replace_based_edit_tool))\n\n# Now Claude can explore files\nfor o in chat.toolloop('Please explain concisely what my _quarto.yml does. Use your tools, and explain before each usage what you are doing.'):\n if not isinstance(o,dict): display(o)\n```\n\nI\u2019ll examine your \\_quarto.yml file to explain what it does. Let me\nstart by looking at the current directory to locate the file.\n\n<details>\n\n- id: `msg_01S59jijaZGLN9jq525KoDRu`\n- content:\n `[{'citations': None, 'text': \"I'll examine your _quarto.yml file to explain what it does. Let me start by looking at the current directory to locate the file.\", 'type': 'text'}, {'id': 'toolu_01NxKxWNHFroLYxTULzFnBAp', 'input': {'command': 'view', 'path': '.'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 1120, 'output_tokens': 106, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nNow I can see the \\_quarto.yml file exists. Let me examine its contents\nto understand what it configures.\n\n<details>\n\n- id: `msg_015w8s5yw4RBs4dXgfLx2CDS`\n- content:\n `[{'citations': None, 'text': 'Now I can see the _quarto.yml file exists. Let me examine its contents to understand what it configures.', 'type': 'text'}, {'id': 'toolu_01ToUv8CSQH69Kx2ahBSwcGf', 'input': {'command': 'view', 'path': '/_Users/jhoward/aai-ws/claudette/_quarto.yml'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 2738, 'output_tokens': 120, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nLet me use the correct path:\n\n<details>\n\n- id: `msg_01Baaa1otgra5CHimvP9Ja5s`\n- content:\n `[{'citations': None, 'text': 'Let me use the correct path:', 'type': 'text'}, {'id': 'toolu_01FTCbeJLRdAyfqqnq3pAQFa', 'input': {'command': 'view', 'path': '/Users/jhoward/aai-ws/claudette/_quarto.yml'}, 'name': 'str_replace_based_edit_tool', 'type': 'tool_use'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 2896, 'output_tokens': 102, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\nYour `_quarto.yml` file configures a Quarto website project with the\nfollowing key settings:\n\n**Project Configuration:** - Sets up a website project type - Includes\nall `.txt` files as resources - Configures preview server on port 3000\nwithout auto-opening browser\n\n**HTML Formatting:** - Uses the \u201ccosmo\u201d theme with custom CSS from\n`styles.css` - Enables table of contents, code tools, and syntax\nhighlighting - Sets a custom layout with wider body (1800px) and\nnarrower sidebar (180px) - Uses \u201carrow\u201d highlight style with custom code\nblock styling - Keeps markdown files during rendering\n\n**Website Features:** - Enables social media cards (Twitter and Open\nGraph) - Adds a search-enabled navbar with primary background - Uses a\nfloating sidebar style - Links to GitHub issues via repo-actions\n\n**Metadata Sources:** - Pulls additional configuration from `nbdev.yml`\nand `sidebar.yml` files\n\nThis appears to be set up for a documentation website, likely for a\nPython package using nbdev (given the nbdev.yml reference), with a focus\non displaying code and technical content with good readability and\nnavigation.\n\n<details>\n\n- id: `msg_01Ba23FNyw6xy7KdtTVnBdk6`\n- content:\n `[{'citations': None, 'text': 'Your`\\_quarto.yml`file configures a Quarto website project with the following key settings:\\n\\n**Project Configuration:**\\n- Sets up a website project type\\n- Includes all`.txt`files as resources\\n- Configures preview server on port 3000 without auto-opening browser\\n\\n**HTML Formatting:**\\n- Uses the \"cosmo\" theme with custom CSS from`styles.css`\\n- Enables table of contents, code tools, and syntax highlighting\\n- Sets a custom layout with wider body (1800px) and narrower sidebar (180px)\\n- Uses \"arrow\" highlight style with custom code block styling\\n- Keeps markdown files during rendering\\n\\n**Website Features:**\\n- Enables social media cards (Twitter and Open Graph)\\n- Adds a search-enabled navbar with primary background\\n- Uses a floating sidebar style\\n- Links to GitHub issues via repo-actions\\n\\n**Metadata Sources:**\\n- Pulls additional configuration from`nbdev.yml`and`sidebar.yml`files\\n\\nThis appears to be set up for a documentation website, likely for a Python package using nbdev (given the nbdev.yml reference), with a focus on displaying code and technical content with good readability and navigation.', 'type': 'text'}]`\n- model: `claude-sonnet-4-20250514`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 3235, 'output_tokens': 267, 'server_tool_use': None, 'service_tier': 'standard'}`\n\n</details>\n\n``` python\nchat.use\n```\n\n In: 9989; Out: 595; Cache create: 0; Cache read: 0; Total Tokens: 10584; Search: 0\n\n## Other model providers\n\nYou can also use 3rd party providers of Anthropic models, as shown here.\n\n### Amazon Bedrock\n\nThese are the models available through Bedrock:\n\n``` python\nmodels_aws\n```\n\n ['anthropic.claude-sonnet-4-20250514-v1:0',\n 'claude-3-5-haiku-20241022',\n 'claude-3-7-sonnet-20250219',\n 'anthropic.claude-3-opus-20240229-v1:0',\n 'anthropic.claude-3-5-sonnet-20241022-v2:0']\n\nTo use them, call `AnthropicBedrock` with your access details, and pass\nthat to [`Client`](https://claudette.answer.ai/core.html#client):\n\n``` python\nfrom anthropic import AnthropicBedrock\n```\n\n``` python\nab = AnthropicBedrock(\n aws_access_key=os.environ['AWS_ACCESS_KEY'],\n aws_secret_key=os.environ['AWS_SECRET_KEY'],\n)\nclient = Client(models_aws[-1], ab)\n```\n\nNow create your [`Chat`](https://claudette.answer.ai/core.html#chat)\nobject passing this client to the `cli` parameter \u2013 and from then on,\neverything is identical to the previous examples.\n\n``` python\nchat = Chat(cli=client)\nchat(\"I'm Jeremy\")\n```\n\n### Google Vertex\n\nThese are the models available through Vertex:\n\n``` python\nmodels_goog\n```\n\nTo use them, call `AnthropicVertex` with your access details, and pass\nthat to [`Client`](https://claudette.answer.ai/core.html#client):\n\n``` python\nfrom anthropic import AnthropicVertex\nimport google.auth\n```\n\n``` python\n# project_id = google.auth.default()[1]\n# gv = AnthropicVertex(project_id=project_id, region=\"us-east5\")\n# client = Client(models_goog[-1], gv)\n```\n\n``` python\nchat = Chat(cli=client)\nchat(\"I'm Jeremy\")\n```\n\n## Extensions\n\n- [Pydantic Structured\n Ouput](https://github.com/tom-pollak/claudette-pydantic)\n\n[^1]: https://www.wunderground.com/weather/us/ca/san-diego \u201cTomorrowSat\n 06/21 High \u00b7 67 \u00b0F \u00b7 14% Precip.\u201d\n\n[^2]: https://www.wunderground.com/weather/us/ca/san-diego \u201cHigh 67F.\u201d\n\n[^3]: https://www.wunderground.com/weather/us/ca/san-diego \u201c/ 0.00 \u00b0in\n Cloudy early with partial sunshine expected late.\u201d\n\n[^4]: https://www.wunderground.com/weather/us/ca/san-diego \u201cWinds SSW at\n 10 to 15 mph.\u201d\n\n[^5]: https://www.wunderground.com/weather/us/ca/san-diego \u201cLow 62F.\n Winds SSW at 10 to 15 mph.\u201d\n\n[^6]: https://www.weather.gov/sgx/ \u201cCooler today with highs around 4-7\n degrees below normal for most areas, still slightly above normal in\n the lower deserts.\u201d\n\n[^7]: https://www.accuweather.com/en/us/san-diego/92101/weather-forecast/347628\n \u201cThe air has reached a high level of pollution and is unhealthy for\n sensitive groups. Reduce time spent outside if you are feeling\n symptoms such as dif\u2026\u201d\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "Claudette is Claude's friend",
"version": "0.3.1",
"project_urls": {
"Homepage": "https://github.com/AnswerDotAI/claudette"
},
"split_keywords": [
"nbdev",
"jupyter",
"notebook",
"python"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c76ba7c4b005286a6c4604f27c5e504d79bf3208131fbcd042e8705392c46f3c",
"md5": "5dcad4a482ceed752e26e752670f459d",
"sha256": "7e9dd60fdbc7b29630ec66ef4354ec0ca60ff416fe198e8ae4dcf426072c9e4b"
},
"downloads": -1,
"filename": "claudette-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5dcad4a482ceed752e26e752670f459d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 40211,
"upload_time": "2025-07-15T23:06:13",
"upload_time_iso_8601": "2025-07-15T23:06:13.108147Z",
"url": "https://files.pythonhosted.org/packages/c7/6b/a7c4b005286a6c4604f27c5e504d79bf3208131fbcd042e8705392c46f3c/claudette-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7c57fe4d22acdc8920293b1eedc308ded6e56761f7b05813ce3e2a5c202d3038",
"md5": "33219d1aa19176bfe0f1f07d5f8e7bab",
"sha256": "6e513c8bedb4d9d2c6898fbbc7d8e00fc00e60e559e35c99b70d986a8f1acb42"
},
"downloads": -1,
"filename": "claudette-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "33219d1aa19176bfe0f1f07d5f8e7bab",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 90463,
"upload_time": "2025-07-15T23:06:14",
"upload_time_iso_8601": "2025-07-15T23:06:14.385641Z",
"url": "https://files.pythonhosted.org/packages/7c/57/fe4d22acdc8920293b1eedc308ded6e56761f7b05813ce3e2a5c202d3038/claudette-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-15 23:06:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AnswerDotAI",
"github_project": "claudette",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "claudette"
}