@teamkeel/functions-runtime 0.421.2 → 0.421.4

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/index.cjs CHANGED
@@ -247,6 +247,8 @@ var import_pg = require("pg");
247
247
  // src/tracing.js
248
248
  var tracing_exports = {};
249
249
  __export(tracing_exports, {
250
+ KEEL_INTERNAL_ATTR: () => KEEL_INTERNAL_ATTR,
251
+ KEEL_INTERNAL_CHILDREN: () => KEEL_INTERNAL_CHILDREN,
250
252
  forceFlush: () => forceFlush,
251
253
  getTracer: () => getTracer,
252
254
  init: () => init,
@@ -263,11 +265,13 @@ async function withSpan(name, fn) {
263
265
  try {
264
266
  return await fn(span);
265
267
  } catch (err) {
266
- span.recordException(err);
267
- span.setStatus({
268
- code: opentelemetry.SpanStatusCode.ERROR,
269
- message: err.message
270
- });
268
+ if (err instanceof Error) {
269
+ span.recordException(err);
270
+ span.setStatus({
271
+ code: opentelemetry.SpanStatusCode.ERROR,
272
+ message: err.message
273
+ });
274
+ }
271
275
  throw err;
272
276
  } finally {
273
277
  span.end();
@@ -405,6 +409,8 @@ function spanNameForModelAPI(modelName, action) {
405
409
  return `Database ${modelName}.${action}`;
406
410
  }
407
411
  __name(spanNameForModelAPI, "spanNameForModelAPI");
412
+ var KEEL_INTERNAL_ATTR = "keel_internal";
413
+ var KEEL_INTERNAL_CHILDREN = "includeChildrenSpans";
408
414
 
409
415
  // src/database.ts
410
416
  var import_ws = __toESM(require("ws"), 1);
@@ -473,6 +479,7 @@ var InstrumentedPool = class extends import_pg.Pool {
473
479
  const _super = super.connect.bind(this);
474
480
  return withSpan("Database Connect", function(span) {
475
481
  span.setAttribute("dialect", process.env["KEEL_DB_CONN_TYPE"]);
482
+ span.setAttribute(KEEL_INTERNAL_ATTR, true);
476
483
  return _super.apply(null, args);
477
484
  });
478
485
  }
@@ -485,6 +492,7 @@ var InstrumentedNeonServerlessPool = class extends neon.Pool {
485
492
  const _super = super.connect.bind(this);
486
493
  return withSpan("Database Connect", function(span) {
487
494
  span.setAttribute("dialect", process.env["KEEL_DB_CONN_TYPE"]);
495
+ span.setAttribute(KEEL_INTERNAL_ATTR, true);
488
496
  return _super.apply(null, args);
489
497
  });
490
498
  }
@@ -2905,6 +2913,11 @@ var pickList = /* @__PURE__ */ __name((name, options) => {
2905
2913
  uiConfig: {
2906
2914
  __type: "ui.interactive.pickList",
2907
2915
  name,
2916
+ supportedInputs: options.supportedInputs || {
2917
+ scanner: true,
2918
+ manual: true
2919
+ },
2920
+ duplicateHandling: options.duplicateHandling,
2908
2921
  data: options.data.map((item) => {
2909
2922
  const rendered = options.render(item);
2910
2923
  return {
@@ -3036,112 +3049,19 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
3036
3049
  };
3037
3050
  }, "complete"),
3038
3051
  step: /* @__PURE__ */ __name(async (name, optionsOrFn, fn) => {
3039
- const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
3040
- const actualFn = typeof optionsOrFn === "function" ? optionsOrFn : fn;
3041
- options.retries = options.retries ?? defaultOpts.retries;
3042
- options.timeout = options.timeout ?? defaultOpts.timeout;
3043
- const db = useDatabase();
3044
- if (usedNames.has(name)) {
3045
- await db.insertInto("keel.flow_step").values({
3046
- run_id: runId,
3047
- name,
3048
- stage: options.stage,
3049
- status: "FAILED" /* FAILED */,
3050
- type: "FUNCTION" /* FUNCTION */,
3051
- error: `Duplicate step name: ${name}`,
3052
- startTime: /* @__PURE__ */ new Date(),
3053
- endTime: /* @__PURE__ */ new Date()
3054
- }).returningAll().executeTakeFirst();
3055
- throw new Error(`Duplicate step name: ${name}`);
3056
- }
3057
- usedNames.add(name);
3058
- const past = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().execute();
3059
- const newSteps = past.filter((step) => step.status === "NEW" /* NEW */);
3060
- const completedSteps = past.filter(
3061
- (step) => step.status === "COMPLETED" /* COMPLETED */
3062
- );
3063
- const failedSteps = past.filter(
3064
- (step) => step.status === "FAILED" /* FAILED */
3065
- );
3066
- if (newSteps.length > 1) {
3067
- throw new Error("Multiple NEW steps found for the same step");
3068
- }
3069
- if (completedSteps.length > 1) {
3070
- throw new Error("Multiple completed steps found for the same step");
3071
- }
3072
- if (completedSteps.length > 1 && newSteps.length > 1) {
3073
- throw new Error(
3074
- "Multiple completed and new steps found for the same step"
3075
- );
3076
- }
3077
- if (completedSteps.length === 1) {
3078
- return completedSteps[0].value;
3079
- }
3080
- if (newSteps.length === 1) {
3081
- let result = null;
3082
- await db.updateTable("keel.flow_step").set({
3083
- startTime: /* @__PURE__ */ new Date()
3084
- }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3085
- try {
3086
- const stepArgs = {
3087
- attempt: failedSteps.length + 1,
3088
- stepOptions: options
3089
- };
3090
- result = await withTimeout(actualFn(stepArgs), options.timeout);
3091
- } catch (e) {
3092
- await db.updateTable("keel.flow_step").set({
3093
- status: "FAILED" /* FAILED */,
3094
- spanId,
3095
- endTime: /* @__PURE__ */ new Date(),
3096
- error: e instanceof Error ? e.message : "An error occurred"
3097
- }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3098
- if (failedSteps.length >= options.retries || e instanceof NonRetriableError) {
3099
- if (options.onFailure) {
3100
- await options.onFailure();
3101
- }
3102
- throw new ExhuastedRetriesDisrupt();
3103
- }
3104
- await db.insertInto("keel.flow_step").values({
3105
- run_id: runId,
3106
- name,
3107
- stage: options.stage,
3108
- status: "NEW" /* NEW */,
3109
- type: "FUNCTION" /* FUNCTION */
3110
- }).returningAll().executeTakeFirst();
3111
- throw new StepCreatedDisrupt(
3112
- options.retryPolicy ? new Date(
3113
- Date.now() + options.retryPolicy(failedSteps.length + 1)
3114
- ) : void 0
3115
- );
3116
- }
3117
- await db.updateTable("keel.flow_step").set({
3118
- status: "COMPLETED" /* COMPLETED */,
3119
- value: JSON.stringify(result),
3120
- spanId,
3121
- endTime: /* @__PURE__ */ new Date()
3122
- }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3123
- return result;
3124
- }
3125
- await db.insertInto("keel.flow_step").values({
3126
- run_id: runId,
3127
- name,
3128
- stage: options.stage,
3129
- status: "NEW" /* NEW */,
3130
- type: "FUNCTION" /* FUNCTION */
3131
- }).returningAll().executeTakeFirst();
3132
- throw new StepCreatedDisrupt();
3133
- }, "step"),
3134
- ui: {
3135
- page: /* @__PURE__ */ __name(async (name, options) => {
3052
+ return withSpan(`Step - ${name}`, async (span) => {
3053
+ const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
3054
+ const actualFn = typeof optionsOrFn === "function" ? optionsOrFn : fn;
3055
+ options.retries = options.retries ?? defaultOpts.retries;
3056
+ options.timeout = options.timeout ?? defaultOpts.timeout;
3136
3057
  const db = useDatabase();
3137
- const isCallback = element && callback;
3138
3058
  if (usedNames.has(name)) {
3139
3059
  await db.insertInto("keel.flow_step").values({
3140
3060
  run_id: runId,
3141
3061
  name,
3142
3062
  stage: options.stage,
3143
3063
  status: "FAILED" /* FAILED */,
3144
- type: "UI" /* UI */,
3064
+ type: "FUNCTION" /* FUNCTION */,
3145
3065
  error: `Duplicate step name: ${name}`,
3146
3066
  startTime: /* @__PURE__ */ new Date(),
3147
3067
  endTime: /* @__PURE__ */ new Date()
@@ -3149,77 +3069,179 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
3149
3069
  throw new Error(`Duplicate step name: ${name}`);
3150
3070
  }
3151
3071
  usedNames.add(name);
3152
- let step = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().executeTakeFirst();
3153
- if (step && step.status === "COMPLETED" /* COMPLETED */) {
3154
- if (step.action) {
3155
- return { data: step.value, action: step.action };
3156
- }
3157
- return step.value;
3072
+ const past = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().execute();
3073
+ const newSteps = past.filter((step) => step.status === "NEW" /* NEW */);
3074
+ const completedSteps = past.filter(
3075
+ (step) => step.status === "COMPLETED" /* COMPLETED */
3076
+ );
3077
+ const failedSteps = past.filter(
3078
+ (step) => step.status === "FAILED" /* FAILED */
3079
+ );
3080
+ if (newSteps.length > 1) {
3081
+ throw new Error("Multiple NEW steps found for the same step");
3158
3082
  }
3159
- if (!step) {
3160
- step = await db.insertInto("keel.flow_step").values({
3161
- run_id: runId,
3162
- name,
3163
- stage: options.stage,
3164
- status: "PENDING" /* PENDING */,
3165
- type: "UI" /* UI */,
3166
- startTime: /* @__PURE__ */ new Date()
3167
- }).returningAll().executeTakeFirst();
3168
- throw new UIRenderDisrupt(
3169
- step?.id,
3170
- (await page(options, null, null)).page
3083
+ if (completedSteps.length > 1) {
3084
+ throw new Error("Multiple completed steps found for the same step");
3085
+ }
3086
+ if (completedSteps.length > 1 && newSteps.length > 1) {
3087
+ throw new Error(
3088
+ "Multiple completed and new steps found for the same step"
3171
3089
  );
3172
3090
  }
3173
- if (isCallback) {
3091
+ if (completedSteps.length === 1) {
3092
+ span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);
3093
+ return completedSteps[0].value;
3094
+ }
3095
+ if (newSteps.length === 1) {
3096
+ let result = null;
3097
+ await db.updateTable("keel.flow_step").set({
3098
+ startTime: /* @__PURE__ */ new Date()
3099
+ }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3174
3100
  try {
3175
- const response = await callbackFn(
3176
- options.content,
3177
- element,
3178
- callback,
3179
- data
3180
- );
3181
- throw new CallbackDisrupt(response, false);
3101
+ const stepArgs = {
3102
+ attempt: failedSteps.length + 1,
3103
+ stepOptions: options
3104
+ };
3105
+ result = await withTimeout(actualFn(stepArgs), options.timeout);
3182
3106
  } catch (e) {
3183
- if (e instanceof CallbackDisrupt) {
3184
- throw e;
3107
+ await db.updateTable("keel.flow_step").set({
3108
+ status: "FAILED" /* FAILED */,
3109
+ spanId,
3110
+ endTime: /* @__PURE__ */ new Date(),
3111
+ error: e instanceof Error ? e.message : "An error occurred"
3112
+ }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3113
+ if (failedSteps.length >= options.retries || e instanceof NonRetriableError) {
3114
+ if (options.onFailure) {
3115
+ await options.onFailure();
3116
+ }
3117
+ throw new ExhuastedRetriesDisrupt();
3185
3118
  }
3186
- throw new CallbackDisrupt(
3187
- e instanceof Error ? e.message : `An error occurred`,
3188
- true
3119
+ await db.insertInto("keel.flow_step").values({
3120
+ run_id: runId,
3121
+ name,
3122
+ stage: options.stage,
3123
+ status: "NEW" /* NEW */,
3124
+ type: "FUNCTION" /* FUNCTION */
3125
+ }).returningAll().executeTakeFirst();
3126
+ throw new StepCreatedDisrupt(
3127
+ options.retryPolicy ? new Date(
3128
+ Date.now() + options.retryPolicy(failedSteps.length + 1)
3129
+ ) : void 0
3189
3130
  );
3190
3131
  }
3132
+ await db.updateTable("keel.flow_step").set({
3133
+ status: "COMPLETED" /* COMPLETED */,
3134
+ value: JSON.stringify(result),
3135
+ spanId,
3136
+ endTime: /* @__PURE__ */ new Date()
3137
+ }).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
3138
+ return result;
3191
3139
  }
3192
- if (!data) {
3193
- throw new UIRenderDisrupt(
3194
- step?.id,
3195
- (await page(options, null, null)).page
3196
- );
3197
- }
3198
- try {
3199
- const p = await page(options, data, action);
3200
- if (p.hasValidationErrors) {
3201
- throw new UIRenderDisrupt(step?.id, p.page);
3140
+ await db.insertInto("keel.flow_step").values({
3141
+ run_id: runId,
3142
+ name,
3143
+ stage: options.stage,
3144
+ status: "NEW" /* NEW */,
3145
+ type: "FUNCTION" /* FUNCTION */
3146
+ }).returningAll().executeTakeFirst();
3147
+ span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);
3148
+ throw new StepCreatedDisrupt();
3149
+ });
3150
+ }, "step"),
3151
+ ui: {
3152
+ page: /* @__PURE__ */ __name(async (name, options) => {
3153
+ return withSpan(`Page - ${name}`, async (span) => {
3154
+ const db = useDatabase();
3155
+ const isCallback = element && callback;
3156
+ if (usedNames.has(name)) {
3157
+ await db.insertInto("keel.flow_step").values({
3158
+ run_id: runId,
3159
+ name,
3160
+ stage: options.stage,
3161
+ status: "FAILED" /* FAILED */,
3162
+ type: "UI" /* UI */,
3163
+ error: `Duplicate step name: ${name}`,
3164
+ startTime: /* @__PURE__ */ new Date(),
3165
+ endTime: /* @__PURE__ */ new Date()
3166
+ }).returningAll().executeTakeFirst();
3167
+ throw new Error(`Duplicate step name: ${name}`);
3202
3168
  }
3203
- } catch (e) {
3204
- if (e instanceof UIRenderDisrupt) {
3169
+ usedNames.add(name);
3170
+ let step = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().executeTakeFirst();
3171
+ if (step && step.status === "COMPLETED" /* COMPLETED */) {
3172
+ span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);
3173
+ if (step.action) {
3174
+ return { data: step.value, action: step.action };
3175
+ }
3176
+ return step.value;
3177
+ }
3178
+ if (!step) {
3179
+ step = await db.insertInto("keel.flow_step").values({
3180
+ run_id: runId,
3181
+ name,
3182
+ stage: options.stage,
3183
+ status: "PENDING" /* PENDING */,
3184
+ type: "UI" /* UI */,
3185
+ startTime: /* @__PURE__ */ new Date()
3186
+ }).returningAll().executeTakeFirst();
3187
+ span.setAttribute("rendered", true);
3188
+ throw new UIRenderDisrupt(
3189
+ step?.id,
3190
+ (await page(options, null, null)).page
3191
+ );
3192
+ }
3193
+ if (isCallback) {
3194
+ span.setAttribute("callback", callback);
3195
+ try {
3196
+ const response = await callbackFn(
3197
+ options.content,
3198
+ element,
3199
+ callback,
3200
+ data
3201
+ );
3202
+ throw new CallbackDisrupt(response, false);
3203
+ } catch (e) {
3204
+ if (e instanceof CallbackDisrupt) {
3205
+ throw e;
3206
+ }
3207
+ throw new CallbackDisrupt(
3208
+ e instanceof Error ? e.message : `An error occurred`,
3209
+ true
3210
+ );
3211
+ }
3212
+ }
3213
+ if (!data) {
3214
+ throw new UIRenderDisrupt(
3215
+ step?.id,
3216
+ (await page(options, null, null)).page
3217
+ );
3218
+ }
3219
+ try {
3220
+ const p = await page(options, data, action);
3221
+ if (p.hasValidationErrors) {
3222
+ throw new UIRenderDisrupt(step?.id, p.page);
3223
+ }
3224
+ } catch (e) {
3225
+ if (e instanceof UIRenderDisrupt) {
3226
+ throw e;
3227
+ }
3228
+ await db.updateTable("keel.flow_step").set({
3229
+ status: "FAILED" /* FAILED */,
3230
+ spanId,
3231
+ endTime: /* @__PURE__ */ new Date(),
3232
+ error: e instanceof Error ? e.message : "An error occurred"
3233
+ }).where("id", "=", step?.id).returningAll().executeTakeFirst();
3205
3234
  throw e;
3206
3235
  }
3207
3236
  await db.updateTable("keel.flow_step").set({
3208
- status: "FAILED" /* FAILED */,
3237
+ status: "COMPLETED" /* COMPLETED */,
3238
+ value: JSON.stringify(data),
3239
+ action,
3209
3240
  spanId,
3210
- endTime: /* @__PURE__ */ new Date(),
3211
- error: e instanceof Error ? e.message : "An error occurred"
3212
- }).where("id", "=", step?.id).returningAll().executeTakeFirst();
3213
- throw e;
3214
- }
3215
- await db.updateTable("keel.flow_step").set({
3216
- status: "COMPLETED" /* COMPLETED */,
3217
- value: JSON.stringify(data),
3218
- action,
3219
- spanId,
3220
- endTime: /* @__PURE__ */ new Date()
3221
- }).where("id", "=", step.id).returningAll().executeTakeFirst();
3222
- return { data, action };
3241
+ endTime: /* @__PURE__ */ new Date()
3242
+ }).where("id", "=", step.id).returningAll().executeTakeFirst();
3243
+ return { data, action };
3244
+ });
3223
3245
  }, "page"),
3224
3246
  inputs: {
3225
3247
  text: textInput,
@@ -3298,6 +3320,7 @@ async function handleFlow(request, config) {
3298
3320
  );
3299
3321
  return opentelemetry6.context.with(activeContext, () => {
3300
3322
  return withSpan(request.method, async (span) => {
3323
+ span.setAttribute(KEEL_INTERNAL_ATTR, true);
3301
3324
  let db = null;
3302
3325
  let flowConfig = null;
3303
3326
  const runId = request.meta?.runId;
@@ -3355,6 +3378,7 @@ async function handleFlow(request, config) {
3355
3378
  });
3356
3379
  } catch (e) {
3357
3380
  if (e instanceof StepCreatedDisrupt) {
3381
+ span.setAttribute(KEEL_INTERNAL_ATTR, KEEL_INTERNAL_CHILDREN);
3358
3382
  return (0, import_json_rpc_26.createJSONRPCSuccessResponse)(request.id, {
3359
3383
  runId,
3360
3384
  runCompleted: false,
@@ -3376,11 +3400,13 @@ async function handleFlow(request, config) {
3376
3400
  ui: e.contents
3377
3401
  });
3378
3402
  }
3379
- span.recordException(e);
3380
- span.setStatus({
3381
- code: opentelemetry6.SpanStatusCode.ERROR,
3382
- message: e instanceof Error ? e.message : "unknown error"
3383
- });
3403
+ if (e instanceof Error) {
3404
+ span.recordException(e);
3405
+ span.setStatus({
3406
+ code: opentelemetry6.SpanStatusCode.ERROR,
3407
+ message: e instanceof Error ? e.message : "unknown error"
3408
+ });
3409
+ }
3384
3410
  if (e instanceof ExhuastedRetriesDisrupt) {
3385
3411
  return (0, import_json_rpc_26.createJSONRPCSuccessResponse)(request.id, {
3386
3412
  runId,