@@ -8,6 +8,8 @@ import type { DeepMutable } from "@opencode/plugin/promise/types";
|
||||
import type { Info, ToolContext, ToolEditor } from "@opencode/plugin/promise/tool";
|
||||
import type { JsonValue, ModelInfo, SessionGetInput } from "@opencode/client";
|
||||
import type { SessionContext } from "@opencode/plugin/promise/session";
|
||||
import type { SkillEditor } from "@opencode/plugin/promise/skill";
|
||||
import type { Skill } from "@opencode/schema/skill";
|
||||
import { z } from "zod";
|
||||
import { gptAgents, settings, workerNames } from "../src/config.js";
|
||||
import { basePlugin as plugin } from "../src/index.js";
|
||||
@@ -107,6 +109,7 @@ async function host(
|
||||
});
|
||||
const storage = new Map<string, JsonValue>();
|
||||
const tools = new Map<string, Info>();
|
||||
const skills = new Map<string, Skill.Info>();
|
||||
const mcpTools = new Set(configuredMcpTools);
|
||||
const mcpServers = new Map(Object.entries(structuredClone(configuredMcp)));
|
||||
let mcpTransform!: (editor: {
|
||||
@@ -204,6 +207,25 @@ async function host(
|
||||
return registration;
|
||||
},
|
||||
},
|
||||
skill: {
|
||||
async transform(callback: (editor: SkillEditor) => void) {
|
||||
callback({
|
||||
list: () => [...skills.values()],
|
||||
get: (id) => skills.get(id),
|
||||
add: (skill) => {
|
||||
skills.set(skill.id, skill);
|
||||
},
|
||||
update(id, update) {
|
||||
const skill = skills.get(id);
|
||||
if (skill) update(skill);
|
||||
},
|
||||
remove: (id) => {
|
||||
skills.delete(id);
|
||||
},
|
||||
});
|
||||
return registration;
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
async list() {
|
||||
return { data: [...agents.values()] };
|
||||
@@ -272,6 +294,7 @@ async function host(
|
||||
if (cleanup) cleanups.push(cleanup);
|
||||
return {
|
||||
agents,
|
||||
skills,
|
||||
build,
|
||||
mcpServers,
|
||||
defaultAgent,
|
||||
@@ -416,6 +439,30 @@ test("orchestration inherits deep-lo and falls back to good-lo with available wo
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("registers the embedded anti-overengineering skill and makes it available to coordinate", async () => {
|
||||
const result = await host();
|
||||
const skill = result.skills.get("anti-overengineering")!;
|
||||
expect(String(skill.name)).toBe("anti-overengineering");
|
||||
expect(skill.content).toContain("## Correctness floor");
|
||||
expect(skill.content).toContain("## Final subtraction pass");
|
||||
expect(await Bun.file(skill.path).exists()).toBe(true);
|
||||
const coordinate = result.agents.get("coordinate")!;
|
||||
expect(coordinate.permissions).toContainEqual({
|
||||
action: "skill",
|
||||
resource: "*",
|
||||
effect: "allow",
|
||||
});
|
||||
expect(coordinate.permissions.some((rule) => rule.action === "shell")).toBe(false);
|
||||
for (const models of [allModels, allModels.slice(0, 2)]) {
|
||||
const prompt = (await host(models)).agents.get("coordinate")?.system;
|
||||
expect(prompt).toContain("Audit subagent review");
|
||||
expect(prompt).toContain("reject overkill or");
|
||||
expect(prompt).toContain("BEFORE delegating it");
|
||||
expect(prompt).toContain("Ordinary in-scope bugfixes need no extra approval");
|
||||
expect(prompt).toContain("Never waive correctness, security or data integrity");
|
||||
}
|
||||
});
|
||||
|
||||
test("custom assignments resolve duplicate model IDs by provider and refresh provider-aware fallback", async () => {
|
||||
const agents = customAssignments("alpha");
|
||||
agents["fast-lo"] = { ...agents["fast-lo"], model: "beta/shared" };
|
||||
|
||||
Reference in New Issue
Block a user