import type { SubagentSpawnContext, ToolSpec } from "@sema-agent/core"; import type { IssuedFileLink } from "../plugins/send-user-file.js"; /** The frame the web/shell renders as a file card. Rides the durable events tail (replayable). */ export interface FileLinkFrame { type: "file_link"; url: string; filename: string; size: number; /** 0 = permanent (public track). */ ttlSec: number; status: "normal" | "proactive"; caption?: string; display?: "render" | "attach"; } export interface SendUserFileRunContext { taskId: string; emit: (frame: FileLinkFrame) => Promise; } /** Per-run ALS carrier (QuestionCoordinator pattern): run legs wrap their body via runWithContext; the tool * recovers the ambient emit at execute time. No pending state, no respond face — emission is one-way. */ export declare class SendUserFileEmitter { private readonly als; runWithContext(ctx: SendUserFileRunContext, fn: () => Promise): Promise; /** Emit into the ambient run's events tail. Returns false when no run context is ambient (a leg not wrapped — * the caller reports "sent but not surfaced live" honestly rather than pretending). */ emit(frame: FileLinkFrame): Promise; } /** Per-call caps (bounded model-facing surface; the issuer has its own ttl/name guards). */ export declare const SEND_USER_FILE_MAX_FILES = 10; export declare const SEND_USER_FILE_MAX_BYTES: number; export declare const SEND_USER_FILE_MAX_CAPTION = 500; export declare function sendUserFileTool(deps: { /** Lane-scoped send: read/stat the file where the lane lives, upload, mint the user-facing link. * Enforces the size cap itself (host: fs stat; sandbox: in-sandbox stat BEFORE presigning). Throws * typed Errors (not-found / too-large / no-sandbox) — surfaced verbatim per file in the tool result. * `principal` = core's VERIFIED ToolExecuteContext.principal — the multi-tenant SCOPE the issuer keys the * hashed key segment on and the ledger records (absent on single-user lanes → the "_" sentinel). */ send: (path: string, ctx: { taskId?: string; sessionId?: string; principal?: string; }) => Promise; emitter: SendUserFileEmitter; }): ToolSpec; export declare const SEND_USER_FILE_TOOL_NAME = "SendUserFile"; /** * Build the `SubagentToolOptions.extraTools` factory that injects SendUserFile into delegated-child rosters — * WITH the two gates the bare `() => [spec]` wiring lacked: * * F1 (HIGH, codex): the subRunner carries NO tool policy and core's child spec does not inherit the parent's * `toolPolicy`, so an extraTools-injected SendUserFile BYPASSED the deployment approval gate (evidence: with * `APPROVAL_DENY=SendUserFile` the top-level call is denied but a delegated child could still call it). Until * core lands a child-policy propagation seam, the CONSERVATIVE server-side stopgap is a deployment-policy * PRE-CHECK: if the deployment's approval face gates SendUserFile at all (deny OR ask — approvalDeny / * approvalRequire / approvalNeverAuto, matched in canonical space exactly like src/approval.ts), the factory * injects NOTHING. deny obviously must not reach children; ask-gated is ALSO withheld because the child leg has * no policy to route the ask (injecting would silently auto-allow — the exact bypass). The gate is read LIVE per * spawn (a getter, not a boot snapshot) so center/env hot-applied governance is honored, mirroring how the * per-request approval baseline reads live config. A deployment with no gate intent is unchanged. * * F2 (MED, codex): read-only builtin agents (Explore/Plan) must NOT get SendUserFile — a read-only agent that * can read sensitive files AND mint public links off them breaks the read-only posture (their denyTools sets * predate this tool, so core's resolveToolSubset would let it through). `ctx.agentType` carries the spawned * definition's name (core subagent.js); membership in core's builtin catalog ⇒ inject nothing for that spawn. */ export declare function subagentSendUserFileExtraTools(deps: { spec: ToolSpec; /** LIVE deployment approval face (config.approvalDeny/approvalRequire/approvalNeverAuto) — evaluated per spawn. */ approvalGate: () => { deny?: string[]; require?: string[]; neverAuto?: string[]; }; }): (ctx: SubagentSpawnContext) => ToolSpec[]; //# sourceMappingURL=send-user-file-tool.d.ts.map