@rasputin-ai/node 0.5.2 → 0.6.0

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 (42) hide show
  1. package/README.md +4 -2
  2. package/dist/auto-instrumentation/instrumentation-manifest-registry.d.ts +1 -1
  3. package/dist/auto-instrumentation/instrumentation-manifest-registry.d.ts.map +1 -1
  4. package/dist/auto-instrumentation/source-map-locations.d.ts +1 -1
  5. package/dist/auto-instrumentation/source-map-locations.d.ts.map +1 -1
  6. package/dist/auto-instrumentation/transform-disk-cache.d.ts +1 -1
  7. package/dist/auto-instrumentation/transform-disk-cache.d.ts.map +1 -1
  8. package/dist/execution-recorder/automatic-runtime.d.ts +2 -33
  9. package/dist/execution-recorder/automatic-runtime.d.ts.map +1 -1
  10. package/dist/execution-recorder/encode-frozen.d.ts.map +1 -1
  11. package/dist/execution-recorder/execution-recorder-types.d.ts +3 -2
  12. package/dist/execution-recorder/execution-recorder-types.d.ts.map +1 -1
  13. package/dist/execution-recorder/execution-recorder.d.ts.map +1 -1
  14. package/dist/execution-recorder/function-plan.d.ts +7 -22
  15. package/dist/execution-recorder/function-plan.d.ts.map +1 -1
  16. package/dist/execution-recorder/runtime-state-size-budget.d.ts.map +1 -1
  17. package/dist/execution-recorder/value-freeze.d.ts.map +1 -1
  18. package/dist/index.js +228 -155
  19. package/dist/instrument/build.js +852 -588
  20. package/dist/instrument/bun.js +639 -373
  21. package/dist/instrument/node.js +605 -339
  22. package/dist/internal.js +225 -152
  23. package/dist/rasputin-init.d.ts +1 -0
  24. package/dist/rasputin-init.d.ts.map +1 -1
  25. package/dist/sdk-meta.d.ts +1 -1
  26. package/package.json +4 -2
  27. package/dist/auto-instrumentation/collect-instrumentation-delta.d.ts +0 -29
  28. package/dist/auto-instrumentation/collect-instrumentation-delta.d.ts.map +0 -1
  29. package/dist/auto-instrumentation/instrumentation-manifest-delta.d.ts +0 -49
  30. package/dist/auto-instrumentation/instrumentation-manifest-delta.d.ts.map +0 -1
  31. package/dist/auto-instrumentation/parameter-initializer-may-run-code.d.ts +0 -3
  32. package/dist/auto-instrumentation/parameter-initializer-may-run-code.d.ts.map +0 -1
  33. package/dist/auto-instrumentation/suspension-whitelist.d.ts +0 -33
  34. package/dist/auto-instrumentation/suspension-whitelist.d.ts.map +0 -1
  35. package/dist/auto-instrumentation/transform-source.d.ts +0 -27
  36. package/dist/auto-instrumentation/transform-source.d.ts.map +0 -1
  37. package/dist/auto-instrumentation/verify-instrumentation-isomorphism.d.ts +0 -2
  38. package/dist/auto-instrumentation/verify-instrumentation-isomorphism.d.ts.map +0 -1
  39. package/dist/auto-instrumentation/verify-transformed-source.d.ts +0 -2
  40. package/dist/auto-instrumentation/verify-transformed-source.d.ts.map +0 -1
  41. package/dist/execution-recorder/run-exactly-once.d.ts +0 -7
  42. package/dist/execution-recorder/run-exactly-once.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -13,14 +13,89 @@ import {
13
13
  sourceLocatorFromFile as sourceLocatorFromFile2
14
14
  } from "@rasputin-ai/core";
15
15
 
16
- // src/execution-recorder/function-plan.ts
16
+ // ../recorder/src/run-exactly-once.ts
17
+ var runExactlyOnce = function __rasputinHandleRun__(invoke, callback) {
18
+ let outcome;
19
+ const wrapped = function __rasputinHandleRun__3() {
20
+ try {
21
+ const value = callback();
22
+ outcome = { kind: "value", value };
23
+ return value;
24
+ } catch (caught) {
25
+ outcome = { kind: "throw", error: caught };
26
+ throw caught;
27
+ }
28
+ };
29
+ try {
30
+ invoke(wrapped);
31
+ } catch {
32
+ }
33
+ if (outcome?.kind === "throw") throw outcome.error;
34
+ if (outcome?.kind === "value") return outcome.value;
35
+ return callback();
36
+ };
37
+
38
+ // ../recorder/src/call-handle.ts
39
+ var passthroughHandle = () => ({
40
+ leave: (value) => value,
41
+ fail: () => {
42
+ },
43
+ end: () => {
44
+ },
45
+ run: function __rasputinHandleRun__3(callback) {
46
+ return runExactlyOnce((invoke) => invoke(), callback);
47
+ },
48
+ suspend: (value) => value,
49
+ resume: (value) => value
50
+ });
51
+ var isolateHandle = (handle) => ({
52
+ leave: (value) => {
53
+ try {
54
+ return handle.leave(value);
55
+ } catch {
56
+ return value;
57
+ }
58
+ },
59
+ fail: (error, liveArgs) => {
60
+ try {
61
+ handle.fail(error, liveArgs);
62
+ } catch {
63
+ }
64
+ },
65
+ end: () => {
66
+ try {
67
+ handle.end();
68
+ } catch {
69
+ }
70
+ },
71
+ run: function __rasputinHandleRun__3(callback) {
72
+ return runExactlyOnce((invoke) => handle.run(invoke), callback);
73
+ },
74
+ suspend: (value) => {
75
+ try {
76
+ return handle.suspend(value);
77
+ } catch {
78
+ return value;
79
+ }
80
+ },
81
+ resume: (value) => {
82
+ try {
83
+ return handle.resume(value);
84
+ } catch {
85
+ return value;
86
+ }
87
+ }
88
+ });
89
+
90
+ // ../recorder/src/encoded-function-plan.ts
91
+ var encodedPlanOmitsCallValues = (plan) => plan[6] === 1;
92
+ var encodedPlanHasPreBodyParameterEvaluation = (plan) => plan[7] === 1;
93
+
94
+ // ../recorder/src/function-plan.ts
17
95
  import {
18
96
  runtimeFunctionId,
19
97
  sourceLocatorFromFile
20
98
  } from "@rasputin-ai/core";
21
- var encodedPlanOmitsCallValues = (plan) => plan[6] === 1;
22
- var encodedPlanHasPreBodyParameterEvaluation = (plan) => plan[7] === 1;
23
- var EVENT_PAIR_BASE_ESTIMATED_BYTES = 512;
24
99
  var definitionFromEncodedPlan = (plan) => {
25
100
  const [functionId, name, packageName, packageRelativePath, line, column] = plan;
26
101
  const source = packageRelativePath ? {
@@ -36,7 +111,57 @@ var definitionFromEncodedPlan = (plan) => {
36
111
  ...encodedPlanHasPreBodyParameterEvaluation(plan) ? { parentAttribution: "pre_body_parameter_evaluation" } : {}
37
112
  };
38
113
  };
39
- var estimatedCallBytesFor = (functionId) => EVENT_PAIR_BASE_ESTIMATED_BYTES + Buffer.byteLength(functionId, "utf8") * 2;
114
+
115
+ // ../recorder/src/runtime-symbol.ts
116
+ var AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v3";
117
+
118
+ // ../recorder/src/registry.ts
119
+ var runtimeSymbol = Symbol.for(AUTOMATIC_RUNTIME_SYMBOL);
120
+ var passthroughRun = (_planIndex, _args, callback) => callback();
121
+ var passthroughEnter = () => passthroughHandle();
122
+ var bindPassthrough = (module) => {
123
+ module.cell.run = passthroughRun;
124
+ module.cell.enter = passthroughEnter;
125
+ };
126
+ var attachRunner = (cell) => {
127
+ const run = ((planIndex, args, callback, omitValues) => cell.run(planIndex, args, callback, omitValues));
128
+ run.enter = (planIndex, args, omitValues, callee) => cell.enter(planIndex, args, omitValues, callee);
129
+ return run;
130
+ };
131
+ var isCompatibleRegistry = (value) => typeof Reflect.get(value, "register") === "function" && Array.isArray(Reflect.get(value, "runtimes")) && Array.isArray(Reflect.get(value, "modules"));
132
+ var registerModule = (registry, plans, moduleIndex) => {
133
+ const cell = { run: passthroughRun, enter: passthroughEnter };
134
+ const module = {
135
+ plans,
136
+ cell,
137
+ ...moduleIndex === void 0 ? {} : { moduleIndex }
138
+ };
139
+ registry.modules.push(module);
140
+ registry.runtimes.at(-1)?.bind(module);
141
+ return attachRunner(cell);
142
+ };
143
+ var createRegistry = () => {
144
+ const registry = {
145
+ runtimes: [],
146
+ modules: [],
147
+ register(plans, moduleIndex) {
148
+ return registerModule(registry, plans, moduleIndex);
149
+ }
150
+ };
151
+ return registry;
152
+ };
153
+ var getAutomaticRuntimeRegistry = () => {
154
+ const existing = Reflect.get(globalThis, runtimeSymbol);
155
+ if (existing && typeof existing === "object" && isCompatibleRegistry(existing)) {
156
+ return existing;
157
+ }
158
+ if (existing != null) {
159
+ return createRegistry();
160
+ }
161
+ const registry = createRegistry();
162
+ Reflect.set(globalThis, runtimeSymbol, registry);
163
+ return registry;
164
+ };
40
165
 
41
166
  // src/auto-instrumentation/instrumentation-manifest-registry.ts
42
167
  var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.v3";
@@ -919,6 +1044,10 @@ var ExecutionJournalPool = class {
919
1044
  }
920
1045
  };
921
1046
 
1047
+ // src/execution-recorder/function-plan.ts
1048
+ var EVENT_PAIR_BASE_ESTIMATED_BYTES = 512;
1049
+ var estimatedCallBytesFor = (functionId) => EVENT_PAIR_BASE_ESTIMATED_BYTES + Buffer.byteLength(functionId, "utf8") * 2;
1050
+
922
1051
  // src/execution-recorder/recorder-memory-budget.ts
923
1052
  var EXECUTION_BASE_ESTIMATED_BYTES = 1024;
924
1053
  var SUMMARY_EVENT_BASE_ESTIMATED_BYTES = 256;
@@ -1054,28 +1183,6 @@ var RecorderMemoryBudget = class {
1054
1183
  }
1055
1184
  };
1056
1185
 
1057
- // src/execution-recorder/run-exactly-once.ts
1058
- var runExactlyOnce = function __rasputinHandleRun__(invoke, callback) {
1059
- let outcome;
1060
- const wrapped = function __rasputinHandleRun__3() {
1061
- try {
1062
- const value = callback();
1063
- outcome = { kind: "value", value };
1064
- return value;
1065
- } catch (caught) {
1066
- outcome = { kind: "throw", error: caught };
1067
- throw caught;
1068
- }
1069
- };
1070
- try {
1071
- invoke(wrapped);
1072
- } catch {
1073
- }
1074
- if (outcome?.kind === "throw") throw outcome.error;
1075
- if (outcome?.kind === "value") return outcome.value;
1076
- return callback();
1077
- };
1078
-
1079
1186
  // src/execution-recorder/runtime-state-size-budget.ts
1080
1187
  import {
1081
1188
  rasputinUnavailable
@@ -1118,6 +1225,7 @@ var dropEventValues = (events) => {
1118
1225
  const marker = () => rasputinUnavailable(VALUE_OMITTED_REASON);
1119
1226
  const bounded = events.map((event) => {
1120
1227
  if (event.type === "function_enter") {
1228
+ if (event.args === void 0) return { ...event };
1121
1229
  dropped += event.args.length;
1122
1230
  return { ...event, args: event.args.map(marker) };
1123
1231
  }
@@ -1301,7 +1409,7 @@ var defaults = {
1301
1409
  maxObjectKeys: 30,
1302
1410
  maxArrayElements: 20,
1303
1411
  maxStringLength: 500,
1304
- maxSerializedValueBytes: 8 * 1024
1412
+ maxSerializedValueBytes: 16 * 1024
1305
1413
  };
1306
1414
  var compileFreezeLimits = (options) => ({
1307
1415
  maxDepth: options.maxDepth ?? defaults.maxDepth,
@@ -1628,6 +1736,21 @@ var redactUrlUserinfo = (text) => {
1628
1736
  };
1629
1737
  var redactUrlLikeString = (text, redactKeys) => redactSensitiveQuery(redactUrlUserinfo(text), redactKeys);
1630
1738
  var isFrozenAtom = (value) => typeof value === "object" && value !== null && FROZEN in value;
1739
+ var isRetainedOverflowChild = (value) => {
1740
+ if (isFrozenAtom(value)) {
1741
+ if (value[FROZEN] === "truncated") return true;
1742
+ return (value[FROZEN] === "Map" || value[FROZEN] === "Set") && value.truncated === true;
1743
+ }
1744
+ if (!Array.isArray(value) || value.length === 0) return false;
1745
+ const last = value[value.length - 1];
1746
+ return isFrozenAtom(last) && last[FROZEN] === "truncated";
1747
+ };
1748
+ var keepOverflowChild = (child, overflowedOnChild) => {
1749
+ if (!overflowedOnChild) return true;
1750
+ if (child === void 0) return false;
1751
+ return isRetainedOverflowChild(child);
1752
+ };
1753
+ var BYTE_LIMIT = "max_serialized_value_bytes";
1631
1754
  var createValueFreezer = (options = {}) => {
1632
1755
  const limits = compileFreezeLimits(options);
1633
1756
  const redactKeys = compileRedactKeys(options.redactKeys);
@@ -1760,20 +1883,32 @@ var createValueFreezer = (options = {}) => {
1760
1883
  for (const mapKey of Map.prototype.keys.call(value)) {
1761
1884
  if (counted2 >= limits.maxArrayElements || metrics.oversize) break;
1762
1885
  const key = freezeInner(mapKey, depth + 1, path, metrics);
1886
+ if (!keepOverflowChild(key, metrics.oversize)) break;
1763
1887
  if (typeof mapKey === "string" && keyIsRedacted(mapKey, redactKeys)) {
1764
1888
  add(metrics, stringEstimate(REDACTED));
1889
+ if (metrics.oversize) break;
1765
1890
  entries.push([key, REDACTED]);
1766
1891
  } else {
1767
- entries.push([
1768
- key,
1769
- freezeInner(Map.prototype.get.call(value, mapKey), depth + 1, path, metrics)
1770
- ]);
1892
+ const mapValue = freezeInner(
1893
+ Map.prototype.get.call(value, mapKey),
1894
+ depth + 1,
1895
+ path,
1896
+ metrics
1897
+ );
1898
+ if (!keepOverflowChild(mapValue, metrics.oversize)) break;
1899
+ entries.push([key, mapValue]);
1771
1900
  }
1772
1901
  counted2++;
1773
1902
  }
1903
+ const hitBytes2 = metrics.oversize && counted2 < Math.min(size, limits.maxArrayElements);
1904
+ const hitCount = size > limits.maxArrayElements;
1774
1905
  return atom("Map", {
1775
1906
  entries,
1776
- ...size > limits.maxArrayElements ? { truncated: true, reason: "max_array_elements", originalLength: size } : {}
1907
+ ...hitBytes2 || hitCount ? {
1908
+ truncated: true,
1909
+ reason: hitBytes2 ? BYTE_LIMIT : "max_array_elements",
1910
+ originalLength: size
1911
+ } : {}
1777
1912
  });
1778
1913
  }
1779
1914
  if (types.isSet(value)) {
@@ -1784,12 +1919,20 @@ var createValueFreezer = (options = {}) => {
1784
1919
  const size = setSize ? setSize.call(value) : 0;
1785
1920
  for (const item of Set.prototype.values.call(value)) {
1786
1921
  if (counted2 >= limits.maxArrayElements || metrics.oversize) break;
1787
- values.push(freezeInner(item, depth + 1, path, metrics));
1922
+ const frozen = freezeInner(item, depth + 1, path, metrics);
1923
+ if (!keepOverflowChild(frozen, metrics.oversize)) break;
1924
+ values.push(frozen);
1788
1925
  counted2++;
1789
1926
  }
1927
+ const hitBytes2 = metrics.oversize && counted2 < Math.min(size, limits.maxArrayElements);
1928
+ const hitCount = size > limits.maxArrayElements;
1790
1929
  return atom("Set", {
1791
1930
  values,
1792
- ...size > limits.maxArrayElements ? { truncated: true, reason: "max_array_elements", originalLength: size } : {}
1931
+ ...hitBytes2 || hitCount ? {
1932
+ truncated: true,
1933
+ reason: hitBytes2 ? BYTE_LIMIT : "max_array_elements",
1934
+ originalLength: size
1935
+ } : {}
1793
1936
  });
1794
1937
  }
1795
1938
  if (Array.isArray(value)) {
@@ -1807,26 +1950,39 @@ var createValueFreezer = (options = {}) => {
1807
1950
  }
1808
1951
  if (!descriptor) {
1809
1952
  add(metrics, NODE + 16);
1953
+ if (metrics.oversize) break;
1810
1954
  items.push(atom("hole"));
1811
1955
  redactNext = false;
1812
1956
  continue;
1813
1957
  }
1814
1958
  if (!("value" in descriptor)) {
1815
1959
  add(metrics, NODE + 16);
1960
+ if (metrics.oversize) break;
1816
1961
  items.push(atom("accessor"));
1817
1962
  redactNext = false;
1818
1963
  continue;
1819
1964
  }
1820
1965
  if (redactNext) {
1821
1966
  add(metrics, stringEstimate(REDACTED));
1967
+ if (metrics.oversize) break;
1822
1968
  items.push(REDACTED);
1823
1969
  redactNext = false;
1824
1970
  } else {
1825
- items.push(freezeInner(descriptor.value, depth + 1, path, metrics));
1971
+ const frozen = freezeInner(descriptor.value, depth + 1, path, metrics);
1972
+ if (!keepOverflowChild(frozen, metrics.oversize)) break;
1973
+ items.push(frozen);
1826
1974
  redactNext = typeof descriptor.value === "string" && keyIsRedacted(descriptor.value, redactKeys);
1827
1975
  }
1828
1976
  }
1829
- if (value.length > limits.maxArrayElements) {
1977
+ if (metrics.oversize && items.length < maxItems) {
1978
+ add(metrics, NODE + 32);
1979
+ items.push(
1980
+ atom("truncated", {
1981
+ reason: BYTE_LIMIT,
1982
+ originalLength: value.length
1983
+ })
1984
+ );
1985
+ } else if (value.length > limits.maxArrayElements) {
1830
1986
  add(metrics, NODE + 32);
1831
1987
  items.push(
1832
1988
  atom("truncated", {
@@ -1934,30 +2090,41 @@ var createValueFreezer = (options = {}) => {
1934
2090
  const pairIsSensitive = pairLabel !== void 0 && typeof pairLabel.value === "string" && keyIsRedacted(pairLabel.value, redactKeys);
1935
2091
  const { keys, truncated } = ownEnumerableKeys(value, limits.maxObjectKeys);
1936
2092
  const maxKeys = truncated ? Math.max(0, limits.maxObjectKeys - 1) : keys.length;
2093
+ let kept = 0;
1937
2094
  for (let index = 0; index < maxKeys; index++) {
2095
+ if (metrics.oversize) break;
1938
2096
  const key = keys[index];
1939
- if (key === void 0 || metrics.oversize) continue;
2097
+ if (key === void 0) continue;
1940
2098
  add(metrics, stringEstimate(key));
2099
+ if (metrics.oversize) break;
1941
2100
  if (keyIsRedacted(key, redactKeys) || key === "value" && pairIsSensitive) {
1942
2101
  add(metrics, stringEstimate(REDACTED));
2102
+ if (metrics.oversize) break;
1943
2103
  assignFrozenField(fields, key, REDACTED);
2104
+ kept++;
1944
2105
  continue;
1945
2106
  }
1946
2107
  const slot = ownData(value, key);
1947
2108
  if (slot) {
1948
2109
  const field = typeof slot.value === "string" && propertyNameLooksLikeUrl(key) ? redactUrlLikeString(slot.value, redactKeys) : slot.value;
1949
- assignFrozenField(fields, key, freezeInner(field, depth + 1, path, metrics));
2110
+ const frozen = freezeInner(field, depth + 1, path, metrics);
2111
+ if (!keepOverflowChild(frozen, metrics.oversize)) break;
2112
+ assignFrozenField(fields, key, frozen);
2113
+ kept++;
1950
2114
  } else {
1951
2115
  add(metrics, NODE + 16);
2116
+ if (metrics.oversize) break;
1952
2117
  assignFrozenField(fields, key, atom("accessor"));
2118
+ kept++;
1953
2119
  }
1954
2120
  }
1955
- if (truncated) {
2121
+ const hitBytes = metrics.oversize && kept < maxKeys;
2122
+ if (hitBytes || truncated) {
1956
2123
  return atom("instance", {
1957
2124
  type: typeName,
1958
2125
  value: fields,
1959
2126
  truncated: true,
1960
- reason: "max_object_keys"
2127
+ reason: hitBytes ? BYTE_LIMIT : "max_object_keys"
1961
2128
  });
1962
2129
  }
1963
2130
  if (typeName) return atom("instance", { type: typeName, value: fields });
@@ -1981,22 +2148,11 @@ var createValueFreezer = (options = {}) => {
1981
2148
  }
1982
2149
  try {
1983
2150
  const frozen = freezeInner(value, 0, path, metrics);
1984
- if (metrics.oversize) {
1985
- return {
1986
- value: atom("truncated", {
1987
- reason: "max_serialized_value_bytes",
1988
- serializedBytes: metrics.estimatedBytes
1989
- }),
1990
- estimatedBytes: metrics.estimatedBytes,
1991
- visitedNodes: metrics.visitedNodes,
1992
- oversize: true
1993
- };
1994
- }
1995
2151
  return {
1996
2152
  value: frozen,
1997
2153
  estimatedBytes: metrics.estimatedBytes,
1998
2154
  visitedNodes: metrics.visitedNodes,
1999
- oversize: false
2155
+ oversize: metrics.oversize
2000
2156
  };
2001
2157
  } catch {
2002
2158
  return {
@@ -2286,14 +2442,18 @@ var encodeFrozen = (value) => {
2286
2442
  }
2287
2443
  return value;
2288
2444
  };
2445
+ var isByteBudgetStub = (encoded) => {
2446
+ if (typeof encoded !== "object" || encoded === null || Array.isArray(encoded)) return false;
2447
+ const record = encoded;
2448
+ if (record.__rasputin_truncated !== true || record.__reason !== "max_serialized_value_bytes") {
2449
+ return false;
2450
+ }
2451
+ return Object.keys(record).every((key) => key.startsWith("__"));
2452
+ };
2289
2453
  var encodeFrozenWithBytes = (frozen, visitedNodes, maxSerializedValueBytes) => {
2290
2454
  const encoded = encodeFrozen(frozen);
2291
- if (typeof encoded === "object" && encoded !== null && !Array.isArray(encoded) && encoded.__reason === "max_serialized_value_bytes") {
2292
- const bytes2 = jsonLiteralUtf8Bytes(encoded);
2293
- return { value: encoded, bytes: bytes2, visitedNodes };
2294
- }
2295
2455
  const bytes = jsonLiteralUtf8Bytes(encoded);
2296
- if (bytes > maxSerializedValueBytes) {
2456
+ if (!isByteBudgetStub(encoded) && bytes > maxSerializedValueBytes) {
2297
2457
  const bounded = truncation("max_serialized_value_bytes", { __serialized_bytes: bytes });
2298
2458
  return { value: bounded, bytes: jsonLiteralUtf8Bytes(bounded), visitedNodes };
2299
2459
  }
@@ -2604,7 +2764,7 @@ var createExecutionRecorder = (options) => {
2604
2764
  const sweepIntervalNs = maxExecutionHoldNs / 4n < 50000000n ? maxExecutionHoldNs / 4n : 50000000n;
2605
2765
  const memoryBudget = new RecorderMemoryBudget(
2606
2766
  maxActiveMemoryBytes,
2607
- options.maxSerializedValueBytes ?? 8 * 1024
2767
+ options.maxSerializedValueBytes ?? 16 * 1024
2608
2768
  );
2609
2769
  const serializer = createSafeSerializer(options);
2610
2770
  const excludesSource = createSourceExclusionMatcher(options.excludeSources);
@@ -2669,7 +2829,10 @@ var createExecutionRecorder = (options) => {
2669
2829
  };
2670
2830
  const encodeEventValues = (events) => events.map((event) => {
2671
2831
  if (event.type === "function_enter") {
2672
- return { ...event, args: event.args.map((argument) => serializer.encode(argument)) };
2832
+ return {
2833
+ ...event,
2834
+ ...event.args === void 0 ? {} : { args: event.args.map((argument) => serializer.encode(argument)) }
2835
+ };
2673
2836
  }
2674
2837
  if (event.type === "function_exit") {
2675
2838
  return { ...event, returnValue: serializer.encode(event.returnValue) };
@@ -2716,7 +2879,7 @@ var createExecutionRecorder = (options) => {
2716
2879
  };
2717
2880
  const eventsHaveOmittedValues = (events) => {
2718
2881
  for (const event of events) {
2719
- if (event.type === "function_enter" && event.args.some((arg) => rasputinTagKind(arg) === "omitted")) {
2882
+ if (event.type === "function_enter" && (event.args ?? []).some((arg) => rasputinTagKind(arg) === "omitted")) {
2720
2883
  return true;
2721
2884
  }
2722
2885
  if (event.type === "function_exit" && rasputinTagKind(event.returnValue) === "omitted") {
@@ -3831,69 +3994,6 @@ var createExecutionRecorder = (options) => {
3831
3994
  };
3832
3995
 
3833
3996
  // src/execution-recorder/automatic-runtime.ts
3834
- var AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v3";
3835
- var runtimeSymbol = Symbol.for(AUTOMATIC_RUNTIME_SYMBOL);
3836
- var passthroughHandle = () => ({
3837
- leave: (value) => value,
3838
- fail: () => {
3839
- },
3840
- end: () => {
3841
- },
3842
- run: function __rasputinHandleRun__3(callback) {
3843
- return runExactlyOnce((invoke) => invoke(), callback);
3844
- },
3845
- suspend: (value) => value,
3846
- resume: (value) => value
3847
- });
3848
- var isolateHandle = (handle) => ({
3849
- leave: (value) => {
3850
- try {
3851
- return handle.leave(value);
3852
- } catch {
3853
- return value;
3854
- }
3855
- },
3856
- fail: (error, liveArgs) => {
3857
- try {
3858
- handle.fail(error, liveArgs);
3859
- } catch {
3860
- }
3861
- },
3862
- end: () => {
3863
- try {
3864
- handle.end();
3865
- } catch {
3866
- }
3867
- },
3868
- run: function __rasputinHandleRun__3(callback) {
3869
- return runExactlyOnce((invoke) => handle.run(invoke), callback);
3870
- },
3871
- suspend: (value) => {
3872
- try {
3873
- return handle.suspend(value);
3874
- } catch {
3875
- return value;
3876
- }
3877
- },
3878
- resume: (value) => {
3879
- try {
3880
- return handle.resume(value);
3881
- } catch {
3882
- return value;
3883
- }
3884
- }
3885
- });
3886
- var passthroughRun = (_planIndex, _args, callback) => callback();
3887
- var passthroughEnter = () => passthroughHandle();
3888
- var bindPassthrough = (module) => {
3889
- module.cell.run = passthroughRun;
3890
- module.cell.enter = passthroughEnter;
3891
- };
3892
- var attachRunner = (cell) => {
3893
- const run = ((planIndex, args, callback, omitValues) => cell.run(planIndex, args, callback, omitValues));
3894
- run.enter = (planIndex, args, omitValues) => cell.enter(planIndex, args, omitValues);
3895
- return run;
3896
- };
3897
3997
  var bindExecution = (execution, module) => {
3898
3998
  const prepared = execution.prepareFunctionPlans(module.plans);
3899
3999
  module.cell.run = (planIndex, args, callback, omitValues) => {
@@ -3904,40 +4004,13 @@ var bindExecution = (execution, module) => {
3904
4004
  try {
3905
4005
  const plan = prepared[planIndex];
3906
4006
  return isolateHandle(
3907
- plan ? execution.enterPreparedFunction(plan, args, omitValues) : passthroughEnter(planIndex, args, omitValues)
4007
+ plan ? execution.enterPreparedFunction(plan, args, omitValues) : passthroughHandle()
3908
4008
  );
3909
4009
  } catch {
3910
4010
  return passthroughHandle();
3911
4011
  }
3912
4012
  };
3913
4013
  };
3914
- var isRegistry = (value) => Array.isArray(Reflect.get(value, "runtimes")) && Array.isArray(Reflect.get(value, "modules")) && typeof Reflect.get(value, "register") === "function";
3915
- var registerModule = (registry, plans) => {
3916
- const cell = { run: passthroughRun, enter: passthroughEnter };
3917
- const module = { plans, cell };
3918
- registry.modules.push(module);
3919
- registry.runtimes.at(-1)?.bind(module);
3920
- return attachRunner(cell);
3921
- };
3922
- var createRegistry = () => {
3923
- const registry = {
3924
- runtimes: [],
3925
- modules: [],
3926
- register(plans) {
3927
- return registerModule(registry, plans);
3928
- }
3929
- };
3930
- return registry;
3931
- };
3932
- var getAutomaticRuntimeRegistry = () => {
3933
- const existing = Reflect.get(globalThis, runtimeSymbol);
3934
- if (existing && typeof existing === "object" && isRegistry(existing)) {
3935
- return existing;
3936
- }
3937
- const registry = createRegistry();
3938
- Reflect.set(globalThis, runtimeSymbol, registry);
3939
- return registry;
3940
- };
3941
4014
  var installAutomaticExecutionRuntime = (execution) => {
3942
4015
  const registry = getAutomaticRuntimeRegistry();
3943
4016
  const runtime = {
@@ -4096,7 +4169,7 @@ var installGlobalHandlers = (client, options = {}) => {
4096
4169
 
4097
4170
  // src/sdk-meta.ts
4098
4171
  var SDK_NAME = "@rasputin-ai/node";
4099
- var SDK_VERSION = "0.5.2";
4172
+ var SDK_VERSION = "0.6.0";
4100
4173
 
4101
4174
  // src/rasputin-init.ts
4102
4175
  var publicExecution = (runtime) => ({
@@ -4175,7 +4248,7 @@ var RasputinInit = (options) => {
4175
4248
  runtime,
4176
4249
  recorderEnabled,
4177
4250
  {
4178
- projectApiKey: options.projectApiKey ?? "",
4251
+ projectApiKey: options.projectApiKey,
4179
4252
  release: options.release,
4180
4253
  apiUrl: options.apiUrl,
4181
4254
  enabled,
@@ -4195,7 +4268,7 @@ var RasputinInit = (options) => {
4195
4268
  createExecutionRecorder({ enabled: false }),
4196
4269
  false,
4197
4270
  {
4198
- projectApiKey: options.projectApiKey ?? "",
4271
+ projectApiKey: options.projectApiKey,
4199
4272
  release: options.release,
4200
4273
  apiUrl: options.apiUrl,
4201
4274
  enabled: false,