Skip to content

feat(sdk/go): Agent.Pause webhook approvals, harness cost reporting, incremental schema mode#744

Merged
AbirAbbas merged 2 commits into
mainfrom
feat/go-sdk-parity
Jul 9, 2026
Merged

feat(sdk/go): Agent.Pause webhook approvals, harness cost reporting, incremental schema mode#744
AbirAbbas merged 2 commits into
mainfrom
feat/go-sdk-parity

Conversation

@AbirAbbas

Copy link
Copy Markdown
Contributor

Summary

Closes three Go SDK parity gaps with the Python SDK, found while porting SWE-AF to Go:

  1. Agent.Pause() with webhook-resumed approvalsPauseManager + /webhooks/approval route (same path and payload contract as the Python agent_server route; verified against the control plane's notifyApprovalCallback). Registers the pending approval before RequestApproval transitions the execution to waiting, then blocks until webhook resolution, expiry, or ctx cancellation. The route is exempted from origin/DID middleware like other CP→worker notifications. PauseClock is intentionally not ported: the Go SDK has no execution watchdog whose budget it would discount.
  2. Harness cost_usdMetrics.CostUSD/Result.CostUSD (*float64, nil = unknown) extracted from Claude's JSON output with Python's cost_usd or total_cost_usd semantics, accumulated across retries including failed attempts. Non-Claude providers report nil (matching Python when litellm is unavailable; their CLIs emit no structured cost).
  3. Harness SchemaMode (single/incremental/auto) — ports the Python incremental structured-output recovery: auto engages when the compact-encoded schema crosses the large-schema token threshold; incremental prompt suffix, per-field failure diagnosis, and followup prompts are byte-verbatim from _schema.py.

Test plan

  • go mod tidy no diff; go build ./..., go vet ./... clean
  • go test ./... — all packages green; pause tests race-clean (-race); pause.go coverage 91.4% (above the repo coverage gates)
  • Webhook contract asserted with httptest against the agent mux: decision mapping (approved/rejected/request_changes/expired), execution-id fallback, concurrent pause independence, middleware bypass
  • Cost accumulation and schema-mode engagement covered by table-driven parity tests with fixtures mirroring the Python behaviors

Consumer: the SWE-AF Go port (Agent-Field/SWE-AF#94) swaps its poll-based HITL workaround to Agent.Pause() on top of this.


🤖 Generated with Claude Code

AbirAbbas and others added 2 commits July 9, 2026 16:55
Parity with the Python SDK's Agent.pause(): PauseManager registers a
pending approval before client.RequestApproval transitions the
execution to waiting, then blocks until the control plane's
/webhooks/approval callback resolves it (or expiry/cancellation).
Route matches the Python agent_server path and the CP's
notifyApprovalCallback payload; exempted from origin/DID middleware
like other CP-to-worker notifications. PauseClock intentionally not
ported: the Go SDK has no execution watchdog to discount.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Metrics/Result gain CostUSD (*float64, nil = unknown) extracted from
Claude's JSON output with Python's cost_usd-or-total_cost_usd
semantics and accumulated across retries including failed attempts.
Options gains SchemaMode (single/incremental/auto): auto engages on
the compact-encoded schema crossing the large-schema token threshold,
with the incremental prompt suffix, per-field failure diagnosis, and
followup prompts ported byte-verbatim from the Python SDK. Non-Claude
providers report nil cost (Python parity when litellm is unavailable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Go 213 B -24% 0.59 µs -41%

✓ No regressions detected

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 86.90% 87.40% ↓ -0.50 pp 🟡
sdk-go 91.90% 92.00% ↓ -0.10 pp 🟢
sdk-python 93.76% 93.73% ↑ +0.03 pp 🟢
sdk-typescript 90.42% 90.42% → +0.00 pp 🟢
web-ui 84.75% 84.79% ↓ -0.04 pp 🟡
aggregate 85.54% 85.75% ↓ -0.21 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 450 90.00%
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

@AbirAbbas AbirAbbas marked this pull request as ready for review July 9, 2026 21:25
@AbirAbbas AbirAbbas requested a review from a team as a code owner July 9, 2026 21:25
@AbirAbbas AbirAbbas merged commit cbe40d4 into main Jul 9, 2026
27 checks passed
@AbirAbbas AbirAbbas deleted the feat/go-sdk-parity branch July 9, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant