import { type JsonSchema } from "../../core/index.js"; import type { DynamicToolUIPart, ToolUIPart } from "ai"; import { type CardFieldRow } from "./field-rows.js"; import { type ToolMeta } from "./humanize.js"; import type { VendoBeat } from "./run-activity.js"; /** * The thread's in-progress presentation speaks in the product's voice: each * tool call renders as a quiet human "beat" — a checklist line with a pulsing * orb while working and a tick when done. Labels come from the ENG-216 * humanization pipeline (host `ToolMeta` wins, else the prettified tool id — * never the raw slug or a lifecycle string). The mechanical record stays in * the audit trail. */ type AnyToolPart = ToolUIPart | DynamicToolUIPart; /** Toolkit marks come from Composio's logo CDN, which covers its full catalog (chrome surfaces only). Unknown slugs get Composio's neutral placeholder rather than a 404, so `onError` fallbacks only fire on real network failures. */ export declare function toolkitLogoUrl(toolkit: string): string; /** * The consent-surface presentation of one tool call, layered on the ENG-216 * pipeline: the title is the humanized tool label (host meta wins), the * question is the ask a person answers, and the description explains what * granting means in plain words — host meta first, else synthesized from the * inputs, never invented beyond them. */ export interface ToolPresentation { title: string; description?: string; /** Short toast byline for the post-approve notification. */ sub?: string; toolkit?: string; logoUrl?: string; /** The ask as a QUESTION, with the one key value inline ("Send $47.50 to Acme Utilities?"). Synthesized ONLY from the real inputs (same honesty rule as `description`); absent when the inputs don't support a truthful one, and a consent card asks with the tool's own label instead. */ question?: string; /** The input KEYS the question already names — the TOP-LEVEL arg keys, verbatim, so each one identifies its own `CardFieldRow.key` exactly. Never a substring scan of the question (a boolean input renders "No", and "No" lives inside plenty of innocent sentences), and never the humanized LABEL: `humanizeToolName` is many-to-one, so labelling `recipient_name` as consumed also hid a real `recipientName` the question never printed. */ questionKeys?: string[]; /** When approving takes effect and whose authority it runs on ("Sends now, as you"), in the ask's own verb — the promise under the question. */ agency: string; /** Vendo's own hand-written sentence for a tool VENDO ships ({@link VENDO_TOOL_NOTES}), when there is one. Ranks below the host's `ToolMeta.description` and above the consequence class. */ note?: string; } export declare function consentClassLine(risk: string): string; /** The M1 consent ask: the question a person answers, and the quiet notes under it. A card renders the notes dot-separated on one muted line. */ export interface ConsentAsk { question: string; notes: string[]; } /** * RULING 14 in M1's shape — the ONE plain-words ladder, shared by the approval * card and its queue row so a card and its row can never say different things * about one ask. * * The question is the ask; the notes are what approving DOES (§16 law 3 lives * across the pair). Precedence, most local authority first: * 1. the question synthesized from the REAL inputs (names the actual money and * counterparty), else the ask's own humanized label as a question; * 2. the HOST's own sentence for this tool (in-code `ToolMeta.description`), * else Vendo's own for a tool Vendo ships (`VENDO_TOOL_NOTES`) — the * human-authored copy in the system; * 3. the agency phrase — when it happens, and that it happens as the person * approving; * 4. the consequence CLASS (`consentClassLine`) when neither 1 nor 2 spoke — * never the tool's own label, and it already ends "as you", so it stands * alone. * * A DESCRIPTOR's description is not on this ladder at any rung. It is authored * for the MODEL (demo-bank's "Amounts are integer cents (e.g. 285000 = * $2,850.00): divide by 100…") or minted by extraction ("POST /api/demo/pin"), * and both reached a bank customer's consent card. Ruling 11 tried to admit a * "clean" descriptor sentence through a regex vocabulary; ruling 14 reversed * that — a regex set admitted raw JSON and exceptions while deleting good host * copy, so it cannot be the runtime authority for what a person may read. */ export declare function consentAsk(risk: string, presentation: ToolPresentation, rows: readonly CardFieldRow[], meta?: ToolMeta): ConsentAsk; export declare function toolPresentation(name: string, args?: unknown, meta?: ToolMeta, /** The descriptor's authored label, when the caller has the descriptor (approval surfaces do; a bare tool beat does not). */ descriptorTitle?: string, /** The declared input schema, when the caller has the descriptor: money in the synthesized sentence is only ever a DECLARED unit. */ inputSchema?: JsonSchema): ToolPresentation; /** The between-steps gap, spoken in the transcript's own beat vocabulary — a checklist line, not a separate pill (2026-08-06 polish: the WorkingRibbon shell was a second visual language for "in progress"; the beat already is one). Mounts at the transcript tail while the turn is busy with no live call and nothing streaming; the next real beat replaces it. */ export declare function WorkingBeat({ label }: { label?: string; }): import("react").JSX.Element; /** * §3.4 + §10.2 — the accumulating rail a heavy build is watched through, on the * EXISTING split-view stage. Quiet dot→tick lines in a vertical list, never a * spinner: the newest beat is the live one, everything above it has settled. * * It is NOT a live region. The between-steps ribbon beside the composer already * announces the latest beat, and the transcript's own beats have never * announced — two live regions saying the same words is the duplication the * ribbon/card ruling (D1) exists to prevent. * * `phase` and `appId` ride as machine affordances only. A phase is a slug, and * a slug is not something a person reads (the same answer `data-vendo-tool` * gives for a raw tool name); the label already carries the words. */ export declare function BeatRail({ beats }: { beats: readonly VendoBeat[]; }): import("react").JSX.Element | null; /** * Spec §1 — the short result a settled beat earned ("Reading transactions · * 142 transactions"). * * Only a COUNT rides here, named by the output's own key. An arbitrary string * off a tool's output is the TOOL's voice (and often a raw slug or an id), and * this line sits in the product's own transcript — so anything we can't say in * plain words is simply absent, exactly like the humanization pipeline's rule * for labels. */ export declare function toolResultSummary(output: unknown): string | undefined; /** M32 — the beat's `title` carried the raw slug too, and it is the surface a reader hovers. Same answer: dev-mode only, `data-vendo-tool` for machines. */ export declare function BuildBeat({ part, risk, count, }: { part: AnyToolPart; risk: string; /** Collapsed-run repeat count (ENG-216) — shown as a ×N suffix. */ count?: number; }): import("react").JSX.Element; /** * Spec §1 — the settled turn's ONE reopenable row: "✓ Did 4 things · 7.1s". * * Beats are the live record of the work; once the turn closes, history has to * stay scannable, so the whole checklist folds into this line and reopens on * click. `seconds` is the turn's measured wall time and is absent for a turn * nobody watched work (restored history carries no per-part timestamps, and an * invented duration would be a lie on a receipt). */ export declare function BeatSummary({ steps, seconds, open, onToggle }: { steps: number; seconds?: number | undefined; open: boolean; onToggle: () => void; }): import("react").JSX.Element; export {};