Files
Agent-System-Backend/internal/server/compiled_list_test.go
T
weichen f1302ed5b3 Enable canonical versioned Go module consumption
Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements.

Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate.

Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable.

Refs: Versioned dependencies U1/U3; feature/dependency-workspace
2026-10-13 15:47:16 +00:00

125 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package server
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/bus"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/plugins"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/profiles"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/runmgr"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/runtime"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/settings"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/store"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/tools"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/pkg/extension"
)
type compiledListView struct {
Manifest struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
APIVersion string `json:"apiVersion"`
Provides struct {
Commands []string `json:"commands"`
Intents []string `json:"intents"`
} `json:"provides"`
Backend struct {
Mode string `json:"mode"`
} `json:"backend"`
} `json:"manifest"`
}
// WP3-I4:/api/plugins 合并编译插件条目——backend.mode=inproc、apiVersion 取
// 扩展面版本、provides 来自注册面摘要;目录插件同名时目录条目权威不重复。
func TestListPluginsMergesCompiled(t *testing.T) {
dir := t.TempDir()
st, err := store.OpenSQLite(filepath.Join(dir, "test.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { st.Close() })
b := bus.New()
reg := tools.NewRegistry()
reg.RegisterBuiltin()
setSvc := settings.NewService(st)
profSvc := profiles.New(st)
profSvc.EnsureDefault()
mgr := runmgr.New(st, b, reg, profSvc, setSvc, &runtime.LLMRunner{}, &runtime.SubLLMRunner{}, &runtime.MockRunner{}, &runtime.MockSubagent{})
pluginsRoot := filepath.Join(dir, "plugins")
// 目录插件与编译条目同名:目录条目权威,编译合成条目不重复列出。
if err := os.MkdirAll(filepath.Join(pluginsRoot, "generative-ui"), 0o755); err != nil {
t.Fatal(err)
}
manifest := `{"id":"generative-ui","name":"目录版","version":"1.2.3","apiVersion":"1.0","provides":{}}`
if err := os.WriteFile(filepath.Join(pluginsRoot, "generative-ui", "plugin.json"), []byte(manifest), 0o644); err != nil {
t.Fatal(err)
}
ph := plugins.New(st, reg, setSvc, pluginsRoot)
for id, err := range ph.LoadDir() {
if err != nil {
t.Fatalf("LoadDir %s: %v", id, err)
}
}
srv := New(st, mgr, reg, profSvc, setSvc, ph)
srv.Auth = NewAuthenticator(st, true)
srv.CompiledPlugins = []CompiledPlugin{
{ID: "rdm", Commands: []string{"rdm.ingest", "rdm.inspect.capabilities"}, Intents: []string{"rdm.write-proposal"}},
{ID: "generative-ui", Commands: []string{"generative-ui.present"}},
}
h := srv.Handler()
key, err := st.CreateAPIKey("alice", "e2e")
if err != nil {
t.Fatal(err)
}
req := httptest.NewRequest(http.MethodGet, "/api/plugins", nil)
req.Header.Set("Authorization", "Bearer "+key)
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status %d: %s", rec.Code, rec.Body.String())
}
var list []compiledListView
if err := json.Unmarshal(rec.Body.Bytes(), &list); err != nil {
t.Fatal(err)
}
var rdm, genui *compiledListView
genuiCount := 0
for i := range list {
switch list[i].Manifest.ID {
case "rdm":
rdm = &list[i]
case "generative-ui":
genui = &list[i]
genuiCount++
}
}
if rdm == nil {
t.Fatalf("compiled rdm entry missing: %s", rec.Body.String())
}
if rdm.Manifest.Name != "rdm" || rdm.Manifest.Backend.Mode != "inproc" {
t.Fatalf("rdm entry = %+v", rdm.Manifest)
}
if rdm.Manifest.APIVersion != extension.SurfaceVersion {
t.Fatalf("rdm apiVersion = %q, want %q", rdm.Manifest.APIVersion, extension.SurfaceVersion)
}
if len(rdm.Manifest.Provides.Commands) != 2 || len(rdm.Manifest.Provides.Intents) != 1 {
t.Fatalf("rdm provides = %+v", rdm.Manifest.Provides)
}
if genuiCount != 1 || genui == nil {
t.Fatalf("generative-ui listed %d times", genuiCount)
}
// 目录条目权威:同名编译条目不重复、manifest 不被合成版覆盖。
if genui.Manifest.Name != "目录版" || genui.Manifest.Version != "1.2.3" || genui.Manifest.Backend.Mode != "" {
t.Fatalf("genui entry = %+v", genui.Manifest)
}
}