Skip to content

Memory v2 PR-2: HTTP plugin client + circuit breaker + capability negotiation - #2731

Merged
HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/memory-v2-pr2-client
May 4, 2026
Merged

HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/memory-v2-pr2-client

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Builds on merged PR-1 (#2729).

Tracking issue: #2728
Task: #276

Summary

  • HTTP client implementing every endpoint in the OpenAPI v1 contract
  • /v1/health probe + capability negotiation; MCP handlers (PR-5) gate features on SupportsCapability
  • Circuit breaker: 3 consecutive 5xx/transport-error failures → ErrBreakerOpen for 60s
  • Validation runs at the boundary (every method calls body.Validate() before the wire)

Why these breaker constants

  • 3 failures to open: long enough to skip transient blips, short enough to react before all in-flight handlers stack on the 2s timeout
  • 60s cooldown: long enough to back off a flapping plugin, short enough that recovery is felt within a single user session
  • 4xx does NOT trip: those are client bugs, not plugin-health issues; resets failure count instead

Coverage

100.0% of statements in client.go.

Edge cases tested

  • Boot success + capability list registered
  • Boot when plugin unreachable (Capabilities() stays nil)
  • Refresh updates capabilities mid-session
  • All 6 public endpoints reject invalid inputs server-side BEFORE making the HTTP call
  • Standard error envelope decoding (404, 403, 500)
  • Non-standard error body (5xx with plain-text body) wrapped into typed *contract.Error
  • Empty error body with arbitrary status (418) → stub error with "empty body" marker
  • 204 NoContent on endpoint expecting a body → zero-value response, no decode error
  • Garbage JSON in 200 response → wrapped decode error
  • Context cancellation propagates to transport
  • Marshal error path (channel in Propagation field)
  • NewRequest error path (unbalanced bracket in BaseURL)
  • 4xx never opens the breaker
  • 5xx opens the breaker after 3 consecutive
  • Cooldown elapsed → next call goes through
  • Success after cooldown resets failure count
  • Successful interleave resets failure count even before threshold
  • Open breaker blocks all 6 endpoints with ErrBreakerOpen

Test plan

  • go test ./internal/memory/client/ -cover reports 100.0%
  • Real HTTP round-trip via httptest covers wire layer wiring
  • Synthetic transport tests cover fast paths

🤖 Generated with Claude Code

Builds on PR-1 (#2729). Implements every endpoint in the OpenAPI spec
plus two operational concerns the agent never sees:

  1. Capability negotiation. Boot/Refresh probes /v1/health and
     captures the plugin's capability list. MCP handlers (PR-5) ask
     SupportsCapability before exposing capability-gated features —
     e.g., agents can only request semantic search when "embedding"
     is reported.

  2. Circuit breaker. Three consecutive failures open the breaker for
     60 seconds; while open, calls fail fast with ErrBreakerOpen.
     Picked these constants because:
       - 3 failures: long enough to skip transient blips, short enough
         to react before all in-flight handlers stack on the timeout
       - 60s cooldown: long enough to back off a flapping plugin,
         short enough that recovery is felt within a single session
     4xx responses do NOT count toward the breaker (those are client
     bugs, not plugin health issues); 5xx + transport errors do.

What ships:
  - workspace-server/internal/memory/client/client.go
  - client_test.go: 100% statement coverage

Coverage corner cases pinned:
  - env-var success branches in New (parseDurationEnv applied)
  - json.Marshal error (via channel in Propagation)
  - http.NewRequestWithContext error (via unbalanced bracket in BaseURL)
  - 204 NoContent on endpoint that normally has a body
  - 4xx vs 5xx breaker behavior (4xx must NOT trip)
  - breaker cooldown elapsed → reset on next success
  - all 6 public endpoints fail-fast when breaker is open

This package has no callers in this PR; integration starts in PR-5.
@HongmingWang-Rabbit
HongmingWang-Rabbit added this pull request to the merge queue May 4, 2026
Merged via the queue into staging with commit d9fb570 May 4, 2026
22 checks passed
@HongmingWang-Rabbit
HongmingWang-Rabbit deleted the feat/memory-v2-pr2-client branch May 4, 2026 14:05
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