Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
3a07b3c
add post demo refactor re-assessments
lunelson Sep 21, 2026
4f28d7e
Route Brunch through canonical Petrinaut tools
lunelson Sep 21, 2026
f1950ac
Verify canonical Petrinaut tool schema carriage
lunelson Sep 21, 2026
ad0e93b
Add matched Petrinaut assistant evaluation
lunelson Sep 21, 2026
1563459
Wait for the Petrinaut welcome tour in parity runs
lunelson Sep 21, 2026
615f771
Reject unavailable parity models before launch
lunelson Sep 21, 2026
0b99032
Allow supported models longer reasoning pauses
lunelson Sep 21, 2026
f3f2937
Resume verified matched evaluation arms
lunelson Sep 21, 2026
dccac8b
Wait for browser tool continuations in persona runs
lunelson Sep 21, 2026
7062f00
Wait for correlated browser results in persona runs
lunelson Sep 21, 2026
3830235
Report browser failures from matched evaluations
lunelson Sep 21, 2026
1de7979
Bound Brunch client-result identities
lunelson Sep 21, 2026
14b3777
Remove legacy Petrinaut browser tooling
lunelson Sep 21, 2026
8bf40fc
Record Petrinaut tooling remediation plan
lunelson Sep 22, 2026
510bcad
Record Petrinaut implementation topology
lunelson Sep 22, 2026
e7d43db
Restore integrated Brunch Petrinaut tooling
lunelson Sep 22, 2026
c42be85
Compare integrated Petrinaut construction interfaces
lunelson Sep 22, 2026
eb09384
Keep Brunch server modules out of browser builds
lunelson Sep 22, 2026
d898b40
Keep live Petrinaut calls outside replay baselines
lunelson Sep 22, 2026
879f7c0
Accept contextual browser mutation results
lunelson Sep 22, 2026
2562db2
Require host mutation records only for recorded canonical names
lunelson Sep 22, 2026
51c9b36
Scope host mutation records to root-level canonical inputs
lunelson Sep 22, 2026
c4d4c01
Record diagnosable failures for matched evaluation arms
lunelson Sep 22, 2026
13a46a6
Route chat sends through the latest host transport
lunelson Sep 22, 2026
444df6e
Resume evaluation arms after diagnosable failures
lunelson Sep 22, 2026
08f1175
Restore Petrinaut Labs and Voice controls in Brunch
lunelson Sep 23, 2026
efc65a6
Restore reviewed Petrinaut experiment drafting in Brunch
lunelson Sep 23, 2026
2644634
Trace canonical scenario and metric changes through Brunch
lunelson Sep 23, 2026
31d81e5
Document unrecorded scenario and metric evidence scope
lunelson Sep 23, 2026
da440d2
Align Brunch experiment guidance with mounted canonical tools
lunelson Sep 23, 2026
0544622
Verify canonical and draft experiment visibility
lunelson Sep 23, 2026
df123f1
Verify reviewed experiment draft plugin mounting
lunelson Sep 23, 2026
4a6efff
Prove reviewed experiment drafts across the browser boundary
lunelson Sep 23, 2026
9ea7802
Trace all canonical scenario and metric changes without causal claims
lunelson Sep 23, 2026
0c26dc4
Keep canonical mutation records through repository settlement renders
lunelson Sep 23, 2026
33430f0
Verify direct experiments through the browser and Ledger
lunelson Sep 23, 2026
8b26d22
Exercise Stock-over-Flue through the browser transport
lunelson Sep 23, 2026
188dbb8
Exercise declared projection before canonical browser construction
lunelson Sep 23, 2026
6f2010d
Preserve deep construction authority across UI input copies
lunelson Sep 23, 2026
2de37fc
Exercise canonical compiler feedback in integrated Brunch
lunelson Sep 23, 2026
0961cd7
Record Petrinaut restack evidence and manual review handoff
lunelson Sep 23, 2026
a948ba8
Route integrated browser tools through verified in-band results
lunelson Sep 23, 2026
a55c204
Keep Brunch instrumentation replaceable across dev-server reloads
lunelson Sep 24, 2026
25f31ad
Default local Brunch development to GPT-5.6 with low reasoning
lunelson Sep 24, 2026
a3dcaca
Release worked-model net writes without a compiler-unsupported try/fi…
lunelson Sep 24, 2026
a12b7cc
Record content-free request and response shapes in Brunch turn chrono…
lunelson Sep 24, 2026
ff76146
Suspend stale-net prompting in integrated Brunch
lunelson Sep 24, 2026
b21cf3d
Stop refusing browser calls after an unverifiable mutation record
lunelson Sep 24, 2026
041a9a2
Package Brunch skills natively through Flue and load Brunch packages …
lunelson Sep 24, 2026
622095f
Clear outstanding lint findings in Brunch and website code
lunelson Sep 24, 2026
2bbc13e
Port the worked-model projection tracer to integrated Brunch tools
lunelson Sep 24, 2026
4498ceb
Run every Petrinaut assistant on one default model: GPT-6 Luna at xhigh
lunelson Sep 24, 2026
5f3ef2d
Rename the dev source export condition to @dev/source and document it
lunelson Sep 24, 2026
4965a08
Delete construction variants A, B, batched and validated, and attribu…
lunelson Sep 24, 2026
5a97856
Split each Brunch package into a main entry and a Flue-only entry, an…
lunelson Sep 24, 2026
8d9ca2a
Define Brunch's named constants in one file
lunelson Sep 24, 2026
24905a2
Carry FE-1778's Voice defaults into the restored Brunch Labs controls
lunelson Sep 24, 2026
b4416f4
Build Brunch core before the transport's unit tests
lunelson Sep 24, 2026
daa62eb
Keep reasoning settings with the model that overrides them
lunelson Sep 24, 2026
dafa0ef
Credit batched arc deletions to the deleted arc
lunelson Sep 24, 2026
20eaaeb
Match only exact placeholder titles in matched-parity summaries
lunelson Sep 24, 2026
9151581
Restore the admission-controls suite on the remaining assistant modes
lunelson Sep 24, 2026
0e879f5
Remove dead Brunch exports and narrow package and app surfaces
lunelson Sep 25, 2026
d7908d5
Remove unmounted Brunch plugins, the matched-parity evaluator and the…
lunelson Sep 25, 2026
d820fef
Drop unused Brunch dependencies and declare the website's test depend…
lunelson Sep 25, 2026
86cb837
Keep test-only helpers out of Brunch package entry points
lunelson Sep 25, 2026
6da1faf
Consolidate duplicated Brunch build config, browser-call handling and…
lunelson Sep 25, 2026
4b4367f
Add a Brunch-scoped knip and fallow reduction analysis script
lunelson Sep 25, 2026
5738654
Trim Brunch integration tests, run them on OpenAI and make browser wi…
lunelson Sep 25, 2026
7377b0b
Trim website Brunch integration tests and name files after the suite …
lunelson Sep 25, 2026
529eaf3
Remove the abandoned worked-model feature and tighten the remaining B…
lunelson Sep 25, 2026
7e45eec
Move the shared Brunch library build config into the core package so …
lunelson Sep 25, 2026
4801168
Let query_workpiece share proposals except with its net read, refuse …
lunelson Sep 25, 2026
f514329
Delete Brunch's Stock-over-Flue evaluation mode and its awaiting-clie…
lunelson Sep 25, 2026
ba092d2
Settle the experiment draft in band like the canonical browser tools …
lunelson Sep 25, 2026
3ce81b2
Remove the two-call client-tool path and derive browser tool effects …
lunelson Sep 25, 2026
be01908
Let an experiment draft follow a net read without a settled Ledger
lunelson Sep 25, 2026
6b606e2
Drop Ledger coupling, stale mode labels and Stock repeats from Brunch…
lunelson Sep 25, 2026
c06d028
Remove Brunch's conversation modes and bind by document alone
lunelson Sep 28, 2026
e5f4f17
Choose the live document handle during render instead of in an effect
lunelson Sep 28, 2026
841ce20
Clear another document's save failure during render
lunelson Sep 28, 2026
7ee153b
Stop the agent render from flagging browser tools in the admission scope
lunelson Sep 28, 2026
0c0010c
Restore the always-on per-answer net disposition in Brunch's modellin…
lunelson Sep 28, 2026
5379347
Add GPT-6 Sol to Brunch's OpenAI model catalogue
lunelson Sep 28, 2026
eab5ee0
Stop refusing a draft proposed beside a Ledger settlement
lunelson Sep 28, 2026
95cffd0
Stop forcing reasoning mode on the Stock route
lunelson Sep 28, 2026
91d6abe
Tell the model a stopped or expired non-mutating browser call left th…
lunelson Sep 28, 2026
47d9df2
Claim an in-band browser call when its document-lane turn starts
lunelson Sep 28, 2026
7015b11
Claim the experiment draft's call before preparing it, and drop the r…
lunelson Sep 28, 2026
e6aa16d
Record the Petrinaut exports this branch adds in their changesets
lunelson Sep 28, 2026
467c909
Keep queued browser calls claimable while the browser renews a call a…
lunelson Sep 28, 2026
452fd92
Keep the Brunch refactoring notes out of the repository
lunelson Sep 28, 2026
638a88c
Run Petrinaut assistants on GPT-5.5 at medium reasoning again
lunelson Sep 29, 2026
b3d0ac4
Narrow Petrinaut's in-band tool boundary to has and run
lunelson Sep 29, 2026
2bec53e
Return a recorded diagnostics result instead of reading live diagnost…
lunelson Sep 29, 2026
0e6321a
Credit no element with a layout change
lunelson Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .changeset/brunch-in-band-browser-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashintel/petrinaut": patch
---

Allow a host to run named AI tool calls and return their results itself while the assistant response is still streaming, through `aiAssistant.inBandBrowserTools: { has(toolName), run(call, execute) }`: Petrinaut calls `run` when the call's turn in same-document order starts, with a `signal` that aborts on Stop, and the host calls `execute(input)` at most once and reports the resolved output or the failure; stock hosts retain their existing tool path. `executePetrinautAiMutation` lets a host run one canonical AI edit with the assistant's own no-op detection and output.
5 changes: 5 additions & 0 deletions .changeset/petrinaut-ai-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashintel/petrinaut-core": patch
---

`petrinautAiModel` names the model and reasoning effort Petrinaut assistants run by default: `gpt-5.5-2026-04-23` at `medium`. `@hashintel/petrinaut-core/ai` also exports the stock prompt's behavioural frame and capability guidance separately, as `petrinautAiStockBehavioralFrame` and `petrinautAiCapabilityGuidance`, and composes `petrinautAiPrompt` from them.
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ The compose stack and the graph take these, so a new dev server stays off them a
| 8200 | Vault | `HASH_VAULT_PORT` |
| 9000, 9001 | MinIO API and console | |

The Brunch agent's `start` and `start:test` scripts and its production image listen on 3002, where the integration tests expect it; the dev pair uses 4321 and 4915.
The Brunch agent's `start` script and its production image listen on 3002; the dev pair uses 4321 and 4915.

### Starting Services

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ For Anthropic schema acceptance after a tool, schema, or adapter change, run `ya

Add `--openai` to `yarn workspace @apps/brunch-agent test:persona` for the same proof through the registered OpenAI provider at low effort. The native Responses serializer and SSE parser remain real; only HTTP responses are synthetic. Each request checks the mounted tools' schemas/descriptions, `strict: false`, model and effort; captured `openai-requests.json` includes browser-result history. Passing is synthetic wiring evidence, not OpenAI server acceptance or a live-model result.

The construction proof holds the recording pause and checks that no submission occurs before release. `test/persona-extension-lifecycle.test.ts`, enabled with `PI_PERSONA_CLI=$(command -v pi)`, crosses the installed Pi's flag hydration and tool-registration boundary with a synthetic socket reply and no inference. After building Brunch, `node --experimental-strip-types test/provider-accounting.integration.ts --disabled` checks that native requests proceed with an unusable historical ledger, preserve it untouched and retain usage in the original database. These checks do not prove live-model fidelity or successful generation with the operator's credential.
The construction proof holds the recording pause and checks that no submission occurs before release. `test/persona-extension-lifecycle.test.ts`, enabled with `PI_PERSONA_CLI=$(command -v pi)`, crosses the installed Pi's flag hydration and tool-registration boundary with a synthetic socket reply and no inference. These checks do not prove live-model fidelity or successful generation with the operator's credential.

From the HASH root, build and run the synthetic browser proof:

Expand Down
36 changes: 22 additions & 14 deletions apps/brunch-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

## Run the Petrinaut panel locally

From the repository root, make `ANTHROPIC_API_KEY` available in the environment and run:
Brunch and the stock chat route both run `petrinautAiModel` from `@hashintel/petrinaut-core` unless a deployment overrides it (`BRUNCH_CHAT_MODEL` and `BRUNCH_CHAT_THINKING` for Brunch, `PETRINAUT_AI_MODEL` and `PETRINAUT_AI_REASONING_EFFORT` for the stock route). An overriding `BRUNCH_CHAT_MODEL` runs without a thinking level unless `BRUNCH_CHAT_THINKING` sets one. From the repository root, make `OPENAI_API_KEY` available and run:

```sh
yarn dev:brunch
```

The first step builds the Petrinaut libraries the panel imports (`dist/` and design-system codegen). Then it starts the Brunch server at `http://127.0.0.1:4321` and the real Petrinaut website at `http://127.0.0.1:4915`. The website proxies `/agents/chat/*` to Brunch without changing the request origin or Flue protocol. The typed panel and Voice mode talk to one Flue chat agent composed from the context-independent core prompt in `@hashintel/brunch-agent/flue`, the SDCPN/Petrinaut instructions, modelling runbook skill, SDCPN plugin tools in `@hashintel/brunch-agent-plugin-sdcpn`, and app-owned deployment material.
The first step builds the Petrinaut libraries the panel imports (`dist/` and design-system codegen). Then it starts the Brunch server at `http://127.0.0.1:4321` and the real Petrinaut website at `http://127.0.0.1:4915`. The website proxies `/agents/chat/*` to Brunch without changing the request origin or Flue protocol. Local development loads `apps/brunch-agent/.env.development`, selecting `openai/gpt-5.6-sol` with low reasoning by default, like the persona launcher. An explicit process environment or app-local `.env.local` can override these values; deployment model settings are separate and not established by this dev default. A configured credential does not authorize a paid run. When Brunch is selected, the typed panel and Voice mode bind the conversation to the open document: Brunch composes its prompt, SDCPN skill, elicitation, Ledger, document-revision attribution, and explanation with Petrinaut-owned capability guidance and the complete canonical `petrinautAiTools` catalogue. Petrinaut retains canonical schemas, execution, and model-visible outputs.

The ordinary browser tools are `read_petrinaut_docs`, `read_petrinaut_net`, `read_petrinaut_diagnostics`, `mutate_petrinaut_net` (one ordered batch that adds, removes, or edits existing parts of the root net by ID), and `layout_petrinaut_net`, whose browser result carries a separately recorded `layoutRecord` of observed pre/post hashes and position effects. The [tool catalogue](src/agents/chat-agent/tool-catalogue.ts) records the mounted names and their definition/execution owners. The skill is activated via `activate_skill`, with supporting resources disclosed via `read_skill_resource`; the app-owned deployment diagnostic is `ping`. There is no generalized elicitation loop, sweep tool, or `brunch_ask` on this path. Brunch settles workpiece revisions through the server-side `mutate_workpiece` tool into Flue persistent state and retrieves them with `read_workpiece`; evidence exports are derived from the retained records, not a separate authoritative capture store.
Native Stock remains a separate assistant choice; `VITE_PETRINAUT_DEFAULT_ASSISTANT` selects native Stock or Brunch.

For browser-visible persona testing, use the [persona launcher and operator guide](.pi/extensions/brunch-persona-testing/README.md):

Expand All @@ -19,19 +19,27 @@ yarn brunch:persona --list-cases
yarn brunch:persona --case inventory-purchasing
```

The launcher opens a dedicated Chrome window, pauses for recording readiness, then drives the real panel with a private Pi persona. Brunch's own tool calls update the visible net and workpiece. Select any listed case or a directory containing `situation-pack.md` and `opening-message.md`. There is no automatic budget cutoff; native usage is retained. The guide owns prerequisites, stop/resume and evidence instructions; consult it before paid execution.
The launcher opens a dedicated Chrome window, pauses for recording readiness, then drives the real panel with a private Pi persona. Petrinaut's stock tool calls update the visible net. Select any listed case or a directory containing `situation-pack.md` and `opening-message.md`. There is no automatic budget cutoff; native usage is retained. The guide owns prerequisites, stop/resume and evidence instructions; consult it before paid execution.

By default outside production, conversations persist in SQLite at `apps/brunch-agent/.data-wipe-me/conversations.db`. `BRUNCH_DEV_DB_PATH` overrides that local path. The hermetic browser-transport test uses `BRUNCH_CHAT_DB_PATH` to point at its own sqlite file. Flue history is the conversation log. The panel rehydrates from the SDK's canonical conversation observation and does not resubmit or replay settled turns.
By default outside production, conversations persist in SQLite at `apps/brunch-agent/.data-wipe-me/conversations.db`. `BRUNCH_DEV_DB_PATH` overrides that local path. Flue history is the conversation log. The panel rehydrates from the SDK's canonical conversation observation and does not resubmit or replay settled turns.

The mounted Flue URL `/agents/chat/:instanceId` requires the principal and logical conversation identity in `x-brunch-principal` and `x-brunch-conversation`. The path id is the hash of those values, not a bearer token or trusted authentication.

Provider admission bounds a dispatch with no model event at 60 seconds and bounds both newly opened and active reasoning silence at 120 seconds. These phase-specific limits tolerate supported reasoning models that legitimately pause for tens of seconds: an observed valid continuation exceeded the former 15-second first-reasoning-delta limit, then its sole retry exceeded the former 10-second between-delta limit. On expiry Brunch cancels the invocation, requires cancellation acknowledgement within two seconds, and permits at most one retry only before any tool call completed; completed tool work is never replayed. Tests may shorten these bounds with `BRUNCH_MODEL_STREAM_FIRST_EVENT_TIMEOUT_MS`, `BRUNCH_MODEL_STREAM_REASONING_START_TIMEOUT_MS`, `BRUNCH_MODEL_STREAM_IDLE_TIMEOUT_MS`, and `BRUNCH_MODEL_STREAM_CANCELLATION_TIMEOUT_MS`; non-test deployments always use the production policy.

Print a human-readable transcript of one conversation from that same Flue history (server already running):

```sh
yarn workspace @apps/brunch-agent transcript -- --principal <key> --id <conversationId>
```

## Local Postgres for fixture-producing development
## Tests

Neither `test:unit` nor `test:integration` needs anything running. `test:integration` checks the built app, starting it as a server and loading it in process with scripted OpenAI responses on the default model.

The `test:manual:*` scripts are not part of either suite and do not run in CI. `test:manual:browser` builds the website and drives it in the local macOS Chrome against the built app.

## Local Postgres

Set `BRUNCH_DB_KIND=postgres` explicitly to use the existing Postgres adapter and migrations locally. An unset selector defaults to SQLite outside production; `BRUNCH_DB_KIND=sqlite` also selects that lightweight path. Production always requires Postgres (selector unset or `postgres`), and rejects `sqlite`. Selector values are exact and case-sensitive; blank or unknown values fail.

Expand Down Expand Up @@ -130,7 +138,7 @@ Petrinaut `/api/chat` stays on the website; the accepted later website path is `
Releasing `/agents/*` to production browser ingress requires separate authentication,
authorization, ingress, and rate/spend gates. CORS, caller-supplied principals, and conversation
hashes are not authentication. Desired count remains one until same-conversation ownership
across replicas is separately proven.
across replicas is separately proven. The direct browser-result handoff is ephemeral in that single owner: its one-use issued-call capability and existing conversation ownership headers do not authenticate a user or route callbacks across replicas. A lost result after a possible document effect is unknown; Stop aborts an active wait, while silent browser disappearance is detected only after the renewable 25-second lease expires. Production release still requires the external ingress authentication, authorization, routing and spend gates described above.

The deployed chat path stores Flue conversations, submissions, compaction records, attachments,
claims, leases, and settlement state in Postgres.
Expand All @@ -155,12 +163,12 @@ against this branch's image until a Mission 8 successor retargets it to `/agents

Voice is a second input modality over the panel's conversation. It is not a Voice route and does not own provider audio or durable conversation state.

| | |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| URL | `/agents/chat/:instanceId`, called through the public Flue browser client and the same-origin local proxy |
| Identity | `x-brunch-principal` plus `x-brunch-conversation`; the server verifies that their hash matches the mounted instance id |
| Initial turn | One `FlueClient.send()` carrying `{ kind: "user", body }` |
| Client-tool follow-up | One `FlueClient.send()` carrying the `client-tool-result` signal for completed client-tool parts, correlated by `toolCallId` |
| Response | `FlueClient.wait()` chunks projected into one finite AI SDK UI-message stream; observation/history provides canonical rehydration |
| | |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| URL | `/agents/chat/:instanceId`, called through the public Flue browser client and the same-origin local proxy |
| Identity | `x-brunch-principal` plus `x-brunch-conversation`; the server verifies that their hash matches the mounted instance id |
| Initial turn | One `FlueClient.send()` carrying `{ kind: "user", body }` |
| Browser tools | A document-bound conversation awaits browser results over HTTP within the server tool call; no follow-up submission is sent |
| Response | `FlueClient.wait()` chunks projected into one finite AI SDK UI-message stream; observation/history provides canonical rehydration |

Typed and finalized spoken turns use this same route. The panel's explicit **Stop** requests a conversation-wide Flue abort before cancelling its local stream. Local Voice interruption stops playback only and leaves canonical history unchanged.
26 changes: 0 additions & 26 deletions apps/brunch-agent/docs/task-dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,32 +235,6 @@
"dependsOn": [],
"cache": false
},
"start:test": {
"dependsOn": [
"build"
],
"cache": false,
"persistent": true,
"affectedBy": [
"error-stack",
"error-stack-macros",
"harpc-types",
"harpc-wire-protocol",
"hash-codec",
"hash-codegen",
"hash-graph-api",
"hash-graph-authorization",
"hash-graph-store",
"hash-graph-temporal-versioning",
"hash-graph-types",
"hash-temporal-client",
"type-system"
]
},
"start:test:healthcheck": {
"dependsOn": [],
"cache": false
},
"test:docker": {
"dependsOn": [
"build:docker"
Expand Down
13 changes: 1 addition & 12 deletions apps/brunch-agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"build:docker": "docker buildx build --tag brunch-agent --file docker/Dockerfile ../../ --load",
"dev": "vite dev",
"fix:eslint": "oxlint --fix --type-aware --type-check --report-unused-disable-directives-severity=error .",
"fixture:worked-model": "node --experimental-strip-types src/evaluations/persona/create-worked-model-fixture.ts",
"lint:eslint": "oxlint --type-aware --type-check --report-unused-disable-directives-severity=error .",
"lint:tsc": "tsgo --noEmit",
"measure:context-replay": "node --experimental-strip-types src/diagnostics/context-replay-measurement.ts",
Expand All @@ -21,19 +20,10 @@
"smoke:deployment": "node --experimental-strip-types src/deployment-smoke.ts",
"start": "PORT=3002 node dist/server.mjs",
"start:healthcheck": "wait-on --timeout 1200000 http-get://localhost:3002/health",
"start:test": "NODE_ENV=test PORT=3002 node dist/server.mjs",
"start:test:healthcheck": "wait-on --timeout 600000 http-get://localhost:3002/health",
"test:anthropic-tools": "turbo run build --filter '@apps/brunch-agent...' && node --experimental-strip-types test/anthropic-tool-preflight.ts",
"test:compiler-feedback": "VITE_BRUNCH_CHAT_ENDPOINT=/agents/chat VITE_PETRINAUT_DEFAULT_ASSISTANT=brunch turbo run build --filter '@apps/brunch-agent...' --filter '@apps/petrinaut-website...' --env-mode=loose && node --experimental-strip-types test/compiler-feedback.integration.ts",
"test:docker": "node --experimental-strip-types test/container-smoke.ts",
"test:integration": "vitest run --config vitest.integration.config.ts",
"test:native-schema": "node --experimental-strip-types test/integration/native-schema-carriage.integration.ts",
"test:passage-policy": "node --experimental-strip-types test/passage-policy.integration.ts",
"test:persona": "VITE_BRUNCH_CHAT_ENDPOINT=/agents/chat VITE_PETRINAUT_DEFAULT_ASSISTANT=brunch turbo run build --filter '@apps/brunch-agent...' --filter '@apps/petrinaut-website...' --env-mode=loose && env -u BRUNCH_STEP_A_ACCOUNTING -u HASH_OTLP_ENDPOINT node --experimental-transform-types test/persona-construction.integration.ts",
"test:manual:browser": "VITE_BRUNCH_CHAT_ENDPOINT=/agents/chat VITE_PETRINAUT_DEFAULT_ASSISTANT=brunch turbo run build --filter '@apps/brunch-agent...' --filter '@apps/petrinaut-website...' --env-mode=loose && node --experimental-strip-types test/browser-witness/petrinaut-panel.ts",
"test:unit": "vitest run --config vitest.config.ts",
"test:worked-model-bundle-copy": "vitest run --config vitest.config.ts --reporter=verbose test/worked-model-bundle-copy.contract.test.ts",
"test:worked-model-net-projection": "VITE_BRUNCH_CHAT_ENDPOINT=/agents/chat turbo run build --filter '@apps/brunch-agent...' --filter '@apps/petrinaut-website...' --env-mode=loose && node --experimental-strip-types test/worked-model-net-projection.integration.ts",
"test:workpiece-evidence": "node --experimental-strip-types test/workpiece-evidence.integration.ts",
"transcript": "node --experimental-strip-types src/diagnostics/transcript-cli.ts"
},
"dependencies": {
Expand All @@ -57,7 +47,6 @@
"valibot": "1.4.2"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.74.0",
"@earendil-works/pi-tui": "0.84.3",
"@flue/vite": "2.0.3",
"@playwright/test": "1.58.2",
Expand Down
6 changes: 4 additions & 2 deletions apps/brunch-agent/petrinaut-local.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
type UserConfig,
} from "vite";

import { brunchEnv } from "@hashintel/brunch-agent/constants";

import {
defaultChatOrigin,
petrinautLocalServer,
Expand Down Expand Up @@ -43,7 +45,7 @@ export default defineConfig(async (environment) => {
throw new Error("PETRINAUT_WEBSITE_ROOT is required.");
}
const root = resolve(websiteRoot);
process.env.VITE_BRUNCH_CHAT_ENDPOINT ??= "/agents/chat";
process.env[brunchEnv.viteChatEndpoint] ??= "/agents/chat";
process.env.VITE_PETRINAUT_DEFAULT_ASSISTANT ??= "brunch";
// Babel resolves the React compiler plugin from the launched project's cwd,
// not from the imported config file. Match a native hash launch before the
Expand All @@ -57,7 +59,7 @@ export default defineConfig(async (environment) => {
if (!loaded)
throw new Error(`Could not load Petrinaut's Vite config from ${root}.`);

const chatOrigin = process.env.BRUNCH_CHAT_ORIGIN ?? defaultChatOrigin;
const chatOrigin = process.env[brunchEnv.chatOrigin] ?? defaultChatOrigin;
return mergePetrinautPanelConfig({
chatOrigin,
loadedConfig: loaded.config,
Expand Down
Loading
Loading