Q37: skill tool text tells the CEO the truth about grants
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
25d054d954
commit
e726c36bac
3 files changed
+18
-4
No files matched your search
@@ -200,12 +200,12 @@ export const AGENT_TOOLS: ToolDefinition[] = [
|
||||
},
|
||||
{
|
||||
name: "list_skills",
|
||||
description: "See the company's skill library and who holds each skill. You carry every skill automatically as CEO; teammates only run with skills you grant them.",
|
||||
description: "See the company's skill library and who holds each skill. A skill joins an agent's runs only once granted, the CEO included; house-style skills are carried by everyone.",
|
||||
parameters: { type: "object", additionalProperties: false, properties: {}, required: [] },
|
||||
},
|
||||
{
|
||||
name: "grant_skill",
|
||||
description: "CEO only: grant a teammate one of the company's skills so its instructions join their next run. Match the skill to the job.",
|
||||
description: "CEO only: grant a teammate, or yourself, one of the company's skills so its instructions join their next run. Match the skill to the job.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
|
||||
@@ -132,7 +132,7 @@ function capabilityBriefing(input: AgentInstructionContext): string {
|
||||
);
|
||||
if (input.isCeo) {
|
||||
lines.push(
|
||||
"You are the CEO: you automatically carry every connected service, and access for everyone else is yours to manage — when you delegate work that needs an external service, grant it first with grant_connector and take it back with revoke_connector when done. The company also ships a built-in skill library: staff every hire with the skills their role needs by passing skills to hire_agent (several per person is normal), and adjust later with grant_skill / revoke_skill. A teammate without the grant cannot use the tool or skill, so grant before you assign. The humanizer skill is company house style — every agent, you included, carries it automatically and must write like a person, not like an AI.",
|
||||
"You are the CEO: you automatically carry every connected service, and access for everyone else is yours to manage — when you delegate work that needs an external service, grant it first with grant_connector and take it back with revoke_connector when done. The company also ships a built-in skill library: staff every hire with the skills their role needs by passing skills to hire_agent (several per person is normal), and adjust later with grant_skill / revoke_skill. You run only with skills granted to you too: grant yourself a playbook before you rely on it. A teammate without the grant cannot use the tool or skill, so grant before you assign. The humanizer skill is company house style — every agent, you included, carries it automatically and must write like a person, not like an AI.",
|
||||
);
|
||||
} else if (input.connectorNames.length === 0) {
|
||||
lines.push(
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DatabaseConnection } from "../../src/main/database/connection";
|
||||
import { OrganizationService } from "../../src/main/services/organization-service";
|
||||
import { ChatService } from "../../src/main/services/chat-service";
|
||||
import { SkillService } from "../../src/main/services/skill-service";
|
||||
import { dispatchAgentTool, type AgentToolContext } from "../../src/main/services/agent-tools";
|
||||
import { AGENT_TOOLS, dispatchAgentTool, type AgentToolContext } from "../../src/main/services/agent-tools";
|
||||
|
||||
function call(name: string, args: Record<string, unknown>) {
|
||||
return { id: `call_${randomUUID()}`, name, arguments: args };
|
||||
@@ -75,6 +75,20 @@ function importSkill(h: Harness, name: string, slug: string): void {
|
||||
}
|
||||
|
||||
describe("skill grants", () => {
|
||||
test("the CEO runs only with granted skills, as the tool text says, and can grant itself", () => {
|
||||
const h = harness();
|
||||
importSkill(h, "Release Gate", "release-gate");
|
||||
const listSkills = AGENT_TOOLS.find((tool) => tool.name === "list_skills");
|
||||
expect(listSkills?.description).not.toContain("every skill automatically");
|
||||
expect(listSkills?.description).toContain("the CEO included");
|
||||
const skills = new SkillService(h.connection.db, "");
|
||||
expect(skills.hasRuntimeSkills(h.orgId, h.ceoId)).toBe(false);
|
||||
expect(dispatchAgentTool(h.deps, h.ceoCtx, call("grant_skill", { agent_name: "CEO", skill: "release-gate" })))
|
||||
.toBe("CEO now has the Release Gate skill; it joins their next run.");
|
||||
expect(skills.hasRuntimeSkills(h.orgId, h.ceoId)).toBe(true);
|
||||
h.connection.close();
|
||||
});
|
||||
|
||||
test("the CEO grants and revokes skills for teammates", () => {
|
||||
const h = harness();
|
||||
importSkill(h, "Release Gate", "release-gate");
|
||||
|
||||
Reference in new issue
Block a user