Skip to content

ci: enable API compliance and condenser test labels - #4204

Open
enyst wants to merge 6 commits into
mainfrom
openhands/enable-special-integration-test-labels
Open

ci: enable API compliance and condenser test labels#4204
enyst wants to merge 6 commits into
mainfrom
openhands/enable-special-integration-test-labels

Conversation

@enyst

@enyst enyst commented Jul 23, 2026

Copy link
Copy Markdown
Member

HUMAN:
Run the test suites for condenser and LLM API format, each on label. They're not run automatically; setting them on label allows us to use the label when suitable.


AGENT:

Why

The api-compliance-test and condenser-test labels still exist, and their test runners still live in the repository, but PR #3974 removed the only workflows that recognized those labels. Applying either label now creates no test job.

This restores the missing routes in the existing integration workflow instead of reviving two duplicated workflow files.

Summary

  • Route condenser-test to the existing c##_* runner and use a two-model default matrix.
  • Route api-compliance-test to an independent job for the a##_* compliance runner.
  • Add manual-dispatch controls so this PR can exercise both suites before merge.

REST API contract changes

Compared with base OpenAPI 2b38718ad34a for public /api/** paths.

--- base public OpenAPI
+++ head public OpenAPI
@@ -2601,0 +2602,2 @@
+schema WebhookSpec property max_batch_bytes optional schema=type="integer" default=5242880 minimum=1.0
+schema WebhookSpec property max_queue_bytes optional schema=type="integer" default=52428800 minimum=1.0

Issue Number

N/A. Follow-up requested in #4203.

How to Test

Static validation:

uv run pre-commit run --files .github/workflows/integration-runner.yml
# Passed after yamlfmt; later verification runs passed without changes.

uv run python -c 'import yaml; yaml.safe_load(open(".github/workflows/integration-runner.yml"))'
# Parsed successfully.

git diff --check
# Passed.

Live runs against the PR branch:

  1. Full two-model run on commit 99cf968d:
    • API compliance runner completed all 24 cases: 12 malformed histories were rejected and 12 were accepted as lenient provider behavior.
    • Claude Sonnet 4.6 passed all 5 condenser tests.
    • GPT-5.5 passed 3 of 4 applicable condenser tests; c01 skipped as expected and c04_token_condenser did not trigger condensation.
    • The test and consolidation jobs passed. The workflow concluded failure only because two report-comment steps lacked PR permission/repository context; commit 9c445c26 fixes both.
  2. Final-code verification run on commit 9c445c26:
    • Entire workflow passed, including both report-comment paths.
    • API compliance again completed all 24 cases with the same 12 rejected / 12 accepted matrix.
    • GPT-5.5 passed all 4 applicable condenser tests; c01 skipped as expected.
    • Generated API compliance report and condenser report were posted to the PR.

Video/Screenshots

N/A — CI workflow change. Live workflow runs and generated reports are linked above.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The existing labels are applied to this PR as requested. Their label-triggered jobs skip against the old main workflow because pull_request_target evaluates the base branch definition. Branch-scoped manual dispatch validates the same runner paths before merge; label-trigger behavior becomes active after merge.

This PR was created by an AI agent (OpenHands) on behalf of the user.


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:0cb037c-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-0cb037c-python \
  ghcr.io/openhands/agent-server:0cb037c-python

All tags pushed for this build

ghcr.io/openhands/agent-server:0cb037c-golang-amd64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-golang-amd64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-golang-amd64
ghcr.io/openhands/agent-server:0cb037c-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:0cb037c-golang-arm64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-golang-arm64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-golang-arm64
ghcr.io/openhands/agent-server:0cb037c-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:0cb037c-java-amd64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-java-amd64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-java-amd64
ghcr.io/openhands/agent-server:0cb037c-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:0cb037c-java-arm64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-java-arm64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-java-arm64
ghcr.io/openhands/agent-server:0cb037c-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:0cb037c-python-amd64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-python-amd64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-python-amd64
ghcr.io/openhands/agent-server:0cb037c-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:0cb037c-python-arm64
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-python-arm64
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-python-arm64
ghcr.io/openhands/agent-server:0cb037c-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:0cb037c-golang
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-golang
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-golang
ghcr.io/openhands/agent-server:0cb037c-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:0cb037c-java
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-java
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-java
ghcr.io/openhands/agent-server:0cb037c-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:0cb037c-python
ghcr.io/openhands/agent-server:0cb037cadd2f4014374042de598100c35e6cffbc-python
ghcr.io/openhands/agent-server:openhands-enable-special-integration-test-labels-python
ghcr.io/openhands/agent-server:0cb037c-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., 0cb037c-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 0cb037c-python-amd64) are also available if needed

Co-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst added api-compliance-test Triggers an API compliance test on the labeled PR condenser-test Triggers a run of all condenser integration tests labels Jul 23, 2026 — with OpenHands AI
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Integration Tests Results

Overall Success Rate: 88.9%
Total Cost: $1.14
Models Tested: 2
Timestamp: 2026-07-23 13:17:54 UTC

📁 Detailed Logs & Artifacts

Click the links below to access detailed agent/LLM logs showing the complete reasoning process for each model. On the GitHub Actions page, scroll down to the 'Artifacts' section to download the logs.

📊 Summary

Model Overall Tests Passed Skipped Total Cost Tokens
litellm_proxy_anthropic_claude_sonnet_4_6 100.0% 5/5 0 5 $0.81 402,304
litellm_proxy_openai_gpt_5.5 75.0% 3/4 1 5 $0.34 90,732

📋 Detailed Results

litellm_proxy_anthropic_claude_sonnet_4_6

  • Success Rate: 100.0% (5/5)
  • Total Cost: $0.81
  • Token Usage: prompt: 373,941, completion: 28,363, cache_read: 295,853, cache_write: 77,648, reasoning: 4,950
  • Run Suffix: litellm_proxy_anthropic_claude_sonnet_4_6_99cf968_claude_sonnet_4_6_run_N5_20260723_131222

litellm_proxy_openai_gpt_5.5

  • Success Rate: 75.0% (3/4)
  • Total Cost: $0.34
  • Token Usage: prompt: 87,824, completion: 2,908, cache_read: 42,496, reasoning: 912
  • Run Suffix: litellm_proxy_openai_gpt_5.5_99cf968_gpt_5_5_run_N5_20260723_131216
  • Skipped Tests: 1

Skipped Tests:

  • c01_thinking_block_condenser: Model litellm_proxy/openai/gpt-5.5 does not support extended thinking (produces reasoning items instead of thinking blocks)

Failed Tests:

  • c04_token_condenser: Condensation not triggered. Token counting may not work. (Cost: $0.05)

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions

Copy link
Copy Markdown
Contributor

Integration Tests Triggered

Results will be posted here when complete.

@github-actions

Copy link
Copy Markdown
Contributor

API Compliance Test Report

Run: compliance_20260723_133118 | Time: 2026-07-23T13:32:03.937228 | Duration: 45.3s

Results Matrix

✅ accepted ❌ rejected ⚠️ error

Pattern claude gpt gemini
unmatched_tool_use
tool_use without following tool_result
unmatched_tool_result
tool_result referencing non-existent tool_use ID
interleaved_user_message
User message between tool_use and tool_result
interleaved_assistant_message
Assistant message between tool_use/tool_result
duplicate_tool_call_id
Same tool_call ID used in multiple tool_use blocks
wrong_tool_call_id
tool_result with mismatched tool_call_id
parallel_missing_result
Parallel tool calls with one result missing
parallel_wrong_order
Parallel tool call results in wrong order

Summary

  • Total tests: 24
  • Rejected (expected for malformed input): 12
  • Accepted (lenient API behavior): 12

Full API responses available in workflow artifacts

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Integration Tests Results

Overall Success Rate: 100.0%
Total Cost: $0.27
Models Tested: 1
Timestamp: 2026-07-23 13:34:21 UTC

📊 Summary

Model Overall Tests Passed Skipped Total Cost Tokens
litellm_proxy_openai_gpt_5.5 100.0% 4/4 1 5 $0.27 96,289

📋 Detailed Results

litellm_proxy_openai_gpt_5.5

  • Success Rate: 100.0% (4/4)
  • Total Cost: $0.27
  • Token Usage: prompt: 92,451, completion: 3,838, cache_read: 69,120, reasoning: 1,746
  • Run Suffix: litellm_proxy_openai_gpt_5.5_9c445c2_gpt_5_5_run_N5_20260723_133306
  • Skipped Tests: 1

Skipped Tests:

  • c01_thinking_block_condenser: Model litellm_proxy/openai/gpt-5.5 does not support extended thinking (produces reasoning items instead of thinking blocks)

enyst added 2 commits August 3, 2026 17:34
…ecial-integration-test-labels

# Conflicts:
#	.github/workflows/integration-runner.yml
@enyst
enyst marked this pull request as ready for review August 3, 2026 15:49
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 90ace0212a703170548fb10e236092625283ec0a
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/f60eb9d8-ca0a-4136-a8c8-f52cccfea09c

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Overview

This PR restores label-triggered CI routing for condenser-test and api-compliance-test inside the existing integration-runner.yml, after the dedicated workflow files were removed in #3974. Routing the labels into the shared workflow (rather than reviving duplicate files) is the simpler, more maintainable approach and keeps a single place for the trigger/comment/consolidation logic.

The change is well-scoped: condenser tests reuse the existing matrix-driven run-integration-tests/consolidate-results path with a narrower default model set, and API compliance gets a standalone job since its a##_* runner is not part of run_infer.py's [tbc]*.py glob. The post-dispatch-comment fixes (adding pull-requests: write and --repo "$GITHUB_REPOSITORY") are correct.

Correctness

  • condenser-test -> run_infer.py --test-type condenser: the c##_* files are classified as condenser in tests/integration/run_infer.py, and the label branches in setup-matrix, run-integration-tests, and consolidate-results are all consistent. Default model set (gpt-5.5,claude-sonnet-4-6) is reasonable.
  • api-compliance-test -> standalone run-api-compliance-tests job invoking tests/integration/api_compliance/run_compliance.py --output-dir compliance-results. Confirmed the script accepts --output-dir and writes compliance_report.md. Correctly excluded from setup-matrix (no matrix), run-integration-tests, and consolidate-results (produces no test-results-* artifacts).
  • The run_api_compliance dispatch input is a boolean (not a test_type value), and the job condition gates on inputs.run_api_compliance -- so dispatching test_type=all no longer implicitly runs compliance. This is a deliberate separation and is fine.
  • Report-posting if correctly fires for both pull_request_target and workflow_dispatch with a non-empty issue_number.

Security

  • The compliance job follows the same pull_request_target pattern as run-integration-tests: label-gated by maintainers, persist-credentials: false, checks out the fork PR head, and only exposes LLM_API_KEY_EVAL + github.token. No new credential surface is introduced. The compliance job correctly scopes permissions to contents: read, issues: write, pull-requests: write (no id-token: write, which the integration job needs for OIDC but compliance does not). Consistent and low risk.

Minor / non-blocking notes

  • The compliance report comment is posted via gh issue comment ... --body-file "$REPORT" directly on the raw report, whereas the condenser/integration path pipes the report through sanitize_openhands_mentions first. Since the compliance report is generated from raw LLM API responses to malformed-history patterns (not arbitrary PR content), the risk of @OpenHands self-mention loops is negligible -- but for consistency you may want to apply the same sanitization helper.
  • The compliance comment uses gh issue comment while consolidate-results's label path uses gh pr comment. Both work against PR numbers; just an inconsistency to be aware of.

These are not blockers.

Risk assessment

Low risk. This is a CI-only change restoring existing label behavior in a single workflow file. Live runs on the PR branch (linked in the description) exercised both suites end-to-end, including report comments. No code paths that ship to users are affected.

No material issues found; the change is safe to merge.

…er labels

Temporary reviewer evidence (.pr/, local-excluded, force-added):
- api-compliance-test: live run against the eval proxy rejected a malformed
  tool_use history (HTTP 400 -> LLMMalformedConversationHistoryError), 3.2s.
- condenser-test: --test-type condenser correctly selects the c01..c05 suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📁 PR Artifacts Notice

This PR contains a .pr/ directory with temporary PR-specific documents. The directory will be automatically removed when the PR is approved.

@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 71df585b4f3e6b721dcc7b750f3d6b2554824b81
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/653c18f1-dafd-4c5a-9a1b-dcd8232725e1

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Overview

This PR restores label-triggered CI routing for condenser-test and api-compliance-test inside the existing integration-runner.yml, after PR #3974 removed the dedicated workflow files that previously recognized those labels. Routing the labels into the shared workflow (instead of reviving two duplicated files) is the simpler, more maintainable approach and keeps a single source of truth for trigger/comment/consolidation logic.

The change is well-scoped and the routing is consistent across all gating points:

  • condenser-test -> the existing matrix-driven run-integration-tests/consolidate-results path with --test-type condenser and a narrower two-model default (gpt-5.5,claude-sonnet-4-6).
  • api-compliance-test -> a standalone run-api-compliance-tests job invoking tests/integration/api_compliance/run_compliance.py --output-dir compliance-results, correctly excluded from setup-matrix/run-integration-tests/consolidate-results since it produces no test-results-* artifacts.

Correctness

  • c##_* files are classified as condenser in tests/integration/run_infer.py (test_type = "condenser" for c-prefixed files), and --test-type condenser is a valid argparse choice. The label branch added in setup-matrix, run-integration-tests, and consolidate-results are all consistent.
  • The compliance runner reads LLM_API_KEY/LLM_BASE_URL from env (tests/integration/api_compliance/base.py), which the job sets to LLM_API_KEY_EVAL and the eval proxy -- correct.
  • run_api_compliance is a separate boolean dispatch input, so test_type=all no longer implicitly runs compliance. This is a deliberate, sensible separation.
  • The report-posting if correctly fires for both pull_request_target and workflow_dispatch with a non-empty issue_number; the find ... -print -quit + if [ -n "$REPORT" ] guard means a failed run with no report file silently skips posting rather than erroring.
  • Patch 2 fixes (pull-requests: write permission + --repo "$GITHUB_REPOSITORY") are correct -- GITHUB_REPOSITORY is a default Actions env var, so no explicit env: declaration is needed.

Security

The compliance job follows the same pull_request_target pattern already established by run-integration-tests: maintainer-gated by label, persist-credentials: false, checks out the head PR ref, and only exposes LLM_API_KEY_EVAL + github.token. Permissions are scoped to contents: read, issues: write, pull-requests: write -- correctly omitting id-token: write, which the integration job needs for OIDC but compliance does not. No new credential surface is introduced; the checkout-head-under-pull_request_target consideration is pre-existing and accepted for this maintainer-gated workflow, not a regression from this PR.

Minor / non-blocking notes

  • The compliance report is posted raw via gh issue comment --body-file "$REPORT", whereas the condenser/integration path pipes the report through sanitize_openhands_mentions first. The compliance report is generated from LLM API error messages and pattern descriptions rather than arbitrary PR content, so the @OpenHands self-mention risk is low -- but for consistency you may want to apply the same sanitization helper (inline comment below).
  • The compliance comment uses gh issue comment while consolidate-results's label path uses gh pr comment. Both post to the same issue-comment endpoint and work against PR numbers, so this is functionally fine -- just an inconsistency to be aware of.
  • The .pr/ evidence files are auto-removed on approval for same-repo PRs (this PR is not cross-repository), so no manual cleanup is needed before merge.

These are not blockers.

Risk assessment

Low risk. This is a CI-only change restoring existing label behavior in a single workflow file. No user-shipping code paths are affected. Live runs linked in the PR description exercised both suites end-to-end against the eval proxy, including report comments on both label and dispatch paths.

No material issues found; the change is safe to merge.

Comment thread .github/workflows/integration-runner.yml Outdated
Co-authored-by: openhands <openhands@all-hands.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-compliance-test Triggers an API compliance test on the labeled PR condenser-test Triggers a run of all condenser integration tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants