@adonis-agora/agent
Version:
Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.
113 lines • 5.31 kB
TypeScript
import { type A2uiOptions } from '../../a2ui/core.js';
import { type AgUiEvent, type AgUiSourceFrame } from './types.js';
export interface AgUiEncoderOptions {
/** The ids the consumer sent on `RunAgentInput`: every boundary event echoes them. */
threadId: string;
runId: string;
/** The library run whose stream is being projected (it mints interrupt ids and the `agora.run` event). */
streamRunId: string;
/** The library's thread id, when it differs from what the consumer calls the thread. */
streamThreadId?: string;
/**
* Frames of the library run's stream that an earlier AG-UI run already delivered (a resume). They
* are fed to the encoder like any other — it has to know what they opened — but produce no events.
*/
skip?: number;
/**
* Tool calls a resuming request just answered. The run has not necessarily said so yet — a parked
* run takes a moment to wake — so without this the encoder would read them as still waiting and
* report the interrupt again before the answer had any effect.
*/
answered?: readonly string[];
/** Model id for the usage entry when the step frames carry none. */
model?: string;
/**
* Also project every `ui` frame onto A2UI (https://a2ui.org) — an `ACTIVITY_SNAPSHOT` of type
* `a2ui-surface` after its `agora.ui` event, the shape AG-UI's A2UI middleware and CopilotKit's
* A2UI renderer read. Off by default.
*/
a2ui?: A2uiOptions;
}
/**
* Projects one library run's stream ({@link AgUiSourceFrame}s, in buffer order) onto AG-UI 1.0 events.
*
* A pure state machine: the same frames always give the same events, which is what lets a resuming
* request — served by any replica — replay the run's buffer, skip what the interrupted AG-UI run
* already delivered, and continue. It writes nothing itself; {@link agUiEvents} drives it and
* decides when the run has stopped to ask.
*
* What maps where:
* - `text` → `TEXT_MESSAGE_*` (one message per stretch of text);
* - `reasoning` → a reasoning span with one reasoning message;
* - `step-start`/`step-finish` → `STEP_STARTED`/`STEP_FINISHED`, the step's usage folded into the
* run's `usage`;
* - `tool-input-*` → `TOOL_CALL_START`/`ARGS`/`END` (the call's kind as `metadata['agora.toolKind']`);
* `tool-output*` → `TOOL_CALL_RESULT`;
* - an approval or a question set the run parks on → an `Interrupt` on the closing `RUN_FINISHED`;
* - `cancelled` → the cancelled outcome; an error frame → `RUN_ERROR`;
* - generative UI, title, queue and the native approval/elicitation frames → `CUSTOM` events named
* in {@link AG_UI_CUSTOM}, for what AG-UI has no event for.
*
* Not mapped: sub-agent attribution (`subagentRunId`) — a delegated agent's frames are projected
* flat, as the protocol allows of a producer that does not attribute.
*/
export declare class AgUiEncoder {
private readonly options;
private position;
private started;
private closed;
private cancelled;
private crossed;
private messageSeq;
private stepSeq;
private openText;
private openReasoning;
/** The last text message of the current step: a tool call attaches to it. */
private stepMessage;
private readonly openSteps;
private readonly calls;
private readonly pending;
private readonly usage;
constructor(options: AgUiEncoderOptions);
/** How many frames of the library stream this encoder has consumed. */
get consumed(): number;
/** The run is waiting on at least one approval or question set nobody has settled yet. */
get waiting(): boolean;
/**
* Is anything still in flight that is NOT waiting on a person — a tool call announced and neither
* answered nor parked? While there is, more frames are coming without anyone's help.
*/
get busy(): boolean;
/** `RUN_STARTED`, and the library's own ids for the run. Call once, before the first frame. */
start(): AgUiEvent[];
/** The AG-UI events the next frame of the library stream stands for (possibly none). */
encode(frame: AgUiSourceFrame): AgUiEvent[];
/**
* The replayed frames are behind us: from here on events are written. The AG-UI run that delivered
* them closed everything it had open before it finished, so this run starts with nothing open, and
* what the resuming request answered is no longer waiting.
*/
private crossBoundary;
private get replaying();
private project;
/**
* The events that end the AG-UI run: whatever is still open is closed first, then `RUN_FINISHED`
* with how it ended — interrupted when the run is waiting on someone, cancelled when it was
* stopped, success otherwise. Nothing after a `RUN_ERROR`. `ended` says the library run's stream
* itself ended, rather than this reader having stopped following it.
*/
finish(ended?: boolean): AgUiEvent[];
private interrupts;
private custom;
private nextMessageId;
private textDelta;
private reasoningDelta;
private closeText;
private closeReasoning;
private closeStreams;
private callStart;
private result;
private addUsage;
private usageEntries;
}
//# sourceMappingURL=encoder.d.ts.map