brass-runtime 1.18.1 → 1.19.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 (71) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/agent/cli/main.cjs +31 -31
  3. package/dist/agent/cli/main.js +3 -3
  4. package/dist/agent/cli/main.mjs +3 -3
  5. package/dist/agent/index.cjs +4 -4
  6. package/dist/agent/index.js +3 -3
  7. package/dist/agent/index.mjs +3 -3
  8. package/dist/{chunk-22HZQG5F.js → chunk-2R3RVNS2.js} +6 -6
  9. package/dist/{chunk-YWLLH27R.mjs → chunk-3NKXUX4T.mjs} +2 -2
  10. package/dist/{chunk-IPSMXUWA.js → chunk-4PKBNG2H.js} +38 -18
  11. package/dist/{chunk-Z3ZZMQUZ.mjs → chunk-5RVHSBJ6.mjs} +182 -34
  12. package/dist/{chunk-B5FKOLTB.mjs → chunk-5UBJT4RW.mjs} +4 -4
  13. package/dist/{chunk-5RZ7YITF.cjs → chunk-6STX4PS3.cjs} +13 -13
  14. package/dist/{chunk-XPIMJQYS.cjs → chunk-7FZUTJM3.cjs} +400 -252
  15. package/dist/{chunk-YZ5LQ32F.js → chunk-A6EG5WRL.js} +3 -3
  16. package/dist/{chunk-TTSPIU3U.js → chunk-APQBU7TM.js} +53 -32
  17. package/dist/{chunk-BC6Q6BCO.mjs → chunk-AQQQFNYD.mjs} +38 -18
  18. package/dist/{chunk-OW5VHAOE.js → chunk-B2VXVNIS.js} +1 -1
  19. package/dist/{chunk-WCBNXPN6.mjs → chunk-BLXBZ6RE.mjs} +1 -1
  20. package/dist/{chunk-7VQLEN37.js → chunk-C3CWI42G.js} +1 -1
  21. package/dist/{chunk-WI7GZF3B.cjs → chunk-DV644N7P.cjs} +85 -85
  22. package/dist/{chunk-RBHNOKH4.mjs → chunk-EKLEDIVJ.mjs} +2 -2
  23. package/dist/{chunk-S4HXADU4.js → chunk-EXBGIC66.js} +1 -1
  24. package/dist/{chunk-LSYQ3C2M.js → chunk-FC5N5QHJ.js} +2 -2
  25. package/dist/{chunk-6MLAZPBL.mjs → chunk-FNWOH2T2.js} +18 -6
  26. package/dist/{chunk-WGE2FEZE.cjs → chunk-FYWWU3Z7.cjs} +2 -2
  27. package/dist/{chunk-2OW6IFY2.cjs → chunk-GOEO763K.cjs} +21 -21
  28. package/dist/{chunk-UAKAF32U.js → chunk-GXOIUBKE.js} +2 -2
  29. package/dist/{chunk-7DU7IQHK.js → chunk-H4ZRUQZL.js} +4 -4
  30. package/dist/{chunk-JWIEMBE6.mjs → chunk-HW2CLRJ3.mjs} +6 -6
  31. package/dist/{chunk-YGR2IN4R.js → chunk-JWFOWPMB.js} +163 -155
  32. package/dist/{chunk-6V2AWT4R.mjs → chunk-KAPZHDO4.mjs} +1 -1
  33. package/dist/{chunk-EEN5OTCR.mjs → chunk-KDXNWGPB.mjs} +1 -1
  34. package/dist/{chunk-UUMKZJRJ.cjs → chunk-KPOL2YEO.cjs} +18 -6
  35. package/dist/{chunk-J6DUHITE.cjs → chunk-MA74OYCI.cjs} +6 -6
  36. package/dist/{chunk-H626ZTDZ.mjs → chunk-MUMBUXU6.mjs} +53 -32
  37. package/dist/{chunk-5LC7V2OZ.cjs → chunk-NQW3YUFN.cjs} +18 -18
  38. package/dist/{chunk-EICAJDNX.cjs → chunk-OO7BGCC3.cjs} +54 -34
  39. package/dist/{chunk-7GBJYOX7.mjs → chunk-OX6MF7SZ.mjs} +163 -155
  40. package/dist/{chunk-WVSZOPGQ.cjs → chunk-QBVS3UYN.cjs} +245 -237
  41. package/dist/{chunk-WUDHOZIH.js → chunk-RZGB3DXR.js} +182 -34
  42. package/dist/{chunk-COOW7BJX.mjs → chunk-URVS2OE2.mjs} +3 -3
  43. package/dist/{chunk-HCJ4S3YB.js → chunk-UZQ3BB6W.mjs} +18 -6
  44. package/dist/{chunk-KNTJ7FQB.cjs → chunk-YQWZ7FZX.cjs} +5 -5
  45. package/dist/{chunk-ELIECDYN.cjs → chunk-Z2YIDHRI.cjs} +5 -5
  46. package/dist/{chunk-2JHJ4YHS.cjs → chunk-ZDZNV6NA.cjs} +59 -38
  47. package/dist/core/index.cjs +8 -8
  48. package/dist/core/index.js +7 -7
  49. package/dist/core/index.mjs +7 -7
  50. package/dist/http/index.cjs +54 -54
  51. package/dist/http/index.js +7 -7
  52. package/dist/http/index.mjs +7 -7
  53. package/dist/http/testing.cjs +9 -9
  54. package/dist/http/testing.js +5 -5
  55. package/dist/http/testing.mjs +5 -5
  56. package/dist/index.cjs +86 -86
  57. package/dist/index.js +8 -8
  58. package/dist/index.mjs +8 -8
  59. package/dist/observability/index.cjs +10 -10
  60. package/dist/observability/index.js +9 -9
  61. package/dist/observability/index.mjs +9 -9
  62. package/dist/perf/cli.cjs +26 -26
  63. package/dist/perf/cli.js +11 -11
  64. package/dist/perf/cli.mjs +11 -11
  65. package/dist/perf/index.cjs +13 -13
  66. package/dist/perf/index.js +11 -11
  67. package/dist/perf/index.mjs +11 -11
  68. package/dist/schema/index.cjs +2 -2
  69. package/dist/schema/index.js +1 -1
  70. package/dist/schema/index.mjs +1 -1
  71. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RuntimeService
3
- } from "./chunk-LSYQ3C2M.js";
3
+ } from "./chunk-FC5N5QHJ.js";
4
4
  import {
5
5
  exemplarFromTraceContext,
6
6
  injectTraceContext,
@@ -13,33 +13,29 @@ import {
13
13
  spanEvent,
14
14
  validateHttpObservabilityOptions,
15
15
  withSpan
16
- } from "./chunk-YZ5LQ32F.js";
16
+ } from "./chunk-A6EG5WRL.js";
17
17
  import {
18
18
  HttpClientService,
19
19
  getHttpRequestPolicy,
20
20
  httpErrorStatus,
21
21
  isRetryableHttpError,
22
22
  makeDefaultHttpClient
23
- } from "./chunk-WUDHOZIH.js";
23
+ } from "./chunk-RZGB3DXR.js";
24
24
  import {
25
25
  registerHttpEffect
26
26
  } from "./chunk-TRM4JUZQ.js";
27
27
  import {
28
28
  layerEffect,
29
29
  makeServiceTag
30
- } from "./chunk-S4HXADU4.js";
30
+ } from "./chunk-EXBGIC66.js";
31
31
  import {
32
32
  Runtime,
33
33
  fromPromiseAbortable,
34
34
  getCurrentFiber
35
- } from "./chunk-TTSPIU3U.js";
35
+ } from "./chunk-APQBU7TM.js";
36
36
  import {
37
37
  Cause,
38
38
  asyncEffect,
39
- asyncFail,
40
- asyncFlatMap,
41
- asyncFold,
42
- asyncSucceed,
43
39
  asyncSync
44
40
  } from "./chunk-UB4B6OFY.js";
45
41
 
@@ -134,43 +130,147 @@ function withHttpObservability(options) {
134
130
  return withLeanHttpSampledSpanObservability(next, resolved, metricCache);
135
131
  }
136
132
  return (req) => {
137
- const run = asyncFlatMap(
138
- beginHttpObservation(req, resolved, metricCache),
139
- (state) => asyncFlatMap(
140
- logHttpRequest(req, resolved),
141
- () => asyncFlatMap(
142
- prepareHttpRequest(req, resolved),
143
- (wireReq) => asyncFold(
144
- next(wireReq),
145
- (error) => {
146
- const finish = state.finishWithError(error);
147
- const adaptiveLimiterAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
148
- const traceEvent = !shouldEmitHttpSpanEvents(resolved) ? asyncSucceed(void 0) : spanEvent("http.client.error", {
149
- ...finish.spanAttributes,
150
- ...adaptiveLimiterAttrs,
151
- "error.type": error._tag
152
- });
153
- return asyncFlatMap(
154
- traceEvent,
155
- () => asyncFlatMap(logHttpError(req, error, finish, resolved), () => asyncFail(error))
156
- );
157
- },
158
- (res) => {
159
- const finish = state.finishWithResponse(res);
160
- const adaptiveLimiterAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
161
- const traceEvent = !shouldEmitHttpSpanEvents(resolved) ? asyncSucceed(void 0) : spanEvent("http.client.response", {
162
- ...finish.spanAttributes,
163
- ...adaptiveLimiterAttrs
164
- });
165
- return asyncFlatMap(
166
- traceEvent,
167
- () => asyncFlatMap(logHttpResponse(req, res, finish, resolved), () => asyncSucceed(res))
168
- );
169
- }
170
- )
171
- )
172
- )
173
- );
133
+ const run = asyncEffect((env, cb) => {
134
+ const startedAt = resolved.clock();
135
+ const baseLabels = getCachedBaseLabels(req, resolved, metricCache);
136
+ const inFlight = resolved.metrics ? getCachedMetric(
137
+ metricCache,
138
+ metricCache.inFlightGauges,
139
+ metricCacheKey("brass_http_client_in_flight", baseLabels),
140
+ () => resolved.metrics.gauge("brass_http_client_in_flight", baseLabels)
141
+ ) : void 0;
142
+ inFlight?.increment();
143
+ let finished = false;
144
+ let cancelInner;
145
+ const completeFinish = (outcome, status, extra) => {
146
+ const durationMs = Math.max(0, resolved.clock() - startedAt);
147
+ const labels = requestFinishLabelsFromBase(baseLabels, outcome, status);
148
+ if (!finished) {
149
+ finished = true;
150
+ if (inFlight && inFlight.value() > 0) inFlight.decrement();
151
+ if (resolved.metrics) {
152
+ getCachedMetric(
153
+ metricCache,
154
+ metricCache.requestCounters,
155
+ metricCacheKey("brass_http_client_requests_total", labels),
156
+ () => resolved.metrics.counter("brass_http_client_requests_total", labels)
157
+ ).increment();
158
+ getCachedMetric(
159
+ metricCache,
160
+ metricCache.durationHistograms,
161
+ metricCacheKey("brass_http_client_duration_ms", labels),
162
+ () => resolved.metrics.histogram(
163
+ "brass_http_client_duration_ms",
164
+ [...resolved.durationBuckets ?? DEFAULT_DURATION_BUCKETS],
165
+ labels
166
+ )
167
+ ).observe(
168
+ durationMs,
169
+ resolved.spans === false ? void 0 : currentTraceExemplar(durationMs, startedAt + durationMs)
170
+ );
171
+ }
172
+ }
173
+ return {
174
+ durationMs,
175
+ outcome,
176
+ labels,
177
+ spanAttributes: resolved.spans === false ? EMPTY_SPAN_ATTRIBUTES : {
178
+ "http.duration_ms": durationMs,
179
+ "http.outcome": outcome,
180
+ ...status ? { "http.status_code": Number(status) } : {},
181
+ ...status ? { "http.response.status_code": Number(status) } : {},
182
+ ...extra
183
+ }
184
+ };
185
+ };
186
+ const fiber = getCurrentFiber();
187
+ fiber?.addFinalizer?.(() => {
188
+ completeFinish("abort", void 0, { "http.cancelled": true });
189
+ });
190
+ const reqLogLevel = resolved.logs === false ? false : resolved.logs.requestLevel ?? false;
191
+ if (reqLogLevel) {
192
+ const logEff = logEffect(reqLogLevel, "http.client.request", requestLogFields(req, resolved));
193
+ registerHttpEffect(logEff, env, () => void 0);
194
+ }
195
+ const wireReq = resolved.injectTraceHeaders ? injectCurrentTraceContext(req) : req;
196
+ const onSuccess = (res) => {
197
+ const finish = completeFinish(httpStatusOutcome(res.status), String(res.status), {});
198
+ const adaptiveAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
199
+ if (shouldEmitHttpSpanEvents(resolved)) {
200
+ const ev = spanEvent("http.client.response", {
201
+ ...finish.spanAttributes,
202
+ ...adaptiveAttrs
203
+ });
204
+ registerHttpEffect(ev, env, () => void 0);
205
+ }
206
+ const respLevel = resolved.logs === false ? false : (resolved.logs.responseLevel ?? false) || (finish.outcome === "error" ? resolved.logs.errorLevel ?? "warn" : false);
207
+ if (respLevel) {
208
+ const logEff = logEffect(respLevel, "http.client.response", {
209
+ ...requestLogFields(req, resolved),
210
+ status: res.status,
211
+ statusText: res.statusText,
212
+ outcome: finish.outcome,
213
+ durationMs: finish.durationMs
214
+ });
215
+ registerHttpEffect(logEff, env, () => void 0);
216
+ }
217
+ cb({ _tag: "Success", value: res });
218
+ };
219
+ const onError = (error) => {
220
+ const status = httpErrorStatus(error);
221
+ const finish = completeFinish(
222
+ httpErrorOutcome(error),
223
+ status !== void 0 ? String(status) : void 0,
224
+ {
225
+ "error.type": error._tag,
226
+ "http.retryable": isRetryableHttpError(error)
227
+ }
228
+ );
229
+ const adaptiveAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
230
+ if (shouldEmitHttpSpanEvents(resolved)) {
231
+ const ev = spanEvent("http.client.error", {
232
+ ...finish.spanAttributes,
233
+ ...adaptiveAttrs,
234
+ "error.type": error._tag
235
+ });
236
+ registerHttpEffect(ev, env, () => void 0);
237
+ }
238
+ const errLevel = resolved.logs === false ? false : resolved.logs.errorLevel ?? "error";
239
+ if (errLevel) {
240
+ const statusText = httpErrorStatusText(error);
241
+ const logEff = logEffect(errLevel, "http.client.error", {
242
+ ...requestLogFields(req, resolved),
243
+ outcome: finish.outcome,
244
+ durationMs: finish.durationMs,
245
+ ...status !== void 0 ? { status } : {},
246
+ ...statusText ? { statusText } : {},
247
+ retryable: isRetryableHttpError(error),
248
+ errorTag: error._tag,
249
+ message: httpErrorMessage(error)
250
+ });
251
+ registerHttpEffect(logEff, env, () => void 0);
252
+ }
253
+ cb({ _tag: "Failure", cause: Cause.fail(error) });
254
+ };
255
+ try {
256
+ cancelInner = registerHttpEffect(next(wireReq), env, (exit) => {
257
+ cancelInner = void 0;
258
+ if (exit._tag === "Success") onSuccess(exit.value);
259
+ else {
260
+ const failure = Cause.firstFailure(exit.cause);
261
+ if (failure._tag === "Some") onError(failure.value);
262
+ else cb(exit);
263
+ }
264
+ });
265
+ } catch (error) {
266
+ cb({ _tag: "Failure", cause: Cause.die(error) });
267
+ }
268
+ return () => {
269
+ const cancel = cancelInner;
270
+ cancelInner = void 0;
271
+ cancel?.();
272
+ };
273
+ });
174
274
  if (resolved.spans === false) return run;
175
275
  return withSpan(spanName(req, resolved.spans), run, spanStartAttributes(req, resolved));
176
276
  };
@@ -191,7 +291,7 @@ function canUseLeanHttpSampledSpanPath(options, adaptiveLimiter) {
191
291
  function withLeanHttpSampledSpanObservability(next, options, metricCache) {
192
292
  return (req) => asyncEffect((env, cb) => {
193
293
  const startedAt = options.clock();
194
- const baseLabels = requestBaseLabels(req, options);
294
+ const baseLabels = getCachedBaseLabels(req, options, metricCache);
195
295
  const handles = beginLeanHttpMetricsObservation(baseLabels, options, metricCache);
196
296
  const span = startLeanHttpSpan(req, options);
197
297
  let finished = false;
@@ -256,7 +356,7 @@ function withLeanHttpSampledSpanObservability(next, options, metricCache) {
256
356
  function withLeanHttpMetricsObservability(next, options, metricCache) {
257
357
  return (req) => asyncEffect((env, cb) => {
258
358
  const startedAt = options.clock();
259
- const baseLabels = requestBaseLabels(req, options);
359
+ const baseLabels = getCachedBaseLabels(req, options, metricCache);
260
360
  const handles = beginLeanHttpMetricsObservation(baseLabels, options, metricCache);
261
361
  let finished = false;
262
362
  let cancelInner;
@@ -486,9 +586,23 @@ function makeHttpMetricCache() {
486
586
  leanEntries: /* @__PURE__ */ new Map(),
487
587
  inFlightGauges: /* @__PURE__ */ new Map(),
488
588
  requestCounters: /* @__PURE__ */ new Map(),
489
- durationHistograms: /* @__PURE__ */ new Map()
589
+ durationHistograms: /* @__PURE__ */ new Map(),
590
+ baseLabelsCache: /* @__PURE__ */ new Map()
490
591
  };
491
592
  }
593
+ function getCachedBaseLabels(req, options, cache) {
594
+ if (cache.disabled) return requestBaseLabels(req, options);
595
+ const route = requestRoute(req, options);
596
+ const host = options.includeHostLabel ? requestHost(req) : void 0;
597
+ const policy = getHttpRequestPolicy(req);
598
+ const preset = typeof policy === "string" ? policy : policy?.preset;
599
+ const key = `${req.method}|${host ?? ""}|${route ?? ""}|${preset ?? ""}`;
600
+ const existing = cache.baseLabelsCache.get(key);
601
+ if (existing) return existing;
602
+ const fresh = requestBaseLabels(req, options);
603
+ cache.baseLabelsCache.set(key, fresh);
604
+ return fresh;
605
+ }
492
606
  function attachMetricCache(metrics, cache) {
493
607
  if (!metrics) return;
494
608
  const existing = metricResetRegistry.get(metrics);
@@ -536,112 +650,6 @@ function metricCacheKey(name, labels) {
536
650
  }
537
651
  return key;
538
652
  }
539
- function beginHttpObservation(req, options, metricCache) {
540
- return asyncSync(() => {
541
- const startedAt = options.clock();
542
- let finished = false;
543
- const baseLabels = requestBaseLabels(req, options);
544
- const inFlight = options.metrics ? getCachedMetric(
545
- metricCache,
546
- metricCache.inFlightGauges,
547
- metricCacheKey("brass_http_client_in_flight", baseLabels),
548
- () => options.metrics.gauge("brass_http_client_in_flight", baseLabels)
549
- ) : void 0;
550
- inFlight?.increment();
551
- const finish = (outcome, status, extra = {}) => {
552
- const durationMs = Math.max(0, options.clock() - startedAt);
553
- const labels = requestFinishLabelsFromBase(baseLabels, outcome, status);
554
- if (!finished) {
555
- finished = true;
556
- if (inFlight && inFlight.value() > 0) inFlight.decrement();
557
- if (options.metrics) {
558
- getCachedMetric(
559
- metricCache,
560
- metricCache.requestCounters,
561
- metricCacheKey("brass_http_client_requests_total", labels),
562
- () => options.metrics.counter("brass_http_client_requests_total", labels)
563
- ).increment();
564
- getCachedMetric(
565
- metricCache,
566
- metricCache.durationHistograms,
567
- metricCacheKey("brass_http_client_duration_ms", labels),
568
- () => options.metrics.histogram(
569
- "brass_http_client_duration_ms",
570
- [...options.durationBuckets ?? DEFAULT_DURATION_BUCKETS],
571
- labels
572
- )
573
- ).observe(
574
- durationMs,
575
- options.spans === false ? void 0 : currentTraceExemplar(durationMs, startedAt + durationMs)
576
- );
577
- }
578
- }
579
- return {
580
- durationMs,
581
- outcome,
582
- labels,
583
- spanAttributes: options.spans === false ? EMPTY_SPAN_ATTRIBUTES : {
584
- "http.duration_ms": durationMs,
585
- "http.outcome": outcome,
586
- ...status ? { "http.status_code": Number(status) } : {},
587
- ...status ? { "http.response.status_code": Number(status) } : {},
588
- ...extra
589
- }
590
- };
591
- };
592
- const fiber = getCurrentFiber();
593
- fiber?.addFinalizer?.(() => {
594
- finish("abort", void 0, { "http.cancelled": true });
595
- });
596
- return {
597
- finishWithResponse: (res) => finish(httpStatusOutcome(res.status), String(res.status)),
598
- finishWithError: (error) => {
599
- const status = httpErrorStatus(error);
600
- return finish(httpErrorOutcome(error), status !== void 0 ? String(status) : void 0, {
601
- "error.type": error._tag,
602
- "http.retryable": isRetryableHttpError(error)
603
- });
604
- }
605
- };
606
- });
607
- }
608
- function prepareHttpRequest(req, options) {
609
- if (!options.injectTraceHeaders) return asyncSucceed(req);
610
- return asyncSync(() => injectCurrentTraceContext(req));
611
- }
612
- function logHttpRequest(req, options) {
613
- const level = options.logs === false ? false : options.logs.requestLevel ?? false;
614
- if (!level) return asyncSucceed(void 0);
615
- return logEffect(level, "http.client.request", requestLogFields(req, options));
616
- }
617
- function logHttpResponse(req, res, finish, options) {
618
- const configured = options.logs === false ? false : options.logs.responseLevel ?? false;
619
- const level = configured || (finish.outcome === "error" ? options.logs !== false ? options.logs.errorLevel ?? "warn" : false : false);
620
- if (!level) return asyncSucceed(void 0);
621
- return logEffect(level, "http.client.response", {
622
- ...requestLogFields(req, options),
623
- status: res.status,
624
- statusText: res.statusText,
625
- outcome: finish.outcome,
626
- durationMs: finish.durationMs
627
- });
628
- }
629
- function logHttpError(req, error, finish, options) {
630
- const level = options.logs === false ? false : options.logs.errorLevel ?? "error";
631
- if (!level) return asyncSucceed(void 0);
632
- const status = httpErrorStatus(error);
633
- const statusText = httpErrorStatusText(error);
634
- return logEffect(level, "http.client.error", {
635
- ...requestLogFields(req, options),
636
- outcome: finish.outcome,
637
- durationMs: finish.durationMs,
638
- ...status !== void 0 ? { status } : {},
639
- ...statusText ? { statusText } : {},
640
- retryable: isRetryableHttpError(error),
641
- errorTag: error._tag,
642
- message: httpErrorMessage(error)
643
- });
644
- }
645
653
  function resolveHttpObservabilityOptions(options) {
646
654
  const maybeObservability = isObservabilityInstance(options) ? options : void 0;
647
655
  const raw = maybeObservability ? { metrics: maybeObservability.metrics } : options;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeBoundedRingBuffer
3
- } from "./chunk-H626ZTDZ.mjs";
3
+ } from "./chunk-MUMBUXU6.mjs";
4
4
  import {
5
5
  Cause
6
6
  } from "./chunk-36I3M4UC.mjs";
@@ -3,7 +3,7 @@ import {
3
3
  liveClock,
4
4
  runtimeClockFromEnv,
5
5
  unsafeGetCurrentRuntime
6
- } from "./chunk-H626ZTDZ.mjs";
6
+ } from "./chunk-MUMBUXU6.mjs";
7
7
  import {
8
8
  Async,
9
9
  Cause,
@@ -237,7 +237,14 @@ function arraySchema(item) {
237
237
  function objectSchema(shape, options = {}) {
238
238
  const unknownKeys = _nullishCoalesce(options.unknownKeys, () => ( "strip"));
239
239
  const shapeEntries = Object.entries(shape);
240
- const knownKeys = unknownKeys === "strict" ? new Set(shapeEntries.map(([key]) => key)) : void 0;
240
+ const fieldKeys = new Array(shapeEntries.length);
241
+ const fieldSchemas = new Array(shapeEntries.length);
242
+ for (let i = 0; i < shapeEntries.length; i++) {
243
+ fieldKeys[i] = shapeEntries[i][0];
244
+ fieldSchemas[i] = shapeEntries[i][1];
245
+ }
246
+ const fieldCount = fieldKeys.length;
247
+ const knownKeys = unknownKeys === "strict" ? new Set(fieldKeys) : void 0;
241
248
  return makeSchema("object", false, (input, path) => {
242
249
  if (typeof input !== "object" || input === null || Array.isArray(input)) {
243
250
  return fail([makeSchemaIssue(path, _nullishCoalesce(options.name, () => ( "object")), input)]);
@@ -246,11 +253,13 @@ function objectSchema(shape, options = {}) {
246
253
  const out = unknownKeys === "passthrough" ? { ...source } : {};
247
254
  const childPath = path.length === 0 ? [] : [...path];
248
255
  let issues;
249
- for (const [key, fieldSchema] of shapeEntries) {
256
+ for (let i = 0; i < fieldCount; i++) {
257
+ const key = fieldKeys[i];
258
+ const fieldSchema = fieldSchemas[i];
250
259
  childPath.push(key);
251
260
  if (!(key in source)) {
252
261
  if (!fieldSchema.isOptional) {
253
- issues ??= [];
262
+ if (!issues) issues = [];
254
263
  issues.push(makeSchemaIssue(childPath, _nullishCoalesce(fieldSchema.name, () => ( fieldSchema.kind)), void 0, "Required field is missing"));
255
264
  }
256
265
  childPath.pop();
@@ -261,15 +270,18 @@ function objectSchema(shape, options = {}) {
261
270
  if (result.success) {
262
271
  out[key] = result.data;
263
272
  } else {
264
- issues ??= [];
265
- issues.push(...result.issues);
273
+ if (!issues) issues = [];
274
+ const resultIssues = result.issues;
275
+ for (let j = 0; j < resultIssues.length; j++) {
276
+ issues.push(resultIssues[j]);
277
+ }
266
278
  }
267
279
  }
268
280
  if (knownKeys) {
269
281
  for (const key of Object.keys(source)) {
270
282
  if (!knownKeys.has(key)) {
271
283
  childPath.push(key);
272
- issues ??= [];
284
+ if (!issues) issues = [];
273
285
  issues.push(makeSchemaIssue(childPath, "known key", source[key], "Unknown key is not allowed"));
274
286
  childPath.pop();
275
287
  }
@@ -4,7 +4,7 @@ var _chunkSA6HUJVIcjs = require('./chunk-SA6HUJVI.cjs');
4
4
 
5
5
 
6
6
 
7
- var _chunk2JHJ4YHScjs = require('./chunk-2JHJ4YHS.cjs');
7
+ var _chunkZDZNV6NAcjs = require('./chunk-ZDZNV6NA.cjs');
8
8
 
9
9
 
10
10
 
@@ -1914,7 +1914,7 @@ var runLoop = (state, scope, runStartedAt) => {
1914
1914
  })
1915
1915
  );
1916
1916
  };
1917
- var runAgent = (runtime, goal) => _chunk2JHJ4YHScjs.withScopeAsync.call(void 0,
1917
+ var runAgent = (runtime, goal) => _chunkZDZNV6NAcjs.withScopeAsync.call(void 0,
1918
1918
  runtime,
1919
1919
  (scope) => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
1920
1920
  nowMillis(),
@@ -2219,14 +2219,14 @@ var parseRipgrep = (stdout) => stdout.split("\n").filter(Boolean).map((line) =>
2219
2219
  return { path, line: Number(lineNo), text: rest.join(":") };
2220
2220
  });
2221
2221
  var makeNodeFileSystem = (shell) => ({
2222
- readFile: (path) => _chunk2JHJ4YHScjs.fromPromiseAbortable.call(void 0,
2222
+ readFile: (path) => _chunkZDZNV6NAcjs.fromPromiseAbortable.call(void 0,
2223
2223
  async (signal) => {
2224
2224
  const { readFile } = await dynamicImport2("node:fs/promises");
2225
2225
  return readFile(path, { encoding: "utf8", signal });
2226
2226
  },
2227
2227
  (cause) => ({ _tag: "FsError", operation: "readFile", cause })
2228
2228
  ),
2229
- exists: (path) => _chunk2JHJ4YHScjs.fromPromiseAbortable.call(void 0,
2229
+ exists: (path) => _chunkZDZNV6NAcjs.fromPromiseAbortable.call(void 0,
2230
2230
  async (signal) => {
2231
2231
  if (signal.aborted) return false;
2232
2232
  const { stat } = await dynamicImport2("node:fs/promises");
@@ -2607,7 +2607,7 @@ var loadNodeAgentConfig = async (options) => {
2607
2607
  // src/agent/llm/openAICompatible.ts
2608
2608
  var extractText = (json) => _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([json, 'optionalAccess', _150 => _150.choices, 'optionalAccess', _151 => _151[0], 'optionalAccess', _152 => _152.message, 'optionalAccess', _153 => _153.content]), () => ( _optionalChain([json, 'optionalAccess', _154 => _154.output_text]))), () => ( _optionalChain([json, 'optionalAccess', _155 => _155.content, 'optionalAccess', _156 => _156[0], 'optionalAccess', _157 => _157.text]))), () => ( JSON.stringify(json)));
2609
2609
  var makeOpenAICompatibleLLM = (config) => ({
2610
- complete: (request) => _chunk2JHJ4YHScjs.fromPromiseAbortable.call(void 0,
2610
+ complete: (request) => _chunkZDZNV6NAcjs.fromPromiseAbortable.call(void 0,
2611
2611
  async (signal) => {
2612
2612
  const res = await fetch(config.endpoint, {
2613
2613
  method: "POST",
@@ -2699,7 +2699,7 @@ var responseErrorMessage = async (res) => {
2699
2699
  }
2700
2700
  };
2701
2701
  var makeGoogleGenerativeAILLM = (config) => ({
2702
- complete: (request) => _chunk2JHJ4YHScjs.fromPromiseAbortable.call(void 0,
2702
+ complete: (request) => _chunkZDZNV6NAcjs.fromPromiseAbortable.call(void 0,
2703
2703
  async (signal) => {
2704
2704
  const res = await fetch(makeGenerateContentEndpoint(config), {
2705
2705
  method: "POST",