feat(server): resume sessions across agent URL query changes#3410
Merged
Conversation
Sessions record the full URL-encoded agent reference as their source key, including query parameters such as gordonTag. When the API server is relaunched with a different tag (e.g. v9-light -> v9-dev), the exact key no longer exists in Sources, so resuming a stored session failed with "agent not found" (HTTP 500), even though the underlying agent is the same. Add a resume-time fallback: resolveSource prefers an exact key match and, on a miss, matches on a stable identity computed by StableSourceKey. For URL references the identity is the path (scheme + host + path); the entire query string and fragment are treated as volatile, so any current or future query parameter is ignored without an enumerated denylist. The fallback only resolves when unambiguous, so side-by-side variants are never silently mis-selected. Viewing/listing old sessions was already unaffected (keyed by session ID in the store); this fixes continuing them.
docker-agent
reviewed
Jul 2, 2026
docker-agent
left a comment
Contributor
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
The session-resumption fallback logic is well-designed and correctly implemented.
What was reviewed:
StableSourceKeyinpkg/config/resolve.go: URL decoding + query/fragment stripping is symmetric — both stored map keys and client-supplied keys areurl.QueryEscape-encoded, so both sides go through the same decode→strip path, producing equal stable keys. Non-URL keys (local files, OCI refs, builtins) fall through unchanged. Error handling on malformed inputs is sound (return key unchanged on any parse failure).resolveSourceinpkg/server/session_manager.go: Exact-match-first logic is correct. The ambiguity guard (matches > 1→ decline) prevents silent mis-selection of side-by-side variants. Thematches == 0path also correctly returns agent-not-found.- Integration into
loadTeam/loadTeamWithConfig: straightforward delegation with unchanged error propagation.
No high or medium severity bugs were found in the changed code.
Sayt-0
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Sessions started via
docker-agent serve api <url>record the full URL-encoded agent reference as their source key, query parameters included.When the server is relaunched with a different tag (e.g. different version of an agent yaml), the exact key recorded by the client no longer exists in
Sources. Resuming a stored session then fails:It works for the first message only because a live runtime is cached in
runtimeSessions(checked beforeSources); after a restart that cache is empty, so the lookup must rebuild fromSourcesand misses.Note: viewing/listing old sessions was never affected — those are keyed by session ID in the store. This PR fixes continuing them.
Fix
Add a resume-time fallback in the session manager.
loadTeam/loadTeamWithConfignow share aresolveSourcehelper that:/api/agents, directory mode) is unchanged.config.StableSourceKey. For URL references the identity is the path (scheme + host + path); the entire query string and fragment are treated as volatile. This is a deliberate rule rather than an enumerated denylist, so any current or future query parameter is ignored without further code changes.agent not found) rather than guessing, so side-by-side variants are never silently mis-selected.task build,task lint(0 issues), and the affected packages' tests all pass.