@sema-agent/core
Version:
Stateless, task-oriented AI agent core
97 lines (96 loc) • 6.78 kB
TypeScript
import type { AgentTool } from "../../internal/harness.js";
import type { AdvertisedWritableDirs } from "./advertised-writable-dirs.js";
import type { AutoModeDenialTracker } from "../auto-mode.js";
import { type Hooks } from "../hooks.js";
import { type OnAsk, type ToolCallRequest, type ToolPolicy } from "../tool-policy.js";
import type { RunnerDeps, TaskSpec } from "../types.js";
import type { CwdRef } from "../../tools/fs/fs-shared.js";
import type { AskLane, Prepared } from "./contracts.js";
import { consumeInheritedAskGrant } from "./inherited-ask-grants.js";
import { type GrantReadRoot } from "./read-root-grant.js";
import type { createRuleOffersOf } from "./permission-rule-lanes.js";
export interface PrepareAskLaneInput {
/** borrowed-readonly — the wiring-manifest phase's ONE activation predicate; false ⇒ this phase builds nothing and
* returns an absent lane. */
gateMachineryActive: boolean;
/** borrowed-readonly — prepare's abort seat; only `.signal` is read (composed into every per-call signal and bound
* onto the deny observer). Never aborted here. */
abortController: {
readonly signal: AbortSignal;
};
/** borrowed-readonly — the policy chain's effective policy, or undefined (then no `adjudicate` wrapper is built and
* the gate reads a missing policy as allow). Called at RUN time, per tool call, through the abort-bound wrapper. */
effectivePolicy: ToolPolicy | undefined;
/** borrowed-readonly — the per-leg-immutable durable budget snapshot stamped onto EVERY adjudicated request. Same
* object every call; the policy cannot write it back. */
budgetSnapshot: NonNullable<ToolCallRequest["budget"]>;
/** borrowed-readonly — the hand's live tracked cwd, or undefined (hands-less). Read per call at RUN time (`current`),
* never captured: the fs hand tools resolve their relative paths against this very ref. Not written here. */
handsCwdRef: CwdRef | undefined;
/** borrowed-readonly — the run's advertised-writable-directory seat, or undefined (hands-less / nothing advertised). `roots` is read at RUN time, never captured: it is the fence's own admitted list and the write gate's exemption domain must be that same list. Not written here. */
advertisedWritableDirs: Pick<AdvertisedWritableDirs, "roots"> | undefined;
/** borrowed-readonly — the shared mount roster; read at RUN time by the approval-preview projection (alias-aware
* lookup over whatever the roster holds when the ask is minted). Never mutated here. */
tools: readonly AgentTool[];
/** borrowed-mutable — the inherited-unavailable marker set. Writer here: `resolveAskBound` consumes (`delete`) a
* marked call at its fail-closed intercept; the policy-chain phase records, the gate station sweeps. */
inheritedUnavailableAsks: Set<string>;
/** borrowed-mutable — the duplicate-frame ask-grant record. Writer here: the grant-reuse consume half
* (`consumeInheritedAskGrant`); the policy-chain phase records, the gate station sweeps. */
inheritedAskGrants: Parameters<typeof consumeInheritedAskGrant>[0];
/** borrowed-readonly — the run's own approver seat (spec over deps), or undefined: the resolve target, the
* live-approver test the carry mint reads, and the grant-reuse identity law's approver. */
onAsk: OnAsk | undefined;
/** borrowed-mutable — the per-task human-review accumulator (`Prepared.humanReviewRef`). Writers here: every
* synchronous resolve that a person actually judged (count / totalWaitMs / gates push); runtask adds the durable
* resume latency. */
humanReviewRef: Prepared["humanReviewRef"];
/** borrowed-readonly — the injectable wall clock every human-time observable reads (`Prepared.now`). */
now: () => number;
/** borrowed-readonly — the policy-chain phase's rule-offer factory (the suggestion members the ask mint threads). */
ruleOffersOf: ReturnType<typeof createRuleOffersOf>;
/** borrowed-readonly — the policy-chain phase's Runner-filled source identity (one factory, every ask mint site). */
askSourceIdentity: () => {
principal?: string;
sourceTaskId?: string;
fromSubagent?: true;
sourceAgentName?: string;
isDelegatedChild?: true;
};
/** borrowed-readonly — the policy-chain phase's per-tool risk-axes projection (`riskAxes` on the ask). */
riskAxesOf: (call: Pick<ToolCallRequest, "toolName" | "face">) => {
riskAxes?: {
irreversible?: boolean;
egress?: boolean;
};
};
/** borrowed-mutable — the auto-mode denial tracker's live seat (undefined until an arming). Writer here: the carry mint
* arms the auto-deny window on it iff the seat about to be called is live (the tracker's one writer). */
autoModeDenialTracking: {
readonly current: AutoModeDenialTracker | undefined;
};
/** borrowed-readonly — the REBOUND spec; only `taskId` is read (the late-settlement observer's tag). */
spec: Pick<TaskSpec, "taskId">;
/** borrowed-readonly — the deployment seats this lane reports on, as a Pick over the SAME `deps` object (receiver
* preserved for `deps.onError?.()`): the late-settlement observer's notice/error sinks and the hook-crash notifier. */
deps: Pick<RunnerDeps, "onNotice" | "onError">;
/** borrowed-readonly — the acquired session id (the observer's tag, the hook-phase error tag). */
sessionId: string;
/** borrowed-readonly — the run's invocation id (the observer's tag). */
runId: string;
/** borrowed-readonly — the resolved hook record; only `permissionDenied` is read (the deny observer's seat). */
hooks: Hooks | undefined;
/** borrowed-readonly — the validated per-prepare hook seat bound (the deny observer's timeout). */
hookTimeoutMs: number;
/** borrowed-readonly — the own hook-crash reporter (the deny observer's swallow-guarded report sink). */
notifyOwnHookCrash: (err: unknown) => void;
/** borrowed-readonly — the hands phase's in-flight read-root widening (an approver's accepted `readRootGrant`), or undefined (hands-less). */
grantReadRoot: GrantReadRoot | undefined;
}
export interface PrepareAskLaneResult {
/** owned — the lane, or undefined exactly when `gateMachineryActive` is false (then the suspend saga, the boundary
* parks, the park closure and the gate station are not built either — they key off this seat). */
askLane: AskLane | undefined;
}
/** The M19 ask-lane phase body — prepareTask's in-stream ask stretch, verbatim (see the module header). */
export declare function prepareAskLane(input: PrepareAskLaneInput): PrepareAskLaneResult;