@absolutejs/ai 0.0.42 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -333,6 +333,61 @@ export type AICompleteMessage = {
333
333
  export type StreamAICompleteMetadata = {
334
334
  sources?: RAGSource[];
335
335
  };
336
+ export type AIStreamFinishReason = "complete" | "max_tokens" | "max_total_tokens" | "max_duration" | "max_turns" | "aborted" | "error";
337
+ export type AIStreamFinish = {
338
+ durationMs: number;
339
+ fullResponse: string;
340
+ reason: AIStreamFinishReason;
341
+ turns: number;
342
+ /** Aggregate normalized usage across every provider turn. */
343
+ usage: AIUsage;
344
+ };
345
+ /** Why an agentic SSE run stopped short of a normal completion.
346
+ * Note: `max_duration_ms` here differs from `AIStreamFinishReason.max_duration`
347
+ * (the `onFinish` vocabulary) — the SSE reason is intentionally suffixed. */
348
+ export type AIStreamStopReason = "max_total_tokens" | "max_duration_ms" | "max_tokens" | "max_turns" | "aborted";
349
+ /** `event: "content"` — an assistant text delta. */
350
+ export type AISSEContentPayload = {
351
+ /** Just this chunk's text. */
352
+ delta: string;
353
+ /** The full assistant text accumulated so far (including `delta`). */
354
+ full: string;
355
+ };
356
+ /** `event: "thinking"` — accumulated reasoning text so far. */
357
+ export type AISSEThinkingPayload = {
358
+ text: string;
359
+ };
360
+ /** `event: "tools"` — a single tool transition (one `running`, then one
361
+ * `complete` per call), unlike the legacy accumulated-HTML blob. */
362
+ export type AISSEToolPayload = {
363
+ name: string;
364
+ status: "running" | "complete";
365
+ input: unknown;
366
+ /** Present only on `status: "complete"`. */
367
+ result?: string;
368
+ };
369
+ /** `event: "images"` — a generated image. */
370
+ export type AISSEImagePayload = {
371
+ data: string;
372
+ format: string;
373
+ revisedPrompt?: string;
374
+ };
375
+ /** `event: "complete"` — a normal terminal completion. */
376
+ export type AISSECompletePayload = {
377
+ usage?: AIUsage;
378
+ durationMs: number;
379
+ model: string;
380
+ };
381
+ /** `event: "stopped"` — a ceiling/limit/abort terminal (not an error). */
382
+ export type AISSEStoppedPayload = {
383
+ reason: AIStreamStopReason;
384
+ /** Human-readable explanation (e.g. "Stopped: token budget reached …"). */
385
+ detail: string;
386
+ };
387
+ /** `event: "error"` — a genuine terminal error (thrown / not found). */
388
+ export type AISSEErrorPayload = {
389
+ message: string;
390
+ };
336
391
  export type AIImageMessage = {
337
392
  type: "image";
338
393
  data: string;
@@ -439,6 +494,10 @@ export type StreamAIOptions = {
439
494
  * order — onTurn(0) → onToolUse… → onTurn(1) → … — reconstructs the live
440
495
  * transcript exactly (each turn's text, then that turn's tool calls). */
441
496
  onTurn?: (turn: number, usage?: AIUsage, turnText?: string) => void;
497
+ /** Guaranteed exactly once when the agent loop terminates, including budget
498
+ * stops, aborts, and errors. Unlike `onComplete`, this reports aggregate
499
+ * usage across every turn and may be async for durable metering. */
500
+ onFinish?: (finish: AIStreamFinish) => void | Promise<void>;
442
501
  maxTokens?: number;
443
502
  maxTurns?: number;
444
503
  /** Cumulative input+output token ceiling across all turns. When reached, the
@@ -459,6 +518,15 @@ export type StreamAIOptions = {
459
518
  * Pings fire ONLY during silence (the timer resets on every real event) so
460
519
  * they never interleave with live output. Default 15000; set 0 to disable. */
461
520
  heartbeatMs?: number;
521
+ /** Switch the SSE stream from pre-rendered HTML in `data` to typed events
522
+ * with JSON payloads, for headless consumers that render their own UI.
523
+ * When enabled: every `data` is JSON (parse it), and the overloaded `status`
524
+ * terminal splits into distinct `complete` (`AISSECompletePayload`), `stopped`
525
+ * (`AISSEStoppedPayload`), and `error` (`AISSEErrorPayload`) events. Delta
526
+ * events keep their names but carry `AISSEContentPayload` / `AISSEThinkingPayload`
527
+ * / `AISSEToolPayload` / `AISSEImagePayload`; `ping` is unchanged. Default off
528
+ * keeps the HTML renderers (built-in HTMX/default UI). */
529
+ structuredEvents?: boolean;
462
530
  signal?: AbortSignal;
463
531
  completeMeta?: StreamAICompleteMetadata;
464
532
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/ai",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "homepage": "https://github.com/absolutejs/ai",
5
5
  "bugs": {
6
6
  "url": "https://github.com/absolutejs/ai/issues"