UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

149 lines • 5.66 kB
/** * The chat stream protocol shared with `@dudousxd/nestjs-agent`: the vocabulary every run's SSE carries * (see `docs/streaming-and-http.mdx`). * * It is a COPY of `AgentStreamEvent` in `@dudousxd/nestjs-agent-core/src/stream-events.ts`, kept * field-for-field identical rather than imported: neither repo depends on the other (the guardrails * detectors are shared the same way). The frame is the contract, so that React client — the * transport, `useAgentChat`, the transcript model — renders an Adonis run unchanged. * * Two rules keep it evolvable, on both sides at once: * - every frame is a JSON object with a string `kind`; a reader MUST tolerate kinds it does not * know (the React transport forwards them as `data-<kind>` parts rather than dropping them); * - fields are only ever added, and new fields are optional. */ import type { ElicitationRequest } from './elicitation.js'; import type { ChatQueueState } from './spi/chat-queue.js'; import type { ToolConfirmation } from './tool-presentation.js'; import type { MessageUsage } from './types.js'; /** * A component the server pushed into the conversation: generative UI that is not a tool call's * rendering. `component` is a key into the client's own registry; `id` is its identity within the * message — a second frame with the same `id` REPLACES the first, it never adds a second one. */ export interface AgentUiComponent { id: string; component: string; props: Record<string, unknown>; /** Schema version of `props`, so a client can keep rendering components an older server persisted. */ version?: number; fallbackText?: string; componentVersions?: Record<string, number>; /** The tool call that pushed the component, when one did. */ toolCallId?: string; /** * A PREVIEW, drawn from a tool call's arguments while the model is still writing them (genui * `streaming: 'partial'`): unvalidated, never persisted, and replaced in place by the final push * under the same `id` — or withdrawn by a partial frame with empty `props`, which a client renders * as nothing. A text surface skips it. Absent on every final frame. */ partial?: true; } /** Who has to settle an action tool call, and until when. Metadata: the call still settles by id. */ export interface AgentApprovalRequest { confirmation?: ToolConfirmation; id: string; /** Open vocabulary: `'requester'` (the person chatting), `'admin'`, a role, a team. */ approver: string; /** ISO-8601 instant after which the request lapses. Absent → it never expires. */ expiresAt?: string; reason?: string; } /** How an approval settled — the other half of {@link AgentApprovalRequest}, under the same `id`. */ export interface AgentApprovalSettlement { id: string; status: 'approved' | 'rejected' | 'expired'; approver?: string; decidedBy?: string; decidedVia?: string; remember?: boolean; reason?: string; } export type AgentStreamEvent = { kind: 'step-start'; } | { kind: 'step-finish'; usage?: MessageUsage; /** An estimate or the provider's figure; `null` when unpriced — never a fabricated `0`. */ costUsd?: number | null; reasoningMs?: number; /** The model the step ran on, when the provider reported one — what a per-model usage report keys on. */ model?: string; } | { kind: 'text'; text: string; } | { kind: 'reasoning'; text: string; } | { kind: 'tool-input-start'; id: string; name: string; toolKind: 'read' | 'action'; parentId?: string; } | { kind: 'tool-input-delta'; id: string; delta: string; } | { kind: 'tool-input-available'; id: string; name: string; input: unknown; toolKind: 'read' | 'action'; parentId?: string; } | { kind: 'tool-output'; id: string; output: unknown; } | { kind: 'tool-output-error'; id: string; error: string; } /** A person declined an action: nothing ran. Distinct from a failure, whose effects are unknown. */ | { kind: 'tool-output-denied'; id: string; reason?: string; } | { kind: 'elicitation'; id: string; request: ElicitationRequest; } | ({ kind: 'approval-requested'; } & AgentApprovalRequest) | ({ kind: 'approval-settled'; } & AgentApprovalSettlement) | ({ kind: 'ui'; } & AgentUiComponent) | { kind: 'title'; title: string; } /** Someone stopped the run: the stream's last frame before a normal end. */ | { kind: 'cancelled'; } /** * The thread's message queue changed — a snapshot of the whole queue, never a delta, so a client * that missed one frame is corrected by the next. Written into the stream of the run that is * holding the thread: when someone queues, edits, reorders or removes a waiting message, and, just * before this run's own terminal frame, with what happens next — `started` names the queued * message that became the next turn and that turn's run id (attach to it with * `GET <base>/chat/:runId/stream`), `queue.paused` says why nothing starts. */ | { kind: 'queue'; queue: ChatQueueState; started?: { messageId: string; runId: string; }; }; /** The `event: error` codes the provider writes, matching the NestJS library's. */ export type AgentStreamErrorCode = 'quota_exceeded' | 'output_rejected' | 'structured_output_invalid' /** The durable runtime refused a checkpoint position: the run's journal and its code disagree. */ | 'replay_diverged' /** A model call ended without producing anything. */ | 'model_no_output' | 'run_failed'; //# sourceMappingURL=stream-events.d.ts.map