@ai-gui/core 0.2.0 → 0.3.0

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.
package/dist/index.d.ts CHANGED
@@ -47,6 +47,58 @@ interface SanitizeHtmlOptions {
47
47
  */
48
48
  declare function sanitizeHtml(html: string, options?: SanitizeHtmlOptions): string;
49
49
 
50
+ //#endregion
51
+ //#region src/debug-events.d.ts
52
+ type DebugSource = "renderer" | "action-runtime" | "card-store";
53
+ interface DebugEvent<TData extends Record<string, unknown> = Record<string, unknown>> {
54
+ type: string;
55
+ source: DebugSource;
56
+ timestamp: number;
57
+ sequence: number;
58
+ data: TData;
59
+ }
60
+ type DebugEventListener = (event: DebugEvent) => void;
61
+ interface DebugEventTarget {
62
+ readonly debugSource: DebugSource;
63
+ subscribeDebug(listener: DebugEventListener): () => void;
64
+ }
65
+ interface DebugOptions {
66
+ debug?: boolean;
67
+ onDebugEvent?: DebugEventListener;
68
+ maxStringLength?: number;
69
+ maxDepth?: number;
70
+ maxNodes?: number;
71
+ redact?: (context: DebugRedactContext) => boolean;
72
+ }
73
+ interface DebugRedactContext {
74
+ key: string;
75
+ path: readonly (string | number)[];
76
+ value: unknown;
77
+ }
78
+ interface DebugInstrumentationTarget extends DebugEventTarget {
79
+ readonly debugEnabled: boolean;
80
+ emitDebug(type: string, data?: Record<string, unknown>): void;
81
+ }
82
+ interface SafeDebugValueOptions {
83
+ maxStringLength?: number;
84
+ maxDepth?: number;
85
+ maxNodes?: number;
86
+ redact?: DebugOptions["redact"];
87
+ }
88
+ declare class DebugEmitter {
89
+ private readonly enabled;
90
+ private readonly source;
91
+ private readonly limits;
92
+ private readonly listeners;
93
+ private sequence;
94
+ constructor(source: DebugSource, options?: DebugOptions);
95
+ get active(): boolean;
96
+ get available(): boolean;
97
+ subscribe(listener: DebugEventListener): () => void;
98
+ emit(type: string, data?: Record<string, unknown>): void;
99
+ }
100
+ declare function safeDebugValue(value: unknown, options?: SafeDebugValueOptions): unknown;
101
+
50
102
  //#endregion
51
103
  //#region src/types.d.ts
52
104
  /** Framework-agnostic render node. */
@@ -62,6 +114,7 @@ interface ASTNode {
62
114
  complete?: boolean;
63
115
  /** card-specific payload */
64
116
  card?: {
117
+ id?: string;
65
118
  type: string;
66
119
  data: unknown;
67
120
  complete: boolean;
@@ -103,11 +156,22 @@ type RenderOutput = {
103
156
  mount: (el: HTMLElement) => void | (() => void);
104
157
  };
105
158
  type NodeRenderer = (node: ASTNode) => RenderOutput | Promise<RenderOutput>;
159
+ type KnownJSONSchemaType = "object" | "array" | "string" | "number" | "integer" | "boolean" | "null";
106
160
  interface JSONSchema {
107
- type?: string;
161
+ type?: KnownJSONSchemaType | (string & {});
108
162
  properties?: Record<string, JSONSchema>;
109
163
  items?: JSONSchema;
110
- required?: string[];
164
+ required?: readonly string[];
165
+ additionalProperties?: boolean | JSONSchema;
166
+ enum?: readonly unknown[];
167
+ const?: unknown;
168
+ minLength?: number;
169
+ maxLength?: number;
170
+ pattern?: string;
171
+ minimum?: number;
172
+ maximum?: number;
173
+ minItems?: number;
174
+ maxItems?: number;
111
175
  [k: string]: unknown;
112
176
  }
113
177
  interface CardDef<TData = unknown, TComponent = unknown> {
@@ -128,7 +192,7 @@ interface AIGuiPlugin {
128
192
  /** LLM-facing guidance describing this plugin's fence syntax. */
129
193
  promptSpec?: string;
130
194
  }
131
- interface RendererOptions {
195
+ interface RendererOptions extends DebugOptions {
132
196
  registry?: CardRegistry;
133
197
  plugins?: AIGuiPlugin[];
134
198
  sanitize?: boolean | SanitizeHtmlOptions;
@@ -155,12 +219,283 @@ declare class CardRegistry {
155
219
  has(type: string): boolean;
156
220
  getRender(type: string): unknown;
157
221
  parse(type: string, rawJson: string): CardParseResult;
158
- private validate;
222
+ validate(type: string, data: unknown): boolean;
223
+ private validateDefinition;
159
224
  toPromptSpec(): string;
160
225
  get size(): number;
161
226
  toJSONSchema(): JSONSchema;
162
227
  }
163
228
 
229
+ //#endregion
230
+ //#region src/card-store.d.ts
231
+ declare const CARD_ID_MAX_LENGTH = 256;
232
+ declare const CARD_JSON_MAX_DEPTH = 32;
233
+ declare const CARD_JSON_MAX_NODES = 10000;
234
+ declare const CARD_PATCH_BATCH_MAX_SIZE = 100;
235
+ type CardAction = {
236
+ status: "idle";
237
+ } | {
238
+ status: "loading";
239
+ actionId: string;
240
+ } | {
241
+ status: "success";
242
+ actionId: string;
243
+ } | {
244
+ status: "error";
245
+ actionId: string;
246
+ error: CardActionError;
247
+ };
248
+ interface CardActionError {
249
+ name: string;
250
+ message: string;
251
+ }
252
+ interface CardRecord {
253
+ readonly id: string;
254
+ readonly type: string;
255
+ readonly data: unknown;
256
+ readonly revision: number;
257
+ readonly action: CardAction;
258
+ }
259
+ interface CardPatch {
260
+ op: "merge" | "replace";
261
+ cardId: string;
262
+ data: unknown;
263
+ revision?: number;
264
+ }
265
+ interface CardPatchBatch {
266
+ op: "batch";
267
+ patches: CardPatch[];
268
+ }
269
+ type CardPatchResult = CardPatch | CardPatchBatch;
270
+ interface CardSnapshot {
271
+ version: 1;
272
+ cards: Array<Pick<CardRecord, "id" | "type" | "data" | "revision">>;
273
+ }
274
+ interface CardStoreOptions extends DebugOptions {
275
+ registry?: CardRegistry;
276
+ }
277
+ type CardListener = (card: CardRecord | undefined) => void;
278
+ type CardStoreListener = (cards: readonly CardRecord[]) => void;
279
+ declare class CardStore {
280
+ readonly debugSource: "card-store";
281
+ private readonly registry?;
282
+ private cards;
283
+ private lastMutationEpoch;
284
+ private mutationEpoch;
285
+ private readonly listeners;
286
+ private readonly allListeners;
287
+ private readonly debug;
288
+ constructor(options?: CardStoreOptions);
289
+ register(input: {
290
+ id: string;
291
+ type: string;
292
+ data: unknown;
293
+ }): CardRecord;
294
+ get(id: string): CardRecord | undefined;
295
+ list(): CardRecord[];
296
+ subscribe(id: string, listener: CardListener): () => void;
297
+ subscribeAll(listener: CardStoreListener): () => void;
298
+ subscribeDebug(listener: DebugEventListener): () => void;
299
+ apply(patch: CardPatch): CardRecord;
300
+ applyAll(patches: readonly CardPatch[]): CardRecord[];
301
+ delete(id: string): boolean;
302
+ clear(): void;
303
+ snapshot(): CardSnapshot;
304
+ restore(snapshot: CardSnapshot): void;
305
+ beginAction(id: string, actionId: string): boolean;
306
+ succeedAction(id: string, actionId: string): boolean;
307
+ failAction(id: string, actionId: string, error: unknown): boolean;
308
+ cancelAction(id: string, actionId: string): boolean;
309
+ isActionCurrent(id: string, actionId: string): boolean;
310
+ revisions(): ReadonlyMap<string, number>;
311
+ captureMutationEpoch(): number;
312
+ applyActionResult(result: CardPatchResult, startedEpoch: number): CardRecord[];
313
+ private preparePatch;
314
+ private assertValid;
315
+ private setAction;
316
+ private nextMutationEpoch;
317
+ private notify;
318
+ private notifyOne;
319
+ private notifyAll;
320
+ }
321
+ declare class CardStoreError extends Error {
322
+ constructor(message: string, options?: ErrorOptions);
323
+ }
324
+ declare class CardNotFoundError extends CardStoreError {
325
+ constructor(id: string);
326
+ }
327
+ declare class CardTypeConflictError extends CardStoreError {
328
+ constructor(id: string, currentType: string, nextType: string);
329
+ }
330
+ declare class CardValidationError extends CardStoreError {
331
+ constructor(type: string);
332
+ }
333
+ declare class CardRevisionConflictError extends CardStoreError {
334
+ constructor(id: string, expected: number, actual: number);
335
+ }
336
+ declare class CardJSONError extends CardStoreError {}
337
+ declare class CardLimitError extends CardStoreError {}
338
+ declare class CardSnapshotError extends CardStoreError {}
339
+ declare function isCardPatchResult(value: unknown): value is CardPatchResult;
340
+
341
+ //#endregion
342
+ //#region src/json-schema.d.ts
343
+ interface JSONSchemaValidationResult {
344
+ valid: boolean;
345
+ issues: string[];
346
+ }
347
+ /** Small, dependency-free validator for the JSON Schema subset used by AIGUI definitions. */
348
+ declare function validateJSONSchema(schema: JSONSchema, value: unknown): JSONSchemaValidationResult;
349
+
350
+ //#endregion
351
+ //#region src/actions.d.ts
352
+ interface ActionContext {
353
+ signal: AbortSignal;
354
+ actionId: string;
355
+ cardType?: string;
356
+ cardId?: string;
357
+ }
358
+ interface ActionDefinition<TParams = unknown, TResult = unknown> {
359
+ type: string;
360
+ schema?: JSONSchema;
361
+ run: (params: TParams, context: ActionContext) => TResult | Promise<TResult>;
362
+ }
363
+ interface ActionRegisterOptions {
364
+ override?: boolean;
365
+ }
366
+ declare class ActionRegistry {
367
+ private actions;
368
+ register<TParams, TResult>(definition: ActionDefinition<TParams, TResult>, options?: ActionRegisterOptions): void;
369
+ has(type: string): boolean;
370
+ get(type: string): ActionDefinition<any, unknown> | undefined;
371
+ list(): ActionDefinition<any, unknown>[];
372
+ }
373
+ interface ActionRequest<TParams = unknown> {
374
+ type: string;
375
+ params: TParams;
376
+ cardType?: string;
377
+ cardId?: string;
378
+ }
379
+ interface ActionDispatchOptions {
380
+ signal?: AbortSignal;
381
+ timeoutMs?: number;
382
+ owner?: object;
383
+ }
384
+ type ActionStatus = "idle" | "pending" | "success" | "error" | "cancelled";
385
+ interface ActionStateBase {
386
+ key: string;
387
+ type: string;
388
+ cardType?: string;
389
+ cardId?: string;
390
+ actionId?: string;
391
+ }
392
+ type ActionState = (ActionStateBase & {
393
+ status: "idle";
394
+ }) | (ActionStateBase & {
395
+ status: "pending";
396
+ actionId: string;
397
+ }) | (ActionStateBase & {
398
+ status: "success";
399
+ actionId: string;
400
+ result: unknown;
401
+ }) | (ActionStateBase & {
402
+ status: "error";
403
+ actionId: string;
404
+ error: ActionRuntimeError;
405
+ }) | (ActionStateBase & {
406
+ status: "cancelled";
407
+ actionId: string;
408
+ error: ActionAbortedError;
409
+ });
410
+ interface ActionEventBase {
411
+ key: string;
412
+ type: string;
413
+ params: unknown;
414
+ actionId: string;
415
+ cardType?: string;
416
+ cardId?: string;
417
+ }
418
+ type ActionStartEvent = ActionEventBase;
419
+ type ActionSuccessEvent = ActionEventBase & {
420
+ result: unknown;
421
+ };
422
+ type ActionErrorEvent = ActionEventBase & {
423
+ error: ActionRuntimeError;
424
+ };
425
+ interface ActionRuntimeOptions extends DebugOptions {
426
+ registry: ActionRegistry;
427
+ cardStore?: CardStore;
428
+ timeoutMs?: number;
429
+ onActionStart?: (event: ActionStartEvent) => void;
430
+ onActionSuccess?: (event: ActionSuccessEvent) => void;
431
+ onActionError?: (event: ActionErrorEvent) => void;
432
+ }
433
+ type ActionStateListener = (state: ActionState) => void;
434
+ declare class ActionRuntime {
435
+ readonly debugSource: "action-runtime";
436
+ private readonly registry;
437
+ private readonly cardStore?;
438
+ private readonly defaultTimeoutMs?;
439
+ private readonly onActionStart?;
440
+ private readonly onActionSuccess?;
441
+ private readonly onActionError?;
442
+ private readonly states;
443
+ private readonly pending;
444
+ private readonly listeners;
445
+ private readonly defaultOwner;
446
+ private readonly runtimeId;
447
+ private generation;
448
+ private nextActionId;
449
+ private destroyed;
450
+ private readonly debug;
451
+ constructor(options: ActionRuntimeOptions);
452
+ dispatch<TResult = unknown>(request: ActionRequest, options?: ActionDispatchOptions): Promise<TResult>;
453
+ getState(key: string): ActionState;
454
+ /** Check the runtime allowlist without exposing executable action definitions. */
455
+ hasAction(type: string): boolean;
456
+ subscribe(listener: ActionStateListener): () => void;
457
+ subscribeDebug(listener: DebugEventListener): () => void;
458
+ cancel(key: string): boolean;
459
+ reset(): void;
460
+ destroy(): void;
461
+ private rejectPreflight;
462
+ private isPublic;
463
+ private commit;
464
+ private notify;
465
+ }
466
+ declare function createActionRuntime(options: ActionRuntimeOptions): ActionRuntime;
467
+ declare class ActionRuntimeError extends Error {
468
+ constructor(message: string, options?: ErrorOptions);
469
+ }
470
+ declare class ActionAlreadyRegisteredError extends ActionRuntimeError {
471
+ constructor(type: string);
472
+ }
473
+ declare class ActionNotFoundError extends ActionRuntimeError {
474
+ constructor(type: string);
475
+ }
476
+ declare class ActionValidationError extends ActionRuntimeError {
477
+ readonly actionType: string;
478
+ readonly issues: string[];
479
+ constructor(actionType: string, issues: string[]);
480
+ }
481
+ declare class ActionExecutionError extends ActionRuntimeError {
482
+ constructor(type: string, cause: unknown);
483
+ }
484
+ declare class ActionAbortedError extends ActionRuntimeError {
485
+ constructor(type: string);
486
+ }
487
+ declare class ActionTimeoutError extends ActionRuntimeError {
488
+ readonly timeoutMs: number;
489
+ constructor(type: string, timeoutMs: number);
490
+ }
491
+ declare class ActionDestroyedError extends ActionRuntimeError {
492
+ constructor();
493
+ }
494
+ declare function getActionKey(type: string, cardType?: string, cardId?: string): string;
495
+ declare function getIdleActionState(key: string): Extract<ActionState, {
496
+ status: "idle";
497
+ }>;
498
+
164
499
  //#endregion
165
500
  //#region src/parser.d.ts
166
501
  interface ParserOptions {
@@ -186,8 +521,11 @@ declare function createParserWithMetadata(options?: ParserOptions): (src: string
186
521
 
187
522
  //#endregion
188
523
  //#region src/plugins.d.ts
524
+ interface CollectNodeRendererOptions extends DebugOptions {
525
+ debugTarget?: DebugInstrumentationTarget;
526
+ }
189
527
  /** Merge every plugin's `nodeRenderers` into a single map (later plugins win). */
190
- declare function collectNodeRenderers(plugins?: AIGuiPlugin[]): Record<string, NodeRenderer>;
528
+ declare function collectNodeRenderers(plugins?: AIGuiPlugin[], debugOptions?: CollectNodeRendererOptions): Record<string, NodeRenderer>;
191
529
  /** The set of node types claimed by the given plugins. */
192
530
  declare function pluginNodeTypes(plugins?: AIGuiPlugin[]): Set<string>;
193
531
 
@@ -206,6 +544,7 @@ declare function applyPatches(nodes: ASTNode[], patches: Patch[]): ASTNode[];
206
544
  * the resulting patches via `onPatch`.
207
545
  */
208
546
  declare class Renderer {
547
+ readonly debugSource: "renderer";
209
548
  private buffer;
210
549
  private prevAst;
211
550
  private parse;
@@ -216,8 +555,12 @@ declare class Renderer {
216
555
  private activeFeed?;
217
556
  private renderScheduled;
218
557
  private scheduleGeneration;
558
+ private readonly debug;
219
559
  constructor(options?: RendererOptions);
560
+ get debugEnabled(): boolean;
561
+ emitDebug(type: string, data?: Record<string, unknown>): void;
220
562
  push(chunk: string): void;
563
+ subscribeDebug(listener: DebugEventListener): () => void;
221
564
  feed(source: FeedSource, options?: FeedOptions): Promise<void>;
222
565
  reset(): void;
223
566
  /** Immediately render pending buffered input, bypassing the scheduler. */
@@ -225,6 +568,7 @@ declare class Renderer {
225
568
  private scheduleRender;
226
569
  private cancelActiveFeed;
227
570
  private render;
571
+ private sanitizeNodesWithDebug;
228
572
  }
229
573
 
230
574
  //#endregion
@@ -268,4 +612,65 @@ interface BuildSystemPromptOptions {
268
612
  declare function buildSystemPrompt(options?: BuildSystemPromptOptions): string;
269
613
 
270
614
  //#endregion
271
- export { AIGuiPlugin, ASTNode, BuildSystemPromptOptions, CardDef, CardParseResult, CardRegistry, ChannelSink, FeedChunk, FeedOptions, FeedSource, JSONSchema, NodeRenderer, ParseResult, ParserOptions, PartialJSONResult, Patch, RenderOutput, Renderer, RendererOptions, SanitizeHtmlOptions, SourceBlock, StreamRouter, applyPatches, buildSystemPrompt, collectNodeRenderers, createParser, createParserWithMetadata, diffAst, parsePartialJSON, pluginNodeTypes, repairMarkdown, sanitizeHtml };
615
+ //#region src/model-stream.d.ts
616
+ interface Citation {
617
+ type?: string;
618
+ id?: string;
619
+ url?: string;
620
+ title?: string;
621
+ citedText?: string;
622
+ [key: string]: unknown;
623
+ }
624
+ interface Usage {
625
+ inputTokens?: number;
626
+ outputTokens?: number;
627
+ totalTokens?: number;
628
+ [key: string]: unknown;
629
+ }
630
+ type ModelStreamEvent = {
631
+ type: "content";
632
+ delta: string;
633
+ } | {
634
+ type: "reasoning";
635
+ delta: string;
636
+ } | {
637
+ type: "citation";
638
+ data: Citation;
639
+ } | {
640
+ type: "usage";
641
+ data: Usage;
642
+ } | {
643
+ type: "error";
644
+ error: unknown;
645
+ };
646
+ type ByteStreamSource = Response | ReadableStream<Uint8Array> | AsyncIterable<Uint8Array | string>;
647
+ interface StreamParseOptions {
648
+ signal?: AbortSignal;
649
+ onMalformed?: (error: Error, input: string) => "skip" | void;
650
+ }
651
+ interface SSEOptions extends StreamParseOptions {
652
+ parseJSON?: boolean;
653
+ doneData?: string | false;
654
+ }
655
+ interface SSEEvent<T = string> {
656
+ data: T;
657
+ event?: string;
658
+ id?: string;
659
+ retry?: number;
660
+ }
661
+ declare function parseSSE(source: ByteStreamSource, options: SSEOptions & {
662
+ parseJSON: true;
663
+ }): AsyncGenerator<SSEEvent<unknown>>;
664
+ declare function parseSSE(source: ByteStreamSource, options?: SSEOptions): AsyncGenerator<SSEEvent<string>>;
665
+ declare function jsonLines<T = unknown>(source: ByteStreamSource, options?: StreamParseOptions): AsyncGenerator<T>;
666
+ declare const ndjson: typeof jsonLines;
667
+ declare function textLines(source: ByteStreamSource, options?: Pick<StreamParseOptions, "signal">): AsyncGenerator<string>;
668
+ declare function contentDeltas(events: AsyncIterable<ModelStreamEvent>): AsyncGenerator<string>;
669
+ declare function mockModelStream(events: Iterable<ModelStreamEvent> | AsyncIterable<ModelStreamEvent>, options?: {
670
+ delayMs?: number;
671
+ signal?: AbortSignal;
672
+ }): AsyncGenerator<ModelStreamEvent>;
673
+ declare function readableBytes(chunks: Iterable<string | Uint8Array> | AsyncIterable<string | Uint8Array>): ReadableStream<Uint8Array>;
674
+
675
+ //#endregion
676
+ export { AIGuiPlugin, ASTNode, ActionAbortedError, ActionAlreadyRegisteredError, ActionContext, ActionDefinition, ActionDestroyedError, ActionDispatchOptions, ActionErrorEvent, ActionEventBase, ActionExecutionError, ActionNotFoundError, ActionRegisterOptions, ActionRegistry, ActionRequest, ActionRuntime, ActionRuntimeError, ActionRuntimeOptions, ActionStartEvent, ActionState, ActionStateListener, ActionStatus, ActionSuccessEvent, ActionTimeoutError, ActionValidationError, BuildSystemPromptOptions, ByteStreamSource, CARD_ID_MAX_LENGTH, CARD_JSON_MAX_DEPTH, CARD_JSON_MAX_NODES, CARD_PATCH_BATCH_MAX_SIZE, CardAction, CardActionError, CardDef, CardJSONError, CardLimitError, CardListener, CardNotFoundError, CardParseResult, CardPatch, CardPatchBatch, CardPatchResult, CardRecord, CardRegistry, CardRevisionConflictError, CardSnapshot, CardSnapshotError, CardStore, CardStoreError, CardStoreListener, CardStoreOptions, CardTypeConflictError, CardValidationError, ChannelSink, Citation, CollectNodeRendererOptions, DebugEmitter, DebugEvent, DebugEventListener, DebugEventTarget, DebugInstrumentationTarget, DebugOptions, DebugRedactContext, DebugSource, FeedChunk, FeedOptions, FeedSource, JSONSchema, JSONSchemaValidationResult, ModelStreamEvent, NodeRenderer, ParseResult, ParserOptions, PartialJSONResult, Patch, RenderOutput, Renderer, RendererOptions, SSEEvent, SSEOptions, SafeDebugValueOptions, SanitizeHtmlOptions, SourceBlock, StreamParseOptions, StreamRouter, Usage, applyPatches, buildSystemPrompt, collectNodeRenderers, contentDeltas, createActionRuntime, createParser, createParserWithMetadata, diffAst, getActionKey, getIdleActionState, isCardPatchResult, jsonLines, mockModelStream, ndjson, parsePartialJSON, parseSSE, pluginNodeTypes, readableBytes, repairMarkdown, safeDebugValue, sanitizeHtml, textLines, validateJSONSchema };