import path from
"node:path" ;
import { describe, expect, it, vi } from
"vitest" ;
import { resolveOpenClawPluginToolInputs } from
"./openclaw-tools.plugin-context.js" ;
import { applyPluginToolDeliveryDefaults } from
"./plugin-tool-delivery-defaults.js" ;
import type { AnyAgentTool } from
"./tools/common.js" ;
describe(
"openclaw plugin tool context" , () => {
it(
"forwards trusted requester sender identity" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
requesterSenderId:
"trusted-sender" ,
senderIsOwner:
true ,
},
});
expect(result.context).toEqual(
expect.objectContaining({
requesterSenderId:
"trusted-sender" ,
senderIsOwner:
true ,
}),
);
});
it(
"forwards fs policy for plugin tool sandbox enforcement" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
fsPolicy: { workspaceOnly:
true },
},
});
expect(result.context).toEqual(
expect.objectContaining({
fsPolicy: { workspaceOnly:
true },
}),
);
});
it(
"forwards ephemeral sessionId" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
agentSessionKey:
"agent:main:telegram:direct:12345" ,
sessionId:
"a1b2c3d4-e5f6-7890-abcd-ef1234567890" ,
},
});
expect(result.context).toEqual(
expect.objectContaining({
sessionKey:
"agent:main:telegram:direct:12345" ,
sessionId:
"a1b2c3d4-e5f6-7890-abcd-ef1234567890" ,
}),
);
});
it(
"infers the default agent workspace when workspaceDir is omitted" , () => {
const workspaceDir = path.join(process.cwd(),
"tmp-main-workspace" );
const result = resolveOpenClawPluginToolInputs({
options: {
config: {
agents: {
defaults: { workspace: workspaceDir },
list: [{ id:
"main" ,
default :
true }],
},
} as never,
agentSessionKey:
"main" ,
},
resolvedConfig: {
agents: {
defaults: { workspace: workspaceDir },
list: [{ id:
"main" ,
default :
true }],
},
} as never,
});
expect(result.context).toEqual(
expect.objectContaining({
agentId:
"main" ,
workspaceDir,
}),
);
});
it(
"infers the session agent workspace when workspaceDir is omitted" , () => {
const supportWorkspace = path.join(process.cwd(),
"tmp-support-workspace" );
const config = {
agents: {
defaults: { workspace: path.join(process.cwd(),
"tmp-default-workspace" ) },
list: [
{ id:
"main" ,
default :
true },
{ id:
"support" , workspace: supportWorkspace },
],
},
} as never;
const result = resolveOpenClawPluginToolInputs({
options: {
config,
agentSessionKey:
"agent:support:main" ,
},
resolvedConfig: config,
});
expect(result.context).toEqual(
expect.objectContaining({
agentId:
"support" ,
workspaceDir: supportWorkspace,
}),
);
});
it(
"forwards browser session wiring" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
sandboxBrowserBridgeUrl:
"http://127.0.0.1:9999 ",
allowHostBrowserControl:
true ,
},
});
expect(result.context).toEqual(
expect.objectContaining({
browser: {
sandboxBridgeUrl:
"http://127.0.0.1:9999 ",
allowHostControl:
true ,
},
}),
);
});
it(
"forwards gateway subagent binding" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
allowGatewaySubagentBinding:
true ,
},
});
expect(result.allowGatewaySubagentBinding).toBe(
true );
});
it(
"forwards ambient deliveryContext" , () => {
const result = resolveOpenClawPluginToolInputs({
options: {
config: {} as never,
agentChannel:
"slack" ,
agentTo:
"channel:C123" ,
agentAccountId:
"work" ,
agentThreadId:
"1710000000.000100" ,
},
});
expect(result.context).toEqual(
expect.objectContaining({
deliveryContext: {
channel:
"slack" ,
to:
"channel:C123" ,
accountId:
"work" ,
threadId:
"1710000000.000100" ,
},
}),
);
});
it(
"does not inject ambient thread defaults into plugin tools" , async () => {
const executeMock = vi.fn(async () => ({
content: [{ type:
"text" as
const , text:
"ok" }],
details: {},
}));
const sharedTool: AnyAgentTool = {
name:
"plugin-thread-default" ,
label:
"plugin-thread-default" ,
description:
"test" ,
parameters: {
type:
"object" ,
properties: {
threadId: { type:
"string" },
},
},
execute: executeMock,
};
const [first] = applyPluginToolDeliveryDefaults({
tools: [sharedTool],
deliveryContext: { threadId:
"111.222" },
});
const [second] = applyPluginToolDeliveryDefaults({
tools: [sharedTool],
deliveryContext: { threadId:
"333.444" },
});
expect(first).toBe(sharedTool);
expect(second).toBe(sharedTool);
await first?.execute(
"call-1" , {});
await second?.execute(
"call-2" , {});
expect(executeMock).toHaveBeenNthCalledWith(
1 ,
"call-1" , {});
expect(executeMock).toHaveBeenNthCalledWith(
2 ,
"call-2" , {});
});
it(
"does not inject messageThreadId defaults for missing params objects" , async () => {
const executeMock = vi.fn(async () => ({
content: [{ type:
"text" as
const , text:
"ok" }],
details: {},
}));
const tool: AnyAgentTool = {
name:
"plugin-message-thread-default" ,
label:
"plugin-message-thread-default" ,
description:
"test" ,
parameters: {
type:
"object" ,
properties: {
messageThreadId: { type:
"number" },
},
},
execute: executeMock,
};
const [wrapped] = applyPluginToolDeliveryDefaults({
tools: [tool],
deliveryContext: { threadId:
"77" },
});
await wrapped?.execute(
"call-1" , undefined);
expect(executeMock).toHaveBeenCalledWith(
"call-1" , undefined);
});
it(
"does not infer string thread ids for tools that declare thread parameters" , async () => {
const executeMock = vi.fn(async () => ({
content: [{ type:
"text" as
const , text:
"ok" }],
details: {},
}));
const tool: AnyAgentTool = {
name:
"plugin-string-thread-default" ,
label:
"plugin-string-thread-default" ,
description:
"test" ,
parameters: {
type:
"object" ,
properties: {
threadId: { type:
"string" },
},
},
execute: executeMock,
};
const [wrapped] = applyPluginToolDeliveryDefaults({
tools: [tool],
deliveryContext: { threadId:
"77" },
});
await wrapped?.execute(
"call-1" , {});
expect(executeMock).toHaveBeenCalledWith(
"call-1" , {});
});
it(
"preserves explicit thread params when ambient defaults exist" , async () => {
const executeMock = vi.fn(async () => ({
content: [{ type:
"text" as
const , text:
"ok" }],
details: {},
}));
const tool: AnyAgentTool = {
name:
"plugin-thread-override" ,
label:
"plugin-thread-override" ,
description:
"test" ,
parameters: {
type:
"object" ,
properties: {
threadId: { type:
"string" },
},
},
execute: executeMock,
};
const [wrapped] = applyPluginToolDeliveryDefaults({
tools: [tool],
deliveryContext: { threadId:
"111.222" },
});
await wrapped?.execute(
"call-1" , { threadId:
"explicit" });
expect(executeMock).toHaveBeenCalledWith(
"call-1" , { threadId:
"explicit" });
});
});
Messung V0.5 in Prozent C=100 H=97 G=98
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland