Team Ai
Modelpublic

MrMoz33/tokioai-coder-iot

sourceHugging Facemitupdated 5d agoView on Hugging Face
0likes
test_engine.py221 linesDownload Raw Back to engine
1"""2TokioAI Engine -- Test Suite3Tests router, verifier, memory, and full pipeline.4"""5 6import json7import time8import sys9 10from .router import classify_intent, build_system_prompt, IntentType11from .verifier import Verifier, verify_and_extract12from .memory import EngineMemory13from .schemas import validate_tool_call, extract_tool_calls_from_text14from .guided import parse_guided_output15 16 17def run_tests(verbose=False, ollama_host=None, model=None):18    """Run all tests."""19    passed = 020    failed = 021    22    def check(name, condition, detail=""):23        nonlocal passed, failed24        if condition:25            passed += 126            print(f"  \033[32mPASS\033[0m {name}")27        else:28            failed += 129            print(f"  \033[31mFAIL\033[0m {name} {detail}")30 31    # ========================32    print("\n=== ROUTER TESTS ===")33    # ========================34    35    intent, conf = classify_intent("check disk space")36    check("tool: check disk space", intent == IntentType.TOOL_CALL, f"got {intent}")37 38    intent, conf = classify_intent("list docker containers")39    check("tool: docker containers", intent == IntentType.TOOL_CALL, f"got {intent}")40 41    intent, conf = classify_intent("read /etc/hostname")42    check("tool: read file", intent == IntentType.TOOL_CALL, f"got {intent}")43 44    intent, conf = classify_intent("run nmap on 192.168.1.1")45    check("tool: nmap scan", intent == IntentType.TOOL_CALL, f"got {intent}")46 47    intent, conf = classify_intent("what is SQL injection")48    check("text: SQL injection", intent in (IntentType.TEXT, IntentType.CODE), f"got {intent}")49 50    intent, conf = classify_intent("hi")51    check("text: greeting", intent == IntentType.TEXT, f"got {intent}")52 53    intent, conf = classify_intent("thanks")54    check("text: thanks", intent == IntentType.TEXT, f"got {intent}")55 56    intent, conf = classify_intent("explain the TCP handshake")57    check("text: TCP explanation", intent in (IntentType.TEXT, IntentType.CODE), f"got {intent}")58 59    intent, conf = classify_intent("what is docker")60    check("decision: what is docker", intent in (IntentType.DECISION, IntentType.TEXT, IntentType.TOOL_CALL), f"got {intent}")61 62    # ========================63    print("\n=== VERIFIER TESTS ===")64    # ========================65 66    v = Verifier()67 68    # Valid tool call69    r = v.verify('{"name": "execute_local", "arguments": {"command": "df -h"}}')70    check("verify: valid tool call", r.valid and r.output_type == "tool_call")71 72    # Tool call in markdown73    r = v.verify('```json\n{"name": "read_file", "arguments": {"path": "/etc/hostname"}}\n```')74    check("verify: markdown tool call", r.valid and r.output_type == "tool_call")75 76    # Invalid tool name77    r = v.verify('{"name": "invalid_tool", "arguments": {"x": 1}}')78    check("verify: invalid tool name", r.output_type in ("text", "error"))79 80    # Missing required param81    r = v.verify('{"name": "execute_local", "arguments": {}}')82    check("verify: missing required param", not r.valid)83 84    # Pure text85    r = v.verify("Docker is a containerization platform.")86    check("verify: pure text", r.valid and r.output_type == "text")87 88    # Empty89    r = v.verify("")90    check("verify: empty output", not r.valid)91 92    # ========================93    print("\n=== SCHEMA TESTS ===")94    # ========================95 96    ok, err = validate_tool_call("execute_local", {"command": "ls"})97    check("schema: valid execute_local", ok, err)98 99    ok, err = validate_tool_call("execute_local", {})100    check("schema: missing command", not ok)101 102    ok, err = validate_tool_call("read_file", {"path": "/tmp/test"})103    check("schema: valid read_file", ok, err)104 105    ok, err = validate_tool_call("diagnose", {"target": "local"})106    check("schema: valid diagnose", ok, err)107 108    ok, err = validate_tool_call("diagnose", {"target": "invalid"})109    check("schema: invalid enum", not ok)110 111    # Extract tool calls from messy text112    calls = extract_tool_calls_from_text(113        'I will check the disk. {"name": "execute_local", "arguments": {"command": "df -h"}} Done.'114    )115    check("extract: tool in text", len(calls) == 1 and calls[0]["name"] == "execute_local")116 117    # ========================118    print("\n=== GUIDED TESTS ===")119    # ========================120 121    parsed = parse_guided_output('{"name": "execute_local", "arguments": {"command": "ls"}}', "tool_call")122    check("guided: tool call parse", parsed["type"] == "tool_call" and parsed["name"] == "execute_local")123 124    parsed = parse_guided_output('{"action": "text_response", "text_response": "hello"}', "decision")125    check("guided: decision text", parsed["type"] == "text" and parsed["response"] == "hello")126 127    parsed = parse_guided_output(128        '{"action": "tool_call", "tool_call": {"name": "execute_local", "arguments": {"command": "ls"}}}',129        "decision"130    )131    check("guided: decision tool", parsed["type"] == "tool_call" and parsed["name"] == "execute_local")132 133    # ========================134    print("\n=== MEMORY TESTS ===")135    # ========================136 137    import tempfile, os138    tmp = os.path.join(tempfile.mkdtemp(), "test_memory.json")139    mem = EngineMemory(path=tmp)140 141    check("memory: seeded", len(mem.examples) > 0)142 143    mem.add("check cpu usage", '{"name": "execute_local", "arguments": {"command": "top -bn1"}}',144            intent="tool_call", tool_name="execute_local")145    check("memory: add", len(mem.examples) > 0)146 147    results = mem.retrieve("show cpu", intent="tool_call", top_k=3)148    check("memory: retrieve", len(results) > 0, f"got {len(results)}")149 150    stats = mem.get_stats()151    check("memory: stats", stats["total"] > 0)152 153    # Cleanup154    os.unlink(tmp)155 156    # ========================157    print(f"\n=== RESULTS: {passed} passed, {failed} failed ===\n")158 159    # ========================160    # LIVE TESTS (optional -- only if model is available)161    # ========================162    if ollama_host or model:163        from .pipeline import Pipeline, EngineConfig164        config = EngineConfig(165            ollama_host=ollama_host,166            model_name=model or "tokioai-coder",167            verbose=verbose,168        )169        170        print("=== LIVE PIPELINE TESTS ===")171        print(f"Model: {config.model_name} @ {config.ollama_host}\n")172        173        engine = Pipeline(config)174        live_passed = 0175        live_failed = 0176 177        test_cases = [178            ("check disk space", "tool_call", "execute_local"),179            ("read /etc/hostname", "tool_call", "read_file"),180            ("find TODO in python files", "tool_call", "search_files"),181            ("what is SQL injection", "text", None),182            ("hi", "text", None),183            ("list running processes", "tool_call", "execute_local"),184            ("check system health", "tool_call", "diagnose"),185            ("explain what docker is", "text", None),186        ]187 188        for prompt, expected_type, expected_tool in test_cases:189            try:190                result = engine.process(prompt)191                192                type_match = result.output_type == expected_type193                tool_match = True194                if expected_tool and result.tool_calls:195                    tool_match = result.tool_calls[0]["name"] == expected_tool196 197                ok = type_match and tool_match198                detail = ""199                if result.output_type == "tool_call" and result.tool_calls:200                    detail = f"-> {result.tool_calls[0]['name']}({list(result.tool_calls[0]['arguments'].keys())})"201                else:202                    detail = f"-> text({len(result.text)} chars)"203 204                if ok:205                    live_passed += 1206                    print(f"  \033[32mPASS\033[0m [{result.latency_ms:4d}ms] [{result.attempts}att] {prompt:40s} {detail}")207                else:208                    live_failed += 1209                    print(f"  \033[31mFAIL\033[0m [{result.latency_ms:4d}ms] [{result.attempts}att] {prompt:40s} {detail} (expected {expected_type}/{expected_tool})")210            except Exception as e:211                live_failed += 1212                print(f"  \033[31mERROR\033[0m {prompt}: {e}")213            214            engine.reset()215 216        print(f"\n=== LIVE RESULTS: {live_passed} passed, {live_failed} failed ===\n")217        passed += live_passed218        failed += live_failed219 220    return passed, failed221