import type { CreateAgentExactProcessEnvironmentInput } from "@tangle-network/agent-interface/environment-provider"; import type { TangleExactProcessOptions } from "./tangle-types.js"; export declare const MAX_EXACT_FILE_BYTES: number; export declare const MAX_LIST_RESULTS = 100000; /** Sandbox caps list responses at 1,000 resources. */ export declare const SANDBOX_LIST_PAGE_SIZE = 1000; export declare const MAX_IDENTIFIER_LENGTH = 512; export declare const MAX_STRING_LENGTH = 16384; /** * MAX_STRING_LENGTH governs CONTROL-PLANE text — names, identifiers, env values, metadata — where * 16 KiB is already generous. It must not govern DATA. The contents of file mounts and of inline * profile resources are the product's cargo, and one bound for both refused a 17,894-character * script AFTER spawn_worker had returned a worker id, so the caller paid for the spawn and got a * child it could not equip (agent-sdk#340). * * Payload is measured in BYTES. `String.length` counts UTF-16 code units, so a CJK file reads a * third of its UTF-8 weight and an emoji half of it; every byte budget between here and the * sandbox counts UTF-8, so this one does too. * * 4 MiB is agent-runtime's SPAWN_RESOURCE_PATH_MAX_BYTES (0.239.0) — the largest file the runtime * will read off a manager's own disk for a by-path spawn resource. Those resolved bytes arrive * here as an inline string, so a smaller number would refuse by-path mounts the runtime had * already accepted, and a larger one would advertise what the runtime will not resolve. * * The transport carries it: @tangle-network/sandbox splits inline `resources.files` out of the * create POST and materializes them afterwards, routing any mount that no longer fits a * gateway-safe single-shot write — SANDBOX_PROXY_REQUEST_MAX_BYTES (1 MiB) less 8 KiB of request * envelope — onto chunked upload, whose session ceiling is 64 MiB. A 4 MiB mount is delivered in * parts, so the 1 MiB request budget on `files/write-batch` never bites. */ export declare const MAX_PAYLOAD_STRING_BYTES: number; /** * Inline `tools`, `agents`, `commands` and `instructions` are NOT split out: they ride the create * POST whole, and inline `skills` ride the one-shot profile-priming POST. Both are single request * bodies under the gateway's 1 MiB cap, so their TOTAL is the bound that binds, and it is the same * budget the sandbox client keeps for a single-shot write: 1 MiB less 8 KiB of envelope. Necessary * rather than sufficient — the rest of the create body shares that request and the gateway stays * the authority — so a resource too large for it belongs in `resources.files`. * * `commands` is bounded here as payload although agent-runtime's by-path resolver covers only * `tools`, `skills`, `agents` and `files`. The request that carries a command resource is the one * that carries the others, and leaving `commands` on the control-plane bound would refuse an 18 KiB * command for no transport reason. Anything the resolver gains later needs no change here. */ export declare const MAX_INLINE_PAYLOAD_BYTES: number; /** * A per-string bound multiplies: MAX_ARRAY_LENGTH mounts at MAX_PAYLOAD_STRING_BYTES is 4 GiB, and * `create` structuredClones and deep-freezes the whole input before the client sees it. The * aggregate stops at the 64 MiB this module already accepts for one exact-process file, which is * also the sandbox's chunked-upload session ceiling. */ export declare const MAX_TOTAL_PAYLOAD_BYTES: number; export declare const MAX_ARRAY_LENGTH = 1024; export declare const MAX_MAP_ENTRIES = 256; export declare const MAX_JSON_DEPTH = 16; export declare const MAX_JSON_NODES = 8192; export declare function boundedIdentifier(value: unknown, label: string): string; export declare function boundedString(value: unknown, label: string): string; /** * The rule a value broke. Only the rules that COUNT something carry a limit; the rest are shape * rejections, where nothing is oversized and saying so misdirects the reader. */ export type JsonBoundRule = "string" | "payload" | "inlinePayload" | "totalPayload" | "array" | "entries" | "depth" | "nodes" | "key" | "undefined" | "number" | "type" | "cycle" | "prototype"; export interface JsonBoundViolation { readonly rule: JsonBoundRule; /** Object keys and array indices only. A path locates the value; it never carries one. */ readonly path: string; readonly observed?: number; readonly limit?: number; readonly limitName?: string; /** Position of the offending key among its object's own keys, for the `key` rule. */ readonly entry?: number; /** A JavaScript type or constructor name — program text, not payload. */ readonly observedType?: string; } /** * Where an AgentProfile sits inside the value being walked, as a key path from its root. * * Payload is classified by POSITION, never by a flag on the call: the same shape reached through * `metadata` is control-plane text and keeps MAX_STRING_LENGTH. Omit it and a value has no payload * at all, which is what every non-profile call site wants. */ export type ProfileLocation = readonly string[]; /** The value IS the profile — `assertBoundedJson(input.profile, ...)`. */ export declare const PROFILE_AT_ROOT: ProfileLocation; /** A wrapper whose `profile` key holds it — the per-turn backend override. */ export declare const PROFILE_AT_PROFILE: ProfileLocation; /** The mapped Sandbox create options, where it rides `backend.profile`. */ export declare const PROFILE_AT_BACKEND_PROFILE: ProfileLocation; /** * The first bound `value` breaks, in document order, or undefined when it breaks none. * * Document order matters: the walk is a LIFO stack, so children are pushed in reverse to make * `pop` yield the order a reader sees in the value. A reason that named whichever sibling the * stack happened to hold last would be a new way to mislead. Only the first violation is * reported — later ones may exist. */ export declare function firstJsonBoundViolation(value: unknown, profileAt?: ProfileLocation): JsonBoundViolation | undefined; export declare function isBoundedJson(value: unknown, profileAt?: ProfileLocation): boolean; /** * One line naming the rule, where it broke, what was measured, and the limit — and never the * value. Profile and metadata strings carry prompt text, mounted briefs, and through `env`, * `mcp.*.env` and `headers` material adjacent to secrets, so no prefix, excerpt, or * length-preserving echo of a value belongs in a reason a journal keeps. */ export declare function describeJsonBoundViolation(violation: JsonBoundViolation): string; /** * `label` names WHICH field was rejected. agent-runtime's `errMessage` flattens a cause chain to * `name: message`, so without it a run record cannot say whether the rejected value was the * profile, the metadata, or a providerOptions map — which is how three children settled on five * words that identified nothing. */ /** * A value refused by a JSON bound, as an error a consumer can classify without reading text. * * Every refusal in this package was a plain `Error` with a message, and the runtime that * supervises these environments classifies a failed retained execution from the error's * STRUCTURE — class name, `code`, status — never its message, because this package's messages * are not a contract. So a bound refusal reached its journal under the one name reserved for an * execution nobody can observe, telling the operator to reconcile before retrying when nothing * had run and nothing needed reconciling (agent-runtime#1204, exhibit 6). * * `name` and `code` are stable; `message` stays the operator-facing line and may change. The * violation is carried whole so a reader can act on the rule and the path without parsing. */ export declare class JsonBoundError extends Error { readonly code: "JSON_BOUND_VIOLATION"; readonly label: string; readonly violation: JsonBoundViolation; constructor(label: string, violation: JsonBoundViolation, message: string); } export declare function assertBoundedJson(value: unknown, label?: string, profileAt?: ProfileLocation): void; /** Keep a late-created provider handle reachable when an abort wins the race. */ export declare function attachCleanupHandle(error: unknown, handle: unknown, cleanupError?: unknown): void; export declare function exactProcessRequestDigest(input: CreateAgentExactProcessEnvironmentInput, providerName: string, options: TangleExactProcessOptions): `sha256:${string}`; export declare function validateExactProcessCreateInput(input: CreateAgentExactProcessEnvironmentInput, providerName: string, options: TangleExactProcessOptions): void; export declare function awaitWithSignal(operation: Promise | T | undefined, signal?: AbortSignal): Promise; /** Await an operation and clean its result if abort wins before it resolves. */ export declare function awaitWithSignalAndCleanup(operation: () => Promise | T, signal: AbortSignal | undefined, cleanup: (value: T) => Promise | void): Promise; export declare function cloneJson(value: T, label?: string): T; export declare function safeIdentifier(value: unknown): string | undefined; export declare function safeString(value: unknown): string | undefined;