Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions pkg/agentfs/sdk_version_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,17 @@ func normalizeVersion(version string) string {
version = version[1:]
}

// Handle prerelease versions: convert various formats to semver
// 1.3.0rc1 -> 1.3.0-rc1, 1.3rc -> 1.3.0-rc, etc.
// First check if we have a version with dot separator (1.0.0.rc2)
// If so, replace the dot with a hyphen to make it semver compliant
if dotIndex := strings.LastIndex(version, "."); dotIndex > 0 {
// Check if what follows the last dot is a prerelease identifier (starts with a letter)
if dotIndex < len(version)-1 && regexp.MustCompile(`^[a-zA-Z]`).MatchString(version[dotIndex+1:]) {
// Convert 1.0.0.rc2 -> 1.0.0-rc2
version = version[:dotIndex] + "-" + version[dotIndex+1:]
}
}

// Handle prerelease versions without separator: 1.3.0rc1 -> 1.3.0-rc1, 1.3rc -> 1.3.0-rc, etc.
prereleasePattern := regexp.MustCompile(`^(\d+(?:\.\d+)*)([a-zA-Z][a-zA-Z0-9]*.*)$`)
if matches := prereleasePattern.FindStringSubmatch(version); matches != nil {
baseVersion := matches[1]
Expand Down
19 changes: 16 additions & 3 deletions pkg/agentfs/sdk_version_check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,13 @@ func TestIsVersionSatisfied(t *testing.T) {
{"~1.5.0", "1.0.0", true, false},
{">=1.5.0", "1.0.0", true, false},
{"==1.5.0", "1.0.0", true, false},
{"1.3.0rc1", "1.3.0", true, false}, // prerelease should satisfy same base version
{"1.3rc", "1.3.0", true, false}, // short prerelease should satisfy same base version
{"1.3.0rc1", "1.4.0", false, false}, // prerelease should not satisfy higher version
{">=1.3.0rc1", "1.2.0", true, false}, // prerelease should satisfy lower base version
{"1.3.0.rc1", "1.3.0", true, false}, // prerelease should satisfy same base version
{"1.3rc", "1.3.0", true, false}, // short prerelease should satisfy same base version
{"1.3.0rc1", "1.4.0", false, false}, // prerelease should not satisfy higher version
{"1.0.0.rc2", "1.0.0", true, false}, // dot prerelease should satisfy same base version
{"1.3.0.beta1", "1.3.0", true, false}, // dot prerelease should satisfy same base version
{"1.2.0.alpha1", "1.3.0", false, false}, // dot prerelease should not satisfy higher version
{"invalid", "1.0.0", false, true},
{"1.5.0", "invalid", false, true},
}
Expand Down Expand Up @@ -265,6 +269,9 @@ func TestNormalizeVersion(t *testing.T) {
{"1.3rc", "1.3.0-rc"},
{"1.3rc1", "1.3.0-rc1"},
{"~=1.3rc", "1.3.0-rc"},
{"1.0.0.rc2", "1.0.0-rc2"},
{"1.3.0.beta1", "1.3.0-beta1"},
{"1.5.2.alpha3", "1.5.2-alpha3"},
}

for _, tt := range tests {
Expand Down Expand Up @@ -412,6 +419,12 @@ func TestParsePythonPackageVersion(t *testing.T) {
expectedOutput: "==1.5.0",
expectedFound: true,
},
{
name: "extra with compatible version",
input: "livekit-agents[extra1,extra2]~=1.5.0.rc2",
expectedOutput: "~=1.5.0.rc2",
expectedFound: true,
},
{
name: "Version with no specifier",
input: "livekit-agents",
Expand Down
Loading