feat(skillpack): lazy BundleStager for bundled files in skill_use
executus CI / test (pull_request) Successful in 2m19s
executus CI / test (pull_request) Successful in 2m19s
Replace Activate's stagedDir string with a BundleStager callback invoked lazily inside skill_use: when the model loads a pack with bundled files, the host stages them (mort: into run-scoped file storage) and the returned note is appended to the body so the model knows how to reach them. A nil stager (or a stager error) degrades gracefully to just listing the file names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,12 @@ func TestActivate_SkillUseTool(t *testing.T) {
|
||||
packs := []*Pack{
|
||||
mustPack(t, "pdf", "Use pdfplumber.", map[string]string{"scripts/x.py": "print()"}),
|
||||
}
|
||||
sk := Activate(packs, "/stage")
|
||||
staged := 0
|
||||
stager := func(_ context.Context, p *Pack) (string, error) {
|
||||
staged++
|
||||
return "staged " + p.Manifest.Name + " (file_id=abc)", nil
|
||||
}
|
||||
sk := Activate(packs, stager)
|
||||
if sk == nil {
|
||||
t.Fatal("expected a non-nil skill")
|
||||
}
|
||||
@@ -56,6 +61,9 @@ func TestActivate_SkillUseTool(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("skill_use tool missing from toolbox")
|
||||
}
|
||||
if staged != 0 {
|
||||
t.Error("stager must be lazy — not called until skill_use runs")
|
||||
}
|
||||
|
||||
// load an existing pack
|
||||
out, err := tool.Handler(ctx, json.RawMessage(`{"name":"pdf"}`))
|
||||
@@ -66,8 +74,11 @@ func TestActivate_SkillUseTool(t *testing.T) {
|
||||
if !strings.Contains(body, "Use pdfplumber.") {
|
||||
t.Errorf("skill_use body missing instructions: %q", body)
|
||||
}
|
||||
if !strings.Contains(body, "scripts/x.py") || !strings.Contains(body, "/stage/pdf") {
|
||||
t.Errorf("skill_use should list bundled files under the staged dir: %q", body)
|
||||
if !strings.Contains(body, "scripts/x.py") {
|
||||
t.Errorf("skill_use should list bundled files: %q", body)
|
||||
}
|
||||
if staged != 1 || !strings.Contains(body, "file_id=abc") {
|
||||
t.Errorf("stager should run on load and its note append to the body: staged=%d body=%q", staged, body)
|
||||
}
|
||||
|
||||
// unknown pack returns guidance, not an error
|
||||
@@ -81,7 +92,7 @@ func TestActivate_SkillUseTool(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActivate_Empty(t *testing.T) {
|
||||
if Activate(nil, "") != nil {
|
||||
if Activate(nil, nil) != nil {
|
||||
t.Error("no packs should activate to a nil skill")
|
||||
}
|
||||
}
|
||||
@@ -92,7 +103,7 @@ func TestNilPackElementsAreSafe(t *testing.T) {
|
||||
if got := Catalog(packs); !strings.Contains(got, "real") {
|
||||
t.Errorf("catalog should include the valid pack and skip nils: %q", got)
|
||||
}
|
||||
sk := Activate(packs, "")
|
||||
sk := Activate(packs, nil)
|
||||
if sk == nil {
|
||||
t.Fatal("a valid pack among nils should still activate")
|
||||
}
|
||||
@@ -100,7 +111,7 @@ func TestNilPackElementsAreSafe(t *testing.T) {
|
||||
t.Error("skill_use missing")
|
||||
}
|
||||
// All-nil activates to nothing rather than panicking.
|
||||
if Activate([]*Pack{nil, {Manifest: nil}}, "") != nil {
|
||||
if Activate([]*Pack{nil, {Manifest: nil}}, nil) != nil {
|
||||
t.Error("only-nil packs should activate to nil")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user