package skillpack import ( "context" "errors" "gitea.stevedudenhoeffer.com/steve/majordomo/llm" ) // Activator adapts the battery to executus/run's SkillPackActivator port: given // an agent's subscribed pack names, it resolves them to their pinned packs and // returns the catalog instructions + the skill_use tool the run injects. It // satisfies run.SkillPackActivator structurally — no import of run — so the // battery stays run-agnostic (the same inversion as the other batteries). // // StagerFor, when set, builds the per-run BundleStager (a host plumbs bundled // files into its own run-scoped storage from the run + subject ids); nil means // skill_use lists a pack's bundled filenames without staging them. type Activator struct { Cache PackCache Subs Store StagerFor func(runID, subjectID string) BundleStager } // ActivateSkillPacks implements run.SkillPackActivator. Unknown or disabled pack // names are skipped; it returns "" + nil when nothing resolves. func (a *Activator) ActivateSkillPacks(ctx context.Context, names []string, runID, subjectID string) (string, []llm.Tool, error) { if a == nil || a.Subs == nil || a.Cache == nil || len(names) == 0 { return "", nil, nil } chosen := make([]Subscription, 0, len(names)) for _, n := range names { sub, err := a.Subs.GetByName(ctx, n) if errors.Is(err, ErrNotFound) { continue } if err != nil { return "", nil, err } if !sub.Enabled { continue } chosen = append(chosen, *sub) } packs, err := Resolve(ctx, a.Cache, chosen) if err != nil { return "", nil, err } var stager BundleStager if a.StagerFor != nil { stager = a.StagerFor(runID, subjectID) } sk := Activate(packs, stager) if sk == nil { return "", nil, nil } return sk.Instructions(), sk.Tools().Tools(), nil }