SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
5.7 KB · 100 lines python
Raw Blame History
1"""Smoke tests for the Gemini Interactions API + Environments API (API Atlas).23Cheap (always run, < $0.002 on gemini-3.5-flash-lite): create → steps/usage shape, stream event order, previous_interaction_id4chaining, GET, DELETE (+404 after), store=false has no id, list endpoint is 404, function tool via generation_config.tool_choice →5requires_action + function_result follow-up, top-level tool_choice rejected (400), environments create/get/delete.6Expensive (RUN_EXPENSIVE_TESTS=true): Deep Research background create + immediate cancel (bills nothing measurable but touches an agent).7Reference run: 2026-09-18 (tmp-live/gemini-tools/h*.json, env*.json).8"""9from __future__ import annotations1011import json1213import pytest1415MODEL = "gemini-3.5-flash-lite"16FN = [{"type": "function", "name": "get_weather", "description": "Get the weather for a city.",17       "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}]181920def _create(gemini, body, note=""):21    st, r, _ = gemini("POST", "/v1beta/interactions", body, note=f"test_interactions {note}")22    return st, r232425def _delete(gemini, *ids):26    for i in ids:27        if i:28            gemini("DELETE", f"/v1beta/interactions/{i}", note="test_interactions cleanup")293031def test_create_get_delete_lifecycle(gemini):32    st, r = _create(gemini, {"model": MODEL, "input": "Reply with OK.", "generation_config": {"max_output_tokens": 16}}, "create")33    assert st == 200 and r["object"] == "interaction" and r["status"] == "completed"34    assert {"id", "model", "steps", "usage", "created", "updated", "service_tier"} <= set(r)35    types = [s["type"] for s in r["steps"]]36    assert "model_output" in types and r["usage"]["total_tokens"] > 037    st, g, _ = gemini("GET", f"/v1beta/interactions/{r['id']}", note="test_interactions get")38    assert st == 200 and g["id"] == r["id"]39    st, _, _ = gemini("DELETE", f"/v1beta/interactions/{r['id']}", note="test_interactions delete")40    assert st == 20041    st, g2, _ = gemini("GET", f"/v1beta/interactions/{r['id']}", note="test_interactions get after delete")42    assert st == 404434445def test_stream_events_and_chaining(gemini):46    st, r = _create(gemini, {"model": MODEL, "input": "Reply with OK.", "generation_config": {"max_output_tokens": 16}}, "chain base")47    assert st == 20048    st, lines, _ = gemini("POST", "/v1beta/interactions", {"model": MODEL, "input": "Reply with OK.", "stream": True, "previous_interaction_id": r["id"],49                                                          "generation_config": {"max_output_tokens": 16}}, stream=True, note="test_interactions stream")50    assert st == 20051    events = [json.loads(ln[5:]) for ln in lines if ln.startswith("data:") and ln[5:].strip() != "[DONE]"]52    types = [e["event_type"] for e in events]53    assert types[0] == "interaction.created" and types[-1] == "interaction.completed"54    assert {"step.start", "step.delta", "step.stop"} <= set(types)55    last = events[-1]["interaction"]56    assert last["status"] == "completed" and last["id"]57    _delete(gemini, r["id"], last["id"])585960def test_store_false_and_list_404(gemini):61    st, r = _create(gemini, {"model": MODEL, "input": "Reply with OK.", "store": False, "generation_config": {"max_output_tokens": 8}}, "store=false")62    assert st == 200 and "id" not in r and r["status"] == "completed"63    st, _, _ = gemini("GET", "/v1beta/interactions", note="test_interactions list probe")64    assert st == 404656667def test_function_tool_round_trip(gemini):68    st, bad = _create(gemini, {"model": MODEL, "input": "Weather in Paris?", "tools": FN, "tool_choice": {"allowed_tools": {"mode": "any"}}}, "tool_choice top-level")69    assert st == 400 and "tool_choice" in json.dumps(bad)70    st, r = _create(gemini, {"model": MODEL, "input": "Weather in Paris?", "tools": FN,71                             "generation_config": {"tool_choice": {"allowed_tools": {"mode": "any", "tools": ["get_weather"]}}, "max_output_tokens": 64}}, "function tool")72    assert st == 200 and r["status"] == "requires_action"73    fc = next(s for s in r["steps"] if s["type"] == "function_call")74    assert fc["name"] == "get_weather" and fc["id"].startswith("call_") and "city" in fc["arguments"]75    st, r2 = _create(gemini, {"model": MODEL, "previous_interaction_id": r["id"], "tools": FN,76                              "input": [{"type": "function_result", "name": "get_weather", "call_id": fc["id"], "result": [{"type": "text", "text": "{\"temperature_c\": 18}"}]}],77                              "generation_config": {"max_output_tokens": 32}}, "function_result")78    assert st == 200 and r2["status"] == "completed" and any(s["type"] == "model_output" for s in r2["steps"])79    _delete(gemini, r["id"], r2["id"])808182def test_environments_lifecycle(gemini):83    st, r, _ = gemini("POST", "/v1beta/environments", {}, note="test_interactions env create")84    assert st == 200 and r["id"]85    st, g, _ = gemini("GET", f"/v1beta/environments/{r['id']}", note="test_interactions env get")86    assert st == 200 and g["status"] == "active" and "storage" in g87    st, lst, _ = gemini("GET", "/v1beta/environments", note="test_interactions env list")88    assert st == 20089    st, _, _ = gemini("DELETE", f"/v1beta/environments/{r['id']}", note="test_interactions env delete")90    assert st == 200919293@pytest.mark.run_expensive_tests94def test_deep_research_background_cancel(gemini):95    st, r = _create(gemini, {"agent": "deep-research-preview-04-2026", "input": "Reply with OK. Do not research anything.", "background": True}, "deep research")96    assert st == 200 and r["status"] in ("queued", "in_progress") and r["agent"].startswith("deep-research")97    st, c, _ = gemini("POST", f"/v1beta/interactions/{r['id']}/cancel", note="test_interactions cancel")98    assert st == 200 and c["status"] == "cancelled"99    _delete(gemini, r["id"])100