mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #375] [MERGED] refactor(gateway): route from one table and share sandbox list cursor vectors #387
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#387
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/375
Author: @yingdi-shan
Created: 10/12/2026
Status: ✅ Merged
Merged: 10/13/2026
Merged by: @yingdi-shan
Base:
main← Head:refactor/gateway-route-table📝 Commits (2)
ba27af9refactor(gateway): route sandbox and build paths from one tableb7723e5fix(gateway): match node API sandbox list cursors via shared vectors📊 Changes
10 files changed (+645 additions, -194 deletions)
View changed files
📝
.github/workflows/services-ci.yml(+4 -0)📝
services/gateway/internal/cluster_list.go(+14 -14)📝
services/gateway/internal/cluster_list_test.go(+105 -3)➕
services/gateway/internal/routes.go(+111 -0)➕
services/gateway/internal/routes_test.go(+108 -0)📝
services/gateway/internal/server.go(+21 -112)📝
services/gateway/internal/server_test.go(+3 -64)📝
services/go.mod(+1 -1)📝
src/api/impls/pagination.rs(+108 -0)➕
src/api/testdata/pagination.json(+170 -0)📄 Description
What
Two commits, both in the gateway:
refactor(gateway): route sandbox and build paths from one table. The gateway's hand-written path parsers (isSandboxControlPlaneRequest,sandboxIDFromPath,templateBuildIDFromPath,v2TemplateBuildIDFromPath,isTemplateBuilderAllocation,isForkPath) become one table,pathRoutesinservices/gateway/internal/routes.go. Each entry names a method, a path pattern, and how the owning node is picked. A new test readssrc/api/openapi.ymland fails if an operation addressed by{sandboxID}or{buildID}is missing from the table, or if a table entry matches no operation.fix(gateway): match node API sandbox list cursors via shared vectors.src/api/testdata/pagination.jsonholds cursor tokens to accept, reject and encode, plus pages to cut from a fixed set of sandboxes. The Rust cursor tests (src/api/impls/pagination.rs) and the gateway's cluster-list tests both read it. The gateway is fixed to match the node API.Why
These came out of a review of why recent feature PRs touch 20–40 files.
cluster_list.go), and nothing kept the two in step. #209 and #263 both had to change both sides. The new vectors show they had already drifted, as listed below.Related issue
N/A. Follow-up to the review behind #367.
Scope and non-goals
x-extension inopenapi.yml; that is a possible follow-up.ownerNewBuildConfirmedalready covers allocations whose ID comes back inx-agentenv-build-id).Design and behavior changes
Route owner kinds, which replace the separate parsers:
ownerSandbox{id}ownerSandboxFork{id}ownerBuild{id}ownerBuildRead{id}; a build with no binding falls back to schedulingownerNewBuild{id}ownerNewBuildConfirmedx-agentenv-build-id, which must equal{id}Gateway behavior changes from the shared vectors:
x-next-tokenwhenever a page was exactlylimitlong. Clients then fetched an empty final page. Nodes issue a token only when more items remain, and the gateway now does the same.RFC3339Nanotimestamps, which drop trailing zeros. Nodes always write nine fraction digits. The gateway now writes the same format. Tokens in the old format are still accepted.Compatibility and operations
x-next-tokenon a final page that is exactlylimitlong.gopkg.in/yaml.v3moves from indirect to direct inservices/go.mod(test only; already ingo.sum). Services CI now also runs whensrc/api/openapi.ymlorsrc/api/testdata/pagination.jsonchanges, since the gateway tests read both.Validation
make fmtmake clippymake test-unitmake -C services test(required whenservices/changes)maketargetCommands and results:
Checks that the new tests catch drift:
/v2/sandboxes/{id}/logsentry failsTestPathRoutesCoverOpenAPIwithGET /v2/sandboxes/{sandboxID}/logs: path routed = false, want true; update pathRoutes.cluster_list.gofails four cases: the timestamp format, and the token on an exact-limit last page.Skipped checks and reasons:
make test-unitcapability tests (--ignored) and integration suites: no capability-dependent or runtime code changed. The Rust change is one test.redis-serveris not installed on this host. The scheduler packages still passgo test.Risks and reviewer notes
routes.gois the file to review. Order matters: the first match wins, soPUT .../builder(allocation) andGET .../status|logs(read) come before the any-method build entries.TestPathRoutesCoverOpenAPIreads the spec by relative path, so the gateway tests must run from a repository checkout, as CI does.Checklist
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.