Compare commits

...
4 Commits
Author SHA1 Message Date
lukaszraczylo 12e448ca39 fix(deps): require Go 1.26.8
Go 1.26.0 carries 17 standard library vulnerabilities that govulncheck reports. The security workflow takes its toolchain from go.mod, so the scan failed. Go 1.26.8 clears them.
2026-10-02 16:18:05 +01:00
lukaszraczylo 0865c405fb feat(pi): emit model context and output limits when set
The pi adapter writes contextWindow and maxTokens to models.json only
when the profile sets them. Pi keeps its own defaults for every other
model. Tests cover both cases.
2026-10-02 05:11:46 +01:00
lukaszraczylo b6bd5303e0 ci(security): resolve latest Go patch in govulncheck job
The govulncheck job fails on 17 standard library findings. The runner
uses an outdated Go toolchain. Set check-latest so setup-go installs
the newest patch release.
2026-10-02 05:10:31 +01:00
lukaszraczyloandGitHub f81492eb46 Update go.mod and go.sum (#28) 2026-09-19 04:18:26 +01:00
5 changed files with 51 additions and 4 deletions
+1
View File
@@ -31,6 +31,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
cache: true
- name: Install govulncheck
+2 -2
View File
@@ -1,6 +1,6 @@
module github.com/lukaszraczylo/harness-sync
go 1.26.0
go 1.26.8
require (
github.com/charmbracelet/huh v1.0.0
@@ -27,7 +27,7 @@ require (
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dustin/go-humanize v1.1.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.4.1 // indirect
+2 -2
View File
@@ -45,8 +45,8 @@ github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dustin/go-humanize v1.1.0 h1:dbKTrvD0klcbBV/h4AWJdMuZogJACoMlvWIWZ5b2xWg=
github.com/dustin/go-humanize v1.1.0/go.mod h1:hc1CvRkJMsgxqjmjMQF3QNRAZBwY8AXBAzKYoSX9sFI=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+11
View File
@@ -116,6 +116,17 @@ func piModelsJSON(b *canonical.Bundle) ([]byte, error) {
if m.Alias != "" {
entry["name"] = m.Alias
}
// Emit limits only when the profile sets them explicitly. Pi applies
// its own defaults (contextWindow 128000, maxTokens 16384) to a model
// definition that omits them, so writing ContextLimit()/OutputLimit()
// unconditionally would push canonical's defaults onto every model
// that never asked for them.
if m.Context > 0 {
entry["contextWindow"] = m.Context
}
if m.Output > 0 {
entry["maxTokens"] = m.Output
}
modelEntries = append(modelEntries, entry)
}
if len(modelEntries) == 0 && b.Profile.Gateway.DefaultModel != "" {
+35
View File
@@ -56,6 +56,41 @@ func TestPiRender(t *testing.T) {
first := modelList[0].(map[string]any)
assert.Equal(t, "claude-sonnet-4-6", first["id"])
assert.Equal(t, "Sonnet", first["name"])
// A model with no explicit limits must carry none, so pi keeps applying
// its own defaults rather than inheriting canonical's.
assert.NotContains(t, first, "contextWindow")
assert.NotContains(t, first, "maxTokens")
}
func TestPiRenderEmitsExplicitModelLimits(t *testing.T) {
home := t.TempDir()
ad := New(WithHome(home))
b := &canonical.Bundle{
Profile: canonical.Profile{
Gateway: canonical.Gateway{URL: "https://gw", Token: "dummy"},
Models: []canonical.Model{
{ID: "local/current-model", Alias: "Local", Context: 1048576, Output: 32768},
{ID: "bare/model"},
},
},
}
fs, err := ad.Render(b)
require.NoError(t, err)
seen := map[string]adapter.File{}
fs.ForEach(func(f adapter.File) { seen[f.Dest] = f })
var models map[string]any
require.NoError(t, json.Unmarshal(seen[filepath.Join(home, ".pi", "agent", "models.json")].Content, &models))
list := models["providers"].(map[string]any)["hs-gw"].(map[string]any)["models"].([]any)
withLimits := list[0].(map[string]any)
assert.InDelta(t, float64(1048576), withLimits["contextWindow"], 0)
assert.InDelta(t, float64(32768), withLimits["maxTokens"], 0)
withoutLimits := list[1].(map[string]any)
assert.NotContains(t, withoutLimits, "contextWindow")
assert.NotContains(t, withoutLimits, "maxTokens")
}
func TestPiRenderMergesExistingSettings(t *testing.T) {