brass-runtime 1.15.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 +673 -136
- package/dist/agent/cli/main.cjs +40 -35
- package/dist/agent/cli/main.js +9 -4
- package/dist/agent/cli/main.mjs +9 -4
- package/dist/agent/index.cjs +8 -4
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +7 -3
- package/dist/agent/index.mjs +7 -3
- package/dist/chunk-2HQTDLHF.mjs +683 -0
- package/dist/chunk-36I3M4UC.mjs +370 -0
- package/dist/chunk-3AYM6WPJ.js +1629 -0
- package/dist/chunk-3LOYJFRR.cjs +300 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-3Y2RIUMM.js +300 -0
- package/dist/{chunk-VEZNF5GZ.cjs → chunk-4ROBZFL6.cjs} +130 -126
- package/dist/{chunk-3QMOKAS5.js → chunk-52OB2ROS.js} +9 -5
- package/dist/chunk-52PPNNI4.cjs +416 -0
- package/dist/chunk-5EC274J5.cjs +2874 -0
- package/dist/chunk-5QC7LRZ3.js +229 -0
- package/dist/chunk-5VRJNBLZ.mjs +2874 -0
- 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-4NHES7VK.mjs → chunk-7JIJOVCT.js} +27 -13
- package/dist/chunk-A2OM6NEH.mjs +194 -0
- package/dist/chunk-AGR5B2BC.cjs +683 -0
- package/dist/chunk-AVNQLJ5V.js +777 -0
- package/dist/chunk-B33ICAKP.js +313 -0
- package/dist/{chunk-ELOOF35R.mjs → chunk-B5JD23U7.mjs} +1 -1
- package/dist/chunk-BABBZK4Y.js +2024 -0
- package/dist/chunk-C3MDXTRZ.js +354 -0
- package/dist/chunk-CIZFIMK5.js +2193 -0
- package/dist/chunk-CZIVE6NT.cjs +354 -0
- package/dist/chunk-DNFJLJMW.mjs +354 -0
- package/dist/chunk-DNFO2EIZ.mjs +777 -0
- package/dist/chunk-EJ6BPYVR.mjs +416 -0
- package/dist/chunk-ENKODRU3.cjs +2193 -0
- package/dist/chunk-EOC4UHBS.mjs +229 -0
- package/dist/{chunk-BMH5AV44.js → chunk-FH2X7BVP.js} +756 -440
- package/dist/{chunk-PPUXIH5R.js → chunk-FHQGHPMO.mjs} +27 -13
- package/dist/{chunk-TGIFUAK4.cjs → chunk-GLE2WY7Z.cjs} +951 -635
- package/dist/{chunk-BDF4AMWX.mjs → chunk-GYM3LLGS.mjs} +756 -440
- package/dist/chunk-HLWLMW2F.mjs +2024 -0
- package/dist/chunk-JF5WGYJJ.cjs +194 -0
- package/dist/chunk-KH4SYAOS.mjs +1629 -0
- package/dist/chunk-KN32XNTH.mjs +313 -0
- package/dist/chunk-KQLYONSE.cjs +2871 -0
- package/dist/{chunk-STVLQ3XD.cjs → chunk-KZJQ723N.cjs} +92 -78
- package/dist/chunk-L2SYFEBS.js +194 -0
- package/dist/chunk-L6VB5N7Q.cjs +104 -0
- package/dist/{chunk-K6M7MDZ4.mjs → chunk-MBEJI5HF.mjs} +9 -5
- package/dist/chunk-MIIYDLGM.js +2874 -0
- package/dist/chunk-MOO4L7F4.mjs +104 -0
- package/dist/chunk-MT3OWDPC.mjs +2193 -0
- package/dist/chunk-MVGUEJ5Z.cjs +370 -0
- package/dist/chunk-OBGZSXTJ.cjs +10 -0
- package/dist/chunk-PD4EJTQC.cjs +229 -0
- package/dist/chunk-PWC3RBQE.mjs +300 -0
- package/dist/chunk-Q2I37RP3.cjs +1629 -0
- package/dist/chunk-RKGKFN2A.js +416 -0
- package/dist/{chunk-R3R2FVLG.cjs → chunk-SA6HUJVI.cjs} +5 -5
- package/dist/chunk-TRM4JUZQ.js +104 -0
- package/dist/chunk-UB4B6OFY.js +370 -0
- package/dist/{chunk-TO7IKXYT.js → chunk-UCUBNWM2.js} +1 -1
- package/dist/chunk-VN44DYYT.cjs +2024 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/client-CZHU674n.d.ts +820 -0
- package/dist/core/index.cjs +198 -4
- package/dist/core/index.d.ts +311 -212
- package/dist/core/index.js +237 -43
- package/dist/core/index.mjs +237 -43
- package/dist/{effect-CMOQKX8y.d.ts → effect-DIUHZ9IN.d.ts} +195 -1
- package/dist/effectRunner-CFLC32IK.cjs +8 -0
- package/dist/effectRunner-L4S7IPT3.js +8 -0
- package/dist/effectRunner-NNGG75QA.mjs +8 -0
- package/dist/http/index.cjs +1227 -2971
- package/dist/http/index.d.ts +826 -280
- package/dist/http/index.js +1089 -2833
- package/dist/http/index.mjs +1089 -2833
- package/dist/http/testing.cjs +161 -0
- package/dist/http/testing.d.ts +43 -0
- package/dist/http/testing.js +161 -0
- package/dist/http/testing.mjs +161 -0
- package/dist/index.cjs +486 -250
- package/dist/index.d.ts +87 -95
- package/dist/index.js +391 -155
- package/dist/index.mjs +391 -155
- package/dist/observability/index.cjs +162 -0
- package/dist/observability/index.d.ts +152 -0
- package/dist/observability/index.js +162 -0
- package/dist/observability/index.mjs +162 -0
- 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 +29 -0
- package/dist/schema/index.d.ts +179 -0
- package/dist/schema/index.js +29 -0
- package/dist/schema/index.mjs +29 -0
- package/dist/server-GJPg8ZSG.d.ts +675 -0
- package/dist/{stream-FQm9h4Mg.d.ts → stream-B4oK9JFP.d.ts} +1 -1
- package/dist/tracer-Hwt1cl7h.d.ts +189 -0
- package/dist/tracing-DqbTKGcf.d.ts +148 -0
- 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 +48 -2
- package/dist/chunk-AR22SXML.js +0 -1043
- package/dist/chunk-BDYEENHT.js +0 -224
- package/dist/chunk-JFPU5GQI.mjs +0 -1043
- package/dist/chunk-MS34J5LY.cjs +0 -224
- package/dist/chunk-UMAZLXAB.mjs +0 -224
- package/dist/chunk-XPZNXSVN.cjs +0 -1043
- package/dist/tracing-DNT9jEbr.d.ts +0 -106
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR 0001: Maintain an AI Context Pack
|
|
2
|
+
|
|
3
|
+
Status: accepted
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`brass-runtime` contains a core effect runtime, streams, HTTP modules, WASM
|
|
8
|
+
engine pieces, benchmarks, and Brass Agent surfaces. The codebase is still small
|
|
9
|
+
enough to navigate manually, but large enough that a contributor or coding agent
|
|
10
|
+
needs a compact map before making safe changes.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
Maintain a small context pack:
|
|
15
|
+
|
|
16
|
+
- `AGENTS.md` for root-level contributor/agent guidance.
|
|
17
|
+
- `docs/ai/PROJECT_MAP.md` for module navigation.
|
|
18
|
+
- `docs/ai/INVARIANTS.md` for semantic rules.
|
|
19
|
+
- `docs/ai/VALIDATION_MATRIX.md` for test selection.
|
|
20
|
+
- `docs/ai/PUBLIC_API.md` for exports and compatibility.
|
|
21
|
+
- `scripts/context-pack.mjs` for generated workspace summaries.
|
|
22
|
+
|
|
23
|
+
The generated context command prints to stdout and does not create tracked
|
|
24
|
+
artifacts by default.
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
- Future changes should update the context pack when they move module
|
|
29
|
+
boundaries, change public API, or add validation expectations.
|
|
30
|
+
- Agents can gather focused context without rereading the entire repository.
|
|
31
|
+
- The context pack is documentation, not a replacement for tests.
|
|
32
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Agent apply mode
|
|
2
|
+
|
|
3
|
+
P3 adds a conservative write path for the experimental agent.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Keep the default CLI behavior safe:
|
|
8
|
+
|
|
9
|
+
- default mode remains `propose`
|
|
10
|
+
- `write` mode must be explicit
|
|
11
|
+
- patch application remains policy-gated and approval-gated
|
|
12
|
+
- patch targets must stay inside the workspace
|
|
13
|
+
- discovered validation commands still go through `PermissionService`
|
|
14
|
+
|
|
15
|
+
## New pieces
|
|
16
|
+
|
|
17
|
+
`src/agent` now includes:
|
|
18
|
+
|
|
19
|
+
- `PatchService`
|
|
20
|
+
- `patch.apply` / `patch.applied`
|
|
21
|
+
- unified-diff extraction helpers
|
|
22
|
+
- a Node patch adapter built on `git apply`
|
|
23
|
+
- CLI flags for `--mode`, `--apply`, and approval strategy
|
|
24
|
+
|
|
25
|
+
## Modes
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
brass-agent "fix the failing tests" # propose (default)
|
|
29
|
+
brass-agent --apply "fix the failing tests" # write, prompts when interactive
|
|
30
|
+
brass-agent --apply --yes "fix the failing tests" # write, auto-approve
|
|
31
|
+
brass-agent --mode write "fix the failing tests"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Safety rules
|
|
35
|
+
|
|
36
|
+
1. The agent only applies unified diffs.
|
|
37
|
+
2. All patch target paths are validated as workspace-relative before apply.
|
|
38
|
+
3. `propose` mode may emit `patch.proposed`, but never `patch.apply`.
|
|
39
|
+
4. `write` mode may apply patches only after approval.
|
|
40
|
+
5. Shell commands remain whitelisted.
|
|
41
|
+
6. After `patch.applied`, the agent re-runs the same discovered validation commands.
|
|
42
|
+
|
|
43
|
+
## Patch adapter
|
|
44
|
+
|
|
45
|
+
The Node adapter uses `git apply --check` before the actual apply step.
|
|
46
|
+
|
|
47
|
+
That gives us a conservative path with a dry-run check first, while keeping the runtime invariant intact:
|
|
48
|
+
all external work is still represented as cancellable `Async`.
|
|
49
|
+
|
|
50
|
+
## Offline smoke tests
|
|
51
|
+
|
|
52
|
+
You can drive the fake LLM with a deterministic response:
|
|
53
|
+
|
|
54
|
+
~~~bash
|
|
55
|
+
export BRASS_LLM_PROVIDER=fake
|
|
56
|
+
export BRASS_FAKE_LLM_RESPONSE='Here is a patch.
|
|
57
|
+
|
|
58
|
+
```diff
|
|
59
|
+
--- a/hello.txt
|
|
60
|
+
+++ b/hello.txt
|
|
61
|
+
@@ -1 +1 @@
|
|
62
|
+
-old
|
|
63
|
+
+new
|
|
64
|
+
```'
|
|
65
|
+
|
|
66
|
+
brass-agent --apply --yes --cwd ./tmp/repro "apply the inferred patch"
|
|
67
|
+
~~~
|
|
68
|
+
|
|
69
|
+
## Patch quality loop
|
|
70
|
+
|
|
71
|
+
P13 adds an optional repair loop for normal generated patches in `write` mode.
|
|
72
|
+
After a generated patch is applied, the agent re-runs discovered validation
|
|
73
|
+
commands. If validation fails and repair budget remains, it calls `llm.patch` to
|
|
74
|
+
request an incremental repair diff, applies that diff, and validates again.
|
|
75
|
+
|
|
76
|
+
The default repair budget is one attempt:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"patchQuality": {
|
|
81
|
+
"enabled": true,
|
|
82
|
+
"maxRepairAttempts": 1
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Exact patch-file flows remain exact. `--apply-patch-file` does not trigger
|
|
88
|
+
repair attempts, because clients such as the VS Code extension use that path
|
|
89
|
+
after the user approved a specific previewed diff.
|
|
90
|
+
|
|
91
|
+
See [Agent patch quality loop](./agent-patch-quality-loop.md).
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Automatic rollback safety
|
|
95
|
+
|
|
96
|
+
P14 adds automatic rollback safety for generated patches. If generated patches
|
|
97
|
+
still fail validation after the configured repair attempts are exhausted, the
|
|
98
|
+
agent can schedule `patch.rollback` actions to reverse the generated patch stack.
|
|
99
|
+
|
|
100
|
+
Rollback is still policy-gated and approval-gated. Exact patch-file flows remain
|
|
101
|
+
protected by default so a VS Code-approved patch is not silently reversed unless
|
|
102
|
+
the project opts in with `rollback.allowForSuppliedPatches`.
|
|
103
|
+
|
|
104
|
+
See [Agent automatic rollback safety](./agent-rollback-safety.md).
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Agent approvals
|
|
2
|
+
|
|
3
|
+
P6 adds interactive approvals to `brass-agent` without moving prompt logic into
|
|
4
|
+
`src/core`.
|
|
5
|
+
|
|
6
|
+
The boundary remains:
|
|
7
|
+
|
|
8
|
+
```txt
|
|
9
|
+
src/core
|
|
10
|
+
↑
|
|
11
|
+
src/agent PermissionService / ApprovalService
|
|
12
|
+
↑
|
|
13
|
+
src/agent/cli prompt UX
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Decision flow
|
|
17
|
+
|
|
18
|
+
Every action still goes through the same policy pipeline:
|
|
19
|
+
|
|
20
|
+
```txt
|
|
21
|
+
AgentAction
|
|
22
|
+
-> PermissionService.check(...)
|
|
23
|
+
-> allow | deny | ask
|
|
24
|
+
-> ApprovalService.request(...) when ask
|
|
25
|
+
-> ToolPolicy timeout/retry
|
|
26
|
+
-> Async tool effect
|
|
27
|
+
-> Observation
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`PermissionService` decides whether an action needs approval. `ApprovalService`
|
|
31
|
+
decides how to obtain that approval: prompt the human, auto-approve, auto-deny,
|
|
32
|
+
or integrate with another UI.
|
|
33
|
+
|
|
34
|
+
## Built-in approvals
|
|
35
|
+
|
|
36
|
+
The agent exports:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
autoApproveApprovals
|
|
40
|
+
makeAutoDenyApprovals(reason?)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The CLI also provides an interactive implementation that prompts on stderr.
|
|
44
|
+
|
|
45
|
+
## CLI behavior
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
brass-agent --apply "fix tests" # prompts when interactive
|
|
49
|
+
brass-agent --apply --yes "fix tests" # auto-approve
|
|
50
|
+
brass-agent --apply --no-input "fix tests" # auto-deny
|
|
51
|
+
brass-agent --approval interactive --apply "fix tests"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Environment variables:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
BRASS_AGENT_APPROVAL=approve|deny|interactive|auto
|
|
58
|
+
BRASS_AGENT_AUTO_APPROVE=true
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`auto` is conservative:
|
|
62
|
+
|
|
63
|
+
```txt
|
|
64
|
+
human TTY session -> interactive prompts
|
|
65
|
+
json/events-json or non-TTY -> deny approval-required actions
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use `--yes` explicitly for non-interactive smoke tests or CI flows that are
|
|
69
|
+
allowed to mutate the workspace.
|
|
70
|
+
|
|
71
|
+
## Events
|
|
72
|
+
|
|
73
|
+
Approvals emit typed events:
|
|
74
|
+
|
|
75
|
+
```txt
|
|
76
|
+
agent.approval.requested
|
|
77
|
+
agent.approval.resolved
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
These events are available in human output and `--events-json`. They are emitted
|
|
81
|
+
before and after the approval service runs.
|
|
82
|
+
|
|
83
|
+
## Safety invariants
|
|
84
|
+
|
|
85
|
+
- Approval prompts are a capability of `src/agent`, not `src/core`.
|
|
86
|
+
- An action that requires approval must not run unless approval is granted.
|
|
87
|
+
- Missing approval service means approval-required actions are rejected.
|
|
88
|
+
- Observability is best-effort and must not change approval semantics.
|
|
89
|
+
- Non-interactive runs deny by default unless explicitly configured to approve.
|
|
90
|
+
|
|
91
|
+
## Config defaults
|
|
92
|
+
|
|
93
|
+
P7 allows a project config file to set the default CLI approval strategy:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"approval": "auto"
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
CLI flags still win over config:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
brass-agent --approval deny "inspect"
|
|
105
|
+
brass-agent --yes --apply "fix tests"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`permissions.patchApply` can also tune whether `patch.apply` is allowed, denied,
|
|
109
|
+
or routed through approval in `write` and `autonomous` modes. See
|
|
110
|
+
[Agent config and policy files](./agent-config.md).
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Agent batch runs
|
|
2
|
+
|
|
3
|
+
P21 adds sequential batch execution to `brass-agent`.
|
|
4
|
+
|
|
5
|
+
The goal is to make common DX/CI workflows composable without introducing a new
|
|
6
|
+
scheduler or breaking the existing boundary:
|
|
7
|
+
|
|
8
|
+
```txt
|
|
9
|
+
src/core
|
|
10
|
+
↑
|
|
11
|
+
src/agent runAgent(...)
|
|
12
|
+
↑
|
|
13
|
+
brass-agent CLI batch runner
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
A batch run is just multiple normal agent runs executed one after another. Each
|
|
17
|
+
run still goes through the same pipeline:
|
|
18
|
+
|
|
19
|
+
```txt
|
|
20
|
+
AgentAction
|
|
21
|
+
-> PermissionService
|
|
22
|
+
-> ApprovalService when ask
|
|
23
|
+
-> ToolPolicy timeout/retry
|
|
24
|
+
-> Async tool effect
|
|
25
|
+
-> Observation
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Batch mode does not bypass policy, approvals, redaction, rollback safety, CI exit
|
|
29
|
+
codes, or artifact export.
|
|
30
|
+
|
|
31
|
+
## CLI
|
|
32
|
+
|
|
33
|
+
Run a batch from a file:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
brass-agent --batch-file ./brass-agent.batch.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
In CI:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
brass-agent --batch-file ./brass-agent.batch.json --ci --batch-stop-on-failure
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`--batch-stop-on-failure` stops after the first run whose CI status is non-zero.
|
|
46
|
+
`--batch-continue-on-failure` forces the opposite.
|
|
47
|
+
|
|
48
|
+
When neither flag is provided, the default is:
|
|
49
|
+
|
|
50
|
+
```txt
|
|
51
|
+
--ci -> stop on failure
|
|
52
|
+
not --ci -> continue
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Batch file formats
|
|
56
|
+
|
|
57
|
+
### JSON array
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
[
|
|
61
|
+
"inspect this workspace",
|
|
62
|
+
{ "preset": "typecheck" },
|
|
63
|
+
{ "preset": "lint" },
|
|
64
|
+
{ "preset": "fix-tests", "mode": "propose" }
|
|
65
|
+
]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### JSON object
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"goals": [
|
|
73
|
+
{ "preset": "inspect" },
|
|
74
|
+
{ "goal": "explain the failing tests", "mode": "read-only" },
|
|
75
|
+
{ "goal": "fix the failing tests", "mode": "propose" }
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Plain text
|
|
81
|
+
|
|
82
|
+
If the file is not valid JSON, `brass-agent` treats it as a line-based goal file.
|
|
83
|
+
Blank lines and `#` comments are ignored.
|
|
84
|
+
|
|
85
|
+
```txt
|
|
86
|
+
# brass-agent.batch.txt
|
|
87
|
+
inspect this workspace
|
|
88
|
+
run typecheck discovery and explain failures
|
|
89
|
+
fix the failing tests
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Per-goal fields
|
|
93
|
+
|
|
94
|
+
JSON batch items support:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
{
|
|
98
|
+
goal?: string;
|
|
99
|
+
preset?: "fix-tests" | "inspect" | "typecheck" | "lint";
|
|
100
|
+
mode?: "read-only" | "propose" | "write" | "autonomous";
|
|
101
|
+
cwd?: string;
|
|
102
|
+
patchFile?: string;
|
|
103
|
+
patchFileMode?: "apply" | "rollback";
|
|
104
|
+
saveRunDir?: string;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`preset` fills in a standard goal. `goal` wins when both are present.
|
|
109
|
+
|
|
110
|
+
`cwd` lets one batch file target multiple workspaces, but the same loaded config
|
|
111
|
+
and CLI environment are reused for the full batch. Use separate invocations when
|
|
112
|
+
different workspaces need different config files.
|
|
113
|
+
|
|
114
|
+
## Config default batch
|
|
115
|
+
|
|
116
|
+
A project can define a default batch:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"batch": {
|
|
121
|
+
"stopOnFailure": true,
|
|
122
|
+
"goals": [
|
|
123
|
+
{ "preset": "inspect" },
|
|
124
|
+
{ "preset": "typecheck" },
|
|
125
|
+
{ "preset": "lint" }
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Then run:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
brass-agent --ci
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The config batch is used only when the CLI does not receive an explicit goal,
|
|
138
|
+
`--preset`, `--patch-file`, or `--batch-file`.
|
|
139
|
+
|
|
140
|
+
## Outputs
|
|
141
|
+
|
|
142
|
+
Human output prints each normal run and then a final batch summary:
|
|
143
|
+
|
|
144
|
+
```txt
|
|
145
|
+
batch summary:
|
|
146
|
+
completed: 3/3
|
|
147
|
+
failed: 0
|
|
148
|
+
exit code: 0
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`--json` prints a batch object:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"type": "batch",
|
|
156
|
+
"summary": {
|
|
157
|
+
"total": 3,
|
|
158
|
+
"completed": 3,
|
|
159
|
+
"failed": 0,
|
|
160
|
+
"exitCode": 0,
|
|
161
|
+
"stoppedEarly": false
|
|
162
|
+
},
|
|
163
|
+
"results": []
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`--protocol-json` emits normal event messages and a `final-state` message per
|
|
168
|
+
run, followed by a `batch-summary` message.
|
|
169
|
+
|
|
170
|
+
## Exit codes
|
|
171
|
+
|
|
172
|
+
In `--ci` mode, batch exit code is aggregated from individual runs:
|
|
173
|
+
|
|
174
|
+
```txt
|
|
175
|
+
1 if any run failed or latest validation failed
|
|
176
|
+
2 if no run failed but at least one run proposed an unapplied patch with --fail-on-patch-proposed
|
|
177
|
+
0 otherwise
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## VS Code
|
|
181
|
+
|
|
182
|
+
P22 adds a VS Code command, `Brass Agent: Run Batch File`, which invokes the CLI
|
|
183
|
+
with `--protocol-json --batch-file`. The extension stores the batch as a parent
|
|
184
|
+
history entry and each CLI `final-state` message as a child run. See
|
|
185
|
+
[VS Code batch runner](./agent-vscode-batch-runner.md).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Agent Module Boundaries
|
|
2
|
+
|
|
3
|
+
These rules keep the experimental agent layer useful without letting it leak into the runtime core.
|
|
4
|
+
|
|
5
|
+
## Dependency direction
|
|
6
|
+
|
|
7
|
+
```txt
|
|
8
|
+
core runtime
|
|
9
|
+
↑
|
|
10
|
+
agent module
|
|
11
|
+
↑
|
|
12
|
+
cli / UX
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Rules:
|
|
16
|
+
|
|
17
|
+
1. `src/core` must not know that `src/agent` exists.
|
|
18
|
+
2. `src/agent` may depend on `src/core` runtime primitives.
|
|
19
|
+
3. Agent-specific shortcuts must not be added to `Runtime`, `Fiber`, `Scope`, or the scheduler.
|
|
20
|
+
4. If the agent reveals a missing semantic in the core, fix the core as a runtime invariant first.
|
|
21
|
+
5. Keep the agent as an experimental consumer of the runtime until the shape is stable.
|
|
22
|
+
|
|
23
|
+
## Agent execution model
|
|
24
|
+
|
|
25
|
+
The agent does not perform side effects directly.
|
|
26
|
+
|
|
27
|
+
It must follow this pipeline:
|
|
28
|
+
|
|
29
|
+
```txt
|
|
30
|
+
Goal
|
|
31
|
+
-> decideNextAction
|
|
32
|
+
-> PermissionService
|
|
33
|
+
-> ApprovalService when permission decision is ask
|
|
34
|
+
-> ToolPolicy
|
|
35
|
+
-> AgentAction interpreted as Async
|
|
36
|
+
-> Observation
|
|
37
|
+
-> reducer
|
|
38
|
+
-> next AgentState
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Rules:
|
|
42
|
+
|
|
43
|
+
1. The planner produces `AgentAction` values.
|
|
44
|
+
2. Every `AgentAction` is interpreted into `Async<AgentEnv, AgentError, Observation>`.
|
|
45
|
+
3. All external work goes through capabilities in `AgentEnv`.
|
|
46
|
+
4. All tool execution goes through permissions first.
|
|
47
|
+
5. Approval-required actions must be approved before tool execution.
|
|
48
|
+
6. All tool execution goes through timeout/retry policy.
|
|
49
|
+
7. No detached background work by default.
|
|
50
|
+
8. Every async tool that touches external work must be cancellable.
|
|
51
|
+
9. Any patch-application path must validate that every target path stays inside the workspace.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Configuration boundary
|
|
55
|
+
|
|
56
|
+
Project policy may be loaded from `.brass-agent.json`, but config is still an
|
|
57
|
+
agent-layer concern:
|
|
58
|
+
|
|
59
|
+
```txt
|
|
60
|
+
src/core
|
|
61
|
+
↑
|
|
62
|
+
src/agent policy/config
|
|
63
|
+
↑
|
|
64
|
+
src/agent/cli Node config loader
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Rules:
|
|
68
|
+
|
|
69
|
+
1. Config loading must not move into `src/core`.
|
|
70
|
+
2. Config is resolved before constructing `AgentEnv`.
|
|
71
|
+
3. Config may tune permissions, approvals, LLM provider/model, and tool policies.
|
|
72
|
+
4. Config must not store secrets; adapters should read API keys from environment variables.
|
|
73
|
+
5. Config must not bypass the `AgentAction -> PermissionService -> ApprovalService -> ToolPolicy -> Async -> Observation` pipeline.
|
|
74
|
+
|
|
75
|
+
## Runtime invariants the agent relies on
|
|
76
|
+
|
|
77
|
+
The agent assumes these runtime semantics:
|
|
78
|
+
|
|
79
|
+
1. `Scope.close()` interrupts child fibers.
|
|
80
|
+
2. `Scope.closeAsync(...)` can be awaited.
|
|
81
|
+
3. Closing a parent scope propagates to subscopes.
|
|
82
|
+
4. Interrupted fibers run their finalizers exactly once.
|
|
83
|
+
5. `Async` work that registers external IO returns a canceler.
|
|
84
|
+
6. Race-like operators close their internal scopes and cancel losing branches.
|
|
85
|
+
7. If a tool cannot be cancelled, it is a bug in the tool adapter.
|
|
86
|
+
|
|
87
|
+
## Safety defaults
|
|
88
|
+
|
|
89
|
+
Initial agent modes should be conservative:
|
|
90
|
+
|
|
91
|
+
1. `read-only`: read/search/model only.
|
|
92
|
+
2. `propose`: read/search/model plus whitelisted read-only commands and patch proposals.
|
|
93
|
+
3. `write`: may apply patches only after approval.
|
|
94
|
+
4. `autonomous`: reserved for later; sensitive actions still require approval.
|
|
95
|
+
|
|
96
|
+
The initial CLI should default to `propose`.
|
|
97
|
+
|
|
98
|
+
## Extraction rule
|
|
99
|
+
|
|
100
|
+
Keep the agent in `src/agent` while validating the vertical slice.
|
|
101
|
+
Extract to packages only after the design stabilizes:
|
|
102
|
+
|
|
103
|
+
```txt
|
|
104
|
+
packages/
|
|
105
|
+
brass-runtime/
|
|
106
|
+
brass-agent/
|
|
107
|
+
brass-node/
|
|
108
|
+
brass-llm/
|
|
109
|
+
brass-cli/
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Until then, `src/agent` is allowed to be experimental, but `src/core` is not.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Brass Agent chat sessions
|
|
2
|
+
|
|
3
|
+
P30 turns the VS Code Chat view from a one-shot launcher into a lightweight
|
|
4
|
+
conversation surface.
|
|
5
|
+
|
|
6
|
+
The CLI remains the canonical execution boundary. The VS Code extension still
|
|
7
|
+
calls:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
brass-agent --protocol-json --protocol-full-patches --cwd <workspace> <goal>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The new session behavior lives entirely in the extension.
|
|
14
|
+
|
|
15
|
+
## What is stored
|
|
16
|
+
|
|
17
|
+
The VS Code extension stores a compact chat session in `workspaceState`:
|
|
18
|
+
|
|
19
|
+
```txt
|
|
20
|
+
messages
|
|
21
|
+
last run summary
|
|
22
|
+
last validation output
|
|
23
|
+
last patch stats
|
|
24
|
+
last patch body, only when brassAgent.storePatchesInHistory is true
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This is editor-local state. It is not written to the repository and it is not
|
|
28
|
+
owned by `src/core` or `src/agent`.
|
|
29
|
+
|
|
30
|
+
The message history length is controlled by:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"brassAgent.chatHistoryLimit": 80
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Disable patch persistence with:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"brassAgent.storePatchesInHistory": false
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Follow-up context
|
|
47
|
+
|
|
48
|
+
After a run, follow-up messages can use the previous run as context.
|
|
49
|
+
|
|
50
|
+
For example:
|
|
51
|
+
|
|
52
|
+
```txt
|
|
53
|
+
fix the failing tests
|
|
54
|
+
why did that fail?
|
|
55
|
+
try again but do not change the public API
|
|
56
|
+
explain the patch
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The extension composes the next agent goal with a compact context block that may
|
|
60
|
+
include:
|
|
61
|
+
|
|
62
|
+
```txt
|
|
63
|
+
previous goal
|
|
64
|
+
previous status
|
|
65
|
+
previous summary/error
|
|
66
|
+
latest validation command output
|
|
67
|
+
last patch stats
|
|
68
|
+
last patch diff, only for explicit explain-last style requests
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The agent is instructed to ignore previous context if the new request is
|
|
72
|
+
unrelated.
|
|
73
|
+
|
|
74
|
+
## Slash commands
|
|
75
|
+
|
|
76
|
+
The chat supports slash commands to avoid menus and flags:
|
|
77
|
+
|
|
78
|
+
```txt
|
|
79
|
+
/inspect
|
|
80
|
+
/fix-tests
|
|
81
|
+
/typecheck
|
|
82
|
+
/lint
|
|
83
|
+
/ask <question>
|
|
84
|
+
/propose <task>
|
|
85
|
+
/apply <task>
|
|
86
|
+
/explain-last
|
|
87
|
+
/apply-last
|
|
88
|
+
/rollback-last
|
|
89
|
+
/doctor
|
|
90
|
+
/output
|
|
91
|
+
/clear
|
|
92
|
+
/help
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Safety behavior
|
|
96
|
+
|
|
97
|
+
`/apply <task>` still uses the safe apply-preview flow:
|
|
98
|
+
|
|
99
|
+
```txt
|
|
100
|
+
chat request
|
|
101
|
+
-> propose run
|
|
102
|
+
-> patch preview
|
|
103
|
+
-> user approval
|
|
104
|
+
-> brass-agent --apply-patch-file <exact diff>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`/apply-last` reopens the last patch preview. It does not silently write.
|
|
108
|
+
|
|
109
|
+
`/rollback-last` calls the CLI rollback path:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
brass-agent --rollback-patch-file <temp.diff> --yes ...
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
It asks for VS Code confirmation first, and the CLI still goes through the normal
|
|
116
|
+
patch rollback service.
|
|
117
|
+
|
|
118
|
+
## Quick actions
|
|
119
|
+
|
|
120
|
+
Assistant messages can include buttons such as:
|
|
121
|
+
|
|
122
|
+
```txt
|
|
123
|
+
Open patch preview
|
|
124
|
+
Explain last
|
|
125
|
+
Rollback last
|
|
126
|
+
Show output
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
These buttons send slash commands back through the same chat handler.
|
|
130
|
+
|
|
131
|
+
## Boundary
|
|
132
|
+
|
|
133
|
+
The boundary remains unchanged:
|
|
134
|
+
|
|
135
|
+
```txt
|
|
136
|
+
src/core
|
|
137
|
+
↑
|
|
138
|
+
src/agent
|
|
139
|
+
↑
|
|
140
|
+
brass-agent CLI protocol
|
|
141
|
+
↑
|
|
142
|
+
VS Code chat session UI
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The extension owns conversation memory and UX. The agent owns execution,
|
|
146
|
+
permissions, validation, redaction, patch application, rollback, and protocol
|
|
147
|
+
semantics.
|
|
148
|
+
|
|
149
|
+
## Explain last behavior
|
|
150
|
+
|
|
151
|
+
`/explain-last` is intentionally local and deterministic. It summarizes the last
|
|
152
|
+
stored run from VS Code workspace state instead of launching a new agent run.
|
|
153
|
+
|
|
154
|
+
That keeps the button useful even when the previous run stopped before the LLM
|
|
155
|
+
step, for example because a context file disappeared or a tool returned `FsError`.
|
|
156
|
+
For an AI follow-up using the same context, use:
|
|
157
|
+
|
|
158
|
+
```txt
|
|
159
|
+
/ask why did that fail?
|
|
160
|
+
```
|