Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
71 lines
2.8 KiB
Go
71 lines
2.8 KiB
Go
package workbench
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/Tencent/WeKnora/internal/types"
|
|
)
|
|
|
|
func TestAgentDutyEnforcedOnSave(t *testing.T) {
|
|
s := sqliteWorkbench(t)
|
|
ctx := workbenchContext(1, "alice", types.TenantRoleContributor)
|
|
for _, role := range []string{"", types.AgentRoleGeneral, types.AgentRoleTrainingMap, types.AgentRoleProduction, types.AgentRoleQC} {
|
|
s.agents = generationAgentStub{config: types.CustomAgentConfig{Role: role}}
|
|
m := &Resource{Name: "map", Kind: "training-maps", Data: asJSON(MapData{Topic: "topic", AgentID: "agent"})}
|
|
f := &Resource{Name: "flow", Kind: "flows", Data: asJSON(FlowData{Nodes: []FlowNode{{ID: "n", AgentID: "agent"}}})}
|
|
for _, item := range []struct {
|
|
resource *Resource
|
|
duty string
|
|
}{{m, types.AgentRoleTrainingMap}, {f, types.AgentRoleProduction}} {
|
|
err := s.validate(ctx, item.resource)
|
|
want := (types.CustomAgentConfig{Role: role}).SupportsDuty(item.duty)
|
|
if (err == nil) != want {
|
|
t.Fatalf("role %q duty %q: %v", role, item.duty, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAgentContentTagsReachTaskDecomposition(t *testing.T) {
|
|
s, ctx, job, model := generationHarness(t)
|
|
s.agents = generationAgentStub{config: types.CustomAgentConfig{Role: types.AgentRoleProduction, ContentTags: []string{"课程标签"}}}
|
|
f := seedResource(t, s, 1, "writer", "flows")
|
|
f.Data = asJSON(FlowData{Nodes: []FlowNode{{ID: "n", AgentID: "agent"}}})
|
|
if err := s.db.Save(f).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
job.Action = "decompose"
|
|
model.output = `{"segments":[{"id":"s","title":"segment","node_id":"n","agent_id":"agent"}]}`
|
|
r := &Resource{Kind: "content-tasks", Data: asJSON(TaskData{FlowID: f.ID, AgentID: "agent", SourceText: "framework"})}
|
|
if err := s.executeTask(ctx, job, r, ActionRequest{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(model.messages) < 2 || !strings.Contains(model.messages[1].Content, "课程标签") {
|
|
t.Fatal("decomposition omitted native content tags")
|
|
}
|
|
}
|
|
|
|
func TestAgentDutyChangeBlocksSavedMapAndFlowExecution(t *testing.T) {
|
|
s, ctx, job, model := generationHarness(t)
|
|
s.agents = generationAgentStub{config: types.CustomAgentConfig{Role: types.AgentRoleQC}}
|
|
job.Action = "generate"
|
|
m := &Resource{Kind: "training-maps", Data: asJSON(MapData{Topic: "topic", AgentID: "agent"})}
|
|
if err := s.executeMap(ctx, job, m, ActionRequest{}); !errors.Is(err, ErrInvalid) {
|
|
t.Fatalf("map: %v", err)
|
|
}
|
|
if len(model.messages) != 0 {
|
|
t.Fatal("incompatible agent invoked model")
|
|
}
|
|
f := seedResource(t, s, 1, "writer", "flows")
|
|
f.Data = asJSON(FlowData{Nodes: []FlowNode{{ID: "n", AgentID: "agent"}}})
|
|
if err := s.db.Save(f).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
snapshot := FlowData{Nodes: []FlowNode{{ID: "frozen", AgentID: "agent"}}}
|
|
if _, err := s.taskFlow(ctx, TaskData{FlowID: f.ID, FlowSnapshot: &snapshot}); !errors.Is(err, ErrInvalid) {
|
|
t.Fatalf("frozen flow: %v", err)
|
|
}
|
|
}
|