@lexq/cli 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +90 -94
- package/dist/mcp/register.js +81 -85
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -910,7 +910,7 @@ function buildUpdateBody2(opts) {
|
|
|
910
910
|
import "commander";
|
|
911
911
|
function registerDeployCommands(program) {
|
|
912
912
|
const deploy = program.command("deploy").description("Deployment lifecycle and history");
|
|
913
|
-
deploy.command("publish").description("Publish a DRAFT version (DRAFT \u2192 ACTIVE)").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to publish").
|
|
913
|
+
deploy.command("publish").description("Publish a DRAFT version (DRAFT \u2192 ACTIVE)").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to publish").requiredOption("--memo <memo>", "Publish Deployment memo").action(async (opts) => {
|
|
914
914
|
try {
|
|
915
915
|
const globalOpts = program.opts();
|
|
916
916
|
await apiRequest(
|
|
@@ -921,7 +921,7 @@ function registerDeployCommands(program) {
|
|
|
921
921
|
baseUrl: globalOpts.baseUrl,
|
|
922
922
|
dryRun: globalOpts.dryRun,
|
|
923
923
|
verbose: globalOpts.verbose,
|
|
924
|
-
body: { memo: opts.memo
|
|
924
|
+
body: { memo: opts.memo }
|
|
925
925
|
}
|
|
926
926
|
);
|
|
927
927
|
console.log(`\u2713 Version ${opts.versionId} published.`);
|
|
@@ -930,7 +930,7 @@ function registerDeployCommands(program) {
|
|
|
930
930
|
process.exit(1);
|
|
931
931
|
}
|
|
932
932
|
});
|
|
933
|
-
deploy.command("live").description("Deploy an ACTIVE version to live traffic").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to deploy").
|
|
933
|
+
deploy.command("live").description("Deploy an ACTIVE version to live traffic").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to deploy").requiredOption("--memo <memo>", "Live Deployment memo").action(async (opts) => {
|
|
934
934
|
try {
|
|
935
935
|
const globalOpts = program.opts();
|
|
936
936
|
await apiRequest("POST", `policy-groups/${opts.groupId}/deploy`, {
|
|
@@ -938,7 +938,7 @@ function registerDeployCommands(program) {
|
|
|
938
938
|
baseUrl: globalOpts.baseUrl,
|
|
939
939
|
dryRun: globalOpts.dryRun,
|
|
940
940
|
verbose: globalOpts.verbose,
|
|
941
|
-
body: { versionId: opts.versionId, memo: opts.memo
|
|
941
|
+
body: { versionId: opts.versionId, memo: opts.memo }
|
|
942
942
|
});
|
|
943
943
|
console.log(`\u2713 Version ${opts.versionId} deployed to live.`);
|
|
944
944
|
} catch (error) {
|
|
@@ -946,7 +946,7 @@ function registerDeployCommands(program) {
|
|
|
946
946
|
process.exit(1);
|
|
947
947
|
}
|
|
948
948
|
});
|
|
949
|
-
deploy.command("rollback").description("Rollback to the previous deployed version").requiredOption("--group-id <groupId>", "Policy group ID").
|
|
949
|
+
deploy.command("rollback").description("Rollback to the previous deployed version").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--memo <memo>", "Rollback reason").option("--force", "Skip confirmation prompt").action(async (opts) => {
|
|
950
950
|
try {
|
|
951
951
|
const globalOpts = program.opts();
|
|
952
952
|
if (!opts.force) {
|
|
@@ -964,7 +964,7 @@ function registerDeployCommands(program) {
|
|
|
964
964
|
baseUrl: globalOpts.baseUrl,
|
|
965
965
|
dryRun: globalOpts.dryRun,
|
|
966
966
|
verbose: globalOpts.verbose,
|
|
967
|
-
body: { memo: opts.memo
|
|
967
|
+
body: { memo: opts.memo }
|
|
968
968
|
});
|
|
969
969
|
console.log(`\u2713 Group ${opts.groupId} rolled back.`);
|
|
970
970
|
} catch (error) {
|
|
@@ -972,7 +972,7 @@ function registerDeployCommands(program) {
|
|
|
972
972
|
process.exit(1);
|
|
973
973
|
}
|
|
974
974
|
});
|
|
975
|
-
deploy.command("undeploy").description("Remove the live version from a group").requiredOption("--group-id <groupId>", "Policy group ID").
|
|
975
|
+
deploy.command("undeploy").description("Remove the live version from a group").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--memo <memo>", "Undeploy reason").option("--force", "Skip confirmation prompt").action(async (opts) => {
|
|
976
976
|
try {
|
|
977
977
|
const globalOpts = program.opts();
|
|
978
978
|
if (!opts.force) {
|
|
@@ -990,7 +990,7 @@ function registerDeployCommands(program) {
|
|
|
990
990
|
baseUrl: globalOpts.baseUrl,
|
|
991
991
|
dryRun: globalOpts.dryRun,
|
|
992
992
|
verbose: globalOpts.verbose,
|
|
993
|
-
body: { memo: opts.memo
|
|
993
|
+
body: { memo: opts.memo }
|
|
994
994
|
});
|
|
995
995
|
console.log(`\u2713 Group ${opts.groupId} undeployed.`);
|
|
996
996
|
} catch (error) {
|
|
@@ -1553,7 +1553,7 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1553
1553
|
process.exit(1);
|
|
1554
1554
|
}
|
|
1555
1555
|
});
|
|
1556
|
-
history.command("get").description("Get execution detail").requiredOption("--id <
|
|
1556
|
+
history.command("get").description("Get execution detail").requiredOption("--id <traceId>", "Trace ID").action(async (opts) => {
|
|
1557
1557
|
try {
|
|
1558
1558
|
const globalOpts = program.opts();
|
|
1559
1559
|
const data = await apiRequest(
|
|
@@ -1942,18 +1942,14 @@ function registerGroupTools(server, callApi) {
|
|
|
1942
1942
|
"lexq_groups_list",
|
|
1943
1943
|
{
|
|
1944
1944
|
title: "List Policy Groups",
|
|
1945
|
-
description: "List all policy groups
|
|
1945
|
+
description: "List all policy groups with pagination.",
|
|
1946
1946
|
inputSchema: {
|
|
1947
1947
|
page: z.number().int().min(0).default(0).describe("Page number (0-indexed)"),
|
|
1948
|
-
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
1949
|
-
status: z.enum(["ACTIVE", "DISABLED", "ARCHIVED"]).optional().describe("Filter by status"),
|
|
1950
|
-
keyword: z.string().optional().describe("Search keyword")
|
|
1948
|
+
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
1951
1949
|
}
|
|
1952
1950
|
},
|
|
1953
|
-
async ({ page, size
|
|
1951
|
+
async ({ page, size }) => {
|
|
1954
1952
|
const params = paginationParams(page, size);
|
|
1955
|
-
if (status) params.status = status;
|
|
1956
|
-
if (keyword) params.keyword = keyword;
|
|
1957
1953
|
return callApi("GET", "policy-groups", { params });
|
|
1958
1954
|
}
|
|
1959
1955
|
);
|
|
@@ -1977,10 +1973,10 @@ function registerGroupTools(server, callApi) {
|
|
|
1977
1973
|
name: z.string().describe("Group name (unique among non-ARCHIVED)"),
|
|
1978
1974
|
priority: z.number().int().min(0).describe("Execution priority (lower = higher)"),
|
|
1979
1975
|
description: z.string().optional().describe("Group description"),
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1976
|
+
activationMode: z.enum(["NONE", "EXCLUSIVE", "MAX_N"]).optional().describe("Conflict resolution mode"),
|
|
1977
|
+
activationStrategy: z.enum(["FIRST_MATCH", "HIGHEST_PRIORITY", "MAX_BENEFIT"]).optional().describe("Strategy when mode is EXCLUSIVE or MAX_N"),
|
|
1978
|
+
executionLimit: z.number().int().min(1).optional().describe("Max rule executions (required when mode is MAX_N)"),
|
|
1979
|
+
activationGroup: z.string().optional().describe("Activation group name")
|
|
1984
1980
|
}
|
|
1985
1981
|
},
|
|
1986
1982
|
async (args) => {
|
|
@@ -1989,12 +1985,10 @@ function registerGroupTools(server, callApi) {
|
|
|
1989
1985
|
priority: args.priority
|
|
1990
1986
|
};
|
|
1991
1987
|
if (args.description !== void 0) body.description = args.description;
|
|
1992
|
-
if (args.
|
|
1993
|
-
|
|
1994
|
-
if (args.
|
|
1995
|
-
|
|
1996
|
-
if (args.maxSelections !== void 0) body.maxSelections = args.maxSelections;
|
|
1997
|
-
if (args.activationGroupId !== void 0) body.activationGroupId = args.activationGroupId;
|
|
1988
|
+
if (args.activationMode !== void 0) body.activationMode = args.activationMode;
|
|
1989
|
+
if (args.activationStrategy !== void 0) body.activationStrategy = args.activationStrategy;
|
|
1990
|
+
if (args.executionLimit !== void 0) body.executionLimit = args.executionLimit;
|
|
1991
|
+
if (args.activationGroup !== void 0) body.activationGroup = args.activationGroup;
|
|
1998
1992
|
return callApi("POST", "policy-groups", { body });
|
|
1999
1993
|
}
|
|
2000
1994
|
);
|
|
@@ -2002,19 +1996,19 @@ function registerGroupTools(server, callApi) {
|
|
|
2002
1996
|
"lexq_groups_update",
|
|
2003
1997
|
{
|
|
2004
1998
|
title: "Update Policy Group",
|
|
2005
|
-
description: "Update
|
|
1999
|
+
description: "Update a policy group. This is a full replacement \u2014 omitted optional fields will be set to null on the server.",
|
|
2006
2000
|
inputSchema: {
|
|
2007
2001
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
2008
2002
|
name: z.string().optional().describe("New name"),
|
|
2009
2003
|
priority: z.number().int().min(0).optional().describe("New priority"),
|
|
2010
2004
|
description: z.string().optional().describe("New description"),
|
|
2011
2005
|
status: z.enum(["ACTIVE", "DISABLED"]).optional().describe("Status (DISABLED = emergency stop)"),
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2006
|
+
activationMode: z.enum(["NONE", "EXCLUSIVE", "MAX_N"]).optional().describe("Conflict resolution mode"),
|
|
2007
|
+
activationStrategy: z.enum(["FIRST_MATCH", "HIGHEST_PRIORITY", "MAX_BENEFIT"]).optional().describe("Strategy"),
|
|
2008
|
+
executionLimit: z.number().int().min(1).optional().describe("Max rule executions")
|
|
2015
2009
|
}
|
|
2016
2010
|
},
|
|
2017
|
-
async ({ groupId, ...body }) => callApi("
|
|
2011
|
+
async ({ groupId, ...body }) => callApi("PUT", `policy-groups/${groupId}`, { body })
|
|
2018
2012
|
);
|
|
2019
2013
|
server.registerTool(
|
|
2020
2014
|
"lexq_groups_delete",
|
|
@@ -2031,41 +2025,37 @@ function registerGroupTools(server, callApi) {
|
|
|
2031
2025
|
"lexq_ab_test_start",
|
|
2032
2026
|
{
|
|
2033
2027
|
title: "Start A/B Test",
|
|
2034
|
-
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic
|
|
2028
|
+
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic rate.",
|
|
2035
2029
|
inputSchema: {
|
|
2036
2030
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
challengerWeight: z.number().int().min(1).max(99).describe("Challenger traffic weight (%)"),
|
|
2040
|
-
identityKey: z.string().optional().describe("Fact key for sticky assignment (e.g. customer_id)")
|
|
2031
|
+
testVersionId: z.string().uuid().describe("Challenger version ID to test"),
|
|
2032
|
+
trafficRate: z.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
|
|
2041
2033
|
}
|
|
2042
2034
|
},
|
|
2043
|
-
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test
|
|
2035
|
+
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test`, { body })
|
|
2044
2036
|
);
|
|
2045
2037
|
server.registerTool(
|
|
2046
2038
|
"lexq_ab_test_stop",
|
|
2047
2039
|
{
|
|
2048
2040
|
title: "Stop A/B Test",
|
|
2049
|
-
description: "Stop a running A/B test.
|
|
2041
|
+
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
2050
2042
|
inputSchema: {
|
|
2051
|
-
groupId: z.string().uuid().describe("Policy group ID")
|
|
2052
|
-
winnerVersionId: z.string().uuid().describe("Version ID to keep as live")
|
|
2043
|
+
groupId: z.string().uuid().describe("Policy group ID")
|
|
2053
2044
|
}
|
|
2054
2045
|
},
|
|
2055
|
-
async ({ groupId
|
|
2046
|
+
async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/ab-test`)
|
|
2056
2047
|
);
|
|
2057
2048
|
server.registerTool(
|
|
2058
2049
|
"lexq_ab_test_adjust",
|
|
2059
2050
|
{
|
|
2060
2051
|
title: "Adjust A/B Test",
|
|
2061
|
-
description: "Adjust traffic
|
|
2052
|
+
description: "Adjust traffic rate of a running A/B test.",
|
|
2062
2053
|
inputSchema: {
|
|
2063
2054
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
2064
|
-
|
|
2065
|
-
challengerWeight: z.number().int().min(1).max(99).describe("New challenger weight (%)")
|
|
2055
|
+
trafficRate: z.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
|
|
2066
2056
|
}
|
|
2067
2057
|
},
|
|
2068
|
-
async ({ groupId, ...body }) => callApi("
|
|
2058
|
+
async ({ groupId, ...body }) => callApi("PATCH", `policy-groups/${groupId}/ab-test/traffic-rate`, { body })
|
|
2069
2059
|
);
|
|
2070
2060
|
}
|
|
2071
2061
|
|
|
@@ -2126,7 +2116,7 @@ function registerVersionTools(server, callApi) {
|
|
|
2126
2116
|
effectiveTo: z2.string().optional().describe("New effective end date")
|
|
2127
2117
|
}
|
|
2128
2118
|
},
|
|
2129
|
-
async ({ groupId, versionId, ...body }) => callApi("
|
|
2119
|
+
async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
|
|
2130
2120
|
);
|
|
2131
2121
|
server.registerTool(
|
|
2132
2122
|
"lexq_versions_delete",
|
|
@@ -2147,15 +2137,12 @@ function registerVersionTools(server, callApi) {
|
|
|
2147
2137
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
2148
2138
|
inputSchema: {
|
|
2149
2139
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
2150
|
-
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
2151
|
-
commitMessage: z2.string().optional().describe("Commit message for the cloned version")
|
|
2140
|
+
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
2152
2141
|
}
|
|
2153
2142
|
},
|
|
2154
|
-
async ({ groupId, versionId
|
|
2155
|
-
const body = {};
|
|
2156
|
-
if (commitMessage !== void 0) body.commitMessage = commitMessage;
|
|
2143
|
+
async ({ groupId, versionId }) => {
|
|
2157
2144
|
return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/clone`, {
|
|
2158
|
-
body
|
|
2145
|
+
body: {}
|
|
2159
2146
|
});
|
|
2160
2147
|
}
|
|
2161
2148
|
);
|
|
@@ -2197,17 +2184,21 @@ function registerRuleTools(server, callApi) {
|
|
|
2197
2184
|
"lexq_rules_create",
|
|
2198
2185
|
{
|
|
2199
2186
|
title: "Create Rule",
|
|
2200
|
-
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
2187
|
+
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
2188
|
+
|
|
2189
|
+
Note: Rules can reference fact keys that are not yet registered in Fact Definitions. The engine allows this for flexibility. However, registering facts via lexq_facts_create is recommended \u2014 it enables type validation, the Console UI autocomplete, and the dry-run requirements analyzer.
|
|
2190
|
+
|
|
2201
2191
|
Condition: { type: "SINGLE", field, operator, value, valueType } or { type: "GROUP", operator: "AND"|"OR", children: [...] }
|
|
2202
|
-
Operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, IN, NOT_IN
|
|
2192
|
+
Operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, IN, NOT_IN
|
|
2203
2193
|
Value types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER
|
|
2204
|
-
|
|
2194
|
+
|
|
2205
2195
|
Actions: [{ type, parameters }]
|
|
2206
|
-
|
|
2196
|
+
|
|
2207
2197
|
Action parameter schemas:
|
|
2208
|
-
- DISCOUNT: { refVar: string, method: "PERCENTAGE"|"AMOUNT", rate
|
|
2198
|
+
- DISCOUNT: { refVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT) }
|
|
2209
2199
|
- POINT: { refVar: string, targetVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT), integrationId: uuid }
|
|
2210
|
-
- COUPON_ISSUE: { couponId: string, integrationId: uuid }
|
|
2200
|
+
- COUPON_ISSUE: { couponId: string, integrationId: uuid }
|
|
2201
|
+
- BLOCK: { reason: string }
|
|
2211
2202
|
- NOTIFICATION: { channel: "SMS"|"EMAIL"|"PUSH"|"KAKAO", targetVar: string, templateId: string, integrationId: uuid }
|
|
2212
2203
|
- WEBHOOK: { url: string, method: "POST" }
|
|
2213
2204
|
- SET_FACT: { key: string, value: string|number|boolean }
|
|
@@ -2241,7 +2232,7 @@ function registerRuleTools(server, callApi) {
|
|
|
2241
2232
|
},
|
|
2242
2233
|
async ({ groupId, versionId, ruleId, rule }) => {
|
|
2243
2234
|
const body = JSON.parse(rule);
|
|
2244
|
-
return callApi("
|
|
2235
|
+
return callApi("PUT", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`, {
|
|
2245
2236
|
body
|
|
2246
2237
|
});
|
|
2247
2238
|
}
|
|
@@ -2282,7 +2273,7 @@ function registerRuleTools(server, callApi) {
|
|
|
2282
2273
|
ruleId,
|
|
2283
2274
|
priority: index
|
|
2284
2275
|
}));
|
|
2285
|
-
return callApi("
|
|
2276
|
+
return callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/reorder`, {
|
|
2286
2277
|
body: { rules }
|
|
2287
2278
|
});
|
|
2288
2279
|
}
|
|
@@ -2299,7 +2290,7 @@ function registerRuleTools(server, callApi) {
|
|
|
2299
2290
|
isEnabled: z3.boolean().describe("true to enable, false to disable")
|
|
2300
2291
|
}
|
|
2301
2292
|
},
|
|
2302
|
-
async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/
|
|
2293
|
+
async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/enabled`, {
|
|
2303
2294
|
body: { isEnabled }
|
|
2304
2295
|
})
|
|
2305
2296
|
);
|
|
@@ -2352,7 +2343,7 @@ function registerFactTools(server, callApi) {
|
|
|
2352
2343
|
isRequired: z4.boolean().describe("Required flag")
|
|
2353
2344
|
}
|
|
2354
2345
|
},
|
|
2355
|
-
async ({ factId, ...body }) => callApi("
|
|
2346
|
+
async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
|
|
2356
2347
|
);
|
|
2357
2348
|
server.registerTool(
|
|
2358
2349
|
"lexq_facts_delete",
|
|
@@ -2378,7 +2369,7 @@ function registerDeployTools(server, callApi) {
|
|
|
2378
2369
|
inputSchema: {
|
|
2379
2370
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
2380
2371
|
versionId: z5.string().uuid().describe("Version ID to publish"),
|
|
2381
|
-
memo: z5.string().
|
|
2372
|
+
memo: z5.string().min(1).describe("Publish Deployment memo (required)")
|
|
2382
2373
|
}
|
|
2383
2374
|
},
|
|
2384
2375
|
async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/versions/${versionId}/publish`, { body: { memo } })
|
|
@@ -2391,7 +2382,7 @@ function registerDeployTools(server, callApi) {
|
|
|
2391
2382
|
inputSchema: {
|
|
2392
2383
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
2393
2384
|
versionId: z5.string().uuid().describe("Version ID to deploy"),
|
|
2394
|
-
memo: z5.string().
|
|
2385
|
+
memo: z5.string().min(1).describe("Live Deployment memo (required)")
|
|
2395
2386
|
}
|
|
2396
2387
|
},
|
|
2397
2388
|
async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/deploy`, {
|
|
@@ -2475,10 +2466,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
2475
2466
|
{
|
|
2476
2467
|
title: "Dry Run",
|
|
2477
2468
|
description: `Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
Always dry-run before publishing to validate rule behavior.`,
|
|
2469
|
+
Example input: { "facts": { "payment_amount": 100000, "customer_tier": "VIP" } }
|
|
2470
|
+
Always dry-run before publishing to validate rule behavior.`,
|
|
2482
2471
|
inputSchema: {
|
|
2483
2472
|
versionId: z6.string().uuid().describe("Policy version ID to test against"),
|
|
2484
2473
|
facts: z6.string().describe('JSON string of facts object, e.g. {"payment_amount":100000}'),
|
|
@@ -2527,14 +2516,21 @@ Always dry-run before publishing to validate rule behavior.`,
|
|
|
2527
2516
|
"lexq_simulation_start",
|
|
2528
2517
|
{
|
|
2529
2518
|
title: "Start Simulation",
|
|
2530
|
-
description: `Start a batch simulation against historical
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2519
|
+
description: `Start a batch simulation against historical or uploaded data.
|
|
2520
|
+
|
|
2521
|
+
dataset.type: "HISTORICAL" or "UPLOADED"
|
|
2522
|
+
dataset.source (when HISTORICAL): "EXECUTION_LOGS"
|
|
2523
|
+
dataset.from / dataset.to: date range (yyyy-MM-dd, when HISTORICAL)
|
|
2524
|
+
options.maxRecords: number (max 100000, default 10000)
|
|
2525
|
+
options.baselinePolicyVersionId: uuid (optional, for comparison)
|
|
2526
|
+
options.includeRuleStats: boolean
|
|
2527
|
+
|
|
2528
|
+
Example body:
|
|
2529
|
+
{
|
|
2530
|
+
"policyVersionId": "<uuid>",
|
|
2531
|
+
"dataset": { "type": "HISTORICAL", "source": "EXECUTION_LOGS", "from": "2025-01-01", "to": "2025-01-31" },
|
|
2532
|
+
"options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true, "maxRecords": 10000 }
|
|
2533
|
+
}`,
|
|
2538
2534
|
inputSchema: {
|
|
2539
2535
|
body: z6.string().describe("JSON string of SimulationRequest")
|
|
2540
2536
|
}
|
|
@@ -2606,16 +2602,15 @@ Example body:
|
|
|
2606
2602
|
{
|
|
2607
2603
|
title: "Upload Dataset",
|
|
2608
2604
|
description: `Upload inline CSV or JSON content as a simulation dataset.
|
|
2609
|
-
The content is uploaded to S3 and a path is returned.
|
|
2610
|
-
Use this path in simulation start with dataset type UPLOADED.
|
|
2611
|
-
|
|
2612
|
-
CSV example:
|
|
2613
|
-
user_id,payment_amount
|
|
2614
|
-
user_001,150000
|
|
2615
|
-
user_002,50000
|
|
2616
|
-
|
|
2617
|
-
JSON example:
|
|
2618
|
-
[{"user_id":"user_001","payment_amount":150000}, {"user_id":"user_002","payment_amount":50000}]`,
|
|
2605
|
+
The content is uploaded to S3 and a path is returned.
|
|
2606
|
+
Use this path in simulation start with dataset type UPLOADED.
|
|
2607
|
+
|
|
2608
|
+
CSV example:
|
|
2609
|
+
user_id,payment_amount
|
|
2610
|
+
user_001,150000
|
|
2611
|
+
user_002,50000
|
|
2612
|
+
|
|
2613
|
+
JSON example: [{"user_id":"user_001","payment_amount":150000}, {"user_id":"user_002","payment_amount":50000}]`,
|
|
2619
2614
|
inputSchema: {
|
|
2620
2615
|
content: z6.string().describe("CSV or JSON content as string"),
|
|
2621
2616
|
filename: z6.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
|
|
@@ -2678,10 +2673,10 @@ function registerHistoryTools(server, callApi) {
|
|
|
2678
2673
|
title: "Get Execution Detail",
|
|
2679
2674
|
description: "Get full execution detail including request facts, result traces, and decision traces.",
|
|
2680
2675
|
inputSchema: {
|
|
2681
|
-
|
|
2676
|
+
traceId: z7.string().describe("Trace ID from execution history")
|
|
2682
2677
|
}
|
|
2683
2678
|
},
|
|
2684
|
-
async ({
|
|
2679
|
+
async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
|
|
2685
2680
|
);
|
|
2686
2681
|
server.registerTool(
|
|
2687
2682
|
"lexq_history_stats",
|
|
@@ -2739,19 +2734,20 @@ function registerIntegrationTools(server, callApi) {
|
|
|
2739
2734
|
"lexq_integrations_save",
|
|
2740
2735
|
{
|
|
2741
2736
|
title: "Save Integration",
|
|
2742
|
-
description: "Create or update an integration. Types: COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK.",
|
|
2737
|
+
description: "Create or update an integration. Provide id to update an existing one; omit id to create new. Types: COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK.",
|
|
2743
2738
|
inputSchema: {
|
|
2739
|
+
id: z8.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
|
|
2744
2740
|
type: z8.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
|
|
2745
2741
|
name: z8.string().describe("Integration name"),
|
|
2746
2742
|
baseUrl: z8.string().describe("Base URL of the external service"),
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2743
|
+
credential: z8.string().optional().describe("API key or token for the service"),
|
|
2744
|
+
additionalConfig: z8.string().optional().describe("JSON string of additional config key-value pairs"),
|
|
2745
|
+
isActive: z8.boolean().default(true).describe("Whether the integration is active")
|
|
2750
2746
|
}
|
|
2751
2747
|
},
|
|
2752
|
-
async ({
|
|
2748
|
+
async ({ additionalConfig, ...rest }) => {
|
|
2753
2749
|
const body = { ...rest };
|
|
2754
|
-
if (
|
|
2750
|
+
if (additionalConfig) body.additionalConfig = JSON.parse(additionalConfig);
|
|
2755
2751
|
return callApi("POST", "integrations", { body });
|
|
2756
2752
|
}
|
|
2757
2753
|
);
|
package/dist/mcp/register.js
CHANGED
|
@@ -35,18 +35,14 @@ function registerGroupTools(server, callApi) {
|
|
|
35
35
|
"lexq_groups_list",
|
|
36
36
|
{
|
|
37
37
|
title: "List Policy Groups",
|
|
38
|
-
description: "List all policy groups
|
|
38
|
+
description: "List all policy groups with pagination.",
|
|
39
39
|
inputSchema: {
|
|
40
40
|
page: z.number().int().min(0).default(0).describe("Page number (0-indexed)"),
|
|
41
|
-
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
42
|
-
status: z.enum(["ACTIVE", "DISABLED", "ARCHIVED"]).optional().describe("Filter by status"),
|
|
43
|
-
keyword: z.string().optional().describe("Search keyword")
|
|
41
|
+
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
44
42
|
}
|
|
45
43
|
},
|
|
46
|
-
async ({ page, size
|
|
44
|
+
async ({ page, size }) => {
|
|
47
45
|
const params = paginationParams(page, size);
|
|
48
|
-
if (status) params.status = status;
|
|
49
|
-
if (keyword) params.keyword = keyword;
|
|
50
46
|
return callApi("GET", "policy-groups", { params });
|
|
51
47
|
}
|
|
52
48
|
);
|
|
@@ -70,10 +66,10 @@ function registerGroupTools(server, callApi) {
|
|
|
70
66
|
name: z.string().describe("Group name (unique among non-ARCHIVED)"),
|
|
71
67
|
priority: z.number().int().min(0).describe("Execution priority (lower = higher)"),
|
|
72
68
|
description: z.string().optional().describe("Group description"),
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
activationMode: z.enum(["NONE", "EXCLUSIVE", "MAX_N"]).optional().describe("Conflict resolution mode"),
|
|
70
|
+
activationStrategy: z.enum(["FIRST_MATCH", "HIGHEST_PRIORITY", "MAX_BENEFIT"]).optional().describe("Strategy when mode is EXCLUSIVE or MAX_N"),
|
|
71
|
+
executionLimit: z.number().int().min(1).optional().describe("Max rule executions (required when mode is MAX_N)"),
|
|
72
|
+
activationGroup: z.string().optional().describe("Activation group name")
|
|
77
73
|
}
|
|
78
74
|
},
|
|
79
75
|
async (args) => {
|
|
@@ -82,12 +78,10 @@ function registerGroupTools(server, callApi) {
|
|
|
82
78
|
priority: args.priority
|
|
83
79
|
};
|
|
84
80
|
if (args.description !== void 0) body.description = args.description;
|
|
85
|
-
if (args.
|
|
86
|
-
|
|
87
|
-
if (args.
|
|
88
|
-
|
|
89
|
-
if (args.maxSelections !== void 0) body.maxSelections = args.maxSelections;
|
|
90
|
-
if (args.activationGroupId !== void 0) body.activationGroupId = args.activationGroupId;
|
|
81
|
+
if (args.activationMode !== void 0) body.activationMode = args.activationMode;
|
|
82
|
+
if (args.activationStrategy !== void 0) body.activationStrategy = args.activationStrategy;
|
|
83
|
+
if (args.executionLimit !== void 0) body.executionLimit = args.executionLimit;
|
|
84
|
+
if (args.activationGroup !== void 0) body.activationGroup = args.activationGroup;
|
|
91
85
|
return callApi("POST", "policy-groups", { body });
|
|
92
86
|
}
|
|
93
87
|
);
|
|
@@ -95,19 +89,19 @@ function registerGroupTools(server, callApi) {
|
|
|
95
89
|
"lexq_groups_update",
|
|
96
90
|
{
|
|
97
91
|
title: "Update Policy Group",
|
|
98
|
-
description: "Update
|
|
92
|
+
description: "Update a policy group. This is a full replacement \u2014 omitted optional fields will be set to null on the server.",
|
|
99
93
|
inputSchema: {
|
|
100
94
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
101
95
|
name: z.string().optional().describe("New name"),
|
|
102
96
|
priority: z.number().int().min(0).optional().describe("New priority"),
|
|
103
97
|
description: z.string().optional().describe("New description"),
|
|
104
98
|
status: z.enum(["ACTIVE", "DISABLED"]).optional().describe("Status (DISABLED = emergency stop)"),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
activationMode: z.enum(["NONE", "EXCLUSIVE", "MAX_N"]).optional().describe("Conflict resolution mode"),
|
|
100
|
+
activationStrategy: z.enum(["FIRST_MATCH", "HIGHEST_PRIORITY", "MAX_BENEFIT"]).optional().describe("Strategy"),
|
|
101
|
+
executionLimit: z.number().int().min(1).optional().describe("Max rule executions")
|
|
108
102
|
}
|
|
109
103
|
},
|
|
110
|
-
async ({ groupId, ...body }) => callApi("
|
|
104
|
+
async ({ groupId, ...body }) => callApi("PUT", `policy-groups/${groupId}`, { body })
|
|
111
105
|
);
|
|
112
106
|
server.registerTool(
|
|
113
107
|
"lexq_groups_delete",
|
|
@@ -124,41 +118,37 @@ function registerGroupTools(server, callApi) {
|
|
|
124
118
|
"lexq_ab_test_start",
|
|
125
119
|
{
|
|
126
120
|
title: "Start A/B Test",
|
|
127
|
-
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic
|
|
121
|
+
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic rate.",
|
|
128
122
|
inputSchema: {
|
|
129
123
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
challengerWeight: z.number().int().min(1).max(99).describe("Challenger traffic weight (%)"),
|
|
133
|
-
identityKey: z.string().optional().describe("Fact key for sticky assignment (e.g. customer_id)")
|
|
124
|
+
testVersionId: z.string().uuid().describe("Challenger version ID to test"),
|
|
125
|
+
trafficRate: z.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
|
|
134
126
|
}
|
|
135
127
|
},
|
|
136
|
-
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test
|
|
128
|
+
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test`, { body })
|
|
137
129
|
);
|
|
138
130
|
server.registerTool(
|
|
139
131
|
"lexq_ab_test_stop",
|
|
140
132
|
{
|
|
141
133
|
title: "Stop A/B Test",
|
|
142
|
-
description: "Stop a running A/B test.
|
|
134
|
+
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
143
135
|
inputSchema: {
|
|
144
|
-
groupId: z.string().uuid().describe("Policy group ID")
|
|
145
|
-
winnerVersionId: z.string().uuid().describe("Version ID to keep as live")
|
|
136
|
+
groupId: z.string().uuid().describe("Policy group ID")
|
|
146
137
|
}
|
|
147
138
|
},
|
|
148
|
-
async ({ groupId
|
|
139
|
+
async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/ab-test`)
|
|
149
140
|
);
|
|
150
141
|
server.registerTool(
|
|
151
142
|
"lexq_ab_test_adjust",
|
|
152
143
|
{
|
|
153
144
|
title: "Adjust A/B Test",
|
|
154
|
-
description: "Adjust traffic
|
|
145
|
+
description: "Adjust traffic rate of a running A/B test.",
|
|
155
146
|
inputSchema: {
|
|
156
147
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
157
|
-
|
|
158
|
-
challengerWeight: z.number().int().min(1).max(99).describe("New challenger weight (%)")
|
|
148
|
+
trafficRate: z.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
|
|
159
149
|
}
|
|
160
150
|
},
|
|
161
|
-
async ({ groupId, ...body }) => callApi("
|
|
151
|
+
async ({ groupId, ...body }) => callApi("PATCH", `policy-groups/${groupId}/ab-test/traffic-rate`, { body })
|
|
162
152
|
);
|
|
163
153
|
}
|
|
164
154
|
|
|
@@ -219,7 +209,7 @@ function registerVersionTools(server, callApi) {
|
|
|
219
209
|
effectiveTo: z2.string().optional().describe("New effective end date")
|
|
220
210
|
}
|
|
221
211
|
},
|
|
222
|
-
async ({ groupId, versionId, ...body }) => callApi("
|
|
212
|
+
async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
|
|
223
213
|
);
|
|
224
214
|
server.registerTool(
|
|
225
215
|
"lexq_versions_delete",
|
|
@@ -240,15 +230,12 @@ function registerVersionTools(server, callApi) {
|
|
|
240
230
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
241
231
|
inputSchema: {
|
|
242
232
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
243
|
-
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
244
|
-
commitMessage: z2.string().optional().describe("Commit message for the cloned version")
|
|
233
|
+
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
245
234
|
}
|
|
246
235
|
},
|
|
247
|
-
async ({ groupId, versionId
|
|
248
|
-
const body = {};
|
|
249
|
-
if (commitMessage !== void 0) body.commitMessage = commitMessage;
|
|
236
|
+
async ({ groupId, versionId }) => {
|
|
250
237
|
return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/clone`, {
|
|
251
|
-
body
|
|
238
|
+
body: {}
|
|
252
239
|
});
|
|
253
240
|
}
|
|
254
241
|
);
|
|
@@ -290,17 +277,21 @@ function registerRuleTools(server, callApi) {
|
|
|
290
277
|
"lexq_rules_create",
|
|
291
278
|
{
|
|
292
279
|
title: "Create Rule",
|
|
293
|
-
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
280
|
+
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
281
|
+
|
|
282
|
+
Note: Rules can reference fact keys that are not yet registered in Fact Definitions. The engine allows this for flexibility. However, registering facts via lexq_facts_create is recommended \u2014 it enables type validation, the Console UI autocomplete, and the dry-run requirements analyzer.
|
|
283
|
+
|
|
294
284
|
Condition: { type: "SINGLE", field, operator, value, valueType } or { type: "GROUP", operator: "AND"|"OR", children: [...] }
|
|
295
|
-
Operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, IN, NOT_IN
|
|
285
|
+
Operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, IN, NOT_IN
|
|
296
286
|
Value types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER
|
|
297
|
-
|
|
287
|
+
|
|
298
288
|
Actions: [{ type, parameters }]
|
|
299
|
-
|
|
289
|
+
|
|
300
290
|
Action parameter schemas:
|
|
301
|
-
- DISCOUNT: { refVar: string, method: "PERCENTAGE"|"AMOUNT", rate
|
|
291
|
+
- DISCOUNT: { refVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT) }
|
|
302
292
|
- POINT: { refVar: string, targetVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT), integrationId: uuid }
|
|
303
|
-
- COUPON_ISSUE: { couponId: string, integrationId: uuid }
|
|
293
|
+
- COUPON_ISSUE: { couponId: string, integrationId: uuid }
|
|
294
|
+
- BLOCK: { reason: string }
|
|
304
295
|
- NOTIFICATION: { channel: "SMS"|"EMAIL"|"PUSH"|"KAKAO", targetVar: string, templateId: string, integrationId: uuid }
|
|
305
296
|
- WEBHOOK: { url: string, method: "POST" }
|
|
306
297
|
- SET_FACT: { key: string, value: string|number|boolean }
|
|
@@ -334,7 +325,7 @@ function registerRuleTools(server, callApi) {
|
|
|
334
325
|
},
|
|
335
326
|
async ({ groupId, versionId, ruleId, rule }) => {
|
|
336
327
|
const body = JSON.parse(rule);
|
|
337
|
-
return callApi("
|
|
328
|
+
return callApi("PUT", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`, {
|
|
338
329
|
body
|
|
339
330
|
});
|
|
340
331
|
}
|
|
@@ -375,7 +366,7 @@ function registerRuleTools(server, callApi) {
|
|
|
375
366
|
ruleId,
|
|
376
367
|
priority: index
|
|
377
368
|
}));
|
|
378
|
-
return callApi("
|
|
369
|
+
return callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/reorder`, {
|
|
379
370
|
body: { rules }
|
|
380
371
|
});
|
|
381
372
|
}
|
|
@@ -392,7 +383,7 @@ function registerRuleTools(server, callApi) {
|
|
|
392
383
|
isEnabled: z3.boolean().describe("true to enable, false to disable")
|
|
393
384
|
}
|
|
394
385
|
},
|
|
395
|
-
async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/
|
|
386
|
+
async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/enabled`, {
|
|
396
387
|
body: { isEnabled }
|
|
397
388
|
})
|
|
398
389
|
);
|
|
@@ -445,7 +436,7 @@ function registerFactTools(server, callApi) {
|
|
|
445
436
|
isRequired: z4.boolean().describe("Required flag")
|
|
446
437
|
}
|
|
447
438
|
},
|
|
448
|
-
async ({ factId, ...body }) => callApi("
|
|
439
|
+
async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
|
|
449
440
|
);
|
|
450
441
|
server.registerTool(
|
|
451
442
|
"lexq_facts_delete",
|
|
@@ -471,7 +462,7 @@ function registerDeployTools(server, callApi) {
|
|
|
471
462
|
inputSchema: {
|
|
472
463
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
473
464
|
versionId: z5.string().uuid().describe("Version ID to publish"),
|
|
474
|
-
memo: z5.string().
|
|
465
|
+
memo: z5.string().min(1).describe("Publish Deployment memo (required)")
|
|
475
466
|
}
|
|
476
467
|
},
|
|
477
468
|
async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/versions/${versionId}/publish`, { body: { memo } })
|
|
@@ -484,7 +475,7 @@ function registerDeployTools(server, callApi) {
|
|
|
484
475
|
inputSchema: {
|
|
485
476
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
486
477
|
versionId: z5.string().uuid().describe("Version ID to deploy"),
|
|
487
|
-
memo: z5.string().
|
|
478
|
+
memo: z5.string().min(1).describe("Live Deployment memo (required)")
|
|
488
479
|
}
|
|
489
480
|
},
|
|
490
481
|
async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/deploy`, {
|
|
@@ -568,10 +559,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
568
559
|
{
|
|
569
560
|
title: "Dry Run",
|
|
570
561
|
description: `Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
Always dry-run before publishing to validate rule behavior.`,
|
|
562
|
+
Example input: { "facts": { "payment_amount": 100000, "customer_tier": "VIP" } }
|
|
563
|
+
Always dry-run before publishing to validate rule behavior.`,
|
|
575
564
|
inputSchema: {
|
|
576
565
|
versionId: z6.string().uuid().describe("Policy version ID to test against"),
|
|
577
566
|
facts: z6.string().describe('JSON string of facts object, e.g. {"payment_amount":100000}'),
|
|
@@ -620,14 +609,21 @@ Always dry-run before publishing to validate rule behavior.`,
|
|
|
620
609
|
"lexq_simulation_start",
|
|
621
610
|
{
|
|
622
611
|
title: "Start Simulation",
|
|
623
|
-
description: `Start a batch simulation against historical
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
612
|
+
description: `Start a batch simulation against historical or uploaded data.
|
|
613
|
+
|
|
614
|
+
dataset.type: "HISTORICAL" or "UPLOADED"
|
|
615
|
+
dataset.source (when HISTORICAL): "EXECUTION_LOGS"
|
|
616
|
+
dataset.from / dataset.to: date range (yyyy-MM-dd, when HISTORICAL)
|
|
617
|
+
options.maxRecords: number (max 100000, default 10000)
|
|
618
|
+
options.baselinePolicyVersionId: uuid (optional, for comparison)
|
|
619
|
+
options.includeRuleStats: boolean
|
|
620
|
+
|
|
621
|
+
Example body:
|
|
622
|
+
{
|
|
623
|
+
"policyVersionId": "<uuid>",
|
|
624
|
+
"dataset": { "type": "HISTORICAL", "source": "EXECUTION_LOGS", "from": "2025-01-01", "to": "2025-01-31" },
|
|
625
|
+
"options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true, "maxRecords": 10000 }
|
|
626
|
+
}`,
|
|
631
627
|
inputSchema: {
|
|
632
628
|
body: z6.string().describe("JSON string of SimulationRequest")
|
|
633
629
|
}
|
|
@@ -699,16 +695,15 @@ Example body:
|
|
|
699
695
|
{
|
|
700
696
|
title: "Upload Dataset",
|
|
701
697
|
description: `Upload inline CSV or JSON content as a simulation dataset.
|
|
702
|
-
The content is uploaded to S3 and a path is returned.
|
|
703
|
-
Use this path in simulation start with dataset type UPLOADED.
|
|
704
|
-
|
|
705
|
-
CSV example:
|
|
706
|
-
user_id,payment_amount
|
|
707
|
-
user_001,150000
|
|
708
|
-
user_002,50000
|
|
709
|
-
|
|
710
|
-
JSON example:
|
|
711
|
-
[{"user_id":"user_001","payment_amount":150000}, {"user_id":"user_002","payment_amount":50000}]`,
|
|
698
|
+
The content is uploaded to S3 and a path is returned.
|
|
699
|
+
Use this path in simulation start with dataset type UPLOADED.
|
|
700
|
+
|
|
701
|
+
CSV example:
|
|
702
|
+
user_id,payment_amount
|
|
703
|
+
user_001,150000
|
|
704
|
+
user_002,50000
|
|
705
|
+
|
|
706
|
+
JSON example: [{"user_id":"user_001","payment_amount":150000}, {"user_id":"user_002","payment_amount":50000}]`,
|
|
712
707
|
inputSchema: {
|
|
713
708
|
content: z6.string().describe("CSV or JSON content as string"),
|
|
714
709
|
filename: z6.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
|
|
@@ -771,10 +766,10 @@ function registerHistoryTools(server, callApi) {
|
|
|
771
766
|
title: "Get Execution Detail",
|
|
772
767
|
description: "Get full execution detail including request facts, result traces, and decision traces.",
|
|
773
768
|
inputSchema: {
|
|
774
|
-
|
|
769
|
+
traceId: z7.string().describe("Trace ID from execution history")
|
|
775
770
|
}
|
|
776
771
|
},
|
|
777
|
-
async ({
|
|
772
|
+
async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
|
|
778
773
|
);
|
|
779
774
|
server.registerTool(
|
|
780
775
|
"lexq_history_stats",
|
|
@@ -832,19 +827,20 @@ function registerIntegrationTools(server, callApi) {
|
|
|
832
827
|
"lexq_integrations_save",
|
|
833
828
|
{
|
|
834
829
|
title: "Save Integration",
|
|
835
|
-
description: "Create or update an integration. Types: COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK.",
|
|
830
|
+
description: "Create or update an integration. Provide id to update an existing one; omit id to create new. Types: COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK.",
|
|
836
831
|
inputSchema: {
|
|
832
|
+
id: z8.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
|
|
837
833
|
type: z8.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
|
|
838
834
|
name: z8.string().describe("Integration name"),
|
|
839
835
|
baseUrl: z8.string().describe("Base URL of the external service"),
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
836
|
+
credential: z8.string().optional().describe("API key or token for the service"),
|
|
837
|
+
additionalConfig: z8.string().optional().describe("JSON string of additional config key-value pairs"),
|
|
838
|
+
isActive: z8.boolean().default(true).describe("Whether the integration is active")
|
|
843
839
|
}
|
|
844
840
|
},
|
|
845
|
-
async ({
|
|
841
|
+
async ({ additionalConfig, ...rest }) => {
|
|
846
842
|
const body = { ...rest };
|
|
847
|
-
if (
|
|
843
|
+
if (additionalConfig) body.additionalConfig = JSON.parse(additionalConfig);
|
|
848
844
|
return callApi("POST", "integrations", { body });
|
|
849
845
|
}
|
|
850
846
|
);
|