# Tool use

## Tool definition

* v1: uses Python types to define tools.
* v2: uses JSON schema to define tools.

**v1**

```python PYTHON
def get_weather(location):
    return {"temperature": "20C"}


functions_map = {"get_weather": get_weather}

tools_v1 = [
    {
        "name": "get_weather",
        "description": "Gets the weather of a given location",
        "parameter_definitions": {
            "location": {
                "description": "The location to get weather, example: San Francisco, CA",
                "type": "str",
                "required": True,
            }
        },
    },
]
```

**v2**

```python PYTHON
def get_weather(location):
    return [{"temperature": "20C"}]
    # You can return a list of objects e.g. [{"url": "abc.com", "text": "..."}, {"url": "xyz.com", "text": "..."}]


functions_map = {"get_weather": get_weather}

tools_v2 = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "gets the weather of a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "the location to get weather, example: San Fransisco, CA",
                    }
                },
                "required": ["location"],
            },
        },
    },
]
```

## Tool calling

* Response handling
  * v1: Tool calls accessed through `response.tool_calls`
  * v2: Tool calls accessed through `response.message.tool_calls`

* Chat history management
  * v1: Tool calls stored in the response's `chat_history`
  * v2: Append the tool call details (`tool_calls` and `tool_plan`) to the `messages` list

**v1**

```python PYTHON
message = "What's the weather in Toronto?"

res_v1 = co_v1.chat(
    model="command-a-03-2025", message=message, tools=tools_v1
)

print(res_v1.tool_calls)
```

```
[ToolCall(name='get_weather', parameters={'location': 'Toronto'})]
```

**v2**

```python PYTHON
messages = [
    {"role": "user", "content": "What's the weather in Toronto?"}
]

res_v2 = co_v2.chat(
    model="command-a-03-2025", messages=messages, tools=tools_v2
)

if res_v2.message.tool_calls:
    messages.append(res_v2.message)

    print(res_v2.message.tool_calls)
```

```
[ToolCallV2(id='get_weather_k88p0m8504w5', type='function', function=ToolCallV2Function(name='get_weather', arguments='{"location":"Toronto"}'))]
```

## Tool call ID

* v1: Tool calls do not emit tool call IDs
* v2: Tool calls emit tool call IDs. This will help the model match tool results to the right tool call.

**v1**

```python PYTHON
tool_results = [
    {
        "call": {
            "name": "<tool name>",
            "parameters": {"<param name>": "<param value>"},
        },
        "outputs": [{"<key>": "<value>"}],
    },
]
```

**v2**

```python PYTHON
messages = [
    {
        "role": "tool",
        "tool_call_id": "123",
        "content": [
            {
                "type": "document",
                "document": {
                    "id": "123",
                    "data": {"<key>": "<value>"},
                },
            }
        ],
    }
]
```

## Response generation

* Tool execution: Chat history management
  * v1: Append `call` and `outputs` to the chat history
  * v2: Append `tool_call_id` and `tool_content` to `messages` to the chat history

* Tool execution: Tool results
  * v1: Passed as `tool_results` parameter
  * v2: Incorporated into the `messages` list as tool responses

* User message
  * v1: Set as empty (`""`)
  * v2: No action required

**v1**

```python PYTHON
tool_content_v1 = []
if res_v1.tool_calls:
    for tc in res_v1.tool_calls:
        tool_call = {"name": tc.name, "parameters": tc.parameters}
        tool_result = functions_map[tc.name](**tc.parameters)
        tool_content_v1.append(
            {"call": tool_call, "outputs": [tool_result]}
        )

res_v1 = co_v1.chat(
    model="command-a-03-2025",
    message="",
    tools=tools_v1,
    tool_results=tool_content_v1,
    chat_history=res_v1.chat_history,
)

print(res_v1.text)
```

```
It is currently 20°C in Toronto.
```

**v2**

```python PYTHON
if res_v2.message.tool_calls:
    for tc in res_v2.message.tool_calls:
        tool_result = functions_map[tc.function.name](
            **json.loads(tc.function.arguments)
        )
        tool_content_v2 = []
        for data in tool_result:
            tool_content_v2.append(
                {
                    "type": "document",
                    "document": {"data": json.dumps(data)},
                }
            )
            # Optional: add an "id" field in the "document" object, otherwise IDs are auto-generated
        messages.append(
            {
                "role": "tool",
                "tool_call_id": tc.id,
                "content": tool_content_v2,
            }
        )

res_v2 = co_v2.chat(
    model="command-a-03-2025", messages=messages, tools=tools_v2
)

print(res_v2.message.content[0].text)
```

```
It's 20°C in Toronto.
```

## Citations

* Citations access:
  * v1: `citations`
  * v2: `message.citations`
* Cited tools access:
  * v1: `documents`
  * v2: as part of `message.citations`, in the `sources` field

**v1**

```python PYTHON
print(res_v1.citations)
print(res_v1.documents)
```

```
[ChatCitation(start=16, end=20, text='20°C', document_ids=['get_weather:0:2:0'])]

[{'id': 'get_weather:0:2:0', 'temperature': '20C', 'tool_name': 'get_weather'}]
```

**v2**

```python PYTHON
print(res_v2.message.citations)
```

```
[Citation(start=5, end=9, text='20°C', sources=[ToolSource(type='tool', id='get_weather_k88p0m8504w5:0', tool_output={'temperature': '20C'})])]
```

## Streaming

* Event containing content:
  * v1: `chunk.event_type == "text-generation"`
  * v2: `chunk.type == "content-delta"`

* Accessing response content:
  * v1: `chunk.text`
  * v2: `chunk.delta.message.content.text`

* Events containing citations:
  * v1: `chunk.event_type == "citation-generation"`
  * v2: `chunk.type == "citation-start"`

* Accessing citations:
  * v1: `chunk.citations`
  * v2: `chunk.delta.message.citations`

**v1**

```python PYTHON
tool_content_v1 = []
if res_v1.tool_calls:
    for tc in res_v1.tool_calls:
        tool_call = {"name": tc.name, "parameters": tc.parameters}
        tool_result = functions_map[tc.name](**tc.parameters)
        tool_content_v1.append(
            {"call": tool_call, "outputs": [tool_result]}
        )

res_v1 = co_v1.chat_stream(
    message="",
    tools=tools_v1,
    tool_results=tool_content_v1,
    chat_history=res_v1.chat_history,
)

for chunk in res_v1:
    if chunk.event_type == "text-generation":
        print(chunk.text, end="")
    if chunk.event_type == "citation-generation":
        print(f"\n{chunk.citations}")
```

```
It's 20°C in Toronto.

[ChatCitation(start=5, end=9, text='20°C', document_ids=['get_weather:0:2:0', 'get_weather:0:4:0'])]
```

**v2**

```python PYTHON
if res_v2.message.tool_calls:
    for tc in res_v2.message.tool_calls:
        tool_result = functions_map[tc.function.name](
            **json.loads(tc.function.arguments)
        )
        tool_content_v2 = []
        for data in tool_result:
            tool_content_v2.append(
                {
                    "type": "document",
                    "document": {"data": json.dumps(data)},
                }
            )
            # Optional: add an "id" field in the "document" object, otherwise IDs are auto-generated
        messages.append(
            {
                "role": "tool",
                "tool_call_id": tc.id,
                "content": tool_content_v2,
            }
        )

res_v2 = co_v2.chat_stream(
    model="command-a-03-2025", messages=messages, tools=tools_v2
)

for chunk in res_v2:
    if chunk:
        if chunk.type == "content-delta":
            print(chunk.delta.message.content.text, end="")
        elif chunk.type == "citation-start":
            print(f"\n{chunk.delta.message.citations}")
```

```
It's 20°C in Toronto.

start=5 end=9 text='20°C' sources=[ToolSource(type='tool', id='get_weather_k88p0m8504w5:0', tool_output={'temperature': '20C'})]
```

## Citation quality (both RAG and tool use)

* v1: controlled via `citation_quality` parameter
* v2: controlled via `citation_options` parameter (with `mode` as a key)