{
  "file": "F30-openai-gateway.md",
  "bullet": "Responses (`F30.responses-basic`).",
  "ids": [
    "F30.responses-basic"
  ],
  "line": 737,
  "script": "RID=$(control-agent-server api POST /v1/responses --auth bearer --timeout 180 \\\n  --json '{\"model\": \"openhands_deepseek-flash\", \"input\": \"QA_F30_RESP: reply with one short word and use no tools.\", \"instructions\": \"QA_F30_INSTR: answer in plain text.\", \"metadata\": {\"qa\": \"f30\"}, \"store\": false, \"tools\": [{\"type\": \"function\", \"name\": \"qa_f30_client_tool\", \"parameters\": {\"type\": \"object\", \"properties\": {}}}], \"temperature\": 0}' \\\n  --check object eq response --check status eq completed --check id matches '^resp_[0-9a-f]{32}$' --check model eq openhands_deepseek-flash \\\n  --check output len-eq 1 --check output.0.type eq message --check output.0.role eq assistant --check output.0.status eq completed \\\n  --check output.0.id matches '^msg_[0-9a-f]{32}$' --check output.0.content.0.type eq output_text \\\n  --check output.0.content.0.text len-ge 1 --check output.0.content.0.annotations len-eq 0 \\\n  --check instructions eq 'QA_F30_INSTR: answer in plain text.' --check metadata.qa eq f30 --check tools len-eq 0 \\\n  --check tool_choice eq none --check parallel_tool_calls eq false --check previous_response_id missing \\\n  --check usage.input_tokens gt 0 --check usage.output_tokens gt 0 --check usage.input_tokens_details.cached_tokens ge 0 \\\n  --check usage.output_tokens_details.reasoning_tokens ge 0 \\\n  --raw-out \"$F30/response.json\" --save F30.responses-basic/response --print-header X-OpenHands-ServerConversation-ID)\ncontrol-agent-server api GET \"<redacted:session-cookie>/$RID\" --check execution_status eq finished \\\n  --check agent.agent_context.system_message_suffix eq 'QA_F30_INSTR: answer in plain text.' --quiet\ncontrol-agent-server api GET \"<redacted:session-cookie>/$RID/events/search\" --query source=user --check items len-eq 1 \\\n  --check items.0.llm_message.content len-eq 1 \\\n  --check items.0.llm_message.content.0.text eq 'QA_F30_RESP: reply with one short word and use no tools.' --quiet\ncontrol-agent-server api GET \"<redacted:session-cookie>/$RID/agent_final_response\" --raw-out \"$F30/response-final.json\" --quiet\npython3 - \"$F30/response.json\" \"$F30/response-final.json\" <<'PY'\nimport json, sys\nresp, final = (json.load(open(path)) for path in sys.argv[1:])\nassert resp[\"output\"][0][\"content\"][0][\"text\"] == final[\"response\"] != \"\", (resp, final)\nusage = resp[\"usage\"]\nassert usage[\"total_tokens\"] == usage[\"input_tokens\"] + usage[\"output_tokens\"], usage\nassert 0 < resp[\"created_at\"] <= resp[\"completed_at\"], resp\nPY\n",
  "exit_code": 0,
  "elapsed_ms": 4138,
  "failed_line": null,
  "failed_command": null,
  "stdout": "{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"GET\",\n    \"path\": \"<redacted:session-cookie>/bd97ebef-9fd1-41d0-a4f5-e0398f81806f\",\n    \"query\": [],\n    \"auth\": \"header\",\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"6636\",\n      \"content-type\": \"application/json\"\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 87,\n  \"checks\": [\n    {\n      \"check\": \"execution_status eq finished\",\n      \"ok\": true,\n      \"actual\": \"finished\"\n    },\n    {\n      \"check\": \"agent.agent_context.system_message_suffix eq QA_F30_INSTR: answer in plain text.\",\n      \"ok\": true,\n      \"actual\": \"QA_F30_INSTR: answer in plain text.\"\n    }\n  ]\n}\n{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"GET\",\n    \"path\": \"<redacted:session-cookie>/bd97ebef-9fd1-41d0-a4f5-e0398f81806f/events/search\",\n    \"query\": [\n      [\n        \"source\",\n        \"user\"\n      ]\n    ],\n    \"auth\": \"header\",\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"417\",\n      \"content-type\": \"application/json\"\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 115,\n  \"checks\": [\n    {\n      \"check\": \"items len-eq 1\",\n      \"ok\": true,\n      \"actual\": \"[{\\\"id\\\": \\\"ddd55ae7-b221-492f-9f77-80f0dee44d89\\\", \\\"timestamp\\\": \\\"2026-10-13T03:33:13.921120\\\", \\\"source\\\": \\\"user\\\", \\\"parent_id\\\": \\\"8b43638f-3e72-4c21-ba13-f0e7d3829e2c\\\", \\\"llm_message\\\": {\\\"role\\\": \\\"user\\\", \\\"conte\\u2026\"\n    },\n    {\n      \"check\": \"items.0.llm_message.content len-eq 1\",\n      \"ok\": true,\n      \"actual\": \"[{\\\"cache_prompt\\\": false, \\\"type\\\": \\\"text\\\", \\\"text\\\": \\\"QA_F30_RESP: reply with one short word and use no tools.\\\"}]\"\n    },\n    {\n      \"check\": \"items.0.llm_message.content.0.text eq QA_F30_RESP: reply with one short word and use no tools.\",\n      \"ok\": true,\n      \"actual\": \"QA_F30_RESP: reply with one short word and use no tools.\"\n    }\n  ]\n}\n{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"GET\",\n    \"path\": \"<redacted:session-cookie>/bd97ebef-9fd1-41d0-a4f5-e0398f81806f/agent_final_response\",\n    \"query\": [],\n    \"auth\": \"header\",\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"28\",\n      \"content-type\": \"application/json\"\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 130,\n  \"raw_out\": \"/workspace/verification-artifacts/runs/20261013-032720-3de9-map-f30/fixtures/qa-f30/response-final.json\"\n}\n",
  "stderr": ""
}
