UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

96 lines • 4.62 kB
import type { CommandFnResult } from '../../../commands/config.ts'; import { type ByteSource, type CommandOutput } from '../../../io/types.ts'; import type { PathSpec, Producer } from '../../../types.ts'; import { type Files } from '../../files.ts'; /** * What a voice says for one failure: the bytes the handler printed before * it, the diagnostic line and the exit code. */ type Failure = [ByteSource | null, Uint8Array, number]; /** * How a caller words a handler that failed, before it answered or while its * output streamed. The runner is one for a mount command and a CLI leaf; the * wording is the caller's, and stays what each said before the two shared * it. Mirrors Python's `HandlerVoice`. */ export interface HandlerVoice { /** The failure as this caller words it. */ fail(err: unknown): Failure; /** * Whether a failure is not the command's to word and reaches the * workspace instead (a limit timeout answers 124 there). */ passes(err: unknown): boolean; /** * Whether output is pulled through `chunks`, which splits even a single * blob, so an answer in bytes streams too. */ splits: boolean; } export interface RunHandlerOpts { /** * Drops the caches a write past the dispatcher leaves stale; absent when * the handler writes nothing or only through the dispatcher. */ drop?: () => Promise<void>; /** * What the caller wraps an answer in before it is framed (a mount binds * its recorder and activity to the stream). */ scope?: (result: CommandOutput) => CommandOutput; /** The caller's abort, which stops waiting for the body. */ signal?: AbortSignal; /** * Called once the answer, its rows rendered, has settled, however the * caller left: a handler and its renderer may run past an abort, so a * caller keeps what they use (a CLI's client) until then. */ settle?: () => void; /** * The handler's files, whose session's hides filter the rows it hands * over; absent filters none. */ vfs?: Files | null; } /** * What a command given a glob past its mount's `walkLimit` says: exec(2)'s * refusal of an argument list too long, which bash reports with exit 126, then * the limit's own line. Mirrors Python's `argument_list_too_long`. */ export declare function argumentListTooLong(command: string, reason: string): Uint8Array; /** The voice of a command a mount runs; `paths` are the operands as typed. */ export declare function mountVoice(name: string, paths: readonly PathSpec[]): HandlerVoice; /** The voice of a CLI leaf, installed or on a mount. */ export declare function cliVoice(prog: string): HandlerVoice; /** * A leaf's answer, an empty one where it returned null. A mount command's * null declines, so its mount tries the next handler; a leaf's null is its * whole answer, an empty one. Mirrors Python's `answered`. */ export declare function answered(body: Promise<CommandFnResult>): Promise<CommandOutput>; /** * Run one handler body: a mount command's, or a CLI leaf's. * * The body runs until it answers or the caller's signal aborts (the line's * deadline among the reasons). Racing a promise does not stop its work, so * output the body hands back after its caller left is closed. * A usage error is the handler's own words and exit code; any other failure * is worded in the caller's voice, so the rest of the line keeps running. A * handler that may have written past the dispatcher drops caches afterwards, * whether it answered, failed (in its own words too), timed out or was * cancelled, again when a body (or the renderer of the rows it handed over) * still running past its abort settles, since its write may land then, and * again once an answer that streams has ended or * been closed, since a stream does its work as it is pulled. An answer * carries the producer the output limits resolve from and * has its stream framed so a failure while it streams is worded too; a * failure the runner framed carries no producer. Null is the handler * declining, which a mount's cascade reads as "try the next handler". * Rows a handler hands over in place of stdout (`IOResult.rows`) lose those * the session cannot see and are rendered here, inside the run, so this * is the one place a command's output meets the session's hides. * Mirrors Python's `run_handler`. */ export declare function runHandler(body: Promise<CommandFnResult>, name: string, producer: Producer, voice: HandlerVoice, opts?: RunHandlerOpts): Promise<CommandFnResult>; export {}; //# sourceMappingURL=handler.d.ts.map