@agentdesk/workflows-mcp
Version:
MCP workflow orchestration tool with presets for thinking, coding and more
423 lines (385 loc) • 13.4 kB
text/typescript
/// <reference types="node" />
/// <reference types="mocha" />
import { expect } from "chai";
import {
validateToolConfig,
convertParametersToJsonSchema,
convertParameterToJsonSchema,
convertParametersToZodSchema,
ParameterConfig,
DevToolsConfig,
} from "../src/config.js";
describe("Advanced Parameter Handling", function () {
describe("Nested Objects Validation", function () {
it("should validate nested object structures", function () {
const config: DevToolsConfig = {
testTool: {
name: "test_tool",
parameters: {
settings: {
type: "object",
description: "Configuration settings",
properties: {
performance: {
type: "object",
description: "Performance settings",
properties: {
level: {
type: "number",
description: "Performance level",
},
optimizeFor: {
type: "enum",
enum: ["speed", "memory", "balanced"],
description: "Optimization target",
},
},
},
},
},
},
},
};
const result = validateToolConfig(config, "testTool");
expect(result).to.be.null;
});
it("should catch invalid nested object structures", function () {
const config: DevToolsConfig = {
testTool: {
name: "test_tool",
parameters: {
settings: {
type: "object",
description: "Configuration settings",
properties: {
performance: {
type: "object",
description: "Performance settings",
properties: {
level: {
// @ts-ignore - Intentionally using an invalid type for testing
type: "invalid_type",
description: "Performance level",
},
},
},
},
},
},
},
};
const result = validateToolConfig(config, "testTool");
expect(result).to.not.be.null;
expect(result).to.include("invalid type");
});
});
describe("Array Items Validation", function () {
it("should validate array with typed items", function () {
const config: DevToolsConfig = {
testTool: {
name: "test_tool",
parameters: {
data: {
type: "array",
description: "Data points",
items: {
type: "number",
description: "Numeric data point",
},
},
},
},
};
const result = validateToolConfig(config, "testTool");
expect(result).to.be.null;
});
it("should catch invalid array item types", function () {
const config: DevToolsConfig = {
testTool: {
name: "test_tool",
parameters: {
data: {
type: "array",
description: "Data points",
items: {
// @ts-ignore - Intentionally using an invalid type for testing
type: "invalid",
description: "Invalid data point type",
},
},
},
},
};
const result = validateToolConfig(config, "testTool");
expect(result).to.not.be.null;
expect(result).to.contain("invalid type");
});
});
describe("Complex Parameter Schema Conversion", function () {
it("should convert nested object structure to JSON Schema", function () {
const parameters: Record<string, ParameterConfig> = {
settings: {
type: "object",
description: "Configuration settings",
required: true,
properties: {
performance: {
type: "object",
description: "Performance settings",
properties: {
level: {
type: "number",
description: "Performance level",
default: 3,
},
optimizeFor: {
type: "enum",
enum: ["speed", "memory", "balanced"],
description: "Optimization target",
default: "balanced",
},
},
},
security: {
type: "object",
description: "Security settings",
properties: {
enabled: {
type: "boolean",
description: "Whether security is enabled",
default: true,
},
},
},
},
},
};
const schema = convertParametersToJsonSchema(parameters);
expect(schema.type).to.equal("object");
expect(schema.required).to.deep.equal(["settings"]);
expect(schema.properties.settings.type).to.equal("object");
expect(schema.properties.settings.properties.performance.type).to.equal(
"object"
);
expect(
schema.properties.settings.properties.performance.properties.level.type
).to.equal("number");
expect(
schema.properties.settings.properties.performance.properties.optimizeFor
.enum
).to.deep.equal(["speed", "memory", "balanced"]);
});
it("should convert array with typed items to JSON Schema", function () {
const parameters: Record<string, ParameterConfig> = {
data: {
type: "array",
description: "Data points",
items: {
type: "number",
description: "Numeric data point",
},
},
};
const schema = convertParametersToJsonSchema(parameters);
expect(schema.type).to.equal("object");
expect(schema.properties.data.type).to.equal("array");
expect(schema.properties.data.items.type).to.equal("number");
});
it("should convert array of enum types to JSON Schema", function () {
const parameters: Record<string, ParameterConfig> = {
operations: {
type: "array",
description: "Operations to perform",
items: {
type: "enum",
enum: ["sum", "average", "min", "max"],
description: "Operation type",
},
},
};
const schema = convertParametersToJsonSchema(parameters);
expect(schema.type).to.equal("object");
expect(schema.properties.operations.type).to.equal("array");
expect(schema.properties.operations.items.type).to.equal("string");
expect(schema.properties.operations.items.enum).to.deep.equal([
"sum",
"average",
"min",
"max",
]);
});
});
describe("Numeric Enum Handling", function () {
it("should correctly identify numeric enum types", function () {
const parameters: Record<string, ParameterConfig> = {
level: {
type: "enum",
enum: [1, 2, 3, 4, 5],
description: "Performance level (1-5)",
default: 3,
},
};
const schema = convertParametersToJsonSchema(parameters);
expect(schema.properties.level.type).to.equal("number");
expect(schema.properties.level.enum).to.deep.equal([1, 2, 3, 4, 5]);
});
it("should handle mixed enum types (defaulting to string)", function () {
const parameters: Record<string, ParameterConfig> = {
mixed: {
type: "enum",
// @ts-ignore - Intentionally using mixed types for testing
enum: ["low", 1, "medium", 2, "high"],
description: "Mixed enum values",
},
};
const schema = convertParametersToJsonSchema(parameters);
// By our implementation, it should use the type of the first value
expect(schema.properties.mixed.type).to.equal("string");
expect(schema.properties.mixed.enum).to.deep.equal([
"low",
1,
"medium",
2,
"high",
]);
});
});
describe("Full Advanced Tool Configuration", function () {
it("should validate the complete advanced tool from examples.yaml", function () {
const config: DevToolsConfig = {
advanced_tool: {
name: "advanced_configuration",
description: "Configure a system with complex parameters",
parameters: {
name: {
type: "string",
description: "Name of the configuration",
required: true,
},
settings: {
type: "object",
description: "Configuration settings",
required: true,
properties: {
performance: {
type: "object",
description: "Performance settings",
properties: {
level: {
type: "enum",
enum: [1, 2, 3, 4, 5],
description: "Performance level (1-5)",
default: 3,
},
optimizeFor: {
type: "enum",
enum: ["speed", "memory", "balanced"],
description: "What to optimize for",
default: "balanced",
},
},
},
security: {
type: "object",
description: "Security settings",
properties: {
enabled: {
type: "boolean",
description: "Whether security is enabled",
default: true,
},
levels: {
type: "array",
description: "Security levels to apply",
items: {
type: "string",
},
},
},
},
},
},
tags: {
type: "array",
description: "Tags for this configuration",
items: {
type: "string",
},
},
timeout: {
type: "number",
description: "Timeout in seconds",
default: 30,
},
},
},
};
const result = validateToolConfig(config, "advanced_tool");
expect(result).to.be.null;
const schema = convertParametersToJsonSchema(
config.advanced_tool!.parameters!
);
expect(schema.type).to.equal("object");
expect(schema.required).to.deep.equal(["name", "settings"]);
// Check nested object paths
expect(
schema.properties.settings.properties.performance.properties.level.enum
).to.deep.equal([1, 2, 3, 4, 5]);
expect(
schema.properties.settings.properties.security.properties.levels.type
).to.equal("array");
// Check array items
expect(schema.properties.tags.items.type).to.equal("string");
});
});
describe("Individual Parameter Schema Conversion", function () {
it("should convert individual string parameter to JSON Schema", function () {
const param: ParameterConfig = {
type: "string",
description: "A string parameter",
default: "default value",
};
const schema = convertParameterToJsonSchema(param);
expect(schema.type).to.equal("string");
expect(schema.description).to.equal("A string parameter");
expect(schema.default).to.equal("default value");
});
it("should convert individual enum parameter to JSON Schema", function () {
const param: ParameterConfig = {
type: "enum",
enum: ["option1", "option2", "option3"],
description: "An enum parameter",
default: "option2",
};
const schema = convertParameterToJsonSchema(param);
expect(schema.type).to.equal("string");
expect(schema.enum).to.deep.equal(["option1", "option2", "option3"]);
expect(schema.default).to.equal("option2");
});
it("should convert individual numeric enum parameter to JSON Schema", function () {
const param: ParameterConfig = {
type: "enum",
enum: [1, 2, 3, 4, 5],
description: "A numeric enum parameter",
default: 3,
};
const schema = convertParameterToJsonSchema(param);
expect(schema.type).to.equal("number");
expect(schema.enum).to.deep.equal([1, 2, 3, 4, 5]);
expect(schema.default).to.equal(3);
});
it("should convert individual array parameter with items to JSON Schema", function () {
const param: ParameterConfig = {
type: "array",
description: "An array parameter",
items: {
type: "string",
description: "String item",
},
};
const schema = convertParameterToJsonSchema(param);
expect(schema.type).to.equal("array");
expect(schema.items.type).to.equal("string");
});
});
});