@klex/agent-admin-api 0.9.0 → 0.11.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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/dist/index.d.ts +387 -34
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,6 +34,16 @@ returned by the API are redacted and must never contain resolved environment
34
34
  secrets. Model selection uses separate `providerId` and opaque `modelId` fields;
35
35
  clients must not split model IDs on colons.
36
36
 
37
+ ## Realtime voice client contract
38
+
39
+ - `GET /v1/providers/{id}/voices?modelId=...&refresh=false` returns `selectionSupported`, optional `defaultVoiceId`, and compatible entries with opaque `voiceId`, display metadata, provenance and preview availability. Provider capabilities advertise discovery/preview hooks; model-scoped support determines whether a selector is available. Listing does not generate audio. Encode the complete model ID in the query, including slashes/colons.
40
+ - `POST /v1/providers/{id}/voices/preview` takes `{ modelId, voiceId }`. It can trigger billable same-model Live generation and returns binary `audio/wav`, not JSON/base64 or a public URL. `X-Voice-Preview-Model` is URI-encoded and `X-Voice-Preview-Mode` is `live`. On failure parse the JSON error contract; 429 means quota, 502 means upstream generation failure. Arbitrary text/URLs/model overrides are not accepted.
41
+ - `PATCH /v1/settings/model-selection` saves `voice.sts` references with optional `voiceId`. Preserve both `voice.tts` and `voice.stt` because the voice object is replaced. Omit `voiceId` in the replacement STS reference to reset. Other selection purposes reject it. New calls use changes; active calls do not switch voices.
42
+
43
+ Existing omitted defaults remain: OpenAI Realtime/GPT-Live `marin`, Gemini's provider default. Unknown/custom model profiles remain usable with defaults, but have no selectable catalog. Catalog provenance distinguishes maintained/discovered data, with explicit fallback/stale flags. Samples improvise a short introduction from the current agent name and full soul. Realtime/Gemini generate it directly; GPT-Live uses the first configured chat model to write commentary before speaking it with the selected Live voice. That extra text call is potentially billable and requires a chat selection. GPT-Live may paraphrase commentary. Name/soul changes bypass old cached samples; different voices may use different wording. Browser clients fetch over their existing authorized Cloud path, check `response.ok`, then use `response.blob()` and an object URL for playback (revoke it afterward). Headless/TUI clients use `arrayBuffer()` and an external WAV player; the backend does not implement playback.
44
+
45
+ Local admin access remains unauthenticated and loopback-only; Cloud access remains authorized through the existing tunnel. Responses use private/no-store headers, while the agent caches successful samples in bounded memory for reuse. Previewing never starts a production call or supplies history, tools, or credentials as prompt context. It intentionally supplies the full soul to the speech provider or, for GPT-Live, the configured chat provider. Prompts instruct models not to speak private details, but generated output still depends on provider behavior. No UI selector is included in this contract change.
46
+
37
47
  ## MCP OAuth authorization
38
48
 
39
49
  Version 0.2 adds the consolidated MCP authorization contract. Authorization is
package/dist/index.d.ts CHANGED
@@ -15,15 +15,6 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
15
15
  } & {
16
16
  "/v1/cloud/status": {
17
17
  $get: {
18
- output: {
19
- error: string;
20
- code: string;
21
- remediation?: string | undefined;
22
- };
23
- outputFormat: "json";
24
- status: 500;
25
- input: {};
26
- } | {
27
18
  output: {
28
19
  cloudEnabled: boolean;
29
20
  enrolled: boolean;
@@ -35,6 +26,15 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
35
26
  outputFormat: "json";
36
27
  status: 200;
37
28
  input: {};
29
+ } | {
30
+ output: {
31
+ error: string;
32
+ code: string;
33
+ remediation?: string | undefined;
34
+ };
35
+ outputFormat: "json";
36
+ status: 500;
37
+ input: {};
38
38
  };
39
39
  };
40
40
  } & {
@@ -207,6 +207,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
207
207
  [x: string]: import("hono/utils/types").JSONValue;
208
208
  };
209
209
  } | undefined;
210
+ voiceId?: string | undefined;
210
211
  }[];
211
212
  tts: {
212
213
  providerId: string;
@@ -280,6 +281,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
280
281
  providerId: string;
281
282
  modelId: string;
282
283
  providerOptions?: Record<string, Record<string, unknown>> | undefined;
284
+ voiceId?: string | undefined;
283
285
  }[];
284
286
  tts: {
285
287
  providerId: string;
@@ -339,6 +341,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
339
341
  providerId: string;
340
342
  modelId: string;
341
343
  providerOptions?: Record<string, Record<string, unknown>> | undefined;
344
+ voiceId?: string | undefined;
342
345
  }[];
343
346
  tts: {
344
347
  providerId: string;
@@ -418,6 +421,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
418
421
  [x: string]: import("hono/utils/types").JSONValue;
419
422
  };
420
423
  } | undefined;
424
+ voiceId?: string | undefined;
421
425
  }[];
422
426
  tts: {
423
427
  providerId: string;
@@ -482,6 +486,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
482
486
  providerId: string;
483
487
  modelId: string;
484
488
  providerOptions?: Record<string, Record<string, unknown>> | undefined;
489
+ voiceId?: string | undefined;
485
490
  }[];
486
491
  tts: {
487
492
  providerId: string;
@@ -512,6 +517,15 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
512
517
  } & {
513
518
  "/v1/introspect": {
514
519
  $get: {
520
+ output: {
521
+ error: string;
522
+ code: string;
523
+ remediation?: string | undefined;
524
+ };
525
+ outputFormat: "json";
526
+ status: 500;
527
+ input: {};
528
+ } | {
515
529
  output: {
516
530
  path: string[];
517
531
  state: {
@@ -526,15 +540,6 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
526
540
  outputFormat: "json";
527
541
  status: 200;
528
542
  input: {};
529
- } | {
530
- output: {
531
- error: string;
532
- code: string;
533
- remediation?: string | undefined;
534
- };
535
- outputFormat: "json";
536
- status: 500;
537
- input: {};
538
543
  };
539
544
  };
540
545
  } & {
@@ -1814,6 +1819,105 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
1814
1819
  };
1815
1820
  };
1816
1821
  };
1822
+ } & {
1823
+ "/v1/skills": {
1824
+ $get: {
1825
+ output: {
1826
+ error: string;
1827
+ code: string;
1828
+ remediation?: string | undefined;
1829
+ };
1830
+ outputFormat: "json";
1831
+ status: 500;
1832
+ input: {};
1833
+ } | {
1834
+ output: {
1835
+ error: string;
1836
+ code: string;
1837
+ remediation?: string | undefined;
1838
+ };
1839
+ outputFormat: "json";
1840
+ status: 503;
1841
+ input: {};
1842
+ } | {
1843
+ output: {
1844
+ skills: {
1845
+ name: string;
1846
+ description: string;
1847
+ origin: "learned";
1848
+ createdAt?: string | undefined;
1849
+ updatedAt?: string | undefined;
1850
+ lastReadAt?: string | null | undefined;
1851
+ readCount?: number | undefined;
1852
+ }[];
1853
+ };
1854
+ outputFormat: "json";
1855
+ status: 200;
1856
+ input: {};
1857
+ };
1858
+ };
1859
+ } & {
1860
+ "/v1/skills/:name": {
1861
+ $get: {
1862
+ output: {
1863
+ error: string;
1864
+ code: string;
1865
+ remediation?: string | undefined;
1866
+ };
1867
+ outputFormat: "json";
1868
+ status: 404;
1869
+ input: {
1870
+ param: {
1871
+ name: string;
1872
+ };
1873
+ };
1874
+ } | {
1875
+ output: {
1876
+ error: string;
1877
+ code: string;
1878
+ remediation?: string | undefined;
1879
+ };
1880
+ outputFormat: "json";
1881
+ status: 500;
1882
+ input: {
1883
+ param: {
1884
+ name: string;
1885
+ };
1886
+ };
1887
+ } | {
1888
+ output: {
1889
+ error: string;
1890
+ code: string;
1891
+ remediation?: string | undefined;
1892
+ };
1893
+ outputFormat: "json";
1894
+ status: 503;
1895
+ input: {
1896
+ param: {
1897
+ name: string;
1898
+ };
1899
+ };
1900
+ } | {
1901
+ output: {
1902
+ name: string;
1903
+ description: string;
1904
+ origin: "learned";
1905
+ createdAt?: string | undefined;
1906
+ updatedAt?: string | undefined;
1907
+ lastReadAt?: string | null | undefined;
1908
+ readCount?: number | undefined;
1909
+ body: string;
1910
+ sourceEpisodes?: string[] | undefined;
1911
+ };
1912
+ outputFormat: "json";
1913
+ status: 200;
1914
+ input: {
1915
+ param: {
1916
+ name: string;
1917
+ };
1918
+ };
1919
+ };
1920
+ };
1817
1921
  } & {
1818
1922
  "/v1/provider-types": {
1819
1923
  $get: {
@@ -1825,6 +1929,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
1825
1929
  documentationUrl?: string | undefined;
1826
1930
  capabilities: {
1827
1931
  modelDiscovery: boolean;
1932
+ voiceDiscovery: boolean;
1933
+ voicePreview: boolean;
1828
1934
  connectivityTest: boolean;
1829
1935
  customModels: boolean;
1830
1936
  };
@@ -1890,6 +1996,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
1890
1996
  documentationUrl?: string | undefined;
1891
1997
  capabilities: {
1892
1998
  modelDiscovery: boolean;
1999
+ voiceDiscovery: boolean;
2000
+ voicePreview: boolean;
1893
2001
  connectivityTest: boolean;
1894
2002
  customModels: boolean;
1895
2003
  };
@@ -1940,6 +2048,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
1940
2048
  documentationUrl?: string | undefined;
1941
2049
  capabilities: {
1942
2050
  modelDiscovery: boolean;
2051
+ voiceDiscovery: boolean;
2052
+ voicePreview: boolean;
1943
2053
  connectivityTest: boolean;
1944
2054
  customModels: boolean;
1945
2055
  };
@@ -2030,6 +2140,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
2030
2140
  documentationUrl?: string | undefined;
2031
2141
  capabilities: {
2032
2142
  modelDiscovery: boolean;
2143
+ voiceDiscovery: boolean;
2144
+ voicePreview: boolean;
2033
2145
  connectivityTest: boolean;
2034
2146
  customModels: boolean;
2035
2147
  };
@@ -2132,6 +2244,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
2132
2244
  documentationUrl?: string | undefined;
2133
2245
  capabilities: {
2134
2246
  modelDiscovery: boolean;
2247
+ voiceDiscovery: boolean;
2248
+ voicePreview: boolean;
2135
2249
  connectivityTest: boolean;
2136
2250
  customModels: boolean;
2137
2251
  };
@@ -2237,6 +2351,8 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
2237
2351
  documentationUrl?: string | undefined;
2238
2352
  capabilities: {
2239
2353
  modelDiscovery: boolean;
2354
+ voiceDiscovery: boolean;
2355
+ voicePreview: boolean;
2240
2356
  connectivityTest: boolean;
2241
2357
  customModels: boolean;
2242
2358
  };
@@ -2429,6 +2545,243 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
2429
2545
  };
2430
2546
  };
2431
2547
  };
2548
+ } & {
2549
+ "/v1/providers/:id/voices": {
2550
+ $get: {
2551
+ output: {
2552
+ error: string;
2553
+ code: string;
2554
+ remediation?: string | undefined;
2555
+ };
2556
+ outputFormat: "json";
2557
+ status: 400;
2558
+ input: {
2559
+ param: {
2560
+ id: string;
2561
+ };
2562
+ } & {
2563
+ query: {
2564
+ modelId: string;
2565
+ refresh?: "false" | "true" | undefined;
2566
+ };
2567
+ };
2568
+ } | {
2569
+ output: {
2570
+ error: string;
2571
+ code: string;
2572
+ remediation?: string | undefined;
2573
+ };
2574
+ outputFormat: "json";
2575
+ status: 404;
2576
+ input: {
2577
+ param: {
2578
+ id: string;
2579
+ };
2580
+ } & {
2581
+ query: {
2582
+ modelId: string;
2583
+ refresh?: "false" | "true" | undefined;
2584
+ };
2585
+ };
2586
+ } | {
2587
+ output: {
2588
+ error: string;
2589
+ code: string;
2590
+ remediation?: string | undefined;
2591
+ };
2592
+ outputFormat: "json";
2593
+ status: 429;
2594
+ input: {
2595
+ param: {
2596
+ id: string;
2597
+ };
2598
+ } & {
2599
+ query: {
2600
+ modelId: string;
2601
+ refresh?: "false" | "true" | undefined;
2602
+ };
2603
+ };
2604
+ } | {
2605
+ output: {
2606
+ error: string;
2607
+ code: string;
2608
+ remediation?: string | undefined;
2609
+ };
2610
+ outputFormat: "json";
2611
+ status: 500;
2612
+ input: {
2613
+ param: {
2614
+ id: string;
2615
+ };
2616
+ } & {
2617
+ query: {
2618
+ modelId: string;
2619
+ refresh?: "false" | "true" | undefined;
2620
+ };
2621
+ };
2622
+ } | {
2623
+ output: {
2624
+ error: string;
2625
+ code: string;
2626
+ remediation?: string | undefined;
2627
+ };
2628
+ outputFormat: "json";
2629
+ status: 502;
2630
+ input: {
2631
+ param: {
2632
+ id: string;
2633
+ };
2634
+ } & {
2635
+ query: {
2636
+ modelId: string;
2637
+ refresh?: "false" | "true" | undefined;
2638
+ };
2639
+ };
2640
+ } | {
2641
+ output: {
2642
+ selectionSupported: boolean;
2643
+ defaultVoiceId?: string | undefined;
2644
+ fallback?: boolean | undefined;
2645
+ stale?: boolean | undefined;
2646
+ voices: {
2647
+ voiceId: string;
2648
+ displayName: string;
2649
+ description?: string | undefined;
2650
+ language?: string | undefined;
2651
+ region?: string | undefined;
2652
+ provenance: {
2653
+ source: "discovered" | "maintained";
2654
+ documentationUrl: string;
2655
+ reviewedAt?: string | undefined;
2656
+ };
2657
+ preview: {
2658
+ available: boolean;
2659
+ mode?: "live" | undefined;
2660
+ };
2661
+ }[];
2662
+ };
2663
+ outputFormat: "json";
2664
+ status: 200;
2665
+ input: {
2666
+ param: {
2667
+ id: string;
2668
+ };
2669
+ } & {
2670
+ query: {
2671
+ modelId: string;
2672
+ refresh?: "false" | "true" | undefined;
2673
+ };
2674
+ };
2675
+ };
2676
+ };
2677
+ } & {
2678
+ "/v1/providers/:id/voices/preview": {
2679
+ $post: {
2680
+ output: {
2681
+ error: string;
2682
+ code: string;
2683
+ remediation?: string | undefined;
2684
+ };
2685
+ outputFormat: "json";
2686
+ status: 400;
2687
+ input: {
2688
+ param: {
2689
+ id: string;
2690
+ };
2691
+ } & {
2692
+ json: {
2693
+ modelId: string;
2694
+ voiceId: string;
2695
+ };
2696
+ };
2697
+ } | {
2698
+ output: {
2699
+ error: string;
2700
+ code: string;
2701
+ remediation?: string | undefined;
2702
+ };
2703
+ outputFormat: "json";
2704
+ status: 404;
2705
+ input: {
2706
+ param: {
2707
+ id: string;
2708
+ };
2709
+ } & {
2710
+ json: {
2711
+ modelId: string;
2712
+ voiceId: string;
2713
+ };
2714
+ };
2715
+ } | {
2716
+ output: {
2717
+ error: string;
2718
+ code: string;
2719
+ remediation?: string | undefined;
2720
+ };
2721
+ outputFormat: "json";
2722
+ status: 429;
2723
+ input: {
2724
+ param: {
2725
+ id: string;
2726
+ };
2727
+ } & {
2728
+ json: {
2729
+ modelId: string;
2730
+ voiceId: string;
2731
+ };
2732
+ };
2733
+ } | {
2734
+ output: {
2735
+ error: string;
2736
+ code: string;
2737
+ remediation?: string | undefined;
2738
+ };
2739
+ outputFormat: "json";
2740
+ status: 500;
2741
+ input: {
2742
+ param: {
2743
+ id: string;
2744
+ };
2745
+ } & {
2746
+ json: {
2747
+ modelId: string;
2748
+ voiceId: string;
2749
+ };
2750
+ };
2751
+ } | {
2752
+ output: {
2753
+ error: string;
2754
+ code: string;
2755
+ remediation?: string | undefined;
2756
+ };
2757
+ outputFormat: "json";
2758
+ status: 502;
2759
+ input: {
2760
+ param: {
2761
+ id: string;
2762
+ };
2763
+ } & {
2764
+ json: {
2765
+ modelId: string;
2766
+ voiceId: string;
2767
+ };
2768
+ };
2769
+ } | {
2770
+ output: Response;
2771
+ outputFormat: "json";
2772
+ status: import("hono/utils/http-status").StatusCode;
2773
+ input: {
2774
+ param: {
2775
+ id: string;
2776
+ };
2777
+ } & {
2778
+ json: {
2779
+ modelId: string;
2780
+ voiceId: string;
2781
+ };
2782
+ };
2783
+ };
2784
+ };
2432
2785
  } & {
2433
2786
  "/v1/providers/:id/models": {
2434
2787
  $post: {
@@ -3001,18 +3354,12 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
3001
3354
  "/v1/introspect/:path": {
3002
3355
  $get: {
3003
3356
  output: {
3004
- path: string[];
3005
- state: {
3006
- [x: string]: import("hono/utils/types").JSONValue;
3007
- } | null;
3008
- children: {
3009
- id: string;
3010
- hasState: boolean;
3011
- hasChildren: boolean;
3012
- }[];
3357
+ error: string;
3358
+ code: string;
3359
+ remediation?: string | undefined;
3013
3360
  };
3014
3361
  outputFormat: "json";
3015
- status: 200;
3362
+ status: 400;
3016
3363
  input: {
3017
3364
  param: {
3018
3365
  path: string;
@@ -3025,7 +3372,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
3025
3372
  remediation?: string | undefined;
3026
3373
  };
3027
3374
  outputFormat: "json";
3028
- status: 400;
3375
+ status: 404;
3029
3376
  input: {
3030
3377
  param: {
3031
3378
  path: string;
@@ -3038,7 +3385,7 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
3038
3385
  remediation?: string | undefined;
3039
3386
  };
3040
3387
  outputFormat: "json";
3041
- status: 404;
3388
+ status: 500;
3042
3389
  input: {
3043
3390
  param: {
3044
3391
  path: string;
@@ -3046,12 +3393,18 @@ export type AdminApi = import("hono/hono-base").HonoBase<any, {
3046
3393
  };
3047
3394
  } | {
3048
3395
  output: {
3049
- error: string;
3050
- code: string;
3051
- remediation?: string | undefined;
3396
+ path: string[];
3397
+ state: {
3398
+ [x: string]: import("hono/utils/types").JSONValue;
3399
+ } | null;
3400
+ children: {
3401
+ id: string;
3402
+ hasState: boolean;
3403
+ hasChildren: boolean;
3404
+ }[];
3052
3405
  };
3053
3406
  outputFormat: "json";
3054
- status: 500;
3407
+ status: 200;
3055
3408
  input: {
3056
3409
  param: {
3057
3410
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klex/agent-admin-api",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Shared types for the Klex Bot Admin API",