brass-runtime 1.16.0 → 1.16.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.
- package/CHANGELOG.md +17 -0
- package/README.md +283 -18
- package/dist/agent/cli/main.cjs +38 -38
- package/dist/agent/cli/main.js +6 -6
- package/dist/agent/cli/main.mjs +6 -6
- package/dist/agent/index.cjs +7 -7
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +6 -6
- package/dist/agent/index.mjs +6 -6
- package/dist/chunk-2HQTDLHF.mjs +683 -0
- package/dist/chunk-36I3M4UC.mjs +370 -0
- package/dist/{chunk-QY5FKYEQ.js → chunk-3AYM6WPJ.js} +570 -51
- package/dist/chunk-3LOYJFRR.cjs +300 -0
- package/dist/chunk-3Y2RIUMM.js +300 -0
- package/dist/{chunk-N6VHMOWB.cjs → chunk-4ROBZFL6.cjs} +128 -128
- package/dist/{chunk-NC5SDRYE.js → chunk-52OB2ROS.js} +4 -4
- package/dist/{chunk-JX3LZQJH.cjs → chunk-52PPNNI4.cjs} +82 -20
- package/dist/{chunk-5YOQOXEQ.cjs → chunk-5EC274J5.cjs} +676 -293
- package/dist/chunk-5QC7LRZ3.js +229 -0
- package/dist/{chunk-7TL2LHQJ.js → chunk-5VRJNBLZ.mjs} +524 -141
- package/dist/chunk-62AZW6UT.cjs +313 -0
- package/dist/chunk-6IXXWIUM.js +683 -0
- package/dist/chunk-74ZTY6CP.js +2871 -0
- package/dist/chunk-76YMRMH2.cjs +777 -0
- package/dist/chunk-7CMJS3QE.mjs +2871 -0
- package/dist/{chunk-2WC63LJK.mjs → chunk-7JIJOVCT.js} +20 -10
- package/dist/{chunk-FM4W4QPL.js → chunk-A2OM6NEH.mjs} +5 -4
- package/dist/chunk-AGR5B2BC.cjs +683 -0
- package/dist/chunk-AVNQLJ5V.js +777 -0
- package/dist/chunk-B33ICAKP.js +313 -0
- package/dist/{chunk-J3H54ZRV.mjs → chunk-B5JD23U7.mjs} +1 -1
- package/dist/chunk-BABBZK4Y.js +2024 -0
- package/dist/{chunk-U5KWK3PX.mjs → chunk-C3MDXTRZ.js} +11 -0
- package/dist/{chunk-F5EUMJL7.mjs → chunk-CIZFIMK5.js} +55 -5
- package/dist/{chunk-SPUEME2B.cjs → chunk-CZIVE6NT.cjs} +12 -1
- package/dist/{chunk-TDVMADDN.js → chunk-DNFJLJMW.mjs} +11 -0
- package/dist/chunk-DNFO2EIZ.mjs +777 -0
- package/dist/{chunk-XDZOO4L5.js → chunk-EJ6BPYVR.mjs} +79 -17
- package/dist/{chunk-JNFRRJYH.cjs → chunk-ENKODRU3.cjs} +242 -192
- package/dist/chunk-EOC4UHBS.mjs +229 -0
- package/dist/{chunk-7LVI2GIN.js → chunk-FH2X7BVP.js} +507 -72
- package/dist/{chunk-OOGJ73B6.js → chunk-FHQGHPMO.mjs} +20 -10
- package/dist/{chunk-WQ5QNU5R.cjs → chunk-GLE2WY7Z.cjs} +652 -217
- package/dist/{chunk-G6IQOE4P.mjs → chunk-GYM3LLGS.mjs} +507 -72
- package/dist/chunk-HLWLMW2F.mjs +2024 -0
- package/dist/{chunk-TVN5I4U6.cjs → chunk-JF5WGYJJ.cjs} +25 -24
- package/dist/{chunk-CY33PGEX.mjs → chunk-KH4SYAOS.mjs} +570 -51
- package/dist/chunk-KN32XNTH.mjs +313 -0
- package/dist/chunk-KQLYONSE.cjs +2871 -0
- package/dist/{chunk-7HUOJA4W.cjs → chunk-KZJQ723N.cjs} +90 -80
- package/dist/{chunk-CCKHV5BT.mjs → chunk-L2SYFEBS.js} +5 -4
- package/dist/{chunk-IJT6RRQ5.cjs → chunk-L6VB5N7Q.cjs} +20 -9
- package/dist/{chunk-ZGLD4TVZ.mjs → chunk-MBEJI5HF.mjs} +4 -4
- package/dist/{chunk-PRWCB3QL.mjs → chunk-MIIYDLGM.js} +524 -141
- package/dist/{chunk-H55LI6WY.js → chunk-MOO4L7F4.mjs} +15 -4
- package/dist/{chunk-7XOPAB5Q.js → chunk-MT3OWDPC.mjs} +55 -5
- package/dist/chunk-MVGUEJ5Z.cjs +370 -0
- package/dist/chunk-PD4EJTQC.cjs +229 -0
- package/dist/chunk-PWC3RBQE.mjs +300 -0
- package/dist/{chunk-MWXMNYJS.cjs → chunk-Q2I37RP3.cjs} +643 -124
- package/dist/{chunk-VFIUZG7J.mjs → chunk-RKGKFN2A.js} +79 -17
- package/dist/{chunk-NYL4D7SK.cjs → chunk-SA6HUJVI.cjs} +5 -5
- package/dist/{chunk-K2T3DV26.mjs → chunk-TRM4JUZQ.js} +15 -4
- package/dist/chunk-UB4B6OFY.js +370 -0
- package/dist/{chunk-G3XGCZDQ.js → chunk-UCUBNWM2.js} +1 -1
- package/dist/chunk-VN44DYYT.cjs +2024 -0
- package/dist/{client-CtFmoDvM.d.ts → client-CZHU674n.d.ts} +211 -36
- package/dist/core/index.cjs +135 -9
- package/dist/core/index.d.ts +238 -33
- package/dist/core/index.js +155 -29
- package/dist/core/index.mjs +155 -29
- package/dist/{effect-CGNl5Rqp.d.ts → effect-DIUHZ9IN.d.ts} +89 -1
- package/dist/effectRunner-CFLC32IK.cjs +8 -0
- package/dist/{effectRunner-A4CHJXJI.js → effectRunner-L4S7IPT3.js} +2 -2
- package/dist/{effectRunner-OPUF6QRN.mjs → effectRunner-NNGG75QA.mjs} +2 -2
- package/dist/http/index.cjs +324 -2986
- package/dist/http/index.d.ts +54 -68
- package/dist/http/index.js +238 -2900
- package/dist/http/index.mjs +238 -2900
- package/dist/http/testing.cjs +14 -12
- package/dist/http/testing.d.ts +5 -4
- package/dist/http/testing.js +10 -8
- package/dist/http/testing.mjs +10 -8
- package/dist/index.cjs +423 -255
- package/dist/index.d.ts +87 -69
- package/dist/index.js +301 -133
- package/dist/index.mjs +301 -133
- package/dist/observability/index.cjs +16 -531
- package/dist/observability/index.d.ts +81 -8
- package/dist/observability/index.js +23 -538
- package/dist/observability/index.mjs +23 -538
- package/dist/perf/cli.cjs +401 -0
- package/dist/perf/cli.d.ts +1 -0
- package/dist/perf/cli.js +401 -0
- package/dist/perf/cli.mjs +401 -0
- package/dist/perf/index.cjs +141 -0
- package/dist/perf/index.d.ts +483 -0
- package/dist/perf/index.js +141 -0
- package/dist/perf/index.mjs +141 -0
- package/dist/schedule-CK3Ml_7p.d.ts +259 -0
- package/dist/schema/index.cjs +6 -2
- package/dist/schema/index.d.ts +3 -1
- package/dist/schema/index.js +5 -1
- package/dist/schema/index.mjs +5 -1
- package/dist/{server-C8hDXA74.d.ts → server-GJPg8ZSG.d.ts} +4 -3
- package/dist/{stream-dvSs0QS5.d.ts → stream-B4oK9JFP.d.ts} +1 -1
- package/dist/{tracer-B5tRH9H7.d.ts → tracer-Hwt1cl7h.d.ts} +13 -54
- package/dist/{tracing-Dt9S_6V8.d.ts → tracing-DqbTKGcf.d.ts} +1 -1
- package/docs/ARCHITECTURE.md +292 -0
- package/docs/README.md +63 -0
- package/docs/adr/0001-ai-context-pack.md +32 -0
- package/docs/agent-apply-mode.md +104 -0
- package/docs/agent-approvals.md +110 -0
- package/docs/agent-batch.md +185 -0
- package/docs/agent-boundaries.md +112 -0
- package/docs/agent-chat-sessions.md +160 -0
- package/docs/agent-ci.md +17 -0
- package/docs/agent-cli.md +405 -0
- package/docs/agent-config.md +480 -0
- package/docs/agent-context-discovery.md +159 -0
- package/docs/agent-copilot-like-dx.md +126 -0
- package/docs/agent-declarative-optimized-planning.md +138 -0
- package/docs/agent-dx.md +224 -0
- package/docs/agent-env-files.md +126 -0
- package/docs/agent-follow-up-context.md +43 -0
- package/docs/agent-global-usage.md +180 -0
- package/docs/agent-init.md +109 -0
- package/docs/agent-install-and-configure.md +516 -0
- package/docs/agent-language-workspace-ux.md +99 -0
- package/docs/agent-llm-adapters.md +123 -0
- package/docs/agent-local-install.md +190 -0
- package/docs/agent-local-tests.md +51 -0
- package/docs/agent-observability.md +155 -0
- package/docs/agent-patch-quality-loop.md +162 -0
- package/docs/agent-presets.md +22 -0
- package/docs/agent-project-commands.md +237 -0
- package/docs/agent-project-intelligence.md +156 -0
- package/docs/agent-redaction.md +18 -0
- package/docs/agent-release-readiness.md +76 -0
- package/docs/agent-rollback-safety.md +162 -0
- package/docs/agent-rollback.md +23 -0
- package/docs/agent-run-artifacts.md +16 -0
- package/docs/agent-vscode-auto-discovery.md +137 -0
- package/docs/agent-vscode-batch-runner.md +100 -0
- package/docs/agent-vscode-chat-layout.md +90 -0
- package/docs/agent-vscode-clean-install.md +147 -0
- package/docs/agent-vscode-code-actions.md +70 -0
- package/docs/agent-vscode-diff-preview.md +45 -0
- package/docs/agent-vscode-inline-assist.md +56 -0
- package/docs/agent-vscode-install.md +186 -0
- package/docs/agent-vscode-model-setup.md +97 -0
- package/docs/agent-vscode-patch-preview.md +92 -0
- package/docs/agent-vscode-problems.md +79 -0
- package/docs/agent-vscode-project-dashboard.md +106 -0
- package/docs/agent-vscode-run-history.md +92 -0
- package/docs/agent-vscode-ux.md +73 -0
- package/docs/ai/INVARIANTS.md +84 -0
- package/docs/ai/PROJECT_MAP.md +338 -0
- package/docs/ai/PUBLIC_API.md +336 -0
- package/docs/ai/VALIDATION_MATRIX.md +67 -0
- package/docs/api-polish.md +37 -0
- package/docs/cancellation.md +162 -0
- package/docs/coverage.md +46 -0
- package/docs/getting-started.md +159 -0
- package/docs/guides/README.md +40 -0
- package/docs/guides/circuit-breaker.md +89 -0
- package/docs/guides/error-handling.md +91 -0
- package/docs/guides/getting-started.md +107 -0
- package/docs/guides/layers.md +189 -0
- package/docs/guides/metrics.md +101 -0
- package/docs/guides/resource-management.md +141 -0
- package/docs/guides/retry.md +215 -0
- package/docs/guides/semaphore.md +66 -0
- package/docs/guides/streams.md +117 -0
- package/docs/guides/supervisors.md +98 -0
- package/docs/guides/testing.md +162 -0
- package/docs/guides/tracing.md +71 -0
- package/docs/http-recipes.md +399 -0
- package/docs/http.md +749 -0
- package/docs/modules.md +285 -0
- package/docs/observability-collector-smoke.md +31 -0
- package/docs/observability-framework-examples.md +98 -0
- package/docs/observability.md +542 -0
- package/docs/otel-collector-smoke.yaml +27 -0
- package/docs/performance-profiler.md +199 -0
- package/docs/production-readiness.md +73 -0
- package/docs/recipes/README.md +12 -0
- package/docs/recipes/http-server.md +45 -0
- package/docs/recipes/layers.md +44 -0
- package/docs/recipes/performance.md +47 -0
- package/docs/recipes/runtime.md +41 -0
- package/docs/recipes/testing.md +41 -0
- package/docs/release.md +53 -0
- package/docs/wasm-bounded-queues.md +44 -0
- package/docs/wasm-engine-observability-benchmarks.md +85 -0
- package/docs/wasm-fiber-engine.md +117 -0
- package/docs/wasm-scheduler-state-machine.md +122 -0
- package/docs/wasm-stream-chunks.md +54 -0
- package/package.json +22 -2
- package/dist/chunk-45F7OKGT.cjs +0 -104
- package/dist/chunk-7V4KY4RL.mjs +0 -104
- package/dist/chunk-DJQ7OMMB.cjs +0 -144
- package/dist/chunk-GOV47PPB.mjs +0 -552
- package/dist/chunk-JF4XXPZ5.cjs +0 -552
- package/dist/chunk-KCPT2D6G.js +0 -552
- package/dist/chunk-NOYZIMUJ.mjs +0 -144
- package/dist/chunk-PNVFW245.js +0 -144
- package/dist/chunk-ROJC3NBJ.js +0 -104
- package/dist/effectRunner-3ZHAD3LE.cjs +0 -8
- package/dist/schedule-Fque9Abz.d.ts +0 -70
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.14.0 - First Public Release Candidate
|
|
4
|
+
|
|
5
|
+
- Added mature core runtime features: structured concurrency, `Cause`,
|
|
6
|
+
interruptibility, `FiberRef`, Layer 2.0, Schedule 2.0, TestRuntime, streams,
|
|
7
|
+
and runtime observability.
|
|
8
|
+
- Added HTTP client/server surface with schema validation, lifecycle
|
|
9
|
+
middleware, adaptive limiter, retry, compression, health/readiness, and
|
|
10
|
+
observability hooks.
|
|
11
|
+
- Added `brass-runtime/perf` with runtime A/B, soak profiling, HTTP memory lab,
|
|
12
|
+
benchmark budgets, and local perf history/baseline storage.
|
|
13
|
+
- Added DX helpers: `runPromise`, `runExit`, `makeRuntime`, `defineService`,
|
|
14
|
+
`getService`, `provide`, `formatLayerError`, `formatConfigError`, and
|
|
15
|
+
`HttpServer`.
|
|
16
|
+
- Added first-release recipes under `docs/recipes/` and release validation via
|
|
17
|
+
`npm run release:check`.
|
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# brass-runtime
|
|
2
2
|
|
|
3
|
-
A ZIO-inspired effect runtime for TypeScript with structured concurrency,
|
|
3
|
+
A ZIO-inspired effect runtime for TypeScript with structured concurrency,
|
|
4
|
+
runtime diagnostics, pull-based streams, and a production-grade HTTP client.
|
|
4
5
|
|
|
5
6
|
Built without `Promise`/`async`/`await` as the primary semantic primitive. Effects are values — lazy, composable, and cancelable by default.
|
|
6
7
|
|
|
@@ -12,19 +13,27 @@ npm i brass-runtime
|
|
|
12
13
|
|
|
13
14
|
## What it does
|
|
14
15
|
|
|
15
|
-
**
|
|
16
|
+
**Runtime** — algebraic effects, fibers, scopes, scheduler, interruptibility
|
|
17
|
+
regions, fiber-local refs, typed layers, semaphores, circuit breakers, rich
|
|
18
|
+
`Cause<E>` failures, metrics, tracing, and an opt-in flight recorder.
|
|
16
19
|
|
|
17
|
-
**Streams** — pull-based with backpressure, bounded buffers,
|
|
20
|
+
**Streams** — pull-based streams with backpressure, bounded buffers, hubs,
|
|
21
|
+
pipelines, fusion optimization, and a small fluent DX facade.
|
|
18
22
|
|
|
19
|
-
**HTTP
|
|
23
|
+
**HTTP** — lazy/cancelable client and server primitives with typed routing,
|
|
24
|
+
schema validation, health/readiness probes, adaptive concurrency, compression,
|
|
25
|
+
batching, prewarm, cache, dedup, priority, retry, and observability.
|
|
20
26
|
|
|
21
|
-
**
|
|
27
|
+
**Production signals** — dependency-free schemas, Prometheus/OTLP exporters,
|
|
28
|
+
structured logs, W3C trace propagation, sampling, redaction, bounded exporters,
|
|
29
|
+
and explicit flush/shutdown.
|
|
22
30
|
|
|
23
|
-
**
|
|
31
|
+
**Performance profiler** — runtime primitives, HTTP layer comparison, memory
|
|
32
|
+
retention reports, observability overhead, CLI/JSON output, and actionable
|
|
33
|
+
recommendations.
|
|
24
34
|
|
|
25
|
-
**
|
|
26
|
-
|
|
27
|
-
**Brass Agent** — experimental CLI coding agent with workspace inspection, LLM integration, and VS Code extension.
|
|
35
|
+
**Optional engine and tools** — Rust/WASM-backed state machines plus the
|
|
36
|
+
experimental Brass Agent CLI/VS Code workflow.
|
|
28
37
|
|
|
29
38
|
---
|
|
30
39
|
|
|
@@ -43,12 +52,86 @@ npm i brass-runtime
|
|
|
43
52
|
### Run an effect
|
|
44
53
|
|
|
45
54
|
```ts
|
|
46
|
-
import {
|
|
55
|
+
import { runPromise, succeed } from "brass-runtime";
|
|
56
|
+
|
|
57
|
+
const value = await runPromise(succeed(42));
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use `makeRuntime` when you want explicit runtime options, and `runExit` when
|
|
61
|
+
you want the full `Exit`/`Cause` instead of a rejected promise.
|
|
62
|
+
|
|
63
|
+
### Inspect failure causes
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { Cause, formatCause } from "brass-runtime";
|
|
67
|
+
|
|
68
|
+
const cause = Cause.then(
|
|
69
|
+
Cause.fail("database unavailable"),
|
|
70
|
+
Cause.both(Cause.interrupt(), Cause.die(new Error("release failed"))),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
console.log(formatCause(cause));
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`Cause<E>` preserves typed failures, defects, interruptions, and sequential or
|
|
77
|
+
parallel composition (`Then` / `Both`) so diagnostics can explain what happened
|
|
78
|
+
without flattening every failure into a single thrown value.
|
|
79
|
+
|
|
80
|
+
### Mask interruption
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { async, flatMap, succeed, uninterruptibleMask } from "brass-runtime";
|
|
84
|
+
|
|
85
|
+
const effect = uninterruptibleMask((restore) =>
|
|
86
|
+
flatMap(succeed("acquired"), (resource) =>
|
|
87
|
+
restore(async((_env, cb) => {
|
|
88
|
+
setTimeout(() => cb({ _tag: "Success", value: `used:${resource}` }), 10);
|
|
89
|
+
})),
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Use `uninterruptible(effect)` for critical regions and
|
|
95
|
+
`uninterruptibleMask((restore) => ...)` when only part of the region should be
|
|
96
|
+
interruptible again. Pending interruption is deferred until the protected region
|
|
97
|
+
exits; restored sub-effects remain cancelable.
|
|
98
|
+
|
|
99
|
+
### Fiber-local context
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { Runtime, makeFiberRef } from "brass-runtime";
|
|
47
103
|
|
|
104
|
+
const requestId = makeFiberRef("anonymous");
|
|
48
105
|
const runtime = Runtime.make({});
|
|
49
|
-
|
|
106
|
+
|
|
107
|
+
const result = await runtime.toPromise(
|
|
108
|
+
requestId.locally("req-123", requestId.get()),
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`FiberRef` values are local to the running fiber, inherited by child fibers at
|
|
113
|
+
fork time, isolated from child mutations, and restored after `locally` regions
|
|
114
|
+
even when the region fails or is interrupted.
|
|
115
|
+
|
|
116
|
+
### Explain runtime behavior
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { Runtime, async, makeRuntimeRecorder } from "brass-runtime";
|
|
120
|
+
|
|
121
|
+
const recorder = makeRuntimeRecorder({ maxEvents: 5000 });
|
|
122
|
+
const runtime = new Runtime({ env: {}, hooks: recorder.hooks });
|
|
123
|
+
|
|
124
|
+
await runtime.toPromise(async((_env, cb) => {
|
|
125
|
+
setTimeout(() => cb({ _tag: "Success", value: "ok" }), 10);
|
|
126
|
+
}));
|
|
127
|
+
|
|
128
|
+
console.log(recorder.explain());
|
|
50
129
|
```
|
|
51
130
|
|
|
131
|
+
The flight recorder is opt-in and keeps a bounded ring buffer of runtime events:
|
|
132
|
+
fiber start/end/suspend/resume, scopes, supervisor events, logs, spans, and
|
|
133
|
+
trace context when available.
|
|
134
|
+
|
|
52
135
|
### Recommended HTTP client
|
|
53
136
|
|
|
54
137
|
```ts
|
|
@@ -75,8 +158,10 @@ console.log(http.compression?.stats());
|
|
|
75
158
|
`makeDefaultHttpClient` is the batteries-included entrypoint: timeout,
|
|
76
159
|
deduplication, priority scheduling, retry, adaptive concurrency, safe-method
|
|
77
160
|
response cache, decompression, stats, `cancelAll`, and JSON/text helpers. Use
|
|
161
|
+
`preset: "production"` when you want that production-ready shape explicitly,
|
|
78
162
|
`preset: "balanced"` to skip the default cache, or `preset: "minimal"` for a
|
|
79
|
-
cheap wire client with the same helper API.
|
|
163
|
+
cheap wire client with the same helper API. `preset: "default"` remains the
|
|
164
|
+
same full preset for compatibility.
|
|
80
165
|
|
|
81
166
|
The HTTP stack is meant to replace the usual `fetch` wrapper plus Zod/Valibot
|
|
82
167
|
glue: schemas are dependency-free, responses and request bodies are validated in
|
|
@@ -84,6 +169,70 @@ the same effect, config validation fails at construction time, and the client
|
|
|
84
169
|
still owns cancellation, retries, compression, observability, and adaptive
|
|
85
170
|
limits as one pipeline.
|
|
86
171
|
|
|
172
|
+
Custom Promise clients such as Axios can be injected without making the
|
|
173
|
+
consumer manage `AbortSignal` or `Async` plumbing:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import {
|
|
177
|
+
defineHttpPolicyPresets,
|
|
178
|
+
formatHttpError,
|
|
179
|
+
isRetryableHttpError,
|
|
180
|
+
makeDefaultHttpClient,
|
|
181
|
+
promiseHttpTransport,
|
|
182
|
+
} from "brass-runtime/http";
|
|
183
|
+
|
|
184
|
+
const transport = promiseHttpTransport()
|
|
185
|
+
.requestConfig(({ request, url }) => ({
|
|
186
|
+
url: url.toString(),
|
|
187
|
+
method: request.method,
|
|
188
|
+
headers: request.headers,
|
|
189
|
+
data: request.body,
|
|
190
|
+
responseType: "json",
|
|
191
|
+
}))
|
|
192
|
+
.send((config) => axiosInstance.request(config))
|
|
193
|
+
.json();
|
|
194
|
+
|
|
195
|
+
const axiosHttp = makeDefaultHttpClient({
|
|
196
|
+
baseUrl: "https://api.example.com",
|
|
197
|
+
transport,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
await axiosHttp.getJson("/users/1").unsafeRunPromise();
|
|
202
|
+
} catch (error) {
|
|
203
|
+
if (isRetryableHttpError(error)) {
|
|
204
|
+
console.warn("transient upstream failure");
|
|
205
|
+
}
|
|
206
|
+
console.error(formatHttpError(error));
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Brass injects the runtime `AbortSignal` into object configs before `send` and
|
|
211
|
+
normalizes external failures with `toHttpError`, including Axios-like
|
|
212
|
+
`response.status`, aborts, and common timeout codes.
|
|
213
|
+
|
|
214
|
+
Repeated execution intent can be named once with policy presets:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
const policies = defineHttpPolicyPresets({
|
|
218
|
+
readModel: {
|
|
219
|
+
lane: "read-model",
|
|
220
|
+
poolKey: "users-api",
|
|
221
|
+
priority: 2,
|
|
222
|
+
retry: { maxRetries: 2, baseDelayMs: 50 },
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const http = makeDefaultHttpClient({
|
|
227
|
+
baseUrl: "https://api.example.com",
|
|
228
|
+
policyPresets: policies,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
await http.getJson("/users/1", {
|
|
232
|
+
policy: { preset: "readModel", dedupKey: "users:1" },
|
|
233
|
+
}).unsafeRunPromise();
|
|
234
|
+
```
|
|
235
|
+
|
|
87
236
|
The default adaptive limiter uses the `aggressive` preset: warmup sample floor,
|
|
88
237
|
P5 baseline, error-rate signal, priority-aware queueing, jittered probes,
|
|
89
238
|
proportional headroom, capped decreases, and TTL-evicted per-key state.
|
|
@@ -122,6 +271,45 @@ The same validation machinery checks runtime, HTTP, and observability configs
|
|
|
122
271
|
at construction time, so invalid values fail with field paths like
|
|
123
272
|
`$.otlp.pipeline.batchSize` instead of surfacing later as ambiguous behavior.
|
|
124
273
|
|
|
274
|
+
### HTTP server
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { asyncSucceed, asyncSync, runPromise, useResource } from "brass-runtime";
|
|
278
|
+
import { HttpServer, s } from "brass-runtime/http";
|
|
279
|
+
|
|
280
|
+
const User = s.object({
|
|
281
|
+
id: s.nonEmptyString(),
|
|
282
|
+
name: s.nonEmptyString(),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const router = HttpServer.router([
|
|
286
|
+
HttpServer.route("GET", "/users/:id", {
|
|
287
|
+
params: s.object({ id: s.nonEmptyString() }),
|
|
288
|
+
response: User,
|
|
289
|
+
}, (ctx) =>
|
|
290
|
+
asyncSucceed(HttpServer.json({
|
|
291
|
+
id: ctx.params.id,
|
|
292
|
+
name: "Ada",
|
|
293
|
+
})),
|
|
294
|
+
),
|
|
295
|
+
HttpServer.healthRoute(),
|
|
296
|
+
HttpServer.readinessRoute(),
|
|
297
|
+
]);
|
|
298
|
+
|
|
299
|
+
await runPromise(
|
|
300
|
+
useResource(
|
|
301
|
+
router.listen({ port: 3000 }),
|
|
302
|
+
(server) => asyncSync(() => {
|
|
303
|
+
console.log(server.url());
|
|
304
|
+
}),
|
|
305
|
+
),
|
|
306
|
+
);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Routes infer `:params` from the path, optional schemas validate
|
|
310
|
+
params/query/body/response, middleware is effect-based, and the Node listener is
|
|
311
|
+
available as a managed resource for graceful shutdown.
|
|
312
|
+
|
|
125
313
|
### Discoverable HTTP builder
|
|
126
314
|
|
|
127
315
|
```ts
|
|
@@ -131,7 +319,7 @@ declare const token: string;
|
|
|
131
319
|
|
|
132
320
|
const http = httpClientBuilder()
|
|
133
321
|
.baseUrl("https://api.example.com")
|
|
134
|
-
.
|
|
322
|
+
.production()
|
|
135
323
|
.balancedLimiter({ maxLimit: 128 })
|
|
136
324
|
.header("authorization", `Bearer ${token}`)
|
|
137
325
|
.cache({ ttlSeconds: 30, maxEntries: 512 })
|
|
@@ -270,6 +458,62 @@ HTTP client observability automatically reads adaptive limiter diagnostics when
|
|
|
270
458
|
the wrapped client owns a limiter, exposing gauges for current limit, queue
|
|
271
459
|
depth, utilization, error rate, request/completion rate, rejection rate, and
|
|
272
460
|
state count.
|
|
461
|
+
It also reads `req.policy` automatically: logs and span attributes include
|
|
462
|
+
`preset`, `lane`, `poolKey`, `dedupKey`, `priority`, and retry overrides when present.
|
|
463
|
+
Metric labels stay conservative by default; opt into stable labels with
|
|
464
|
+
`withHttpObservability({ policy: { labelKeys: ["preset", "lane", "poolKey"] } })`.
|
|
465
|
+
|
|
466
|
+
### Performance profiler
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
npm run perf
|
|
470
|
+
npm run perf:json
|
|
471
|
+
npm run benchmark:perf
|
|
472
|
+
npm run perf:runtime:ab
|
|
473
|
+
npm run perf:runtime:soak
|
|
474
|
+
npm run perf:runtime:budget
|
|
475
|
+
npm run perf:http:memory
|
|
476
|
+
npm run perf:history
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
```ts
|
|
480
|
+
import { runBrassPerformanceProfile } from "brass-runtime/perf";
|
|
481
|
+
|
|
482
|
+
const report = await runBrassPerformanceProfile({
|
|
483
|
+
http: {
|
|
484
|
+
calls: 20_000,
|
|
485
|
+
concurrency: 512,
|
|
486
|
+
delayMs: 2,
|
|
487
|
+
forceGc: true,
|
|
488
|
+
variants: ["default-json", "default-json-observed"],
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
console.log(report.recommendations);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
The profiler compares runtime primitives, runtime A/B variants, runtime-only
|
|
496
|
+
soak behavior, `node:http`, Brass wire/default HTTP clients, HTTP long-run
|
|
497
|
+
memory, observability overhead, history/baseline regressions, and memory deltas. Use
|
|
498
|
+
[`docs/performance-profiler.md`](docs/performance-profiler.md) for focused
|
|
499
|
+
commands and `node --expose-gc` runs.
|
|
500
|
+
|
|
501
|
+
Perf runs can be persisted and compared locally:
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
npm run perf -- --profile runtime-ab --record-history --save-baseline runtime-main
|
|
505
|
+
npm run perf -- --profile runtime-ab --compare-baseline runtime-main --fail-on-baseline-regression
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### First-release recipes
|
|
509
|
+
|
|
510
|
+
Copyable happy paths live in [`docs/recipes`](docs/recipes/README.md):
|
|
511
|
+
|
|
512
|
+
- runtime execution
|
|
513
|
+
- typed layers
|
|
514
|
+
- HTTP server
|
|
515
|
+
- testing
|
|
516
|
+
- performance baselines
|
|
273
517
|
|
|
274
518
|
### Structured concurrency
|
|
275
519
|
|
|
@@ -289,12 +533,13 @@ await runtime.toPromise(
|
|
|
289
533
|
### Streams
|
|
290
534
|
|
|
291
535
|
```ts
|
|
292
|
-
import { Runtime,
|
|
536
|
+
import { Runtime, Stream } from "brass-runtime";
|
|
293
537
|
|
|
294
538
|
const runtime = Runtime.make({});
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
539
|
+
const result = await Stream
|
|
540
|
+
.from([1, 2, 3, 4, 5])
|
|
541
|
+
.map((n) => n * 2)
|
|
542
|
+
.collect(runtime);
|
|
298
543
|
// [2, 4, 6, 8, 10]
|
|
299
544
|
```
|
|
300
545
|
|
|
@@ -310,6 +555,7 @@ const result = await runtime.toPromise(collectStream(doubled));
|
|
|
310
555
|
| `brass-runtime/http/testing` | Dependency-free mock clients, mock fetch, response factories, and effect runner helpers |
|
|
311
556
|
| `brass-runtime/schema` | Dependency-free runtime schema DSL with type inference |
|
|
312
557
|
| `brass-runtime/observability` | Prometheus/OTLP exporters, logs, spans, trace propagation, request adapters |
|
|
558
|
+
| `brass-runtime/perf` | Runtime, HTTP, observability, memory, and baseline performance profiler |
|
|
313
559
|
| `brass-runtime/agent` | Brass Agent core (experimental) |
|
|
314
560
|
|
|
315
561
|
CLI: `brass-agent`
|
|
@@ -346,6 +592,8 @@ All layers emit lifecycle events, track stats, and support cancellation.
|
|
|
346
592
|
The recommended `makeDefaultHttpClient` factory wires the default preset
|
|
347
593
|
for you and accepts extra middleware, so observability can be attached with
|
|
348
594
|
`middleware: [withHttpObservability(obs)]` without coupling HTTP to exporters.
|
|
595
|
+
Per-request `policy` travels through that stack and is visible to observability
|
|
596
|
+
without being forwarded to the host transport.
|
|
349
597
|
|
|
350
598
|
---
|
|
351
599
|
|
|
@@ -388,7 +636,14 @@ Docs: [Install](./docs/agent-install-and-configure.md) · [CLI](./docs/agent-cli
|
|
|
388
636
|
npm test # vitest suite
|
|
389
637
|
npm run test:types # TypeScript type checking
|
|
390
638
|
npm run test:coverage # coverage with baseline gate
|
|
639
|
+
npm run release:check # full release gate: types, tests, build, CJS, perf budgets
|
|
391
640
|
npm run benchmark # runtime, HTTP lifecycle, and 100k local HTTP concurrency
|
|
641
|
+
npm run benchmark:runtime # Runtime Performance Track
|
|
642
|
+
npm run benchmark:runtime:budget # Runtime Performance Track regression budget
|
|
643
|
+
npm run perf:runtime:ab # Runtime A/B Performance Lab
|
|
644
|
+
npm run perf:runtime:soak # Runtime-only soak profile
|
|
645
|
+
npm run perf:runtime:budget # Runtime profiler budget
|
|
646
|
+
npm run perf:http:memory # HTTP long-run memory lab
|
|
392
647
|
npm run benchmark -- http-concurrent # HTTP compare mode variants
|
|
393
648
|
node --expose-gc --import tsx src/benchmarks/runner.ts http-concurrent # HTTP memory/limiter diagnostics
|
|
394
649
|
npm run benchmark:adaptive
|
|
@@ -426,10 +681,16 @@ Property-based tests use `fast-check` with 100+ iterations per property. Each HT
|
|
|
426
681
|
|
|
427
682
|
- [x] Sync effect values via `ZIO<R, E, A>` aliases
|
|
428
683
|
- [x] Algebraic async: `Async<R, E, A>`
|
|
684
|
+
- [x] Rich `Cause<E>` failure trees with pretty printing
|
|
685
|
+
- [x] Interruptibility regions with `uninterruptible` / `uninterruptibleMask`
|
|
686
|
+
- [x] Fiber-local refs with fork inheritance and scoped restoration
|
|
687
|
+
- [x] TS TestRuntime with deterministic scheduler and virtual clock
|
|
688
|
+
- [x] Schedule 2.0 with drivers, runtime-clock budgets, observability, and HTTP integration
|
|
429
689
|
- [x] Cooperative scheduler (observable, testable)
|
|
430
690
|
- [x] Fibers with interruption & finalizers
|
|
431
691
|
- [x] Structured scopes & resource safety
|
|
432
|
-
- [x]
|
|
692
|
+
- [x] Runtime flight recorder for bounded execution traces
|
|
693
|
+
- [x] Layer 2.0 typed contexts, semaphores, circuit breakers
|
|
433
694
|
- [x] Metrics, tracing, runtime hooks
|
|
434
695
|
- [x] Worker pools
|
|
435
696
|
- [x] WASM engine (optional)
|
|
@@ -437,6 +698,7 @@ Property-based tests use `fast-check` with 100+ iterations per property. Each HT
|
|
|
437
698
|
### Streams
|
|
438
699
|
|
|
439
700
|
- [x] Pull-based streams with backpressure
|
|
701
|
+
- [x] Fluent `Stream` / `Pipeline` DX facade
|
|
440
702
|
- [x] Bounded buffers, queues, hubs
|
|
441
703
|
- [x] Pipelines with fusion optimization
|
|
442
704
|
- [x] Stream merge, zip, broadcast
|
|
@@ -445,6 +707,9 @@ Property-based tests use `fast-check` with 100+ iterations per property. Each HT
|
|
|
445
707
|
### HTTP
|
|
446
708
|
|
|
447
709
|
- [x] Lazy, cancelable HTTP client
|
|
710
|
+
- [x] Effect-based Node HTTP server listener with resource lifecycle
|
|
711
|
+
- [x] Declarative typed routing with params/query/body/response schemas
|
|
712
|
+
- [x] Health/readiness routes backed by runtime health reports
|
|
448
713
|
- [x] Schema-validated JSON helpers
|
|
449
714
|
- [x] Discoverable builder API
|
|
450
715
|
- [x] Test helper subpath
|
package/dist/agent/cli/main.cjs
CHANGED
|
@@ -17,18 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
var
|
|
21
|
-
require('../../chunk-
|
|
22
|
-
require('../../chunk-
|
|
20
|
+
var _chunk4ROBZFL6cjs = require('../../chunk-4ROBZFL6.cjs');
|
|
21
|
+
require('../../chunk-SA6HUJVI.cjs');
|
|
22
|
+
require('../../chunk-JF5WGYJJ.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
var
|
|
25
|
+
var _chunkGLE2WY7Zcjs = require('../../chunk-GLE2WY7Z.cjs');
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
var
|
|
31
|
-
require('../../chunk-
|
|
30
|
+
var _chunkMVGUEJ5Zcjs = require('../../chunk-MVGUEJ5Z.cjs');
|
|
31
|
+
require('../../chunk-CZIVE6NT.cjs');
|
|
32
32
|
require('../../chunk-OBGZSXTJ.cjs');
|
|
33
33
|
|
|
34
34
|
// src/agent/cli/approvals.ts
|
|
@@ -45,7 +45,7 @@ var answerToResponse = (answer, request) => {
|
|
|
45
45
|
return { type: "rejected", reason: `Unrecognized approval answer: ${answer}` };
|
|
46
46
|
};
|
|
47
47
|
var makeCliApprovalService = (options = {}) => ({
|
|
48
|
-
request: (request) =>
|
|
48
|
+
request: (request) => _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (_env, cb) => {
|
|
49
49
|
let closed = false;
|
|
50
50
|
let rl;
|
|
51
51
|
dynamicImport("node:readline/promises").then(({ createInterface }) => {
|
|
@@ -57,7 +57,7 @@ var makeCliApprovalService = (options = {}) => ({
|
|
|
57
57
|
_optionalChain([output, 'optionalAccess', _ => _.write, 'optionalCall', _2 => _2(`
|
|
58
58
|
Approval required (${request.risk})
|
|
59
59
|
`)]);
|
|
60
|
-
_optionalChain([output, 'optionalAccess', _3 => _3.write, 'optionalCall', _4 => _4(`Action: ${
|
|
60
|
+
_optionalChain([output, 'optionalAccess', _3 => _3.write, 'optionalCall', _4 => _4(`Action: ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, request.action)}
|
|
61
61
|
`)]);
|
|
62
62
|
_optionalChain([output, 'optionalAccess', _5 => _5.write, 'optionalCall', _6 => _6(`Reason: ${request.reason}
|
|
63
63
|
`)]);
|
|
@@ -66,14 +66,14 @@ Approval required (${request.risk})
|
|
|
66
66
|
if (answer === void 0 || closed) return;
|
|
67
67
|
closed = true;
|
|
68
68
|
_optionalChain([rl, 'optionalAccess', _7 => _7.close, 'optionalCall', _8 => _8()]);
|
|
69
|
-
cb(
|
|
69
|
+
cb(_chunkMVGUEJ5Zcjs.Exit.succeed(answerToResponse(answer, request)));
|
|
70
70
|
}).catch((cause) => {
|
|
71
71
|
if (closed) return;
|
|
72
72
|
closed = true;
|
|
73
73
|
_optionalChain([rl, 'optionalAccess', _9 => _9.close, 'optionalCall', _10 => _10()]);
|
|
74
74
|
cb(
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
_chunkMVGUEJ5Zcjs.Exit.failCause(
|
|
76
|
+
_chunkMVGUEJ5Zcjs.Cause.fail({
|
|
77
77
|
_tag: "AgentLoopError",
|
|
78
78
|
message: `Approval prompt failed: ${String(cause)}`
|
|
79
79
|
})
|
|
@@ -1104,7 +1104,7 @@ var parseCliArgs = (argv) => {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
if (arg === "--preset" || arg.startsWith("--preset=")) {
|
|
1106
1106
|
const [value, nextIndex] = readFlagValue(argv, index, "--preset");
|
|
1107
|
-
if (!
|
|
1107
|
+
if (!_chunk4ROBZFL6cjs.isAgentPreset.call(void 0, value)) {
|
|
1108
1108
|
throw new Error("--preset requires one of: fix-tests, inspect, typecheck, lint");
|
|
1109
1109
|
}
|
|
1110
1110
|
preset = value;
|
|
@@ -1280,7 +1280,7 @@ var parseBatchGoal = (value, path) => {
|
|
|
1280
1280
|
if (cwd !== void 0 && typeof cwd !== "string") throw new Error(`${path}.cwd must be a string.`);
|
|
1281
1281
|
if (patchFile !== void 0 && typeof patchFile !== "string") throw new Error(`${path}.patchFile must be a string.`);
|
|
1282
1282
|
if (saveRunDir !== void 0 && typeof saveRunDir !== "string") throw new Error(`${path}.saveRunDir must be a string.`);
|
|
1283
|
-
if (preset !== void 0 && (typeof preset !== "string" || !
|
|
1283
|
+
if (preset !== void 0 && (typeof preset !== "string" || !_chunk4ROBZFL6cjs.isAgentPreset.call(void 0, preset))) {
|
|
1284
1284
|
throw new Error(`${path}.preset must be one of: fix-tests, inspect, typecheck, lint.`);
|
|
1285
1285
|
}
|
|
1286
1286
|
if (mode !== void 0 && (typeof mode !== "string" || !isAgentMode(mode))) {
|
|
@@ -1324,7 +1324,7 @@ var readBatchFile = async (cwd, batchFile) => {
|
|
|
1324
1324
|
var resolveBatchGoalText = (item, fallbackPatchFile) => {
|
|
1325
1325
|
if (typeof item === "string") return item;
|
|
1326
1326
|
if (item.goal) return item.goal;
|
|
1327
|
-
if (item.preset) return
|
|
1327
|
+
if (item.preset) return _chunk4ROBZFL6cjs.goalForAgentPreset.call(void 0, item.preset);
|
|
1328
1328
|
if (_nullishCoalesce(item.patchFile, () => ( fallbackPatchFile))) return "apply supplied patch";
|
|
1329
1329
|
return "";
|
|
1330
1330
|
};
|
|
@@ -1351,7 +1351,7 @@ var resolveBatchRuns = (items, parsed, config) => items.map((item, index) => {
|
|
|
1351
1351
|
};
|
|
1352
1352
|
});
|
|
1353
1353
|
var resolveParsedConfig = async (parsed) => {
|
|
1354
|
-
const workspaceDiscovery =
|
|
1354
|
+
const workspaceDiscovery = _chunk4ROBZFL6cjs.discoverNodeWorkspaceRoot.call(void 0, parsed.cwd, {
|
|
1355
1355
|
enabled: parsed.discoverWorkspace
|
|
1356
1356
|
});
|
|
1357
1357
|
const cwdResolved = workspaceDiscovery.cwd;
|
|
@@ -1359,7 +1359,7 @@ var resolveParsedConfig = async (parsed) => {
|
|
|
1359
1359
|
...parsed,
|
|
1360
1360
|
cwd: cwdResolved
|
|
1361
1361
|
};
|
|
1362
|
-
const loaded = await
|
|
1362
|
+
const loaded = await _chunk4ROBZFL6cjs.loadNodeAgentConfig.call(void 0, {
|
|
1363
1363
|
cwd: cwdResolved,
|
|
1364
1364
|
configPath: parsed.configPath,
|
|
1365
1365
|
noConfig: parsed.noConfig
|
|
@@ -1375,7 +1375,7 @@ var resolveParsedConfig = async (parsed) => {
|
|
|
1375
1375
|
const batchRuns = resolveBatchRuns(batchItems, parsedAtWorkspace, loaded.config);
|
|
1376
1376
|
return {
|
|
1377
1377
|
...parsedAtWorkspace,
|
|
1378
|
-
goalText: parsed.goalText || (parsed.preset ?
|
|
1378
|
+
goalText: parsed.goalText || (parsed.preset ? _chunk4ROBZFL6cjs.goalForAgentPreset.call(void 0, parsed.preset) : parsed.patchFile ? "apply supplied patch" : parsed.goalText),
|
|
1379
1379
|
mode: parsed.modeSpecified ? parsed.mode : parsed.preset === "inspect" ? "read-only" : _nullishCoalesce(loaded.config.mode, () => ( parsed.mode)),
|
|
1380
1380
|
approval: parsed.approvalSpecified ? parsed.approval : _nullishCoalesce(loaded.config.approval, () => ( parsed.approval)),
|
|
1381
1381
|
config: loaded.config,
|
|
@@ -1499,7 +1499,7 @@ var envByName = (name) => name ? process.env[name] : void 0;
|
|
|
1499
1499
|
var makeGoogleLLMFromEnv = (config) => {
|
|
1500
1500
|
const apiKey = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(envByName(_optionalChain([config, 'optionalAccess', _39 => _39.apiKeyEnv])), () => ( process.env.BRASS_GOOGLE_API_KEY)), () => ( process.env.GOOGLE_API_KEY)), () => ( process.env.GEMINI_API_KEY));
|
|
1501
1501
|
if (!apiKey) return void 0;
|
|
1502
|
-
return
|
|
1502
|
+
return _chunk4ROBZFL6cjs.makeGoogleGenerativeAILLM.call(void 0, {
|
|
1503
1503
|
apiKey,
|
|
1504
1504
|
model: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(process.env.BRASS_GOOGLE_MODEL, () => ( process.env.BRASS_LLM_MODEL)), () => ( _optionalChain([config, 'optionalAccess', _40 => _40.model]))), () => ( "gemini-2.5-flash")),
|
|
1505
1505
|
apiVersion: _nullishCoalesce(_nullishCoalesce(process.env.BRASS_GOOGLE_API_VERSION, () => ( _optionalChain([config, 'optionalAccess', _41 => _41.apiVersion]))), () => ( "v1beta")),
|
|
@@ -1517,12 +1517,12 @@ var makeOpenAICompatibleLLMFromEnv = (config) => {
|
|
|
1517
1517
|
const apiKey = _nullishCoalesce(envByName(_optionalChain([config, 'optionalAccess', _50 => _50.apiKeyEnv])), () => ( process.env.BRASS_LLM_API_KEY));
|
|
1518
1518
|
const model = _nullishCoalesce(_nullishCoalesce(process.env.BRASS_LLM_MODEL, () => ( _optionalChain([config, 'optionalAccess', _51 => _51.model]))), () => ( "gpt-4.1"));
|
|
1519
1519
|
if (!endpoint || !apiKey) return void 0;
|
|
1520
|
-
return
|
|
1520
|
+
return _chunk4ROBZFL6cjs.makeOpenAICompatibleLLM.call(void 0, { endpoint, apiKey, model });
|
|
1521
1521
|
};
|
|
1522
1522
|
var makeLLMFromEnv = (config) => {
|
|
1523
1523
|
const provider = _optionalChain([(_nullishCoalesce(process.env.BRASS_LLM_PROVIDER, () => ( _optionalChain([config, 'optionalAccess', _52 => _52.provider])))), 'optionalAccess', _53 => _53.trim, 'call', _54 => _54(), 'access', _55 => _55.toLowerCase, 'call', _56 => _56()]);
|
|
1524
1524
|
const fakeResponse = _nullishCoalesce(process.env.BRASS_FAKE_LLM_RESPONSE, () => ( _optionalChain([config, 'optionalAccess', _57 => _57.fakeResponse])));
|
|
1525
|
-
if (provider === "fake") return
|
|
1525
|
+
if (provider === "fake") return _chunk4ROBZFL6cjs.makeFakeLLM.call(void 0, { content: fakeResponse });
|
|
1526
1526
|
if (provider === "google" || provider === "gemini") {
|
|
1527
1527
|
const google = makeGoogleLLMFromEnv(config);
|
|
1528
1528
|
if (!google) {
|
|
@@ -1544,7 +1544,7 @@ var makeLLMFromEnv = (config) => {
|
|
|
1544
1544
|
if (provider) {
|
|
1545
1545
|
throw new Error(`Unsupported LLM provider: ${provider}`);
|
|
1546
1546
|
}
|
|
1547
|
-
return _nullishCoalesce(_nullishCoalesce(makeGoogleLLMFromEnv(config), () => ( makeOpenAICompatibleLLMFromEnv(config))), () => (
|
|
1547
|
+
return _nullishCoalesce(_nullishCoalesce(makeGoogleLLMFromEnv(config), () => ( makeOpenAICompatibleLLMFromEnv(config))), () => ( _chunk4ROBZFL6cjs.makeFakeLLM.call(void 0, { content: fakeResponse })));
|
|
1548
1548
|
};
|
|
1549
1549
|
var parseApprovalModeFromEnv = () => {
|
|
1550
1550
|
const raw = _optionalChain([process, 'access', _58 => _58.env, 'access', _59 => _59.BRASS_AGENT_APPROVAL, 'optionalAccess', _60 => _60.trim, 'call', _61 => _61(), 'access', _62 => _62.toLowerCase, 'call', _63 => _63()]);
|
|
@@ -1567,9 +1567,9 @@ var makeApprovalServiceFromCli = (parsed) => {
|
|
|
1567
1567
|
const mode = resolveApprovalMode(parsed);
|
|
1568
1568
|
switch (mode) {
|
|
1569
1569
|
case "approve":
|
|
1570
|
-
return
|
|
1570
|
+
return _chunk4ROBZFL6cjs.autoApproveApprovals;
|
|
1571
1571
|
case "deny":
|
|
1572
|
-
return
|
|
1572
|
+
return _chunk4ROBZFL6cjs.makeAutoDenyApprovals.call(void 0, "Approval rejected because the CLI is running without interactive input. Use --yes to auto-approve.");
|
|
1573
1573
|
case "interactive":
|
|
1574
1574
|
return makeCliApprovalService();
|
|
1575
1575
|
}
|
|
@@ -1701,32 +1701,32 @@ var createHumanEventSink = (configPath) => ({
|
|
|
1701
1701
|
console.log("");
|
|
1702
1702
|
break;
|
|
1703
1703
|
case "agent.action.started":
|
|
1704
|
-
console.log(`\u2192 ${
|
|
1704
|
+
console.log(`\u2192 ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)}`);
|
|
1705
1705
|
break;
|
|
1706
1706
|
case "agent.action.completed": {
|
|
1707
|
-
const status =
|
|
1708
|
-
console.log(`${statusIcon2(status)} ${
|
|
1707
|
+
const status = _chunk4ROBZFL6cjs.observationStatus.call(void 0, event.observation);
|
|
1708
|
+
console.log(`${statusIcon2(status)} ${_chunk4ROBZFL6cjs.summarizeAgentObservation.call(void 0, event.observation)} ${formatDuration(event.durationMs)}`);
|
|
1709
1709
|
break;
|
|
1710
1710
|
}
|
|
1711
1711
|
case "agent.action.failed":
|
|
1712
1712
|
if (event.error._tag !== "ToolTimeout" && event.error._tag !== "PermissionDenied" && event.error._tag !== "ApprovalRejected") {
|
|
1713
|
-
console.log(`\u2717 ${
|
|
1713
|
+
console.log(`\u2717 ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)} failed with ${event.error._tag} ${formatDuration(event.durationMs)}`);
|
|
1714
1714
|
}
|
|
1715
1715
|
break;
|
|
1716
1716
|
case "agent.tool.timeout":
|
|
1717
|
-
console.log(`! ${
|
|
1717
|
+
console.log(`! ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)} timed out after ${event.timeoutMs}ms`);
|
|
1718
1718
|
break;
|
|
1719
1719
|
case "agent.permission.denied":
|
|
1720
|
-
console.log(`\u2717 ${
|
|
1720
|
+
console.log(`\u2717 ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)} denied: ${event.reason}`);
|
|
1721
1721
|
break;
|
|
1722
1722
|
case "agent.approval.requested":
|
|
1723
|
-
console.log(`? approval required for ${
|
|
1723
|
+
console.log(`? approval required for ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)} (${event.risk})`);
|
|
1724
1724
|
break;
|
|
1725
1725
|
case "agent.approval.resolved":
|
|
1726
1726
|
if (event.approved) {
|
|
1727
|
-
console.log(`\u2713 approval granted for ${
|
|
1727
|
+
console.log(`\u2713 approval granted for ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)}`);
|
|
1728
1728
|
} else {
|
|
1729
|
-
console.log(`\u2717 approval rejected for ${
|
|
1729
|
+
console.log(`\u2717 approval rejected for ${_chunk4ROBZFL6cjs.summarizeAgentAction.call(void 0, event.action)}${event.reason ? `: ${event.reason}` : ""}`);
|
|
1730
1730
|
}
|
|
1731
1731
|
break;
|
|
1732
1732
|
case "agent.patch.applied":
|
|
@@ -1831,13 +1831,13 @@ var printHumanFinalSummary = (state) => {
|
|
|
1831
1831
|
};
|
|
1832
1832
|
var makeEventsSink = (parsed, compactOptions) => parsed.output === "human" ? createHumanEventSink(parsed.resolvedConfigPath) : parsed.output === "events-json" ? createJsonEventSink(compactOptions) : parsed.output === "protocol-json" ? createProtocolEventSink(compactOptions) : void 0;
|
|
1833
1833
|
var makeAgentEnv = (parsed, events) => {
|
|
1834
|
-
const shell =
|
|
1834
|
+
const shell = _chunk4ROBZFL6cjs.NodeShell;
|
|
1835
1835
|
return {
|
|
1836
1836
|
shell,
|
|
1837
|
-
fs:
|
|
1838
|
-
patch:
|
|
1837
|
+
fs: _chunk4ROBZFL6cjs.makeNodeFileSystem.call(void 0, shell),
|
|
1838
|
+
patch: _chunk4ROBZFL6cjs.makeNodePatchService.call(void 0, shell),
|
|
1839
1839
|
llm: makeLLMFromEnv(parsed.config.llm),
|
|
1840
|
-
permissions:
|
|
1840
|
+
permissions: _chunk4ROBZFL6cjs.makeConfiguredPermissions.call(void 0, parsed.config.permissions),
|
|
1841
1841
|
approvals: makeApprovalServiceFromCli(parsed),
|
|
1842
1842
|
...events ? { events } : {},
|
|
1843
1843
|
...parsed.config.tools ? { toolPolicies: parsed.config.tools } : {}
|
|
@@ -1854,10 +1854,10 @@ var singleRunFromParsed = (parsed) => ({
|
|
|
1854
1854
|
});
|
|
1855
1855
|
var runCliAgent = async (parsed, run, compactOptions, events) => {
|
|
1856
1856
|
const env = makeAgentEnv(parsed, events);
|
|
1857
|
-
const runtime = new (0,
|
|
1857
|
+
const runtime = new (0, _chunkGLE2WY7Zcjs.Runtime)({ env });
|
|
1858
1858
|
const initialPatch = run.patchFile ? await readPatchFile(run.cwd, run.patchFile) : void 0;
|
|
1859
1859
|
const state = await runtime.toPromise(
|
|
1860
|
-
|
|
1860
|
+
_chunk4ROBZFL6cjs.runAgent.call(void 0, runtime, {
|
|
1861
1861
|
id: `agent-${Date.now()}-${run.index + 1}`,
|
|
1862
1862
|
cwd: run.cwd,
|
|
1863
1863
|
text: run.goalText,
|