// The procedure contracts of the agent module: schemas and names, no handler and no port. // // A run is a bounded, person-requested plan of tool calls that the worker executes durably: the // progress a page renders is the run row and its step log, and the only writes a tool's result can // cause are proposals a person decides. The approval queue renders the EXACT stored proposed // arguments — never a model's narration of them. import { procedure } from "@conusai-kit/core" import { z } from "zod" import { APPROVAL_REVIEWED, RUN_CANCELLED_ACTION } from "./constants.js" const inProject = { org: z.string(), workspace: z.string(), project: z.string() } /** One step of the plan a person admits: one explicitly published tool, exact arguments. */ export const planStepSchema = z .object({ key: z .string() .min(1) .max(128) .regex(/^[a-z][a-z0-9-]*$/, "lower-case letters, digits and dashes"), label: z.string().min(1).max(200), tool: z.string().min(1).max(200), args: z.record(z.string(), z.unknown()), }) .strict() /** What a run may spend; the engine clamps it by the hard safety ceilings. */ export const runBudgetSchema = z .object({ maxCostMicrocents: z.number().int().positive().optional(), maxSteps: z.number().int().positive().optional(), maxDurationSeconds: z.number().int().positive().optional(), }) .strict() export const runViewSchema = z.object({ runId: z.string(), goal: z.string(), status: z.enum(["queued", "running", "awaiting_approval", "completed", "failed", "cancelled", "uncertain"]), failureCode: z .enum(["tool_error", "budget_exhausted", "plan_refused", "approval_unavailable", "internal"]) .nullable(), failureDetail: z.string().nullable(), /** The plan as admitted: what the run will do, visible before it does it. */ plan: z.array( z.object({ key: z.string(), label: z.string(), tool: z.string(), args: z.record(z.string(), z.unknown()), /** The step's state from the step log; steps not begun have no row yet. */ status: z.enum(["pending", "committed", "failed", "cancelled", "uncertain"]), attempts: z.number().int(), error: z.string().nullable(), }), ), usageCostMicrocents: z.number().int(), usageSteps: z.number().int(), /** Committed steps over the plan: the progress bar. */ percent: z.number(), cancelRequested: z.boolean(), actorId: z.string(), createdAt: z.string(), startedAt: z.string().nullable(), finishedAt: z.string().nullable(), }) export type RunView = z.output /** One parked approval: the exact stored proposed arguments, copied before they were proposed. */ export const approvalViewSchema = z.object({ runId: z.string(), stepKey: z.string(), goal: z.string(), tool: z.string(), /** The exact arguments the tool was called with; a reviewer reads THESE, never a narration. */ arguments: z.record(z.string(), z.unknown()), /** Where the persisted proposal is reviewed in the console, when the platform names one. */ reviewUrl: z.string().nullable(), createdAt: z.string(), }) export type ApprovalView = z.output export const runStart = procedure("agent.run.start") .kind("write") .scope("project") .permission("agent.run.start") .input( z.object({ ...inProject, goal: z.string().min(1).max(2_000), plan: z.array(planStepSchema).min(1).max(25), budget: runBudgetSchema.optional(), }), ) .output(runViewSchema) .contract() export const runStatus = procedure("agent.run.status") .kind("read") .scope("project") .permission("agent.run.read") .tool() .input(z.object({ ...inProject, runId: z.string() })) .output(runViewSchema) .contract() export const runCancel = procedure("agent.run.cancel") .kind("write") .scope("project") .permission("agent.run.cancel") .input(z.object({ ...inProject, runId: z.string() })) .output(z.object({ runId: z.string(), cancelled: z.boolean() })) .audit(RUN_CANCELLED_ACTION) .contract() export const runList = procedure("agent.run.list") .kind("read") .scope("project") .permission("agent.run.read") .input(z.object({ ...inProject, cursor: z.string().optional(), limit: z.number().int().min(1).max(100).optional() })) .output(z.object({ runs: z.array(runViewSchema), cursor: z.string().optional(), hasMore: z.boolean() })) .contract() export const approvalList = procedure("agent.approval.list") .kind("read") .scope("project") .permission("agent.approval.review") .input(z.object({ ...inProject })) .output(z.object({ approvals: z.array(approvalViewSchema) })) .contract() export const approvalReview = procedure("agent.approval.review") .kind("write") .scope("project") .permission("agent.approval.review") .input( z.object({ ...inProject, runId: z.string(), stepKey: z.string(), decision: z.enum(["approve", "reject"]), reason: z.string().max(500).optional(), }), ) .output( z.object({ runId: z.string(), status: z.enum(["queued", "running", "awaiting_approval", "completed", "failed", "cancelled", "uncertain"]), }), ) .audit(APPROVAL_REVIEWED) .contract() export const AGENT_PROCEDURES = [runStart, runStatus, runCancel, runList, approvalList, approvalReview]