import type { RouteMeta } from "../route-meta.js"; import { fillRoutePath, type RoutePathParams } from "./route-path.js"; import type { ContractRoute } from "../routes.js"; import { runnerTranslatorPath } from "../doors/runner-protocol.js"; // Every route the daemon serves outside oRPC (streamed bytes, WebSocket upgrades, doors checking their own credential), // keyed `METHOD /path` in the order the daemon registers them: among overlapping ones the first registered answers. // `{param}` is one path segment, a trailing `/*` any further ones, `ALL` every method; the daemon serves no other. // A route that answers plain JSON has its input and answer schemas in raw-json-routes.ts, under the same key. export const RAW_ROUTES = { // The "is a daemon there" probe every flow uses; it names the sandbox and says whether it is still converging. "GET /health": { auth: "door", beforeBoot: true }, // A person opening this sandbox's own address in a browser: sent to the app's /open on it, the address being what // they may still hold when the platform has lost the rest. Anything else gets the same 401 as before it existed. "GET /": { auth: "door", beforeBoot: true }, // The tab icon a browser asks for on that address: the lotus in the sandbox green, the same bytes for everyone. "GET /favicon.ico": { auth: "door", beforeBoot: true }, "GET /diff/raw": { lane: "bulk" }, // Arming the dictation model is a read any tier makes; dictating is writing a message, the collaborator's grant. "GET /speech/status": { guest: true }, "POST /speech/prepare": { guest: true }, "POST /speech/transcribe": { floor: "collaborator", guest: true }, // A device claiming a wake word it heard (schemas/speech.ts): what it opens is a turn, so the collaborator's. "POST /speech/wake": { floor: "collaborator" }, // The live phrase stream (schemas/speech.ts): a WebSocket, so the query ticket, floored at the collaborator in the // handler like the transcribe it streams. "GET /speech/stream": { auth: "door" }, // Speaking (schemas/voice.ts): the voices to choose from is a read any tier makes; speech costs this box's CPU or // the owner's provider credits, so saying anything is the collaborator's, like dictating. The WebSocket floors its // query ticket in the handler; the HTTP door is Discord's calls and anything without a socket. "GET /speech/voices": { guest: true }, "POST /speech/say": { floor: "collaborator" }, "GET /speech/say": { auth: "door" }, // A conversation's recorded documents as bytes, for whoever owns it, a guest with no Files included; the route // serves those paths alone (the daemon's conversations/produced-files.ts). "GET /agents/{id}/documents/raw": { guest: true, lane: "bulk" }, // The bytes behind the workspace reads; each applies the caller's fence itself. "GET /workspace/raw": { guest: true, lane: "bulk" }, // No door, unlike media: the page fetches a thumbnail itself, so the request carries the header. "GET /workspace/thumb": { guest: true }, // Fetched by a