brass-runtime 1.14.0 → 1.16.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 (90) hide show
  1. package/README.md +410 -135
  2. package/dist/agent/cli/main.cjs +49 -43
  3. package/dist/agent/cli/main.js +11 -5
  4. package/dist/agent/cli/main.mjs +11 -5
  5. package/dist/agent/index.cjs +8 -3
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +7 -2
  8. package/dist/agent/index.mjs +7 -2
  9. package/dist/{chunk-BMRF4FN6.js → chunk-2WC63LJK.mjs} +68 -242
  10. package/dist/chunk-3RG5ZIWI.js +10 -0
  11. package/dist/chunk-45F7OKGT.cjs +104 -0
  12. package/dist/chunk-5YOQOXEQ.cjs +2491 -0
  13. package/dist/chunk-7HUOJA4W.cjs +493 -0
  14. package/dist/{chunk-4N2JEK4H.mjs → chunk-7LVI2GIN.js} +252 -495
  15. package/dist/chunk-7TL2LHQJ.js +2491 -0
  16. package/dist/chunk-7V4KY4RL.mjs +104 -0
  17. package/dist/chunk-7XOPAB5Q.js +2143 -0
  18. package/dist/chunk-CCKHV5BT.mjs +193 -0
  19. package/dist/chunk-CY33PGEX.mjs +1110 -0
  20. package/dist/chunk-DJQ7OMMB.cjs +144 -0
  21. package/dist/chunk-F5EUMJL7.mjs +2143 -0
  22. package/dist/chunk-FM4W4QPL.js +193 -0
  23. package/dist/chunk-G3XGCZDQ.js +131 -0
  24. package/dist/{chunk-JT7D6M5H.js → chunk-G6IQOE4P.mjs} +252 -495
  25. package/dist/chunk-GOV47PPB.mjs +552 -0
  26. package/dist/chunk-H55LI6WY.js +93 -0
  27. package/dist/chunk-IJT6RRQ5.cjs +93 -0
  28. package/dist/chunk-J3H54ZRV.mjs +131 -0
  29. package/dist/chunk-JF4XXPZ5.cjs +552 -0
  30. package/dist/chunk-JNFRRJYH.cjs +2143 -0
  31. package/dist/chunk-JX3LZQJH.cjs +354 -0
  32. package/dist/chunk-K2T3DV26.mjs +93 -0
  33. package/dist/chunk-KCPT2D6G.js +552 -0
  34. package/dist/chunk-MWXMNYJS.cjs +1110 -0
  35. package/dist/{chunk-XTMZTVIT.cjs → chunk-N6VHMOWB.cjs} +140 -134
  36. package/dist/{chunk-WJESVBWN.js → chunk-NC5SDRYE.js} +16 -10
  37. package/dist/chunk-NOYZIMUJ.mjs +144 -0
  38. package/dist/chunk-NYL4D7SK.cjs +131 -0
  39. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  40. package/dist/{chunk-UWMMYKVK.mjs → chunk-OOGJ73B6.js} +68 -242
  41. package/dist/chunk-PNVFW245.js +144 -0
  42. package/dist/chunk-PRWCB3QL.mjs +2491 -0
  43. package/dist/chunk-QY5FKYEQ.js +1110 -0
  44. package/dist/chunk-ROJC3NBJ.js +104 -0
  45. package/dist/chunk-SPUEME2B.cjs +343 -0
  46. package/dist/chunk-TDVMADDN.js +343 -0
  47. package/dist/chunk-TVN5I4U6.cjs +193 -0
  48. package/dist/chunk-U5KWK3PX.mjs +343 -0
  49. package/dist/chunk-VFIUZG7J.mjs +354 -0
  50. package/dist/{chunk-BKBFSOGT.cjs → chunk-WQ5QNU5R.cjs} +460 -703
  51. package/dist/chunk-XDZOO4L5.js +354 -0
  52. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  53. package/dist/{chunk-MQF7HZ7Y.mjs → chunk-ZGLD4TVZ.mjs} +16 -10
  54. package/dist/client-CtFmoDvM.d.ts +645 -0
  55. package/dist/core/index.cjs +284 -0
  56. package/dist/core/index.d.ts +567 -0
  57. package/dist/core/index.js +284 -0
  58. package/dist/core/index.mjs +284 -0
  59. package/dist/{effect-DM56H743.d.ts → effect-CGNl5Rqp.d.ts} +118 -11
  60. package/dist/effectRunner-3ZHAD3LE.cjs +8 -0
  61. package/dist/effectRunner-A4CHJXJI.js +8 -0
  62. package/dist/effectRunner-OPUF6QRN.mjs +8 -0
  63. package/dist/http/index.cjs +4130 -890
  64. package/dist/http/index.d.ts +2289 -219
  65. package/dist/http/index.js +4116 -876
  66. package/dist/http/index.mjs +4116 -876
  67. package/dist/http/testing.cjs +159 -0
  68. package/dist/http/testing.d.ts +42 -0
  69. package/dist/http/testing.js +159 -0
  70. package/dist/http/testing.mjs +159 -0
  71. package/dist/index.cjs +305 -1168
  72. package/dist/index.d.ts +9 -701
  73. package/dist/index.js +176 -1039
  74. package/dist/index.mjs +176 -1039
  75. package/dist/observability/index.cjs +677 -0
  76. package/dist/observability/index.d.ts +79 -0
  77. package/dist/observability/index.js +677 -0
  78. package/dist/observability/index.mjs +677 -0
  79. package/dist/schedule-Fque9Abz.d.ts +70 -0
  80. package/dist/schema/index.cjs +25 -0
  81. package/dist/schema/index.d.ts +177 -0
  82. package/dist/schema/index.js +25 -0
  83. package/dist/schema/index.mjs +25 -0
  84. package/dist/server-C8hDXA74.d.ts +674 -0
  85. package/dist/stream-dvSs0QS5.d.ts +74 -0
  86. package/dist/tracer-B5tRH9H7.d.ts +230 -0
  87. package/dist/tracing-Dt9S_6V8.d.ts +148 -0
  88. package/package.json +37 -3
  89. package/dist/chunk-SKVY72E5.cjs +0 -667
  90. package/dist/stream-Oqe6WeLE.d.ts +0 -173
@@ -0,0 +1,354 @@
1
+ import {
2
+ makeBoundedRingBuffer
3
+ } from "./chunk-7LVI2GIN.js";
4
+
5
+ // src/core/runtime/metrics.ts
6
+ var DEFAULT_BOUNDARIES = [1, 5, 10, 25, 50, 100, 250, 500, 1e3, 5e3, 1e4];
7
+ function makeMetrics() {
8
+ const counters = /* @__PURE__ */ new Map();
9
+ const gauges = /* @__PURE__ */ new Map();
10
+ const histograms = /* @__PURE__ */ new Map();
11
+ const key = (name, labels) => labels ? `${name}|${Object.entries(labels).sort().map(([k, v]) => `${k}=${v}`).join(",")}` : name;
12
+ const counter = (name, labels = {}) => {
13
+ const k = key(name, labels);
14
+ if (!counters.has(k)) counters.set(k, { labels, value: 0 });
15
+ const entry = counters.get(k);
16
+ return {
17
+ increment: (n = 1) => {
18
+ entry.value += Math.max(0, n);
19
+ },
20
+ value: () => entry.value
21
+ };
22
+ };
23
+ const gauge = (name, labels = {}) => {
24
+ const k = key(name, labels);
25
+ if (!gauges.has(k)) gauges.set(k, { labels, value: 0 });
26
+ const entry = gauges.get(k);
27
+ return {
28
+ set: (v) => {
29
+ entry.value = v;
30
+ },
31
+ increment: (n = 1) => {
32
+ entry.value += n;
33
+ },
34
+ decrement: (n = 1) => {
35
+ entry.value -= n;
36
+ },
37
+ value: () => entry.value
38
+ };
39
+ };
40
+ const histogram = (name, boundaries = DEFAULT_BOUNDARIES, labels = {}) => {
41
+ const k = key(name, labels);
42
+ if (!histograms.has(k)) {
43
+ const sorted = [...boundaries].sort((a, b) => a - b);
44
+ histograms.set(k, {
45
+ labels,
46
+ boundaries: sorted,
47
+ data: { boundaries: sorted, counts: new Array(sorted.length + 1).fill(0), sum: 0, count: 0, min: Infinity, max: -Infinity }
48
+ });
49
+ }
50
+ const entry = histograms.get(k);
51
+ return {
52
+ observe: (value, exemplar) => {
53
+ entry.data.sum += value;
54
+ entry.data.count++;
55
+ entry.data.min = Math.min(entry.data.min, value);
56
+ entry.data.max = Math.max(entry.data.max, value);
57
+ let placed = false;
58
+ let bucketIndex = entry.boundaries.length;
59
+ for (let i = 0; i < entry.boundaries.length; i++) {
60
+ if (value <= entry.boundaries[i]) {
61
+ entry.data.counts[i]++;
62
+ bucketIndex = i;
63
+ placed = true;
64
+ break;
65
+ }
66
+ }
67
+ if (!placed) entry.data.counts[entry.boundaries.length]++;
68
+ if (exemplar) {
69
+ const exemplars = entry.data.exemplars ?? new Array(entry.boundaries.length + 1).fill(void 0);
70
+ exemplars[bucketIndex] = {
71
+ ...exemplar,
72
+ value,
73
+ timestamp: exemplar.timestamp
74
+ };
75
+ entry.data.exemplars = exemplars;
76
+ }
77
+ },
78
+ buckets: () => ({ ...entry.data, counts: [...entry.data.counts], exemplars: entry.data.exemplars ? [...entry.data.exemplars] : void 0 }),
79
+ percentile: (p) => {
80
+ const target = Math.ceil(entry.data.count * (p / 100));
81
+ let cumulative = 0;
82
+ for (let i = 0; i < entry.boundaries.length; i++) {
83
+ cumulative += entry.data.counts[i];
84
+ if (cumulative >= target) return entry.boundaries[i];
85
+ }
86
+ return entry.data.max;
87
+ }
88
+ };
89
+ };
90
+ return {
91
+ counter,
92
+ gauge,
93
+ histogram,
94
+ snapshot: () => ({
95
+ counters: Array.from(counters.entries()).map(([k, v]) => ({ name: k.split("|")[0], labels: v.labels, value: v.value })),
96
+ gauges: Array.from(gauges.entries()).map(([k, v]) => ({ name: k.split("|")[0], labels: v.labels, value: v.value })),
97
+ histograms: Array.from(histograms.entries()).map(([k, v]) => ({ name: k.split("|")[0], labels: v.labels, buckets: v.data }))
98
+ }),
99
+ reset: () => {
100
+ counters.clear();
101
+ gauges.clear();
102
+ histograms.clear();
103
+ }
104
+ };
105
+ }
106
+
107
+ // src/core/runtime/events.ts
108
+ function makeRuntimeEventRecord(ev, ctx, seq) {
109
+ const wallTs = Date.now();
110
+ const ts = typeof performance !== "undefined" ? performance.now() : wallTs;
111
+ return {
112
+ ...ctx,
113
+ contextFiberId: ctx.fiberId,
114
+ contextScopeId: ctx.scopeId,
115
+ ...ev,
116
+ seq,
117
+ wallTs,
118
+ ts
119
+ };
120
+ }
121
+ function runtimeEventRecordContext(record) {
122
+ return {
123
+ fiberId: record.contextFiberId ?? record.fiberId,
124
+ scopeId: record.contextScopeId ?? record.scopeId,
125
+ traceId: record.traceId,
126
+ spanId: record.spanId,
127
+ parentSpanId: record.parentSpanId,
128
+ traceState: record.traceState,
129
+ baggage: record.baggage,
130
+ sampled: record.sampled
131
+ };
132
+ }
133
+
134
+ // src/core/runtime/eventBus.ts
135
+ function runtimeHooksToEventHandler(hooks) {
136
+ return (record) => {
137
+ hooks.emit(record, runtimeEventRecordContext(record));
138
+ };
139
+ }
140
+ var EventBus = class {
141
+ constructor(options = {}) {
142
+ this.options = options;
143
+ }
144
+ options;
145
+ seq = 1;
146
+ subs = [];
147
+ flushScheduled = false;
148
+ boundFlush = () => this.flush();
149
+ emit(ev, ctx) {
150
+ if (this.subs.length === 0) return;
151
+ const full = makeRuntimeEventRecord(ev, ctx, this.seq++);
152
+ for (const s of this.subs) {
153
+ const st = s.q.push(full);
154
+ if (st & 2 /* Dropped */) s.dropped++;
155
+ }
156
+ if (!this.flushScheduled) {
157
+ this.flushScheduled = true;
158
+ queueMicrotask(this.boundFlush);
159
+ }
160
+ }
161
+ subscribe(handler, perSubscriberCapacity = 2048) {
162
+ this.subs.push({
163
+ handler,
164
+ q: makeBoundedRingBuffer(perSubscriberCapacity, perSubscriberCapacity, this.options),
165
+ dropped: 0
166
+ });
167
+ return () => {
168
+ this.subs = this.subs.filter((s) => s.handler !== handler);
169
+ };
170
+ }
171
+ subscribeHooks(hooks, perSubscriberCapacity = 2048) {
172
+ return this.subscribe(runtimeHooksToEventHandler(hooks), perSubscriberCapacity);
173
+ }
174
+ flush(budget = 4096) {
175
+ this.flushScheduled = false;
176
+ for (const s of this.subs) {
177
+ let n = 0;
178
+ if (s.dropped > 0) {
179
+ const dropEv = makeRuntimeEventRecord(
180
+ {
181
+ type: "log",
182
+ level: "warn",
183
+ message: "eventbus.dropped",
184
+ fields: { dropped: s.dropped }
185
+ },
186
+ {},
187
+ 0
188
+ );
189
+ try {
190
+ s.handler(dropEv);
191
+ } catch {
192
+ }
193
+ s.dropped = 0;
194
+ }
195
+ while (n++ < budget) {
196
+ const ev = s.q.shift();
197
+ if (!ev) break;
198
+ try {
199
+ s.handler(ev);
200
+ } catch {
201
+ }
202
+ }
203
+ }
204
+ }
205
+ };
206
+
207
+ // src/core/runtime/tracingSink.ts
208
+ var InMemoryTracer = class {
209
+ constructor(options = {}) {
210
+ this.options = options;
211
+ }
212
+ options;
213
+ spans = /* @__PURE__ */ new Map();
214
+ // key: spanId
215
+ prunedFinishedSpans = 0;
216
+ emit(ev, ctx) {
217
+ if (ctx.sampled === false) return;
218
+ const wallTs = this.now();
219
+ const traceId = ctx.traceId ?? "no-trace";
220
+ const spanId = ctx.spanId;
221
+ if (ev.type === "fiber.start") {
222
+ if (!spanId) return;
223
+ this.spans.set(spanId, {
224
+ traceId,
225
+ spanId,
226
+ parentSpanId: ctx.parentSpanId,
227
+ traceState: ctx.traceState,
228
+ name: ev.name ?? `fiber#${ev.fiberId}`,
229
+ startWallTs: wallTs,
230
+ attrs: this.attrs({ fiberId: ev.fiberId, parentFiberId: ev.parentFiberId, scopeId: ev.scopeId }),
231
+ links: [],
232
+ events: []
233
+ });
234
+ return;
235
+ }
236
+ if (ev.type === "fiber.end") {
237
+ if (!spanId) return;
238
+ const sp = this.spans.get(spanId);
239
+ if (sp) {
240
+ sp.endWallTs = wallTs;
241
+ sp.events.push({ wallTs, name: "fiber.end", attrs: this.attrs({ status: ev.status, error: this.error(ev.error) }) });
242
+ this.pruneFinished();
243
+ }
244
+ return;
245
+ }
246
+ if (ev.type === "span.start") {
247
+ if (!spanId) return;
248
+ this.spans.set(spanId, {
249
+ traceId,
250
+ spanId,
251
+ parentSpanId: ctx.parentSpanId,
252
+ traceState: ctx.traceState,
253
+ name: ev.name,
254
+ startWallTs: wallTs,
255
+ attrs: this.attrs(ev.attributes ?? {}),
256
+ links: ev.links ?? [],
257
+ events: []
258
+ });
259
+ return;
260
+ }
261
+ if (ev.type === "span.event") {
262
+ if (!spanId) return;
263
+ const sp = this.spans.get(spanId);
264
+ if (!sp) return;
265
+ sp.events.push({ wallTs, name: ev.name, attrs: this.attrs(ev.attributes ?? {}) });
266
+ return;
267
+ }
268
+ if (ev.type === "span.end") {
269
+ if (!spanId) return;
270
+ const sp = this.spans.get(spanId);
271
+ if (sp) {
272
+ sp.endWallTs = wallTs;
273
+ sp.events.push({ wallTs, name: "span.end", attrs: this.attrs({ status: ev.status, error: this.error(ev.error), ...ev.attributes ?? {} }) });
274
+ this.pruneFinished();
275
+ }
276
+ return;
277
+ }
278
+ if (ev.type === "fiber.suspend" || ev.type === "fiber.resume" || ev.type === "scope.open" || ev.type === "scope.close") {
279
+ if (!spanId) return;
280
+ const sp = this.spans.get(spanId);
281
+ if (!sp) return;
282
+ sp.events.push({ wallTs, name: ev.type, attrs: this.attrs(ev) });
283
+ }
284
+ }
285
+ exportFinished() {
286
+ this.pruneFinished();
287
+ return Array.from(this.spans.values()).filter((s) => s.endWallTs != null);
288
+ }
289
+ pruneFinished(spanIds) {
290
+ let dropped = 0;
291
+ if (spanIds) {
292
+ for (const spanId of spanIds) {
293
+ const span = this.spans.get(spanId);
294
+ if (span?.endWallTs == null) continue;
295
+ if (this.spans.delete(spanId)) dropped++;
296
+ }
297
+ this.prunedFinishedSpans += dropped;
298
+ return dropped;
299
+ }
300
+ dropped += this.pruneExpiredFinished();
301
+ dropped += this.pruneFinishedOverLimit();
302
+ this.prunedFinishedSpans += dropped;
303
+ return dropped;
304
+ }
305
+ stats() {
306
+ return {
307
+ storedSpans: this.spans.size,
308
+ finishedSpans: Array.from(this.spans.values()).filter((s) => s.endWallTs != null).length,
309
+ prunedFinishedSpans: this.prunedFinishedSpans
310
+ };
311
+ }
312
+ attrs(attrs) {
313
+ return this.options.sanitizeAttributes?.(attrs) ?? attrs;
314
+ }
315
+ error(error) {
316
+ return error === void 0 ? void 0 : this.options.sanitizeError?.(error) ?? error;
317
+ }
318
+ now() {
319
+ return this.options.clock?.() ?? Date.now();
320
+ }
321
+ pruneExpiredFinished() {
322
+ const maxAgeMs = this.options.maxSpanAgeMs;
323
+ if (maxAgeMs === void 0 || maxAgeMs <= 0) return 0;
324
+ const now = this.now();
325
+ let dropped = 0;
326
+ for (const [spanId, span] of this.spans) {
327
+ if (span.endWallTs == null) continue;
328
+ if (now - span.endWallTs > maxAgeMs && this.spans.delete(spanId)) dropped++;
329
+ }
330
+ return dropped;
331
+ }
332
+ pruneFinishedOverLimit() {
333
+ const maxFinishedSpans = this.options.maxFinishedSpans;
334
+ if (maxFinishedSpans === void 0 || maxFinishedSpans < 0) return 0;
335
+ const finished = Array.from(this.spans.values()).filter((span) => span.endWallTs != null).sort((a, b) => (a.endWallTs ?? 0) - (b.endWallTs ?? 0));
336
+ const overflow = finished.length - maxFinishedSpans;
337
+ if (overflow <= 0) return 0;
338
+ let dropped = 0;
339
+ for (let i = 0; i < overflow; i++) {
340
+ const span = finished[i];
341
+ if (this.spans.delete(span.spanId)) dropped++;
342
+ }
343
+ return dropped;
344
+ }
345
+ };
346
+
347
+ export {
348
+ makeMetrics,
349
+ makeRuntimeEventRecord,
350
+ runtimeEventRecordContext,
351
+ runtimeHooksToEventHandler,
352
+ EventBus,
353
+ InMemoryTracer
354
+ };
@@ -0,0 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ export {
9
+ __require
10
+ };
@@ -1,17 +1,23 @@
1
+ import {
2
+ race
3
+ } from "./chunk-J3H54ZRV.mjs";
4
+ import {
5
+ withScopeAsync
6
+ } from "./chunk-CCKHV5BT.mjs";
7
+ import {
8
+ fromPromiseAbortable
9
+ } from "./chunk-G6IQOE4P.mjs";
1
10
  import {
2
11
  Cause,
3
12
  Exit,
4
- async,
13
+ asyncEffect,
5
14
  asyncFail,
6
15
  asyncFlatMap,
7
16
  asyncFold,
8
17
  asyncMap,
9
18
  asyncSucceed,
10
- asyncSync,
11
- fromPromiseAbortable,
12
- race,
13
- withScopeAsync
14
- } from "./chunk-4N2JEK4H.mjs";
19
+ asyncSync
20
+ } from "./chunk-NOYZIMUJ.mjs";
15
21
 
16
22
  // src/agent/core/state.ts
17
23
  var initialAgentState = (goal) => ({
@@ -1425,10 +1431,10 @@ var decideNextAction = (state) => {
1425
1431
  };
1426
1432
 
1427
1433
  // src/agent/core/events.ts
1428
- var nowMillis = () => async((_env, cb) => {
1434
+ var nowMillis = () => asyncEffect((_env, cb) => {
1429
1435
  cb({ _tag: "Success", value: Date.now() });
1430
1436
  });
1431
- var emitAgentEvent = (event) => async((env, cb) => {
1437
+ var emitAgentEvent = (event) => asyncEffect((env, cb) => {
1432
1438
  try {
1433
1439
  env.events?.emit(event);
1434
1440
  } catch {
@@ -1684,7 +1690,7 @@ var retry = (make, options) => {
1684
1690
  };
1685
1691
 
1686
1692
  // src/agent/tools/timeout.ts
1687
- var sleep = (ms) => async((_env, cb) => {
1693
+ var sleep = (ms) => asyncEffect((_env, cb) => {
1688
1694
  const id = setTimeout(() => cb({ _tag: "Success", value: void 0 }), ms);
1689
1695
  return () => clearTimeout(id);
1690
1696
  });
@@ -2124,7 +2130,7 @@ var chunkToString = (chunk) => {
2124
2130
  return typeof maybeToString === "function" ? maybeToString.call(chunk, "utf8") : String(chunk);
2125
2131
  };
2126
2132
  var NodeShell = {
2127
- exec: (command, options) => async((_env, cb) => {
2133
+ exec: (command, options) => asyncEffect((_env, cb) => {
2128
2134
  const [bin, ...args] = command;
2129
2135
  if (!bin) {
2130
2136
  cb(