Skip to content

Commit 8c600d3

Browse files
authored
Merge pull request #2473 from gtardif/agent_name_url_source
Encode agent source URL when using it as agent name and key, so that it can be used properly in conversations when using `serve api`
2 parents a2e9461 + 71f508a commit 8c600d3

3 files changed

Lines changed: 37 additions & 11 deletions

File tree

pkg/config/resolve.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"log/slog"
88
"maps"
9+
"net/url"
910
"os"
1011
"path/filepath"
1112
"slices"
@@ -104,7 +105,8 @@ func resolveOne(resolvedPath string, envProvider environment.Provider) (string,
104105
case builtinAgents[resolvedPath] != nil:
105106
return resolvedPath, NewBytesSource(resolvedPath, builtinAgents[resolvedPath])
106107
case IsURLReference(resolvedPath):
107-
return resolvedPath, NewURLSource(resolvedPath, envProvider)
108+
// URL-encode the URL to make it safe for use as a map key
109+
return url.QueryEscape(resolvedPath), NewURLSource(resolvedPath, envProvider)
108110
case isLocalFile(resolvedPath):
109111
return fileNameWithoutExt(resolvedPath), NewFileSource(resolvedPath)
110112
default:

pkg/config/resolve_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package config
22

33
import (
4+
"net/url"
45
"os"
56
"path/filepath"
67
"testing"
@@ -768,3 +769,21 @@ func TestParseExternalAgentRef(t *testing.T) {
768769
})
769770
}
770771
}
772+
773+
func TestResolveSources_URLEncodedKey(t *testing.T) {
774+
t.Parallel()
775+
776+
testURL := "https://example.com/agent.yaml?agentTag=v1.0.0-dev&origin=cli"
777+
778+
sources, err := ResolveSources(testURL, nil)
779+
require.NoError(t, err)
780+
require.Len(t, sources, 1)
781+
782+
// The key should be the URL-encoded version of the URL
783+
expectedKey := url.QueryEscape(testURL)
784+
source, ok := sources[expectedKey]
785+
require.True(t, ok, "expected source key '%s'", expectedKey)
786+
787+
// The source Name() should still return the original URL for fetching
788+
assert.Equal(t, testURL, source.Name())
789+
}

pkg/config/sources_test.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"net/http"
55
"net/http/httptest"
6+
"net/url"
67
"os"
78
"path/filepath"
89
"sync/atomic"
@@ -200,10 +201,10 @@ func TestURLSource_Read_FallsBackToCacheOnNetworkError(t *testing.T) {
200201
// Not parallel - uses shared cache directory
201202

202203
// Pre-populate cache for a non-existent server
203-
url := "http://invalid.invalid:12345/config-network-error.yaml"
204+
agentURL := "http://invalid.invalid:12345/config-network-error.yaml"
204205
urlCacheDir := getURLCacheDir()
205206
require.NoError(t, os.MkdirAll(urlCacheDir, 0o755))
206-
urlHash := hashURL(url)
207+
urlHash := hashURL(agentURL)
207208
cachePath := filepath.Join(urlCacheDir, urlHash)
208209
require.NoError(t, os.WriteFile(cachePath, []byte("cached content network error"), 0o644))
209210

@@ -212,7 +213,7 @@ func TestURLSource_Read_FallsBackToCacheOnNetworkError(t *testing.T) {
212213
_ = os.Remove(cachePath)
213214
})
214215

215-
source := NewURLSource(url, nil)
216+
source := NewURLSource(agentURL, nil)
216217

217218
// Read should fall back to cached content
218219
data, err := source.Read(t.Context())
@@ -336,14 +337,16 @@ func TestResolve_URLReference(t *testing.T) {
336337
func TestResolveSources_URLReference(t *testing.T) {
337338
t.Parallel()
338339

339-
url := "https://example.com/agent.yaml"
340-
sources, err := ResolveSources(url, nil)
340+
testURL := "https://example.com/agent.yaml"
341+
sources, err := ResolveSources(testURL, nil)
341342
require.NoError(t, err)
342343
require.Len(t, sources, 1)
343344

344-
source, ok := sources[url]
345+
// The key should be the URL-encoded version
346+
expectedKey := url.QueryEscape(testURL)
347+
source, ok := sources[expectedKey]
345348
require.True(t, ok)
346-
assert.Equal(t, url, source.Name())
349+
assert.Equal(t, testURL, source.Name())
347350
}
348351

349352
func TestURLSource_Read_WithGitHubAuth(t *testing.T) {
@@ -500,12 +503,14 @@ func TestResolveSources_URLReference_WithEnvProvider(t *testing.T) {
500503
"GITHUB_TOKEN": "test-token",
501504
})
502505

503-
url := "https://github.com/owner/repo/raw/main/agent.yaml"
504-
sources, err := ResolveSources(url, envProvider)
506+
testURL := "https://github.com/owner/repo/raw/main/agent.yaml"
507+
sources, err := ResolveSources(testURL, envProvider)
505508
require.NoError(t, err)
506509
require.Len(t, sources, 1)
507510

508-
source, ok := sources[url]
511+
// The key should be the URL-encoded version
512+
expectedKey := url.QueryEscape(testURL)
513+
source, ok := sources[expectedKey]
509514
require.True(t, ok)
510515

511516
// Verify the source has the env provider set

0 commit comments

Comments
 (0)