Files
Agent-System-Backend/internal/cmdbus/slash_intent_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

98 lines
3.5 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 cmdbus
import (
"context"
"encoding/json"
"testing"
agentcommand "git-ssh.u1680832.nyat.app/weichen/Agent-Command.git"
)
// EXT-10② 红测:插件命令规格自带 slash 别名 → 四入口同源(slash 命中同一命令
// id,经总线分发同审计信封)。
func TestPluginSlashAliasBindsAndDispatches(t *testing.T) {
bus := New(nopAudit{}, nil, nil)
called := ""
if err := bus.RegisterPluginCommand(spec(t, `{
"id": "rdm.ping", "title": "自检", "slash": "/rdm.ping"
}`), func(ctx context.Context, req Request) (any, error) {
called = req.ID + "|" + req.Entrance
return map[string]any{"ok": true}, nil
}); err != nil {
t.Fatal(err)
}
id, ok := bus.ResolveSlash("/rdm.ping")
if !ok || id != "rdm.ping" {
t.Fatalf("ResolveSlash = %q ok=%v(插件别名未绑定)", id, ok)
}
// 大小写与首尾空白归一。
if id, ok := bus.ResolveSlash(" /RDM.PING "); !ok || id != "rdm.ping" {
t.Fatalf("归一解析失败: %q %v", id, ok)
}
resp := bus.Dispatch(context.Background(), Request{ID: id, Entrance: "slash", Owner: "alice"})
if resp.Receipt.State != "committed" {
t.Fatalf("slash 分发 = %+v", resp.Receipt)
}
if called != "rdm.ping|slash" {
t.Fatalf("处理器见到 %q(须同命令 id)", called)
}
// 同一命令按钮入口分发——同源同信封。
if resp2 := bus.Dispatch(context.Background(), Request{ID: "rdm.ping", Entrance: "button", Owner: "alice"}); resp2.Receipt.State != "committed" {
t.Fatalf("button 分发 = %+v", resp2.Receipt)
}
}
// G2-2 红测:意图声明→归一包含匹配(最长短语优先)→路由到命令(chat 入口)。
func TestIntentDeclareMatchRoute(t *testing.T) {
bus := New(nopAudit{}, nil, nil)
_ = bus.RegisterPluginCommand(spec(t, `{
"id": "rdm.draft.compose", "title": "起草"
}`), func(ctx context.Context, req Request) (any, error) {
return map[string]any{"sectionId": req.Params["sectionId"]}, nil
})
if err := bus.Intents().Declare(Intent{
ID: "rdm.write-proposal", Phrases: []string{"帮我写项目建议书", "写项目建议书"},
Command: "rdm.draft.compose", Params: map[string]any{"sectionId": "sec-1"},
Plugin: "rdm",
}); err != nil {
t.Fatal(err)
}
// 未命中。
if _, ok := bus.Intents().Match("今天天气如何"); ok {
t.Fatal("无关文本不得命中")
}
// 命中(含大小写/空白归一)。
in, ok := bus.Intents().Match("请 帮我写项目建议书,尽快")
if !ok || in.ID != "rdm.write-proposal" {
t.Fatalf("匹配 = %+v ok=%v", in, ok)
}
// 路由:匹配到的命令经总线 chat 入口分发成功。
resp := bus.Dispatch(context.Background(), Request{ID: in.Command, Params: in.Params, Entrance: "chat", Owner: "alice"})
if resp.Receipt.State != "committed" {
t.Fatalf("路由分发 = %+v", resp.Receipt)
}
// 声明校验:缺短语拒绝。
if err := bus.Intents().Declare(Intent{ID: "x", Command: "y"}); err == nil {
t.Fatal("不完整声明须拒绝")
}
// 最长短语优先:更具体的意图先命中。
if err := bus.Intents().Declare(Intent{
ID: "rdm.write-competitive", Phrases: []string{"写竞品分析"},
Command: "rdm.draft.compose", Plugin: "rdm",
}); err != nil {
t.Fatal(err)
}
if in, _ := bus.Intents().Match("帮我写项目建议书"); in.ID != "rdm.write-proposal" {
t.Fatalf("长短语意图应先命中: %+v", in)
}
}
func spec(t *testing.T, raw string) agentcommand.CommandSpec {
t.Helper()
var s agentcommand.CommandSpec
if err := json.Unmarshal([]byte(raw), &s); err != nil {
t.Fatal(err)
}
return s
}