Problem with tools
# support
a
I have API to connect with assistant. I am creating call like that:
Copy code
def create_call():
    resp = requests.post(
        "https://api.vapi.ai/call",
        headers={"Authorization": API_KEY, "Content-Type": "application/json"},
        json={
            "assistantId": ASSISTANT_ID,
            "transport": {
                "provider": "vapi.websocket",
                "audioFormat": {
                    "format": "pcm_s16le",
                    "container": "raw",
                    "sampleRate": SR
                }
            },
            "assistantOverrides": {
                "variableValues": {
                    "full_name": "",
                    "phone": "",
                    "date": "",
                    "time": "",
                    "appointment_type": ""
                }
            }
        }
    )
    if not resp.ok:
        print("Failed to create call:", resp.text)
        return None
    return resp.json()["transport"]["websocketCallUrl"]
call id for example: 9cda111e-53f5-4fe6-97f6-da072adbde6c
i have a tool:
Copy code
{
  "id": "71276008-3da2-48c6-bc80-31b3b9d0d63d",
  "createdAt": "2025-06-14T20:16:34.394Z",
  "updatedAt": "2025-08-05T18:00:45.226Z",
  "type": "function",
  "function": {
    "name": "search_patient",
    "strict": true,
    "parameters": {
      "type": "object",
      "properties": {
        "phone": {
          "description": "",
          "type": "string"
        },
        "full_name": {
          "description": "",
          "type": "string"
        }
      },
      "required": []
    }
  },
  "messages": [
    {
      "role": "assistant",
      "type": "request-complete",
      "content": "I have found patient {{full_name}}. The phone number is: {{phone}}. Do you want to schedule an appointment?",
      "conditions": [
        {
          "param": "phone",
          "value": "\"\"",
          "operator": "neq"
        }
      ],
      "endCallAfterSpokenEnabled": false
    },
    {
      "type": "request-start",
      "content": "Please wait a second, i am checking our database for the patient called {{full_name}}",
      "blocking": false,
      "conditions": [
        {
          "param": "full_name",
          "value": "\"\"",
          "operator": "neq"
        }
      ]
    },
    {
      "type": "request-response-delayed",
      "content": "I am facing some delay, sorry for that.",
      "timingMilliseconds": 1000
    }
  ],
  "orgId": "577d690d-6bc1-40e5-ba66-2baad1505f3f",
  "async": false
}
i am getting tool call request: search_patient
Copy code
(call_id=call_rnm9I0v5U6A8NUsWn4OwTHhc): {"full_name": "Xxx"}
And i am sending answer:
{'results': [{'toolCallId': 'call_rnm9I0v5U6A8NUsWn4OwTHhc', 'result': {'full_name': 'Xxx', 'phone': 'Yyy'}}]}}
i use function to create and sent tool call snawer:
Copy code
async def handle_tool_call(ws, tool_call):
    import uuid

    call_id = tool_call["id"]
    tool_name = tool_call["function"]["name"]
    args = json.loads(tool_call["function"].get("arguments", "{}") or "{}")

    result = {}

    try:
        if tool_name == "search_patient":
            r = requests.get("https://scheduling-test.vercel.app/patients/search", params=args)
            if r.ok and r.text.strip():
                d = r.json()
                user_data.update({
                    "user_id": d.get("user_id"),
                    "full_name": d.get("full_name"),
                    "phone": d.get("phone")
                })
                result = {
                    "full_name": d.get("full_name"),
                    "phone": d.get("phone")
                }
                payload_data = {
                    "user_id": user_data["user_id"],
                    "datetime": f"{args.get('date')} {args.get('time')}",
                    "appointment_type": appointment_type,
                    "full_name": user_data.get("full_name"),
                    "phone": user_data.get("phone")
                }
                r = requests.post("https://scheduling-test.vercel.app/appointments/create", json=payload_data)
                data = r.json()
                if data.get("status") == "success":
                    result = {
                        "full_name": user_data["full_name"],
                        "date": args.get("date"),
                        "time": args.get("time"),
                        "appointment_type": appointment_type
                    }

        else:
            print(f"Unknown tool: {tool_name}")

    except Exception as e:
        print(f"Error in {tool_name}: {e}")
        result = {}

    payload = {
        "results": [{
            "toolCallId": call_id,
            "result": result
        }]
    }
    await ws.send(json.dumps(payload))
and the call transcription is:
Copy code
{
  "role": "bot",
  "time": 1754416697157,
  "source": "",
  "endTime": 1754416701547,
  "message": "Thank you for calling Vera Dental of Riverton. Uh, this is Robin, your health care coordinator.",
  "duration": 4310,
  "secondsFromStart": 0.79999995
}
{
  "role": "user",
  "time": 1754416702906.9998,
  "endTime": 1754416706257,
  "message": "Hi. Please provide me with the information about patient Max.",
  "duration": 3060.000244140625,
  "secondsFromStart": 6.5499997
}
{
  "role": "bot",
  "time": 1754416707746.999,
  "source": "",
  "endTime": 1754416710007,
  "message": "Please wait a second. I am checking our database.",
  "duration": 2260.0009765625,
  "secondsFromStart": 11.389999
}
{
  "role": "tool_calls",
  "time": 1754416708120,
  "message": "",
  "toolCalls": [
    {
      "id": "call_rnm9I0v5U6A8NUsWn4OwTHhc",
      "type": "function",
      "function": {
        "name": "search_patient",
        "arguments": "{\"full_name\": \"Max\"}"
      }
    }
  ],
  "secondsFromStart": 9.858
}
{
  "role": "bot",
  "time": 1754416710927.001,
  "source": "",
  "endTime": 1754416711767,
  "message": "For the patient called",
  "duration": 839.9990234375,
  "secondsFromStart": 14.570001
}
{
  "name": "search_patient",
  "role": "tool_call_result",
  "time": 1754416713018,
  "result": "No result returned.",
  "toolCallId": "call_rnm9I0v5U6A8NUsWn4OwTHhc",
  "secondsFromStart": 14.756
}
{
  "role": "bot",
  "time": 1754416713687,
  "source": "",
  "endTime": 1754416722717,
  "message": "I'm sorry, but I couldn't find any information for a patient named Max in our records. Could you please provide a full name or a phone number for more accurate results?",
  "duration": 8470,
  "secondsFromStart": 17.33
}
so the assistant still doesnt get any tool call answer from my API. I have spent several months and this problem and dont know what to do, pls help me. I can send full script of my api
h
Your assistant says “No result returned” because Vapi never receives or properly parses your tool response. Most likely causes: Your result payload is missing required fields (full_name, phone) or is {}. You sent malformed JSON or string instead of a proper object. You’re not sending the WebSocket message on the correct open connection. Your API call failed silently and returned nothing.
try this script import asyncio, requests, json, sounddevice as sd, numpy as np, websockets API_KEY = "Bearer af15582f-034d-41f2-8086-78a02df86b84" ASSISTANT_ID = "b0f78268-f43c-426f-a341-fa2544f1b46d" SR = 16000 def create_call(): resp = requests.post( "https://api.vapi.ai/call", headers={"Authorization": API_KEY, "Content-Type": "application/json"}, json={ "assistantId": ASSISTANT_ID, "transport": { "provider": "vapi.websocket", "audioFormat": { "format": "pcm_s16le", "container": "raw", "sampleRate": SR } }, "assistantOverrides": { "variableValues": { "full_name": "", "phone": "", "date": "", "time": "", "appointment_type": "" } } } ) if not resp.ok: print("Failed to create call:", resp.text) return None return resp.json()["transport"]["websocketCallUrl"]
async def handle_tool_call(ws, tool_call): tool_id = tool_call["id"] name = tool_call["function"]["name"] args = json.loads(tool_call["function"].get("arguments", "{}") or "{}") print("Tool call received:", name, args) # Just return dummy data for now to verify response works if name == "search_patient": result = { "full_name": "Max Taylor", "phone": "1234567890" } else: result = {} payload = { "results": [{ "toolCallId": tool_id, "result": result }] } print("Sending tool result:", payload) await ws.send(json.dumps(payload)) async def stream_call(ws_url): async with websockets.connect(ws_url) as ws: print("WebSocket connected!") async def recv_loop(): async for msg in ws: data = json.loads(msg) role = data.get("role") if role == "tool_calls": for call in data["toolCalls"]: await handle_tool_call(ws, call) elif role == "bot": print("BOT:", data["message"]) elif role == "user": print("USER:", data["message"]) elif role == "tool_call_result": print("TOOL RESULT ACK:", data) async def send_audio(): def callback(indata, frames, time, status): if status: print("Input error:", status) ws.send(indata.tobytes()) # send raw audio with sd.InputStream(channels=1, samplerate=SR, dtype='int16', callback=callback): await asyncio.Future() # run forever or until user stops await asyncio.gather(recv_loop()) if __name__ == "__main__": ws_url = create_call() if ws_url: asyncio.run(stream_call(ws_url)) else: print("No call started.")
a
Basicaly this code isnt working at all cos of: UnicodeDecodeError: 'utf-32-be' codec can't decode bytes in position 40-43: code point not in range(0x110000) decoding with 'utf-32-be' codec failed On the way for solution i have changed a lot so it is not the same code so experiment is irrelevant
Also your script doesnt have any fuctionality for me to answer assistant so i cant trigger tool with my voice and i cant even trigger conversation
call id for fixed version of your code: 093a39f3-0960-4e41-b455-0a9f3861e4a5 i triggered tool call but no proper result in the transcription: in the message.txt no information about tool response, so how should them work? https://cdn.discordapp.com/attachments/1402394550307262597/1405156799795167344/message.txt?ex=689dcdbf&is=689c7c3f&hm=f9e5e7f64fd607e44f4a38c1b0c25575595c62f3d0a5088f3d85f78f565883a5&
c
Hey there! It seems like your tool call response format isn’t quite right. You’ll need to adjust it to match the expected format. You can check out the documentation and snippet below for the correct details. Hope this helps! Documentation Link: Tool Call Response Format:
Copy code
{
  "results": [
    {
      "toolCallId": "X",
      "result": "Y"
    }
  ]
}
a
I have used format you gave me and it is pretty much the same you texted
c
Can you let me know if you're still experiencing this issue?
a
yes
c
Hi, let me check with our team and get back to you with an update.
k
Can you please provide a recent call id made within the past <7 days where the tool call fails?
a
it doesnt have sense cos u will answer for 2-3 weeks
c
We apologize for the delay in our responses and we would still like to provide support to you if you need assistance. If you are no longer experiencing issues, we will close this ticket.
3 Views