@genesislcap/foundation-ai 14.461.2 → 14.462.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.
@@ -537,6 +537,24 @@ export declare interface ChatMessage {
537
537
  * Not shown to the user.
538
538
  */
539
539
  responseMeta?: ChatResponseMeta;
540
+ /**
541
+ * Concrete model id that produced this message — what the active provider's
542
+ * {@link AIProvider.getStatus} reported for the turn (e.g.
543
+ * `'gemini-2.5-flash-lite'`, `'claude-haiku-4-5-20251001'`). Stamped by the
544
+ * driver onto model-produced assistant messages; tool calls ride on the
545
+ * assistant message that requested them, so a message's `model` also
546
+ * attributes its `toolCalls`. Absent on driver-authored messages (error/empty
547
+ * fallbacks, user/tool messages) and when the provider reports no status.
548
+ */
549
+ model?: string;
550
+ /**
551
+ * Registry name the provider was resolved under for the turn that produced
552
+ * this message (e.g. a tier name, or the default name). Together with `model`
553
+ * it records both the slot the turn selected and the concrete model behind it,
554
+ * so swapping the model behind a stable name stays visible in the debug log.
555
+ * Stamped by the driver alongside `model`.
556
+ */
557
+ providerName?: string;
540
558
  }
541
559
 
542
560
  /**
@@ -1308,6 +1326,15 @@ export declare const isAIFeatureEnabled: () => boolean;
1308
1326
  */
1309
1327
  export declare function isChatToolCallUnknown(tc: ChatToolCall): tc is ChatToolCallUnknown;
1310
1328
 
1329
+ /**
1330
+ * Feature-detects an {@link ObservableAIProviderRegistry}. Returns `true` when
1331
+ * `r` exposes a `subscribe` method — i.e. it can notify on runtime changes —
1332
+ * and `false` for the immutable built-ins.
1333
+ *
1334
+ * @beta
1335
+ */
1336
+ export declare function isObservableAIProviderRegistry(r: AIProviderRegistry): r is ObservableAIProviderRegistry;
1337
+
1311
1338
  /**
1312
1339
  * Speech-to-text using Web Speech API.
1313
1340
  * Gracefully degrades when SpeechRecognition is unavailable.
@@ -1333,6 +1360,108 @@ export declare class MalformedFunctionCallError extends Error {
1333
1360
  constructor(finishMessage?: string);
1334
1361
  }
1335
1362
 
1363
+ /**
1364
+ * Map-backed registry built by {@link registerAIProviders}. Preserves the
1365
+ * insertion order of `providers` for {@link (AIProviderRegistry:interface).names}
1366
+ * and {@link (AIProviderRegistry:interface).listStatuses}.
1367
+ *
1368
+ * Mutable and observable: a host that holds a reference can rebind names,
1369
+ * change the default, or atomically replace the whole mapping at runtime via
1370
+ * {@link MutableAIProviderRegistry.set}, {@link MutableAIProviderRegistry.setDefault}
1371
+ * and {@link MutableAIProviderRegistry.update}, and subscribe to be told when
1372
+ * any of those happen. This is the substrate for runtime provider switching:
1373
+ * the DI token resolves one stable instance, and consumers re-resolve their
1374
+ * cached providers when {@link MutableAIProviderRegistry.subscribe | subscribe}
1375
+ * fires. A registry that is never mutated behaves identically to an immutable
1376
+ * one, so existing single-registration callers are unaffected.
1377
+ *
1378
+ * @beta
1379
+ */
1380
+ export declare class MutableAIProviderRegistry implements ObservableAIProviderRegistry {
1381
+ private providers;
1382
+ private _defaultName;
1383
+ private readonly listeners;
1384
+ constructor(providers: Map<string, AIProvider>, defaultName: string);
1385
+ /**
1386
+ * The mapping invariant shared by construction and
1387
+ * {@link MutableAIProviderRegistry.update}: at least one provider, and the
1388
+ * resolved default name must be one of the keys. Throws
1389
+ * with the same messages from both call sites. Validates the finalized map, so
1390
+ * callers normalize/copy and resolve the default name first, then validate.
1391
+ */
1392
+ private static assertValidMapping;
1393
+ get(name: string): AIProvider | undefined;
1394
+ default(): AIProvider;
1395
+ defaultName(): string;
1396
+ names(): string[];
1397
+ getStatus(name?: string): Promise<AIStatus | null>;
1398
+ listStatuses(): Promise<AIProviderRegistryStatusEntry[]>;
1399
+ /**
1400
+ * Rebind (or add) a single name. Rebinding an existing name preserves its
1401
+ * position in `names()`; a new name is appended. Notifies subscribers.
1402
+ */
1403
+ set(name: string, provider: AIProvider): void;
1404
+ /**
1405
+ * Change the default provider. Throws if `name` is not currently registered.
1406
+ * Notifies subscribers.
1407
+ */
1408
+ setDefault(name: string): void;
1409
+ /**
1410
+ * Atomically replace the whole mapping (and optionally the default) in one
1411
+ * step, then notify subscribers once. Applies the same validation as the
1412
+ * constructor: an empty mapping throws, and the resolved default must be
1413
+ * present. When `options.default` is omitted the current default name is
1414
+ * retained (and must still exist in the new mapping).
1415
+ */
1416
+ update(providers: Record<string, AIProvider> | Map<string, AIProvider>, options?: {
1417
+ default?: string;
1418
+ }): void;
1419
+ subscribe(listener: () => void): () => void;
1420
+ /**
1421
+ * Fire every listener once. Iterates a snapshot so a listener that
1422
+ * unsubscribes (or subscribes) during notification doesn't perturb the
1423
+ * in-flight iteration.
1424
+ */
1425
+ private notify;
1426
+ }
1427
+
1428
+ /**
1429
+ * Optional capability layered onto {@link (AIProviderRegistry:interface)}: a
1430
+ * registry whose provider mapping and default can change at runtime, and that
1431
+ * notifies listeners when they do.
1432
+ *
1433
+ * @remarks
1434
+ * Consumers should **feature-detect** this with
1435
+ * {@link isObservableAIProviderRegistry} rather than depend on it — the
1436
+ * built-in empty fallback registry is immutable and deliberately does not
1437
+ * implement it. The read contract ({@link (AIProviderRegistry:interface)})
1438
+ * is unchanged; this only adds change notification, never new read methods.
1439
+ *
1440
+ * @beta
1441
+ */
1442
+ export declare interface ObservableAIProviderRegistry extends AIProviderRegistry {
1443
+ /**
1444
+ * Register a listener fired once after any change to the provider mapping or
1445
+ * default. Returns an unsubscribe function; call it to stop notifications.
1446
+ */
1447
+ subscribe(listener: () => void): () => void;
1448
+ }
1449
+
1450
+ /**
1451
+ * Registers a host-supplied {@link (AIProviderRegistry:interface)} instance on
1452
+ * the DI container under the {@link (AIProviderRegistry:variable)} token.
1453
+ *
1454
+ * @remarks
1455
+ * A thin wrapper over FAST's `Registration.instance` so a host can register its
1456
+ * own pre-built registry — typically a {@link MutableAIProviderRegistry} it
1457
+ * owns and mutates for runtime provider switching — **without importing FAST
1458
+ * primitives** itself. {@link registerAIProviders} delegates to this; reach for
1459
+ * it directly when you construct the registry yourself.
1460
+ *
1461
+ * @beta
1462
+ */
1463
+ export declare function registerAIProviderRegistry(container: Container, registry: AIProviderRegistry): void;
1464
+
1336
1465
  /**
1337
1466
  * Registers one or more named AI providers as an {@link (AIProviderRegistry:interface)}
1338
1467
  * on the given DI container.
@@ -1356,9 +1485,16 @@ export declare class MalformedFunctionCallError extends Error {
1356
1485
  * );
1357
1486
  * ```
1358
1487
  *
1488
+ * @returns the constructed {@link MutableAIProviderRegistry}, so a host that
1489
+ * wants to switch providers at runtime can keep the handle and call
1490
+ * {@link MutableAIProviderRegistry.set | set} /
1491
+ * {@link MutableAIProviderRegistry.setDefault | setDefault} /
1492
+ * {@link MutableAIProviderRegistry.update | update} on it later. Callers that
1493
+ * register once and never switch can ignore the return value.
1494
+ *
1359
1495
  * @beta
1360
1496
  */
1361
- export declare function registerAIProviders(container: Container, providers: Record<string, AIProvider>, options?: RegisterAIProvidersOptions): void;
1497
+ export declare function registerAIProviders(container: Container, providers: Record<string, AIProvider>, options?: RegisterAIProvidersOptions): MutableAIProviderRegistry;
1362
1498
 
1363
1499
  /**
1364
1500
  * Options for {@link registerAIProviders}.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/foundation-ai",
3
3
  "description": "Genesis Foundation AI - Provider-agnostic AI configuration and shared utilities",
4
- "version": "14.461.2",
4
+ "version": "14.462.0",
5
5
  "sideEffects": false,
6
6
  "license": "SEE LICENSE IN license.txt",
7
7
  "main": "dist/esm/index.js",
@@ -52,17 +52,17 @@
52
52
  }
53
53
  },
54
54
  "devDependencies": {
55
- "@genesislcap/foundation-testing": "14.461.2",
56
- "@genesislcap/genx": "14.461.2",
57
- "@genesislcap/rollup-builder": "14.461.2",
58
- "@genesislcap/ts-builder": "14.461.2",
59
- "@genesislcap/uvu-playwright-builder": "14.461.2",
60
- "@genesislcap/vite-builder": "14.461.2",
61
- "@genesislcap/webpack-builder": "14.461.2"
55
+ "@genesislcap/foundation-testing": "14.462.0",
56
+ "@genesislcap/genx": "14.462.0",
57
+ "@genesislcap/rollup-builder": "14.462.0",
58
+ "@genesislcap/ts-builder": "14.462.0",
59
+ "@genesislcap/uvu-playwright-builder": "14.462.0",
60
+ "@genesislcap/vite-builder": "14.462.0",
61
+ "@genesislcap/webpack-builder": "14.462.0"
62
62
  },
63
63
  "dependencies": {
64
- "@genesislcap/foundation-logger": "14.461.2",
65
- "@genesislcap/foundation-utils": "14.461.2",
64
+ "@genesislcap/foundation-logger": "14.462.0",
65
+ "@genesislcap/foundation-utils": "14.462.0",
66
66
  "@microsoft/fast-foundation": "2.50.0"
67
67
  },
68
68
  "repository": {
@@ -73,5 +73,5 @@
73
73
  "publishConfig": {
74
74
  "access": "public"
75
75
  },
76
- "gitHead": "7999f5af9df17157002c463d10fe75a14ac43521"
76
+ "gitHead": "d332227a536531b1b807ae33f65ce4639f0991ba"
77
77
  }