callman-core 1.31.0 → 1.32.0
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/ai-packs/db-queries.md +1 -1
- package/ai-packs/scenario-nodes.md +33 -14
- package/dist/ai/prompts/scenario.d.ts.map +1 -1
- package/dist/ai/prompts/scenario.js +3 -2
- package/dist/ai/prompts/scenario.js.map +1 -1
- package/dist/ai/prompts/scenarioNodeReference.d.ts.map +1 -1
- package/dist/ai/prompts/scenarioNodeReference.js +56 -15
- package/dist/ai/prompts/scenarioNodeReference.js.map +1 -1
- package/dist/host/db/db-query-reference.js +1 -1
- package/dist/host/db/db-query-reference.js.map +1 -1
- package/dist/host/db/mongoAdapter.d.ts +1 -0
- package/dist/host/db/mongoAdapter.d.ts.map +1 -1
- package/dist/host/db/mongoAdapter.js +21 -0
- package/dist/host/db/mongoAdapter.js.map +1 -1
- package/dist/host/db/queryExecutor.js +2 -2
- package/dist/host/db/queryExecutor.js.map +1 -1
- package/dist/host/index.d.ts +1 -1
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +1 -1
- package/dist/host/index.js.map +1 -1
- package/dist/scenario-runner/adapters/index.d.ts +1 -0
- package/dist/scenario-runner/adapters/index.d.ts.map +1 -1
- package/dist/scenario-runner/adapters/index.js +1 -0
- package/dist/scenario-runner/adapters/index.js.map +1 -1
- package/dist/scenario-runner/adapters/kafka-executor.d.ts +5 -0
- package/dist/scenario-runner/adapters/kafka-executor.d.ts.map +1 -1
- package/dist/scenario-runner/adapters/kafka-executor.js +12 -3
- package/dist/scenario-runner/adapters/kafka-executor.js.map +1 -1
- package/dist/scenario-runner/adapters/types.d.ts +1 -0
- package/dist/scenario-runner/adapters/types.d.ts.map +1 -1
- package/dist/scenario-runner/index.d.ts +3 -0
- package/dist/scenario-runner/index.d.ts.map +1 -1
- package/dist/scenario-runner/index.js +5 -0
- package/dist/scenario-runner/index.js.map +1 -1
- package/dist/scenario-runner/kafkaEvent.d.ts +3 -0
- package/dist/scenario-runner/kafkaEvent.d.ts.map +1 -0
- package/dist/scenario-runner/kafkaEvent.js +18 -0
- package/dist/scenario-runner/kafkaEvent.js.map +1 -0
- package/dist/scenario-runner/nodePolicy.d.ts +8 -1
- package/dist/scenario-runner/nodePolicy.d.ts.map +1 -1
- package/dist/scenario-runner/nodePolicy.js +50 -0
- package/dist/scenario-runner/nodePolicy.js.map +1 -1
- package/dist/scenario-runner/runScenario.d.ts.map +1 -1
- package/dist/scenario-runner/runScenario.js +39 -22
- package/dist/scenario-runner/runScenario.js.map +1 -1
- package/dist/scenario-runner/scenarioReference.d.ts +45 -0
- package/dist/scenario-runner/scenarioReference.d.ts.map +1 -0
- package/dist/scenario-runner/scenarioReference.js +151 -0
- package/dist/scenario-runner/scenarioReference.js.map +1 -0
- package/dist/scenario-runner/types.d.ts +5 -0
- package/dist/scenario-runner/types.d.ts.map +1 -1
- package/dist-cjs/ai/prompts/scenario.js +3 -2
- package/dist-cjs/ai/prompts/scenario.js.map +1 -1
- package/dist-cjs/ai/prompts/scenarioNodeReference.js +56 -15
- package/dist-cjs/ai/prompts/scenarioNodeReference.js.map +1 -1
- package/dist-cjs/host/db/db-query-reference.js +1 -1
- package/dist-cjs/host/db/db-query-reference.js.map +1 -1
- package/dist-cjs/host/db/mongoAdapter.js +23 -1
- package/dist-cjs/host/db/mongoAdapter.js.map +1 -1
- package/dist-cjs/host/db/queryExecutor.js +1 -1
- package/dist-cjs/host/db/queryExecutor.js.map +1 -1
- package/dist-cjs/host/index.js +3 -2
- package/dist-cjs/host/index.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/index.js +9 -3
- package/dist-cjs/scenario-runner/adapters/index.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/kafka-executor.js +15 -4
- package/dist-cjs/scenario-runner/adapters/kafka-executor.js.map +1 -1
- package/dist-cjs/scenario-runner/index.js +21 -1
- package/dist-cjs/scenario-runner/index.js.map +1 -1
- package/dist-cjs/scenario-runner/kafkaEvent.js +22 -0
- package/dist-cjs/scenario-runner/kafkaEvent.js.map +1 -0
- package/dist-cjs/scenario-runner/nodePolicy.js +53 -1
- package/dist-cjs/scenario-runner/nodePolicy.js.map +1 -1
- package/dist-cjs/scenario-runner/runScenario.js +38 -21
- package/dist-cjs/scenario-runner/runScenario.js.map +1 -1
- package/dist-cjs/scenario-runner/scenarioReference.js +159 -0
- package/dist-cjs/scenario-runner/scenarioReference.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.patchScenarioNodeExecutionPolicy = exports.getScenarioNodePolicyBadges = exports.getScenarioNodeMaxAttempts = exports.getScenarioNodeExecutionPolicy = exports.getNewScenarioNodeExecutionPolicyPreset = exports.getLegacyScenarioNodeExecutionPolicy = exports.normalizeScenarioNodeExecutionPolicy = exports.supportsScenarioNodeExecutionPolicy = exports.STRICT_SCENARIO_NODE_EXECUTION_POLICY = void 0;
|
|
3
|
+
exports.patchScenarioNodeExecutionPolicy = exports.getScenarioNodePolicyBadges = exports.getScenarioNodeMaxAttempts = exports.getScenarioNodeExecutionPolicy = exports.getNewScenarioNodeExecutionPolicyPreset = exports.getLegacyScenarioNodeExecutionPolicy = exports.normalizeScenarioNodeExecutionPolicy = exports.supportsScenarioNodeExecutionPolicy = exports.matchScenarioExpectedFailure = exports.supportsScenarioNodeExpectedFailure = exports.SCENARIO_EXPECT_FAILURE_NODE_TYPES = exports.EXPECT_FAILURE_PATTERN_MAX_LENGTH = exports.STRICT_SCENARIO_NODE_EXECUTION_POLICY = void 0;
|
|
4
4
|
exports.STRICT_SCENARIO_NODE_EXECUTION_POLICY = {
|
|
5
5
|
onFailure: "stop",
|
|
6
6
|
retry: {
|
|
@@ -64,6 +64,51 @@ const clonePolicy = (policy) => ({
|
|
|
64
64
|
delayMs: policy.retry.delayMs,
|
|
65
65
|
},
|
|
66
66
|
});
|
|
67
|
+
exports.EXPECT_FAILURE_PATTERN_MAX_LENGTH = 500;
|
|
68
|
+
// Leaf nodes whose own work can fail. Containers (foreach, subscenario,
|
|
69
|
+
// scenario-ref), routing (condition, end), pure data nodes (set-vars,
|
|
70
|
+
// aggregator) and wait have no failure of their own to expect.
|
|
71
|
+
exports.SCENARIO_EXPECT_FAILURE_NODE_TYPES = [
|
|
72
|
+
"request",
|
|
73
|
+
"db",
|
|
74
|
+
"redis",
|
|
75
|
+
"kafka",
|
|
76
|
+
"websocket",
|
|
77
|
+
"script",
|
|
78
|
+
"assertion",
|
|
79
|
+
"poll",
|
|
80
|
+
"ai",
|
|
81
|
+
"notification",
|
|
82
|
+
];
|
|
83
|
+
const supportsScenarioNodeExpectedFailure = (type) => exports.SCENARIO_EXPECT_FAILURE_NODE_TYPES.includes(type);
|
|
84
|
+
exports.supportsScenarioNodeExpectedFailure = supportsScenarioNodeExpectedFailure;
|
|
85
|
+
const normalizeExpectedFailure = (value) => {
|
|
86
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const raw = value.messagePattern;
|
|
90
|
+
const pattern = typeof raw === "string" ? raw.trim().slice(0, exports.EXPECT_FAILURE_PATTERN_MAX_LENGTH) : "";
|
|
91
|
+
return pattern ? { messagePattern: pattern } : {};
|
|
92
|
+
};
|
|
93
|
+
// Whether a failure message satisfies the expectation. An empty expectation
|
|
94
|
+
// accepts any failure; an invalid regex never matches (and says so).
|
|
95
|
+
const matchScenarioExpectedFailure = (expectation, message) => {
|
|
96
|
+
const pattern = expectation.messagePattern?.trim();
|
|
97
|
+
if (!pattern) {
|
|
98
|
+
return { matched: true, mismatchReason: null };
|
|
99
|
+
}
|
|
100
|
+
let re;
|
|
101
|
+
try {
|
|
102
|
+
re = new RegExp(pattern);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return { matched: false, mismatchReason: `invalid expectFailure.messagePattern regex: ${pattern}` };
|
|
106
|
+
}
|
|
107
|
+
return re.test(message)
|
|
108
|
+
? { matched: true, mismatchReason: null }
|
|
109
|
+
: { matched: false, mismatchReason: `the error did not match /${pattern}/` };
|
|
110
|
+
};
|
|
111
|
+
exports.matchScenarioExpectedFailure = matchScenarioExpectedFailure;
|
|
67
112
|
const supportsScenarioNodeExecutionPolicy = (nodeOrType) => {
|
|
68
113
|
const type = typeof nodeOrType === "string" ? nodeOrType : nodeOrType.type;
|
|
69
114
|
return type !== "condition";
|
|
@@ -108,6 +153,9 @@ const normalizeScenarioNodeExecutionPolicy = (value, fallback = exports.STRICT_S
|
|
|
108
153
|
const maxDelayMs = retryEnabled && backoffMultiplier && typeof retryMaxDelayRaw === "number" && retryMaxDelayRaw > 0
|
|
109
154
|
? Math.max(delayMs, Math.round(retryMaxDelayRaw))
|
|
110
155
|
: undefined;
|
|
156
|
+
const expectFailure = typeof value === "object" && value !== null && "expectFailure" in value
|
|
157
|
+
? normalizeExpectedFailure(value.expectFailure)
|
|
158
|
+
: undefined;
|
|
111
159
|
return {
|
|
112
160
|
onFailure: normalizedOnFailure,
|
|
113
161
|
retry: {
|
|
@@ -117,6 +165,7 @@ const normalizeScenarioNodeExecutionPolicy = (value, fallback = exports.STRICT_S
|
|
|
117
165
|
...(backoffMultiplier ? { backoffMultiplier } : {}),
|
|
118
166
|
...(maxDelayMs ? { maxDelayMs } : {}),
|
|
119
167
|
},
|
|
168
|
+
...(expectFailure ? { expectFailure } : {}),
|
|
120
169
|
};
|
|
121
170
|
};
|
|
122
171
|
exports.normalizeScenarioNodeExecutionPolicy = normalizeScenarioNodeExecutionPolicy;
|
|
@@ -140,6 +189,9 @@ const getScenarioNodePolicyBadges = (node) => {
|
|
|
140
189
|
if (policy.retry.enabled) {
|
|
141
190
|
badges.push(`Retry ×${(0, exports.getScenarioNodeMaxAttempts)(policy)}`);
|
|
142
191
|
}
|
|
192
|
+
if (policy.expectFailure && (0, exports.supportsScenarioNodeExpectedFailure)(node.type)) {
|
|
193
|
+
badges.push("Expects failure");
|
|
194
|
+
}
|
|
143
195
|
return badges;
|
|
144
196
|
};
|
|
145
197
|
exports.getScenarioNodePolicyBadges = getScenarioNodePolicyBadges;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodePolicy.js","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"nodePolicy.js","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ const graphTraversal_js_1 = require("./graphTraversal.js");
|
|
|
9
9
|
const websocket_js_1 = require("./websocket.js");
|
|
10
10
|
const executionPolicyRunner_js_1 = require("./executionPolicyRunner.js");
|
|
11
11
|
const boundSnapshot_js_1 = require("./boundSnapshot.js");
|
|
12
|
+
const kafkaEvent_js_1 = require("./kafkaEvent.js");
|
|
12
13
|
const nodePolicy_js_1 = require("./nodePolicy.js");
|
|
13
14
|
const templateResolver_js_1 = require("./templateResolver.js");
|
|
14
15
|
const waitNodeExecutor_js_1 = require("./waitNodeExecutor.js");
|
|
@@ -25,6 +26,11 @@ class ScenarioNodeFailureError extends Error {
|
|
|
25
26
|
this.name = "ScenarioNodeFailureError";
|
|
26
27
|
}
|
|
27
28
|
}
|
|
29
|
+
// An attempt that succeeded although the node's policy expects a failure.
|
|
30
|
+
// Kept apart from ordinary failures so it is never mistaken for the
|
|
31
|
+
// expected one.
|
|
32
|
+
class ScenarioExpectedFailureNotMetError extends ScenarioNodeFailureError {
|
|
33
|
+
}
|
|
28
34
|
const DEFAULT_MIN_NODE_VISUAL_STATE_MS = 180;
|
|
29
35
|
const createId = (prefix) => {
|
|
30
36
|
const randomUuid = globalThis.crypto?.randomUUID?.();
|
|
@@ -125,24 +131,6 @@ const createContextSnapshot = (context, mode = "full") => {
|
|
|
125
131
|
redisResult: bound(context.redisResult),
|
|
126
132
|
};
|
|
127
133
|
};
|
|
128
|
-
const buildKafkaEventValue = (message) => {
|
|
129
|
-
const fallbackValue = {
|
|
130
|
-
value: message.valueJson ?? message.valueText,
|
|
131
|
-
text: message.valueText,
|
|
132
|
-
key: message.key,
|
|
133
|
-
partition: message.partition,
|
|
134
|
-
offset: message.offset,
|
|
135
|
-
timestamp: message.timestamp,
|
|
136
|
-
headers: Object.fromEntries(message.headers.map((header) => [header.key, header.value])),
|
|
137
|
-
};
|
|
138
|
-
if (isRecord(message.valueJson)) {
|
|
139
|
-
return {
|
|
140
|
-
...message.valueJson,
|
|
141
|
-
meta: fallbackValue,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
return fallbackValue;
|
|
145
|
-
};
|
|
146
134
|
const buildKafkaFailureMessage = (result, usedMatch) => {
|
|
147
135
|
if (result.errorMessage?.trim()) {
|
|
148
136
|
return result.errorMessage;
|
|
@@ -867,6 +855,16 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
867
855
|
retry: { enabled: false, maxAttempts: 0, delayMs: 0 },
|
|
868
856
|
};
|
|
869
857
|
}
|
|
858
|
+
// Negative test: this node must fail. On a db node a non-empty
|
|
859
|
+
// expectError is the more precise expectation and wins.
|
|
860
|
+
const dbExpectsError = node.type === "db" &&
|
|
861
|
+
Boolean(node.data.config.expectError?.sqlState?.trim() ||
|
|
862
|
+
node.data.config.expectError?.messagePattern?.trim());
|
|
863
|
+
const expectedFailure = executionPolicy.expectFailure &&
|
|
864
|
+
(0, nodePolicy_js_1.supportsScenarioNodeExpectedFailure)(node.type) &&
|
|
865
|
+
!dbExpectsError
|
|
866
|
+
? executionPolicy.expectFailure
|
|
867
|
+
: undefined;
|
|
870
868
|
const executionStartedAtMs = Date.now();
|
|
871
869
|
let inputData = createInputSnapshot(runtimeContext);
|
|
872
870
|
// The node's OWN resolved input (query + params, topic + payload, the
|
|
@@ -1515,7 +1513,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1515
1513
|
if (resolvedMatchMode === "rules" && rules.length > 0) {
|
|
1516
1514
|
matchedMessage =
|
|
1517
1515
|
captureResult.messages.find((message) => {
|
|
1518
|
-
const kafkaEventValue =
|
|
1516
|
+
const kafkaEventValue = (0, kafkaEvent_js_1.buildScenarioKafkaEventValue)(message, captureResult.topic);
|
|
1519
1517
|
const scopedValues = (0, templateResolver_js_1.buildScenarioTemplateValues)({
|
|
1520
1518
|
environment: runtimeContext.environment,
|
|
1521
1519
|
globals: runtimeContext.globals,
|
|
@@ -1534,7 +1532,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1534
1532
|
throw new ScenarioNodeFailureError(buildKafkaFailureMessage(captureResult, Boolean(rules.length)));
|
|
1535
1533
|
}
|
|
1536
1534
|
runtimeContext.kafkaCapture = captureResult;
|
|
1537
|
-
runtimeContext.kafkaEvent =
|
|
1535
|
+
runtimeContext.kafkaEvent = (0, kafkaEvent_js_1.buildScenarioKafkaEventValue)(matchedMessage, captureResult.topic);
|
|
1538
1536
|
outputData = runtimeContext.kafkaEvent;
|
|
1539
1537
|
}
|
|
1540
1538
|
}
|
|
@@ -2228,15 +2226,34 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
2228
2226
|
runtimeContext.workflowContext[nodeLabel] = workflowOutput;
|
|
2229
2227
|
}
|
|
2230
2228
|
await ensureMinimumVisualDuration(attemptStartedAtMs);
|
|
2229
|
+
if (expectedFailure) {
|
|
2230
|
+
throw new ScenarioExpectedFailureNotMetError(`Expected this node to fail${expectedFailure.messagePattern
|
|
2231
|
+
? ` with an error matching /${expectedFailure.messagePattern}/`
|
|
2232
|
+
: ""}, but it succeeded.`);
|
|
2233
|
+
}
|
|
2231
2234
|
}
|
|
2232
2235
|
catch (error) {
|
|
2233
2236
|
if (error instanceof ScenarioStopError) {
|
|
2234
2237
|
throw error;
|
|
2235
2238
|
}
|
|
2236
2239
|
await ensureMinimumVisualDuration(attemptStartedAtMs);
|
|
2237
|
-
|
|
2240
|
+
const failure = error instanceof ScenarioNodeFailureError
|
|
2238
2241
|
? error
|
|
2239
2242
|
: new ScenarioNodeFailureError(error instanceof Error ? error.message : "Scenario node failed");
|
|
2243
|
+
if (expectedFailure && !(failure instanceof ScenarioExpectedFailureNotMetError)) {
|
|
2244
|
+
const match = (0, nodePolicy_js_1.matchScenarioExpectedFailure)(expectedFailure, failure.message);
|
|
2245
|
+
if (!match.matched) {
|
|
2246
|
+
throw new ScenarioNodeFailureError(`The node failed, but not as expected (${match.mismatchReason}): ${failure.message}`);
|
|
2247
|
+
}
|
|
2248
|
+
// The failure IS the result: the node succeeds and exposes it.
|
|
2249
|
+
outputData = { expectedFailure: { message: failure.message } };
|
|
2250
|
+
workflowOutput = outputData;
|
|
2251
|
+
if (nodeLabel && !RESERVED_WORKFLOW_ROOT_LABELS.has(nodeLabel)) {
|
|
2252
|
+
runtimeContext.workflowContext[nodeLabel] = workflowOutput;
|
|
2253
|
+
}
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
throw failure;
|
|
2240
2257
|
}
|
|
2241
2258
|
};
|
|
2242
2259
|
try {
|