update the archive options
Some checks failed
CI / test (push) Failing after 4m40s
CI / fixture (push) Failing after 7s

This commit is contained in:
2026-09-10 19:30:46 +05:30
parent 74089eb3e9
commit 4e1f746b22
5 changed files with 388 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ import (
"github.com/krow/krow-backend/go-api/internal/auth"
"github.com/krow/krow-backend/go-api/internal/config"
"github.com/krow/krow-backend/go-api/internal/db"
"github.com/krow/krow-backend/go-api/internal/definition"
"github.com/krow/krow-backend/go-api/internal/knowledge"
"github.com/krow/krow-backend/go-api/internal/runtime"
"github.com/krow/krow-backend/go-api/internal/service"
@@ -109,6 +110,11 @@ type serverOptions struct {
// Not configuration: it describes the artefact, not the deployment, and an
// environment variable could disagree with the code it claims to describe.
version string
// curatedAgents replaces the set New would otherwise read from disk.
// nil means "read the configured directory"; an empty non-nil set means
// "protect nothing", which is a thing a test needs to be able to say.
curatedAgents map[string]bool
}
// WithBuildVersion records which build this is.
@@ -154,6 +160,21 @@ func WithClock(now func() time.Time) Option {
// It does not weaken anything: the engine still loads agents through the same
// loader, still runs them under the same budgets, and still authorizes through
// the same principal. Only the model behind it changes.
// WithCuratedAgents names the delete-protected agent ids directly.
//
// Production loads these from disk; this exists so a test can state its own
// protected set without a directory, exactly as WithAgentEngine lets one
// supply an engine without a model credential.
func WithCuratedAgents(ids ...string) Option {
return func(o *serverOptions) {
set := make(map[string]bool, len(ids))
for _, id := range ids {
set[id] = true
}
o.curatedAgents = set
}
}
func WithAgentEngine(e *runtime.Engine) Option {
return func(o *serverOptions) { o.agents = e }
}
@@ -232,6 +253,30 @@ func New(cfg *config.Config, database *db.DB, log *slog.Logger, opts ...Option)
// rather than becoming an agent that silently cannot do what it claims.
s.definitions = s.definitions.WithToolCheck(toolRegistry.Known)
// The agents this deployment ships specs for, so DELETE refuses them at the
// endpoint rather than only in the list that renders the button.
//
// Read from the directory `importagents` publishes from, so the protected
// set is the published set by construction. A deployment without that
// directory protects nothing and says so here, once, at boot: silence would
// leave an operator believing in a guard that is not running.
curated := o.curatedAgents
if curated == nil {
loaded, err := definition.CuratedIDs(cfg.Agents.CuratedPath)
if err != nil {
return nil, fmt.Errorf("load curated agents: %w", err)
}
curated = loaded
}
if len(curated) == 0 {
log.Warn("no curated agent specs found; built-in agents are not delete-protected",
"path", cfg.Agents.CuratedPath)
} else {
log.Info("curated agents are delete-protected",
"count", len(curated), "ids", definition.SortedIDs(curated))
}
s.definitions = s.definitions.WithCuratedAgents(curated)
mux := http.NewServeMux()
mux.HandleFunc("GET /health", s.handleHealth)
s.endpoints = s.routeAuth(mux) + s.routeResources(mux) + s.routeMe(mux) +