@botpress/runtime 1.13.9 → 1.13.11

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/dist/define-config.d.ts +23 -1
  2. package/dist/define-config.d.ts.map +1 -1
  3. package/dist/definition.js +438 -293
  4. package/dist/definition.js.map +4 -4
  5. package/dist/internal.js +532 -387
  6. package/dist/internal.js.map +4 -4
  7. package/dist/library.d.ts +4 -2
  8. package/dist/library.d.ts.map +1 -1
  9. package/dist/library.js +465 -287
  10. package/dist/library.js.map +4 -4
  11. package/dist/primitives/conversation.d.ts +24 -11
  12. package/dist/primitives/conversation.d.ts.map +1 -1
  13. package/dist/primitives/data-sources/source-base.d.ts +1 -1
  14. package/dist/primitives/data-sources/source-base.d.ts.map +1 -1
  15. package/dist/primitives/index.d.ts +1 -1
  16. package/dist/primitives/workflow-instance.d.ts +45 -1
  17. package/dist/primitives/workflow-instance.d.ts.map +1 -1
  18. package/dist/primitives/workflow.d.ts +3 -2
  19. package/dist/primitives/workflow.d.ts.map +1 -1
  20. package/dist/runtime/autonomous.d.ts +1 -0
  21. package/dist/runtime/autonomous.d.ts.map +1 -1
  22. package/dist/runtime/context/context.d.ts +21 -0
  23. package/dist/runtime/context/context.d.ts.map +1 -1
  24. package/dist/runtime/context/handlers.d.ts.map +1 -1
  25. package/dist/runtime/handlers/event.d.ts.map +1 -1
  26. package/dist/runtime/handlers/trigger.d.ts.map +1 -1
  27. package/dist/runtime/handlers/workflow.d.ts.map +1 -1
  28. package/dist/runtime/tracked-tags.d.ts +2 -0
  29. package/dist/runtime/tracked-tags.d.ts.map +1 -1
  30. package/dist/runtime.js +503 -317
  31. package/dist/runtime.js.map +4 -4
  32. package/dist/utilities/events.d.ts +28 -0
  33. package/dist/utilities/events.d.ts.map +1 -1
  34. package/dist/utilities/validate-event-name.d.ts +20 -0
  35. package/dist/utilities/validate-event-name.d.ts.map +1 -0
  36. package/package.json +1 -1
package/dist/runtime.js CHANGED
@@ -48,7 +48,7 @@ var init_define_BUILD = __esm({
48
48
  var define_PACKAGE_VERSIONS_default;
49
49
  var init_define_PACKAGE_VERSIONS = __esm({
50
50
  "<define:__PACKAGE_VERSIONS__>"() {
51
- define_PACKAGE_VERSIONS_default = { runtime: "1.13.9", adk: "1.13.9", sdk: "5.0.2", llmz: "0.0.35", zai: "2.5.6", cognitive: "0.3.3" };
51
+ define_PACKAGE_VERSIONS_default = { runtime: "1.13.11", adk: "1.13.11", sdk: "5.0.2", llmz: "0.0.37", zai: "2.5.6", cognitive: "0.3.3" };
52
52
  }
53
53
  });
54
54
 
@@ -14851,7 +14851,7 @@ var init_assets = __esm({
14851
14851
 
14852
14852
  // src/runtime/context/context.ts
14853
14853
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
14854
- var storage, context2;
14854
+ var storage, defaultContext, context2;
14855
14855
  var init_context3 = __esm({
14856
14856
  "src/runtime/context/context.ts"() {
14857
14857
  "use strict";
@@ -14859,6 +14859,7 @@ var init_context3 = __esm({
14859
14859
  init_define_PACKAGE_VERSIONS();
14860
14860
  init_singletons();
14861
14861
  storage = getSingleton("__ADK_GLOBAL_CTX_STORAGE", () => new AsyncLocalStorage2());
14862
+ defaultContext = getSingleton("__ADK_GLOBAL_DEFAULT_CTX", () => ({ value: null }));
14862
14863
  context2 = {
14863
14864
  enterWith: (data) => {
14864
14865
  storage.enterWith(data);
@@ -14877,7 +14878,10 @@ var init_context3 = __esm({
14877
14878
  return store;
14878
14879
  },
14879
14880
  get: (key, opts) => {
14880
- const store = storage.getStore();
14881
+ let store = storage.getStore();
14882
+ if (!store && defaultContext.value) {
14883
+ store = defaultContext.value;
14884
+ }
14881
14885
  if (store) {
14882
14886
  store.states ??= [];
14883
14887
  store.tags ??= [];
@@ -14893,6 +14897,28 @@ var init_context3 = __esm({
14893
14897
  const store = storage.getStore();
14894
14898
  if (!store) throw new Error("Cannot set context outside of `run`");
14895
14899
  store[key] = value;
14900
+ },
14901
+ /**
14902
+ * Set a default context that will be used as a fallback when no AsyncLocalStorage context is active.
14903
+ * This is useful for testing and script execution where code runs outside of request handlers.
14904
+ *
14905
+ * @example
14906
+ * ```typescript
14907
+ * context.setDefaultContext({
14908
+ * botId: 'my-bot',
14909
+ * integrations: agentRegistry.integrations,
14910
+ * interfaces: agentRegistry.interfaces,
14911
+ * })
14912
+ * ```
14913
+ */
14914
+ setDefaultContext: (data) => {
14915
+ defaultContext.value = data;
14916
+ },
14917
+ /**
14918
+ * Clear the default context.
14919
+ */
14920
+ clearDefaultContext: () => {
14921
+ defaultContext.value = null;
14896
14922
  }
14897
14923
  };
14898
14924
  }
@@ -27286,41 +27312,41 @@ var require_ms = __commonJS({
27286
27312
  return void 0;
27287
27313
  }
27288
27314
  }
27289
- function fmtShort(ms3) {
27290
- var msAbs = Math.abs(ms3);
27315
+ function fmtShort(ms4) {
27316
+ var msAbs = Math.abs(ms4);
27291
27317
  if (msAbs >= d) {
27292
- return Math.round(ms3 / d) + "d";
27318
+ return Math.round(ms4 / d) + "d";
27293
27319
  }
27294
27320
  if (msAbs >= h) {
27295
- return Math.round(ms3 / h) + "h";
27321
+ return Math.round(ms4 / h) + "h";
27296
27322
  }
27297
27323
  if (msAbs >= m) {
27298
- return Math.round(ms3 / m) + "m";
27324
+ return Math.round(ms4 / m) + "m";
27299
27325
  }
27300
27326
  if (msAbs >= s) {
27301
- return Math.round(ms3 / s) + "s";
27327
+ return Math.round(ms4 / s) + "s";
27302
27328
  }
27303
- return ms3 + "ms";
27329
+ return ms4 + "ms";
27304
27330
  }
27305
- function fmtLong(ms3) {
27306
- var msAbs = Math.abs(ms3);
27331
+ function fmtLong(ms4) {
27332
+ var msAbs = Math.abs(ms4);
27307
27333
  if (msAbs >= d) {
27308
- return plural(ms3, msAbs, d, "day");
27334
+ return plural(ms4, msAbs, d, "day");
27309
27335
  }
27310
27336
  if (msAbs >= h) {
27311
- return plural(ms3, msAbs, h, "hour");
27337
+ return plural(ms4, msAbs, h, "hour");
27312
27338
  }
27313
27339
  if (msAbs >= m) {
27314
- return plural(ms3, msAbs, m, "minute");
27340
+ return plural(ms4, msAbs, m, "minute");
27315
27341
  }
27316
27342
  if (msAbs >= s) {
27317
- return plural(ms3, msAbs, s, "second");
27343
+ return plural(ms4, msAbs, s, "second");
27318
27344
  }
27319
- return ms3 + " ms";
27345
+ return ms4 + " ms";
27320
27346
  }
27321
- function plural(ms3, msAbs, n, name) {
27347
+ function plural(ms4, msAbs, n, name) {
27322
27348
  var isPlural = msAbs >= n * 1.5;
27323
- return Math.round(ms3 / n) + " " + name + (isPlural ? "s" : "");
27349
+ return Math.round(ms4 / n) + " " + name + (isPlural ? "s" : "");
27324
27350
  }
27325
27351
  }
27326
27352
  });
@@ -27365,8 +27391,8 @@ var require_common = __commonJS({
27365
27391
  }
27366
27392
  const self2 = debug;
27367
27393
  const curr = Number(/* @__PURE__ */ new Date());
27368
- const ms3 = curr - (prevTime || curr);
27369
- self2.diff = ms3;
27394
+ const ms4 = curr - (prevTime || curr);
27395
+ self2.diff = ms4;
27370
27396
  self2.prev = prevTime;
27371
27397
  self2.curr = curr;
27372
27398
  prevTime = curr;
@@ -34273,6 +34299,9 @@ Always prefer information from the knowledge bases over general knowledge when a
34273
34299
  ...props.hooks?.onBeforeTool && {
34274
34300
  onBeforeTool: asyncResource.bind(props.hooks.onBeforeTool)
34275
34301
  },
34302
+ ...props.hooks?.onIterationStart && {
34303
+ onIterationStart: asyncResource.bind(props.hooks.onIterationStart)
34304
+ },
34276
34305
  ...props.hooks?.onAfterTool && {
34277
34306
  onAfterTool: asyncResource.bind(props.hooks.onAfterTool)
34278
34307
  },
@@ -44200,7 +44229,7 @@ var init_actions = __esm({
44200
44229
  }
44201
44230
  integrations ??= context2.get("integrations", { optional: true });
44202
44231
  client2 ??= context2.get("client", { optional: true });
44203
- const integration = integrations.find((i) => i.alias === integrationName);
44232
+ const integration = integrations?.find((i) => i.alias === integrationName);
44204
44233
  const actionDef = integration?.definition.actions?.[actionName];
44205
44234
  const handler = async (params) => {
44206
44235
  integrations ??= context2.get("integrations", { optional: true });
@@ -45123,15 +45152,51 @@ var init_validate_tag_name = __esm({
45123
45152
  }
45124
45153
  });
45125
45154
 
45155
+ // src/utilities/validate-event-name.ts
45156
+ function validateEventName(name) {
45157
+ if (!name || typeof name !== "string") {
45158
+ return { valid: false, error: "Event name must be a non-empty string" };
45159
+ }
45160
+ if (name.length > 100) {
45161
+ return { valid: false, error: `Event name "${name}" must be less than 100 characters` };
45162
+ }
45163
+ if (!/^[a-zA-Z]/.test(name)) {
45164
+ return { valid: false, error: `Event name "${name}" must start with a letter` };
45165
+ }
45166
+ if (!/^[a-zA-Z0-9_]+$/.test(name)) {
45167
+ return {
45168
+ valid: false,
45169
+ error: `Event name "${name}" can only contain letters (A-Z, a-z), numbers (0-9), and underscores (_)`
45170
+ };
45171
+ }
45172
+ return { valid: true };
45173
+ }
45174
+ function validateEventDefinitions(events, context3) {
45175
+ for (const eventName of Object.keys(events)) {
45176
+ const validation = validateEventName(eventName);
45177
+ if (!validation.valid) {
45178
+ throw new Error(`Invalid event name in ${context3}: ${validation.error}`);
45179
+ }
45180
+ }
45181
+ }
45182
+ var init_validate_event_name = __esm({
45183
+ "src/utilities/validate-event-name.ts"() {
45184
+ "use strict";
45185
+ init_define_BUILD();
45186
+ init_define_PACKAGE_VERSIONS();
45187
+ }
45188
+ });
45189
+
45126
45190
  // src/define-config.ts
45127
45191
  import { z as z17 } from "@botpress/sdk";
45128
- var zuiSchema, modelSchema, tagDefinitionSchema, configSchema, AGENT_CONFIG_BRAND, defineConfig;
45192
+ var zuiSchema, modelSchema, tagDefinitionSchema, eventDefinitionSchema, configSchema, AGENT_CONFIG_BRAND, defineConfig;
45129
45193
  var init_define_config = __esm({
45130
45194
  "src/define-config.ts"() {
45131
45195
  "use strict";
45132
45196
  init_define_BUILD();
45133
45197
  init_define_PACKAGE_VERSIONS();
45134
45198
  init_validate_tag_name();
45199
+ init_validate_event_name();
45135
45200
  zuiSchema = z17.custom(
45136
45201
  (val) => {
45137
45202
  if (typeof val === "object" && val !== null && "parse" in val) {
@@ -45156,6 +45221,13 @@ var init_define_config = __esm({
45156
45221
  description: z17.string().optional()
45157
45222
  })
45158
45223
  );
45224
+ eventDefinitionSchema = z17.record(
45225
+ z17.string(),
45226
+ z17.object({
45227
+ schema: zuiSchema.optional(),
45228
+ description: z17.string().optional()
45229
+ })
45230
+ );
45159
45231
  configSchema = z17.object({
45160
45232
  name: z17.string().optional(),
45161
45233
  description: z17.string().optional(),
@@ -45196,7 +45268,8 @@ var init_define_config = __esm({
45196
45268
  zai: val?.zai ?? "openai:gpt-4.1-2025-04-14",
45197
45269
  autonomous: val?.autonomous ?? "openai:gpt-4.1-mini-2025-04-14"
45198
45270
  })),
45199
- dependencies: z17.custom()
45271
+ dependencies: z17.custom(),
45272
+ events: eventDefinitionSchema.optional()
45200
45273
  });
45201
45274
  AGENT_CONFIG_BRAND = Symbol.for("@botpress/runtime/AgentConfig");
45202
45275
  defineConfig = (config) => {
@@ -45216,6 +45289,9 @@ var init_define_config = __esm({
45216
45289
  if (parsed.workflow?.tags) {
45217
45290
  validateTagDefinitions(parsed.workflow.tags, "workflow.tags");
45218
45291
  }
45292
+ if (parsed.events) {
45293
+ validateEventDefinitions(parsed.events, "events");
45294
+ }
45219
45295
  return {
45220
45296
  ...parsed,
45221
45297
  __brand: "AgentConfig",
@@ -45473,12 +45549,12 @@ var init_workflow_step = __esm({
45473
45549
  workflowControlContext.abort();
45474
45550
  throw createStepSignal();
45475
45551
  };
45476
- step.sleep = async (name, ms3) => {
45552
+ step.sleep = async (name, ms4) => {
45477
45553
  await _step(
45478
45554
  name,
45479
45555
  async () => {
45480
45556
  const remainingTime = context2.get("runtime").getRemainingExecutionTimeInMs();
45481
- if (remainingTime - MIN_STEP_REMAINING_TIME_MS <= ms3 || ms3 >= 1e4) {
45557
+ if (remainingTime - MIN_STEP_REMAINING_TIME_MS <= ms4 || ms4 >= 1e4) {
45482
45558
  const client2 = context2.get("client");
45483
45559
  const workflowControlContext = context2.get("workflowControlContext");
45484
45560
  await client2.createEvent({
@@ -45486,7 +45562,7 @@ var init_workflow_step = __esm({
45486
45562
  payload: {},
45487
45563
  workflowId: workflowControlContext.workflow.id,
45488
45564
  schedule: {
45489
- delay: ms3
45565
+ delay: ms4
45490
45566
  }
45491
45567
  });
45492
45568
  await updateWorkflow({
@@ -45495,7 +45571,7 @@ var init_workflow_step = __esm({
45495
45571
  });
45496
45572
  workflowControlContext.abort();
45497
45573
  } else {
45498
- await new Promise((resolve) => void setTimeout(resolve, ms3));
45574
+ await new Promise((resolve) => void setTimeout(resolve, ms4));
45499
45575
  context2.get("workflowControlContext").signal.throwIfAborted();
45500
45576
  }
45501
45577
  },
@@ -45506,8 +45582,8 @@ var init_workflow_step = __esm({
45506
45582
  );
45507
45583
  };
45508
45584
  step.sleepUntil = async (name, date) => {
45509
- const ms3 = Math.max(0, new Date(date).getTime() - Date.now() - MIN_STEP_REMAINING_TIME_MS);
45510
- await step.sleep(name, ms3);
45585
+ const ms4 = Math.max(0, new Date(date).getTime() - Date.now() - MIN_STEP_REMAINING_TIME_MS);
45586
+ await step.sleep(name, ms4);
45511
45587
  };
45512
45588
  step.waitForWorkflow = async (name, workflowId) => {
45513
45589
  const workflowControlContext = context2.get("workflowControlContext");
@@ -45726,12 +45802,13 @@ function createWorkflowExecutionState(client2, workflowId) {
45726
45802
  name: BUILT_IN_STATES.workflowSteps
45727
45803
  });
45728
45804
  }
45729
- var workflowStepContextSchema, workflowExecutionContextSchema, StepSymbol, BaseWorkflowInstance;
45805
+ var import_ms2, workflowStepContextSchema, workflowExecutionContextSchema, StepSymbol, BaseWorkflowInstance;
45730
45806
  var init_workflow_instance = __esm({
45731
45807
  "src/primitives/workflow-instance.ts"() {
45732
45808
  "use strict";
45733
45809
  init_define_BUILD();
45734
45810
  init_define_PACKAGE_VERSIONS();
45811
+ import_ms2 = __toESM(require_ms(), 1);
45735
45812
  init_errors();
45736
45813
  init_library();
45737
45814
  init_autonomous();
@@ -45858,6 +45935,81 @@ var init_workflow_instance = __esm({
45858
45935
  });
45859
45936
  Object.assign(this.workflow, workflow);
45860
45937
  }
45938
+ /**
45939
+ * Extend the workflow timeout by setting a new timeout.
45940
+ * This is useful for long-running workflows that need more time to complete.
45941
+ *
45942
+ * @param options - Either `{ in: string }` for relative duration or `{ at: string }` for absolute ISO timestamp
45943
+ * @returns A promise that resolves when the timeout is updated (can be awaited or not)
45944
+ * @example
45945
+ * // Relative timeout (duration from now):
45946
+ * workflow.setTimeout({ in: '30m' }) // Timeout in 30 minutes
45947
+ * workflow.setTimeout({ in: '6 hours' }) // Timeout in 6 hours
45948
+ *
45949
+ * // Absolute timeout (ISO timestamp):
45950
+ * workflow.setTimeout({ at: '2024-12-25T00:00:00Z' })
45951
+ *
45952
+ * // Optionally await if you need to ensure the update completes:
45953
+ * await workflow.setTimeout({ in: '1h' })
45954
+ */
45955
+ setTimeout(options) {
45956
+ let newTimeoutAt;
45957
+ if ("in" in options) {
45958
+ const durationMs = (0, import_ms2.default)(options.in);
45959
+ if (!durationMs) {
45960
+ throw new Error(`Invalid duration format: "${options.in}". Use formats like "30m", "1h", "6 hours".`);
45961
+ }
45962
+ newTimeoutAt = new Date(Date.now() + durationMs).toISOString();
45963
+ } else {
45964
+ const date = new Date(options.at);
45965
+ if (isNaN(date.getTime())) {
45966
+ throw new Error(`Invalid ISO date format: "${options.at}".`);
45967
+ }
45968
+ newTimeoutAt = date.toISOString();
45969
+ }
45970
+ return updateWorkflow({
45971
+ id: this.id,
45972
+ timeoutAt: newTimeoutAt
45973
+ }).then(({ workflow }) => {
45974
+ Object.assign(this.workflow, workflow);
45975
+ });
45976
+ }
45977
+ /**
45978
+ * Fail the workflow with an error reason.
45979
+ * This immediately interrupts the workflow handler and marks the workflow as failed.
45980
+ * Can only be called from within a workflow handler.
45981
+ *
45982
+ * @param reason - The error reason for the failure
45983
+ * @throws Never returns - always throws to interrupt the handler
45984
+ * @example
45985
+ * workflow.fail('Invalid input data')
45986
+ */
45987
+ fail(reason) {
45988
+ const controlContext = context2.get("workflowControlContext", { optional: true });
45989
+ if (!controlContext || controlContext.workflow.id !== this.id) {
45990
+ throw new Error("workflow.fail() can only be called from within the workflow handler");
45991
+ }
45992
+ controlContext.fail(reason);
45993
+ throw createStepSignal();
45994
+ }
45995
+ /**
45996
+ * Complete the workflow early with the given output.
45997
+ * This immediately interrupts the workflow handler and marks the workflow as completed.
45998
+ * Can only be called from within a workflow handler.
45999
+ *
46000
+ * @param output - The workflow output (typed according to workflow definition)
46001
+ * @throws Never returns - always throws to interrupt the handler
46002
+ * @example
46003
+ * workflow.complete({ result: 'success', data: processedData })
46004
+ */
46005
+ complete(output2) {
46006
+ const controlContext = context2.get("workflowControlContext", { optional: true });
46007
+ if (!controlContext || controlContext.workflow.id !== this.id) {
46008
+ throw new Error("workflow.complete() can only be called from within the workflow handler");
46009
+ }
46010
+ controlContext.complete(output2);
46011
+ throw createStepSignal();
46012
+ }
45861
46013
  /**
45862
46014
  * Provide data in response to a workflow data request (instance method).
45863
46015
  * Call this method from a conversation handler when you receive a WorkflowDataRequestEvent.
@@ -45908,6 +46060,7 @@ var init_workflow_instance = __esm({
45908
46060
  workflow: this.workflow,
45909
46061
  aborted: false,
45910
46062
  failed: false,
46063
+ completed: false,
45911
46064
  acked: false,
45912
46065
  restarted: false,
45913
46066
  signal: abortSignal,
@@ -45922,6 +46075,10 @@ var init_workflow_instance = __esm({
45922
46075
  workflowControlContext.failed = true;
45923
46076
  workflowControlContext.failedReason = reason;
45924
46077
  },
46078
+ complete: (result) => {
46079
+ workflowControlContext.completed = true;
46080
+ workflowControlContext.completedResult = result;
46081
+ },
45925
46082
  ack: async () => {
45926
46083
  if (workflowControlContext.acked) {
45927
46084
  return;
@@ -45975,7 +46132,8 @@ var init_workflow_instance = __esm({
45975
46132
  step,
45976
46133
  client: this.client,
45977
46134
  execute: this.execute.bind(this),
45978
- signal: abortSignal
46135
+ signal: abortSignal,
46136
+ workflow: this
45979
46137
  });
45980
46138
  return {
45981
46139
  status: "done",
@@ -45986,6 +46144,12 @@ var init_workflow_instance = __esm({
45986
46144
  }
45987
46145
  } catch (err) {
45988
46146
  if (isStepSignal(err)) {
46147
+ if (workflowControlContext.completed) {
46148
+ return {
46149
+ status: "done",
46150
+ result: workflowControlContext.completedResult
46151
+ };
46152
+ }
45989
46153
  if (workflowControlContext.failed) {
45990
46154
  return {
45991
46155
  status: "error",
@@ -46601,6 +46765,268 @@ var init_tracked_state = __esm({
46601
46765
  }
46602
46766
  });
46603
46767
 
46768
+ // src/runtime/tracked-tags.ts
46769
+ function isSystemTag(key) {
46770
+ return key.includes(":");
46771
+ }
46772
+ var TrackedTags;
46773
+ var init_tracked_tags = __esm({
46774
+ "src/runtime/tracked-tags.ts"() {
46775
+ "use strict";
46776
+ init_define_BUILD();
46777
+ init_define_PACKAGE_VERSIONS();
46778
+ init_context3();
46779
+ init_tracing();
46780
+ TrackedTags = class _TrackedTags {
46781
+ type;
46782
+ id;
46783
+ client;
46784
+ _tags = {};
46785
+ _initialTags = {};
46786
+ _loaded = false;
46787
+ _saving = false;
46788
+ _saveAgain = false;
46789
+ _saveAgainCount = 0;
46790
+ static _savingAll = false;
46791
+ static _saveAllAgain = false;
46792
+ static _saveAllCount = 0;
46793
+ constructor(props) {
46794
+ this.type = props.type;
46795
+ this.id = props.id;
46796
+ this.client = props.client;
46797
+ }
46798
+ static create(props) {
46799
+ const tags = context2.get("tags", { optional: true });
46800
+ const executionFinished = context2.get("executionFinished", { optional: true });
46801
+ if (executionFinished) {
46802
+ throw new Error(`Cannot create new TrackedTags "${props.type}/${props.id}" after execution has finished.`);
46803
+ }
46804
+ const match2 = tags?.find((x) => x.id === props.id && x.type === props.type);
46805
+ if (match2) {
46806
+ return match2;
46807
+ }
46808
+ const instance = new _TrackedTags(props);
46809
+ if (props.initialTags) {
46810
+ instance._tags = { ...props.initialTags };
46811
+ instance._initialTags = { ...props.initialTags };
46812
+ instance._loaded = true;
46813
+ }
46814
+ tags?.push(instance);
46815
+ return instance;
46816
+ }
46817
+ static async saveAllDirty() {
46818
+ if (this._savingAll) {
46819
+ this._saveAllAgain = true;
46820
+ return;
46821
+ }
46822
+ try {
46823
+ this._savingAll = true;
46824
+ const tags = context2.get("tags", { optional: true });
46825
+ const dirtyTags = tags?.filter((t) => t.isDirty()) || [];
46826
+ if (!dirtyTags.length) {
46827
+ return;
46828
+ }
46829
+ await span(
46830
+ "tags.saveAllDirty",
46831
+ {
46832
+ tags_count: tags?.length || 0,
46833
+ tags: tags.map((t) => `${t.type}/${t.id}`)
46834
+ },
46835
+ () => Promise.allSettled(dirtyTags.map((t) => t.save()))
46836
+ );
46837
+ } finally {
46838
+ this._savingAll = false;
46839
+ if (this._saveAllAgain && this._saveAllCount++ <= 5) {
46840
+ this._saveAllAgain = false;
46841
+ await this.saveAllDirty();
46842
+ } else {
46843
+ this._saveAllCount = 0;
46844
+ }
46845
+ }
46846
+ }
46847
+ static async loadAll() {
46848
+ await span("tags.loadAll", {}, async () => {
46849
+ const client2 = context2.get("client")._inner;
46850
+ const bot2 = context2.get("bot", { optional: true });
46851
+ const user2 = context2.get("user", { optional: true });
46852
+ const conversation = context2.get("conversation", { optional: true });
46853
+ const workflow = context2.get("workflow", { optional: true });
46854
+ if (bot2) {
46855
+ const botTags = bot2.tags;
46856
+ _TrackedTags.create({
46857
+ client: client2,
46858
+ type: "bot",
46859
+ id: bot2.id,
46860
+ ...botTags && { initialTags: botTags }
46861
+ });
46862
+ }
46863
+ if (user2) {
46864
+ const userTags = user2.tags;
46865
+ _TrackedTags.create({
46866
+ client: client2,
46867
+ type: "user",
46868
+ id: user2.id,
46869
+ ...userTags && { initialTags: userTags }
46870
+ });
46871
+ }
46872
+ if (conversation) {
46873
+ const conversationTags = conversation.tags;
46874
+ _TrackedTags.create({
46875
+ client: client2,
46876
+ type: "conversation",
46877
+ id: conversation.id,
46878
+ ...conversationTags && { initialTags: conversationTags }
46879
+ });
46880
+ }
46881
+ if (workflow) {
46882
+ const workflowTags = workflow.tags;
46883
+ _TrackedTags.create({
46884
+ client: client2,
46885
+ type: "workflow",
46886
+ id: workflow.id,
46887
+ ...workflowTags && { initialTags: workflowTags }
46888
+ });
46889
+ }
46890
+ const tags = context2.get("tags", { optional: true });
46891
+ const unloadedTags = tags?.filter((tag) => !tag._loaded) ?? [];
46892
+ if (unloadedTags.length > 0) {
46893
+ await Promise.allSettled(unloadedTags.map((tag) => tag.load()));
46894
+ }
46895
+ });
46896
+ }
46897
+ static unloadAll() {
46898
+ context2.get("tags", { optional: true })?.splice(0);
46899
+ }
46900
+ async load(force = false) {
46901
+ if (this._loaded && !force) {
46902
+ return;
46903
+ }
46904
+ await span(
46905
+ "tags.load",
46906
+ {
46907
+ type: this.type,
46908
+ id: this.id
46909
+ },
46910
+ async () => {
46911
+ const tags = await this.fetchTags();
46912
+ this._tags = { ...tags };
46913
+ this._initialTags = { ...tags };
46914
+ this._loaded = true;
46915
+ }
46916
+ );
46917
+ }
46918
+ async save() {
46919
+ if (this._saving) {
46920
+ this._saveAgain = true;
46921
+ return;
46922
+ }
46923
+ const executionFinished = context2.get("executionFinished", { optional: true });
46924
+ if (executionFinished) {
46925
+ throw new Error(`Cannot save TrackedTags "${this.type}/${this.id}" after execution has finished.`);
46926
+ }
46927
+ try {
46928
+ this._saving = true;
46929
+ await span(
46930
+ "tags.save",
46931
+ {
46932
+ type: this.type,
46933
+ id: this.id
46934
+ },
46935
+ async () => {
46936
+ await this.persistTags(this._tags);
46937
+ this._initialTags = { ...this._tags };
46938
+ }
46939
+ );
46940
+ } finally {
46941
+ this._saving = false;
46942
+ if (this._saveAgain && this._saveAgainCount++ <= 5) {
46943
+ this._saveAgain = false;
46944
+ await this.save();
46945
+ } else {
46946
+ this._saveAgainCount = 0;
46947
+ }
46948
+ }
46949
+ }
46950
+ isDirty() {
46951
+ const currentKeys = Object.keys(this._tags).filter((k) => !isSystemTag(k)).sort();
46952
+ const initialKeys = Object.keys(this._initialTags).filter((k) => !isSystemTag(k)).sort();
46953
+ if (currentKeys.length !== initialKeys.length) {
46954
+ return true;
46955
+ }
46956
+ for (const key of currentKeys) {
46957
+ if (this._tags[key] !== this._initialTags[key]) {
46958
+ return true;
46959
+ }
46960
+ }
46961
+ return false;
46962
+ }
46963
+ get tags() {
46964
+ return new Proxy(this._tags, {
46965
+ set: (target, prop, value) => {
46966
+ if (isSystemTag(prop)) {
46967
+ return true;
46968
+ }
46969
+ target[prop] = value;
46970
+ return true;
46971
+ },
46972
+ deleteProperty: (target, prop) => {
46973
+ if (isSystemTag(prop)) {
46974
+ return true;
46975
+ }
46976
+ target[prop] = void 0;
46977
+ return true;
46978
+ }
46979
+ });
46980
+ }
46981
+ set tags(value) {
46982
+ this._tags = { ...value };
46983
+ }
46984
+ async fetchTags() {
46985
+ try {
46986
+ if (this.type === "bot") {
46987
+ const { bot: bot2 } = await this.client.getBot({ id: this.id });
46988
+ return bot2.tags || {};
46989
+ } else if (this.type === "user") {
46990
+ const { user: user2 } = await this.client.getUser({ id: this.id });
46991
+ return user2.tags || {};
46992
+ } else if (this.type === "conversation") {
46993
+ const { conversation } = await this.client.getConversation({ id: this.id });
46994
+ return conversation.tags || {};
46995
+ } else if (this.type === "workflow") {
46996
+ const { workflow } = await this.client.getWorkflow({ id: this.id });
46997
+ return workflow.tags || {};
46998
+ }
46999
+ } catch (err) {
47000
+ console.error(`Failed to fetch tags for ${this.type}/${this.id}:`, err);
47001
+ }
47002
+ return {};
47003
+ }
47004
+ async persistTags(tags) {
47005
+ const tagsForApi = {};
47006
+ for (const [key, value] of Object.entries(tags)) {
47007
+ if (value !== void 0 && !isSystemTag(key)) {
47008
+ tagsForApi[key] = value;
47009
+ }
47010
+ }
47011
+ try {
47012
+ if (this.type === "bot") {
47013
+ await this.client.updateBot({ id: this.id, tags: tagsForApi });
47014
+ } else if (this.type === "user") {
47015
+ await this.client.updateUser({ id: this.id, tags: tagsForApi });
47016
+ } else if (this.type === "conversation") {
47017
+ await this.client.updateConversation({ id: this.id, tags: tagsForApi });
47018
+ } else if (this.type === "workflow") {
47019
+ await this.client.updateWorkflow({ id: this.id, tags: tagsForApi });
47020
+ }
47021
+ } catch (err) {
47022
+ console.error(`Failed to persist tags for ${this.type}/${this.id}:`, err);
47023
+ throw err;
47024
+ }
47025
+ }
47026
+ };
47027
+ }
47028
+ });
47029
+
46604
47030
  // src/runtime/context/inspector-handler.ts
46605
47031
  async function handleInspectorDisable() {
46606
47032
  const inspector = await import("inspector");
@@ -46743,6 +47169,7 @@ var init_handlers = __esm({
46743
47169
  init_http();
46744
47170
  init_agent_registry();
46745
47171
  init_tracked_state();
47172
+ init_tracked_tags();
46746
47173
  init_tracing();
46747
47174
  init_heavy_imports();
46748
47175
  init_environment();
@@ -46870,12 +47297,13 @@ var init_handlers = __esm({
46870
47297
  reject(error);
46871
47298
  } finally {
46872
47299
  clearTimeout(timeout);
46873
- await TrackedState2.saveAllDirty();
47300
+ await Promise.all([TrackedState2.saveAllDirty(), TrackedTags.saveAllDirty()]);
46874
47301
  }
46875
47302
  });
46876
47303
  } finally {
46877
- await TrackedState2.saveAllDirty();
47304
+ await Promise.all([TrackedState2.saveAllDirty(), TrackedTags.saveAllDirty()]);
46878
47305
  TrackedState2.unloadAll();
47306
+ TrackedTags.unloadAll();
46879
47307
  context2.set("executionFinished", true);
46880
47308
  await shutdownPromiseTracker();
46881
47309
  }
@@ -48343,34 +48771,36 @@ var init_trigger2 = __esm({
48343
48771
  } else {
48344
48772
  events.add(name);
48345
48773
  }
48346
- const [integration, event] = name.split(":");
48347
48774
  const names = /* @__PURE__ */ new Set([name]);
48348
- const int = adk.project.integrations.find((x) => x.alias === integration || x.definition.name === integration);
48349
- if (!int) {
48350
- console.warn(`Integration "${integration}" not found for event "${name}". Skipping trigger registration.`);
48351
- continue;
48775
+ if (name.includes(":")) {
48776
+ const [integration, event] = name.split(":");
48777
+ const int = adk.project.integrations.find((x) => x.alias === integration || x.definition.name === integration);
48778
+ if (!int) {
48779
+ console.warn(`Integration "${integration}" not found for event "${name}". Skipping trigger registration.`);
48780
+ continue;
48781
+ }
48782
+ names.add(`${int.definition.name}:${event}`);
48783
+ names.add(`${int.alias}:${event}`);
48352
48784
  }
48353
- names.add(`${int.definition.name}:${event}`);
48354
- names.add(`${int.alias}:${event}`);
48355
48785
  for (const name2 of names) {
48356
- bot2.on.event(name2, async ({ event: event2, ctx }) => {
48786
+ bot2.on.event(name2, async ({ event, ctx }) => {
48357
48787
  const conversation = context2.get("conversation", { optional: true });
48358
48788
  await span(
48359
48789
  "handler.trigger",
48360
48790
  {
48361
48791
  botId: ctx.botId,
48362
- eventId: event2.id,
48792
+ eventId: event.id,
48363
48793
  "event.type": originalName,
48364
- conversationId: event2.conversationId,
48794
+ conversationId: event.conversationId,
48365
48795
  integration: conversation?.integration,
48366
48796
  channel: conversation?.channel,
48367
- userId: event2.userId
48797
+ userId: event.userId
48368
48798
  },
48369
48799
  async () => {
48370
48800
  console.log(`Evaluating trigger "${trigger.name}" for event "${originalName}" (mapped to "${name2}")`);
48371
48801
  await trigger.handler({
48372
48802
  event: {
48373
- ...event2,
48803
+ ...event,
48374
48804
  type: originalName
48375
48805
  }
48376
48806
  });
@@ -48389,7 +48819,7 @@ var workflow_exports = {};
48389
48819
  __export(workflow_exports, {
48390
48820
  setup: () => setup3
48391
48821
  });
48392
- var import_ms2, setup3;
48822
+ var import_ms3, setup3;
48393
48823
  var init_workflow2 = __esm({
48394
48824
  "src/runtime/handlers/workflow.ts"() {
48395
48825
  "use strict";
@@ -48402,7 +48832,7 @@ var init_workflow2 = __esm({
48402
48832
  init_esm();
48403
48833
  init_adk();
48404
48834
  init_workflow_utils();
48405
- import_ms2 = __toESM(require_ms(), 1);
48835
+ import_ms3 = __toESM(require_ms(), 1);
48406
48836
  setup3 = (bot2) => {
48407
48837
  const handler = async function({ workflow, event, client: client2, ctx, conversation }) {
48408
48838
  await span(
@@ -48430,7 +48860,7 @@ var init_workflow2 = __esm({
48430
48860
  });
48431
48861
  return;
48432
48862
  }
48433
- const DEFAULT_TIMEOUT_MS = (0, import_ms2.default)("5m");
48863
+ const DEFAULT_TIMEOUT_MS = (0, import_ms3.default)("5m");
48434
48864
  const configuredTimeout = workflowDefinition.timeout;
48435
48865
  if (workflow.timeoutAt && configuredTimeout !== DEFAULT_TIMEOUT_MS) {
48436
48866
  const workflowStartedAt = new Date(workflow.createdAt).getTime();
@@ -48448,10 +48878,13 @@ var init_workflow2 = __esm({
48448
48878
  s.setAttribute("workflow.timeout.to", configuredTimeout);
48449
48879
  }
48450
48880
  }
48451
- const instance = await BaseWorkflowInstance.load({
48452
- id: workflow.id,
48453
- workflow
48454
- });
48881
+ const [instance] = await Promise.all([
48882
+ BaseWorkflowInstance.load({
48883
+ id: workflow.id,
48884
+ workflow
48885
+ }),
48886
+ TrackedState2.loadAll()
48887
+ ]);
48455
48888
  void workflow.acknowledgeStartOfProcessing();
48456
48889
  try {
48457
48890
  const interval = setInterval(async () => {
@@ -48606,15 +49039,18 @@ var init_event = __esm({
48606
49039
  logger.warn(`Skipping ${WorkflowCallbackEvent.name} event, conversation not found in context`);
48607
49040
  return;
48608
49041
  }
48609
- let alias = conversation.integration;
48610
- const colonIndex = event.type.indexOf(":");
48611
- if (colonIndex > 0) {
48612
- alias = event.type.substring(0, colonIndex);
48613
- }
48614
- const handlerName = alias + "." + conversation.channel;
48615
- const handler = findMatchingHandler(adk.project.conversations, handlerName);
49042
+ const handlerName = conversation.integration + "." + conversation.channel;
49043
+ const isBuiltInEvent = event.type === WorkflowCallbackEvent.name || event.type === WorkflowDataRequestEvent2.name;
49044
+ const matchingHandlers = adk.project.conversations.filter(
49045
+ (h) => matchesChannel(h.channel, handlerName) && (isBuiltInEvent || h.events.includes(event.type))
49046
+ );
49047
+ const handler = matchingHandlers.sort((a, b) => {
49048
+ const aScore = a.channel === "*" ? 0 : Array.isArray(a.channel) ? 1 : 2;
49049
+ const bScore = b.channel === "*" ? 0 : Array.isArray(b.channel) ? 1 : 2;
49050
+ return bScore - aScore;
49051
+ })[0];
48616
49052
  if (!handler) {
48617
- logger.debug(`Skipping message, no ADK Conversation defined for "${handlerName}"`);
49053
+ logger.debug(`Skipping event "${event.type}", no ADK Conversation listening to this event for channel "${handlerName}"`);
48618
49054
  return;
48619
49055
  }
48620
49056
  await span(
@@ -48632,15 +49068,18 @@ var init_event = __esm({
48632
49068
  async () => {
48633
49069
  const chat = new BotpressChat(context2.getAll());
48634
49070
  context2.set("chat", chat);
48635
- const transcript = await chat.fetchTranscript();
49071
+ const [transcript, _statesLoaded, _tagsLoaded] = await Promise.all([
49072
+ chat.fetchTranscript(),
49073
+ TrackedState2.loadAll(),
49074
+ TrackedTags.loadAll()
49075
+ ]);
48636
49076
  if (transcript.find((x) => x.id === event.id)) {
48637
49077
  logger.debug(`Message ${event.id} already processed`);
48638
49078
  return;
48639
49079
  }
48640
49080
  await chat.addEvent(event);
48641
- await TrackedState2.loadAll();
48642
49081
  await handler[ConversationHandler]();
48643
- await TrackedState2.saveAllDirty();
49082
+ await Promise.all([TrackedState2.saveAllDirty(), TrackedTags.saveAllDirty()]);
48644
49083
  await chat.saveTranscript();
48645
49084
  }
48646
49085
  );
@@ -48733,259 +49172,6 @@ var init_handlers2 = __esm({
48733
49172
  }
48734
49173
  });
48735
49174
 
48736
- // src/runtime/tracked-tags.ts
48737
- var TrackedTags;
48738
- var init_tracked_tags = __esm({
48739
- "src/runtime/tracked-tags.ts"() {
48740
- "use strict";
48741
- init_define_BUILD();
48742
- init_define_PACKAGE_VERSIONS();
48743
- init_context3();
48744
- init_tracing();
48745
- TrackedTags = class _TrackedTags {
48746
- type;
48747
- id;
48748
- client;
48749
- _tags = {};
48750
- _initialTags = {};
48751
- _loaded = false;
48752
- _saving = false;
48753
- _saveAgain = false;
48754
- _saveAgainCount = 0;
48755
- static _savingAll = false;
48756
- static _saveAllAgain = false;
48757
- static _saveAllCount = 0;
48758
- constructor(props) {
48759
- this.type = props.type;
48760
- this.id = props.id;
48761
- this.client = props.client;
48762
- }
48763
- static create(props) {
48764
- const tags = context2.get("tags", { optional: true });
48765
- const executionFinished = context2.get("executionFinished", { optional: true });
48766
- if (executionFinished) {
48767
- throw new Error(`Cannot create new TrackedTags "${props.type}/${props.id}" after execution has finished.`);
48768
- }
48769
- const match2 = tags?.find((x) => x.id === props.id && x.type === props.type);
48770
- if (match2) {
48771
- return match2;
48772
- }
48773
- const instance = new _TrackedTags(props);
48774
- if (props.initialTags) {
48775
- instance._tags = { ...props.initialTags };
48776
- instance._initialTags = { ...props.initialTags };
48777
- instance._loaded = true;
48778
- }
48779
- tags?.push(instance);
48780
- return instance;
48781
- }
48782
- static async saveAllDirty() {
48783
- if (this._savingAll) {
48784
- this._saveAllAgain = true;
48785
- return;
48786
- }
48787
- try {
48788
- this._savingAll = true;
48789
- const tags = context2.get("tags", { optional: true });
48790
- const dirtyTags = tags?.filter((t) => t.isDirty()) || [];
48791
- if (!dirtyTags.length) {
48792
- return;
48793
- }
48794
- await span(
48795
- "tags.saveAllDirty",
48796
- {
48797
- tags_count: tags?.length || 0,
48798
- tags: tags.map((t) => `${t.type}/${t.id}`)
48799
- },
48800
- () => Promise.allSettled(dirtyTags.map((t) => t.save()))
48801
- );
48802
- } finally {
48803
- this._savingAll = false;
48804
- if (this._saveAllAgain && this._saveAllCount++ <= 5) {
48805
- this._saveAllAgain = false;
48806
- await this.saveAllDirty();
48807
- } else {
48808
- this._saveAllCount = 0;
48809
- }
48810
- }
48811
- }
48812
- static async loadAll() {
48813
- await span("tags.loadAll", {}, async () => {
48814
- const client2 = context2.get("client")._inner;
48815
- const bot2 = context2.get("bot", { optional: true });
48816
- const user2 = context2.get("user", { optional: true });
48817
- const conversation = context2.get("conversation", { optional: true });
48818
- const workflow = context2.get("workflow", { optional: true });
48819
- if (bot2) {
48820
- const botTags = bot2.tags;
48821
- _TrackedTags.create({
48822
- client: client2,
48823
- type: "bot",
48824
- id: bot2.id,
48825
- ...botTags && { initialTags: botTags }
48826
- });
48827
- }
48828
- if (user2) {
48829
- const userTags = user2.tags;
48830
- _TrackedTags.create({
48831
- client: client2,
48832
- type: "user",
48833
- id: user2.id,
48834
- ...userTags && { initialTags: userTags }
48835
- });
48836
- }
48837
- if (conversation) {
48838
- const conversationTags = conversation.tags;
48839
- _TrackedTags.create({
48840
- client: client2,
48841
- type: "conversation",
48842
- id: conversation.id,
48843
- ...conversationTags && { initialTags: conversationTags }
48844
- });
48845
- }
48846
- if (workflow) {
48847
- const workflowTags = workflow.tags;
48848
- _TrackedTags.create({
48849
- client: client2,
48850
- type: "workflow",
48851
- id: workflow.id,
48852
- ...workflowTags && { initialTags: workflowTags }
48853
- });
48854
- }
48855
- const tags = context2.get("tags", { optional: true });
48856
- const unloadedTags = tags?.filter((tag) => !tag._loaded) ?? [];
48857
- if (unloadedTags.length > 0) {
48858
- await Promise.allSettled(unloadedTags.map((tag) => tag.load()));
48859
- }
48860
- });
48861
- }
48862
- static unloadAll() {
48863
- context2.get("tags", { optional: true })?.splice(0);
48864
- }
48865
- async load(force = false) {
48866
- if (this._loaded && !force) {
48867
- return;
48868
- }
48869
- await span(
48870
- "tags.load",
48871
- {
48872
- type: this.type,
48873
- id: this.id
48874
- },
48875
- async () => {
48876
- const tags = await this.fetchTags();
48877
- this._tags = { ...tags };
48878
- this._initialTags = { ...tags };
48879
- this._loaded = true;
48880
- }
48881
- );
48882
- }
48883
- async save() {
48884
- if (this._saving) {
48885
- this._saveAgain = true;
48886
- return;
48887
- }
48888
- const executionFinished = context2.get("executionFinished", { optional: true });
48889
- if (executionFinished) {
48890
- throw new Error(`Cannot save TrackedTags "${this.type}/${this.id}" after execution has finished.`);
48891
- }
48892
- try {
48893
- this._saving = true;
48894
- await span(
48895
- "tags.save",
48896
- {
48897
- type: this.type,
48898
- id: this.id
48899
- },
48900
- async () => {
48901
- await this.persistTags(this._tags);
48902
- this._initialTags = { ...this._tags };
48903
- }
48904
- );
48905
- } finally {
48906
- this._saving = false;
48907
- if (this._saveAgain && this._saveAgainCount++ <= 5) {
48908
- this._saveAgain = false;
48909
- await this.save();
48910
- } else {
48911
- this._saveAgainCount = 0;
48912
- }
48913
- }
48914
- }
48915
- isDirty() {
48916
- const currentKeys = Object.keys(this._tags).sort();
48917
- const initialKeys = Object.keys(this._initialTags).sort();
48918
- if (currentKeys.length !== initialKeys.length) {
48919
- return true;
48920
- }
48921
- for (const key of currentKeys) {
48922
- if (this._tags[key] !== this._initialTags[key]) {
48923
- return true;
48924
- }
48925
- }
48926
- return false;
48927
- }
48928
- get tags() {
48929
- return new Proxy(this._tags, {
48930
- set: (target, prop, value) => {
48931
- target[prop] = value;
48932
- return true;
48933
- },
48934
- deleteProperty: (target, prop) => {
48935
- target[prop] = void 0;
48936
- return true;
48937
- }
48938
- });
48939
- }
48940
- set tags(value) {
48941
- this._tags = { ...value };
48942
- }
48943
- async fetchTags() {
48944
- try {
48945
- if (this.type === "bot") {
48946
- const { bot: bot2 } = await this.client.getBot({ id: this.id });
48947
- return bot2.tags || {};
48948
- } else if (this.type === "user") {
48949
- const { user: user2 } = await this.client.getUser({ id: this.id });
48950
- return user2.tags || {};
48951
- } else if (this.type === "conversation") {
48952
- const { conversation } = await this.client.getConversation({ id: this.id });
48953
- return conversation.tags || {};
48954
- } else if (this.type === "workflow") {
48955
- const { workflow } = await this.client.getWorkflow({ id: this.id });
48956
- return workflow.tags || {};
48957
- }
48958
- } catch (err) {
48959
- console.error(`Failed to fetch tags for ${this.type}/${this.id}:`, err);
48960
- }
48961
- return {};
48962
- }
48963
- async persistTags(tags) {
48964
- const tagsForApi = {};
48965
- for (const [key, value] of Object.entries(tags)) {
48966
- if (value !== void 0) {
48967
- tagsForApi[key] = value;
48968
- }
48969
- }
48970
- try {
48971
- if (this.type === "bot") {
48972
- await this.client.updateBot({ id: this.id, tags: tagsForApi });
48973
- } else if (this.type === "user") {
48974
- await this.client.updateUser({ id: this.id, tags: tagsForApi });
48975
- } else if (this.type === "conversation") {
48976
- await this.client.updateConversation({ id: this.id, tags: tagsForApi });
48977
- } else if (this.type === "workflow") {
48978
- await this.client.updateWorkflow({ id: this.id, tags: tagsForApi });
48979
- }
48980
- } catch (err) {
48981
- console.error(`Failed to persist tags for ${this.type}/${this.id}:`, err);
48982
- throw err;
48983
- }
48984
- }
48985
- };
48986
- }
48987
- });
48988
-
48989
49175
  // src/runtime/index.ts
48990
49176
  var init_runtime = __esm({
48991
49177
  "src/runtime/index.ts"() {