@ductape/sdk 0.0.5 → 0.0.7

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.
Files changed (36) hide show
  1. package/README.md +87 -53
  2. package/dist/apps/services/app.service.js +14 -5
  3. package/dist/apps/services/app.service.js.map +1 -1
  4. package/dist/apps/utils/string.utils.d.ts +7 -0
  5. package/dist/apps/utils/string.utils.js +33 -1
  6. package/dist/apps/utils/string.utils.js.map +1 -1
  7. package/dist/apps/validators/joi-validators/create.appEnv.validator.js +1 -0
  8. package/dist/apps/validators/joi-validators/create.appEnv.validator.js.map +1 -1
  9. package/dist/apps/validators/joi-validators/update.appEnv.validator.js +1 -0
  10. package/dist/apps/validators/joi-validators/update.appEnv.validator.js.map +1 -1
  11. package/dist/brokers/brokers.service.d.ts +4 -1
  12. package/dist/brokers/brokers.service.js +104 -20
  13. package/dist/brokers/brokers.service.js.map +1 -1
  14. package/dist/database/databases.service.d.ts +15 -0
  15. package/dist/database/databases.service.js +183 -14
  16. package/dist/database/databases.service.js.map +1 -1
  17. package/dist/graph/graphs.service.d.ts +6 -0
  18. package/dist/graph/graphs.service.js +155 -35
  19. package/dist/graph/graphs.service.js.map +1 -1
  20. package/dist/index.d.ts +28 -10
  21. package/dist/index.js +88 -10
  22. package/dist/index.js.map +1 -1
  23. package/dist/processor/services/processor.service.d.ts +15 -2
  24. package/dist/processor/services/processor.service.js +246 -28
  25. package/dist/processor/services/processor.service.js.map +1 -1
  26. package/dist/products/services/products.service.js +23 -24
  27. package/dist/products/services/products.service.js.map +1 -1
  28. package/dist/types/appBuilder.types.d.ts +6 -0
  29. package/dist/vector/vector-database.service.d.ts +6 -0
  30. package/dist/vector/vector-database.service.js +138 -31
  31. package/dist/vector/vector-database.service.js.map +1 -1
  32. package/dist/workflows/workflow-executor.js +99 -44
  33. package/dist/workflows/workflow-executor.js.map +1 -1
  34. package/dist/workflows/workflows.service.js +63 -20
  35. package/dist/workflows/workflows.service.js.map +1 -1
  36. package/package.json +1 -1
@@ -346,31 +346,13 @@ class WorkflowExecutor {
346
346
  durationMs: duration,
347
347
  });
348
348
  try {
349
- // Persist result that matches the step's return shape (workflow definition step.output) when defined
349
+ // Caller passes the step return value (resolved shape) on success; we persist it as-is
350
350
  const stepProcessId = `${this.state.workflow_id}:${step.tag}`;
351
- let value;
352
- if (status === types_1.LogEventStatus.SUCCESS) {
353
- const out = output !== null && output !== void 0 ? output : {};
354
- const raw = typeof out === 'object' && out !== null && 'output' in out
355
- ? out.output
356
- : out;
357
- const outputSchema = step.output;
358
- if (outputSchema && typeof outputSchema === 'object' && !Array.isArray(outputSchema) && Object.keys(outputSchema).length > 0) {
359
- try {
360
- value = await this.resolveInput(outputSchema);
361
- }
362
- catch (_a) {
363
- value = raw;
364
- }
365
- }
366
- else {
367
- value = raw;
368
- }
369
- }
370
- else {
371
- value = { error: error !== null && error !== void 0 ? error : 'Step failed' };
372
- }
373
- const resultPayload = { process_id: stepProcessId, result: value };
351
+ const value = status === types_1.LogEventStatus.SUCCESS
352
+ ? output !== undefined && output !== null
353
+ ? output
354
+ : {}
355
+ : { error: error !== null && error !== void 0 ? error : 'Step failed' };
374
356
  const stepResult = {
375
357
  process_id: stepProcessId,
376
358
  product_id: this.productId || null,
@@ -380,7 +362,7 @@ class WorkflowExecutor {
380
362
  start: Date.now() - (duration || 0),
381
363
  end: Date.now(),
382
364
  retryable: true,
383
- result: JSON.stringify(resultPayload),
365
+ result: JSON.stringify(value),
384
366
  feature_id: undefined,
385
367
  input: JSON.stringify(resolvedInput),
386
368
  workflow_id: this.state.workflow_id,
@@ -489,7 +471,6 @@ class WorkflowExecutor {
489
471
  this.logStepEvent(step, `Step ${step.tag} - started`, logs_types_1.LogEventStatus.PROCESSING);
490
472
  const result = await this.executeStep(step);
491
473
  stepLog('Step end', Object.assign({ tag: step.tag, type: step.type === types_1.WorkflowStepType.PUBLISH ? 'produce' : step.type, success: result.success, duration_ms: result.duration }, (result.error && { error: result.error })));
492
- console.warn(`[WorkflowExecutor] Step "${step.tag}" output:`, result.output);
493
474
  if (result.error) {
494
475
  console.warn(`[WorkflowExecutor] Step "${step.tag}" error:`, result.error);
495
476
  }
@@ -504,8 +485,24 @@ class WorkflowExecutor {
504
485
  });
505
486
  // Log step completion
506
487
  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 });
507
- // Persist step result to backend
508
- await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, result.output, result.error, result.duration, result.input);
488
+ // Step return value = resolved step.output schema with primitive result, or raw when no schema
489
+ const outputSchema = step.output;
490
+ const hasOutputSchema = outputSchema && typeof outputSchema === 'object' && !Array.isArray(outputSchema) && Object.keys(outputSchema).length > 0;
491
+ let stepReturnValue = result.output;
492
+ if (result.success && hasOutputSchema) {
493
+ try {
494
+ stepReturnValue = await this.resolveInput(outputSchema, result.output);
495
+ }
496
+ catch (_p) {
497
+ stepReturnValue = result.output;
498
+ }
499
+ }
500
+ else if (!result.success) {
501
+ stepReturnValue = undefined;
502
+ }
503
+ console.warn(`[WorkflowExecutor] Step "${step.tag}" output:`, stepReturnValue);
504
+ // Persist step result to backend (use step return shape, not raw primitive)
505
+ await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValue, result.error, result.duration, result.input);
509
506
  this.state.step_timings.push({
510
507
  tag: step.tag,
511
508
  duration_ms: result.duration,
@@ -577,8 +574,8 @@ class WorkflowExecutor {
577
574
  },
578
575
  };
579
576
  }
580
- // Store step output and mark as completed
581
- this.state.steps[step.tag] = result.output;
577
+ // Store step return shape in state (same value we persisted)
578
+ this.state.steps[step.tag] = stepReturnValue;
582
579
  this.state.completed_steps.push(step.tag);
583
580
  }
584
581
  this.state.status = types_1.WorkflowStatus.COMPLETED;
@@ -724,6 +721,21 @@ class WorkflowExecutor {
724
721
  debugLog('[WorkflowExecutor] executeStep unknown step type (passthrough)', { step_tag: step.tag, step_type: step.type });
725
722
  output = resolvedInput;
726
723
  }
724
+ // For action steps with no app: if step.output is a template with $ refs (e.g. $Sequence{main}{step-a}{value}-b),
725
+ // resolve it so downstream steps get the correct value (checkpoint / closure-style steps).
726
+ if (step.type === types_1.WorkflowStepType.ACTION &&
727
+ !step.app &&
728
+ step.output &&
729
+ typeof step.output === 'object' &&
730
+ !Array.isArray(step.output) &&
731
+ this.hasOperatorRefsInOutput(step.output)) {
732
+ try {
733
+ output = (await this.resolveInput(step.output));
734
+ }
735
+ catch (_a) {
736
+ // keep output from executeActionStep if resolve fails
737
+ }
738
+ }
727
739
  const duration = Date.now() - startTime;
728
740
  debugLog('[WorkflowExecutor] executeStep output', {
729
741
  workflow_id: this.state.workflow_id,
@@ -1043,17 +1055,25 @@ class WorkflowExecutor {
1043
1055
  * Execute a child workflow step
1044
1056
  */
1045
1057
  async executeChildWorkflowStep(step, input) {
1046
- debugLog('[WorkflowExecutor] executeChildWorkflowStep', { workflow_id: this.state.workflow_id, step_tag: step.tag, child_workflow: step.workflow });
1047
- // Create a new executor for the child workflow
1048
- const childWorkflow = await this.productBuilder.fetchWorkflow(step.workflow);
1058
+ let childTag = step.workflow;
1059
+ if (childTag == null) {
1060
+ const fromResolved = input === null || input === void 0 ? void 0 : input.workflow;
1061
+ const fromStepInput = step.input && typeof step.input === 'object' ? step.input.workflow : undefined;
1062
+ childTag = typeof fromResolved === 'string' ? fromResolved : typeof fromStepInput === 'string' ? fromStepInput : undefined;
1063
+ }
1064
+ debugLog('[WorkflowExecutor] executeChildWorkflowStep', { workflow_id: this.state.workflow_id, step_tag: step.tag, child_workflow: childTag });
1065
+ if (!childTag) {
1066
+ throw new Error('Child workflow step has no workflow tag (missing workflow or step.input.workflow)');
1067
+ }
1068
+ const childWorkflow = await this.productBuilder.fetchWorkflow(childTag);
1049
1069
  if (!childWorkflow) {
1050
- debugLog('[WorkflowExecutor] executeChildWorkflowStep child not found', { step_tag: step.tag, child_workflow: step.workflow });
1051
- throw new Error(`Child workflow ${step.workflow} not found`);
1070
+ debugLog('[WorkflowExecutor] executeChildWorkflowStep child not found', { step_tag: step.tag, child_workflow: childTag });
1071
+ throw new Error(`Child workflow ${childTag} not found`);
1052
1072
  }
1053
1073
  const childExecutor = new WorkflowExecutor(this.config, childWorkflow, {
1054
1074
  product: this.state.product,
1055
1075
  env: this.state.env,
1056
- tag: step.workflow,
1076
+ tag: childTag,
1057
1077
  input,
1058
1078
  }, this._privateKey);
1059
1079
  const result = await childExecutor.execute();
@@ -2139,14 +2159,26 @@ class WorkflowExecutor {
2139
2159
  return lastStep ? this.state.steps[lastStep] : {};
2140
2160
  }
2141
2161
  const hasRefs = this.hasOperatorRefsInOutput(outputDef);
2162
+ let result;
2142
2163
  if (hasRefs) {
2143
- return this.resolveInput(outputDef);
2164
+ result = this.resolveInput(outputDef);
2144
2165
  }
2145
- if (this.isOutputTypeSchema(outputDef)) {
2166
+ else if (this.isOutputTypeSchema(outputDef)) {
2146
2167
  const out = this.buildOutputFromStepsToMatchDefinition(outputDef);
2147
- return Object.keys(out).length > 0 ? out : {};
2168
+ result = Object.keys(out).length > 0 ? out : {};
2169
+ }
2170
+ else {
2171
+ result = this.resolveInput(outputDef);
2148
2172
  }
2149
- return this.resolveInput(outputDef);
2173
+ // recordScenarios: workflow.output is from last scenario; override outcome from which branch actually ran
2174
+ if (result != null && typeof result === 'object' && 'outcome' in result) {
2175
+ const res = result;
2176
+ if (this.state.completed_steps.includes('approve-request'))
2177
+ res.outcome = 'approved';
2178
+ else if (this.state.completed_steps.includes('reject-request'))
2179
+ res.outcome = 'rejected';
2180
+ }
2181
+ return result;
2150
2182
  }
2151
2183
  /**
2152
2184
  * Build output with same keys as workflow definition, values from step_outputs (last step first, then others).
@@ -2160,6 +2192,7 @@ class WorkflowExecutor {
2160
2192
  const out = {};
2161
2193
  const stepsReversed = [...this.state.completed_steps].reverse();
2162
2194
  for (const key of keys) {
2195
+ let found = false;
2163
2196
  for (const stepTag of stepsReversed) {
2164
2197
  const stepData = this.state.steps[stepTag];
2165
2198
  if (stepData == null || typeof stepData !== 'object')
@@ -2167,14 +2200,21 @@ class WorkflowExecutor {
2167
2200
  const rec = stepData;
2168
2201
  if (key in rec) {
2169
2202
  out[key] = rec[key];
2203
+ found = true;
2170
2204
  break;
2171
2205
  }
2172
2206
  const nested = (_a = rec.output) !== null && _a !== void 0 ? _a : rec.result;
2173
2207
  if (nested != null && typeof nested === 'object' && key in nested) {
2174
2208
  out[key] = nested[key];
2209
+ found = true;
2175
2210
  break;
2176
2211
  }
2177
2212
  }
2213
+ // Handler return shape { a, b } often maps to steps step-a, step-b; use step output so out.a.value / out.b.value exist
2214
+ if (!found && this.state.steps[`step-${key}`] != null) {
2215
+ const stepResult = this.state.steps[`step-${key}`];
2216
+ out[key] = ((stepResult === null || stepResult === void 0 ? void 0 : stepResult.output) != null ? stepResult.output : stepResult);
2217
+ }
2178
2218
  }
2179
2219
  if (Object.keys(out).length === 0 && this.state.completed_steps.length > 0) {
2180
2220
  const lastStep = this.state.completed_steps[this.state.completed_steps.length - 1];
@@ -2276,8 +2316,23 @@ class WorkflowExecutor {
2276
2316
  const result = await this.executeStep(step);
2277
2317
  // Log step completion
2278
2318
  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 });
2279
- // Persist step result to backend
2280
- await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, result.output, result.error, result.duration, result.input);
2319
+ // Step return value = resolved step.output schema with primitive result, or raw when no schema
2320
+ const outputSchemaResume = step.output;
2321
+ const hasOutputSchemaResume = outputSchemaResume && typeof outputSchemaResume === 'object' && !Array.isArray(outputSchemaResume) && Object.keys(outputSchemaResume).length > 0;
2322
+ let stepReturnValueResume = result.output;
2323
+ if (result.success && hasOutputSchemaResume) {
2324
+ try {
2325
+ stepReturnValueResume = await this.resolveInput(outputSchemaResume, result.output);
2326
+ }
2327
+ catch (_m) {
2328
+ stepReturnValueResume = result.output;
2329
+ }
2330
+ }
2331
+ else if (!result.success) {
2332
+ stepReturnValueResume = undefined;
2333
+ }
2334
+ // Persist step result to backend (use step return shape, not raw primitive)
2335
+ await this.persistStepResult(step, result.success ? types_1.LogEventStatus.SUCCESS : types_1.LogEventStatus.FAIL, stepReturnValueResume, result.error, result.duration, result.input);
2281
2336
  this.state.step_timings.push({
2282
2337
  tag: step.tag,
2283
2338
  duration_ms: result.duration,
@@ -2324,8 +2379,8 @@ class WorkflowExecutor {
2324
2379
  },
2325
2380
  };
2326
2381
  }
2327
- // Store step output and mark as completed
2328
- this.state.steps[step.tag] = result.output;
2382
+ // Store step return shape in state (same value we persisted)
2383
+ this.state.steps[step.tag] = stepReturnValueResume;
2329
2384
  this.state.completed_steps.push(step.tag);
2330
2385
  }
2331
2386
  this.state.status = types_1.WorkflowStatus.COMPLETED;