@fluentcommerce/fluent-mcp-extn 0.7.0 → 0.7.2
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/README.md +176 -174
- package/dist/batch-tools.js +21 -21
- package/dist/cache-tools.js +5 -5
- package/dist/config.js +1 -1
- package/dist/entity-tools.js +16 -16
- package/dist/environment-tools.js +10 -10
- package/dist/event-tools.js +26 -26
- package/dist/fluent-client.js +20 -0
- package/dist/graphql-query-tools.js +15 -15
- package/dist/graphql-schema-tools.js +14 -14
- package/dist/metrics-tools.js +40 -40
- package/dist/profile-registry.js +2 -2
- package/dist/response-shaper.js +1 -1
- package/dist/settings-tools.js +9 -9
- package/dist/test-tools.js +4 -4
- package/dist/tools.js +153 -148
- package/dist/workflow-tools.js +34 -44
- package/docs/E2E_TESTING.md +59 -59
- package/docs/HANDOVER_GITHUB_COPILOT.md +9 -9
- package/docs/HANDOVER_GITHUB_REPO_MCP_CONFIG.example.json +12 -12
- package/docs/RUNBOOK.md +38 -38
- package/docs/TOOL_REFERENCE.md +296 -296
- package/package.json +1 -1
package/dist/batch-tools.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Batch Ingestion Tools
|
|
3
3
|
*
|
|
4
4
|
* Five batch lifecycle tools:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* batch_create — create a batch ingestion job
|
|
6
|
+
* batch_send — send records to an existing job
|
|
7
|
+
* batch_status — check overall job status
|
|
8
|
+
* batch_batchStatus — check a specific batch inside a job
|
|
9
|
+
* batch_results — get per-record outcomes for a completed job
|
|
10
10
|
*/
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { ToolError } from "./errors.js";
|
|
@@ -50,8 +50,8 @@ export const BatchDescribePayloadInputSchema = z.object({
|
|
|
50
50
|
// ---------------------------------------------------------------------------
|
|
51
51
|
export const BATCH_TOOL_DEFINITIONS = [
|
|
52
52
|
{
|
|
53
|
-
name: "
|
|
54
|
-
description: "Create a batch ingestion job. Next:
|
|
53
|
+
name: "batch_create",
|
|
54
|
+
description: "Create a batch ingestion job. Next: batch_send -> batch_status -> batch_results.",
|
|
55
55
|
annotations: {
|
|
56
56
|
title: "Create Batch Job",
|
|
57
57
|
readOnlyHint: false,
|
|
@@ -61,8 +61,8 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
|
-
name: "
|
|
65
|
-
description: "Send records to an existing batch job. Requires jobId from
|
|
64
|
+
name: "batch_send",
|
|
65
|
+
description: "Send records to an existing batch job. Requires jobId from batch_create.",
|
|
66
66
|
annotations: {
|
|
67
67
|
title: "Send Batch",
|
|
68
68
|
readOnlyHint: false,
|
|
@@ -72,7 +72,7 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
72
72
|
},
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
|
-
name: "
|
|
75
|
+
name: "batch_status",
|
|
76
76
|
description: "Check overall job status for polling loops. Repeat until terminal status.",
|
|
77
77
|
annotations: {
|
|
78
78
|
title: "Batch Job Status",
|
|
@@ -83,7 +83,7 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
|
-
name: "
|
|
86
|
+
name: "batch_batchStatus",
|
|
87
87
|
description: "Check a specific batch inside a job (jobId + batchId). Use for troubleshooting partial failures.",
|
|
88
88
|
annotations: {
|
|
89
89
|
title: "Batch Status",
|
|
@@ -94,7 +94,7 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
94
94
|
},
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
|
-
name: "
|
|
97
|
+
name: "batch_results",
|
|
98
98
|
description: "Get per-record batch outcomes for a completed job.",
|
|
99
99
|
annotations: {
|
|
100
100
|
title: "Batch Results",
|
|
@@ -105,8 +105,8 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
105
105
|
},
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
|
-
name: "
|
|
109
|
-
description: "Returns entity-type-specific payload shape, field requirements, and example rows for
|
|
108
|
+
name: "batch_describePayload",
|
|
109
|
+
description: "Returns entity-type-specific payload shape, field requirements, and example rows for batch_send. No API call.",
|
|
110
110
|
annotations: {
|
|
111
111
|
title: "Describe Batch Payload",
|
|
112
112
|
readOnlyHint: true,
|
|
@@ -121,7 +121,7 @@ export const BATCH_TOOL_DEFINITIONS = [
|
|
|
121
121
|
// ---------------------------------------------------------------------------
|
|
122
122
|
function requireClient(ctx) {
|
|
123
123
|
if (!ctx.client) {
|
|
124
|
-
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run
|
|
124
|
+
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run config_validate and fix auth/base URL.");
|
|
125
125
|
}
|
|
126
126
|
return ctx.client;
|
|
127
127
|
}
|
|
@@ -221,7 +221,7 @@ const BATCH_PAYLOAD_DESCRIPTORS = {
|
|
|
221
221
|
// Handlers
|
|
222
222
|
// ---------------------------------------------------------------------------
|
|
223
223
|
/**
|
|
224
|
-
* Handle
|
|
224
|
+
* Handle batch_create tool call.
|
|
225
225
|
*/
|
|
226
226
|
export async function handleBatchCreate(args, ctx) {
|
|
227
227
|
const client = requireClient(ctx);
|
|
@@ -243,7 +243,7 @@ export async function handleBatchCreate(args, ctx) {
|
|
|
243
243
|
return { ok: true, job: result };
|
|
244
244
|
}
|
|
245
245
|
/**
|
|
246
|
-
* Handle
|
|
246
|
+
* Handle batch_send tool call.
|
|
247
247
|
*/
|
|
248
248
|
export async function handleBatchSend(args, ctx) {
|
|
249
249
|
const client = requireClient(ctx);
|
|
@@ -254,7 +254,7 @@ export async function handleBatchSend(args, ctx) {
|
|
|
254
254
|
return { ok: true, batch: result };
|
|
255
255
|
}
|
|
256
256
|
/**
|
|
257
|
-
* Handle
|
|
257
|
+
* Handle batch_status tool call.
|
|
258
258
|
*/
|
|
259
259
|
export async function handleBatchStatus(args, ctx) {
|
|
260
260
|
const client = requireClient(ctx);
|
|
@@ -263,7 +263,7 @@ export async function handleBatchStatus(args, ctx) {
|
|
|
263
263
|
return { ok: true, status: result };
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
266
|
-
* Handle
|
|
266
|
+
* Handle batch_batchStatus tool call.
|
|
267
267
|
*/
|
|
268
268
|
export async function handleBatchBatchStatus(args, ctx) {
|
|
269
269
|
const client = requireClient(ctx);
|
|
@@ -272,7 +272,7 @@ export async function handleBatchBatchStatus(args, ctx) {
|
|
|
272
272
|
return { ok: true, batchStatus: result };
|
|
273
273
|
}
|
|
274
274
|
/**
|
|
275
|
-
* Handle
|
|
275
|
+
* Handle batch_results tool call.
|
|
276
276
|
*/
|
|
277
277
|
export async function handleBatchResults(args, ctx) {
|
|
278
278
|
const client = requireClient(ctx);
|
|
@@ -281,7 +281,7 @@ export async function handleBatchResults(args, ctx) {
|
|
|
281
281
|
return { ok: true, results: result };
|
|
282
282
|
}
|
|
283
283
|
/**
|
|
284
|
-
* Handle
|
|
284
|
+
* Handle batch_describePayload tool call.
|
|
285
285
|
*/
|
|
286
286
|
export async function handleBatchDescribePayload(args, _ctx) {
|
|
287
287
|
const parsed = BatchDescribePayloadInputSchema.parse(args);
|
package/dist/cache-tools.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cache management tools:
|
|
2
|
+
* Cache management tools: cache_status and cache_clear.
|
|
3
3
|
* No API calls — operates on local filesystem cache only.
|
|
4
4
|
*/
|
|
5
5
|
import { z } from "zod";
|
|
@@ -13,14 +13,14 @@ export const CacheClearInputSchema = z.object({
|
|
|
13
13
|
pattern: z
|
|
14
14
|
.string()
|
|
15
15
|
.optional()
|
|
16
|
-
.describe('Glob pattern to clear. Omit to clear all. Examples: "workflow:*", "setting:get:fc.mystique.*", "introspect:*".'),
|
|
16
|
+
.describe('Glob pattern to clear. Omit to clear all. Examples: "workflow:get:*", "workflow:list:*", "setting:get:fc.mystique.*", "plugin:list:*", "introspect:*".'),
|
|
17
17
|
});
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
19
|
// Tool definitions
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
export const CACHE_TOOL_DEFINITIONS = [
|
|
22
22
|
{
|
|
23
|
-
name: "
|
|
23
|
+
name: "cache_status",
|
|
24
24
|
description: "Local cache statistics: entry count, size, hit/miss rate, per-category breakdown.",
|
|
25
25
|
annotations: {
|
|
26
26
|
title: "Cache Status",
|
|
@@ -31,8 +31,8 @@ export const CACHE_TOOL_DEFINITIONS = [
|
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
name: "
|
|
35
|
-
description: "Clear cached entries by pattern (e.g. workflow:*, setting:get:*, introspect:*) or all.",
|
|
34
|
+
name: "cache_clear",
|
|
35
|
+
description: "Clear cached entries by pattern (e.g. workflow:get:*, workflow:list:*, setting:get:*, plugin:list:*, introspect:*) or all.",
|
|
36
36
|
annotations: {
|
|
37
37
|
title: "Clear Cache",
|
|
38
38
|
readOnlyHint: false,
|
package/dist/config.js
CHANGED
|
@@ -345,7 +345,7 @@ export function loadConfigForProfile(profileName, retailer, base) {
|
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
347
|
* Build a RuntimeConfig from explicit credentials (not a CLI profile).
|
|
348
|
-
* Used by
|
|
348
|
+
* Used by connection_add when the caller provides baseUrl + OAuth/token.
|
|
349
349
|
*/
|
|
350
350
|
export function buildExplicitConfig(params, base) {
|
|
351
351
|
return {
|
package/dist/entity-tools.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Entity lifecycle tools:
|
|
2
|
+
* Entity lifecycle tools: entity_create, entity_update, entity_get
|
|
3
3
|
*
|
|
4
4
|
* Type-safe entity CRUD with built-in validation, gotcha knowledge,
|
|
5
5
|
* and audit trail for agentic workflows.
|
|
@@ -63,7 +63,7 @@ export const EntityPlanUpdateInputSchema = z.object({
|
|
|
63
63
|
// ---------------------------------------------------------------------------
|
|
64
64
|
export const ENTITY_TOOL_DEFINITIONS = [
|
|
65
65
|
{
|
|
66
|
-
name: "
|
|
66
|
+
name: "entity_create",
|
|
67
67
|
description: `Type-safe entity creation with field validation, compound key encoding, and retailerId auto-resolve. Supports dryRun. Types: ${SUPPORTED_ENTITY_TYPES.join(", ")}`,
|
|
68
68
|
annotations: {
|
|
69
69
|
title: "Create Entity",
|
|
@@ -74,8 +74,8 @@ export const ENTITY_TOOL_DEFINITIONS = [
|
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
name: "
|
|
78
|
-
description: "Update entity fields/status. Optional validateTransition checks
|
|
77
|
+
name: "entity_update",
|
|
78
|
+
description: "Update entity fields/status. Optional validateTransition checks workflow_transitions before status change.",
|
|
79
79
|
annotations: {
|
|
80
80
|
title: "Update Entity",
|
|
81
81
|
readOnlyHint: false,
|
|
@@ -85,7 +85,7 @@ export const ENTITY_TOOL_DEFINITIONS = [
|
|
|
85
85
|
},
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
|
-
name: "
|
|
88
|
+
name: "entity_get",
|
|
89
89
|
description: "Look up an entity by ID or ref. Use includeEdges to fetch related entities.",
|
|
90
90
|
annotations: {
|
|
91
91
|
title: "Get Entity",
|
|
@@ -96,7 +96,7 @@ export const ENTITY_TOOL_DEFINITIONS = [
|
|
|
96
96
|
},
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
|
-
name: "
|
|
99
|
+
name: "entity_planCreate",
|
|
100
100
|
description: `Plan an entity creation. Returns required fields, variables skeleton, GraphQL mutation, gotchas, and auto-inject info. No API call. Types: ${SUPPORTED_ENTITY_TYPES.join(", ")}.`,
|
|
101
101
|
annotations: {
|
|
102
102
|
title: "Plan Entity Create",
|
|
@@ -107,8 +107,8 @@ export const ENTITY_TOOL_DEFINITIONS = [
|
|
|
107
107
|
},
|
|
108
108
|
},
|
|
109
109
|
{
|
|
110
|
-
name: "
|
|
111
|
-
description: `Plan an
|
|
110
|
+
name: "entity_planUpdate",
|
|
111
|
+
description: `Plan an entity_update. Returns updatable fields, variables skeleton, GraphQL mutation, gotchas, and status-change guidance. No API call. Types: ${SUPPORTED_ENTITY_TYPES.join(", ")}.`,
|
|
112
112
|
annotations: {
|
|
113
113
|
title: "Plan Entity Update",
|
|
114
114
|
readOnlyHint: true,
|
|
@@ -120,7 +120,7 @@ export const ENTITY_TOOL_DEFINITIONS = [
|
|
|
120
120
|
];
|
|
121
121
|
function requireEntityClient(ctx) {
|
|
122
122
|
if (!ctx.client) {
|
|
123
|
-
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run
|
|
123
|
+
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run config_validate and fix auth/base URL.");
|
|
124
124
|
}
|
|
125
125
|
return ctx.client;
|
|
126
126
|
}
|
|
@@ -178,7 +178,7 @@ function optionalPlanFields(meta) {
|
|
|
178
178
|
return Array.from(base);
|
|
179
179
|
}
|
|
180
180
|
/**
|
|
181
|
-
* Handle
|
|
181
|
+
* Handle entity_create tool call.
|
|
182
182
|
*/
|
|
183
183
|
export async function handleEntityCreate(args, ctx) {
|
|
184
184
|
const parsed = EntityCreateInputSchema.parse(args);
|
|
@@ -245,7 +245,7 @@ export async function handleEntityCreate(args, ctx) {
|
|
|
245
245
|
};
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
248
|
-
* Handle
|
|
248
|
+
* Handle entity_update tool call.
|
|
249
249
|
*/
|
|
250
250
|
export async function handleEntityUpdate(args, ctx) {
|
|
251
251
|
const parsed = EntityUpdateInputSchema.parse(args);
|
|
@@ -326,7 +326,7 @@ export async function handleEntityUpdate(args, ctx) {
|
|
|
326
326
|
};
|
|
327
327
|
}
|
|
328
328
|
/**
|
|
329
|
-
* Handle
|
|
329
|
+
* Handle entity_get tool call.
|
|
330
330
|
*/
|
|
331
331
|
export async function handleEntityGet(args, ctx) {
|
|
332
332
|
const parsed = EntityGetInputSchema.parse(args);
|
|
@@ -399,7 +399,7 @@ export async function handleEntityGet(args, ctx) {
|
|
|
399
399
|
};
|
|
400
400
|
}
|
|
401
401
|
/**
|
|
402
|
-
* Handle
|
|
402
|
+
* Handle entity_planCreate tool call.
|
|
403
403
|
*/
|
|
404
404
|
export function handleEntityPlanCreate(args, ctx) {
|
|
405
405
|
const parsed = EntityPlanCreateInputSchema.parse(args);
|
|
@@ -454,7 +454,7 @@ export function handleEntityPlanCreate(args, ctx) {
|
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
456
|
/**
|
|
457
|
-
* Handle
|
|
457
|
+
* Handle entity_planUpdate tool call.
|
|
458
458
|
*/
|
|
459
459
|
export function handleEntityPlanUpdate(args, _ctx) {
|
|
460
460
|
const parsed = EntityPlanUpdateInputSchema.parse(args);
|
|
@@ -498,8 +498,8 @@ export function handleEntityPlanUpdate(args, _ctx) {
|
|
|
498
498
|
hasRef: meta.hasRef,
|
|
499
499
|
},
|
|
500
500
|
_hints: [
|
|
501
|
-
"Required input field: id (ID!). Add status, attributes, and any other changed fields before calling
|
|
502
|
-
"Use
|
|
501
|
+
"Required input field: id (ID!). Add status, attributes, and any other changed fields before calling entity_update.",
|
|
502
|
+
"Use entity_update for direct mutations. When changing status, validateTransition can warn when no workflow transition exists from the current state.",
|
|
503
503
|
],
|
|
504
504
|
};
|
|
505
505
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Environment tools:
|
|
2
|
+
* Environment tools: environment_discover, environment_validate
|
|
3
3
|
*
|
|
4
4
|
* Closes the setup loop — single-call environment snapshot and pre-flight checks
|
|
5
5
|
* for agentic workflows that need to understand what they're working with.
|
|
@@ -44,7 +44,7 @@ export const EnvironmentValidateInputSchema = z.object({
|
|
|
44
44
|
// ---------------------------------------------------------------------------
|
|
45
45
|
export const ENVIRONMENT_TOOL_DEFINITIONS = [
|
|
46
46
|
{
|
|
47
|
-
name: "
|
|
47
|
+
name: "environment_discover",
|
|
48
48
|
description: [
|
|
49
49
|
"Full environment snapshot. Sections opt-in via include array: retailer, locations, networks, catalogues, workflows, settings, modules, users.",
|
|
50
50
|
"Returns refs, IDs, statuses — enough to construct valid mutations. First 100 items per section.",
|
|
@@ -58,7 +58,7 @@ export const ENVIRONMENT_TOOL_DEFINITIONS = [
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
|
-
name: "
|
|
61
|
+
name: "environment_validate",
|
|
62
62
|
description: "Pre-flight validation checks: auth, retailer, locations, inventory, workflows, settings, modules. Returns pass/fail per check with severity.",
|
|
63
63
|
annotations: {
|
|
64
64
|
title: "Validate Environment",
|
|
@@ -123,7 +123,7 @@ const QUERIES = {
|
|
|
123
123
|
};
|
|
124
124
|
function requireEnvClient(ctx) {
|
|
125
125
|
if (!ctx.client) {
|
|
126
|
-
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run
|
|
126
|
+
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run config_validate and fix auth/base URL.");
|
|
127
127
|
}
|
|
128
128
|
return ctx.client;
|
|
129
129
|
}
|
|
@@ -152,7 +152,7 @@ function extractNodes(connection) {
|
|
|
152
152
|
.filter((n) => n !== null);
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
|
-
* Handle
|
|
155
|
+
* Handle environment_discover tool call.
|
|
156
156
|
*/
|
|
157
157
|
export async function handleEnvironmentDiscover(args, ctx) {
|
|
158
158
|
const parsed = EnvironmentDiscoverInputSchema.parse(args);
|
|
@@ -187,7 +187,7 @@ export async function handleEnvironmentDiscover(args, ctx) {
|
|
|
187
187
|
const locPageInfo = data.locations?.pageInfo;
|
|
188
188
|
result.locations = locationNodes;
|
|
189
189
|
if (locPageInfo?.hasNextPage) {
|
|
190
|
-
result.locationsNote = `Showing first ${locationNodes.length} locations. Use
|
|
190
|
+
result.locationsNote = `Showing first ${locationNodes.length} locations. Use graphql_queryAll for complete list.`;
|
|
191
191
|
}
|
|
192
192
|
break;
|
|
193
193
|
}
|
|
@@ -211,7 +211,7 @@ export async function handleEnvironmentDiscover(args, ctx) {
|
|
|
211
211
|
}
|
|
212
212
|
case "workflows": {
|
|
213
213
|
// Workflows are not directly queryable via standard GraphQL.
|
|
214
|
-
// We use the
|
|
214
|
+
// We use the workflow_transitions API to discover deployed workflow types.
|
|
215
215
|
const retailerId = ctx.config.retailerId;
|
|
216
216
|
if (retailerId) {
|
|
217
217
|
try {
|
|
@@ -259,12 +259,12 @@ export async function handleEnvironmentDiscover(args, ctx) {
|
|
|
259
259
|
const settPageInfo = data.settings?.pageInfo;
|
|
260
260
|
result.settings = settingNodes;
|
|
261
261
|
if (settPageInfo?.hasNextPage) {
|
|
262
|
-
result.settingsNote = `Showing first ${settingNodes.length} settings. Use
|
|
262
|
+
result.settingsNote = `Showing first ${settingNodes.length} settings. Use graphql_queryAll for complete list.`;
|
|
263
263
|
}
|
|
264
264
|
break;
|
|
265
265
|
}
|
|
266
266
|
case "modules": {
|
|
267
|
-
// Modules discoverable via
|
|
267
|
+
// Modules discoverable via plugin_list
|
|
268
268
|
try {
|
|
269
269
|
const plugins = await client.getPlugins();
|
|
270
270
|
if (plugins && typeof plugins === "object") {
|
|
@@ -305,7 +305,7 @@ export async function handleEnvironmentDiscover(args, ctx) {
|
|
|
305
305
|
return { ok: true, ...result };
|
|
306
306
|
}
|
|
307
307
|
/**
|
|
308
|
-
* Handle
|
|
308
|
+
* Handle environment_validate tool call.
|
|
309
309
|
*/
|
|
310
310
|
export async function handleEnvironmentValidate(args, ctx) {
|
|
311
311
|
const parsed = EnvironmentValidateInputSchema.parse(args);
|
package/dist/event-tools.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Event lifecycle tools:
|
|
2
|
+
* Event lifecycle tools: event_build, event_send, event_get, event_list, event_flowInspect
|
|
3
3
|
*
|
|
4
4
|
* Extracted from tools.ts — follows the same pattern as entity-tools.ts.
|
|
5
5
|
*/
|
|
@@ -46,7 +46,7 @@ export const EventPublishInputSchema = z.object({
|
|
|
46
46
|
export const EventGetInputSchema = z.object({
|
|
47
47
|
eventId: z.string().min(1),
|
|
48
48
|
});
|
|
49
|
-
/** Tool input for
|
|
49
|
+
/** Tool input for event_list. Supports canonical keys and backward-compatible aliases. */
|
|
50
50
|
export const EventListInputSchema = z
|
|
51
51
|
.object({
|
|
52
52
|
// Canonical keys (SDK FluentEventQueryParams)
|
|
@@ -113,31 +113,31 @@ export const EventFlowInspectInputSchema = z.object({
|
|
|
113
113
|
// ---------------------------------------------------------------------------
|
|
114
114
|
export const EVENT_TOOL_DEFINITIONS = [
|
|
115
115
|
{
|
|
116
|
-
name: "
|
|
117
|
-
description: "Payload-only builder for Event API input. Use before
|
|
116
|
+
name: "event_build",
|
|
117
|
+
description: "Payload-only builder for Event API input. Use before event_send to verify defaults and required context (no API call).",
|
|
118
118
|
schema: EventBuildInputSchema,
|
|
119
119
|
annotations: { title: "Build Event Payload", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
|
-
name: "
|
|
123
|
-
description: "Builds and sends a Fluent event (supports dryRun). dryRun=true includes _workflowPreview with matching rulesets, predicted target status, and rule analysis when workflow is cached. Call
|
|
122
|
+
name: "event_send",
|
|
123
|
+
description: "Builds and sends a Fluent event (supports dryRun). dryRun=true includes _workflowPreview with matching rulesets, predicted target status, and rule analysis when workflow is cached. Call workflow_get first for full preview.",
|
|
124
124
|
schema: EventPublishInputSchema,
|
|
125
125
|
annotations: { title: "Send Event", readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
|
-
name: "
|
|
129
|
-
description: "Fetch one event by ID. Use after
|
|
128
|
+
name: "event_get",
|
|
129
|
+
description: "Fetch one event by ID. Use after event_send if response contains eventId, or after event_list resolves eventId.",
|
|
130
130
|
schema: EventGetInputSchema,
|
|
131
131
|
annotations: { title: "Get Event", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
|
-
name: "
|
|
135
|
-
description: "List/filter events via SDK getEvents with filters and pagination. Use to verify sends, discover eventId, then call
|
|
134
|
+
name: "event_list",
|
|
135
|
+
description: "List/filter events via SDK getEvents with filters and pagination. Use to verify sends, discover eventId, then call event_get for full details.",
|
|
136
136
|
schema: EventListInputSchema,
|
|
137
137
|
annotations: { title: "List Events", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
|
-
name: "
|
|
140
|
+
name: "event_flowInspect",
|
|
141
141
|
description: "One-call event forensics for a root entity. Collects ORCHESTRATION events, extracts timelines, mutations, webhooks, NO_MATCH diagnostics. Compact mode (default) returns pre-analyzed summary.",
|
|
142
142
|
schema: EventFlowInspectInputSchema,
|
|
143
143
|
annotations: { title: "Inspect Event Flow", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
@@ -145,7 +145,7 @@ export const EVENT_TOOL_DEFINITIONS = [
|
|
|
145
145
|
];
|
|
146
146
|
function requireEventClient(ctx) {
|
|
147
147
|
if (!ctx.client) {
|
|
148
|
-
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run
|
|
148
|
+
throw new ToolError("CONFIG_ERROR", "SDK client is not available. Run config_validate and fix auth/base URL.");
|
|
149
149
|
}
|
|
150
150
|
return ctx.client;
|
|
151
151
|
}
|
|
@@ -255,7 +255,7 @@ export function toEventQueryParams(input) {
|
|
|
255
255
|
// Handlers
|
|
256
256
|
// ---------------------------------------------------------------------------
|
|
257
257
|
/**
|
|
258
|
-
* Handle
|
|
258
|
+
* Handle event_build tool call.
|
|
259
259
|
*/
|
|
260
260
|
export async function handleEventBuild(args, ctx) {
|
|
261
261
|
const parsed = EventBuildInputSchema.parse(args);
|
|
@@ -268,14 +268,14 @@ export async function handleEventBuild(args, ctx) {
|
|
|
268
268
|
export function buildEventDryRunEnrichment(eventName, entityType, entitySubtype, cache, retailerId) {
|
|
269
269
|
const hints = [];
|
|
270
270
|
if (!cache || !retailerId) {
|
|
271
|
-
hints.push("Call
|
|
271
|
+
hints.push("Call workflow_get with entityType + entitySubtype to enable workflow simulation preview in dryRun.");
|
|
272
272
|
return { _hints: hints };
|
|
273
273
|
}
|
|
274
274
|
const subtype = entitySubtype ?? "DEFAULT";
|
|
275
275
|
const cacheKey = `workflow:get:${retailerId}:${entityType}::${subtype}:latest`;
|
|
276
276
|
const cached = cache.get(cacheKey);
|
|
277
277
|
if (!cached.hit || !cached.data || typeof cached.data !== "object") {
|
|
278
|
-
hints.push(`No cached workflow for ${entityType}::${subtype}. Call
|
|
278
|
+
hints.push(`No cached workflow for ${entityType}::${subtype}. Call workflow_get first to enable simulation preview.`);
|
|
279
279
|
return { _hints: hints };
|
|
280
280
|
}
|
|
281
281
|
const wf = cached.data;
|
|
@@ -346,7 +346,7 @@ export function buildEventDryRunEnrichment(eventName, entityType, entitySubtype,
|
|
|
346
346
|
});
|
|
347
347
|
}
|
|
348
348
|
if (matchingRulesets.length === 0) {
|
|
349
|
-
hints.push(`No ruleset named "${eventName}" found in workflow ${entityType}::${subtype}. The event may trigger by entity status match instead. Use
|
|
349
|
+
hints.push(`No ruleset named "${eventName}" found in workflow ${entityType}::${subtype}. The event may trigger by entity status match instead. Use workflow_simulate for full analysis.`);
|
|
350
350
|
return { _hints: hints };
|
|
351
351
|
}
|
|
352
352
|
// Deduplicated aggregates
|
|
@@ -371,7 +371,7 @@ export function buildEventDryRunEnrichment(eventName, entityType, entitySubtype,
|
|
|
371
371
|
if (uniqueFollowOnEvents.length > 0) {
|
|
372
372
|
hints.push(`Follow-on event(s) will be emitted: ${uniqueFollowOnEvents.join(", ")}.`);
|
|
373
373
|
}
|
|
374
|
-
hints.push("Use
|
|
374
|
+
hints.push("Use event_flowInspect after sending to verify execution results.");
|
|
375
375
|
return {
|
|
376
376
|
_workflowPreview: {
|
|
377
377
|
workflowName: wf.name ?? `${entityType}::${subtype}`,
|
|
@@ -388,7 +388,7 @@ export function buildEventDryRunEnrichment(eventName, entityType, entitySubtype,
|
|
|
388
388
|
};
|
|
389
389
|
}
|
|
390
390
|
/**
|
|
391
|
-
* Handle
|
|
391
|
+
* Handle event_send tool call.
|
|
392
392
|
*/
|
|
393
393
|
export async function handleEventSend(args, ctx) {
|
|
394
394
|
const parsed = EventPublishInputSchema.parse(args);
|
|
@@ -406,7 +406,7 @@ export async function handleEventSend(args, ctx) {
|
|
|
406
406
|
: {}),
|
|
407
407
|
_hints: [
|
|
408
408
|
...enrichment._hints,
|
|
409
|
-
"Use
|
|
409
|
+
"Use workflow_simulate with currentStatus + eventName for full static analysis.",
|
|
410
410
|
],
|
|
411
411
|
};
|
|
412
412
|
}
|
|
@@ -419,17 +419,17 @@ export async function handleEventSend(args, ctx) {
|
|
|
419
419
|
_hints: parsed.mode === "async"
|
|
420
420
|
? [
|
|
421
421
|
"Event sent asynchronously. Processing happens in the background.",
|
|
422
|
-
"Use
|
|
423
|
-
"Use
|
|
422
|
+
"Use event_list with context.entityRef + name to find the event and check eventStatus.",
|
|
423
|
+
"Use event_flowInspect with rootEntityRef for full execution forensics.",
|
|
424
424
|
]
|
|
425
425
|
: [
|
|
426
|
-
"Use
|
|
427
|
-
"Use
|
|
426
|
+
"Use event_get with the returned eventId to check detailed status.",
|
|
427
|
+
"Use event_flowInspect with rootEntityRef for full execution forensics.",
|
|
428
428
|
],
|
|
429
429
|
};
|
|
430
430
|
}
|
|
431
431
|
/**
|
|
432
|
-
* Handle
|
|
432
|
+
* Handle event_get tool call.
|
|
433
433
|
*/
|
|
434
434
|
export async function handleEventGet(args, ctx) {
|
|
435
435
|
const parsed = EventGetInputSchema.parse(args);
|
|
@@ -438,7 +438,7 @@ export async function handleEventGet(args, ctx) {
|
|
|
438
438
|
return { ok: true, event };
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
441
|
-
* Handle
|
|
441
|
+
* Handle event_list tool call.
|
|
442
442
|
*/
|
|
443
443
|
export async function handleEventList(args, ctx) {
|
|
444
444
|
const parsed = EventListInputSchema.parse(args);
|
|
@@ -476,7 +476,7 @@ export async function handleEventList(args, ctx) {
|
|
|
476
476
|
return { ok: true, events };
|
|
477
477
|
}
|
|
478
478
|
/**
|
|
479
|
-
* Handle
|
|
479
|
+
* Handle event_flowInspect tool call.
|
|
480
480
|
*/
|
|
481
481
|
export async function handleEventFlowInspect(args, ctx) {
|
|
482
482
|
const parsed = EventFlowInspectInputSchema.parse(args);
|
package/dist/fluent-client.js
CHANGED
|
@@ -170,6 +170,26 @@ export class FluentClientAdapter {
|
|
|
170
170
|
return FluentClientAdapter.unwrapResponse(response);
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Upload (deploy) a workflow JSON to the Fluent environment.
|
|
175
|
+
* PUT /api/v4.1/workflow/{retailerId}
|
|
176
|
+
* Uses PUT for idempotent upsert — replaces the workflow definition
|
|
177
|
+
* rather than creating a new version on every call (which POST does).
|
|
178
|
+
* Write operation — executeOnce (timeout, no retry).
|
|
179
|
+
*
|
|
180
|
+
* NOTE: This does NOT update the CLI workflowlog cache.
|
|
181
|
+
*/
|
|
182
|
+
async uploadWorkflow(retailerId, workflow) {
|
|
183
|
+
const requestClient = this.requireRequestClient("Workflow REST upload API");
|
|
184
|
+
return this.executeOnce("uploadWorkflow", async () => {
|
|
185
|
+
const response = await requestClient.request(`/api/v4.1/workflow/${retailerId}`, {
|
|
186
|
+
method: "PUT",
|
|
187
|
+
headers: { "Content-Type": "application/json" },
|
|
188
|
+
body: workflow,
|
|
189
|
+
});
|
|
190
|
+
return FluentClientAdapter.unwrapResponse(response);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
173
193
|
/**
|
|
174
194
|
* Query Prometheus metrics via GraphQL metricInstant / metricRange queries.
|
|
175
195
|
* The Fluent platform does NOT expose raw Prometheus REST endpoints
|