The assistant could not read a file the user attached: the bytes were gone after the request, the thread only held the file's name, and read_trip_file stays denied because it would send any document of the trip to the provider. A new server tool, read_attached_file, reads only the files attached in this conversation by this user; any other id is answered "No such attachment in this conversation.", whoever it belongs to. It is offered in a trip turn whose thread holds a file with text. The first read of a file is held as a change card that names the file and the model and host its text would go to; once the user agrees, the agreement is kept on the attachment and later reads run at once. The text reaches the model through the history and, for a later read, as a tool answer only the model gets (AgentToolRun.modelText): no message part, stream chunk, shared answer or client store ever carries it. The model is told each kept file's attachment id, and the standing instructions say to read the file when the user wants to work with it, to propose a booking found in it through create_reservation and then to offer keeping the file with it. The card's verb, its "Sent to" row and the step's name are new keys in all 27 locales.
@trek/shared
Single source of truth for TREK's API contracts, expressed as Zod schemas and consumed by both the server (request validation + inferred DTO types) and the client (typed requests/responses).
This package is part of the incremental NestJS + React 19 migration (see the "Brownfield Rewrite" board). It is intentionally dormant until modules start importing it — adding it changes nothing for users.
Rules
- One folder per domain:
src/<domain>/<domain>.schema.ts(+.spec.ts). - Domain-agnostic building blocks live in
src/common/. - A route is only considered migrated once its contract lives here.
- Schemas are the source of truth; server DTOs and client types are inferred from them
(
z.infer<typeof schema>), never hand-duplicated.
Consumption (dev)
Both apps resolve @trek/shared to this package's TypeScript source:
- Server (
tsx): viapathsinserver/tsconfig.json. - Client (
vite): viaresolve.aliasinclient/vite.config.ts(+pathsfor the type-checker).
Production packaging (Docker / workspace wiring) is introduced in card F2, when the server first depends on this package at runtime. Until then prod builds are untouched.
Not yet here
The canonical error envelope is finalised in card F5 (it must match TREK's current Express error responses byte-for-byte), so it is deliberately not invented in F1.