fix(sdk): use async /v1/graphs/supermodel endpoint with polling#79
fix(sdk): use async /v1/graphs/supermodel endpoint with polling#79greynewell merged 2 commits intomainfrom
Conversation
AnalyzeZip was posting to the legacy /v1/supermodel endpoint which returned a sync JSON response. All other code (internal client, scripts/check-architecture) uses the current /v1/graphs/supermodel endpoint that returns an async job envelope. This change: - Switches to /v1/graphs/supermodel - Adds jobResponse/jobResult types to decode the async envelope - Adds a polling loop that waits RetryAfter seconds between polls (defaulting to 5s) until the job reaches a terminal state - Extracts the Graph from result.graph on completion Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAnalyzeZip was changed from a direct synchronous POST/decode to an asynchronous job flow: it POSTs the ZIP to Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API as Server
participant JobSvc as JobService
Client->>API: POST /v1/graphs/supermodel (zip, idempotency)
API->>Client: 202 { jobId, status: "pending"|"processing", retryAfter }
loop while status != completed
Client->>API: GET /jobs/{jobId}
API->>Client: { status, retryAfter, (error|result) }
alt status is pending/processing
Client->>Client: wait retryAfter (or 5s)
end
end
alt status == completed
API->>Client: { result: { graph, repo } }
Client->>Client: decode graph result
else unexpected status or error
API->>Client: { error }
Client->>Client: return analysis failed / unexpected status
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
pkg/supermodel/client.go (1)
228-245: Quick note on file re-reading during pollsEach time
postZipis called (which happens on every poll iteration), you're:
- Opening the ZIP file
- Reading it into a buffer
- Re-uploading to the server
The server handles this correctly via the idempotency key (it'll just return the existing job status), so this is functionally correct. But for big repos, you're doing a lot of redundant I/O and network transfer.
The internal API client does the same thing, so this is consistent. Just something to be aware of if someone reports slow polling on large repos later - a future optimization could cache the job ID and poll a separate status endpoint (if the API supports it).
Not blocking since it matches internal behavior. 👌
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/supermodel/client.go` around lines 228 - 245, postZip currently re-opens and re-uploads the ZIP on every poll which causes redundant I/O/network for large repos; modify Client.postZip to first check a concurrency-safe cache (e.g., Client-level map or sync.Map protected by a mutex) keyed by idempotencyKey and return the cached *jobResponse if present, and only open/read/upload the file when there is no cached entry; ensure the cache is populated with the jobResponse after a successful upload and that the cache access uses proper synchronization to avoid races.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@pkg/supermodel/client.go`:
- Around line 228-245: postZip currently re-opens and re-uploads the ZIP on
every poll which causes redundant I/O/network for large repos; modify
Client.postZip to first check a concurrency-safe cache (e.g., Client-level map
or sync.Map protected by a mutex) keyed by idempotencyKey and return the cached
*jobResponse if present, and only open/read/upload the file when there is no
cached entry; ensure the cache is populated with the jobResponse after a
successful upload and that the cache access uses proper synchronization to avoid
races.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ab416a5d-2a56-4468-9de2-4191294ba124
📒 Files selected for processing (1)
pkg/supermodel/client.go
The /v1/graphs/supermodel result includes a top-level "repo" field alongside "graph". jobResult now captures it, and AnalyzeZip sets graph.Metadata["repoId"] so Graph.RepoID() works correctly. Without this, Graph.RepoID() always returned "" for SDK callers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
pkg/supermodelAnalyzeZipwas calling the legacy/v1/supermodelendpoint which returned a synchronous JSON responsescripts/check-architecture) uses/v1/graphs/supermodelwhich returns an async job envelopeChanges
/v1/graphs/supermodeljobResponse/jobResulttypes to decode the async envelope (status,jobId,retryAfter,error,result)RetryAfter-based backoff (defaults to 5s) until job reaches terminal stateGraphfromresult.graphon completionTest plan
go build ./...passesgo test ./...passes🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes