@botpress/runtime 1.14.0 → 1.14.1

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.
@@ -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.14.0", adk: "1.14.0", sdk: "5.0.2", llmz: "0.0.37", zai: "2.5.6", cognitive: "0.3.3" };
51
+ define_PACKAGE_VERSIONS_default = { runtime: "1.14.1", adk: "1.14.1", sdk: "5.0.2", llmz: "0.0.37", zai: "2.5.6", cognitive: "0.3.3" };
52
52
  }
53
53
  });
54
54
 
@@ -26416,6 +26416,7 @@ var init_context_manager = __esm({
26416
26416
  import { randomBytes } from "node:crypto";
26417
26417
  import http3 from "node:http";
26418
26418
  import https2 from "node:https";
26419
+ import { gunzipSync, inflateSync, brotliDecompressSync } from "node:zlib";
26419
26420
  import { Dispatcher, getGlobalDispatcher, setGlobalDispatcher } from "undici";
26420
26421
  function isBotpressUrl(fullUrl) {
26421
26422
  try {
@@ -26447,6 +26448,31 @@ function extractIds(fullUrl, body) {
26447
26448
  }
26448
26449
  return ids;
26449
26450
  }
26451
+ function decompressBody(buffer, contentEncoding) {
26452
+ if (!contentEncoding) {
26453
+ return buffer.toString("utf-8");
26454
+ }
26455
+ const encoding = contentEncoding.toLowerCase().trim();
26456
+ try {
26457
+ switch (encoding) {
26458
+ case "gzip":
26459
+ case "x-gzip":
26460
+ return gunzipSync(buffer).toString("utf-8");
26461
+ case "deflate":
26462
+ return inflateSync(buffer).toString("utf-8");
26463
+ case "br":
26464
+ return brotliDecompressSync(buffer).toString("utf-8");
26465
+ case "identity":
26466
+ case "":
26467
+ return buffer.toString("utf-8");
26468
+ default:
26469
+ return buffer.toString("utf-8");
26470
+ }
26471
+ } catch (error) {
26472
+ console.warn(`Failed to decompress response with encoding "${encoding}":`, error);
26473
+ return buffer.toString("utf-8");
26474
+ }
26475
+ }
26450
26476
  function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26451
26477
  const restores = [];
26452
26478
  const genId = (n) => randomBytes(n).toString("hex");
@@ -26481,6 +26507,9 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26481
26507
  if (options.headers[INSTRUMENTED_HEADER]) {
26482
26508
  return requestFn.apply(this, args);
26483
26509
  }
26510
+ if (isSilentTracing()) {
26511
+ return requestFn.apply(this, args);
26512
+ }
26484
26513
  options.headers[INSTRUMENTED_HEADER] = "true";
26485
26514
  const method = (options.method || "GET").toUpperCase();
26486
26515
  const isBotpress = isBotpressUrl(urlString);
@@ -26496,12 +26525,14 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26496
26525
  if (method === "POST" && urlString.includes("/v1/chat/actions") && bodyData?.type) {
26497
26526
  actionName = bodyData.type;
26498
26527
  }
26528
+ const isWorkflowStatusCheck = method === "GET" && /\/workflows\/[^/?]+$/.test(urlString);
26499
26529
  const spanName = isBotpress ? "botpress.client" : "http.client";
26500
26530
  const spanAttributes = isBotpress ? {
26501
26531
  "botpress.method": method,
26502
26532
  "botpress.url": urlString,
26503
26533
  "botpress.via": "http",
26504
- importance: "medium",
26534
+ importance: isWorkflowStatusCheck ? "low" : "medium",
26535
+ ...isWorkflowStatusCheck && { "debug.type": "workflow-status-check" },
26505
26536
  ...ids,
26506
26537
  ...actionName && { "action.name": actionName }
26507
26538
  } : {
@@ -26546,12 +26577,14 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26546
26577
  req.on("response", (res) => {
26547
26578
  span2.setAttribute(isBotpress ? "botpress.status_code" : "http.status_code", res.statusCode || 0);
26548
26579
  const responseBodyChunks = [];
26580
+ const contentEncoding = res.headers["content-encoding"];
26549
26581
  res.on("data", (chunk) => {
26550
26582
  responseBodyChunks.push(chunk);
26551
26583
  });
26552
26584
  res.on("end", () => {
26553
26585
  if (responseBodyChunks.length > 0) {
26554
- const bodyString = Buffer.concat(responseBodyChunks).toString("utf-8");
26586
+ const bodyBuffer = Buffer.concat(responseBodyChunks);
26587
+ const bodyString = decompressBody(bodyBuffer, contentEncoding);
26555
26588
  span2.setAttribute(isBotpress ? "botpress.response.body" : "http.response.body", bodyString);
26556
26589
  }
26557
26590
  if ((res.statusCode || 0) >= 400) {
@@ -26624,6 +26657,9 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26624
26657
  }
26625
26658
  }
26626
26659
  }
26660
+ if (isSilentTracing()) {
26661
+ return this.d.dispatch(opts, handler);
26662
+ }
26627
26663
  const method = (opts.method || "GET").toUpperCase();
26628
26664
  const origin2 = String(opts.origin ?? "");
26629
26665
  const path4 = String(opts.path ?? "");
@@ -26642,12 +26678,14 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26642
26678
  if (method === "POST" && path4 === "/v1/chat/actions" && bodyData?.type) {
26643
26679
  actionName = bodyData.type;
26644
26680
  }
26681
+ const isWorkflowStatusCheck = method === "GET" && /\/workflows\/[^/?]+$/.test(fullUrl);
26645
26682
  const spanName = isBotpress ? "botpress.client" : "http.client";
26646
26683
  const spanAttributes = isBotpress ? {
26647
26684
  "botpress.method": method,
26648
26685
  "botpress.url": path4,
26649
26686
  "botpress.via": "undici",
26650
- importance: "medium",
26687
+ importance: isWorkflowStatusCheck ? "low" : "medium",
26688
+ ...isWorkflowStatusCheck && { "debug.type": "workflow-status-check" },
26651
26689
  ...ids,
26652
26690
  ...actionName && { "action.name": actionName }
26653
26691
  } : {
@@ -26698,11 +26736,18 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26698
26736
  }
26699
26737
  const nextOpts = { ...opts, headers };
26700
26738
  const responseBodyChunks = [];
26739
+ let contentEncoding;
26701
26740
  const wrap = {
26702
26741
  onConnect: handler.onConnect?.bind(handler),
26703
26742
  onUpgrade: handler.onUpgrade?.bind(handler),
26704
26743
  onHeaders: (statusCode, rawHeaders, resume) => {
26705
26744
  span2.setAttribute(isBotpress ? "botpress.status_code" : "http.status_code", statusCode);
26745
+ for (let i = 0; i < rawHeaders.length; i += 2) {
26746
+ if (String(rawHeaders[i]).toLowerCase() === "content-encoding") {
26747
+ contentEncoding = String(rawHeaders[i + 1]);
26748
+ break;
26749
+ }
26750
+ }
26706
26751
  if (statusCode >= 500) {
26707
26752
  span2.setStatus({
26708
26753
  code: SpanStatusCode.ERROR,
@@ -26733,7 +26778,8 @@ function installHttpClientInstrumentation({ injectTraceHeader = true } = {}) {
26733
26778
  },
26734
26779
  onComplete: (trailers) => {
26735
26780
  if (responseBodyChunks.length > 0) {
26736
- const bodyString = Buffer.concat(responseBodyChunks).toString("utf-8");
26781
+ const bodyBuffer = Buffer.concat(responseBodyChunks);
26782
+ const bodyString = decompressBody(bodyBuffer, contentEncoding);
26737
26783
  span2.setAttribute(isBotpress ? "botpress.response.body" : "http.response.body", bodyString);
26738
26784
  }
26739
26785
  span2.end();
@@ -31143,7 +31189,7 @@ var require_lodash = __commonJS({
31143
31189
  return value === true || value === false || isObjectLike2(value) && baseGetTag(value) == boolTag;
31144
31190
  }
31145
31191
  var isBuffer2 = nativeIsBuffer || stubFalse;
31146
- var isDate2 = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
31192
+ var isDate3 = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
31147
31193
  function isElement(value) {
31148
31194
  return isObjectLike2(value) && value.nodeType === 1 && !isPlainObject2(value);
31149
31195
  }
@@ -32278,7 +32324,7 @@ var require_lodash = __commonJS({
32278
32324
  lodash.isArrayLikeObject = isArrayLikeObject;
32279
32325
  lodash.isBoolean = isBoolean2;
32280
32326
  lodash.isBuffer = isBuffer2;
32281
- lodash.isDate = isDate2;
32327
+ lodash.isDate = isDate3;
32282
32328
  lodash.isElement = isElement;
32283
32329
  lodash.isEmpty = isEmpty;
32284
32330
  lodash.isEqual = isEqual;
@@ -45573,6 +45619,61 @@ var init_library = __esm({
45573
45619
  }
45574
45620
  });
45575
45621
 
45622
+ // src/primitives/date-serialization.ts
45623
+ function isDateMarker(value) {
45624
+ return typeof value === "object" && value !== null && DATE_MARKER in value && typeof value[DATE_MARKER] === "string";
45625
+ }
45626
+ function isDate2(value) {
45627
+ return value instanceof Date;
45628
+ }
45629
+ function serializeDates(data) {
45630
+ if (data === null || data === void 0) {
45631
+ return data;
45632
+ }
45633
+ if (isDate2(data)) {
45634
+ return { [DATE_MARKER]: data.toISOString() };
45635
+ }
45636
+ if (Array.isArray(data)) {
45637
+ return data.map((item) => serializeDates(item));
45638
+ }
45639
+ if (typeof data === "object" && data.constructor === Object) {
45640
+ const result = {};
45641
+ for (const [key, value] of Object.entries(data)) {
45642
+ result[key] = serializeDates(value);
45643
+ }
45644
+ return result;
45645
+ }
45646
+ return data;
45647
+ }
45648
+ function deserializeDates(data) {
45649
+ if (data === null || data === void 0) {
45650
+ return data;
45651
+ }
45652
+ if (isDateMarker(data)) {
45653
+ return new Date(data[DATE_MARKER]);
45654
+ }
45655
+ if (Array.isArray(data)) {
45656
+ return data.map((item) => deserializeDates(item));
45657
+ }
45658
+ if (typeof data === "object" && data.constructor === Object) {
45659
+ const result = {};
45660
+ for (const [key, value] of Object.entries(data)) {
45661
+ result[key] = deserializeDates(value);
45662
+ }
45663
+ return result;
45664
+ }
45665
+ return data;
45666
+ }
45667
+ var DATE_MARKER;
45668
+ var init_date_serialization = __esm({
45669
+ "src/primitives/date-serialization.ts"() {
45670
+ "use strict";
45671
+ init_define_BUILD();
45672
+ init_define_PACKAGE_VERSIONS();
45673
+ DATE_MARKER = "__date__";
45674
+ }
45675
+ });
45676
+
45576
45677
  // src/primitives/workflow-step.ts
45577
45678
  import { ulid } from "ulid";
45578
45679
  import assert from "assert";
@@ -45580,7 +45681,8 @@ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
45580
45681
  import { transforms as transforms3 } from "@botpress/sdk";
45581
45682
  async function _step(name, run, { maxAttempts = DEFAULT_MAX_ATTEMPTS } = {}, {
45582
45683
  spanFunc,
45583
- stepType
45684
+ stepType,
45685
+ stepMeta
45584
45686
  } = {}) {
45585
45687
  const workflowControlContext = context2.get("workflowControlContext");
45586
45688
  workflowControlContext.signal.throwIfAborted();
@@ -45604,14 +45706,19 @@ async function _step(name, run, { maxAttempts = DEFAULT_MAX_ATTEMPTS } = {}, {
45604
45706
  const steps = stepContext?.steps ?? state.value.steps;
45605
45707
  steps[name] ??= {
45606
45708
  attempts: 0,
45709
+ maxAttempts,
45607
45710
  steps: {},
45608
45711
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
45609
45712
  };
45713
+ if (stepMeta) {
45714
+ Object.assign(steps[name], stepMeta);
45715
+ console.log(`[_step] Applied stepMeta to "${name}":`, JSON.stringify(stepMeta), "\u2192 keys now:", Object.keys(steps[name]));
45716
+ }
45610
45717
  if (steps[name].finishedAt) {
45611
45718
  if (steps[name].error) {
45612
45719
  throw new Error(steps[name].error.message);
45613
45720
  }
45614
- return steps[name].output;
45721
+ return deserializeDates(steps[name].output);
45615
45722
  }
45616
45723
  while (true) {
45617
45724
  let shouldRetry = false;
@@ -45693,7 +45800,7 @@ async function _step(name, run, { maxAttempts = DEFAULT_MAX_ATTEMPTS } = {}, {
45693
45800
  throw createStepSignal();
45694
45801
  }
45695
45802
  steps[name].finishedAt = (/* @__PURE__ */ new Date()).toISOString();
45696
- steps[name].output = result;
45803
+ steps[name].output = serializeDates(result);
45697
45804
  steps[name].steps = {};
45698
45805
  state.value.revision++;
45699
45806
  await workflowControlContext.ack();
@@ -45741,6 +45848,7 @@ var init_workflow_step = __esm({
45741
45848
  init_adk();
45742
45849
  init_singletons();
45743
45850
  init_workflow_utils();
45851
+ init_date_serialization();
45744
45852
  DEFAULT_MAX_ATTEMPTS = 5;
45745
45853
  MIN_STEP_REMAINING_TIME_MS = 1e4;
45746
45854
  storage2 = getSingleton("__ADK_GLOBAL_CTX_WORKFLOW_STEP", () => new AsyncLocalStorage3());
@@ -45882,6 +45990,8 @@ var init_workflow_step = __esm({
45882
45990
  {}
45883
45991
  );
45884
45992
  step.map = async (name, items, run, opts = {}) => {
45993
+ const concurrency = opts.concurrency ?? 1;
45994
+ const maxAttempts = opts.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
45885
45995
  return _step(
45886
45996
  name,
45887
45997
  async () => {
@@ -45893,15 +46003,28 @@ var init_workflow_step = __esm({
45893
46003
  async () => {
45894
46004
  return await run(item, { i });
45895
46005
  },
45896
- opts
46006
+ opts,
46007
+ {
46008
+ stepType: "map-item",
46009
+ spanFunc: (span2) => {
46010
+ span2.setAttribute("workflow.map.item_index", i);
46011
+ span2.setAttribute("workflow.map.total", items.length);
46012
+ }
46013
+ }
45897
46014
  );
45898
46015
  },
45899
- opts.concurrency ?? 1
46016
+ concurrency
45900
46017
  );
45901
46018
  },
45902
46019
  opts,
45903
46020
  {
45904
- stepType: "map"
46021
+ stepType: "map",
46022
+ stepMeta: { mapTotal: items.length, mapConcurrency: concurrency },
46023
+ spanFunc: (span2) => {
46024
+ span2.setAttribute("workflow.map.total", items.length);
46025
+ span2.setAttribute("workflow.map.concurrency", concurrency);
46026
+ span2.setAttribute("workflow.step.max_attempts", maxAttempts);
46027
+ }
45905
46028
  }
45906
46029
  );
45907
46030
  };
@@ -45996,7 +46119,7 @@ function startWorkflowCancellationMonitor(props) {
45996
46119
  return;
45997
46120
  }
45998
46121
  try {
45999
- const { workflow } = await client2.getWorkflow({ id: workflowId });
46122
+ const { workflow } = await withSilentTracing(() => client2.getWorkflow({ id: workflowId }));
46000
46123
  const isTerminated = workflow.status === "cancelled" || workflow.status === "failed" || workflow.status === "timedout";
46001
46124
  if (isTerminated) {
46002
46125
  workflowControlContext.aborted = true;
@@ -46019,6 +46142,7 @@ var init_workflow_cancellation_monitor = __esm({
46019
46142
  "use strict";
46020
46143
  init_define_BUILD();
46021
46144
  init_define_PACKAGE_VERSIONS();
46145
+ init_tracing();
46022
46146
  }
46023
46147
  });
46024
46148
 
@@ -46071,7 +46195,9 @@ var init_workflow_instance = __esm({
46071
46195
  i: z22.number().optional(),
46072
46196
  startedAt: z22.string(),
46073
46197
  finishedAt: z22.string().optional(),
46198
+ maxAttempts: z22.number().optional(),
46074
46199
  steps: z22.record(z22.string(), workflowStepContextSchema).optional(),
46200
+ mapTotal: z22.number().optional(),
46075
46201
  error: z22.object({
46076
46202
  message: z22.string(),
46077
46203
  failedAt: z22.string(),
@@ -47984,7 +48110,11 @@ var init_spans = __esm({
47984
48110
  "workflow.step.attempt": { type: "number", required: true },
47985
48111
  "workflow.step.output": { type: "json" },
47986
48112
  "workflow.step.max_attempts": { type: "number" },
47987
- "workflow.step.error": { type: "string" }
48113
+ "workflow.step.error": { type: "string" },
48114
+ // Map-specific attributes
48115
+ "workflow.map.total": { type: "number", description: "Total number of items to process in map" },
48116
+ "workflow.map.concurrency": { type: "number", description: "Concurrency level for map operation" },
48117
+ "workflow.map.item_index": { type: "number", description: "Index of item in map operation" }
47988
48118
  }
47989
48119
  };
47990
48120
  ActionHandlerSpan = {
@@ -48446,7 +48576,14 @@ var init_span_helpers = __esm({
48446
48576
  });
48447
48577
 
48448
48578
  // src/telemetry/tracing.ts
48449
- var import_sdk_trace_base, import_sdk_trace_node, import_resources, import_core2, spanProcessors, environmentInfo, resource, provider, contextManager, tracer;
48579
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
48580
+ function withSilentTracing(fn) {
48581
+ return silentTracingFlag.run(true, fn);
48582
+ }
48583
+ function isSilentTracing() {
48584
+ return silentTracingFlag.getStore() === true;
48585
+ }
48586
+ var import_sdk_trace_base, import_sdk_trace_node, import_resources, import_core2, spanProcessors, environmentInfo, resource, provider, contextManager, tracer, silentTracingFlag;
48450
48587
  var init_tracing = __esm({
48451
48588
  "src/telemetry/tracing.ts"() {
48452
48589
  "use strict";
@@ -48494,6 +48631,7 @@ var init_tracing = __esm({
48494
48631
  });
48495
48632
  }
48496
48633
  tracer = trace.getTracer("adk", "1.0.0");
48634
+ silentTracingFlag = getSingleton("__ADK_GLOBAL_SILENT_TRACING", () => new AsyncLocalStorage4());
48497
48635
  for (const sig of ["SIGINT", "SIGTERM"]) {
48498
48636
  process.on(sig, async () => {
48499
48637
  await provider.forceFlush();