mirror of https://github.com/openclaw/openclaw.git
Skills: expand direct slash dispatch regression coverage
This commit is contained in:
parent
6b47a95c6f
commit
b71d5609d9
|
|
@ -43,7 +43,7 @@ const createTypingController = (): TypingController => ({
|
||||||
cleanup: vi.fn(),
|
cleanup: vi.fn(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const skillCommands: SkillCommandSpec[] = [
|
const defaultSkillCommands: SkillCommandSpec[] = [
|
||||||
{
|
{
|
||||||
name: "danger-skill",
|
name: "danger-skill",
|
||||||
skillName: "danger-skill",
|
skillName: "danger-skill",
|
||||||
|
|
@ -53,12 +53,26 @@ const skillCommands: SkillCommandSpec[] = [
|
||||||
toolName: "gateway",
|
toolName: "gateway",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "read-skill",
|
||||||
|
skillName: "read-skill",
|
||||||
|
description: "Allowed direct tool dispatch",
|
||||||
|
dispatch: {
|
||||||
|
kind: "tool",
|
||||||
|
toolName: "read",
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function createInput(): HandleInlineActionsInput {
|
function createInput(overrides?: {
|
||||||
|
body?: string;
|
||||||
|
senderIsOwner?: boolean;
|
||||||
|
skillCommands?: SkillCommandSpec[];
|
||||||
|
}): HandleInlineActionsInput {
|
||||||
|
const body = overrides?.body ?? "/danger-skill test";
|
||||||
const ctx = buildTestCtx({
|
const ctx = buildTestCtx({
|
||||||
Body: "/danger-skill test",
|
Body: body,
|
||||||
CommandBody: "/danger-skill test",
|
CommandBody: body,
|
||||||
Provider: "whatsapp",
|
Provider: "whatsapp",
|
||||||
Surface: "whatsapp",
|
Surface: "whatsapp",
|
||||||
From: "whatsapp:+123",
|
From: "whatsapp:+123",
|
||||||
|
|
@ -85,17 +99,17 @@ function createInput(): HandleInlineActionsInput {
|
||||||
channel: "whatsapp",
|
channel: "whatsapp",
|
||||||
channelId: "whatsapp",
|
channelId: "whatsapp",
|
||||||
ownerList: [],
|
ownerList: [],
|
||||||
senderIsOwner: true,
|
senderIsOwner: overrides?.senderIsOwner ?? true,
|
||||||
isAuthorizedSender: true,
|
isAuthorizedSender: true,
|
||||||
senderId: "owner-1",
|
senderId: "owner-1",
|
||||||
abortKey: "whatsapp:+123",
|
abortKey: "whatsapp:+123",
|
||||||
rawBodyNormalized: "/danger-skill test",
|
rawBodyNormalized: body,
|
||||||
commandBodyNormalized: "/danger-skill test",
|
commandBodyNormalized: body,
|
||||||
from: "whatsapp:+123",
|
from: "whatsapp:+123",
|
||||||
to: "whatsapp:+123",
|
to: "whatsapp:+123",
|
||||||
},
|
},
|
||||||
directives: clearInlineDirectives("/danger-skill test"),
|
directives: clearInlineDirectives(body),
|
||||||
cleanedBody: "/danger-skill test",
|
cleanedBody: body,
|
||||||
elevatedEnabled: false,
|
elevatedEnabled: false,
|
||||||
elevatedAllowed: false,
|
elevatedAllowed: false,
|
||||||
elevatedFailures: [],
|
elevatedFailures: [],
|
||||||
|
|
@ -110,7 +124,7 @@ function createInput(): HandleInlineActionsInput {
|
||||||
contextTokens: 0,
|
contextTokens: 0,
|
||||||
abortedLastRun: false,
|
abortedLastRun: false,
|
||||||
sessionScope: "per-sender",
|
sessionScope: "per-sender",
|
||||||
skillCommands,
|
skillCommands: overrides?.skillCommands ?? defaultSkillCommands,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,4 +144,24 @@ describe("handleInlineActions skill tool dispatch", () => {
|
||||||
});
|
});
|
||||||
expect(gatewayExecuteMock).not.toHaveBeenCalled();
|
expect(gatewayExecuteMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("executes an allowed tool through direct /skill dispatch", async () => {
|
||||||
|
const result = await handleInlineActions(createInput({ body: "/read-skill test" }));
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
kind: "reply",
|
||||||
|
reply: { text: "READ" },
|
||||||
|
});
|
||||||
|
expect(readExecuteMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps owner-only tools blocked for non-owners before policy resolution", async () => {
|
||||||
|
const result = await handleInlineActions(createInput({ senderIsOwner: false }));
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
kind: "reply",
|
||||||
|
reply: { text: "❌ Tool not available: gateway" },
|
||||||
|
});
|
||||||
|
expect(gatewayExecuteMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ function resolveSkillDispatchTools(params: {
|
||||||
});
|
});
|
||||||
const toolsByAuthorization = applyOwnerOnlyToolPolicy(tools, params.senderIsOwner);
|
const toolsByAuthorization = applyOwnerOnlyToolPolicy(tools, params.senderIsOwner);
|
||||||
const {
|
const {
|
||||||
agentId,
|
agentId: resolvedAgentId,
|
||||||
globalPolicy,
|
globalPolicy,
|
||||||
globalProviderPolicy,
|
globalProviderPolicy,
|
||||||
agentPolicy,
|
agentPolicy,
|
||||||
|
|
@ -194,7 +194,7 @@ function resolveSkillDispatchTools(params: {
|
||||||
agentPolicy,
|
agentPolicy,
|
||||||
agentProviderPolicy,
|
agentProviderPolicy,
|
||||||
groupPolicy,
|
groupPolicy,
|
||||||
agentId,
|
agentId: resolvedAgentId,
|
||||||
}),
|
}),
|
||||||
{ policy: sandboxPolicy, label: "sandbox tools.allow" },
|
{ policy: sandboxPolicy, label: "sandbox tools.allow" },
|
||||||
{ policy: subagentPolicy, label: "subagent tools.allow" },
|
{ policy: subagentPolicy, label: "subagent tools.allow" },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue