Spaces:
Running on Zero
Running on Zero
File size: 7,030 Bytes
cb3451f | 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | import pytest
from hackathon_advisor.dashboard_chat_contracts import (
CHAT_TOOL_SPECS,
chat_tool_schemas,
heuristic_chat_call,
parse_native_tool_call,
resolve_chat_tool_call,
strip_function_blocks,
)
from hackathon_advisor.tool_contracts import ToolContractError
def test_chat_tool_schemas_are_openai_style() -> None:
schemas = chat_tool_schemas()
assert len(schemas) == len(CHAT_TOOL_SPECS) == 9
for schema in schemas:
assert schema["type"] == "function"
assert schema["function"]["parameters"]["type"] == "object"
def test_parse_native_tool_call_reads_params() -> None:
call = parse_native_tool_call(
'<function name="search_projects"><param name="query">voice agents</param></function>'
)
assert call.name == "search_projects"
assert call.arguments == {"query": "voice agents"}
def test_parse_native_tool_call_handles_cdata_and_surrounding_prose() -> None:
call = parse_native_tool_call(
'Let me look that up.\n<function name="show_cluster">'
"<param name=\"label\"><![CDATA[Voice / Chatbot & ASR]]></param></function> Done."
)
assert call.name == "show_cluster"
assert call.arguments == {"label": "Voice / Chatbot & ASR"}
def test_parse_native_tool_call_without_params() -> None:
call = parse_native_tool_call('<function name="list_quests"></function>')
assert call.name == "list_quests"
assert call.arguments == {}
def test_parse_native_tool_call_rejects_garbage() -> None:
with pytest.raises(ToolContractError):
parse_native_tool_call('<function name="x"><param name="q">unclosed</function>')
with pytest.raises(ToolContractError):
parse_native_tool_call("just prose, no call")
with pytest.raises(ToolContractError):
parse_native_tool_call('<function><param name="q">missing name</param></function>')
def test_resolve_marks_plain_prose_as_none() -> None:
resolution = resolve_chat_tool_call("Hello! Ask me about the atlas.", fallback_query="hello")
assert resolution.status == "none"
assert resolution.call is None
assert resolution.errors == ()
def test_resolve_accepts_valid_call() -> None:
resolution = resolve_chat_tool_call(
'<function name="show_quest"><param name="quest">Tiny Titan</param></function>',
fallback_query="tiny titan",
)
assert resolution.status == "valid"
assert resolution.call is not None
assert resolution.call.name == "show_quest"
def test_resolve_defaults_unknown_tool_through_intent_router() -> None:
resolution = resolve_chat_tool_call(
'<function name="made_up_tool"></function>',
fallback_query="who completed the most quests?",
)
assert resolution.status == "defaulted"
assert resolution.call is not None
assert resolution.call.name == "top_projects_by_quests"
assert resolution.errors
def test_resolve_defaults_malformed_xml_to_search() -> None:
resolution = resolve_chat_tool_call(
'<function name="search_projects"><param name="query">a < b</param></function>',
fallback_query="projects about voice",
)
assert resolution.status == "defaulted"
assert resolution.call is not None
assert resolution.call.name == "search_projects"
assert resolution.call.arguments["query"] == "projects about voice"
def test_resolve_rejects_missing_required_argument() -> None:
resolution = resolve_chat_tool_call(
'<function name="show_cluster"></function>',
fallback_query="show me the voice cluster",
)
assert resolution.status == "defaulted"
assert resolution.errors
def test_heuristic_chat_call_routes_intents() -> None:
assert heuristic_chat_call("who completed the most quests").name == "top_projects_by_quests"
assert heuristic_chat_call("what clusters exist").name == "list_clusters"
assert heuristic_chat_call("list the quests please").name == "list_quests"
assert heuristic_chat_call("what changed recently").name == "recent_activity"
assert heuristic_chat_call("what is everyone building").name == "atlas_overview"
assert heuristic_chat_call("knitting helpers").name == "search_projects"
assert heuristic_chat_call("").name == "atlas_overview"
def test_data_intent_call_separates_detail_from_listing() -> None:
from hackathon_advisor.dashboard_chat_contracts import data_intent_call
detail = data_intent_call("what is in the Dream / Oracle cluster?")
assert detail is not None and detail.name == "show_cluster"
assert "Dream / Oracle" in detail.arguments["label"]
quest_detail = data_intent_call("tell me about the Tiny Titan quest")
assert quest_detail is not None and quest_detail.name == "show_quest"
assert data_intent_call("what clusters exist").name == "list_clusters"
assert data_intent_call("find projects about voice").name == "search_projects"
assert data_intent_call("how many voice apps").name == "search_projects"
assert data_intent_call("what is the coolest project?").name == "atlas_overview"
assert data_intent_call("which project is most liked").name == "atlas_overview"
assert data_intent_call("hello there") is None
assert data_intent_call("thanks!") is None
def test_data_intent_call_routes_project_reading() -> None:
from hackathon_advisor.dashboard_chat_contracts import data_intent_call
readme = data_intent_call("read the readme of Jawbreaker")
assert readme is not None and readme.name == "show_project"
how = data_intent_call("how does Jawbreaker work?")
assert how is not None and how.name == "show_project"
about = data_intent_call("tell me about Jawbreaker")
assert about is not None and about.name == "show_project"
assert about.arguments["project"] == "tell me about Jawbreaker"
# cluster/quest detail intents keep their own tools
assert data_intent_call("tell me about the Tiny Titan quest").name == "show_quest"
assert data_intent_call("what is in the Dream / Oracle cluster?").name == "show_cluster"
def test_smalltalk_intent_only_matches_greetings_and_followups() -> None:
from hackathon_advisor.dashboard_chat_contracts import smalltalk_intent
assert smalltalk_intent("hello!")
assert smalltalk_intent("hey there")
assert smalltalk_intent("thanks")
assert smalltalk_intent("why")
assert smalltalk_intent("are you sure?")
assert smalltalk_intent("who are you")
assert smalltalk_intent("")
assert not smalltalk_intent("how many voice apps")
assert not smalltalk_intent("what is the coolest project?")
assert not smalltalk_intent("voice agents for elderly care")
assert not smalltalk_intent("knitting helpers")
def test_strip_function_blocks_removes_stray_calls() -> None:
text = 'Here you go. <function name="x"><param name="q">v</param></function> The map shows it.'
assert strip_function_blocks(text) == "Here you go. The map shows it.".strip()
assert strip_function_blocks("plain prose") == "plain prose"
|