Cosette’s source

Setup

from IPython.display import display,Image,Markdown
from datetime import datetime
from pprint import pprint
def print_columns(items, cols=3, width=30):
    for i in range(0, len(items), cols):
        row = items[i:i+cols]
        print(''.join(item[:width-1].ljust(width) for item in row))

client = OpenAI()
model_list = client.models.list()
print(f"Available models as of {datetime.now().strftime('%Y-%m-%d')}:\n")
print_columns(sorted([m.id for m in model_list]))
Available models as of 2025-11-17:

babbage-002                   chatgpt-4o-latest             codex-mini-latest             
computer-use-preview          computer-use-preview-2025-03- dall-e-2                      
dall-e-3                      davinci-002                   ft:gpt-4o-2024-08-06:answerai 
ft:gpt-4o-2024-08-06:answerai ft:gpt-4o-2024-08-06:answerai ft:gpt-4o-mini-2024-07-18:ans 
ft:gpt-4o-mini-2024-07-18:ans gpt-3.5-turbo                 gpt-3.5-turbo-0125            
gpt-3.5-turbo-1106            gpt-3.5-turbo-16k             gpt-3.5-turbo-instruct        
gpt-3.5-turbo-instruct-0914   gpt-4                         gpt-4-0125-preview            
gpt-4-1106-preview            gpt-4-turbo                   gpt-4-turbo-2024-04-09        
gpt-4-turbo-preview           gpt-4.1                       gpt-4.1-2025-04-14            
gpt-4.1-mini                  gpt-4.1-mini-2025-04-14       gpt-4.1-nano                  
gpt-4.1-nano-2025-04-14       gpt-4o                        gpt-4o-2024-05-13             
gpt-4o-2024-08-06             gpt-4o-2024-11-20             gpt-4o-audio-preview          
gpt-4o-audio-preview-2024-10- gpt-4o-audio-preview-2024-12- gpt-4o-audio-preview-2025-06- 
gpt-4o-mini                   gpt-4o-mini-2024-07-18        gpt-4o-mini-audio-preview     
gpt-4o-mini-audio-preview-202 gpt-4o-mini-realtime-preview  gpt-4o-mini-realtime-preview- 
gpt-4o-mini-search-preview    gpt-4o-mini-search-preview-20 gpt-4o-mini-transcribe        
gpt-4o-mini-tts               gpt-4o-realtime-preview       gpt-4o-realtime-preview-2024- 
gpt-4o-realtime-preview-2024- gpt-4o-realtime-preview-2025- gpt-4o-search-preview         
gpt-4o-search-preview-2025-03 gpt-4o-transcribe             gpt-4o-transcribe-diarize     
gpt-5                         gpt-5-2025-08-07              gpt-5-chat-latest             
gpt-5-codex                   gpt-5-mini                    gpt-5-mini-2025-08-07         
gpt-5-nano                    gpt-5-nano-2025-08-07         gpt-5-pro                     
gpt-5-pro-2025-10-06          gpt-5-search-api              gpt-5-search-api-2025-10-14   
gpt-5.1                       gpt-5.1-2025-11-13            gpt-5.1-chat-latest           
gpt-5.1-codex                 gpt-5.1-codex-mini            gpt-audio                     
gpt-audio-2025-08-28          gpt-audio-mini                gpt-audio-mini-2025-10-06     
gpt-image-1                   gpt-image-1-mini              gpt-realtime                  
gpt-realtime-2025-08-28       gpt-realtime-mini             gpt-realtime-mini-2025-10-06  
o1                            o1-2024-12-17                 o1-pro                        
o1-pro-2025-03-19             o3                            o3-2025-04-16                 
o3-deep-research              o3-deep-research-2025-06-26   o3-mini                       
o3-mini-2025-01-31            o3-pro                        o3-pro-2025-06-10             
o4-mini                       o4-mini-2025-04-16            o4-mini-deep-research         
o4-mini-deep-research-2025-06 omni-moderation-2024-09-26    omni-moderation-latest        
sora-2                        sora-2-pro                    text-embedding-3-large        
text-embedding-3-small        text-embedding-ada-002        tts-1                         
tts-1-1106                    tts-1-hd                      tts-1-hd-1106                 
whisper-1                     
Exported source
models = 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'o1-preview', 'o1-mini', 'gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4', 'gpt-4-32k', 'gpt-3.5-turbo', 'gpt-3.5-turbo-instruct', 'o1', 'o3-mini', 'chatgpt-4o-latest', 'o1-pro', 'o3', 'o4-mini', 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4.1-nano'

o1 should support images while o1-mini, o3-mini do not support images.


source

can_set_temp

 can_set_temp (m)
Exported source
text_only_models = 'o1-preview', 'o1-mini', 'o3-mini'
Exported source
has_streaming_models = set(models) - set(('o1-mini', 'o3-mini'))
has_sp_models = set(models) - set(('o1-mini', 'o3-mini'))
has_temp_models = set(models) - set(('o1', 'o1-mini', 'o3-mini'))
Exported source
def can_stream(m): return m in has_streaming_models
def can_set_sp(m): return m in has_sp_models
def can_set_temp(m): return m in has_temp_models

source

can_set_sp

 can_set_sp (m)

source

can_stream

 can_stream (m)
assert can_stream("gpt-4o")
assert not can_stream("o1-mini")
model = 'gpt-5-mini'

OpenAI SDK

cli = OpenAI().responses
m = {'role': 'user', 'content': "I'm Jeremy"}
r = cli.create(
    input=[m], model=model, max_output_tokens=100,
    text={ "verbosity": "low" },
    reasoning={ "effort": "minimal" }
)
print(r)
Response(id='resp_0ed79f1cec3cc2f900691ba4892b6481928066d0cf9ced4b49', created_at=1763419273.0, error=None, incomplete_details=None, instructions=None, metadata={}, model='gpt-5-mini-2025-08-07', object='response', output=[ResponseReasoningItem(id='rs_0ed79f1cec3cc2f900691ba489d8fc8192aa85f992718feb3e', summary=[], type='reasoning', content=None, encrypted_content=None, status=None), ResponseOutputMessage(id='msg_0ed79f1cec3cc2f900691ba48a18508192a9c6dad82fc6283c', content=[ResponseOutputText(annotations=[], text='Nice to meet you, Jeremy. How can I help you today?', type='output_text', logprobs=[])], role='assistant', status='completed', type='message')], parallel_tool_calls=True, temperature=1.0, tool_choice='auto', tools=[], top_p=1.0, background=False, conversation=None, max_output_tokens=100, max_tool_calls=None, previous_response_id=None, prompt=None, prompt_cache_key=None, prompt_cache_retention=None, reasoning=Reasoning(effort='minimal', generate_summary=None, summary=None), safety_identifier=None, service_tier='default', status='completed', text=ResponseTextConfig(format=ResponseFormatText(type='text'), verbosity='low'), top_logprobs=0, truncation='disabled', usage=ResponseUsage(input_tokens=8, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=20, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=28), user=None, billing={'payer': 'developer'}, store=True)

Formatting output

Exported source
@patch
def _repr_markdown_(self:Response):
    det = '\n- '.join(f'{k}: {v}' for k,v in dict(self).items())
    res = self.output_text
    if not res: return f"- {det}"
    return f"""{res}

<details>

- {det}

</details>"""
r

Nice to meet you, Jeremy. How can I help you today?

  • id: resp_0ed79f1cec3cc2f900691ba4892b6481928066d0cf9ced4b49
  • created_at: 1763419273.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_0ed79f1cec3cc2f900691ba489d8fc8192aa85f992718feb3e’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_0ed79f1cec3cc2f900691ba48a18508192a9c6dad82fc6283c’, content=[ResponseOutputText(annotations=[], text=‘Nice to meet you, Jeremy. How can I help you today?’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 100
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=8, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=20, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=28)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True
r.usage
ResponseUsage(input_tokens=8, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=20, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=28)

source

usage

 usage (inp=0, out=0)

Slightly more concise version of ResponseUsage.

Type Default Details
inp int 0 Number of prompt tokens
out int 0 Number of completion tokens
Exported source
def usage(inp=0, # Number of prompt tokens
          out=0  # Number of completion tokens
         ):
    "Slightly more concise version of `ResponseUsage`."
    return ResponseUsage(input_tokens=inp, output_tokens=out, total_tokens=inp+out, input_tokens_details={'cached_tokens':0}, output_tokens_details={'cached_tokens':0, 'reasoning_tokens':0})
usage(5)
ResponseUsage(input_tokens=5, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=0, output_tokens_details=OutputTokensDetails(reasoning_tokens=0, cached_tokens=0), total_tokens=5)

source

ResponseUsage.__repr__

 ResponseUsage.__repr__ ()

Return repr(self).

Exported source
@patch
def __repr__(self:ResponseUsage): return f'In: {self.input_tokens}; Out: {self.output_tokens}; Total: {self.total_tokens}'
r.usage
In: 8; Out: 20; Total: 28

source

ResponseUsage.__add__

 ResponseUsage.__add__ (b)

Add together each of input_tokens and output_tokens

Exported source
@patch
def __add__(self:ResponseUsage, b):
    "Add together each of `input_tokens` and `output_tokens`"
    return usage(self.input_tokens+b.input_tokens, self.output_tokens+b.output_tokens)
r.usage+r.usage
In: 16; Out: 40; Total: 56

source

wrap_latex

 wrap_latex (text)

Replace OpenAI LaTeX codes with markdown-compatible ones

Creating messages

Creating correctly formatted dicts from scratch every time isn’t very handy, so we’ll import a couple of helper functions from the msglm library.

Let’s use mk_msg to recreate our msg {'role': 'user', 'content': "I'm Jeremy"} from earlier.

rkw = dict(
    text={ "verbosity": "low" },
    reasoning={ "effort": "minimal" }
)
prompt = "I'm Jeremy"
m = mk_msg(prompt)
r = cli.create(input=[m], model=model, max_output_tokens=400, **rkw)
r

Hi Jeremy — how can I help you today?

  • id: resp_066ef03f7862205800691ba48bb41081a29fe24bedaae17e2e
  • created_at: 1763419275.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_066ef03f7862205800691ba48c2f4881a2acf01543b4dbe11c’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_066ef03f7862205800691ba48ca67881a2840c269a2db188c8’, content=[ResponseOutputText(annotations=[], text=‘Hi Jeremy — how can I help you today?’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 400
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=8, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=16, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=24)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True
print(r)
Response(id='resp_066ef03f7862205800691ba48bb41081a29fe24bedaae17e2e', created_at=1763419275.0, error=None, incomplete_details=None, instructions=None, metadata={}, model='gpt-5-mini-2025-08-07', object='response', output=[ResponseReasoningItem(id='rs_066ef03f7862205800691ba48c2f4881a2acf01543b4dbe11c', summary=[], type='reasoning', content=None, encrypted_content=None, status=None), ResponseOutputMessage(id='msg_066ef03f7862205800691ba48ca67881a2840c269a2db188c8', content=[ResponseOutputText(annotations=[], text='Hi Jeremy — how can I help you today?', type='output_text', logprobs=[])], role='assistant', status='completed', type='message')], parallel_tool_calls=True, temperature=1.0, tool_choice='auto', tools=[], top_p=1.0, background=False, conversation=None, max_output_tokens=400, max_tool_calls=None, previous_response_id=None, prompt=None, prompt_cache_key=None, prompt_cache_retention=None, reasoning=Reasoning(effort='minimal', generate_summary=None, summary=None), safety_identifier=None, service_tier='default', status='completed', text=ResponseTextConfig(format=ResponseFormatText(type='text'), verbosity='low'), top_logprobs=0, truncation='disabled', usage=In: 8; Out: 16; Total: 24, user=None, billing={'payer': 'developer'}, store=True)

We can pass more than just text messages to OpenAI. As we’ll see later we can also pass images, SDK objects, etc. To handle these different data types we need to pass the type along with our content to OpenAI.

mk_msg infers the type automatically and creates the appropriate data structure.

LLMs, don’t actually have state, but instead dialogs are created by passing back all previous prompts and responses every time. With OpenAI, they always alternate user and assistant. We’ll use mk_msgs from msglm to make it easier to build up these dialog lists.

msgs = mk_msgs([prompt, r, "I forgot my name. Can you remind me please?"]) 
msgs
[{'role': 'user', 'content': "I'm Jeremy"},
 ResponseReasoningItem(id='rs_066ef03f7862205800691ba48c2f4881a2acf01543b4dbe11c', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseOutputMessage(id='msg_066ef03f7862205800691ba48ca67881a2840c269a2db188c8', content=[ResponseOutputText(annotations=[], text='Hi Jeremy — how can I help you today?', type='output_text', logprobs=[])], role='assistant', status='completed', type='message'),
 {'role': 'user', 'content': 'I forgot my name. Can you remind me please?'}]
cli.create(input=msgs, model=model, max_output_tokens=400, **rkw)

You said your name is Jeremy.

  • id: resp_066ef03f7862205800691ba48d381881a2a7551de4b01beaab
  • created_at: 1763419277.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_066ef03f7862205800691ba48d847c81a2870ffcea385813eb’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_066ef03f7862205800691ba48db7b881a2853ab00c72cc912e’, content=[ResponseOutputText(annotations=[], text=‘You said your name is Jeremy.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 400
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=39, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=13, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=52)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

Client

Basics


source

Client

 Client (model, cli=None, api_key_env=None, base_url=None)

Basic LLM messages client.

Exported source
class Client:
    def __init__(self, model, cli=None, api_key_env=None, base_url=None):
        "Basic LLM messages client."
        self.model,self.use = model,usage(0,0)
        self.text_only = model in text_only_models
        if not cli:
            cli = OpenAI(api_key=os.getenv(api_key_env or "OPENAI_API_KEY"), base_url=base_url )
        self.c = cli.responses
c = Client(model)
c.use
In: 0; Out: 0; Total: 0
Exported source
@patch
def _r(self:Client, r):
    "Store the result of the message and accrue total usage."
    self.result = r
    if getattr(r,'usage',None): self.use += r.usage
    return r
c._r(r)
c.use
In: 8; Out: 16; Total: 24

source

mk_openai_func

 mk_openai_func (f)

source

mk_tool_choice

 mk_tool_choice (f)

source

get_stream

 get_stream (o, r, cli, cb=None)

source

Client.__call__

 Client.__call__ (msgs:list, sp:str='', maxtok=4096, stream:bool=False,
                  tools:Optional[list]=None,
                  tool_choice:Optional[str]=None, cb:<built-
                  infunctioncallable>=None,
                  background:Optional[bool]|Omit=<openai.Omit object at
                  0x7f959677c6a0>, conversation:Optional[response_create_p
                  arams.Conversation]|Omit=<openai.Omit object at
                  0x7f959677c6a0>, include:Optional[List[ResponseIncludabl
                  e]]|Omit=<openai.Omit object at 0x7f959677c6a0>,
                  input:Union[str,ResponseInputParam]|Omit=<openai.Omit
                  object at 0x7f959677c6a0>,
                  instructions:Optional[str]|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  max_output_tokens:Optional[int]|Omit=<openai.Omit object
                  at 0x7f959677c6a0>,
                  max_tool_calls:Optional[int]|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  metadata:Optional[Metadata]|Omit=<openai.Omit object at
                  0x7f959677c6a0>, model:ResponsesModel|Omit=<openai.Omit
                  object at 0x7f959677c6a0>,
                  parallel_tool_calls:Optional[bool]|Omit=<openai.Omit
                  object at 0x7f959677c6a0>,
                  previous_response_id:Optional[str]|Omit=<openai.Omit
                  object at 0x7f959677c6a0>,
                  prompt:Optional[ResponsePromptParam]|Omit=<openai.Omit
                  object at 0x7f959677c6a0>,
                  prompt_cache_key:str|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  prompt_cache_retention:"Optional[Literal['in-
                  memory','24h']]|Omit"=<openai.Omit object at
                  0x7f959677c6a0>,
                  reasoning:Optional[Reasoning]|Omit=<openai.Omit object
                  at 0x7f959677c6a0>,
                  safety_identifier:str|Omit=<openai.Omit object at
                  0x7f959677c6a0>, service_tier:"Optional[Literal['auto','
                  default','flex','scale','priority']]|Omit"=<openai.Omit
                  object at 0x7f959677c6a0>,
                  store:Optional[bool]|Omit=<openai.Omit object at
                  0x7f959677c6a0>, stream_options:Optional[response_create
                  _params.StreamOptions]|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  temperature:Optional[float]|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  text:ResponseTextConfigParam|Omit=<openai.Omit object at
                  0x7f959677c6a0>,
                  top_logprobs:Optional[int]|Omit=<openai.Omit object at
                  0x7f959677c6a0>, top_p:Optional[float]|Omit=<openai.Omit
                  object at 0x7f959677c6a0>, truncation:"Optional[Literal[
                  'auto','disabled']]|Omit"=<openai.Omit object at
                  0x7f959677c6a0>, user:str|Omit=<openai.Omit object at
                  0x7f959677c6a0>, extra_headers:Headers|None=None,
                  extra_query:Query|None=None, extra_body:Body|None=None,
                  timeout:float|httpx.Timeout|None|NotGiven=NOT_GIVEN)

Make a call to LLM.

Type Default Details
msgs list List of messages in the dialog
sp str System prompt
maxtok int 4096 Maximum tokens
stream bool False Stream response?
tools Optional None List of tools to make available
tool_choice Optional None Forced tool choice
cb callable None Callback after completion
background Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
conversation Optional[response_create_params.Conversation] | Omit <openai.Omit object at 0x7f959677c6a0>
include Optional[List[ResponseIncludable]] | Omit <openai.Omit object at 0x7f959677c6a0>
input Union[str, ResponseInputParam] | Omit <openai.Omit object at 0x7f959677c6a0>
instructions Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
max_output_tokens Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
max_tool_calls Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
metadata Optional[Metadata] | Omit <openai.Omit object at 0x7f959677c6a0>
model ResponsesModel | Omit <openai.Omit object at 0x7f959677c6a0>
parallel_tool_calls Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
previous_response_id Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt Optional[ResponsePromptParam] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_key str | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_retention Optional[Literal[‘in-memory’, ‘24h’]] | Omit <openai.Omit object at 0x7f959677c6a0>
reasoning Optional[Reasoning] | Omit <openai.Omit object at 0x7f959677c6a0>
safety_identifier str | Omit <openai.Omit object at 0x7f959677c6a0>
service_tier Optional[Literal[‘auto’, ‘default’, ‘flex’, ‘scale’, ‘priority’]] | Omit <openai.Omit object at 0x7f959677c6a0>
store Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
stream_options Optional[response_create_params.StreamOptions] | Omit <openai.Omit object at 0x7f959677c6a0>
temperature Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
text ResponseTextConfigParam | Omit <openai.Omit object at 0x7f959677c6a0>
top_logprobs Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
top_p Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
truncation Optional[Literal[‘auto’, ‘disabled’]] | Omit <openai.Omit object at 0x7f959677c6a0>
user str | Omit <openai.Omit object at 0x7f959677c6a0>
extra_headers Optional None Use the following arguments if you need to pass additional parameters to the API that aren’t available via kwargs.
The extra values given here take precedence over values defined on the client or passed to this method.
extra_query Query | None None
extra_body Body | None None
timeout float | httpx.Timeout | None | NotGiven NOT_GIVEN
Exported source
@patch
@delegates(Responses.create)
def __call__(self:Client,
             msgs:list, # List of messages in the dialog
             sp:str='', # System prompt
             maxtok=4096, # Maximum tokens
             stream:bool=False, # Stream response?
             tools:Optional[list]=None, # List of tools to make available
             tool_choice:Optional[str]=None, # Forced tool choice
             cb:callable=None, # Callback after completion
             **kwargs):
    "Make a call to LLM."
    if tools: assert not self.text_only, "Tool use is not supported by the current model type."
    if any(c['type'] == 'image_url' for msg in msgs if isinstance(msg, dict) and isinstance(msg.get('content'), list) for c in msg['content']): assert not self.text_only, "Images are not supported by the current model type."
    tools = [mk_openai_func(o) for o in listify(tools)]
    r = self.c.create(
        model=self.model, input=msgs, max_output_tokens=maxtok, stream=stream, instructions=sp,
        tools=tools, tool_choice=mk_tool_choice(tool_choice), **kwargs)
    if stream: return get_stream(r, self, cb=cb)
    else:
        res = self._r(r)
        if cb: cb(res)
        return res
msgs = 'Hi'
c(msgs)

Hi — how can I help you today?

  • id: resp_0de6f9b93aaf7e0400691ba48f7094819fa6eb50bcd2c21be2
  • created_at: 1763419279.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_0de6f9b93aaf7e0400691ba4904244819f8c5919a926063328’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_0de6f9b93aaf7e0400691ba4916e98819f8ff7670784ac5a1c’, content=[ResponseOutputText(annotations=[], text=‘Hi — how can I help you today?’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘medium’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘medium’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=7, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=79, output_tokens_details=OutputTokensDetails(reasoning_tokens=64), total_tokens=86)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True
c.use
In: 15; Out: 95; Total: 110
r = c(msgs, stream=True)
for o in r: print(o, end='')
Hi — how can I help you today? 

Here are some things I can do if that helps you decide:
- Answer questions or explain concepts
- Draft, edit, or summarize text (emails, essays, reports)
- Brainstorm ideas (projects, names, topics)
- Help with coding, debugging, or math
- Translate or proofread
- Plan trips, schedules, or workouts

Or just tell me what you need and I’ll jump in.
r.value

Hi — how can I help you today?

Here are some things I can do if that helps you decide: - Answer questions or explain concepts - Draft, edit, or summarize text (emails, essays, reports) - Brainstorm ideas (projects, names, topics) - Help with coding, debugging, or math - Translate or proofread - Plan trips, schedules, or workouts

Or just tell me what you need and I’ll jump in.

  • id: resp_0b3414f405d0a98000691ba491e73c81a1ae6fb0fa5be1b907
  • created_at: 1763419281.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_0b3414f405d0a98000691ba49223f081a1ba1f46db0bd49879’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_0b3414f405d0a98000691ba49364e081a196006d4fd870cd0a’, content=[ResponseOutputText(annotations=[], text=‘Hi — how can I help you today? are some things I can do if that helps you decide:- Answer questions or explain concepts- Draft, edit, or summarize text (emails, essays, reports)- Brainstorm ideas (projects, names, topics)- Help with coding, debugging, or math- Translate or proofread- Plan trips, schedules, or workoutsjust tell me what you need and I’ll jump in.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘medium’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘medium’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=7, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=164, output_tokens_details=OutputTokensDetails(reasoning_tokens=64), total_tokens=171)
  • user: None
  • store: True
len(r.events)
104
c.use
In: 22; Out: 259; Total: 281
c(msgs, sp='Talk like GLaDOS.', **rkw)

Oh, hello. I suppose you wanted to say something. Go on — make it interesting.

  • id: resp_000bd80fb2574b5b00691ba496a47481a098cd19747ae4945e
  • created_at: 1763419286.0
  • error: None
  • incomplete_details: None
  • instructions: Talk like GLaDOS.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_000bd80fb2574b5b00691ba497180c81a0ba3417974bb34f02’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_000bd80fb2574b5b00691ba4973b0881a0a2765d0a594e5167’, content=[ResponseOutputText(annotations=[], text=‘Oh, hello. I suppose you wanted to say something. Go on — make it interesting.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=17, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=25, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=42)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

Images

As everyone knows, when testing image APIs you have to use a cute puppy.

# Image is Cute_dog.jpg from Wikimedia
fn = Path('samples/puppy.jpg')
Image(filename=fn, width=200)

img = fn.read_bytes()

OpenAI expects an image message to have the following structure

{
  "type": "image_url",
  "image_url": {
    "url": f"data:{MEDIA_TYPE};base64,{IMG}"
  }
}

msglm automatically detects if a message is an image, encodes it, and generates the data structure above. All we need to do is a create a list containing our image and a query and then pass it to mk_msg.

Let’s try it out…

q = "In brief, what color flowers are in this image?"
msg = [mk_msg(img), mk_msg(q)]
c = Client(model)
c(msg, **rkw)

The flowers are purple.

  • id: resp_054dd489ed3e49a700691ba498325c819d8aa117b838886210
  • created_at: 1763419288.0
  • error: None
  • incomplete_details: None
  • instructions: None
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_054dd489ed3e49a700691ba498bf08819d9e1af187eb4dd401’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_054dd489ed3e49a700691ba498c620819d8f58a822b9d269f4’, content=[ResponseOutputText(annotations=[], text=‘The flowers are purple.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=107, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=11, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=118)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

Tool use

Basic tool calling

def sums(
    a:int,  # First thing to sum
    b:int # 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
def add(x: int, y:int):
    "adds x and y"
    return x + y

mk_openai_func(add)
{'type': 'function',
 'name': 'add',
 'description': 'adds x and y',
 'parameters': {'type': 'object',
  'properties': {'x': {'type': 'integer', 'description': ''},
   'y': {'type': 'integer', 'description': ''}},
  'required': ['x', 'y']}}
sysp = "You are a helpful assistant. When using tools, be sure to pass all required parameters. Don't use tools unless needed for the provided prompt."
a,b = 604542,6458932
pr = f"What is {a}+{b}?"
tools=sums
tool_choice="sums"
msgs = [mk_msg(pr)]
r = c(msgs, sp=sysp, tools=tools, tool_choice='required', **rkw)
tc = [o for o in r.output if isinstance(o, ResponseFunctionToolCall)]
tc
[ResponseFunctionToolCall(arguments='{"a":604542,"b":6458932}', call_id='call_Dlpla3agsovUqWYMBEtydSRZ', name='sums', type='function_call', id='fc_0b05ac64fb9f2e3300691ba49a52f481a09ac755b15b55aba9', status='completed')]
func = tc[0]
func
ResponseFunctionToolCall(arguments='{"a":604542,"b":6458932}', call_id='call_Dlpla3agsovUqWYMBEtydSRZ', name='sums', type='function_call', id='fc_0b05ac64fb9f2e3300691ba49a52f481a09ac755b15b55aba9', status='completed')

source

call_func_openai

 call_func_openai (func, ns:Optional[collections.abc.Mapping]=None)
Exported source
def call_func_openai(func, ns:Optional[abc.Mapping]=None):
    return call_func(func.name, json.loads(func.arguments), ns, raise_on_err=False)
ns = mk_ns(sums)
res = call_func_openai(func, ns=ns)
res
Finding the sum of 604542 and 6458932
7063474

source

mk_toolres

 mk_toolres (r:collections.abc.Mapping,
             ns:Optional[collections.abc.Mapping]=None)

Create a tool_result message from response r.

Type Default Details
r Mapping Response containing tool use request
ns Optional None Namespace to search for tools
Exported source
def _toolres(r, ns):
    "Create a result dict from `tcs`."
    tcs = [o for o in getattr(r, 'output', []) if isinstance(o, ResponseFunctionToolCall)]
    if ns is None: ns = globals()
    return { tc.call_id: call_func_openai(tc, ns=mk_ns(ns)) for tc in tcs }
Exported source
def mk_toolres(
    r:abc.Mapping, # Response containing tool use request
    ns:Optional[abc.Mapping]=None # Namespace to search for tools
    ):
    "Create a `tool_result` message from response `r`."
    tr = _toolres(r, ns)
    r = mk_msg(r)
    res = [r] if isinstance(r, dict) else listify(r)
    for k,v in tr.items(): res.append(dict(type="function_call_output", call_id=k, output=str(v)))
    return res
tr = mk_toolres(r, ns=ns)
tr
Finding the sum of 604542 and 6458932
[ResponseReasoningItem(id='rs_0b05ac64fb9f2e3300691ba49a185881a0a14fd49b1ba0543b', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseFunctionToolCall(arguments='{"a":604542,"b":6458932}', call_id='call_Dlpla3agsovUqWYMBEtydSRZ', name='sums', type='function_call', id='fc_0b05ac64fb9f2e3300691ba49a52f481a09ac755b15b55aba9', status='completed'),
 {'type': 'function_call_output',
  'call_id': 'call_Dlpla3agsovUqWYMBEtydSRZ',
  'output': '7063474'}]
m2 = msgs + tr
res = c(mk_msgs(m2), sp=sysp, tools=tools)
res

604542 + 6,458,932 = 7,063,474

  • id: resp_0b05ac64fb9f2e3300691ba49b810881a0a17737bf23005f54
  • created_at: 1763419291.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseOutputMessage(id=‘msg_0b05ac64fb9f2e3300691ba49c627481a0b80f4cb5db7b9fbb’, content=[ResponseOutputText(annotations=[], text=‘604542 + 6,458,932 = 7,063,474’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: [FunctionTool(name=‘sums’, parameters={‘type’: ‘object’, ‘properties’: {‘a’: {‘type’: ‘integer’, ‘description’: ‘First thing to sum’}, ‘b’: {‘type’: ‘integer’, ‘description’: ‘Second thing to sum’}}, ‘required’: [‘a’, ‘b’], ‘additionalProperties’: False}, strict=True, type=‘function’, description=‘Adds a + b.:- type: integer’)]
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘medium’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘medium’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=157, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=20, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=177)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

This should also work in situations where no tool use is required:

msgs = mk_toolres("I'm Jeremy")
c(msgs, sp=sysp, tools=tools, **rkw)

Nice to meet you, Jeremy. How can I help you today?

  • id: resp_0aef60f57b7b2a2800691ba49d5ed88195b06058eecd01fcd7
  • created_at: 1763419293.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_0aef60f57b7b2a2800691ba49dd0dc8195accd2091ef50bcef’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_0aef60f57b7b2a2800691ba49df7a881959ba9c14b029648f5’, content=[ResponseOutputText(annotations=[], text=‘Nice to meet you, Jeremy. How can I help you today?’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: [FunctionTool(name=‘sums’, parameters={‘type’: ‘object’, ‘properties’: {‘a’: {‘type’: ‘integer’, ‘description’: ‘First thing to sum’}, ‘b’: {‘type’: ‘integer’, ‘description’: ‘Second thing to sum’}}, ‘required’: [‘a’, ‘b’], ‘additionalProperties’: False}, strict=True, type=‘function’, description=‘Adds a + b.:- type: integer’)]
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=96, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=20, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=116)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

source

Client.structured

 Client.structured (msgs:list, tools:Optional[list]=None,
                    ns:Optional[collections.abc.Mapping]=None, sp:str='',
                    maxtok=4096, stream:bool=False,
                    tool_choice:Optional[str]=None, cb:<built-
                    infunctioncallable>=None,
                    background:Optional[bool]|Omit=<openai.Omit object at
                    0x7f959677c6a0>, conversation:Optional[response_create
                    _params.Conversation]|Omit=<openai.Omit object at
                    0x7f959677c6a0>, include:Optional[List[ResponseIncluda
                    ble]]|Omit=<openai.Omit object at 0x7f959677c6a0>,
                    input:Union[str,ResponseInputParam]|Omit=<openai.Omit
                    object at 0x7f959677c6a0>,
                    instructions:Optional[str]|Omit=<openai.Omit object at
                    0x7f959677c6a0>,
                    max_output_tokens:Optional[int]|Omit=<openai.Omit
                    object at 0x7f959677c6a0>,
                    max_tool_calls:Optional[int]|Omit=<openai.Omit object
                    at 0x7f959677c6a0>,
                    metadata:Optional[Metadata]|Omit=<openai.Omit object
                    at 0x7f959677c6a0>,
                    model:ResponsesModel|Omit=<openai.Omit object at
                    0x7f959677c6a0>,
                    parallel_tool_calls:Optional[bool]|Omit=<openai.Omit
                    object at 0x7f959677c6a0>,
                    previous_response_id:Optional[str]|Omit=<openai.Omit
                    object at 0x7f959677c6a0>,
                    prompt:Optional[ResponsePromptParam]|Omit=<openai.Omit
                    object at 0x7f959677c6a0>,
                    prompt_cache_key:str|Omit=<openai.Omit object at
                    0x7f959677c6a0>,
                    prompt_cache_retention:"Optional[Literal['in-
                    memory','24h']]|Omit"=<openai.Omit object at
                    0x7f959677c6a0>,
                    reasoning:Optional[Reasoning]|Omit=<openai.Omit object
                    at 0x7f959677c6a0>,
                    safety_identifier:str|Omit=<openai.Omit object at
                    0x7f959677c6a0>, service_tier:"Optional[Literal['auto'
                    ,'default','flex','scale','priority']]|Omit"=<openai.O
                    mit object at 0x7f959677c6a0>,
                    store:Optional[bool]|Omit=<openai.Omit object at
                    0x7f959677c6a0>, stream_options:Optional[response_crea
                    te_params.StreamOptions]|Omit=<openai.Omit object at
                    0x7f959677c6a0>,
                    temperature:Optional[float]|Omit=<openai.Omit object
                    at 0x7f959677c6a0>,
                    text:ResponseTextConfigParam|Omit=<openai.Omit object
                    at 0x7f959677c6a0>,
                    top_logprobs:Optional[int]|Omit=<openai.Omit object at
                    0x7f959677c6a0>,
                    top_p:Optional[float]|Omit=<openai.Omit object at
                    0x7f959677c6a0>, truncation:"Optional[Literal['auto','
                    disabled']]|Omit"=<openai.Omit object at
                    0x7f959677c6a0>, user:str|Omit=<openai.Omit object at
                    0x7f959677c6a0>, extra_headers:Headers|None=None,
                    extra_query:Query|None=None,
                    extra_body:Body|None=None,
                    timeout:float|httpx.Timeout|None|NotGiven=NOT_GIVEN)

Return the value of all tool calls (generally used for structured outputs)

Type Default Details
msgs list Prompt
tools Optional None List of tools to make available to OpenAI model
ns Optional None Namespace to search for tools
sp str System prompt
maxtok int 4096 Maximum tokens
stream bool False Stream response?
tool_choice Optional None Forced tool choice
cb callable None Callback after completion
background Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
conversation Optional[response_create_params.Conversation] | Omit <openai.Omit object at 0x7f959677c6a0>
include Optional[List[ResponseIncludable]] | Omit <openai.Omit object at 0x7f959677c6a0>
input Union[str, ResponseInputParam] | Omit <openai.Omit object at 0x7f959677c6a0>
instructions Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
max_output_tokens Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
max_tool_calls Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
metadata Optional[Metadata] | Omit <openai.Omit object at 0x7f959677c6a0>
model ResponsesModel | Omit <openai.Omit object at 0x7f959677c6a0>
parallel_tool_calls Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
previous_response_id Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt Optional[ResponsePromptParam] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_key str | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_retention Optional[Literal[‘in-memory’, ‘24h’]] | Omit <openai.Omit object at 0x7f959677c6a0>
reasoning Optional[Reasoning] | Omit <openai.Omit object at 0x7f959677c6a0>
safety_identifier str | Omit <openai.Omit object at 0x7f959677c6a0>
service_tier Optional[Literal[‘auto’, ‘default’, ‘flex’, ‘scale’, ‘priority’]] | Omit <openai.Omit object at 0x7f959677c6a0>
store Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
stream_options Optional[response_create_params.StreamOptions] | Omit <openai.Omit object at 0x7f959677c6a0>
temperature Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
text ResponseTextConfigParam | Omit <openai.Omit object at 0x7f959677c6a0>
top_logprobs Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
top_p Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
truncation Optional[Literal[‘auto’, ‘disabled’]] | Omit <openai.Omit object at 0x7f959677c6a0>
user str | Omit <openai.Omit object at 0x7f959677c6a0>
extra_headers Optional None Use the following arguments if you need to pass additional parameters to the API that aren’t available via kwargs.
The extra values given here take precedence over values defined on the client or passed to this method.
extra_query Query | None None
extra_body Body | None None
timeout float | httpx.Timeout | None | NotGiven NOT_GIVEN
Exported source
@patch
@delegates(Client.__call__)
def structured(self:Client,
               msgs: list, # Prompt
               tools:Optional[list]=None, # List of tools to make available to OpenAI model
               ns:Optional[abc.Mapping]=None, # Namespace to search for tools
               **kwargs):
    "Return the value of all tool calls (generally used for structured outputs)"
    if ns is None: ns = mk_ns(tools)
    r = self(msgs, tools=tools, tool_choice='required', **kwargs)
    return first(_toolres(r, ns).values())
class PrimeMinister(BasicRepr):
    "An Australian prime minister"
    def __init__(
        self,
        firstname:str, # First name
        surname:str, # Surname
        dob:str, # Date of birth
        year_entered:int, # Year first became PM
    ): store_attr()
c1 = Client(model)
c1.structured('Who was the first prime minister of Australia?', [PrimeMinister], **rkw)
PrimeMinister(firstname='Edmund', surname='Barton', dob='1849-01-18', year_entered=1901)

Streaming tool calling

msgs = [mk_msg(pr)]
r = c(msgs, sp=sysp, tools=tools, stream=True, **rkw)

We can stream back any tool call text (which may be empty):

for o in r: print(o, end='')

After streaming is complete, value.output will contain the tool calls:

r.value.output
[ResponseReasoningItem(id='rs_08c3e97d4ddd09b800691ba4a0aafc8195bd7818f8d7b9ffb4', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseFunctionToolCall(arguments='{"a":604542,"b":6458932}', call_id='call_TrwIU2wLr6wVWIaXUwdqIWvg', name='sums', type='function_call', id='fc_08c3e97d4ddd09b800691ba4a0ed808195bb1339b1c870ea41', status='completed')]

Therefore we can repeat the same process as before, but using the value attr:

tr = mk_toolres(r.value, ns=ns)
msgs += tr
c(mk_msgs(msgs), sp=sysp, tools=tools, **rkw)
Finding the sum of 604542 and 6458932

7063474

  • id: resp_08c3e97d4ddd09b800691ba4a1b1fc8195b365eedb4fb6427f
  • created_at: 1763419297.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseOutputMessage(id=‘msg_08c3e97d4ddd09b800691ba4a216448195a412da0131247b6c’, content=[ResponseOutputText(annotations=[], text=‘7063474’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: [FunctionTool(name=‘sums’, parameters={‘type’: ‘object’, ‘properties’: {‘a’: {‘type’: ‘integer’, ‘description’: ‘First thing to sum’}, ‘b’: {‘type’: ‘integer’, ‘description’: ‘Second thing to sum’}}, ‘required’: [‘a’, ‘b’], ‘additionalProperties’: False}, strict=True, type=‘function’, description=‘Adds a + b.:- type: integer’)]
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=157, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=7, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=164)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

Chat

Basic chat


source

Chat

 Chat (model:Optional[str]=None, cli:Optional[__main__.Client]=None,
       sp='', tools:Optional[list]=None, hist:list=None,
       tool_choice:Optional[str]=None,
       ns:Optional[collections.abc.Mapping]=None, **kw)

OpenAI chat client.

Type Default Details
model Optional None Model to use (leave empty if passing cli)
cli Optional None Client to use (leave empty if passing model)
sp str Optional system prompt
tools Optional None List of tools to make available
hist list None Initialize history
tool_choice Optional None Forced tool choice
ns Optional None Namespace to search for tools
kw VAR_KEYWORD
Exported source
class Chat:
    def __init__(self,
                 model:Optional[str]=None, # Model to use (leave empty if passing `cli`)
                 cli:Optional[Client]=None, # Client to use (leave empty if passing `model`)
                 sp='', # Optional system prompt
                 tools:Optional[list]=None, # List of tools to make available
                 hist: list = None,  # Initialize history
                 tool_choice:Optional[str]=None, # Forced tool choice
                 ns:Optional[abc.Mapping]=None,  # Namespace to search for tools
                 **kw):
        "OpenAI chat client."
        assert model or cli
        self.c = (cli or Client(model))
        self.h = hist if hist else []
        if ns is None: ns=tools
        self.sp,self.tools,self.tool_choice,self.ns,self.kw = sp,tools,tool_choice,ns,kw
    
    @property
    def use(self): return self.c.use
chat = Chat(model, sp=sysp, **rkw)
chat.c.use, chat.h
(In: 0; Out: 0; Total: 0, [])

source

Chat.__call__

 Chat.__call__ (pr=None, stream:bool=False, tools=None, tool_choice=None,
                background:Optional[bool]|Omit=<openai.Omit object at
                0x7f959677c6a0>, conversation:Optional[response_create_par
                ams.Conversation]|Omit=<openai.Omit object at
                0x7f959677c6a0>, include:Optional[List[ResponseIncludable]
                ]|Omit=<openai.Omit object at 0x7f959677c6a0>,
                input:Union[str,ResponseInputParam]|Omit=<openai.Omit
                object at 0x7f959677c6a0>,
                instructions:Optional[str]|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                max_output_tokens:Optional[int]|Omit=<openai.Omit object
                at 0x7f959677c6a0>,
                max_tool_calls:Optional[int]|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                metadata:Optional[Metadata]|Omit=<openai.Omit object at
                0x7f959677c6a0>, model:ResponsesModel|Omit=<openai.Omit
                object at 0x7f959677c6a0>,
                parallel_tool_calls:Optional[bool]|Omit=<openai.Omit
                object at 0x7f959677c6a0>,
                previous_response_id:Optional[str]|Omit=<openai.Omit
                object at 0x7f959677c6a0>,
                prompt:Optional[ResponsePromptParam]|Omit=<openai.Omit
                object at 0x7f959677c6a0>,
                prompt_cache_key:str|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                prompt_cache_retention:"Optional[Literal['in-
                memory','24h']]|Omit"=<openai.Omit object at
                0x7f959677c6a0>,
                reasoning:Optional[Reasoning]|Omit=<openai.Omit object at
                0x7f959677c6a0>, safety_identifier:str|Omit=<openai.Omit
                object at 0x7f959677c6a0>, service_tier:"Optional[Literal[
                'auto','default','flex','scale','priority']]|Omit"=<openai
                .Omit object at 0x7f959677c6a0>,
                store:Optional[bool]|Omit=<openai.Omit object at
                0x7f959677c6a0>, stream_options:Optional[response_create_p
                arams.StreamOptions]|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                temperature:Optional[float]|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                text:ResponseTextConfigParam|Omit=<openai.Omit object at
                0x7f959677c6a0>,
                top_logprobs:Optional[int]|Omit=<openai.Omit object at
                0x7f959677c6a0>, top_p:Optional[float]|Omit=<openai.Omit
                object at 0x7f959677c6a0>, truncation:"Optional[Literal['a
                uto','disabled']]|Omit"=<openai.Omit object at
                0x7f959677c6a0>, user:str|Omit=<openai.Omit object at
                0x7f959677c6a0>, extra_headers:Headers|None=None,
                extra_query:Query|None=None, extra_body:Body|None=None,
                timeout:float|httpx.Timeout|None|NotGiven=NOT_GIVEN)

Add prompt pr to dialog and get a response

Type Default Details
pr NoneType None Prompt / message
stream bool False Stream response?
tools NoneType None Tools to use
tool_choice NoneType None Required tools to use
background Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
conversation Optional[response_create_params.Conversation] | Omit <openai.Omit object at 0x7f959677c6a0>
include Optional[List[ResponseIncludable]] | Omit <openai.Omit object at 0x7f959677c6a0>
input Union[str, ResponseInputParam] | Omit <openai.Omit object at 0x7f959677c6a0>
instructions Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
max_output_tokens Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
max_tool_calls Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
metadata Optional[Metadata] | Omit <openai.Omit object at 0x7f959677c6a0>
model ResponsesModel | Omit <openai.Omit object at 0x7f959677c6a0>
parallel_tool_calls Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
previous_response_id Optional[str] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt Optional[ResponsePromptParam] | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_key str | Omit <openai.Omit object at 0x7f959677c6a0>
prompt_cache_retention Optional[Literal[‘in-memory’, ‘24h’]] | Omit <openai.Omit object at 0x7f959677c6a0>
reasoning Optional[Reasoning] | Omit <openai.Omit object at 0x7f959677c6a0>
safety_identifier str | Omit <openai.Omit object at 0x7f959677c6a0>
service_tier Optional[Literal[‘auto’, ‘default’, ‘flex’, ‘scale’, ‘priority’]] | Omit <openai.Omit object at 0x7f959677c6a0>
store Optional[bool] | Omit <openai.Omit object at 0x7f959677c6a0>
stream_options Optional[response_create_params.StreamOptions] | Omit <openai.Omit object at 0x7f959677c6a0>
temperature Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
text ResponseTextConfigParam | Omit <openai.Omit object at 0x7f959677c6a0>
top_logprobs Optional[int] | Omit <openai.Omit object at 0x7f959677c6a0>
top_p Optional[float] | Omit <openai.Omit object at 0x7f959677c6a0>
truncation Optional[Literal[‘auto’, ‘disabled’]] | Omit <openai.Omit object at 0x7f959677c6a0>
user str | Omit <openai.Omit object at 0x7f959677c6a0>
extra_headers Optional None Use the following arguments if you need to pass additional parameters to the API that aren’t available via kwargs.
The extra values given here take precedence over values defined on the client or passed to this method.
extra_query Query | None None
extra_body Body | None None
timeout float | httpx.Timeout | None | NotGiven NOT_GIVEN
Exported source
@patch
@delegates(Responses.create)
def __call__(self:Chat,
             pr=None,  # Prompt / message
             stream:bool=False, # Stream response?
             tools=None, # Tools to use
             tool_choice=None, # Required tools to use
             **kwargs):
    "Add prompt `pr` to dialog and get a response"
    if isinstance(pr,str): pr = pr.strip()
    if pr: self.h.append(mk_msg(pr))
    if not tools: tools = self.tools
    if not tool_choice: tool_choice = self.tool_choice
    kw = self.kw | kwargs
    def _cb(v):
        self.last = mk_toolres(v, ns=self.ns)
        self.h += self.last
    res = self.c(self.h, sp=self.sp, stream=stream, cb=_cb, tools=tools, **kw)
    return res
chat("I'm Jeremy")
chat("What's my name?")

Your name is Jeremy.

  • id: resp_035c622e9303fba600691ba4a3ec2c8192b023847c0feb78e9
  • created_at: 1763419299.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_035c622e9303fba600691ba4a48d28819299726cee46729ecb’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_035c622e9303fba600691ba4a4b7188192b44dfccd7d73bcf7’, content=[ResponseOutputText(annotations=[], text=‘Your name is Jeremy.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=68, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=11, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=79)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True
chat = Chat(model, sp=sysp, **rkw)
for o in chat("I'm Jeremy", stream=True): print(o, end='')
Nice to meet you, Jeremy. How can I help you today?
r = chat("What's my name?", stream=True, **rkw)
for o in r: print(o, end='')
Your name is Jeremy.
r.value

Your name is Jeremy.

  • id: resp_08464518fa64a03200691ba4a693808190a7e46bee38560f98
  • created_at: 1763419302.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_08464518fa64a03200691ba4a71cec819093b98378fa21d647’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_08464518fa64a03200691ba4a743f08190a8c4b9b9f933a435’, content=[ResponseOutputText(annotations=[], text=‘Your name is Jeremy.’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=68, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=11, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=79)
  • user: None
  • store: True

History is stored in the h attr:

chat.h
[{'role': 'user', 'content': "I'm Jeremy"},
 ResponseReasoningItem(id='rs_08464518fa64a03200691ba4a5ab60819099386e08686aa1d2', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseOutputMessage(id='msg_08464518fa64a03200691ba4a5ce48819095a23194bdaf6184', content=[ResponseOutputText(annotations=[], text='Nice to meet you, Jeremy. How can I help you today?', type='output_text', logprobs=[])], role='assistant', status='completed', type='message'),
 {'role': 'user', 'content': "What's my name?"},
 ResponseReasoningItem(id='rs_08464518fa64a03200691ba4a71cec819093b98378fa21d647', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseOutputMessage(id='msg_08464518fa64a03200691ba4a743f08190a8c4b9b9f933a435', content=[ResponseOutputText(annotations=[], text='Your name is Jeremy.', type='output_text', logprobs=[])], role='assistant', status='completed', type='message')]

Chat tool use

pr = f"What is {a}+{b}?"
pr
'What is 604542+6458932?'
chat = Chat(model, sp=sysp, tools=[sums], **rkw)
r = chat(pr)
r.output
Finding the sum of 604542 and 6458932
[ResponseReasoningItem(id='rs_0ee933694072489500691ba4a859c081a3a60b193960051eb4', summary=[], type='reasoning', content=None, encrypted_content=None, status=None),
 ResponseFunctionToolCall(arguments='{"a":604542,"b":6458932}', call_id='call_ebTRKFMiijgOGVfwFhjH5pPL', name='sums', type='function_call', id='fc_0ee933694072489500691ba4a8a8d881a3b3090c7231d8b92d', status='completed')]
chat()

7,063,474

  • id: resp_0ee933694072489500691ba4a944e081a39ad25146ac43735a
  • created_at: 1763419305.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseOutputMessage(id=‘msg_0ee933694072489500691ba4a9bc1081a39dc3eebde73ed1d6’, content=[ResponseOutputText(annotations=[], text=‘7,063,474’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: [FunctionTool(name=‘sums’, parameters={‘type’: ‘object’, ‘properties’: {‘a’: {‘type’: ‘integer’, ‘description’: ‘First thing to sum’}, ‘b’: {‘type’: ‘integer’, ‘description’: ‘Second thing to sum’}}, ‘required’: [‘a’, ‘b’], ‘additionalProperties’: False}, strict=True, type=‘function’, description=‘Adds a + b.:- type: integer’)]
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=157, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=9, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=166)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True
q = "In brief, what color flowers are in this image?"
chat([img, q])

Purple

  • id: resp_0ee933694072489500691ba4ab556481a388a77a6d4dd0c798
  • created_at: 1763419307.0
  • error: None
  • incomplete_details: None
  • instructions: You are a helpful assistant. When using tools, be sure to pass all required parameters. Don’t use tools unless needed for the provided prompt.
  • metadata: {}
  • model: gpt-5-mini-2025-08-07
  • object: response
  • output: [ResponseReasoningItem(id=‘rs_0ee933694072489500691ba4abbd5881a3ac733003839637b8’, summary=[], type=‘reasoning’, content=None, encrypted_content=None, status=None), ResponseOutputMessage(id=‘msg_0ee933694072489500691ba4abeda481a3a4a19dbed1d05c7f’, content=[ResponseOutputText(annotations=[], text=‘Purple’, type=‘output_text’, logprobs=[])], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: [FunctionTool(name=‘sums’, parameters={‘type’: ‘object’, ‘properties’: {‘a’: {‘type’: ‘integer’, ‘description’: ‘First thing to sum’}, ‘b’: {‘type’: ‘integer’, ‘description’: ‘Second thing to sum’}}, ‘required’: [‘a’, ‘b’], ‘additionalProperties’: False}, strict=True, type=‘function’, description=‘Adds a + b.:- type: integer’)]
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘minimal’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=‘low’)
  • top_logprobs: 0
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=257, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=7, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=264)
  • user: None
  • billing: {‘payer’: ‘developer’}
  • store: True

Third Party Providers

Azure OpenAI Service

Example Azure usage:

azure_endpoint = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
  api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version="2024-08-01-preview"
)

client = Client(models_azure[0], azure_endpoint)
chat = Chat(cli=client)
chat("Hi.")

Other providers

Here’s an example of using the library with Groq:

groq_c = Client(
    model="openai/gpt-oss-20b",
    api_key_env="GROQ_KEY",
    base_url="https://api.groq.com/openai/v1"
)

groq_c("Hello! What's 2+2?")

Hello! 2 + 2 equals 4.

  • id: resp_01kaa21yfhfaja29yr841tz1c9
  • created_at: 1763421780.0
  • error: None
  • incomplete_details: None
  • instructions:
  • metadata: {}
  • model: openai/gpt-oss-20b
  • object: response
  • output: [ResponseReasoningItem(id=‘resp_01kaa21yfhfajsp0cbvjx0ww5b’, summary=[], type=‘reasoning’, content=[Content(text=‘The user: “Hello! What's 2+2?” It's a straightforward arithmetic question. We need to respond. The policies: no disallowed content. It's fine. Just answer 4. Provide friendly tone.’, type=‘reasoning_text’)], encrypted_content=None, status=‘completed’), ResponseOutputMessage(id=‘msg_01kaa21yfhfak80c1kcggjhmh4’, content=[ResponseOutputText(annotations=[], text=‘Hello! 202f+02f2 equals 4.’, type=‘output_text’, logprobs=None)], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘medium’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=None)
  • top_logprobs: None
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=79, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=66, output_tokens_details=OutputTokensDetails(reasoning_tokens=44), total_tokens=145)
  • user: None
  • store: False
gchat = Chat(cli=groq_c)
gchat("Hello! I'm Jeremy")

Hey Jeremy! 👋 How’s it going? Anything exciting on your radar today or something you’d like to chat about?

  • id: resp_01kaa27bsrfxnb5p75bztj84pb
  • created_at: 1763421957.0
  • error: None
  • incomplete_details: None
  • instructions:
  • metadata: {}
  • model: openai/gpt-oss-20b
  • object: response
  • output: [ResponseReasoningItem(id=‘resp_01kaa27bsrfxnrkywsnwzgd52z’, summary=[], type=‘reasoning’, content=[Content(text=‘The user says “Hello! I'm Jeremy”. They are greeting the assistant. Likely want a friendly response. We should respond politely, maybe ask how they can help. Use friendly tone.’, type=‘reasoning_text’)], encrypted_content=None, status=‘completed’), ResponseOutputMessage(id=‘msg_01kaa27bsrfxpastb7n905j67d’, content=[ResponseOutputText(annotations=[], text=‘Hey Jeremy! 👋 How’s it going? Anything exciting on your radar today or something you’d like to chat about?’, type=‘output_text’, logprobs=None)], role=‘assistant’, status=‘completed’, type=‘message’)]
  • parallel_tool_calls: True
  • temperature: 1.0
  • tool_choice: auto
  • tools: []
  • top_p: 1.0
  • background: False
  • conversation: None
  • max_output_tokens: 4096
  • max_tool_calls: None
  • previous_response_id: None
  • prompt: None
  • prompt_cache_key: None
  • prompt_cache_retention: None
  • reasoning: Reasoning(effort=‘medium’, generate_summary=None, summary=None)
  • safety_identifier: None
  • service_tier: default
  • status: completed
  • text: ResponseTextConfig(format=ResponseFormatText(type=‘text’), verbosity=None)
  • top_logprobs: None
  • truncation: disabled
  • usage: ResponseUsage(input_tokens=75, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=73, output_tokens_details=OutputTokensDetails(reasoning_tokens=39), total_tokens=148)
  • user: None
  • store: False
gchat("What's my name?")