mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-27 01:41:40 +00:00
test: tighten shared card schema coverage
This commit is contained in:
@@ -576,17 +576,6 @@ describe("feishuPlugin actions", () => {
|
||||
).rejects.toThrow("Feishu thread-reply requires messageId.");
|
||||
});
|
||||
|
||||
it("declares card as optional in the tool schema", () => {
|
||||
const discovery = feishuPlugin.actions?.describeMessageTool?.({ cfg });
|
||||
const schema = Array.isArray(discovery?.schema) ? discovery.schema[0] : discovery?.schema;
|
||||
const cardSchema = schema?.properties?.card;
|
||||
expect(cardSchema).toBeDefined();
|
||||
// TypeBox marks Optional schemas with Symbol(TypeBox.Optional) = "Optional".
|
||||
expect(
|
||||
(cardSchema as unknown as Record<symbol, unknown>)?.[Symbol.for("TypeBox.Optional")],
|
||||
).toBe("Optional");
|
||||
});
|
||||
|
||||
it("sends media-only messages without requiring card", async () => {
|
||||
feishuOutboundSendMediaMock.mockResolvedValueOnce({
|
||||
channel: "feishu",
|
||||
|
||||
@@ -294,7 +294,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("custom", "missing-model", "/tmp/agent", cfg);
|
||||
|
||||
@@ -314,7 +314,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("google-paid", "missing-model", "/tmp/agent", cfg);
|
||||
|
||||
@@ -362,7 +362,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
// Requesting a non-listed model forces the providerCfg fallback branch.
|
||||
const result = resolveModelForTest("custom", "missing-model", "/tmp/agent", cfg);
|
||||
@@ -388,7 +388,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("custom", "missing-model", "/tmp/agent", cfg);
|
||||
|
||||
@@ -442,7 +442,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("custom", "model-b", "/tmp/agent", cfg);
|
||||
|
||||
@@ -469,7 +469,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("custom", "model-b", "/tmp/agent", cfg);
|
||||
|
||||
@@ -495,7 +495,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const models = buildInlineProviderModels(cfg.models?.providers ?? {});
|
||||
expect(models).toEqual(
|
||||
@@ -661,7 +661,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("onehub", "glm-5", "/tmp/agent", cfg);
|
||||
|
||||
@@ -720,7 +720,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("qwen", "qwen3-coder-plus", "/tmp/agent", cfg);
|
||||
|
||||
@@ -869,7 +869,7 @@ describe("resolveModel", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const result = resolveModelForTest("github-copilot", "gpt-5.4-mini", "/tmp/agent", cfg);
|
||||
|
||||
|
||||
@@ -37,6 +37,24 @@ function createTelegramPollExtraToolSchemas() {
|
||||
};
|
||||
}
|
||||
|
||||
function createCardSchemaPlugin(params: {
|
||||
id: string;
|
||||
label: string;
|
||||
docsPath: string;
|
||||
blurb: string;
|
||||
}) {
|
||||
return createChannelPlugin({
|
||||
...params,
|
||||
actions: ["send"],
|
||||
capabilities: ["cards"],
|
||||
toolSchema: () => ({
|
||||
properties: {
|
||||
card: createMessageToolCardSchema(),
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
runMessageAction: vi.fn(),
|
||||
loadConfig: vi.fn(() => ({})),
|
||||
@@ -421,37 +439,45 @@ describe("message tool schema scoping", () => {
|
||||
expect(actionEnum).toContain("poll");
|
||||
});
|
||||
|
||||
it("keeps provider card schema optional after merging into the message tool schema", () => {
|
||||
const feishuPlugin = createChannelPlugin({
|
||||
id: "feishu",
|
||||
label: "Feishu",
|
||||
docsPath: "/channels/feishu",
|
||||
blurb: "Feishu test plugin.",
|
||||
actions: ["send"],
|
||||
capabilities: ["cards"],
|
||||
toolSchema: () => ({
|
||||
properties: {
|
||||
card: createMessageToolCardSchema(),
|
||||
},
|
||||
it.each([
|
||||
{
|
||||
provider: "feishu",
|
||||
plugin: createCardSchemaPlugin({
|
||||
id: "feishu",
|
||||
label: "Feishu",
|
||||
docsPath: "/channels/feishu",
|
||||
blurb: "Feishu test plugin.",
|
||||
}),
|
||||
});
|
||||
},
|
||||
{
|
||||
provider: "msteams",
|
||||
plugin: createCardSchemaPlugin({
|
||||
id: "msteams",
|
||||
label: "MSTeams",
|
||||
docsPath: "/channels/msteams",
|
||||
blurb: "MSTeams test plugin.",
|
||||
}),
|
||||
},
|
||||
])(
|
||||
"keeps $provider card schema optional after merging into the message tool schema",
|
||||
({ plugin }) => {
|
||||
setActivePluginRegistry(
|
||||
createTestRegistry([{ pluginId: plugin.id, source: "test", plugin }]),
|
||||
);
|
||||
|
||||
setActivePluginRegistry(
|
||||
createTestRegistry([{ pluginId: "feishu", source: "test", plugin: feishuPlugin }]),
|
||||
);
|
||||
const tool = createMessageTool({
|
||||
config: {} as never,
|
||||
currentChannelProvider: plugin.id,
|
||||
});
|
||||
const schema = tool.parameters as {
|
||||
properties?: Record<string, unknown>;
|
||||
required?: string[];
|
||||
};
|
||||
|
||||
const tool = createMessageTool({
|
||||
config: {} as never,
|
||||
currentChannelProvider: "feishu",
|
||||
});
|
||||
const schema = tool.parameters as {
|
||||
properties?: Record<string, unknown>;
|
||||
required?: string[];
|
||||
};
|
||||
|
||||
expect(schema.properties?.card).toBeDefined();
|
||||
expect(schema.required ?? []).not.toContain("card");
|
||||
});
|
||||
expect(schema.properties?.card).toBeDefined();
|
||||
expect(schema.required ?? []).not.toContain("card");
|
||||
},
|
||||
);
|
||||
|
||||
it("hides telegram poll extras when telegram polls are disabled in scoped mode", () => {
|
||||
const telegramPluginWithConfig = createChannelPlugin({
|
||||
|
||||
Reference in New Issue
Block a user