> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yelu.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool calling example

> Request a model tool call, validate arguments, return a tool result, and generate the final answer.

This example shows the protocol in two requests. The weather result is deterministic sample application data; replace it with your validated tool implementation.

## 1. Request a call

<CodeGroup>
  ```bash Curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  tools='[{"type":"function","function":{"name":"get_weather","description":"Get current weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"],"additionalProperties":false}}}]'

  first_request=$(jq -nc --argjson tools "$tools" '{
    model: "gpt-4o-mini",
    messages: [{role:"user", content:"Do I need an umbrella in Shanghai?"}],
    tools: $tools
  }')
  first_response=$(curl -sS https://api.yelu.ai/v1/chat/completions \
    -H "Authorization: Bearer $YELU_API_KEY" \
    -H "Content-Type: application/json" \
    -d "$first_request")

  assistant=$(jq -c '.choices[0].message' <<<"$first_response")
  call_id=$(jq -r '.tool_calls[0].id' <<<"$assistant")
  city=$(jq -r '.tool_calls[0].function.arguments | fromjson | .city' <<<"$assistant")
  tool_result=$(jq -nc --arg city "$city" '{city:$city, condition:"rain", temperature_c:24}')

  second_request=$(jq -nc \
    --argjson tools "$tools" \
    --argjson assistant "$assistant" \
    --arg call_id "$call_id" \
    --arg tool_result "$tool_result" '{
      model: "gpt-4o-mini",
      messages: [
        {role:"user", content:"Do I need an umbrella in Shanghai?"},
        $assistant,
        {role:"tool", tool_call_id:$call_id, content:$tool_result}
      ],
      tools: $tools
    }')

  curl -sS https://api.yelu.ai/v1/chat/completions \
    -H "Authorization: Bearer $YELU_API_KEY" \
    -H "Content-Type: application/json" \
    -d "$second_request" | jq -r '.choices[0].message.content'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const messages = [{ role: 'user', content: 'Do I need an umbrella in Shanghai?' }];
  const tools = [{ type: 'function', function: {
    name: 'get_weather',
    description: 'Get current weather for a city',
    parameters: {
      type: 'object',
      properties: { city: { type: 'string' } },
      required: ['city'],
      additionalProperties: false,
    },
  } }];

  async function complete(body) {
    const response = await fetch('https://api.yelu.ai/v1/chat/completions', {
      method: 'POST',
      headers: { Authorization: `Bearer ${process.env.YELU_API_KEY}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({ model: 'gpt-4o-mini', ...body }),
    });
    if (!response.ok) throw new Error(await response.text());
    return response.json();
  }

  const first = await complete({ messages, tools });
  const assistant = first.choices[0].message;
  const call = assistant.tool_calls[0];
  const args = JSON.parse(call.function.arguments);
  if (call.function.name !== 'get_weather' || typeof args.city !== 'string') throw new Error('Invalid tool call');

  messages.push(assistant, {
    role: 'tool',
    tool_call_id: call.id,
    content: JSON.stringify({ city: args.city, condition: 'rain', temperature_c: 24 }),
  });
  const final = await complete({ messages, tools });
  console.log(final.choices[0].message.content);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import json
  import os
  import requests

  messages = [{"role": "user", "content": "Do I need an umbrella in Shanghai?"}]
  tools = [{"type": "function", "function": {
      "name": "get_weather",
      "description": "Get current weather for a city",
      "parameters": {
          "type": "object",
          "properties": {"city": {"type": "string"}},
          "required": ["city"],
          "additionalProperties": False,
      },
  }}]

  def complete():
      response = requests.post(
          "https://api.yelu.ai/v1/chat/completions",
          headers={"Authorization": f"Bearer {os.environ['YELU_API_KEY']}"},
          json={"model": "gpt-4o-mini", "messages": messages, "tools": tools},
          timeout=60,
      )
      response.raise_for_status()
      return response.json()

  assistant = complete()["choices"][0]["message"]
  call = assistant["tool_calls"][0]
  arguments = json.loads(call["function"]["arguments"])
  if call["function"]["name"] != "get_weather" or not isinstance(arguments.get("city"), str):
      raise ValueError("Invalid tool call")

  messages.extend([assistant, {
      "role": "tool",
      "tool_call_id": call["id"],
      "content": json.dumps({"city": arguments["city"], "condition": "rain", "temperature_c": 24}),
  }])
  print(complete()["choices"][0]["message"]["content"])
  ```
</CodeGroup>

<Warning>
  Never execute a tool solely because the model requested it. Validate the name and arguments, enforce user authorization, and require confirmation for consequential actions.
</Warning>
