@ductape/sdk 0.1.110 → 0.1.114
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/api/services/processorApi.service.d.ts +2 -0
- package/dist/api/services/processorApi.service.js +51 -0
- package/dist/api/services/processorApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +7 -1
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/urls.d.ts +1 -0
- package/dist/api/urls.js +5 -4
- package/dist/api/urls.js.map +1 -1
- package/dist/context/execution-context.d.ts +37 -0
- package/dist/context/execution-context.js +38 -0
- package/dist/context/execution-context.js.map +1 -0
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.js +18 -0
- package/dist/context/index.js.map +1 -0
- package/dist/database/adapters/mongodb.adapter.js +7 -7
- package/dist/database/adapters/mongodb.adapter.js.map +1 -1
- package/dist/database/databases.service.d.ts +4 -0
- package/dist/database/databases.service.js +7 -1
- package/dist/database/databases.service.js.map +1 -1
- package/dist/features/feature-executor.d.ts +19 -0
- package/dist/features/feature-executor.js +330 -98
- package/dist/features/feature-executor.js.map +1 -1
- package/dist/features/features.service.d.ts +21 -1
- package/dist/features/features.service.js +136 -33
- package/dist/features/features.service.js.map +1 -1
- package/dist/features/index.d.ts +2 -1
- package/dist/features/index.js +3 -1
- package/dist/features/index.js.map +1 -1
- package/dist/features/types/features.types.d.ts +17 -2
- package/dist/features/types/features.types.js.map +1 -1
- package/dist/functions/functions.runtime.d.ts +25 -0
- package/dist/functions/functions.runtime.js +278 -0
- package/dist/functions/functions.runtime.js.map +1 -0
- package/dist/functions/http-handler.d.ts +17 -0
- package/dist/functions/http-handler.js +51 -0
- package/dist/functions/http-handler.js.map +1 -0
- package/dist/functions/index.d.ts +3 -0
- package/dist/functions/index.js +20 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/functions/types.d.ts +100 -0
- package/dist/functions/types.js +15 -0
- package/dist/functions/types.js.map +1 -0
- package/dist/graph/graphs.service.d.ts +1 -1
- package/dist/graph/graphs.service.js +73 -43
- package/dist/graph/graphs.service.js.map +1 -1
- package/dist/graph/types/traversal.interface.d.ts +2 -0
- package/dist/index.d.ts +18 -2
- package/dist/index.js +27 -3
- package/dist/index.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +6 -0
- package/dist/processor/services/processor.service.js +8 -13
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/products/bootstrap-cache.js +7 -2
- package/dist/products/bootstrap-cache.js.map +1 -1
- package/dist/products/services/products.service.d.ts +2 -2
- package/dist/products/services/products.service.js +36 -1
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/sessions/sessions.helper.js +13 -1
- package/dist/sessions/sessions.helper.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/processor.types.d.ts +15 -0
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +3 -0
- package/dist/types/productsBuilder.types.js +2 -0
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/vector/vector-database.service.d.ts +2 -0
- package/dist/vector/vector-database.service.js +21 -12
- package/dist/vector/vector-database.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
|
-
var _a, _b;
|
|
14
|
+
var _a, _b, _c, _d;
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.FeatureExecutor = void 0;
|
|
16
|
+
exports.FeatureExecutor = exports.UnresolvedInputReferenceError = void 0;
|
|
17
17
|
const crypto_1 = require("crypto");
|
|
18
18
|
const processor_service_1 = __importDefault(require("../processor/services/processor.service"));
|
|
19
19
|
const products_service_1 = __importDefault(require("../products/services/products.service"));
|
|
@@ -32,12 +32,24 @@ const inputs_types_1 = require("../types/inputs.types");
|
|
|
32
32
|
const processor_utils_1 = require("../processor/utils/processor.utils");
|
|
33
33
|
const productsBuilder_types_1 = require("../types/productsBuilder.types");
|
|
34
34
|
const date_fns_1 = require("date-fns");
|
|
35
|
+
const functions_1 = require("../functions");
|
|
36
|
+
const context_1 = require("../context");
|
|
37
|
+
class UnresolvedInputReferenceError extends Error {
|
|
38
|
+
constructor(reference, required) {
|
|
39
|
+
super(`Runtime input reference ${reference} is absent${required ? ' but required by the feature contract' : ''}.`);
|
|
40
|
+
this.reference = reference;
|
|
41
|
+
this.required = required;
|
|
42
|
+
this.code = 'UNRESOLVED_INPUT_REFERENCE';
|
|
43
|
+
this.name = 'UnresolvedInputReferenceError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.UnresolvedInputReferenceError = UnresolvedInputReferenceError;
|
|
35
47
|
/** Only log when DUCTAPE_DEBUG is set to avoid sync I/O and serialization cost in hot path */
|
|
36
48
|
const debugLog = typeof process !== 'undefined' && (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DUCTAPE_DEBUG) === 'true' || ((_b = process.env) === null || _b === void 0 ? void 0 : _b.DUCTAPE_DEBUG) === '1')
|
|
37
49
|
? (...args) => console.log(...args)
|
|
38
50
|
: () => { };
|
|
39
|
-
/**
|
|
40
|
-
const stepLog = typeof process !== 'undefined'
|
|
51
|
+
/** Detailed step logging is opt-in; synchronous stdout is expensive in server runtimes. */
|
|
52
|
+
const stepLog = typeof process !== 'undefined' && (((_c = process.env) === null || _c === void 0 ? void 0 : _c.DUCTAPE_DEBUG) === 'true' || ((_d = process.env) === null || _d === void 0 ? void 0 : _d.DUCTAPE_DEBUG) === '1')
|
|
41
53
|
? (msg, data) => {
|
|
42
54
|
if (data != null && Object.keys(data).length > 0) {
|
|
43
55
|
console.log(`[FeatureExecutor] ${msg}`, data);
|
|
@@ -47,6 +59,39 @@ const stepLog = typeof process !== 'undefined'
|
|
|
47
59
|
}
|
|
48
60
|
}
|
|
49
61
|
: () => { };
|
|
62
|
+
const SENSITIVE_LOG_KEY = /(?:authorization|cookie|password|passwd|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret|session)/i;
|
|
63
|
+
const MAX_LOG_STRING_LENGTH = 2000;
|
|
64
|
+
/** Produce useful payload traces without leaking credentials or exploding logs. */
|
|
65
|
+
const sanitizeForLog = (value, key = '', seen = new WeakSet()) => {
|
|
66
|
+
if (key !== 'has_session' && SENSITIVE_LOG_KEY.test(key))
|
|
67
|
+
return '[REDACTED]';
|
|
68
|
+
if (value == null || typeof value === 'number' || typeof value === 'boolean')
|
|
69
|
+
return value;
|
|
70
|
+
if (typeof value === 'bigint')
|
|
71
|
+
return value.toString();
|
|
72
|
+
if (typeof value === 'string') {
|
|
73
|
+
return value.length > MAX_LOG_STRING_LENGTH
|
|
74
|
+
? `${value.slice(0, MAX_LOG_STRING_LENGTH)}...[truncated ${value.length - MAX_LOG_STRING_LENGTH} chars]`
|
|
75
|
+
: value;
|
|
76
|
+
}
|
|
77
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
|
|
78
|
+
return `[Buffer ${value.length} bytes]`;
|
|
79
|
+
}
|
|
80
|
+
if (value instanceof Error)
|
|
81
|
+
return { name: value.name, message: value.message, stack: value.stack };
|
|
82
|
+
if (Array.isArray(value))
|
|
83
|
+
return value.map((item) => sanitizeForLog(item, key, seen));
|
|
84
|
+
if (typeof value === 'object') {
|
|
85
|
+
if (seen.has(value))
|
|
86
|
+
return '[Circular]';
|
|
87
|
+
seen.add(value);
|
|
88
|
+
return Object.fromEntries(Object.entries(value).map(([nestedKey, nestedValue]) => [
|
|
89
|
+
nestedKey,
|
|
90
|
+
sanitizeForLog(nestedValue, nestedKey, seen),
|
|
91
|
+
]));
|
|
92
|
+
}
|
|
93
|
+
return String(value);
|
|
94
|
+
};
|
|
50
95
|
/** Observability must not disappear because a successful result contains BigInt or cycles. */
|
|
51
96
|
const stringifyProcessorValue = (value) => {
|
|
52
97
|
const seen = new WeakSet();
|
|
@@ -115,6 +160,9 @@ class FeatureExecutor {
|
|
|
115
160
|
this.graphConnectionUsed = false;
|
|
116
161
|
/** Pre-fetched bootstrap data per step tag (feature batch prefetch). */
|
|
117
162
|
this.stepBootstrapCache = new Map();
|
|
163
|
+
this.functionInvocations = new Map();
|
|
164
|
+
/** Step telemetry is accumulated and persisted with the terminal feature record in one round trip. */
|
|
165
|
+
this.pendingProcessorResults = [];
|
|
118
166
|
debugLog('[FeatureExecutor] constructor ENTRY', {
|
|
119
167
|
feature_tag: feature.tag,
|
|
120
168
|
product: options.product,
|
|
@@ -123,6 +171,7 @@ class FeatureExecutor {
|
|
|
123
171
|
});
|
|
124
172
|
this.config = config;
|
|
125
173
|
this.feature = feature;
|
|
174
|
+
this.inheritedSession = options.session;
|
|
126
175
|
this.sessionLogFields = sessionLogFields || {};
|
|
127
176
|
this._privateKey = private_key || '';
|
|
128
177
|
this.preInitializedProduct = Boolean(preInitializedBuilder);
|
|
@@ -158,8 +207,26 @@ class FeatureExecutor {
|
|
|
158
207
|
feature_id: this.state.feature_id,
|
|
159
208
|
feature_tag: this.state.feature_tag,
|
|
160
209
|
steps_count: (_b = (_a = feature.steps) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
|
|
210
|
+
has_session: Boolean(this.inheritedSession),
|
|
211
|
+
input: sanitizeForLog(options.input),
|
|
161
212
|
});
|
|
162
213
|
}
|
|
214
|
+
/** Debug-only structured execution trace. Payloads are recursively redacted. */
|
|
215
|
+
trace(stage, payload = {}) {
|
|
216
|
+
debugLog('[FeatureExecutor][trace]', sanitizeForLog(Object.assign({ stage, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product: this.state.product, env: this.state.env, has_session: Boolean(this.inheritedSession) }, payload)));
|
|
217
|
+
}
|
|
218
|
+
/** Brokers expose the same session as separate tag/token fields. */
|
|
219
|
+
inheritedBrokerSession() {
|
|
220
|
+
if (!this.inheritedSession)
|
|
221
|
+
return undefined;
|
|
222
|
+
const separator = this.inheritedSession.indexOf(':');
|
|
223
|
+
if (separator < 1)
|
|
224
|
+
return undefined;
|
|
225
|
+
return {
|
|
226
|
+
tag: this.inheritedSession.slice(0, separator),
|
|
227
|
+
token: this.inheritedSession.slice(separator + 1),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
163
230
|
/**
|
|
164
231
|
* Get auth payload for API calls
|
|
165
232
|
*/
|
|
@@ -190,6 +257,10 @@ class FeatureExecutor {
|
|
|
190
257
|
access_key: this.config.access_key,
|
|
191
258
|
preInitializedProductBuilder: this.productBuilder,
|
|
192
259
|
});
|
|
260
|
+
this._processorService.setFeatureExecutionContext({
|
|
261
|
+
feature_id: this.state.feature_id,
|
|
262
|
+
feature_tag: this.state.feature_tag,
|
|
263
|
+
});
|
|
193
264
|
}
|
|
194
265
|
return this._processorService;
|
|
195
266
|
}
|
|
@@ -204,6 +275,7 @@ class FeatureExecutor {
|
|
|
204
275
|
env_type: this.config.env_type,
|
|
205
276
|
private_key: this._privateKey,
|
|
206
277
|
access_key: this.config.access_key,
|
|
278
|
+
redis_client: this.config.redis_client,
|
|
207
279
|
});
|
|
208
280
|
}
|
|
209
281
|
return this._graphService;
|
|
@@ -219,6 +291,8 @@ class FeatureExecutor {
|
|
|
219
291
|
env_type: this.config.env_type,
|
|
220
292
|
private_key: this._privateKey,
|
|
221
293
|
access_key: this.config.access_key,
|
|
294
|
+
redis_client: this.config.redis_client,
|
|
295
|
+
preInitializedProductBuilder: this.productBuilder,
|
|
222
296
|
});
|
|
223
297
|
}
|
|
224
298
|
return this._databaseService;
|
|
@@ -322,23 +396,10 @@ class FeatureExecutor {
|
|
|
322
396
|
const resultStr = stringifyProcessorValue(resultData);
|
|
323
397
|
const inputStr = stringifyProcessorValue(inputPayload);
|
|
324
398
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
325
|
-
const processorResult = {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
component: types_1.LogEventTypes.FEATURE,
|
|
330
|
-
status,
|
|
331
|
-
start: this.state.started_at,
|
|
332
|
-
end: Date.now(),
|
|
333
|
-
retryable: true,
|
|
334
|
-
result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr,
|
|
335
|
-
input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr,
|
|
336
|
-
feature_id: this.state.feature_id,
|
|
337
|
-
feature_tag: this.state.feature_tag,
|
|
338
|
-
product_tag: this.state.product,
|
|
339
|
-
workspace_id: this.config.workspace_id,
|
|
340
|
-
};
|
|
341
|
-
await this.processorApiService.saveResult(processorResult, this.getAuthPayload());
|
|
399
|
+
const processorResult = Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), { process_id: this.state.feature_id, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE, status, start: this.state.started_at, end: Date.now(), retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr, input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product_tag: this.state.product, workspace_id: this.config.workspace_id });
|
|
400
|
+
this.trace('execution.persistence.sent', { status, payload: resultData });
|
|
401
|
+
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), processorResult], this.getAuthPayload());
|
|
402
|
+
this.trace('execution.persistence.acknowledged', { status, process_id: this.state.feature_id });
|
|
342
403
|
debugLog('[FeatureExecutor] persistExecutionResult SUCCESS', { feature_id: this.state.feature_id, status });
|
|
343
404
|
}
|
|
344
405
|
catch (err) {
|
|
@@ -374,6 +435,7 @@ class FeatureExecutor {
|
|
|
374
435
|
* Processor results for steps always have component: 'feature_step' and step_type set to the step kind.
|
|
375
436
|
*/
|
|
376
437
|
async persistStepResult(step, status, output, error, duration, input) {
|
|
438
|
+
var _a;
|
|
377
439
|
const resolvedInput = input !== null && input !== void 0 ? input : step.input;
|
|
378
440
|
const stepType = this.getStepTypeForResult(step);
|
|
379
441
|
debugLog('[FeatureExecutor] persistStepResult ENTRY', {
|
|
@@ -394,27 +456,17 @@ class FeatureExecutor {
|
|
|
394
456
|
const resultStr = stringifyProcessorValue(value);
|
|
395
457
|
const inputStr = stringifyProcessorValue(resolvedInput);
|
|
396
458
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
397
|
-
const stepResult = {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
env: this.state.env,
|
|
401
|
-
component: types_1.LogEventTypes.FEATURE_STEP, // step results always feature_step
|
|
402
|
-
status,
|
|
403
|
-
start: Date.now() - (duration || 0),
|
|
404
|
-
end: Date.now(),
|
|
405
|
-
retryable: true,
|
|
406
|
-
result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr,
|
|
407
|
-
input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr,
|
|
408
|
-
feature_id: this.state.feature_id,
|
|
409
|
-
feature_tag: this.state.feature_tag,
|
|
410
|
-
product_tag: this.state.product,
|
|
411
|
-
workspace_id: this.config.workspace_id,
|
|
459
|
+
const stepResult = Object.assign(Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), { process_id: stepProcessId, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE_STEP, // step results always feature_step
|
|
460
|
+
status, start: Date.now() - (duration || 0), end: Date.now(), retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr, input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product_tag: this.state.product, workspace_id: this.config.workspace_id, step_tag: step.tag, step_type: stepType, step_error: error, step_duration_ms: duration }), ((_a = this.functionInvocations.get(step.tag)) !== null && _a !== void 0 ? _a : {}));
|
|
461
|
+
this.trace('step.persistence.sent', {
|
|
412
462
|
step_tag: step.tag,
|
|
413
|
-
step_type: stepType,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
463
|
+
step_type: stepType,
|
|
464
|
+
status,
|
|
465
|
+
input: resolvedInput,
|
|
466
|
+
output: value,
|
|
467
|
+
});
|
|
468
|
+
this.pendingProcessorResults.push(stepResult);
|
|
469
|
+
this.trace('step.persistence.queued', { step_tag: step.tag, status, process_id: stepProcessId });
|
|
418
470
|
debugLog('[FeatureExecutor] persistStepResult SUCCESS', { feature_id: this.state.feature_id, step_tag: step.tag });
|
|
419
471
|
}
|
|
420
472
|
catch (err) {
|
|
@@ -467,7 +519,26 @@ class FeatureExecutor {
|
|
|
467
519
|
* Execute the feature
|
|
468
520
|
*/
|
|
469
521
|
async execute() {
|
|
470
|
-
var _a
|
|
522
|
+
var _a;
|
|
523
|
+
const context = (0, context_1.createExecutionContext)({
|
|
524
|
+
kind: 'feature',
|
|
525
|
+
workspace_id: this.config.workspace_id,
|
|
526
|
+
product_id: (_a = this.productId) !== null && _a !== void 0 ? _a : undefined,
|
|
527
|
+
product_tag: this.state.product,
|
|
528
|
+
env: this.state.env,
|
|
529
|
+
feature_id: this.state.feature_id,
|
|
530
|
+
feature_tag: this.state.feature_tag,
|
|
531
|
+
feature_run_id: this.state.feature_id,
|
|
532
|
+
process_id: this.state.feature_id,
|
|
533
|
+
session: this.inheritedSession,
|
|
534
|
+
session_id: this.sessionLogFields.session_id,
|
|
535
|
+
session_tag: this.sessionLogFields.session_tag,
|
|
536
|
+
session_user_id: this.sessionLogFields.session_user_id,
|
|
537
|
+
});
|
|
538
|
+
return (0, context_1.runWithExecutionContext)(context, () => this.executeInContext());
|
|
539
|
+
}
|
|
540
|
+
async executeInContext() {
|
|
541
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
471
542
|
const startTime = Date.now();
|
|
472
543
|
debugLog('[FeatureExecutor] execute ENTRY', {
|
|
473
544
|
feature_id: this.state.feature_id,
|
|
@@ -475,6 +546,10 @@ class FeatureExecutor {
|
|
|
475
546
|
product: this.state.product,
|
|
476
547
|
env: this.state.env,
|
|
477
548
|
});
|
|
549
|
+
this.trace('execution.started', {
|
|
550
|
+
input: this.state.input,
|
|
551
|
+
configured_steps: (_a = this.feature.steps) === null || _a === void 0 ? void 0 : _a.map((step) => ({ tag: step.tag, type: step.type, input: step.input })),
|
|
552
|
+
});
|
|
478
553
|
try {
|
|
479
554
|
// Track phase so failures before first step are reported as (initialization)
|
|
480
555
|
this.state.current_step = '(initialization)';
|
|
@@ -487,6 +562,7 @@ class FeatureExecutor {
|
|
|
487
562
|
this.productId = this.productBuilder.fetchProductId();
|
|
488
563
|
}
|
|
489
564
|
debugLog('[FeatureExecutor] execute product initialized', { feature_id: this.state.feature_id, product_id: this.productId });
|
|
565
|
+
this.trace('product.fetched', { product_id: this.productId, preinitialized: this.preInitializedProduct });
|
|
490
566
|
// Initialize logging after we have product ID
|
|
491
567
|
this.initializeLogging();
|
|
492
568
|
this.state.status = types_1.FeatureStatus.RUNNING;
|
|
@@ -507,14 +583,17 @@ class FeatureExecutor {
|
|
|
507
583
|
}
|
|
508
584
|
catch (prefetchErr) {
|
|
509
585
|
stepLog('Bootstrap prefetch failed (continuing without prefetch)', {
|
|
510
|
-
error: (
|
|
586
|
+
error: (_b = prefetchErr === null || prefetchErr === void 0 ? void 0 : prefetchErr.message) !== null && _b !== void 0 ? _b : String(prefetchErr),
|
|
511
587
|
});
|
|
512
588
|
this.stepBootstrapCache.clear();
|
|
513
589
|
}
|
|
514
590
|
// Execute each step
|
|
515
591
|
for (const step of orderedSteps) {
|
|
516
592
|
// Check step condition if present
|
|
517
|
-
|
|
593
|
+
const conditionMet = step.condition ? await this.evaluateCondition(step.condition) : true;
|
|
594
|
+
if (step.condition)
|
|
595
|
+
this.trace('step.condition.evaluated', { step_tag: step.tag, condition: step.condition, result: conditionMet });
|
|
596
|
+
if (!conditionMet) {
|
|
518
597
|
debugLog('[FeatureExecutor] execute step SKIPPED (condition)', { feature_id: this.state.feature_id, step_tag: step.tag });
|
|
519
598
|
this.logStepEvent(step, `Step ${step.tag} - skipped (condition not met)`, logs_types_1.LogEventStatus.SUCCESS, { skipped: true });
|
|
520
599
|
continue; // Skip step if condition not met
|
|
@@ -535,8 +614,8 @@ class FeatureExecutor {
|
|
|
535
614
|
success: result.success,
|
|
536
615
|
durationMs: result.duration,
|
|
537
616
|
hasError: !!result.error,
|
|
538
|
-
input: result.input,
|
|
539
|
-
output: result.output,
|
|
617
|
+
input: sanitizeForLog(result.input),
|
|
618
|
+
output: sanitizeForLog(result.output),
|
|
540
619
|
});
|
|
541
620
|
// Log step completion
|
|
542
621
|
this.logStepEvent(step, result.success ? `Step ${step.tag} - completed` : `Step ${step.tag} - failed`, result.success ? logs_types_1.LogEventStatus.SUCCESS : logs_types_1.LogEventStatus.FAIL, { duration: result.duration, error: result.error });
|
|
@@ -548,14 +627,14 @@ class FeatureExecutor {
|
|
|
548
627
|
try {
|
|
549
628
|
stepReturnValue = await this.resolveInput(outputSchema, result.output);
|
|
550
629
|
}
|
|
551
|
-
catch (
|
|
630
|
+
catch (_q) {
|
|
552
631
|
stepReturnValue = result.output;
|
|
553
632
|
}
|
|
554
633
|
}
|
|
555
634
|
else if (!result.success) {
|
|
556
635
|
stepReturnValue = undefined;
|
|
557
636
|
}
|
|
558
|
-
|
|
637
|
+
debugLog(`[FeatureExecutor] Step "${step.tag}" output:`, stepReturnValue);
|
|
559
638
|
// Persist step result to backend (use step return shape, not raw primitive)
|
|
560
639
|
await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValue, result.error, result.duration, result.input);
|
|
561
640
|
this.state.step_timings.push({
|
|
@@ -565,22 +644,22 @@ class FeatureExecutor {
|
|
|
565
644
|
});
|
|
566
645
|
if (!result.success) {
|
|
567
646
|
this.state.failed_step = step.tag;
|
|
568
|
-
stepLog('Step failed', { tag: step.tag, error: result.error, allow_fail: (
|
|
647
|
+
stepLog('Step failed', { tag: step.tag, error: result.error, allow_fail: (_c = step.options) === null || _c === void 0 ? void 0 : _c.allow_fail, optional: (_d = step.options) === null || _d === void 0 ? void 0 : _d.optional });
|
|
569
648
|
debugLog('[FeatureExecutor] execute step FAILED', {
|
|
570
649
|
feature_id: this.state.feature_id,
|
|
571
650
|
step_tag: step.tag,
|
|
572
651
|
error: result.error,
|
|
573
|
-
allow_fail: (
|
|
574
|
-
optional: (
|
|
652
|
+
allow_fail: (_e = step.options) === null || _e === void 0 ? void 0 : _e.allow_fail,
|
|
653
|
+
optional: (_f = step.options) === null || _f === void 0 ? void 0 : _f.optional,
|
|
575
654
|
});
|
|
576
655
|
// Check if step allows failure
|
|
577
|
-
if ((
|
|
656
|
+
if ((_g = step.options) === null || _g === void 0 ? void 0 : _g.allow_fail) {
|
|
578
657
|
// Store error but continue
|
|
579
658
|
this.state.steps[step.tag] = { error: result.error };
|
|
580
659
|
continue;
|
|
581
660
|
}
|
|
582
661
|
// Check if step is optional
|
|
583
|
-
if ((
|
|
662
|
+
if ((_h = step.options) === null || _h === void 0 ? void 0 : _h.optional) {
|
|
584
663
|
// Don't trigger rollback, just continue
|
|
585
664
|
continue;
|
|
586
665
|
}
|
|
@@ -592,7 +671,7 @@ class FeatureExecutor {
|
|
|
592
671
|
feature_id: this.state.feature_id,
|
|
593
672
|
success: rollbackResult.success,
|
|
594
673
|
rolled_back_steps: rollbackResult.rolled_back_steps,
|
|
595
|
-
failed_rollbacks: (
|
|
674
|
+
failed_rollbacks: (_k = (_j = rollbackResult.failed_steps) === null || _j === void 0 ? void 0 : _j.length) !== null && _k !== void 0 ? _k : 0,
|
|
596
675
|
});
|
|
597
676
|
// Persist failed feature result
|
|
598
677
|
await this.persistExecutionResult(types_1.LogEventStatus.FAIL, undefined, result.error);
|
|
@@ -603,7 +682,7 @@ class FeatureExecutor {
|
|
|
603
682
|
completed_steps: this.state.completed_steps,
|
|
604
683
|
step_timings: this.state.step_timings,
|
|
605
684
|
});
|
|
606
|
-
await ((
|
|
685
|
+
await ((_l = this.logService) === null || _l === void 0 ? void 0 : _l.publish());
|
|
607
686
|
if (this.graphConnectionUsed) {
|
|
608
687
|
await this.getGraphService().disconnect().catch(() => { });
|
|
609
688
|
await this.getProcessorService().disconnectBrokerConnections().catch(() => { });
|
|
@@ -637,6 +716,7 @@ class FeatureExecutor {
|
|
|
637
716
|
this.state.ended_at = Date.now();
|
|
638
717
|
// Determine output - use last step output or aggregate (resolves $ operators)
|
|
639
718
|
const output = await this.determineWorkflowOutput();
|
|
719
|
+
this.trace('execution.output.resolved', { output, completed_steps: this.state.completed_steps });
|
|
640
720
|
stepLog('Run finished (completed)', {
|
|
641
721
|
status: types_1.FeatureStatus.COMPLETED,
|
|
642
722
|
completed_steps: this.state.completed_steps,
|
|
@@ -652,7 +732,7 @@ class FeatureExecutor {
|
|
|
652
732
|
// Persist successful feature result
|
|
653
733
|
await this.persistExecutionResult(types_1.LogEventStatus.SUCCESS, output);
|
|
654
734
|
// Fire-and-forget log publish on success so we don't block on log upload
|
|
655
|
-
(
|
|
735
|
+
(_m = this.logService) === null || _m === void 0 ? void 0 : _m.publish().catch(() => { });
|
|
656
736
|
if (this.graphConnectionUsed) {
|
|
657
737
|
await this.getGraphService().disconnect().catch(() => { });
|
|
658
738
|
await this.getProcessorService().disconnectBrokerConnections().catch(() => { });
|
|
@@ -675,8 +755,9 @@ class FeatureExecutor {
|
|
|
675
755
|
this.state.status = types_1.FeatureStatus.FAILED;
|
|
676
756
|
this.state.ended_at = Date.now();
|
|
677
757
|
const details = formatErrorDetails(error);
|
|
678
|
-
const failedAt = (
|
|
679
|
-
debugLog('[FeatureExecutor] execute FAILED (exception)', Object.assign(Object.assign({ feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, failed_at: failedAt, completed_steps: this.state.completed_steps, error: details.message }, (details.status != null && { http_status: details.status })), (details.responseBody != null && { response_body: details.responseBody })));
|
|
758
|
+
const failedAt = (_o = this.state.current_step) !== null && _o !== void 0 ? _o : '(unknown)';
|
|
759
|
+
debugLog('[FeatureExecutor] execute FAILED (exception)', Object.assign(Object.assign({ feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, failed_at: failedAt, completed_steps: this.state.completed_steps, error: details.message }, (details.status != null && { http_status: details.status })), (details.responseBody != null && { response_body: sanitizeForLog(details.responseBody) })));
|
|
760
|
+
this.trace('execution.failed', { failed_at: failedAt, error: details, completed_steps: this.state.completed_steps });
|
|
680
761
|
if (details.stack) {
|
|
681
762
|
debugLog('[FeatureExecutor] execute FAILED stack', details.stack);
|
|
682
763
|
}
|
|
@@ -686,7 +767,7 @@ class FeatureExecutor {
|
|
|
686
767
|
: `Failed at ${failedAt}: ${details.message}`;
|
|
687
768
|
stepLog('Run finished (failed - exception)', Object.assign({ status: types_1.FeatureStatus.FAILED, failed_step: failedAt, error: errorSummary, completed_steps: this.state.completed_steps, step_timings: this.state.step_timings }, (details.reason && { reason: details.reason })));
|
|
688
769
|
await this.persistExecutionResult(types_1.LogEventStatus.FAIL, undefined, errorSummary);
|
|
689
|
-
await ((
|
|
770
|
+
await ((_p = this.logService) === null || _p === void 0 ? void 0 : _p.publish());
|
|
690
771
|
if (this.graphConnectionUsed) {
|
|
691
772
|
await this.getGraphService().disconnect().catch(() => { });
|
|
692
773
|
await this.getProcessorService().disconnectBrokerConnections().catch(() => { });
|
|
@@ -711,6 +792,19 @@ class FeatureExecutor {
|
|
|
711
792
|
* Execute a single step
|
|
712
793
|
*/
|
|
713
794
|
async executeStep(step) {
|
|
795
|
+
const parent = (0, context_1.currentExecutionContext)();
|
|
796
|
+
const stepRunId = (0, crypto_1.randomUUID)();
|
|
797
|
+
const context = (0, context_1.createExecutionContext)({
|
|
798
|
+
kind: 'step',
|
|
799
|
+
step_tag: step.tag,
|
|
800
|
+
step_run_id: stepRunId,
|
|
801
|
+
step_attempt: 1,
|
|
802
|
+
process_id: `${this.state.feature_id}:${step.tag}`,
|
|
803
|
+
parent_process_id: this.state.feature_id,
|
|
804
|
+
}, parent);
|
|
805
|
+
return (0, context_1.runWithExecutionContext)(context, () => this.executeStepInContext(step));
|
|
806
|
+
}
|
|
807
|
+
async executeStepInContext(step) {
|
|
714
808
|
const startTime = Date.now();
|
|
715
809
|
debugLog('[FeatureExecutor] executeStep ENTRY', {
|
|
716
810
|
feature_id: this.state.feature_id,
|
|
@@ -719,12 +813,14 @@ class FeatureExecutor {
|
|
|
719
813
|
});
|
|
720
814
|
let resolvedInput = {};
|
|
721
815
|
try {
|
|
816
|
+
this.trace('step.input.supplied', { step_tag: step.tag, step_type: step.type, payload: step.input || {} });
|
|
722
817
|
// Resolve input with data references and all $ operators
|
|
723
818
|
resolvedInput = (await this.resolveInput(step.input || {}));
|
|
819
|
+
this.trace('step.input.resolved', { step_tag: step.tag, step_type: step.type, payload: resolvedInput });
|
|
724
820
|
debugLog('[FeatureExecutor] executeStep input', {
|
|
725
821
|
feature_id: this.state.feature_id,
|
|
726
822
|
step_tag: step.tag,
|
|
727
|
-
input: resolvedInput,
|
|
823
|
+
input: sanitizeForLog(resolvedInput),
|
|
728
824
|
});
|
|
729
825
|
let output;
|
|
730
826
|
// Route steps to dedicated services; only action and notification use ProcessorService.
|
|
@@ -751,6 +847,9 @@ class FeatureExecutor {
|
|
|
751
847
|
case types_1.FeatureStepType.VECTOR:
|
|
752
848
|
output = await this.executeVectorStep(step, resolvedInput);
|
|
753
849
|
break;
|
|
850
|
+
case types_1.FeatureStepType.FUNCTION:
|
|
851
|
+
output = await this.executeFunctionStep(step, resolvedInput);
|
|
852
|
+
break;
|
|
754
853
|
case types_1.FeatureStepType.QUOTA:
|
|
755
854
|
output = await this.executeQuotaStep(step, resolvedInput);
|
|
756
855
|
break;
|
|
@@ -792,15 +891,16 @@ class FeatureExecutor {
|
|
|
792
891
|
}
|
|
793
892
|
}
|
|
794
893
|
const duration = Date.now() - startTime;
|
|
894
|
+
this.trace('step.response.received', { step_tag: step.tag, step_type: step.type, payload: output, duration_ms: duration });
|
|
795
895
|
debugLog('[FeatureExecutor] executeStep output', {
|
|
796
896
|
feature_id: this.state.feature_id,
|
|
797
897
|
step_tag: step.tag,
|
|
798
|
-
output,
|
|
898
|
+
output: sanitizeForLog(output),
|
|
799
899
|
durationMs: duration,
|
|
800
900
|
});
|
|
801
901
|
return {
|
|
802
902
|
success: true,
|
|
803
|
-
input: resolvedInput,
|
|
903
|
+
input: sanitizeForLog(resolvedInput),
|
|
804
904
|
output,
|
|
805
905
|
duration,
|
|
806
906
|
};
|
|
@@ -812,7 +912,14 @@ class FeatureExecutor {
|
|
|
812
912
|
const stepErrorMsg = details.reason != null
|
|
813
913
|
? (details.status != null ? `${details.reason} (HTTP ${details.status})` : details.reason)
|
|
814
914
|
: (details.status != null ? `${details.message} (HTTP ${details.status})` : details.message);
|
|
815
|
-
debugLog('[FeatureExecutor] executeStep FAILED', Object.assign(Object.assign({ feature_id: this.state.feature_id, step_tag: step.tag, step_type: step.type, durationMs: duration, input: resolvedInput, error: stepErrorMsg }, (details.status != null && { http_status: details.status })), (details.responseBody != null && { response_body: details.responseBody })));
|
|
915
|
+
debugLog('[FeatureExecutor] executeStep FAILED', Object.assign(Object.assign({ feature_id: this.state.feature_id, step_tag: step.tag, step_type: step.type, durationMs: duration, input: resolvedInput, error: stepErrorMsg }, (details.status != null && { http_status: details.status })), (details.responseBody != null && { response_body: sanitizeForLog(details.responseBody) })));
|
|
916
|
+
this.trace('step.failed', {
|
|
917
|
+
step_tag: step.tag,
|
|
918
|
+
step_type: step.type,
|
|
919
|
+
payload: resolvedInput,
|
|
920
|
+
error: details,
|
|
921
|
+
duration_ms: duration,
|
|
922
|
+
});
|
|
816
923
|
return {
|
|
817
924
|
success: false,
|
|
818
925
|
input: resolvedInput,
|
|
@@ -829,9 +936,10 @@ class FeatureExecutor {
|
|
|
829
936
|
debugLog('[FeatureExecutor] executeActionStep', { feature_id: this.state.feature_id, step_tag: step.tag, app: step.app });
|
|
830
937
|
// Step that only returns (no component call): no app → passthrough, output = resolved input
|
|
831
938
|
if (!step.app) {
|
|
939
|
+
this.trace('action.passthrough', { step_tag: step.tag, payload: input });
|
|
832
940
|
return input;
|
|
833
941
|
}
|
|
834
|
-
|
|
942
|
+
const payload = {
|
|
835
943
|
product: this.state.product,
|
|
836
944
|
env: this.state.env,
|
|
837
945
|
app: step.app,
|
|
@@ -839,25 +947,30 @@ class FeatureExecutor {
|
|
|
839
947
|
input: input,
|
|
840
948
|
retries: ((_a = step.options) === null || _a === void 0 ? void 0 : _a.retries) || 0,
|
|
841
949
|
cache: (_b = step.options) === null || _b === void 0 ? void 0 : _b.cache,
|
|
950
|
+
session: this.inheritedSession,
|
|
842
951
|
preloadedBootstrap: this.stepBootstrapCache.get(step.tag),
|
|
843
|
-
}
|
|
952
|
+
};
|
|
953
|
+
this.trace('action.request.sent', { step_tag: step.tag, payload });
|
|
954
|
+
return this.getProcessorService().processAction(payload);
|
|
844
955
|
}
|
|
845
956
|
/**
|
|
846
957
|
* Execute a database step: use query/insert/update/delete/upsert for DB operations, execute() for named actions.
|
|
847
958
|
*/
|
|
848
959
|
async executeDatabaseStep(step, input) {
|
|
960
|
+
var _a;
|
|
849
961
|
const database = step.database;
|
|
850
962
|
const product = this.state.product;
|
|
851
963
|
const env = this.state.env;
|
|
852
964
|
const event = (step.event || '').toLowerCase();
|
|
853
965
|
const db = this.getDatabaseService();
|
|
854
|
-
const opts = Object.assign({ product, env, database }, input);
|
|
966
|
+
const opts = Object.assign(Object.assign({ product, env, database }, input), { session: (_a = input.session) !== null && _a !== void 0 ? _a : this.inheritedSession });
|
|
855
967
|
debugLog('[FeatureExecutor] executeDatabaseStep', {
|
|
856
968
|
feature_id: this.state.feature_id,
|
|
857
969
|
step_tag: step.tag,
|
|
858
970
|
database,
|
|
859
971
|
event,
|
|
860
972
|
});
|
|
973
|
+
this.trace('database.request.sent', { step_tag: step.tag, event, payload: opts });
|
|
861
974
|
switch (event) {
|
|
862
975
|
case 'query':
|
|
863
976
|
return db.query(opts);
|
|
@@ -876,6 +989,7 @@ class FeatureExecutor {
|
|
|
876
989
|
database,
|
|
877
990
|
action: step.event,
|
|
878
991
|
input: input,
|
|
992
|
+
session: this.inheritedSession,
|
|
879
993
|
});
|
|
880
994
|
}
|
|
881
995
|
}
|
|
@@ -886,14 +1000,17 @@ class FeatureExecutor {
|
|
|
886
1000
|
var _a;
|
|
887
1001
|
const event = `${step.notification}:${step.event}`;
|
|
888
1002
|
debugLog('[FeatureExecutor] executeNotificationStep', { feature_id: this.state.feature_id, step_tag: step.tag, event });
|
|
889
|
-
|
|
1003
|
+
const payload = {
|
|
890
1004
|
product: this.state.product,
|
|
891
1005
|
env: this.state.env,
|
|
892
1006
|
event,
|
|
893
1007
|
input: input,
|
|
894
1008
|
retries: ((_a = step.options) === null || _a === void 0 ? void 0 : _a.retries) || 0,
|
|
1009
|
+
session: this.inheritedSession,
|
|
895
1010
|
preloadedBootstrap: this.stepBootstrapCache.get(step.tag),
|
|
896
|
-
}
|
|
1011
|
+
};
|
|
1012
|
+
this.trace('notification.request.sent', { step_tag: step.tag, payload });
|
|
1013
|
+
return this.getProcessorService().processNotification(payload);
|
|
897
1014
|
}
|
|
898
1015
|
/**
|
|
899
1016
|
* Execute a storage step using StorageService (upload, download, or delete by input shape).
|
|
@@ -903,9 +1020,10 @@ class FeatureExecutor {
|
|
|
903
1020
|
const product = this.state.product;
|
|
904
1021
|
const env = this.state.env;
|
|
905
1022
|
const storage = step.storage;
|
|
906
|
-
const opts = { product, env, storage };
|
|
1023
|
+
const opts = { product, env, storage, session: this.inheritedSession };
|
|
907
1024
|
debugLog('[FeatureExecutor] executeStorageStep', { feature_id: this.state.feature_id, step_tag: step.tag, storage, event: step.event });
|
|
908
1025
|
const inp = input;
|
|
1026
|
+
this.trace('storage.request.sent', { step_tag: step.tag, event: step.event, payload: Object.assign(Object.assign({}, opts), inp) });
|
|
909
1027
|
if (inp.buffer != null && inp.fileName != null) {
|
|
910
1028
|
return this.getStorageService().upload(Object.assign(Object.assign({}, opts), { fileName: String(inp.fileName), buffer: inp.buffer, mimeType: inp.mimeType != null ? String(inp.mimeType) : undefined }));
|
|
911
1029
|
}
|
|
@@ -922,12 +1040,15 @@ class FeatureExecutor {
|
|
|
922
1040
|
const event = `${step.broker}:${step.event}`;
|
|
923
1041
|
const message = (input && input.message != null) ? input.message : (input || {});
|
|
924
1042
|
debugLog('[FeatureExecutor] executeProduceStep', { feature_id: this.state.feature_id, step_tag: step.tag, event });
|
|
925
|
-
|
|
1043
|
+
const payload = {
|
|
926
1044
|
product: this.state.product,
|
|
927
1045
|
env: this.state.env,
|
|
928
1046
|
event,
|
|
929
1047
|
message: message,
|
|
930
|
-
|
|
1048
|
+
session: this.inheritedBrokerSession(),
|
|
1049
|
+
};
|
|
1050
|
+
this.trace('event.request.sent', { step_tag: step.tag, payload });
|
|
1051
|
+
return this.getBrokersService().publish(payload);
|
|
931
1052
|
}
|
|
932
1053
|
/**
|
|
933
1054
|
* Execute a graph step
|
|
@@ -938,6 +1059,7 @@ class FeatureExecutor {
|
|
|
938
1059
|
const graphTag = step.graph;
|
|
939
1060
|
const action = step.event;
|
|
940
1061
|
debugLog('[FeatureExecutor] executeGraphStep', { feature_id: this.state.feature_id, step_tag: step.tag, graph: graphTag, action });
|
|
1062
|
+
this.trace('graph.request.preparing', { step_tag: step.tag, action, graph: graphTag, payload: input });
|
|
941
1063
|
this.graphConnectionUsed = true;
|
|
942
1064
|
await this.getGraphService().connect({
|
|
943
1065
|
env: this.state.env,
|
|
@@ -951,6 +1073,7 @@ class FeatureExecutor {
|
|
|
951
1073
|
const result = await this.getGraphService().createNode({
|
|
952
1074
|
labels: input.labels,
|
|
953
1075
|
properties: input.properties,
|
|
1076
|
+
session: this.inheritedSession,
|
|
954
1077
|
});
|
|
955
1078
|
return result;
|
|
956
1079
|
}
|
|
@@ -958,6 +1081,7 @@ class FeatureExecutor {
|
|
|
958
1081
|
const result = await this.getGraphService().updateNode({
|
|
959
1082
|
id: input.id,
|
|
960
1083
|
properties: input.properties,
|
|
1084
|
+
session: this.inheritedSession,
|
|
961
1085
|
});
|
|
962
1086
|
return result;
|
|
963
1087
|
}
|
|
@@ -965,6 +1089,7 @@ class FeatureExecutor {
|
|
|
965
1089
|
const result = await this.getGraphService().deleteNode({
|
|
966
1090
|
id: input.id,
|
|
967
1091
|
detach: input.detach,
|
|
1092
|
+
session: this.inheritedSession,
|
|
968
1093
|
});
|
|
969
1094
|
return result;
|
|
970
1095
|
}
|
|
@@ -974,17 +1099,19 @@ class FeatureExecutor {
|
|
|
974
1099
|
endNodeId: input.endNodeId || input.to,
|
|
975
1100
|
type: input.type,
|
|
976
1101
|
properties: input.properties,
|
|
1102
|
+
session: this.inheritedSession,
|
|
977
1103
|
});
|
|
978
1104
|
return result;
|
|
979
1105
|
}
|
|
980
1106
|
case 'deleteRelationship': {
|
|
981
1107
|
const result = await this.getGraphService().deleteRelationship({
|
|
982
1108
|
id: input.id,
|
|
1109
|
+
session: this.inheritedSession,
|
|
983
1110
|
});
|
|
984
1111
|
return result;
|
|
985
1112
|
}
|
|
986
1113
|
case 'query': {
|
|
987
|
-
const result = await this.getGraphService().query(input.query, input.params);
|
|
1114
|
+
const result = await this.getGraphService().query(input.query, input.params, undefined, this.inheritedSession);
|
|
988
1115
|
return result;
|
|
989
1116
|
}
|
|
990
1117
|
case 'findNodes': {
|
|
@@ -993,6 +1120,7 @@ class FeatureExecutor {
|
|
|
993
1120
|
where: input.where,
|
|
994
1121
|
limit: input.limit,
|
|
995
1122
|
skip: input.skip,
|
|
1123
|
+
session: this.inheritedSession,
|
|
996
1124
|
});
|
|
997
1125
|
return result;
|
|
998
1126
|
}
|
|
@@ -1002,6 +1130,7 @@ class FeatureExecutor {
|
|
|
1002
1130
|
relationshipTypes: input.relationshipTypes,
|
|
1003
1131
|
direction: input.direction,
|
|
1004
1132
|
maxDepth: input.maxDepth,
|
|
1133
|
+
session: this.inheritedSession,
|
|
1005
1134
|
});
|
|
1006
1135
|
return result;
|
|
1007
1136
|
}
|
|
@@ -1013,6 +1142,7 @@ class FeatureExecutor {
|
|
|
1013
1142
|
graph: graphTag,
|
|
1014
1143
|
action,
|
|
1015
1144
|
input,
|
|
1145
|
+
session: this.inheritedSession,
|
|
1016
1146
|
});
|
|
1017
1147
|
return result;
|
|
1018
1148
|
}
|
|
@@ -1026,7 +1156,7 @@ class FeatureExecutor {
|
|
|
1026
1156
|
* Execute a vector step (query, upsert, deleteVectors, or custom action via execute).
|
|
1027
1157
|
*/
|
|
1028
1158
|
async executeVectorStep(step, input) {
|
|
1029
|
-
var _a;
|
|
1159
|
+
var _a, _b, _c, _d, _e;
|
|
1030
1160
|
const vectorTag = step.vector;
|
|
1031
1161
|
if (!vectorTag) {
|
|
1032
1162
|
throw new Error(`Vector step "${step.tag}" has no vector tag`);
|
|
@@ -1041,21 +1171,22 @@ class FeatureExecutor {
|
|
|
1041
1171
|
vector: vectorTag,
|
|
1042
1172
|
event,
|
|
1043
1173
|
});
|
|
1174
|
+
this.trace('vector.request.preparing', { step_tag: step.tag, event, vector: vectorTag, payload: input });
|
|
1044
1175
|
switch (event) {
|
|
1045
1176
|
case 'query': {
|
|
1046
|
-
const result = await svc.query(Object.assign({ product,
|
|
1047
|
-
env, tag: vectorTag }, input));
|
|
1177
|
+
const result = await svc.query(Object.assign(Object.assign({ product,
|
|
1178
|
+
env, tag: vectorTag }, input), { session: (_a = input.session) !== null && _a !== void 0 ? _a : this.inheritedSession }));
|
|
1048
1179
|
return result;
|
|
1049
1180
|
}
|
|
1050
1181
|
case 'upsert': {
|
|
1051
|
-
const result = await svc.upsert(Object.assign({ product,
|
|
1052
|
-
env, tag: vectorTag }, input));
|
|
1182
|
+
const result = await svc.upsert(Object.assign(Object.assign({ product,
|
|
1183
|
+
env, tag: vectorTag }, input), { session: (_b = input.session) !== null && _b !== void 0 ? _b : this.inheritedSession }));
|
|
1053
1184
|
return result;
|
|
1054
1185
|
}
|
|
1055
1186
|
case 'delete':
|
|
1056
1187
|
case 'deletevectors': {
|
|
1057
|
-
const result = await svc.deleteVectors(Object.assign({ product,
|
|
1058
|
-
env, tag: vectorTag }, input));
|
|
1188
|
+
const result = await svc.deleteVectors(Object.assign(Object.assign({ product,
|
|
1189
|
+
env, tag: vectorTag }, input), { session: (_c = input.session) !== null && _c !== void 0 ? _c : this.inheritedSession }));
|
|
1059
1190
|
return result;
|
|
1060
1191
|
}
|
|
1061
1192
|
default: {
|
|
@@ -1066,9 +1197,10 @@ class FeatureExecutor {
|
|
|
1066
1197
|
vector: vectorTag,
|
|
1067
1198
|
action: step.event,
|
|
1068
1199
|
input: input,
|
|
1200
|
+
session: this.inheritedSession,
|
|
1069
1201
|
});
|
|
1070
|
-
const op = (
|
|
1071
|
-
const opts = Object.assign({ product, env, tag: vectorTag }, resolved);
|
|
1202
|
+
const op = (_d = resolved === null || resolved === void 0 ? void 0 : resolved._operation) !== null && _d !== void 0 ? _d : resolved === null || resolved === void 0 ? void 0 : resolved.operation;
|
|
1203
|
+
const opts = Object.assign(Object.assign({ product, env, tag: vectorTag }, resolved), { session: (_e = resolved.session) !== null && _e !== void 0 ? _e : this.inheritedSession });
|
|
1072
1204
|
if (op === 'query' || !op) {
|
|
1073
1205
|
return svc.query(opts);
|
|
1074
1206
|
}
|
|
@@ -1082,6 +1214,54 @@ class FeatureExecutor {
|
|
|
1082
1214
|
}
|
|
1083
1215
|
}
|
|
1084
1216
|
}
|
|
1217
|
+
/** Execute a portable application function through a local handler or signed HTTP transport. */
|
|
1218
|
+
async executeFunctionStep(step, input) {
|
|
1219
|
+
var _a, _b, _c;
|
|
1220
|
+
const reference = step.function_ref;
|
|
1221
|
+
if (!reference) {
|
|
1222
|
+
throw new Error(`Function step "${step.tag}" has no function_ref. Recompile the feature with ctx.functions.`);
|
|
1223
|
+
}
|
|
1224
|
+
const invocationId = (0, crypto_1.randomUUID)();
|
|
1225
|
+
this.functionInvocations.set(step.tag, {
|
|
1226
|
+
function_invocation_id: invocationId,
|
|
1227
|
+
function_namespace: reference.namespace,
|
|
1228
|
+
function_operation: reference.operation,
|
|
1229
|
+
function_version: reference.version,
|
|
1230
|
+
});
|
|
1231
|
+
const deadlineAt = reference.timeout_ms ? Date.now() + reference.timeout_ms : undefined;
|
|
1232
|
+
this.trace('function.resolution.started', {
|
|
1233
|
+
step_tag: step.tag,
|
|
1234
|
+
invocation_id: invocationId,
|
|
1235
|
+
function: `${reference.namespace}.${reference.operation}@${reference.version}`,
|
|
1236
|
+
transports: reference.transports.map(transport => transport.type),
|
|
1237
|
+
payload: input,
|
|
1238
|
+
});
|
|
1239
|
+
const output = await functions_1.portableFunctions.invoke(reference, input, {
|
|
1240
|
+
product: this.state.product,
|
|
1241
|
+
env: this.state.env,
|
|
1242
|
+
workspace_id: this.config.workspace_id,
|
|
1243
|
+
feature_id: this.state.feature_id,
|
|
1244
|
+
feature_tag: this.state.feature_tag,
|
|
1245
|
+
feature_run_id: this.state.feature_id,
|
|
1246
|
+
step_tag: step.tag,
|
|
1247
|
+
step_run_id: (_a = (0, context_1.currentExecutionContext)()) === null || _a === void 0 ? void 0 : _a.step_run_id,
|
|
1248
|
+
invocation_id: invocationId,
|
|
1249
|
+
trace_id: (_b = (0, context_1.currentExecutionContext)()) === null || _b === void 0 ? void 0 : _b.trace_id,
|
|
1250
|
+
parent_span_id: (_c = (0, context_1.currentExecutionContext)()) === null || _c === void 0 ? void 0 : _c.span_id,
|
|
1251
|
+
session: this.inheritedSession,
|
|
1252
|
+
session_id: this.sessionLogFields.session_id,
|
|
1253
|
+
session_tag: this.sessionLogFields.session_tag,
|
|
1254
|
+
session_user_id: this.sessionLogFields.session_user_id,
|
|
1255
|
+
deadline_at: deadlineAt,
|
|
1256
|
+
}, this.config.access_key);
|
|
1257
|
+
this.trace('function.response.received', {
|
|
1258
|
+
step_tag: step.tag,
|
|
1259
|
+
invocation_id: invocationId,
|
|
1260
|
+
function: `${reference.namespace}.${reference.operation}@${reference.version}`,
|
|
1261
|
+
payload: output,
|
|
1262
|
+
});
|
|
1263
|
+
return output;
|
|
1264
|
+
}
|
|
1085
1265
|
/**
|
|
1086
1266
|
* Execute a quota step
|
|
1087
1267
|
*/
|
|
@@ -1092,6 +1272,7 @@ class FeatureExecutor {
|
|
|
1092
1272
|
env: this.state.env,
|
|
1093
1273
|
tag: step.quota,
|
|
1094
1274
|
input,
|
|
1275
|
+
session: this.inheritedSession,
|
|
1095
1276
|
});
|
|
1096
1277
|
}
|
|
1097
1278
|
/**
|
|
@@ -1104,6 +1285,7 @@ class FeatureExecutor {
|
|
|
1104
1285
|
env: this.state.env,
|
|
1105
1286
|
tag: step.fallback,
|
|
1106
1287
|
input,
|
|
1288
|
+
session: this.inheritedSession,
|
|
1107
1289
|
});
|
|
1108
1290
|
}
|
|
1109
1291
|
/**
|
|
@@ -1130,7 +1312,8 @@ class FeatureExecutor {
|
|
|
1130
1312
|
env: this.state.env,
|
|
1131
1313
|
tag: childTag,
|
|
1132
1314
|
input,
|
|
1133
|
-
|
|
1315
|
+
session: this.inheritedSession,
|
|
1316
|
+
}, this._privateKey, this.sessionLogFields, this.productBuilder);
|
|
1134
1317
|
const result = await childExecutor.execute();
|
|
1135
1318
|
debugLog('[FeatureExecutor] executeChildWorkflowStep result', {
|
|
1136
1319
|
feature_id: this.state.feature_id,
|
|
@@ -1405,12 +1588,13 @@ class FeatureExecutor {
|
|
|
1405
1588
|
* Execute a rollback handler
|
|
1406
1589
|
*/
|
|
1407
1590
|
async executeRollbackHandler(rollback, stepOutput) {
|
|
1408
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1591
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
1409
1592
|
if (!rollback)
|
|
1410
1593
|
return;
|
|
1411
1594
|
debugLog('[FeatureExecutor] executeRollbackHandler', { feature_id: this.state.feature_id, rollback_type: rollback.type });
|
|
1412
1595
|
// Resolve rollback input, including step output references
|
|
1413
1596
|
const resolvedInput = await this.resolveInput(rollback.input || {}, stepOutput);
|
|
1597
|
+
this.trace('rollback.input.resolved', { rollback_type: rollback.type, payload: resolvedInput });
|
|
1414
1598
|
switch (rollback.type) {
|
|
1415
1599
|
case types_1.FeatureStepType.ACTION:
|
|
1416
1600
|
await this.getProcessorService().processAction({
|
|
@@ -1420,6 +1604,7 @@ class FeatureExecutor {
|
|
|
1420
1604
|
action: rollback.event,
|
|
1421
1605
|
input: resolvedInput,
|
|
1422
1606
|
retries: (_a = rollback.retries) !== null && _a !== void 0 ? _a : 0,
|
|
1607
|
+
session: this.inheritedSession,
|
|
1423
1608
|
});
|
|
1424
1609
|
break;
|
|
1425
1610
|
case types_1.FeatureStepType.DATABASE_ACTION: {
|
|
@@ -1428,7 +1613,7 @@ class FeatureExecutor {
|
|
|
1428
1613
|
const env = this.state.env;
|
|
1429
1614
|
const database = rollback.database;
|
|
1430
1615
|
const event = ((_b = rollback.event) !== null && _b !== void 0 ? _b : '').toLowerCase();
|
|
1431
|
-
const opts = Object.assign({ product, env, database }, resolvedInput);
|
|
1616
|
+
const opts = Object.assign(Object.assign({ product, env, database }, resolvedInput), { session: (_c = resolvedInput.session) !== null && _c !== void 0 ? _c : this.inheritedSession });
|
|
1432
1617
|
if (event === 'query')
|
|
1433
1618
|
await db.query(opts);
|
|
1434
1619
|
else if (event === 'insert')
|
|
@@ -1446,6 +1631,7 @@ class FeatureExecutor {
|
|
|
1446
1631
|
database,
|
|
1447
1632
|
action: rollback.event,
|
|
1448
1633
|
input: resolvedInput,
|
|
1634
|
+
session: this.inheritedSession,
|
|
1449
1635
|
});
|
|
1450
1636
|
break;
|
|
1451
1637
|
}
|
|
@@ -1456,14 +1642,15 @@ class FeatureExecutor {
|
|
|
1456
1642
|
env: this.state.env,
|
|
1457
1643
|
event: notifEvent,
|
|
1458
1644
|
input: resolvedInput,
|
|
1459
|
-
retries: (
|
|
1645
|
+
retries: (_d = rollback.retries) !== null && _d !== void 0 ? _d : 0,
|
|
1646
|
+
session: this.inheritedSession,
|
|
1460
1647
|
});
|
|
1461
1648
|
break;
|
|
1462
1649
|
case types_1.FeatureStepType.STORAGE: {
|
|
1463
1650
|
const product = this.state.product;
|
|
1464
1651
|
const env = this.state.env;
|
|
1465
1652
|
const storage = rollback.storage;
|
|
1466
|
-
const opts = { product, env, storage };
|
|
1653
|
+
const opts = { product, env, storage, session: this.inheritedSession };
|
|
1467
1654
|
const inp = resolvedInput;
|
|
1468
1655
|
if (inp.buffer != null && inp.fileName != null) {
|
|
1469
1656
|
await this.getStorageService().upload(Object.assign(Object.assign({}, opts), { fileName: String(inp.fileName), buffer: inp.buffer, mimeType: inp.mimeType != null ? String(inp.mimeType) : undefined }));
|
|
@@ -1472,7 +1659,7 @@ class FeatureExecutor {
|
|
|
1472
1659
|
await this.getStorageService().delete(Object.assign(Object.assign({}, opts), { fileName: String(inp.file_key) }));
|
|
1473
1660
|
}
|
|
1474
1661
|
else {
|
|
1475
|
-
await this.getStorageService().download(Object.assign(Object.assign({}, opts), { fileName: String((
|
|
1662
|
+
await this.getStorageService().download(Object.assign(Object.assign({}, opts), { fileName: String((_f = (_e = inp.fileName) !== null && _e !== void 0 ? _e : inp.file_key) !== null && _f !== void 0 ? _f : '') }));
|
|
1476
1663
|
}
|
|
1477
1664
|
break;
|
|
1478
1665
|
}
|
|
@@ -1481,16 +1668,16 @@ class FeatureExecutor {
|
|
|
1481
1668
|
const env = this.state.env;
|
|
1482
1669
|
const vectorTag = rollback.vector;
|
|
1483
1670
|
const inp = resolvedInput;
|
|
1484
|
-
const event = ((
|
|
1671
|
+
const event = ((_g = rollback.event) !== null && _g !== void 0 ? _g : '').toLowerCase();
|
|
1485
1672
|
const svc = this.getVectorService();
|
|
1486
1673
|
if (event === 'query') {
|
|
1487
|
-
await svc.query(Object.assign({ product, env, tag: vectorTag }, inp));
|
|
1674
|
+
await svc.query(Object.assign(Object.assign({ product, env, tag: vectorTag }, inp), { session: (_h = inp.session) !== null && _h !== void 0 ? _h : this.inheritedSession }));
|
|
1488
1675
|
}
|
|
1489
1676
|
else if (event === 'upsert') {
|
|
1490
|
-
await svc.upsert(Object.assign({ product, env, tag: vectorTag }, inp));
|
|
1677
|
+
await svc.upsert(Object.assign(Object.assign({ product, env, tag: vectorTag }, inp), { session: (_j = inp.session) !== null && _j !== void 0 ? _j : this.inheritedSession }));
|
|
1491
1678
|
}
|
|
1492
1679
|
else if (event === 'delete' || event === 'deletevectors') {
|
|
1493
|
-
await svc.deleteVectors(Object.assign({ product, env, tag: vectorTag }, inp));
|
|
1680
|
+
await svc.deleteVectors(Object.assign(Object.assign({ product, env, tag: vectorTag }, inp), { session: (_k = inp.session) !== null && _k !== void 0 ? _k : this.inheritedSession }));
|
|
1494
1681
|
}
|
|
1495
1682
|
else {
|
|
1496
1683
|
const resolved = await svc.actions.resolve({
|
|
@@ -1499,9 +1686,10 @@ class FeatureExecutor {
|
|
|
1499
1686
|
vector: vectorTag,
|
|
1500
1687
|
action: rollback.event,
|
|
1501
1688
|
input: inp,
|
|
1689
|
+
session: this.inheritedSession,
|
|
1502
1690
|
});
|
|
1503
|
-
const op = (
|
|
1504
|
-
const opts = Object.assign({ product, env, tag: vectorTag }, resolved);
|
|
1691
|
+
const op = (_l = resolved === null || resolved === void 0 ? void 0 : resolved._operation) !== null && _l !== void 0 ? _l : resolved === null || resolved === void 0 ? void 0 : resolved.operation;
|
|
1692
|
+
const opts = Object.assign(Object.assign({ product, env, tag: vectorTag }, resolved), { session: (_m = resolved.session) !== null && _m !== void 0 ? _m : this.inheritedSession });
|
|
1505
1693
|
if (op === 'upsert')
|
|
1506
1694
|
await svc.upsert(opts);
|
|
1507
1695
|
else if (op === 'delete' || op === 'deleteVectors')
|
|
@@ -1519,6 +1707,7 @@ class FeatureExecutor {
|
|
|
1519
1707
|
env: this.state.env,
|
|
1520
1708
|
event: pubEvent,
|
|
1521
1709
|
input: resolvedInput,
|
|
1710
|
+
session: this.inheritedSession,
|
|
1522
1711
|
});
|
|
1523
1712
|
break;
|
|
1524
1713
|
}
|
|
@@ -1532,7 +1721,10 @@ class FeatureExecutor {
|
|
|
1532
1721
|
const resolvedValues = await Promise.all(entries.map(([, value]) => this.resolveValue(value, stepOutput)));
|
|
1533
1722
|
const resolved = {};
|
|
1534
1723
|
entries.forEach(([key], i) => {
|
|
1535
|
-
|
|
1724
|
+
// An absent optional input is absence, not an unresolved operator string
|
|
1725
|
+
// and not an explicit null. Omitting it preserves defaulting semantics.
|
|
1726
|
+
if (resolvedValues[i] !== undefined)
|
|
1727
|
+
resolved[key] = resolvedValues[i];
|
|
1536
1728
|
});
|
|
1537
1729
|
return resolved;
|
|
1538
1730
|
}
|
|
@@ -1566,14 +1758,23 @@ class FeatureExecutor {
|
|
|
1566
1758
|
* $Uppercase, $Lowercase, $Dateformat, $Replace, $Filter, $Find, $Size, $Length
|
|
1567
1759
|
*/
|
|
1568
1760
|
async resolveStringValue(value, stepOutput) {
|
|
1569
|
-
var _a;
|
|
1761
|
+
var _a, _b;
|
|
1570
1762
|
const v = value.trim();
|
|
1571
1763
|
// --- Data references (exact match) ---
|
|
1572
1764
|
if (v === '$Now' || v === '$Now()')
|
|
1573
1765
|
return Date.now();
|
|
1574
1766
|
const inputMatch = v.match(/^\$Input\{(.+)\}$/);
|
|
1575
|
-
if (inputMatch)
|
|
1576
|
-
|
|
1767
|
+
if (inputMatch) {
|
|
1768
|
+
const path = inputMatch[1];
|
|
1769
|
+
const resolved = this.getNestedValue(this.state.input, path);
|
|
1770
|
+
if (resolved !== undefined)
|
|
1771
|
+
return resolved;
|
|
1772
|
+
const root = path.split('.')[0];
|
|
1773
|
+
const inputDefinition = (_a = this.feature.input) === null || _a === void 0 ? void 0 : _a[root];
|
|
1774
|
+
if (inputDefinition === null || inputDefinition === void 0 ? void 0 : inputDefinition.required)
|
|
1775
|
+
throw new UnresolvedInputReferenceError(v, true);
|
|
1776
|
+
return undefined;
|
|
1777
|
+
}
|
|
1577
1778
|
const sequenceMatch = v.match(/^\$Sequence\{main\}\{([^}]+)\}\{(.+)\}$/);
|
|
1578
1779
|
if (sequenceMatch) {
|
|
1579
1780
|
const stepData = this.state.steps[sequenceMatch[1]];
|
|
@@ -1634,6 +1835,10 @@ class FeatureExecutor {
|
|
|
1634
1835
|
const separator = concatMatch[2];
|
|
1635
1836
|
const parts = arrContent.split(',').map((s) => this.unquote(s.trim()));
|
|
1636
1837
|
const resolvedParts = await Promise.all(parts.map((p) => this.resolveValue(p, stepOutput)));
|
|
1838
|
+
const missingIndex = resolvedParts.findIndex((part) => part === undefined);
|
|
1839
|
+
if (missingIndex >= 0) {
|
|
1840
|
+
throw new UnresolvedInputReferenceError(parts[missingIndex], false);
|
|
1841
|
+
}
|
|
1637
1842
|
return resolvedParts.map((x) => (x == null ? '' : String(x))).join(separator);
|
|
1638
1843
|
}
|
|
1639
1844
|
// $Substring(str, start, end)
|
|
@@ -1688,7 +1893,7 @@ class FeatureExecutor {
|
|
|
1688
1893
|
const val = await this.resolveValue(this.unquote(pickMatch[1]), stepOutput);
|
|
1689
1894
|
const idx = Number(pickMatch[2]);
|
|
1690
1895
|
if (typeof val === 'string' || Array.isArray(val))
|
|
1691
|
-
return (
|
|
1896
|
+
return (_b = val[idx]) !== null && _b !== void 0 ? _b : '';
|
|
1692
1897
|
return '';
|
|
1693
1898
|
}
|
|
1694
1899
|
// $Filter(array, "op", value)
|
|
@@ -1835,6 +2040,24 @@ class FeatureExecutor {
|
|
|
1835
2040
|
storage_tag: step.storage,
|
|
1836
2041
|
});
|
|
1837
2042
|
}
|
|
2043
|
+
else if (step.type === types_1.FeatureStepType.DATABASE_ACTION && step.database) {
|
|
2044
|
+
workflowSteps.push({ step_tag: step.tag, type: 'database', database_tag: step.database });
|
|
2045
|
+
}
|
|
2046
|
+
else if ((step.type === types_1.FeatureStepType.PUBLISH || step.type === types_1.FeatureStepType.PRODUCE) && step.broker) {
|
|
2047
|
+
workflowSteps.push({ step_tag: step.tag, type: 'broker', broker_tag: step.broker, topic_tag: step.event });
|
|
2048
|
+
}
|
|
2049
|
+
else if (step.type === types_1.FeatureStepType.GRAPH && step.graph) {
|
|
2050
|
+
workflowSteps.push({ step_tag: step.tag, type: 'graph', graph_tag: step.graph });
|
|
2051
|
+
}
|
|
2052
|
+
else if (step.type === types_1.FeatureStepType.VECTOR && step.vector) {
|
|
2053
|
+
workflowSteps.push({ step_tag: step.tag, type: 'vector', vector_tag: step.vector });
|
|
2054
|
+
}
|
|
2055
|
+
else if (step.type === types_1.FeatureStepType.QUOTA && step.quota) {
|
|
2056
|
+
workflowSteps.push({ step_tag: step.tag, type: 'quota', component_tag: step.quota });
|
|
2057
|
+
}
|
|
2058
|
+
else if (step.type === types_1.FeatureStepType.FALLBACK && step.fallback) {
|
|
2059
|
+
workflowSteps.push({ step_tag: step.tag, type: 'fallback', component_tag: step.fallback });
|
|
2060
|
+
}
|
|
1838
2061
|
}
|
|
1839
2062
|
if (workflowSteps.length > 0) {
|
|
1840
2063
|
stepLog('Bootstrap feature API call (single request)', {
|
|
@@ -1848,6 +2071,7 @@ class FeatureExecutor {
|
|
|
1848
2071
|
env_slug: env,
|
|
1849
2072
|
steps: workflowSteps,
|
|
1850
2073
|
});
|
|
2074
|
+
this.trace('bootstrap.response.fetched', { requested_steps: workflowSteps, payload: bootstraps });
|
|
1851
2075
|
stepLog('Bootstrap feature API response', {
|
|
1852
2076
|
received_keys: Object.keys(bootstraps),
|
|
1853
2077
|
keys_count: Object.keys(bootstraps).length,
|
|
@@ -1858,6 +2082,9 @@ class FeatureExecutor {
|
|
|
1858
2082
|
}
|
|
1859
2083
|
}
|
|
1860
2084
|
}
|
|
2085
|
+
// All primitive metadata above is fetched by the single feature bootstrap call.
|
|
2086
|
+
return;
|
|
2087
|
+
// Legacy fallback retained below for older servers; unreachable with the unified bootstrap.
|
|
1861
2088
|
// Pre-fetch message brokers for produce steps so runBrokerPublish has broker/topic in cache
|
|
1862
2089
|
const brokerTags = new Set();
|
|
1863
2090
|
for (const step of steps) {
|
|
@@ -1871,6 +2098,7 @@ class FeatureExecutor {
|
|
|
1871
2098
|
var _a;
|
|
1872
2099
|
try {
|
|
1873
2100
|
const broker = await this.productBuilder.fetchMessageBroker(tag);
|
|
2101
|
+
this.trace('resource.fetched', { resource_type: 'event', resource_tag: tag, payload: broker });
|
|
1874
2102
|
return { tag, found: !!broker };
|
|
1875
2103
|
}
|
|
1876
2104
|
catch (e) {
|
|
@@ -1892,6 +2120,7 @@ class FeatureExecutor {
|
|
|
1892
2120
|
var _a;
|
|
1893
2121
|
try {
|
|
1894
2122
|
const db = await this.productBuilder.fetchDatabase(tag);
|
|
2123
|
+
this.trace('resource.fetched', { resource_type: 'database', resource_tag: tag, payload: db });
|
|
1895
2124
|
return { tag, found: !!db };
|
|
1896
2125
|
}
|
|
1897
2126
|
catch (e) {
|
|
@@ -1913,6 +2142,7 @@ class FeatureExecutor {
|
|
|
1913
2142
|
var _a;
|
|
1914
2143
|
try {
|
|
1915
2144
|
const graph = await this.productBuilder.fetchGraph(tag);
|
|
2145
|
+
this.trace('resource.fetched', { resource_type: 'graph', resource_tag: tag, payload: graph });
|
|
1916
2146
|
return { tag, found: !!graph };
|
|
1917
2147
|
}
|
|
1918
2148
|
catch (e) {
|
|
@@ -1933,6 +2163,7 @@ class FeatureExecutor {
|
|
|
1933
2163
|
var _a;
|
|
1934
2164
|
try {
|
|
1935
2165
|
const vec = await this.productBuilder.fetchVector(tag);
|
|
2166
|
+
this.trace('resource.fetched', { resource_type: 'vector', resource_tag: tag, payload: vec });
|
|
1936
2167
|
return { tag, found: !!vec };
|
|
1937
2168
|
}
|
|
1938
2169
|
catch (e) {
|
|
@@ -1954,6 +2185,7 @@ class FeatureExecutor {
|
|
|
1954
2185
|
var _a;
|
|
1955
2186
|
try {
|
|
1956
2187
|
const quota = await this.productBuilder.fetchQuota(tag);
|
|
2188
|
+
this.trace('resource.fetched', { resource_type: 'quota', resource_tag: tag, payload: quota });
|
|
1957
2189
|
return { tag, found: !!quota };
|
|
1958
2190
|
}
|
|
1959
2191
|
catch (e) {
|