File size: 1,460 Bytes
f8197b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from __future__ import annotations

import pytest

from app.llm.base import ProviderError, parse_openai_choice


def test_parse_valid_tool_call():
    data = {"choices": [{"message": {"content": None, "tool_calls": [
        {"id": "1", "function": {"name": "search_products", "arguments": '{"query": "hose"}'}}
    ]}, "finish_reason": "tool_calls"}]}
    res = parse_openai_choice(data)
    assert res.tool_calls[0].name == "search_products"
    assert res.tool_calls[0].arguments == {"query": "hose"}


def test_empty_string_args_become_empty_dict():
    data = {"choices": [{"message": {"tool_calls": [
        {"id": "1", "function": {"name": "reorder", "arguments": "  "}}
    ]}}]}
    assert parse_openai_choice(data).tool_calls[0].arguments == {}


def test_malformed_tool_args_raise_to_failover():
    # a weak model emitted invalid JSON for a required-arg tool — must NOT be
    # silently dispatched with {}; raise so the router fails over.
    data = {"choices": [{"message": {"tool_calls": [
        {"id": "1", "function": {"name": "lookup_order", "arguments": "{email: not json"}}
    ]}}]}
    with pytest.raises(ProviderError):
        parse_openai_choice(data)


def test_plain_text_answer_parsed():
    data = {"choices": [{"message": {"content": "hello"}, "finish_reason": "stop"}],
            "usage": {"total_tokens": 5}}
    res = parse_openai_choice(data)
    assert res.content == "hello"
    assert res.usage["total_tokens"] == 5