/** * Local-file readiness for file arguments (`image_urls`, `url`, `*_url`). * * Agents batch tool calls in parallel, so `gsk understand_images -i * /home/user/workspace/x.png` routinely starts while a sibling tool call in * the same batch is still writing x.png. The old `fs.existsSync` gate then * classified the path as "not a local file" and shipped the raw filesystem * path to the backend, where it failed AI Drive resolution as an opaque * "Unable to process image URL" — silently disabling the agent's visual * self-check (~10.9k failures / 5.4k users over the 7 days before this fix). * * gsk is an npm package that runs on arbitrary machines (sandboxes, developer * laptops, OpenClaw VMs, desktops), and AI Drive folder names are user-chosen, * so NO path shape or prefix list can tell a local file from a server-side * path. The classifier therefore only uses real filesystem evidence from the * machine it is running on: * * - The file exists (or the value is a relative path the backend cannot * interpret) → the CLI owns it: wait for the write to stabilize, upload, * and fail loudly if it never becomes readable. * - The file is missing but its parent directory exists locally → the one * place a same-batch sibling write can land, so wait for the race window; * upload if it appears, otherwise pass through for server-side resolution. * - No local evidence at all → pass through unchanged with zero added * latency; only the backend can tell an AI Drive path from a typo, and its * failure mode is a per-URL actionable error. */ export type FileArgKind = /** URI scheme (http, https, aidrive, ...) or /api/ wrapper — pass through. */ 'remote' /** Absolute path with no local filesystem evidence — the backend resolves * it against the user's AI Drive; only that side can tell if it exists. */ | 'aidrive' /** Positive filesystem evidence (exists, or relative form) — the CLI owns * resolution and uploads it. */ | 'local' /** Missing file whose parent directory exists on this machine: the one * place a same-batch sibling write can land. Wait for the race window, * then defer to the backend instead of failing locally. */ | 'local-candidate'; export declare function classifyFileArg(value: string, exists?: (p: string) => boolean): FileArgKind; /** What resolveFileArg should do once the readiness wait has finished. */ export type LocalResolveAction = 'upload' | 'error' | 'passthrough'; export declare function decideAfterWait(kind: FileArgKind, result: AwaitFileResult): LocalResolveAction; export interface AwaitFileOptions { /** Total budget for the file to appear AND stabilize. */ timeoutMs?: number; /** Poll interval while waiting for the file to appear. */ pollMs?: number; /** Interval between the size probes of the stability check. */ stabilityMs?: number; /** Files last modified longer ago than this skip the stability wait. */ recentMtimeMs?: number; } export interface AwaitFileResult { ready: boolean; reason?: 'not-found' | 'disappeared' | 'empty'; waitedMs: number; } export declare function awaitLocalFileReady(filePath: string, { timeoutMs, pollMs, stabilityMs, recentMtimeMs, }?: AwaitFileOptions): Promise; /** * Stderr warning for the passthrough decision: a path with a locally * existing parent directory never appeared during the readiness wait, so * it is being handed to the backend for AI Drive resolution. In agent * batches the dominant cause is a PRODUCER tool call that failed (the * file was supposed to exist here); without this line the model only * sees the backend's "URL could not be read" and retries blindly — * observed as 5 consecutive blind retries in one production session. */ export declare function passthroughWarning(filePath: string, result: AwaitFileResult): string; export declare function localFileNotReadyError(filePath: string, result: AwaitFileResult): string; /** * Items of a `*_urls` server param, or null when the param is not one. * * By convention `*_urls` params are arrays, and flag parsing always yields * arrays for them (array-typed params register as variadic options). But an * `--args-file` payload is merged verbatim, and callers — usually LLMs — * routinely author `"image_urls": "/home/user/x.png"` where the schema wants * an array. Before this helper the resolver matched such a value against * neither its array branch (`*_urls` + Array) nor its string branch * (`*_url`/`url` + string), so the raw local path skipped auto-upload and * leaked to the server, which can only fail it as an AI Drive lookup. * A string value therefore counts as a single-element array; the resolver * writes the resolved array back, which also restores the schema shape. */ export declare function urlsParamItems(key: string, value: unknown): unknown[] | null; //# sourceMappingURL=localFiles.d.ts.map