@botpress/runtime 1.13.8 → 1.13.10

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 (40) 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 +406 -378
  4. package/dist/definition.js.map +4 -4
  5. package/dist/internal.js +500 -472
  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 +433 -372
  10. package/dist/library.js.map +4 -4
  11. package/dist/primitives/conversation-instance.d.ts +0 -8
  12. package/dist/primitives/conversation-instance.d.ts.map +1 -1
  13. package/dist/primitives/conversation.d.ts +24 -13
  14. package/dist/primitives/conversation.d.ts.map +1 -1
  15. package/dist/primitives/data-sources/source-base.d.ts +1 -1
  16. package/dist/primitives/data-sources/source-base.d.ts.map +1 -1
  17. package/dist/primitives/index.d.ts +1 -1
  18. package/dist/primitives/workflow-instance.d.ts +45 -1
  19. package/dist/primitives/workflow-instance.d.ts.map +1 -1
  20. package/dist/primitives/workflow.d.ts +3 -2
  21. package/dist/primitives/workflow.d.ts.map +1 -1
  22. package/dist/runtime/autonomous.d.ts +1 -0
  23. package/dist/runtime/autonomous.d.ts.map +1 -1
  24. package/dist/runtime/context/context.d.ts +3 -0
  25. package/dist/runtime/context/context.d.ts.map +1 -1
  26. package/dist/runtime/context/handlers.d.ts.map +1 -1
  27. package/dist/runtime/handlers/event.d.ts.map +1 -1
  28. package/dist/runtime/handlers/workflow.d.ts.map +1 -1
  29. package/dist/runtime/tracked-tags.d.ts.map +1 -1
  30. package/dist/runtime.d.ts +0 -1
  31. package/dist/runtime.d.ts.map +1 -1
  32. package/dist/runtime.js +457 -394
  33. package/dist/runtime.js.map +4 -4
  34. package/dist/utilities/events.d.ts +28 -0
  35. package/dist/utilities/events.d.ts.map +1 -1
  36. package/dist/utilities/validate-event-name.d.ts +20 -0
  37. package/dist/utilities/validate-event-name.d.ts.map +1 -0
  38. package/package.json +2 -2
  39. package/dist/utilities/trigger-tags.d.ts +0 -31
  40. package/dist/utilities/trigger-tags.d.ts.map +0 -1
package/dist/library.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.8", adk: "1.13.8", sdk: "5.0.2", llmz: "0.0.35", zai: "2.5.6", cognitive: "0.3.3" };
51
+ define_PACKAGE_VERSIONS_default = { runtime: "1.13.10", adk: "1.13.10", sdk: "5.0.2", llmz: "0.0.35", zai: "2.5.6", cognitive: "0.3.3" };
52
52
  }
53
53
  });
54
54
 
@@ -26314,7 +26314,7 @@ var require_form_data = __commonJS({
26314
26314
  var parseUrl = __require("url").parse;
26315
26315
  var fs3 = __require("fs");
26316
26316
  var Stream2 = __require("stream").Stream;
26317
- var crypto3 = __require("crypto");
26317
+ var crypto2 = __require("crypto");
26318
26318
  var mime = require_mime_types();
26319
26319
  var asynckit = require_asynckit();
26320
26320
  var setToStringTag = require_es_set_tostringtag();
@@ -26520,7 +26520,7 @@ var require_form_data = __commonJS({
26520
26520
  return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]);
26521
26521
  };
26522
26522
  FormData3.prototype._generateBoundary = function() {
26523
- this._boundary = "--------------------------" + crypto3.randomBytes(12).toString("hex");
26523
+ this._boundary = "--------------------------" + crypto2.randomBytes(12).toString("hex");
26524
26524
  };
26525
26525
  FormData3.prototype.getLengthSync = function() {
26526
26526
  var knownLength = this._overheadLength + this._valueLength;
@@ -27795,41 +27795,41 @@ var require_ms = __commonJS({
27795
27795
  return void 0;
27796
27796
  }
27797
27797
  }
27798
- function fmtShort(ms3) {
27799
- var msAbs = Math.abs(ms3);
27798
+ function fmtShort(ms4) {
27799
+ var msAbs = Math.abs(ms4);
27800
27800
  if (msAbs >= d) {
27801
- return Math.round(ms3 / d) + "d";
27801
+ return Math.round(ms4 / d) + "d";
27802
27802
  }
27803
27803
  if (msAbs >= h) {
27804
- return Math.round(ms3 / h) + "h";
27804
+ return Math.round(ms4 / h) + "h";
27805
27805
  }
27806
27806
  if (msAbs >= m) {
27807
- return Math.round(ms3 / m) + "m";
27807
+ return Math.round(ms4 / m) + "m";
27808
27808
  }
27809
27809
  if (msAbs >= s) {
27810
- return Math.round(ms3 / s) + "s";
27810
+ return Math.round(ms4 / s) + "s";
27811
27811
  }
27812
- return ms3 + "ms";
27812
+ return ms4 + "ms";
27813
27813
  }
27814
- function fmtLong(ms3) {
27815
- var msAbs = Math.abs(ms3);
27814
+ function fmtLong(ms4) {
27815
+ var msAbs = Math.abs(ms4);
27816
27816
  if (msAbs >= d) {
27817
- return plural(ms3, msAbs, d, "day");
27817
+ return plural(ms4, msAbs, d, "day");
27818
27818
  }
27819
27819
  if (msAbs >= h) {
27820
- return plural(ms3, msAbs, h, "hour");
27820
+ return plural(ms4, msAbs, h, "hour");
27821
27821
  }
27822
27822
  if (msAbs >= m) {
27823
- return plural(ms3, msAbs, m, "minute");
27823
+ return plural(ms4, msAbs, m, "minute");
27824
27824
  }
27825
27825
  if (msAbs >= s) {
27826
- return plural(ms3, msAbs, s, "second");
27826
+ return plural(ms4, msAbs, s, "second");
27827
27827
  }
27828
- return ms3 + " ms";
27828
+ return ms4 + " ms";
27829
27829
  }
27830
- function plural(ms3, msAbs, n, name) {
27830
+ function plural(ms4, msAbs, n, name) {
27831
27831
  var isPlural = msAbs >= n * 1.5;
27832
- return Math.round(ms3 / n) + " " + name + (isPlural ? "s" : "");
27832
+ return Math.round(ms4 / n) + " " + name + (isPlural ? "s" : "");
27833
27833
  }
27834
27834
  }
27835
27835
  });
@@ -27874,8 +27874,8 @@ var require_common = __commonJS({
27874
27874
  }
27875
27875
  const self2 = debug;
27876
27876
  const curr = Number(/* @__PURE__ */ new Date());
27877
- const ms3 = curr - (prevTime || curr);
27878
- self2.diff = ms3;
27877
+ const ms4 = curr - (prevTime || curr);
27878
+ self2.diff = ms4;
27879
27879
  self2.prev = prevTime;
27880
27880
  self2.curr = curr;
27881
27881
  prevTime = curr;
@@ -34476,6 +34476,9 @@ Always prefer information from the knowledge bases over general knowledge when a
34476
34476
  ...props.hooks?.onBeforeTool && {
34477
34477
  onBeforeTool: asyncResource.bind(props.hooks.onBeforeTool)
34478
34478
  },
34479
+ ...props.hooks?.onIterationStart && {
34480
+ onIterationStart: asyncResource.bind(props.hooks.onIterationStart)
34481
+ },
34479
34482
  ...props.hooks?.onAfterTool && {
34480
34483
  onAfterTool: asyncResource.bind(props.hooks.onAfterTool)
34481
34484
  },
@@ -34821,47 +34824,6 @@ var init_structured_logging = __esm({
34821
34824
  }
34822
34825
  });
34823
34826
 
34824
- // src/utilities/trigger-tags.ts
34825
- var trigger_tags_exports = {};
34826
- __export(trigger_tags_exports, {
34827
- getTriggerSubscriptionTags: () => getTriggerSubscriptionTags,
34828
- getTriggerTagName: () => getTriggerTagName,
34829
- getTriggerTagValue: () => getTriggerTagValue,
34830
- isConversationSubscribedToTrigger: () => isConversationSubscribedToTrigger
34831
- });
34832
- import crypto2 from "crypto";
34833
- var hashString, getTriggerTagName, getTriggerTagValue, getTriggerSubscriptionTags, isConversationSubscribedToTrigger;
34834
- var init_trigger_tags = __esm({
34835
- "src/utilities/trigger-tags.ts"() {
34836
- "use strict";
34837
- init_define_BUILD();
34838
- init_define_PACKAGE_VERSIONS();
34839
- hashString = (str) => {
34840
- return crypto2.createHash("md5").update(str).digest("hex").substring(0, 5).toUpperCase();
34841
- };
34842
- getTriggerTagName = (triggerName) => {
34843
- return `trigger${hashString(triggerName)}`;
34844
- };
34845
- getTriggerTagValue = (key) => {
34846
- return key ?? "*";
34847
- };
34848
- getTriggerSubscriptionTags = (triggerName, key) => {
34849
- return {
34850
- name: getTriggerTagName(triggerName),
34851
- value: getTriggerTagValue(key)
34852
- };
34853
- };
34854
- isConversationSubscribedToTrigger = (conversationTags, triggerName, triggerKey) => {
34855
- const tagName = getTriggerTagName(triggerName);
34856
- const tagValue = conversationTags[tagName];
34857
- if (!tagValue) {
34858
- return false;
34859
- }
34860
- return tagValue === "*" || tagValue === triggerKey;
34861
- };
34862
- }
34863
- });
34864
-
34865
34827
  // src/types.ts
34866
34828
  var init_types2 = __esm({
34867
34829
  "src/types.ts"() {
@@ -35086,15 +35048,51 @@ var init_validate_tag_name = __esm({
35086
35048
  }
35087
35049
  });
35088
35050
 
35051
+ // src/utilities/validate-event-name.ts
35052
+ function validateEventName(name) {
35053
+ if (!name || typeof name !== "string") {
35054
+ return { valid: false, error: "Event name must be a non-empty string" };
35055
+ }
35056
+ if (name.length > 100) {
35057
+ return { valid: false, error: `Event name "${name}" must be less than 100 characters` };
35058
+ }
35059
+ if (!/^[a-zA-Z]/.test(name)) {
35060
+ return { valid: false, error: `Event name "${name}" must start with a letter` };
35061
+ }
35062
+ if (!/^[a-zA-Z0-9_]+$/.test(name)) {
35063
+ return {
35064
+ valid: false,
35065
+ error: `Event name "${name}" can only contain letters (A-Z, a-z), numbers (0-9), and underscores (_)`
35066
+ };
35067
+ }
35068
+ return { valid: true };
35069
+ }
35070
+ function validateEventDefinitions(events, context3) {
35071
+ for (const eventName of Object.keys(events)) {
35072
+ const validation = validateEventName(eventName);
35073
+ if (!validation.valid) {
35074
+ throw new Error(`Invalid event name in ${context3}: ${validation.error}`);
35075
+ }
35076
+ }
35077
+ }
35078
+ var init_validate_event_name = __esm({
35079
+ "src/utilities/validate-event-name.ts"() {
35080
+ "use strict";
35081
+ init_define_BUILD();
35082
+ init_define_PACKAGE_VERSIONS();
35083
+ }
35084
+ });
35085
+
35089
35086
  // src/define-config.ts
35090
35087
  import { z as z3 } from "@botpress/sdk";
35091
- var zuiSchema, modelSchema, tagDefinitionSchema, configSchema, AGENT_CONFIG_BRAND, defineConfig;
35088
+ var zuiSchema, modelSchema, tagDefinitionSchema, eventDefinitionSchema, configSchema, AGENT_CONFIG_BRAND, defineConfig;
35092
35089
  var init_define_config = __esm({
35093
35090
  "src/define-config.ts"() {
35094
35091
  "use strict";
35095
35092
  init_define_BUILD();
35096
35093
  init_define_PACKAGE_VERSIONS();
35097
35094
  init_validate_tag_name();
35095
+ init_validate_event_name();
35098
35096
  zuiSchema = z3.custom(
35099
35097
  (val) => {
35100
35098
  if (typeof val === "object" && val !== null && "parse" in val) {
@@ -35119,6 +35117,13 @@ var init_define_config = __esm({
35119
35117
  description: z3.string().optional()
35120
35118
  })
35121
35119
  );
35120
+ eventDefinitionSchema = z3.record(
35121
+ z3.string(),
35122
+ z3.object({
35123
+ schema: zuiSchema.optional(),
35124
+ description: z3.string().optional()
35125
+ })
35126
+ );
35122
35127
  configSchema = z3.object({
35123
35128
  name: z3.string().optional(),
35124
35129
  description: z3.string().optional(),
@@ -35159,7 +35164,8 @@ var init_define_config = __esm({
35159
35164
  zai: val?.zai ?? "openai:gpt-4.1-2025-04-14",
35160
35165
  autonomous: val?.autonomous ?? "openai:gpt-4.1-mini-2025-04-14"
35161
35166
  })),
35162
- dependencies: z3.custom()
35167
+ dependencies: z3.custom(),
35168
+ events: eventDefinitionSchema.optional()
35163
35169
  });
35164
35170
  AGENT_CONFIG_BRAND = Symbol.for("@botpress/runtime/AgentConfig");
35165
35171
  defineConfig = (config) => {
@@ -35179,6 +35185,9 @@ var init_define_config = __esm({
35179
35185
  if (parsed.workflow?.tags) {
35180
35186
  validateTagDefinitions(parsed.workflow.tags, "workflow.tags");
35181
35187
  }
35188
+ if (parsed.events) {
35189
+ validateEventDefinitions(parsed.events, "events");
35190
+ }
35182
35191
  return {
35183
35192
  ...parsed,
35184
35193
  __brand: "AgentConfig",
@@ -35201,7 +35210,6 @@ var init_runtime = __esm({
35201
35210
  init_structured_logging();
35202
35211
  init_environment();
35203
35212
  init_runtime2();
35204
- init_trigger_tags();
35205
35213
  init_types2();
35206
35214
  init_errors();
35207
35215
  init_state();
@@ -35954,6 +35962,9 @@ function isEventMessage(event) {
35954
35962
  function isWorkflowCallback(event) {
35955
35963
  return event !== null && typeof event === "object" && "type" in event && event.type === "workflowCallback" && "payload" in event && event.payload !== null && typeof event.payload === "object";
35956
35964
  }
35965
+ function isEventOfType(event, eventName) {
35966
+ return isEvent(event) && event.type === eventName;
35967
+ }
35957
35968
  var init_events = __esm({
35958
35969
  "src/utilities/events.ts"() {
35959
35970
  "use strict";
@@ -36227,12 +36238,12 @@ var init_workflow_step = __esm({
36227
36238
  workflowControlContext.abort();
36228
36239
  throw createStepSignal();
36229
36240
  };
36230
- step.sleep = async (name, ms3) => {
36241
+ step.sleep = async (name, ms4) => {
36231
36242
  await _step(
36232
36243
  name,
36233
36244
  async () => {
36234
36245
  const remainingTime = context.get("runtime").getRemainingExecutionTimeInMs();
36235
- if (remainingTime - MIN_STEP_REMAINING_TIME_MS <= ms3 || ms3 >= 1e4) {
36246
+ if (remainingTime - MIN_STEP_REMAINING_TIME_MS <= ms4 || ms4 >= 1e4) {
36236
36247
  const client2 = context.get("client");
36237
36248
  const workflowControlContext = context.get("workflowControlContext");
36238
36249
  await client2.createEvent({
@@ -36240,7 +36251,7 @@ var init_workflow_step = __esm({
36240
36251
  payload: {},
36241
36252
  workflowId: workflowControlContext.workflow.id,
36242
36253
  schedule: {
36243
- delay: ms3
36254
+ delay: ms4
36244
36255
  }
36245
36256
  });
36246
36257
  await updateWorkflow({
@@ -36249,7 +36260,7 @@ var init_workflow_step = __esm({
36249
36260
  });
36250
36261
  workflowControlContext.abort();
36251
36262
  } else {
36252
- await new Promise((resolve) => void setTimeout(resolve, ms3));
36263
+ await new Promise((resolve) => void setTimeout(resolve, ms4));
36253
36264
  context.get("workflowControlContext").signal.throwIfAborted();
36254
36265
  }
36255
36266
  },
@@ -36260,8 +36271,8 @@ var init_workflow_step = __esm({
36260
36271
  );
36261
36272
  };
36262
36273
  step.sleepUntil = async (name, date) => {
36263
- const ms3 = Math.max(0, new Date(date).getTime() - Date.now() - MIN_STEP_REMAINING_TIME_MS);
36264
- await step.sleep(name, ms3);
36274
+ const ms4 = Math.max(0, new Date(date).getTime() - Date.now() - MIN_STEP_REMAINING_TIME_MS);
36275
+ await step.sleep(name, ms4);
36265
36276
  };
36266
36277
  step.waitForWorkflow = async (name, workflowId) => {
36267
36278
  const workflowControlContext = context.get("workflowControlContext");
@@ -36480,12 +36491,13 @@ function createWorkflowExecutionState(client2, workflowId) {
36480
36491
  name: BUILT_IN_STATES.workflowSteps
36481
36492
  });
36482
36493
  }
36483
- var workflowStepContextSchema, workflowExecutionContextSchema, StepSymbol, BaseWorkflowInstance;
36494
+ var import_ms2, workflowStepContextSchema, workflowExecutionContextSchema, StepSymbol, BaseWorkflowInstance;
36484
36495
  var init_workflow_instance = __esm({
36485
36496
  "src/primitives/workflow-instance.ts"() {
36486
36497
  "use strict";
36487
36498
  init_define_BUILD();
36488
36499
  init_define_PACKAGE_VERSIONS();
36500
+ import_ms2 = __toESM(require_ms(), 1);
36489
36501
  init_errors();
36490
36502
  init_library();
36491
36503
  init_autonomous();
@@ -36612,6 +36624,81 @@ var init_workflow_instance = __esm({
36612
36624
  });
36613
36625
  Object.assign(this.workflow, workflow);
36614
36626
  }
36627
+ /**
36628
+ * Extend the workflow timeout by setting a new timeout.
36629
+ * This is useful for long-running workflows that need more time to complete.
36630
+ *
36631
+ * @param options - Either `{ in: string }` for relative duration or `{ at: string }` for absolute ISO timestamp
36632
+ * @returns A promise that resolves when the timeout is updated (can be awaited or not)
36633
+ * @example
36634
+ * // Relative timeout (duration from now):
36635
+ * workflow.setTimeout({ in: '30m' }) // Timeout in 30 minutes
36636
+ * workflow.setTimeout({ in: '6 hours' }) // Timeout in 6 hours
36637
+ *
36638
+ * // Absolute timeout (ISO timestamp):
36639
+ * workflow.setTimeout({ at: '2024-12-25T00:00:00Z' })
36640
+ *
36641
+ * // Optionally await if you need to ensure the update completes:
36642
+ * await workflow.setTimeout({ in: '1h' })
36643
+ */
36644
+ setTimeout(options) {
36645
+ let newTimeoutAt;
36646
+ if ("in" in options) {
36647
+ const durationMs = (0, import_ms2.default)(options.in);
36648
+ if (!durationMs) {
36649
+ throw new Error(`Invalid duration format: "${options.in}". Use formats like "30m", "1h", "6 hours".`);
36650
+ }
36651
+ newTimeoutAt = new Date(Date.now() + durationMs).toISOString();
36652
+ } else {
36653
+ const date = new Date(options.at);
36654
+ if (isNaN(date.getTime())) {
36655
+ throw new Error(`Invalid ISO date format: "${options.at}".`);
36656
+ }
36657
+ newTimeoutAt = date.toISOString();
36658
+ }
36659
+ return updateWorkflow({
36660
+ id: this.id,
36661
+ timeoutAt: newTimeoutAt
36662
+ }).then(({ workflow }) => {
36663
+ Object.assign(this.workflow, workflow);
36664
+ });
36665
+ }
36666
+ /**
36667
+ * Fail the workflow with an error reason.
36668
+ * This immediately interrupts the workflow handler and marks the workflow as failed.
36669
+ * Can only be called from within a workflow handler.
36670
+ *
36671
+ * @param reason - The error reason for the failure
36672
+ * @throws Never returns - always throws to interrupt the handler
36673
+ * @example
36674
+ * workflow.fail('Invalid input data')
36675
+ */
36676
+ fail(reason) {
36677
+ const controlContext = context.get("workflowControlContext", { optional: true });
36678
+ if (!controlContext || controlContext.workflow.id !== this.id) {
36679
+ throw new Error("workflow.fail() can only be called from within the workflow handler");
36680
+ }
36681
+ controlContext.fail(reason);
36682
+ throw createStepSignal();
36683
+ }
36684
+ /**
36685
+ * Complete the workflow early with the given output.
36686
+ * This immediately interrupts the workflow handler and marks the workflow as completed.
36687
+ * Can only be called from within a workflow handler.
36688
+ *
36689
+ * @param output - The workflow output (typed according to workflow definition)
36690
+ * @throws Never returns - always throws to interrupt the handler
36691
+ * @example
36692
+ * workflow.complete({ result: 'success', data: processedData })
36693
+ */
36694
+ complete(output2) {
36695
+ const controlContext = context.get("workflowControlContext", { optional: true });
36696
+ if (!controlContext || controlContext.workflow.id !== this.id) {
36697
+ throw new Error("workflow.complete() can only be called from within the workflow handler");
36698
+ }
36699
+ controlContext.complete(output2);
36700
+ throw createStepSignal();
36701
+ }
36615
36702
  /**
36616
36703
  * Provide data in response to a workflow data request (instance method).
36617
36704
  * Call this method from a conversation handler when you receive a WorkflowDataRequestEvent.
@@ -36662,6 +36749,7 @@ var init_workflow_instance = __esm({
36662
36749
  workflow: this.workflow,
36663
36750
  aborted: false,
36664
36751
  failed: false,
36752
+ completed: false,
36665
36753
  acked: false,
36666
36754
  restarted: false,
36667
36755
  signal: abortSignal,
@@ -36676,6 +36764,10 @@ var init_workflow_instance = __esm({
36676
36764
  workflowControlContext.failed = true;
36677
36765
  workflowControlContext.failedReason = reason;
36678
36766
  },
36767
+ complete: (result) => {
36768
+ workflowControlContext.completed = true;
36769
+ workflowControlContext.completedResult = result;
36770
+ },
36679
36771
  ack: async () => {
36680
36772
  if (workflowControlContext.acked) {
36681
36773
  return;
@@ -36729,7 +36821,8 @@ var init_workflow_instance = __esm({
36729
36821
  step,
36730
36822
  client: this.client,
36731
36823
  execute: this.execute.bind(this),
36732
- signal: abortSignal
36824
+ signal: abortSignal,
36825
+ workflow: this
36733
36826
  });
36734
36827
  return {
36735
36828
  status: "done",
@@ -36740,6 +36833,12 @@ var init_workflow_instance = __esm({
36740
36833
  }
36741
36834
  } catch (err) {
36742
36835
  if (isStepSignal(err)) {
36836
+ if (workflowControlContext.completed) {
36837
+ return {
36838
+ status: "done",
36839
+ result: workflowControlContext.completedResult
36840
+ };
36841
+ }
36743
36842
  if (workflowControlContext.failed) {
36744
36843
  return {
36745
36844
  status: "error",
@@ -37355,6 +37454,259 @@ var init_tracked_state = __esm({
37355
37454
  }
37356
37455
  });
37357
37456
 
37457
+ // src/runtime/tracked-tags.ts
37458
+ var TrackedTags;
37459
+ var init_tracked_tags = __esm({
37460
+ "src/runtime/tracked-tags.ts"() {
37461
+ "use strict";
37462
+ init_define_BUILD();
37463
+ init_define_PACKAGE_VERSIONS();
37464
+ init_context();
37465
+ init_tracing();
37466
+ TrackedTags = class _TrackedTags {
37467
+ type;
37468
+ id;
37469
+ client;
37470
+ _tags = {};
37471
+ _initialTags = {};
37472
+ _loaded = false;
37473
+ _saving = false;
37474
+ _saveAgain = false;
37475
+ _saveAgainCount = 0;
37476
+ static _savingAll = false;
37477
+ static _saveAllAgain = false;
37478
+ static _saveAllCount = 0;
37479
+ constructor(props) {
37480
+ this.type = props.type;
37481
+ this.id = props.id;
37482
+ this.client = props.client;
37483
+ }
37484
+ static create(props) {
37485
+ const tags = context.get("tags", { optional: true });
37486
+ const executionFinished = context.get("executionFinished", { optional: true });
37487
+ if (executionFinished) {
37488
+ throw new Error(`Cannot create new TrackedTags "${props.type}/${props.id}" after execution has finished.`);
37489
+ }
37490
+ const match2 = tags?.find((x) => x.id === props.id && x.type === props.type);
37491
+ if (match2) {
37492
+ return match2;
37493
+ }
37494
+ const instance = new _TrackedTags(props);
37495
+ if (props.initialTags) {
37496
+ instance._tags = { ...props.initialTags };
37497
+ instance._initialTags = { ...props.initialTags };
37498
+ instance._loaded = true;
37499
+ }
37500
+ tags?.push(instance);
37501
+ return instance;
37502
+ }
37503
+ static async saveAllDirty() {
37504
+ if (this._savingAll) {
37505
+ this._saveAllAgain = true;
37506
+ return;
37507
+ }
37508
+ try {
37509
+ this._savingAll = true;
37510
+ const tags = context.get("tags", { optional: true });
37511
+ const dirtyTags = tags?.filter((t) => t.isDirty()) || [];
37512
+ if (!dirtyTags.length) {
37513
+ return;
37514
+ }
37515
+ await span(
37516
+ "tags.saveAllDirty",
37517
+ {
37518
+ tags_count: tags?.length || 0,
37519
+ tags: tags.map((t) => `${t.type}/${t.id}`)
37520
+ },
37521
+ () => Promise.allSettled(dirtyTags.map((t) => t.save()))
37522
+ );
37523
+ } finally {
37524
+ this._savingAll = false;
37525
+ if (this._saveAllAgain && this._saveAllCount++ <= 5) {
37526
+ this._saveAllAgain = false;
37527
+ await this.saveAllDirty();
37528
+ } else {
37529
+ this._saveAllCount = 0;
37530
+ }
37531
+ }
37532
+ }
37533
+ static async loadAll() {
37534
+ await span("tags.loadAll", {}, async () => {
37535
+ const client2 = context.get("client")._inner;
37536
+ const bot2 = context.get("bot", { optional: true });
37537
+ const user2 = context.get("user", { optional: true });
37538
+ const conversation = context.get("conversation", { optional: true });
37539
+ const workflow = context.get("workflow", { optional: true });
37540
+ if (bot2) {
37541
+ const botTags = bot2.tags;
37542
+ _TrackedTags.create({
37543
+ client: client2,
37544
+ type: "bot",
37545
+ id: bot2.id,
37546
+ ...botTags && { initialTags: botTags }
37547
+ });
37548
+ }
37549
+ if (user2) {
37550
+ const userTags = user2.tags;
37551
+ _TrackedTags.create({
37552
+ client: client2,
37553
+ type: "user",
37554
+ id: user2.id,
37555
+ ...userTags && { initialTags: userTags }
37556
+ });
37557
+ }
37558
+ if (conversation) {
37559
+ const conversationTags = conversation.tags;
37560
+ _TrackedTags.create({
37561
+ client: client2,
37562
+ type: "conversation",
37563
+ id: conversation.id,
37564
+ ...conversationTags && { initialTags: conversationTags }
37565
+ });
37566
+ }
37567
+ if (workflow) {
37568
+ const workflowTags = workflow.tags;
37569
+ _TrackedTags.create({
37570
+ client: client2,
37571
+ type: "workflow",
37572
+ id: workflow.id,
37573
+ ...workflowTags && { initialTags: workflowTags }
37574
+ });
37575
+ }
37576
+ const tags = context.get("tags", { optional: true });
37577
+ const unloadedTags = tags?.filter((tag) => !tag._loaded) ?? [];
37578
+ if (unloadedTags.length > 0) {
37579
+ await Promise.allSettled(unloadedTags.map((tag) => tag.load()));
37580
+ }
37581
+ });
37582
+ }
37583
+ static unloadAll() {
37584
+ context.get("tags", { optional: true })?.splice(0);
37585
+ }
37586
+ async load(force = false) {
37587
+ if (this._loaded && !force) {
37588
+ return;
37589
+ }
37590
+ await span(
37591
+ "tags.load",
37592
+ {
37593
+ type: this.type,
37594
+ id: this.id
37595
+ },
37596
+ async () => {
37597
+ const tags = await this.fetchTags();
37598
+ this._tags = { ...tags };
37599
+ this._initialTags = { ...tags };
37600
+ this._loaded = true;
37601
+ }
37602
+ );
37603
+ }
37604
+ async save() {
37605
+ if (this._saving) {
37606
+ this._saveAgain = true;
37607
+ return;
37608
+ }
37609
+ const executionFinished = context.get("executionFinished", { optional: true });
37610
+ if (executionFinished) {
37611
+ throw new Error(`Cannot save TrackedTags "${this.type}/${this.id}" after execution has finished.`);
37612
+ }
37613
+ try {
37614
+ this._saving = true;
37615
+ await span(
37616
+ "tags.save",
37617
+ {
37618
+ type: this.type,
37619
+ id: this.id
37620
+ },
37621
+ async () => {
37622
+ await this.persistTags(this._tags);
37623
+ this._initialTags = { ...this._tags };
37624
+ }
37625
+ );
37626
+ } finally {
37627
+ this._saving = false;
37628
+ if (this._saveAgain && this._saveAgainCount++ <= 5) {
37629
+ this._saveAgain = false;
37630
+ await this.save();
37631
+ } else {
37632
+ this._saveAgainCount = 0;
37633
+ }
37634
+ }
37635
+ }
37636
+ isDirty() {
37637
+ const currentKeys = Object.keys(this._tags).filter((k) => !k.includes(":")).sort();
37638
+ const initialKeys = Object.keys(this._initialTags).filter((k) => !k.includes(":")).sort();
37639
+ if (currentKeys.length !== initialKeys.length) {
37640
+ return true;
37641
+ }
37642
+ for (const key of currentKeys) {
37643
+ if (this._tags[key] !== this._initialTags[key]) {
37644
+ return true;
37645
+ }
37646
+ }
37647
+ return false;
37648
+ }
37649
+ get tags() {
37650
+ return new Proxy(this._tags, {
37651
+ set: (target, prop, value) => {
37652
+ target[prop] = value;
37653
+ return true;
37654
+ },
37655
+ deleteProperty: (target, prop) => {
37656
+ target[prop] = void 0;
37657
+ return true;
37658
+ }
37659
+ });
37660
+ }
37661
+ set tags(value) {
37662
+ this._tags = { ...value };
37663
+ }
37664
+ async fetchTags() {
37665
+ try {
37666
+ if (this.type === "bot") {
37667
+ const { bot: bot2 } = await this.client.getBot({ id: this.id });
37668
+ return bot2.tags || {};
37669
+ } else if (this.type === "user") {
37670
+ const { user: user2 } = await this.client.getUser({ id: this.id });
37671
+ return user2.tags || {};
37672
+ } else if (this.type === "conversation") {
37673
+ const { conversation } = await this.client.getConversation({ id: this.id });
37674
+ return conversation.tags || {};
37675
+ } else if (this.type === "workflow") {
37676
+ const { workflow } = await this.client.getWorkflow({ id: this.id });
37677
+ return workflow.tags || {};
37678
+ }
37679
+ } catch (err) {
37680
+ console.error(`Failed to fetch tags for ${this.type}/${this.id}:`, err);
37681
+ }
37682
+ return {};
37683
+ }
37684
+ async persistTags(tags) {
37685
+ const tagsForApi = {};
37686
+ for (const [key, value] of Object.entries(tags)) {
37687
+ if (value !== void 0 && !key.includes(":")) {
37688
+ tagsForApi[key] = value;
37689
+ }
37690
+ }
37691
+ try {
37692
+ if (this.type === "bot") {
37693
+ await this.client.updateBot({ id: this.id, tags: tagsForApi });
37694
+ } else if (this.type === "user") {
37695
+ await this.client.updateUser({ id: this.id, tags: tagsForApi });
37696
+ } else if (this.type === "conversation") {
37697
+ await this.client.updateConversation({ id: this.id, tags: tagsForApi });
37698
+ } else if (this.type === "workflow") {
37699
+ await this.client.updateWorkflow({ id: this.id, tags: tagsForApi });
37700
+ }
37701
+ } catch (err) {
37702
+ console.error(`Failed to persist tags for ${this.type}/${this.id}:`, err);
37703
+ throw err;
37704
+ }
37705
+ }
37706
+ };
37707
+ }
37708
+ });
37709
+
37358
37710
  // src/runtime/context/inspector-handler.ts
37359
37711
  var init_inspector_handler = __esm({
37360
37712
  "src/runtime/context/inspector-handler.ts"() {
@@ -37436,6 +37788,7 @@ var init_handlers = __esm({
37436
37788
  init_http();
37437
37789
  init_agent_registry();
37438
37790
  init_tracked_state();
37791
+ init_tracked_tags();
37439
37792
  init_tracing();
37440
37793
  init_heavy_imports();
37441
37794
  init_environment();
@@ -38274,38 +38627,6 @@ var init_conversation_instance = __esm({
38274
38627
  });
38275
38628
  }
38276
38629
  }
38277
- /**
38278
- * Subscribe to a trigger
38279
- */
38280
- async subscribeToTrigger(triggerName, key) {
38281
- const { getTriggerSubscriptionTags: getTriggerSubscriptionTags2, isConversationSubscribedToTrigger: isConversationSubscribedToTrigger2 } = await Promise.resolve().then(() => (init_trigger_tags(), trigger_tags_exports));
38282
- if (isConversationSubscribedToTrigger2(this.tags, triggerName, key)) {
38283
- return;
38284
- }
38285
- const { name, value } = getTriggerSubscriptionTags2(triggerName, key);
38286
- await this.client.updateConversation({
38287
- id: this.id,
38288
- tags: {
38289
- [name]: value
38290
- }
38291
- });
38292
- }
38293
- /**
38294
- * Unsubscribe from a trigger
38295
- */
38296
- async unsubscribeFromTrigger(triggerName, key) {
38297
- const { getTriggerSubscriptionTags: getTriggerSubscriptionTags2, isConversationSubscribedToTrigger: isConversationSubscribedToTrigger2 } = await Promise.resolve().then(() => (init_trigger_tags(), trigger_tags_exports));
38298
- if (!isConversationSubscribedToTrigger2(this.tags, triggerName, key)) {
38299
- return;
38300
- }
38301
- const { name } = getTriggerSubscriptionTags2(triggerName, key);
38302
- await this.client.updateConversation({
38303
- id: this.id,
38304
- tags: {
38305
- [name]: ""
38306
- }
38307
- });
38308
- }
38309
38630
  };
38310
38631
  }
38311
38632
  });
@@ -38341,19 +38662,11 @@ var init_conversation = __esm({
38341
38662
  /** @internal */
38342
38663
  schema;
38343
38664
  #handler;
38344
- #startFromTrigger;
38345
38665
  constructor(props) {
38346
38666
  this.channel = props.channel;
38347
38667
  this.events = props.events ?? [];
38348
38668
  this.schema = props.state ?? z19.object({}).passthrough();
38349
38669
  this.#handler = props.handler;
38350
- if (props.startFromTrigger) {
38351
- this.#startFromTrigger = props.startFromTrigger;
38352
- }
38353
- }
38354
- /** @internal */
38355
- get startFromTrigger() {
38356
- return this.#startFromTrigger;
38357
38670
  }
38358
38671
  /** @internal */
38359
38672
  getDefinition() {
@@ -40773,7 +41086,7 @@ var init_source_website = __esm({
40773
41086
  type: "website",
40774
41087
  state: State,
40775
41088
  async handler({ input, step: step2, state, client: client2 }) {
40776
- const crypto3 = await import("crypto");
41089
+ const crypto2 = await import("crypto");
40777
41090
  console.log(
40778
41091
  `Starting sync for WebsiteSource [${this.id}] in mode [${this.mode}, maxPages=${this.maxPages}, maxDepth=${this.maxDepth}, baseUrl=${this.baseUrl}, sitemapUrl=${this.sitemapUrl}]`
40779
41092
  );
@@ -40855,7 +41168,7 @@ var init_source_website = __esm({
40855
41168
  content,
40856
41169
  metadata: fetchMetadata
40857
41170
  } = await this.fetchUrl(sitemapUrl.loc);
40858
- const hash = crypto3.createHash("sha256").update(content).digest("hex");
41171
+ const hash = crypto2.createHash("sha256").update(content).digest("hex");
40859
41172
  let contentType = fetchedContentType;
40860
41173
  if (!contentType) {
40861
41174
  contentType = content.includes("<html") ? "text/html" : "text/markdown";
@@ -47852,7 +48165,7 @@ var init_source_directory = __esm({
47852
48165
  const glob2 = await Promise.resolve().then(() => (init_esm9(), esm_exports3));
47853
48166
  const path4 = await import("path");
47854
48167
  const fs3 = await import("fs/promises");
47855
- const crypto3 = await import("crypto");
48168
+ const crypto2 = await import("crypto");
47856
48169
  const directory = path4.resolve(adk.environment.agent.directory, this.directoryPath);
47857
48170
  const tags = {
47858
48171
  [WellKnownTags.knowledge.KNOWLEDGE]: "knowledge-base",
@@ -47914,7 +48227,7 @@ var init_source_directory = __esm({
47914
48227
  const upsertFile = async (local) => {
47915
48228
  const key = `data_source://${this.type}/${this.id}/${local.rel}`;
47916
48229
  const content = await fs3.readFile(local.abs);
47917
- const hash = crypto3.createHash("sha256").update(content).digest("hex");
48230
+ const hash = crypto2.createHash("sha256").update(content).digest("hex");
47918
48231
  const { file } = await client2.getFile({ id: key }).catch(() => ({ file: null }));
47919
48232
  if (!input.force && file?.metadata?.hash === hash) {
47920
48233
  console.log(`Skipping unchanged file: ${local.rel}`);
@@ -48421,7 +48734,7 @@ var init_primitives = __esm({
48421
48734
  });
48422
48735
 
48423
48736
  // src/runtime/handlers/workflow.ts
48424
- var import_ms2;
48737
+ var import_ms3;
48425
48738
  var init_workflow2 = __esm({
48426
48739
  "src/runtime/handlers/workflow.ts"() {
48427
48740
  "use strict";
@@ -48433,7 +48746,7 @@ var init_workflow2 = __esm({
48433
48746
  init_tracing();
48434
48747
  init_adk();
48435
48748
  init_workflow_utils();
48436
- import_ms2 = __toESM(require_ms(), 1);
48749
+ import_ms3 = __toESM(require_ms(), 1);
48437
48750
  }
48438
48751
  });
48439
48752
 
@@ -48477,259 +48790,6 @@ var init_handlers2 = __esm({
48477
48790
  }
48478
48791
  });
48479
48792
 
48480
- // src/runtime/tracked-tags.ts
48481
- var TrackedTags;
48482
- var init_tracked_tags = __esm({
48483
- "src/runtime/tracked-tags.ts"() {
48484
- "use strict";
48485
- init_define_BUILD();
48486
- init_define_PACKAGE_VERSIONS();
48487
- init_context();
48488
- init_tracing();
48489
- TrackedTags = class _TrackedTags {
48490
- type;
48491
- id;
48492
- client;
48493
- _tags = {};
48494
- _initialTags = {};
48495
- _loaded = false;
48496
- _saving = false;
48497
- _saveAgain = false;
48498
- _saveAgainCount = 0;
48499
- static _savingAll = false;
48500
- static _saveAllAgain = false;
48501
- static _saveAllCount = 0;
48502
- constructor(props) {
48503
- this.type = props.type;
48504
- this.id = props.id;
48505
- this.client = props.client;
48506
- }
48507
- static create(props) {
48508
- const tags = context.get("tags", { optional: true });
48509
- const executionFinished = context.get("executionFinished", { optional: true });
48510
- if (executionFinished) {
48511
- throw new Error(`Cannot create new TrackedTags "${props.type}/${props.id}" after execution has finished.`);
48512
- }
48513
- const match2 = tags?.find((x) => x.id === props.id && x.type === props.type);
48514
- if (match2) {
48515
- return match2;
48516
- }
48517
- const instance = new _TrackedTags(props);
48518
- if (props.initialTags) {
48519
- instance._tags = { ...props.initialTags };
48520
- instance._initialTags = { ...props.initialTags };
48521
- instance._loaded = true;
48522
- }
48523
- tags?.push(instance);
48524
- return instance;
48525
- }
48526
- static async saveAllDirty() {
48527
- if (this._savingAll) {
48528
- this._saveAllAgain = true;
48529
- return;
48530
- }
48531
- try {
48532
- this._savingAll = true;
48533
- const tags = context.get("tags", { optional: true });
48534
- const dirtyTags = tags?.filter((t) => t.isDirty()) || [];
48535
- if (!dirtyTags.length) {
48536
- return;
48537
- }
48538
- await span(
48539
- "tags.saveAllDirty",
48540
- {
48541
- tags_count: tags?.length || 0,
48542
- tags: tags.map((t) => `${t.type}/${t.id}`)
48543
- },
48544
- () => Promise.allSettled(dirtyTags.map((t) => t.save()))
48545
- );
48546
- } finally {
48547
- this._savingAll = false;
48548
- if (this._saveAllAgain && this._saveAllCount++ <= 5) {
48549
- this._saveAllAgain = false;
48550
- await this.saveAllDirty();
48551
- } else {
48552
- this._saveAllCount = 0;
48553
- }
48554
- }
48555
- }
48556
- static async loadAll() {
48557
- await span("tags.loadAll", {}, async () => {
48558
- const client2 = context.get("client")._inner;
48559
- const bot2 = context.get("bot", { optional: true });
48560
- const user2 = context.get("user", { optional: true });
48561
- const conversation = context.get("conversation", { optional: true });
48562
- const workflow = context.get("workflow", { optional: true });
48563
- if (bot2) {
48564
- const botTags = bot2.tags;
48565
- _TrackedTags.create({
48566
- client: client2,
48567
- type: "bot",
48568
- id: bot2.id,
48569
- ...botTags && { initialTags: botTags }
48570
- });
48571
- }
48572
- if (user2) {
48573
- const userTags = user2.tags;
48574
- _TrackedTags.create({
48575
- client: client2,
48576
- type: "user",
48577
- id: user2.id,
48578
- ...userTags && { initialTags: userTags }
48579
- });
48580
- }
48581
- if (conversation) {
48582
- const conversationTags = conversation.tags;
48583
- _TrackedTags.create({
48584
- client: client2,
48585
- type: "conversation",
48586
- id: conversation.id,
48587
- ...conversationTags && { initialTags: conversationTags }
48588
- });
48589
- }
48590
- if (workflow) {
48591
- const workflowTags = workflow.tags;
48592
- _TrackedTags.create({
48593
- client: client2,
48594
- type: "workflow",
48595
- id: workflow.id,
48596
- ...workflowTags && { initialTags: workflowTags }
48597
- });
48598
- }
48599
- const tags = context.get("tags", { optional: true });
48600
- const unloadedTags = tags?.filter((tag) => !tag._loaded) ?? [];
48601
- if (unloadedTags.length > 0) {
48602
- await Promise.allSettled(unloadedTags.map((tag) => tag.load()));
48603
- }
48604
- });
48605
- }
48606
- static unloadAll() {
48607
- context.get("tags", { optional: true })?.splice(0);
48608
- }
48609
- async load(force = false) {
48610
- if (this._loaded && !force) {
48611
- return;
48612
- }
48613
- await span(
48614
- "tags.load",
48615
- {
48616
- type: this.type,
48617
- id: this.id
48618
- },
48619
- async () => {
48620
- const tags = await this.fetchTags();
48621
- this._tags = { ...tags };
48622
- this._initialTags = { ...tags };
48623
- this._loaded = true;
48624
- }
48625
- );
48626
- }
48627
- async save() {
48628
- if (this._saving) {
48629
- this._saveAgain = true;
48630
- return;
48631
- }
48632
- const executionFinished = context.get("executionFinished", { optional: true });
48633
- if (executionFinished) {
48634
- throw new Error(`Cannot save TrackedTags "${this.type}/${this.id}" after execution has finished.`);
48635
- }
48636
- try {
48637
- this._saving = true;
48638
- await span(
48639
- "tags.save",
48640
- {
48641
- type: this.type,
48642
- id: this.id
48643
- },
48644
- async () => {
48645
- await this.persistTags(this._tags);
48646
- this._initialTags = { ...this._tags };
48647
- }
48648
- );
48649
- } finally {
48650
- this._saving = false;
48651
- if (this._saveAgain && this._saveAgainCount++ <= 5) {
48652
- this._saveAgain = false;
48653
- await this.save();
48654
- } else {
48655
- this._saveAgainCount = 0;
48656
- }
48657
- }
48658
- }
48659
- isDirty() {
48660
- const currentKeys = Object.keys(this._tags).sort();
48661
- const initialKeys = Object.keys(this._initialTags).sort();
48662
- if (currentKeys.length !== initialKeys.length) {
48663
- return true;
48664
- }
48665
- for (const key of currentKeys) {
48666
- if (this._tags[key] !== this._initialTags[key]) {
48667
- return true;
48668
- }
48669
- }
48670
- return false;
48671
- }
48672
- get tags() {
48673
- return new Proxy(this._tags, {
48674
- set: (target, prop, value) => {
48675
- target[prop] = value;
48676
- return true;
48677
- },
48678
- deleteProperty: (target, prop) => {
48679
- target[prop] = void 0;
48680
- return true;
48681
- }
48682
- });
48683
- }
48684
- set tags(value) {
48685
- this._tags = { ...value };
48686
- }
48687
- async fetchTags() {
48688
- try {
48689
- if (this.type === "bot") {
48690
- const { bot: bot2 } = await this.client.getBot({ id: this.id });
48691
- return bot2.tags || {};
48692
- } else if (this.type === "user") {
48693
- const { user: user2 } = await this.client.getUser({ id: this.id });
48694
- return user2.tags || {};
48695
- } else if (this.type === "conversation") {
48696
- const { conversation } = await this.client.getConversation({ id: this.id });
48697
- return conversation.tags || {};
48698
- } else if (this.type === "workflow") {
48699
- const { workflow } = await this.client.getWorkflow({ id: this.id });
48700
- return workflow.tags || {};
48701
- }
48702
- } catch (err) {
48703
- console.error(`Failed to fetch tags for ${this.type}/${this.id}:`, err);
48704
- }
48705
- return {};
48706
- }
48707
- async persistTags(tags) {
48708
- const tagsForApi = {};
48709
- for (const [key, value] of Object.entries(tags)) {
48710
- if (value !== void 0) {
48711
- tagsForApi[key] = value;
48712
- }
48713
- }
48714
- try {
48715
- if (this.type === "bot") {
48716
- await this.client.updateBot({ id: this.id, tags: tagsForApi });
48717
- } else if (this.type === "user") {
48718
- await this.client.updateUser({ id: this.id, tags: tagsForApi });
48719
- } else if (this.type === "conversation") {
48720
- await this.client.updateConversation({ id: this.id, tags: tagsForApi });
48721
- } else if (this.type === "workflow") {
48722
- await this.client.updateWorkflow({ id: this.id, tags: tagsForApi });
48723
- }
48724
- } catch (err) {
48725
- console.error(`Failed to persist tags for ${this.type}/${this.id}:`, err);
48726
- throw err;
48727
- }
48728
- }
48729
- };
48730
- }
48731
- });
48732
-
48733
48793
  // src/runtime/client.ts
48734
48794
  import { Client as Client3 } from "@botpress/client";
48735
48795
  function getStandaloneClient() {
@@ -48844,6 +48904,7 @@ export {
48844
48904
  configuration,
48845
48905
  context,
48846
48906
  defineConfig,
48907
+ isEventOfType,
48847
48908
  isWorkflowCallback,
48848
48909
  isWorkflowDataRequest,
48849
48910
  user,