@teamkeel/functions-runtime 0.413.0-next.1 → 0.413.2-next.2
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 +136 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -15
- package/dist/index.d.ts +21 -15
- package/dist/index.js +136 -66
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
- package/scripts/oas.ts +86 -0
package/dist/index.cjs
CHANGED
|
@@ -2333,6 +2333,7 @@ __name(tryExecuteFlow, "tryExecuteFlow");
|
|
|
2333
2333
|
// src/flows/ui/elements/input/text.ts
|
|
2334
2334
|
var textInput = /* @__PURE__ */ __name((name, options) => {
|
|
2335
2335
|
return {
|
|
2336
|
+
__type: "input",
|
|
2336
2337
|
uiConfig: {
|
|
2337
2338
|
__type: "ui.input.text",
|
|
2338
2339
|
name,
|
|
@@ -2352,6 +2353,7 @@ var textInput = /* @__PURE__ */ __name((name, options) => {
|
|
|
2352
2353
|
// src/flows/ui/elements/input/number.ts
|
|
2353
2354
|
var numberInput = /* @__PURE__ */ __name((name, options) => {
|
|
2354
2355
|
return {
|
|
2356
|
+
__type: "input",
|
|
2355
2357
|
uiConfig: {
|
|
2356
2358
|
__type: "ui.input.number",
|
|
2357
2359
|
name,
|
|
@@ -2379,6 +2381,7 @@ var divider = /* @__PURE__ */ __name((options) => {
|
|
|
2379
2381
|
// src/flows/ui/elements/input/boolean.ts
|
|
2380
2382
|
var booleanInput = /* @__PURE__ */ __name((name, options) => {
|
|
2381
2383
|
return {
|
|
2384
|
+
__type: "input",
|
|
2382
2385
|
uiConfig: {
|
|
2383
2386
|
__type: "ui.input.boolean",
|
|
2384
2387
|
name,
|
|
@@ -2420,11 +2423,12 @@ var table = /* @__PURE__ */ __name((options) => {
|
|
|
2420
2423
|
};
|
|
2421
2424
|
}, "table");
|
|
2422
2425
|
|
|
2423
|
-
// src/flows/ui/elements/select/
|
|
2426
|
+
// src/flows/ui/elements/select/one.ts
|
|
2424
2427
|
var selectOne = /* @__PURE__ */ __name((name, options) => {
|
|
2425
2428
|
return {
|
|
2429
|
+
__type: "input",
|
|
2426
2430
|
uiConfig: {
|
|
2427
|
-
__type: "ui.select.
|
|
2431
|
+
__type: "ui.select.one",
|
|
2428
2432
|
name,
|
|
2429
2433
|
label: options?.label || name,
|
|
2430
2434
|
defaultValue: options?.defaultValue,
|
|
@@ -2436,6 +2440,20 @@ var selectOne = /* @__PURE__ */ __name((name, options) => {
|
|
|
2436
2440
|
};
|
|
2437
2441
|
}, "selectOne");
|
|
2438
2442
|
|
|
2443
|
+
// src/flows/ui/page.ts
|
|
2444
|
+
var page = /* @__PURE__ */ __name((options) => {
|
|
2445
|
+
const content = options.content;
|
|
2446
|
+
const contentUiConfig = content.map((c) => c.uiConfig).filter(Boolean);
|
|
2447
|
+
return {
|
|
2448
|
+
__type: "ui.page",
|
|
2449
|
+
stage: options.stage,
|
|
2450
|
+
title: options.title,
|
|
2451
|
+
description: options.description,
|
|
2452
|
+
content: contentUiConfig,
|
|
2453
|
+
actions: options.actions
|
|
2454
|
+
};
|
|
2455
|
+
}, "page");
|
|
2456
|
+
|
|
2439
2457
|
// src/flows/disrupts.ts
|
|
2440
2458
|
var FlowDisrupt = class {
|
|
2441
2459
|
static {
|
|
@@ -2454,18 +2472,17 @@ var UIRenderDisrupt = class extends FlowDisrupt {
|
|
|
2454
2472
|
__name(this, "UIRenderDisrupt");
|
|
2455
2473
|
}
|
|
2456
2474
|
};
|
|
2457
|
-
var
|
|
2458
|
-
constructor(message) {
|
|
2459
|
-
super();
|
|
2460
|
-
this.message = message;
|
|
2461
|
-
}
|
|
2475
|
+
var StepCreatedDisrupt = class extends FlowDisrupt {
|
|
2462
2476
|
static {
|
|
2463
|
-
__name(this, "
|
|
2477
|
+
__name(this, "StepCreatedDisrupt");
|
|
2478
|
+
}
|
|
2479
|
+
constructor() {
|
|
2480
|
+
super();
|
|
2464
2481
|
}
|
|
2465
2482
|
};
|
|
2466
|
-
var
|
|
2483
|
+
var ExhuastedRetriesDisrupt = class extends FlowDisrupt {
|
|
2467
2484
|
static {
|
|
2468
|
-
__name(this, "
|
|
2485
|
+
__name(this, "ExhuastedRetriesDisrupt");
|
|
2469
2486
|
}
|
|
2470
2487
|
constructor() {
|
|
2471
2488
|
super();
|
|
@@ -2513,7 +2530,14 @@ var grid = /* @__PURE__ */ __name((options) => {
|
|
|
2513
2530
|
return {
|
|
2514
2531
|
uiConfig: {
|
|
2515
2532
|
__type: "ui.display.grid",
|
|
2516
|
-
data: options.data.map(
|
|
2533
|
+
data: options.data.map((item) => {
|
|
2534
|
+
const rendered = options.render(item);
|
|
2535
|
+
return {
|
|
2536
|
+
title: rendered.title,
|
|
2537
|
+
description: rendered.description,
|
|
2538
|
+
image: rendered.image
|
|
2539
|
+
};
|
|
2540
|
+
})
|
|
2517
2541
|
}
|
|
2518
2542
|
};
|
|
2519
2543
|
}, "grid");
|
|
@@ -2523,7 +2547,14 @@ var list = /* @__PURE__ */ __name((options) => {
|
|
|
2523
2547
|
return {
|
|
2524
2548
|
uiConfig: {
|
|
2525
2549
|
__type: "ui.display.list",
|
|
2526
|
-
data: options.data.map(
|
|
2550
|
+
data: options.data.map((item) => {
|
|
2551
|
+
const rendered = options.render(item);
|
|
2552
|
+
return {
|
|
2553
|
+
title: rendered.title,
|
|
2554
|
+
description: rendered.description,
|
|
2555
|
+
image: rendered.image
|
|
2556
|
+
};
|
|
2557
|
+
})
|
|
2527
2558
|
}
|
|
2528
2559
|
};
|
|
2529
2560
|
}, "list");
|
|
@@ -2547,46 +2578,80 @@ var defaultOpts = {
|
|
|
2547
2578
|
};
|
|
2548
2579
|
function createFlowContext(runId, data, spanId) {
|
|
2549
2580
|
return {
|
|
2550
|
-
step: /* @__PURE__ */ __name(async (name,
|
|
2581
|
+
step: /* @__PURE__ */ __name(async (name, optionsOrFn, fn) => {
|
|
2582
|
+
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
2583
|
+
const actualFn = typeof optionsOrFn === "function" ? optionsOrFn : fn;
|
|
2551
2584
|
const db = useDatabase();
|
|
2552
|
-
const
|
|
2553
|
-
|
|
2554
|
-
|
|
2585
|
+
const past = await db.selectFrom("keel_flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().execute();
|
|
2586
|
+
const newSteps = past.filter((step) => step.status === "NEW" /* NEW */);
|
|
2587
|
+
const completedSteps = past.filter(
|
|
2588
|
+
(step) => step.status === "COMPLETED" /* COMPLETED */
|
|
2589
|
+
);
|
|
2590
|
+
const failedSteps = past.filter(
|
|
2591
|
+
(step) => step.status === "FAILED" /* FAILED */
|
|
2592
|
+
);
|
|
2593
|
+
if (newSteps.length > 1) {
|
|
2594
|
+
throw new Error("Multiple NEW steps found for the same step");
|
|
2595
|
+
}
|
|
2596
|
+
if (completedSteps.length > 1) {
|
|
2597
|
+
throw new Error("Multiple completed steps found for the same step");
|
|
2598
|
+
}
|
|
2599
|
+
if (completedSteps.length > 1 && newSteps.length > 1) {
|
|
2600
|
+
throw new Error(
|
|
2601
|
+
"Multiple completed and new steps found for the same step"
|
|
2602
|
+
);
|
|
2603
|
+
}
|
|
2604
|
+
if (completedSteps.length === 1) {
|
|
2605
|
+
return completedSteps[0].value;
|
|
2606
|
+
}
|
|
2607
|
+
if (newSteps.length === 1) {
|
|
2608
|
+
let result = null;
|
|
2609
|
+
await db.updateTable("keel_flow_step").set({
|
|
2610
|
+
startTime: /* @__PURE__ */ new Date()
|
|
2611
|
+
}).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
|
|
2612
|
+
try {
|
|
2613
|
+
result = await withTimeout(
|
|
2614
|
+
actualFn(),
|
|
2615
|
+
options.timeoutInMs ?? defaultOpts.timeoutInMs
|
|
2616
|
+
);
|
|
2617
|
+
} catch (e) {
|
|
2618
|
+
await db.updateTable("keel_flow_step").set({
|
|
2619
|
+
status: "FAILED" /* FAILED */,
|
|
2620
|
+
spanId,
|
|
2621
|
+
endTime: /* @__PURE__ */ new Date(),
|
|
2622
|
+
error: e instanceof Error ? e.message : "An error occurred"
|
|
2623
|
+
}).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
|
|
2624
|
+
if (failedSteps.length + 1 >= (options.maxRetries ?? defaultOpts.maxRetries)) {
|
|
2625
|
+
throw new ExhuastedRetriesDisrupt();
|
|
2626
|
+
}
|
|
2627
|
+
await db.insertInto("keel_flow_step").values({
|
|
2628
|
+
run_id: runId,
|
|
2629
|
+
name,
|
|
2630
|
+
stage: options.stage,
|
|
2631
|
+
status: "NEW" /* NEW */,
|
|
2632
|
+
type: "FUNCTION" /* FUNCTION */
|
|
2633
|
+
}).returningAll().executeTakeFirst();
|
|
2634
|
+
throw new StepCreatedDisrupt();
|
|
2635
|
+
}
|
|
2636
|
+
await db.updateTable("keel_flow_step").set({
|
|
2637
|
+
status: "COMPLETED" /* COMPLETED */,
|
|
2638
|
+
value: JSON.stringify(result),
|
|
2639
|
+
spanId,
|
|
2640
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2641
|
+
}).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
|
|
2642
|
+
return result;
|
|
2555
2643
|
}
|
|
2556
|
-
|
|
2644
|
+
await db.insertInto("keel_flow_step").values({
|
|
2557
2645
|
run_id: runId,
|
|
2558
2646
|
name,
|
|
2559
2647
|
stage: options.stage,
|
|
2560
2648
|
status: "NEW" /* NEW */,
|
|
2561
|
-
type: "FUNCTION" /* FUNCTION
|
|
2562
|
-
maxRetries: options?.maxRetries ?? defaultOpts.maxRetries,
|
|
2563
|
-
timeoutInMs: options?.timeoutInMs ?? defaultOpts.timeoutInMs
|
|
2649
|
+
type: "FUNCTION" /* FUNCTION */
|
|
2564
2650
|
}).returningAll().executeTakeFirst();
|
|
2565
|
-
|
|
2566
|
-
throw new Error("Failed to create step");
|
|
2567
|
-
}
|
|
2568
|
-
let result = null;
|
|
2569
|
-
try {
|
|
2570
|
-
result = await withTimeout(fn(), step.timeoutInMs);
|
|
2571
|
-
} catch (e) {
|
|
2572
|
-
await db.updateTable("keel_flow_step").set({
|
|
2573
|
-
status: "FAILED" /* FAILED */,
|
|
2574
|
-
spanId
|
|
2575
|
-
// TODO: store error message
|
|
2576
|
-
}).where("id", "=", step.id).returningAll().executeTakeFirst();
|
|
2577
|
-
throw new StepErrorDisrupt(
|
|
2578
|
-
e instanceof Error ? e.message : "an error occurred"
|
|
2579
|
-
);
|
|
2580
|
-
}
|
|
2581
|
-
await db.updateTable("keel_flow_step").set({
|
|
2582
|
-
status: "COMPLETED" /* COMPLETED */,
|
|
2583
|
-
value: JSON.stringify(result),
|
|
2584
|
-
spanId
|
|
2585
|
-
}).where("id", "=", step.id).returningAll().executeTakeFirst();
|
|
2586
|
-
throw new StepCompletedDisrupt();
|
|
2651
|
+
throw new StepCreatedDisrupt();
|
|
2587
2652
|
}, "step"),
|
|
2588
2653
|
ui: {
|
|
2589
|
-
page: /* @__PURE__ */ __name(async (name,
|
|
2654
|
+
page: /* @__PURE__ */ __name(async (name, options) => {
|
|
2590
2655
|
const db = useDatabase();
|
|
2591
2656
|
let step = await db.selectFrom("keel_flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().executeTakeFirst();
|
|
2592
2657
|
if (step && step.status === "COMPLETED" /* COMPLETED */) {
|
|
@@ -2596,26 +2661,23 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2596
2661
|
step = await db.insertInto("keel_flow_step").values({
|
|
2597
2662
|
run_id: runId,
|
|
2598
2663
|
name,
|
|
2599
|
-
stage:
|
|
2664
|
+
stage: options.stage,
|
|
2600
2665
|
status: "PENDING" /* PENDING */,
|
|
2601
2666
|
type: "UI" /* UI */,
|
|
2602
|
-
|
|
2603
|
-
timeoutInMs: 1e3
|
|
2667
|
+
startTime: /* @__PURE__ */ new Date()
|
|
2604
2668
|
}).returningAll().executeTakeFirst();
|
|
2669
|
+
throw new UIRenderDisrupt(step?.id, page(options));
|
|
2605
2670
|
}
|
|
2606
|
-
if (!
|
|
2607
|
-
throw new
|
|
2608
|
-
}
|
|
2609
|
-
if (data) {
|
|
2610
|
-
await db.updateTable("keel_flow_step").set({
|
|
2611
|
-
status: "COMPLETED" /* COMPLETED */,
|
|
2612
|
-
value: JSON.stringify(data),
|
|
2613
|
-
spanId
|
|
2614
|
-
}).where("id", "=", step.id).returningAll().executeTakeFirst();
|
|
2615
|
-
return data;
|
|
2616
|
-
} else {
|
|
2617
|
-
throw new UIRenderDisrupt(step.id, page);
|
|
2671
|
+
if (!data) {
|
|
2672
|
+
throw new UIRenderDisrupt(step?.id, page(options));
|
|
2618
2673
|
}
|
|
2674
|
+
await db.updateTable("keel_flow_step").set({
|
|
2675
|
+
status: "COMPLETED" /* COMPLETED */,
|
|
2676
|
+
value: JSON.stringify(data),
|
|
2677
|
+
spanId,
|
|
2678
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2679
|
+
}).where("id", "=", step.id).returningAll().executeTakeFirst();
|
|
2680
|
+
return data;
|
|
2619
2681
|
}, "page"),
|
|
2620
2682
|
inputs: {
|
|
2621
2683
|
text: textInput,
|
|
@@ -2634,7 +2696,7 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2634
2696
|
list
|
|
2635
2697
|
},
|
|
2636
2698
|
select: {
|
|
2637
|
-
|
|
2699
|
+
one: selectOne
|
|
2638
2700
|
}
|
|
2639
2701
|
}
|
|
2640
2702
|
};
|
|
@@ -2648,7 +2710,7 @@ function withTimeout(promiseFn, timeout) {
|
|
|
2648
2710
|
return Promise.race([
|
|
2649
2711
|
promiseFn,
|
|
2650
2712
|
wait(timeout).then(() => {
|
|
2651
|
-
throw new Error(`
|
|
2713
|
+
throw new Error(`Step function timed out after ${timeout}ms`);
|
|
2652
2714
|
})
|
|
2653
2715
|
]);
|
|
2654
2716
|
}
|
|
@@ -2706,7 +2768,7 @@ async function handleFlow(request, config) {
|
|
|
2706
2768
|
config: flowConfig
|
|
2707
2769
|
});
|
|
2708
2770
|
} catch (e) {
|
|
2709
|
-
if (e instanceof
|
|
2771
|
+
if (e instanceof StepCreatedDisrupt) {
|
|
2710
2772
|
return (0, import_json_rpc_26.createJSONRPCSuccessResponse)(request.id, {
|
|
2711
2773
|
runId,
|
|
2712
2774
|
runCompleted: false,
|
|
@@ -2726,11 +2788,19 @@ async function handleFlow(request, config) {
|
|
|
2726
2788
|
code: opentelemetry6.SpanStatusCode.ERROR,
|
|
2727
2789
|
message: e.message
|
|
2728
2790
|
});
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2791
|
+
if (e instanceof ExhuastedRetriesDisrupt) {
|
|
2792
|
+
return (0, import_json_rpc_26.createJSONRPCSuccessResponse)(request.id, {
|
|
2793
|
+
runId,
|
|
2794
|
+
runCompleted: true,
|
|
2795
|
+
error: "flow failed due to exhausted step retries",
|
|
2796
|
+
config: flowConfig
|
|
2797
|
+
});
|
|
2798
|
+
}
|
|
2799
|
+
return (0, import_json_rpc_26.createJSONRPCErrorResponse)(
|
|
2800
|
+
request.id,
|
|
2801
|
+
import_json_rpc_26.JSONRPCErrorCode.InternalError,
|
|
2802
|
+
e.message
|
|
2803
|
+
);
|
|
2734
2804
|
} finally {
|
|
2735
2805
|
if (db) {
|
|
2736
2806
|
await db.destroy();
|