@ductape/sdk 0.1.145 → 0.1.148
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/context/execution-context.d.ts +29 -1
- package/dist/context/execution-context.js +57 -1
- package/dist/context/execution-context.js.map +1 -1
- package/dist/database/actions/action-manager.d.ts +1 -5
- package/dist/database/actions/action-manager.js +5 -10
- package/dist/database/actions/action-manager.js.map +1 -1
- package/dist/database/databases.service.d.ts +1 -0
- package/dist/database/databases.service.js +48 -6
- package/dist/database/databases.service.js.map +1 -1
- package/dist/features/feature-executor.d.ts +4 -3
- package/dist/features/feature-executor.js +125 -67
- package/dist/features/feature-executor.js.map +1 -1
- package/dist/functions/functions.runtime.js +30 -6
- package/dist/functions/functions.runtime.js.map +1 -1
- package/dist/functions/http-handler.js +22 -4
- package/dist/functions/http-handler.js.map +1 -1
- package/dist/functions/types.d.ts +2 -0
- package/dist/functions/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -9
- package/dist/index.js.map +1 -1
- package/dist/resilience/fallback.service.d.ts +19 -0
- package/dist/resilience/fallback.service.js +139 -3
- package/dist/resilience/fallback.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/processor.types.d.ts +6 -0
- package/dist/types/processor.types.js.map +1 -1
- package/package.json +1 -1
|
@@ -118,6 +118,8 @@ function formatErrorDetails(error) {
|
|
|
118
118
|
const out = { message };
|
|
119
119
|
if (err === null || err === void 0 ? void 0 : err.stack)
|
|
120
120
|
out.stack = err.stack;
|
|
121
|
+
if ((err === null || err === void 0 ? void 0 : err.details) != null)
|
|
122
|
+
out.details = sanitizeForLog(err.details);
|
|
121
123
|
if (err === null || err === void 0 ? void 0 : err.response) {
|
|
122
124
|
out.status = (_b = err.response) === null || _b === void 0 ? void 0 : _b.status;
|
|
123
125
|
const data = (_c = err.response) === null || _c === void 0 ? void 0 : _c.data;
|
|
@@ -165,6 +167,8 @@ class FeatureExecutor {
|
|
|
165
167
|
this.functionInvocations = new Map();
|
|
166
168
|
/** Step telemetry is accumulated and persisted with the terminal feature record in one round trip. */
|
|
167
169
|
this.pendingProcessorResults = [];
|
|
170
|
+
this.assetSpans = [];
|
|
171
|
+
this.stepContexts = new Map();
|
|
168
172
|
debugLog('[FeatureExecutor] constructor ENTRY', {
|
|
169
173
|
feature_tag: feature.tag,
|
|
170
174
|
product: options.product,
|
|
@@ -420,8 +424,18 @@ class FeatureExecutor {
|
|
|
420
424
|
const inputStr = stringifyProcessorValue(inputPayload);
|
|
421
425
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
422
426
|
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 });
|
|
427
|
+
const assetResults = this.assetSpans.splice(0).map((span) => {
|
|
428
|
+
const spanResult = stringifyProcessorValue({
|
|
429
|
+
asset_type: span.asset_type,
|
|
430
|
+
asset_tag: span.asset_tag,
|
|
431
|
+
operation: span.asset_operation,
|
|
432
|
+
action: span.asset_action,
|
|
433
|
+
});
|
|
434
|
+
const spanInput = stringifyProcessorValue({});
|
|
435
|
+
return Object.assign(Object.assign({}, span), { process_id: span.span_id, product_id: this.productId || null, product_tag: this.state.product, workspace_id: this.config.workspace_id, env: this.state.env, component: 'asset_invocation', execution_kind: 'asset', retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(spanResult, encKey) : spanResult, input: encKey ? (0, processor_utils_1.encrypt)(spanInput, encKey) : spanInput, asset_duration_ms: span.duration_ms, asset_error: span.error_message });
|
|
436
|
+
});
|
|
423
437
|
this.trace('execution.persistence.sent', { status, payload: resultData });
|
|
424
|
-
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), processorResult], this.getAuthPayload());
|
|
438
|
+
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), ...assetResults, processorResult], this.getAuthPayload());
|
|
425
439
|
this.trace('execution.persistence.acknowledged', { status, process_id: this.state.feature_id });
|
|
426
440
|
debugLog('[FeatureExecutor] persistExecutionResult SUCCESS', { feature_id: this.state.feature_id, status });
|
|
427
441
|
}
|
|
@@ -457,8 +471,8 @@ class FeatureExecutor {
|
|
|
457
471
|
* Persist individual step execution to backend (input/output per step in processor result).
|
|
458
472
|
* Processor results for steps always have component: 'feature_step' and step_type set to the step kind.
|
|
459
473
|
*/
|
|
460
|
-
async persistStepResult(step, status, output, error, duration, input) {
|
|
461
|
-
var _a;
|
|
474
|
+
async persistStepResult(step, status, output, error, duration, input, errorDetails) {
|
|
475
|
+
var _a, _b;
|
|
462
476
|
const resolvedInput = input !== null && input !== void 0 ? input : step.input;
|
|
463
477
|
const stepType = this.getStepTypeForResult(step);
|
|
464
478
|
debugLog('[FeatureExecutor] persistStepResult ENTRY', {
|
|
@@ -475,12 +489,12 @@ class FeatureExecutor {
|
|
|
475
489
|
? output !== undefined && output !== null
|
|
476
490
|
? output
|
|
477
491
|
: {}
|
|
478
|
-
: { error: error !== null && error !== void 0 ? error : 'Step failed' };
|
|
492
|
+
: Object.assign({ error: error !== null && error !== void 0 ? error : 'Step failed' }, (errorDetails != null ? { details: errorDetails } : {}));
|
|
479
493
|
const resultStr = stringifyProcessorValue(value);
|
|
480
494
|
const inputStr = stringifyProcessorValue(resolvedInput);
|
|
481
495
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
482
|
-
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
|
|
483
|
-
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 }), ((
|
|
496
|
+
const stepResult = Object.assign(Object.assign(Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), ((_a = this.stepContexts.get(step.tag)) !== null && _a !== void 0 ? _a : {})), { process_id: stepProcessId, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE_STEP, // step results always feature_step
|
|
497
|
+
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 }), ((_b = this.functionInvocations.get(step.tag)) !== null && _b !== void 0 ? _b : {}));
|
|
484
498
|
this.trace('step.persistence.sent', {
|
|
485
499
|
step_tag: step.tag,
|
|
486
500
|
step_type: stepType,
|
|
@@ -557,6 +571,7 @@ class FeatureExecutor {
|
|
|
557
571
|
session_id: this.sessionLogFields.session_id,
|
|
558
572
|
session_tag: this.sessionLogFields.session_tag,
|
|
559
573
|
session_user_id: this.sessionLogFields.session_user_id,
|
|
574
|
+
asset_span_sink: this.assetSpans,
|
|
560
575
|
});
|
|
561
576
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeInContext());
|
|
562
577
|
}
|
|
@@ -659,7 +674,7 @@ class FeatureExecutor {
|
|
|
659
674
|
}
|
|
660
675
|
debugLog(`[FeatureExecutor] Step "${step.tag}" output:`, stepReturnValue);
|
|
661
676
|
// Persist step result to backend (use step return shape, not raw primitive)
|
|
662
|
-
await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValue, result.error, result.duration, result.input);
|
|
677
|
+
await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValue, result.error, result.duration, result.input, result.errorDetails);
|
|
663
678
|
this.state.step_timings.push({
|
|
664
679
|
tag: step.tag,
|
|
665
680
|
duration_ms: result.duration,
|
|
@@ -825,6 +840,12 @@ class FeatureExecutor {
|
|
|
825
840
|
process_id: `${this.state.feature_id}:${step.tag}`,
|
|
826
841
|
parent_process_id: this.state.feature_id,
|
|
827
842
|
}, parent);
|
|
843
|
+
this.stepContexts.set(step.tag, {
|
|
844
|
+
trace_id: context.trace_id,
|
|
845
|
+
span_id: context.span_id,
|
|
846
|
+
parent_span_id: context.parent_span_id,
|
|
847
|
+
step_run_id: context.step_run_id,
|
|
848
|
+
});
|
|
828
849
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeStepInContext(step));
|
|
829
850
|
}
|
|
830
851
|
async executeStepInContext(step) {
|
|
@@ -845,62 +866,67 @@ class FeatureExecutor {
|
|
|
845
866
|
step_tag: step.tag,
|
|
846
867
|
input: sanitizeForLog(resolvedInput),
|
|
847
868
|
});
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
869
|
+
const asset = this.describeStepAsset(step);
|
|
870
|
+
const runOperation = async () => {
|
|
871
|
+
let value;
|
|
872
|
+
// Route steps to dedicated services; only action and notification use ProcessorService.
|
|
873
|
+
switch (step.type) {
|
|
874
|
+
case types_1.FeatureStepType.ACTION:
|
|
875
|
+
value = await this.executeActionStep(step, resolvedInput);
|
|
876
|
+
break;
|
|
877
|
+
case types_1.FeatureStepType.DATABASE_ACTION:
|
|
878
|
+
value = await this.executeDatabaseStep(step, resolvedInput);
|
|
879
|
+
break;
|
|
880
|
+
case types_1.FeatureStepType.NOTIFICATION:
|
|
881
|
+
value = await this.executeNotificationStep(step, resolvedInput);
|
|
882
|
+
break;
|
|
883
|
+
case types_1.FeatureStepType.STORAGE:
|
|
884
|
+
value = await this.executeStorageStep(step, resolvedInput);
|
|
885
|
+
break;
|
|
886
|
+
case types_1.FeatureStepType.PUBLISH:
|
|
887
|
+
case types_1.FeatureStepType.PRODUCE:
|
|
888
|
+
value = await this.executeProduceStep(step, resolvedInput);
|
|
889
|
+
break;
|
|
890
|
+
case types_1.FeatureStepType.GRAPH:
|
|
891
|
+
value = await this.executeGraphStep(step, resolvedInput);
|
|
892
|
+
break;
|
|
893
|
+
case types_1.FeatureStepType.VECTOR:
|
|
894
|
+
value = await this.executeVectorStep(step, resolvedInput);
|
|
895
|
+
break;
|
|
896
|
+
case types_1.FeatureStepType.SESSION:
|
|
897
|
+
value = await this.executeSessionStep(step, resolvedInput);
|
|
898
|
+
break;
|
|
899
|
+
case types_1.FeatureStepType.FUNCTION:
|
|
900
|
+
value = await this.executeFunctionStep(step, resolvedInput);
|
|
901
|
+
break;
|
|
902
|
+
case types_1.FeatureStepType.QUOTA:
|
|
903
|
+
value = await this.executeQuotaStep(step, resolvedInput);
|
|
904
|
+
break;
|
|
905
|
+
case types_1.FeatureStepType.FALLBACK:
|
|
906
|
+
value = await this.executeFallbackStep(step, resolvedInput);
|
|
907
|
+
break;
|
|
908
|
+
case types_1.FeatureStepType.CHILD_FEATURE:
|
|
909
|
+
value = await this.executeChildWorkflowStep(step, resolvedInput);
|
|
910
|
+
break;
|
|
911
|
+
case types_1.FeatureStepType.SLEEP:
|
|
912
|
+
await this.executeSleepStep(step, resolvedInput);
|
|
913
|
+
value = { slept: true };
|
|
914
|
+
break;
|
|
915
|
+
case types_1.FeatureStepType.WAIT_FOR_SIGNAL:
|
|
916
|
+
value = await this.executeWaitForSignalStep(step, resolvedInput);
|
|
917
|
+
break;
|
|
918
|
+
case types_1.FeatureStepType.CHECKPOINT:
|
|
919
|
+
await this.executeCheckpointStep(step, resolvedInput);
|
|
920
|
+
value = { checkpoint: step.tag };
|
|
921
|
+
break;
|
|
922
|
+
default:
|
|
923
|
+
stepLog('Step type not implemented (passthrough)', { tag: step.tag, type: step.type });
|
|
924
|
+
debugLog('[FeatureExecutor] executeStep unknown step type (passthrough)', { step_tag: step.tag, step_type: step.type });
|
|
925
|
+
value = resolvedInput;
|
|
926
|
+
}
|
|
927
|
+
return value;
|
|
928
|
+
};
|
|
929
|
+
let output = asset ? await (0, context_1.withAssetSpan)(asset, runOperation) : await runOperation();
|
|
904
930
|
// For action steps with no app: if step.output is a template with $ refs (e.g. $Sequence{main}{step-a}{value}-b),
|
|
905
931
|
// resolve it so downstream steps get the correct value (checkpoint / closure-style steps).
|
|
906
932
|
if (step.type === types_1.FeatureStepType.ACTION &&
|
|
@@ -950,13 +976,45 @@ class FeatureExecutor {
|
|
|
950
976
|
success: false,
|
|
951
977
|
input: resolvedInput,
|
|
952
978
|
error: stepErrorMsg,
|
|
979
|
+
errorDetails: details.details,
|
|
953
980
|
duration,
|
|
954
981
|
};
|
|
955
982
|
}
|
|
956
983
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
984
|
+
describeStepAsset(step) {
|
|
985
|
+
var _a, _b;
|
|
986
|
+
const operation = step.event || 'execute';
|
|
987
|
+
switch (step.type) {
|
|
988
|
+
case types_1.FeatureStepType.ACTION:
|
|
989
|
+
return step.app ? { type: 'app', tag: step.app, operation, action: step.event } : null;
|
|
990
|
+
case types_1.FeatureStepType.DATABASE_ACTION:
|
|
991
|
+
return { type: 'database', tag: step.database || 'database', operation, action: step.event };
|
|
992
|
+
case types_1.FeatureStepType.GRAPH:
|
|
993
|
+
return { type: 'graph', tag: step.graph || 'graph', operation, action: step.event };
|
|
994
|
+
case types_1.FeatureStepType.VECTOR:
|
|
995
|
+
return { type: 'vector', tag: step.vector || 'vector', operation, action: step.event };
|
|
996
|
+
case types_1.FeatureStepType.STORAGE:
|
|
997
|
+
return { type: 'storage', tag: step.storage || 'storage', operation, action: step.event };
|
|
998
|
+
case types_1.FeatureStepType.NOTIFICATION:
|
|
999
|
+
return { type: 'notification', tag: step.notification || 'notification', operation, action: step.event };
|
|
1000
|
+
case types_1.FeatureStepType.PUBLISH:
|
|
1001
|
+
case types_1.FeatureStepType.PRODUCE:
|
|
1002
|
+
return { type: 'message_broker', tag: step.broker || 'message-broker', operation: 'produce', action: step.event };
|
|
1003
|
+
case types_1.FeatureStepType.SESSION:
|
|
1004
|
+
return { type: 'session', tag: step.session || 'session', operation, action: step.event };
|
|
1005
|
+
case types_1.FeatureStepType.QUOTA:
|
|
1006
|
+
return { type: 'quota', tag: step.quota || 'quota', operation: 'execute' };
|
|
1007
|
+
case types_1.FeatureStepType.FALLBACK:
|
|
1008
|
+
return { type: 'fallback', tag: step.fallback || 'fallback', operation: 'execute' };
|
|
1009
|
+
case types_1.FeatureStepType.CHILD_FEATURE:
|
|
1010
|
+
return { type: 'feature', tag: step.feature || 'feature', operation: 'execute' };
|
|
1011
|
+
case types_1.FeatureStepType.FUNCTION:
|
|
1012
|
+
return { type: 'function', tag: ((_a = step.function_ref) === null || _a === void 0 ? void 0 : _a.namespace) || 'function', operation: ((_b = step.function_ref) === null || _b === void 0 ? void 0 : _b.operation) || operation };
|
|
1013
|
+
default:
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
/** Execute an action step. */
|
|
960
1018
|
async executeActionStep(step, input) {
|
|
961
1019
|
var _a, _b;
|
|
962
1020
|
debugLog('[FeatureExecutor] executeActionStep', { feature_id: this.state.feature_id, step_tag: step.tag, app: step.app });
|
|
@@ -2658,7 +2716,7 @@ class FeatureExecutor {
|
|
|
2658
2716
|
stepReturnValueResume = undefined;
|
|
2659
2717
|
}
|
|
2660
2718
|
// Persist step result to backend (use step return shape, not raw primitive)
|
|
2661
|
-
await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValueResume, result.error, result.duration, result.input);
|
|
2719
|
+
await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValueResume, result.error, result.duration, result.input, result.errorDetails);
|
|
2662
2720
|
this.state.step_timings.push({
|
|
2663
2721
|
tag: step.tag,
|
|
2664
2722
|
duration_ms: result.duration,
|