@independo/inderun-contracts 0.4.0 → 0.5.0-rc.1

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 (52) hide show
  1. package/dist/generated/execution-provenance.d.ts +1 -1
  2. package/dist/generated/execution-provenance.d.ts.map +1 -1
  3. package/dist/generated/inderun-error.d.ts +1 -1
  4. package/dist/generated/inderun-error.d.ts.map +1 -1
  5. package/dist/generated/index.d.ts +3 -0
  6. package/dist/generated/index.d.ts.map +1 -1
  7. package/dist/generated/provider-capability-snapshot.d.ts +370 -0
  8. package/dist/generated/provider-capability-snapshot.d.ts.map +1 -0
  9. package/dist/generated/provider-capability-snapshot.js +2 -0
  10. package/dist/generated/provider-descriptor.d.ts +264 -0
  11. package/dist/generated/provider-descriptor.d.ts.map +1 -0
  12. package/dist/generated/provider-descriptor.js +2 -0
  13. package/dist/generated/provider-dynamic-capabilities.d.ts +99 -0
  14. package/dist/generated/provider-dynamic-capabilities.d.ts.map +1 -0
  15. package/dist/generated/provider-dynamic-capabilities.js +2 -0
  16. package/dist/generated/route-plan.d.ts +47 -3
  17. package/dist/generated/route-plan.d.ts.map +1 -1
  18. package/dist/generated/route-planner-input.d.ts +417 -32
  19. package/dist/generated/route-planner-input.d.ts.map +1 -1
  20. package/dist/generated/schemas.d.ts +458 -85
  21. package/dist/generated/schemas.d.ts.map +1 -1
  22. package/dist/generated/schemas.js +549 -104
  23. package/dist/generated/stream-event.d.ts +1 -1
  24. package/dist/generated/stream-event.d.ts.map +1 -1
  25. package/dist/generated/stream-terminal-outcome.d.ts +1 -1
  26. package/dist/generated/stream-terminal-outcome.d.ts.map +1 -1
  27. package/dist/generated/task-result.d.ts +1 -1
  28. package/dist/generated/task-result.d.ts.map +1 -1
  29. package/dist/index.d.ts +4 -4
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -2
  32. package/dist/types.d.ts +7 -1
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/validators.d.ts +9 -0
  35. package/dist/validators.d.ts.map +1 -1
  36. package/dist/validators.js +24 -1
  37. package/package.json +1 -1
  38. package/src/generated/execution-provenance.ts +1 -1
  39. package/src/generated/inderun-error.ts +1 -1
  40. package/src/generated/index.ts +3 -0
  41. package/src/generated/provider-capability-snapshot.ts +388 -0
  42. package/src/generated/provider-descriptor.ts +278 -0
  43. package/src/generated/provider-dynamic-capabilities.ts +103 -0
  44. package/src/generated/route-plan.ts +49 -3
  45. package/src/generated/route-planner-input.ts +437 -36
  46. package/src/generated/schemas.ts +552 -104
  47. package/src/generated/stream-event.ts +1 -1
  48. package/src/generated/stream-terminal-outcome.ts +1 -1
  49. package/src/generated/task-result.ts +1 -1
  50. package/src/index.ts +13 -1
  51. package/src/types.ts +7 -0
  52. package/src/validators.ts +39 -0
@@ -522,7 +522,7 @@ export const routePlannerInputSchema = {
522
522
  ],
523
523
  "properties": {
524
524
  "task": {
525
- "description": "Minimal task descriptor for provider task matching.",
525
+ "description": "Task descriptor for provider task matching: the kind plus the requirements routing can check against declared capabilities. Absent requirement fields are never checked, so a text request carries the kind alone.",
526
526
  "type": "object",
527
527
  "additionalProperties": true,
528
528
  "required": [
@@ -530,8 +530,85 @@ export const routePlannerInputSchema = {
530
530
  ],
531
531
  "properties": {
532
532
  "kind": {
533
+ "description": "The task kind, matched against the providers' task capabilities.",
533
534
  "type": "string",
534
535
  "minLength": 1
536
+ },
537
+ "inputs": {
538
+ "description": "Input media kinds the request carries. Every one must be accepted by the provider's task capability. The SDKs send ['text'] for text_to_text.",
539
+ "type": "array",
540
+ "items": {
541
+ "$ref": "provider-descriptor.schema.json#/$defs/inputKind"
542
+ }
543
+ },
544
+ "delivery": {
545
+ "title": "DeliveryRequirement",
546
+ "description": "The output delivery the request requires. Absent for text, whose delivery is implicitly inline.",
547
+ "type": "object",
548
+ "additionalProperties": true,
549
+ "required": [
550
+ "mode"
551
+ ],
552
+ "properties": {
553
+ "mode": {
554
+ "$ref": "provider-descriptor.schema.json#/$defs/outputDelivery"
555
+ },
556
+ "mediaTypes": {
557
+ "description": "Acceptable media types; the provider must declare at least one for the requested delivery. Absent means any.",
558
+ "type": "array",
559
+ "items": {
560
+ "type": "string",
561
+ "minLength": 1
562
+ }
563
+ }
564
+ }
565
+ },
566
+ "locale": {
567
+ "title": "LocaleRequirement",
568
+ "description": "The locale the request requires. Under 'language' matching the region is a preference: a provider known to offer the exact tag ranks ahead of an otherwise equal one. A provider that cannot enumerate its locales is not rejected on this basis; it must fail before committing instead.",
569
+ "type": "object",
570
+ "additionalProperties": true,
571
+ "required": [
572
+ "tag",
573
+ "match"
574
+ ],
575
+ "properties": {
576
+ "tag": {
577
+ "description": "BCP 47 tag.",
578
+ "type": "string",
579
+ "minLength": 1
580
+ },
581
+ "match": {
582
+ "title": "LocaleMatch",
583
+ "description": "'exact' requires the full tag; 'language' requires only the primary language subtag and treats the region as a preference.",
584
+ "enum": [
585
+ "exact",
586
+ "language"
587
+ ]
588
+ }
589
+ }
590
+ },
591
+ "voice": {
592
+ "title": "VoiceRequirement",
593
+ "description": "Voice traits the request asks for. Only a 'required' voice can reject a provider; a 'preferred' one shapes which listed voice the plan binds a candidate to, always within the request's privacy policy.",
594
+ "type": "object",
595
+ "additionalProperties": true,
596
+ "required": [
597
+ "requirement"
598
+ ],
599
+ "properties": {
600
+ "gender": {
601
+ "$ref": "provider-dynamic-capabilities.schema.json#/$defs/voiceGender"
602
+ },
603
+ "requirement": {
604
+ "title": "RequirementLevel",
605
+ "description": "'required' takes part in routing; 'preferred' does not.",
606
+ "enum": [
607
+ "required",
608
+ "preferred"
609
+ ]
610
+ }
611
+ }
535
612
  }
536
613
  }
537
614
  },
@@ -612,7 +689,7 @@ export const routePlannerInputSchema = {
612
689
  }
613
690
  },
614
691
  "providers": {
615
- "description": "Static descriptors plus dynamic capability snapshots for planning.",
692
+ "description": "Static descriptors plus dynamic capability checks for planning. Both shapes are the provider schemas themselves, shared by $ref, so the planner reads exactly what checkCapabilities() reports.",
616
693
  "type": "array",
617
694
  "items": {
618
695
  "type": "object",
@@ -623,107 +700,12 @@ export const routePlannerInputSchema = {
623
700
  ],
624
701
  "properties": {
625
702
  "descriptor": {
626
- "type": "object",
627
- "additionalProperties": true,
628
- "required": [
629
- "id",
630
- "type",
631
- "supports",
632
- "tasks"
633
- ],
634
- "properties": {
635
- "id": {
636
- "type": "string",
637
- "minLength": 1
638
- },
639
- "type": {
640
- "enum": [
641
- "local",
642
- "edge",
643
- "cloud"
644
- ]
645
- },
646
- "supports": {
647
- "type": "object",
648
- "additionalProperties": true,
649
- "required": [
650
- "run"
651
- ],
652
- "properties": {
653
- "run": {
654
- "type": "boolean"
655
- },
656
- "streaming": {
657
- "description": "Whether the provider statically declares Mode-2 streaming. Absent is treated as false: a descriptor that predates this field cannot be assumed to stream.",
658
- "type": "boolean"
659
- }
660
- }
661
- },
662
- "cancel": {
663
- "description": "Cancellation guarantee the provider offers. Carried for route explanations and telemetry; the planner does not filter on it.",
664
- "enum": [
665
- "hard",
666
- "soft",
667
- "none"
668
- ]
669
- },
670
- "tasks": {
671
- "type": "array",
672
- "items": {
673
- "type": "string",
674
- "minLength": 1
675
- }
676
- },
677
- "privacy": {
678
- "description": "Descriptor privacy metadata used to enforce local/cloud routing rules.",
679
- "type": "object",
680
- "additionalProperties": true,
681
- "required": [
682
- "dataLeavesDevice"
683
- ],
684
- "properties": {
685
- "dataLeavesDevice": {
686
- "type": "boolean"
687
- },
688
- "regions": {
689
- "type": "array",
690
- "items": {
691
- "type": "string",
692
- "minLength": 1
693
- }
694
- }
695
- }
696
- }
697
- }
703
+ "description": "The provider's static capability declaration.",
704
+ "$ref": "provider-descriptor.schema.json"
698
705
  },
699
706
  "capabilities": {
700
- "type": "object",
701
- "additionalProperties": true,
702
- "required": [
703
- "available"
704
- ],
705
- "properties": {
706
- "available": {
707
- "type": "boolean"
708
- },
709
- "reason": {
710
- "type": "string",
711
- "minLength": 1
712
- },
713
- "streamingAvailable": {
714
- "description": "Whether the provider can stream right now in this host environment. Absent inherits the static descriptor.supports.streaming value.",
715
- "type": "boolean"
716
- },
717
- "streamingUnavailableReason": {
718
- "description": "Human-readable explanation used when streamingAvailable is false. Absent lets the planner synthesize a default message.",
719
- "type": "string",
720
- "minLength": 1
721
- },
722
- "cancellationAvailable": {
723
- "description": "Whether cancellation is honored right now in this host environment. Absent inherits the static descriptor.cancel value (any value other than 'none' means available).",
724
- "type": "boolean"
725
- }
726
- }
707
+ "description": "The provider's live capability check, already folded by the engine (for example, streamingAvailable is false when the provider declares streaming but does not implement it).",
708
+ "$ref": "provider-dynamic-capabilities.schema.json"
727
709
  }
728
710
  }
729
711
  }
@@ -775,6 +757,10 @@ export const routePlanSchema = {
775
757
  "order": {
776
758
  "type": "integer",
777
759
  "minimum": 0
760
+ },
761
+ "voice": {
762
+ "description": "The voice this candidate must use if it is attempted, chosen by the planner from the provider's dynamic voice inventory. It is the best voice that satisfies the request's locale, required voice traits and privacy — under local-required privacy always one that keeps data on the device — ranked by preferred gender, then exact locale region, then on-device before network. The adapter must use a voice with exactly these traits. Absent when the request names no locale or voice, or the provider does not list its voices; the adapter then chooses itself under the same rules.",
763
+ "$ref": "provider-dynamic-capabilities.schema.json#/$defs/voice"
778
764
  }
779
765
  }
780
766
  }
@@ -805,7 +791,7 @@ export const routePlanSchema = {
805
791
  ],
806
792
  "properties": {
807
793
  "code": {
808
- "description": "Normalized rejection reason. 'streaming_not_supported' means the descriptor does not statically declare Mode-2 streaming; 'streaming_unavailable' means it declares streaming but the dynamic capability snapshot reports it cannot stream in the current host environment. 'not_in_model_profile' means the request named a model profile that does not list this provider.",
794
+ "description": "Normalized rejection reason. 'streaming_not_supported' means the descriptor does not statically declare Mode-2 streaming; 'streaming_unavailable' means it declares streaming but the dynamic capability snapshot reports it cannot stream in the current host environment. 'not_in_model_profile' means the request named a model profile that does not list this provider. 'input_not_supported', 'output_delivery_not_supported', 'output_format_not_supported', 'locale_not_supported' and 'voice_not_available' mean the provider's task capability lacks an input kind, output delivery, media type, locale or voice the request requires.",
809
795
  "enum": [
810
796
  "task_not_supported",
811
797
  "run_not_supported",
@@ -815,7 +801,12 @@ export const routePlanSchema = {
815
801
  "cloud_constraint",
816
802
  "offline",
817
803
  "capability_unavailable",
818
- "not_in_model_profile"
804
+ "not_in_model_profile",
805
+ "input_not_supported",
806
+ "output_delivery_not_supported",
807
+ "output_format_not_supported",
808
+ "locale_not_supported",
809
+ "voice_not_available"
819
810
  ]
820
811
  },
821
812
  "message": {
@@ -1753,6 +1744,455 @@ export const streamTerminalOutcomeSchema = {
1753
1744
  }
1754
1745
  ]
1755
1746
  };
1747
+ export const providerCapabilitySnapshotSchema = {
1748
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1749
+ "$id": "https://schemas.inderun.dev/1.0/provider-capability-snapshot.schema.json",
1750
+ "title": "ProviderCapabilitySnapshot",
1751
+ "description": "One registered provider's identity, static declaration and live capability check, as returned by checkCapabilities(). A read-only snapshot: producing it executes no task and has no side effects.",
1752
+ "type": "object",
1753
+ "additionalProperties": true,
1754
+ "required": [
1755
+ "providerId",
1756
+ "descriptor",
1757
+ "capabilities"
1758
+ ],
1759
+ "properties": {
1760
+ "providerId": {
1761
+ "description": "Identifier of the provider; equal to descriptor.id.",
1762
+ "type": "string",
1763
+ "minLength": 1
1764
+ },
1765
+ "descriptor": {
1766
+ "description": "The provider's static capability declaration.",
1767
+ "$ref": "provider-descriptor.schema.json"
1768
+ },
1769
+ "capabilities": {
1770
+ "description": "The provider's live capability check at the time of the call.",
1771
+ "$ref": "provider-dynamic-capabilities.schema.json"
1772
+ }
1773
+ }
1774
+ };
1775
+ export const providerDescriptorSchema = {
1776
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1777
+ "$id": "https://schemas.inderun.dev/1.0/provider-descriptor.schema.json",
1778
+ "title": "ProviderDescriptor",
1779
+ "description": "A provider's static capability declaration: identity, placement, transport, supported interaction modes and tasks, cancellation guarantee, resource limits and privacy posture. It does not change while the provider is registered. The route planner, checkCapabilities() and execution provenance all read this one shape.",
1780
+ "type": "object",
1781
+ "additionalProperties": true,
1782
+ "required": [
1783
+ "id",
1784
+ "type",
1785
+ "transport",
1786
+ "supports",
1787
+ "cancel",
1788
+ "tasks"
1789
+ ],
1790
+ "properties": {
1791
+ "id": {
1792
+ "description": "Unique identifier of the provider instance (a target), e.g. 'apple_foundation_models' or 'openai_compatible_cloud:gpt-5-mini'. Model profiles list targets by this id.",
1793
+ "type": "string",
1794
+ "minLength": 1
1795
+ },
1796
+ "type": {
1797
+ "title": "ProviderType",
1798
+ "description": "Execution placement: 'local' (on the device), 'edge', or 'cloud'.",
1799
+ "enum": [
1800
+ "local",
1801
+ "edge",
1802
+ "cloud"
1803
+ ]
1804
+ },
1805
+ "model": {
1806
+ "description": "The model this provider instance is bound to, when it can name one. Cloud providers report the model id they send; platform-managed models report an opaque platform alias rather than a guessed weight name. Absent means the provider cannot name its model.",
1807
+ "type": "string",
1808
+ "minLength": 1
1809
+ },
1810
+ "transport": {
1811
+ "title": "ProviderTransport",
1812
+ "description": "How the engine reaches the provider: in-process runtime, operating-system service, buffered HTTP, server-sent events, or a realtime connection.",
1813
+ "enum": [
1814
+ "in_process",
1815
+ "system_service",
1816
+ "http",
1817
+ "sse",
1818
+ "realtime"
1819
+ ]
1820
+ },
1821
+ "streamingStyle": {
1822
+ "title": "StreamingStyle",
1823
+ "description": "How a streaming provider delivers incremental output: individual tokens, larger chunks, or whole snapshots. Absent for providers that do not stream.",
1824
+ "enum": [
1825
+ "tokens",
1826
+ "chunks",
1827
+ "snapshots"
1828
+ ]
1829
+ },
1830
+ "supports": {
1831
+ "title": "ProviderSupports",
1832
+ "description": "Interaction modes and features the provider statically declares.",
1833
+ "type": "object",
1834
+ "additionalProperties": true,
1835
+ "required": [
1836
+ "run",
1837
+ "streaming",
1838
+ "realtime",
1839
+ "tools",
1840
+ "reasoningEvents",
1841
+ "structuredOutput",
1842
+ "multimodal"
1843
+ ],
1844
+ "properties": {
1845
+ "run": {
1846
+ "description": "Whether the provider supports Mode 1 run (request/response).",
1847
+ "type": "boolean"
1848
+ },
1849
+ "streaming": {
1850
+ "description": "Whether the provider supports Mode 2 stream. A provider that declares it must also implement the streaming adapter; the engines report it as unavailable otherwise.",
1851
+ "type": "boolean"
1852
+ },
1853
+ "realtime": {
1854
+ "description": "Whether the provider supports Mode 3 realtime sessions. Reserved; no engine implements Mode 3 yet.",
1855
+ "type": "boolean"
1856
+ },
1857
+ "tools": {
1858
+ "description": "Whether the provider supports tool calling.",
1859
+ "type": "boolean"
1860
+ },
1861
+ "reasoningEvents": {
1862
+ "description": "Whether the provider emits reasoning events alongside content.",
1863
+ "type": "boolean"
1864
+ },
1865
+ "structuredOutput": {
1866
+ "description": "Whether the provider supports structured output constrained by a JSON schema.",
1867
+ "type": "boolean"
1868
+ },
1869
+ "multimodal": {
1870
+ "description": "Whether the provider accepts non-text inputs such as images or audio.",
1871
+ "type": "boolean"
1872
+ }
1873
+ }
1874
+ },
1875
+ "cancel": {
1876
+ "title": "CancelSemantics",
1877
+ "description": "Cancellation guarantee: 'hard' stops processing including remote work, 'soft' stops reading locally while remote work may continue, 'none' means cancellation is unsupported. Independently of this value, the engine delivers no event after a cancel.",
1878
+ "enum": [
1879
+ "hard",
1880
+ "soft",
1881
+ "none"
1882
+ ]
1883
+ },
1884
+ "tasks": {
1885
+ "description": "Task kinds the provider supports, e.g. 'text_to_text'. When taskCapabilities is present it must describe the same kinds and is what routing reads; without it, routing infers capabilities for 'text_to_text' alone (see taskCapabilities).",
1886
+ "type": "array",
1887
+ "items": {
1888
+ "type": "string",
1889
+ "minLength": 1
1890
+ }
1891
+ },
1892
+ "limits": {
1893
+ "title": "ProviderLimits",
1894
+ "description": "Optional input and output resource limits.",
1895
+ "type": "object",
1896
+ "additionalProperties": true,
1897
+ "properties": {
1898
+ "maxInputTokens": {
1899
+ "description": "Largest accepted input, in tokens.",
1900
+ "type": "integer",
1901
+ "minimum": 1
1902
+ },
1903
+ "maxOutputTokens": {
1904
+ "description": "Largest output the provider produces, in tokens.",
1905
+ "type": "integer",
1906
+ "minimum": 1
1907
+ },
1908
+ "maxImageBytes": {
1909
+ "description": "Largest accepted image, in bytes.",
1910
+ "type": "integer",
1911
+ "minimum": 1
1912
+ },
1913
+ "maxAudioSeconds": {
1914
+ "description": "Longest accepted or produced audio, in seconds.",
1915
+ "type": "integer",
1916
+ "minimum": 1
1917
+ }
1918
+ }
1919
+ },
1920
+ "privacy": {
1921
+ "title": "ProviderPrivacy",
1922
+ "description": "Data-egress posture, used to enforce local and cloud routing rules. Absent means a local or edge provider is treated as keeping data on the device and a cloud provider as sending it off.",
1923
+ "type": "object",
1924
+ "additionalProperties": true,
1925
+ "required": [
1926
+ "dataLeavesDevice"
1927
+ ],
1928
+ "properties": {
1929
+ "dataLeavesDevice": {
1930
+ "description": "Whether request content leaves the device.",
1931
+ "type": "boolean"
1932
+ },
1933
+ "regions": {
1934
+ "description": "Geographic regions where a cloud provider processes data.",
1935
+ "type": "array",
1936
+ "items": {
1937
+ "type": "string",
1938
+ "minLength": 1
1939
+ }
1940
+ }
1941
+ }
1942
+ },
1943
+ "taskCapabilities": {
1944
+ "description": "What the provider can do for each task: accepted inputs, interaction modes, output deliveries and formats, cancellation, locales and privacy. When present it is authoritative for routing and must list every task the provider serves. When absent (a legacy descriptor), routing infers exactly one entry — 'text_to_text' with text input, inline output, run/stream from supports and cancel from cancel — if tasks contains 'text_to_text', and nothing for any other task: a legacy descriptor is never treated as capable of a non-text task.",
1945
+ "type": "array",
1946
+ "items": {
1947
+ "$ref": "#/$defs/taskCapability"
1948
+ }
1949
+ }
1950
+ },
1951
+ "$defs": {
1952
+ "taskCapability": {
1953
+ "title": "ProviderTaskCapability",
1954
+ "description": "The provider's static capabilities for one task kind.",
1955
+ "type": "object",
1956
+ "additionalProperties": true,
1957
+ "required": [
1958
+ "kind",
1959
+ "inputs",
1960
+ "interaction",
1961
+ "cancel",
1962
+ "outputs"
1963
+ ],
1964
+ "properties": {
1965
+ "kind": {
1966
+ "description": "The task kind this entry describes, e.g. 'text_to_speech'.",
1967
+ "type": "string",
1968
+ "minLength": 1
1969
+ },
1970
+ "inputs": {
1971
+ "description": "Input media kinds the provider accepts for this task.",
1972
+ "type": "array",
1973
+ "minItems": 1,
1974
+ "items": {
1975
+ "$ref": "#/$defs/inputKind"
1976
+ }
1977
+ },
1978
+ "interaction": {
1979
+ "title": "ProviderTaskInteraction",
1980
+ "description": "Interaction modes the provider supports for this task.",
1981
+ "type": "object",
1982
+ "additionalProperties": true,
1983
+ "required": [
1984
+ "run",
1985
+ "stream"
1986
+ ],
1987
+ "properties": {
1988
+ "run": {
1989
+ "description": "Whether the provider supports Mode 1 run for this task.",
1990
+ "type": "boolean"
1991
+ },
1992
+ "stream": {
1993
+ "description": "Whether the provider supports Mode 2 stream for this task.",
1994
+ "type": "boolean"
1995
+ }
1996
+ }
1997
+ },
1998
+ "cancel": {
1999
+ "description": "Cancellation guarantee for this task. It may differ from the provider-level cancel, e.g. when stopping playback is immediate but a synthesis request cannot be aborted.",
2000
+ "$ref": "#/properties/cancel"
2001
+ },
2002
+ "outputs": {
2003
+ "description": "How results of this task can be delivered. A provider lists only what it really produces: a provider that can only play audio lists 'playback' and never 'artifact'.",
2004
+ "type": "array",
2005
+ "minItems": 1,
2006
+ "items": {
2007
+ "$ref": "#/$defs/taskOutput"
2008
+ }
2009
+ },
2010
+ "locales": {
2011
+ "description": "BCP 47 locales the provider can serve for this task, when it knows them statically. Absent means unknown; the dynamic check may report them instead.",
2012
+ "type": "array",
2013
+ "items": {
2014
+ "type": "string",
2015
+ "minLength": 1
2016
+ }
2017
+ },
2018
+ "privacy": {
2019
+ "description": "Data-egress posture for this task when it differs from the provider-level privacy, e.g. a provider whose speech synthesis uses a network service. Absent inherits descriptor.privacy.",
2020
+ "$ref": "#/properties/privacy"
2021
+ }
2022
+ }
2023
+ },
2024
+ "taskOutput": {
2025
+ "title": "ProviderTaskOutput",
2026
+ "description": "One way the provider can deliver a task's result.",
2027
+ "type": "object",
2028
+ "additionalProperties": true,
2029
+ "required": [
2030
+ "delivery"
2031
+ ],
2032
+ "properties": {
2033
+ "delivery": {
2034
+ "$ref": "#/$defs/outputDelivery"
2035
+ },
2036
+ "mediaTypes": {
2037
+ "description": "Media types the provider can produce with this delivery, e.g. 'audio/wav'. Absent means the provider does not declare them; a request that requires specific media types never routes to such an output.",
2038
+ "type": "array",
2039
+ "items": {
2040
+ "type": "string",
2041
+ "minLength": 1
2042
+ }
2043
+ }
2044
+ }
2045
+ },
2046
+ "inputKind": {
2047
+ "title": "TaskInputKind",
2048
+ "description": "A kind of input medium a task consumes.",
2049
+ "enum": [
2050
+ "text",
2051
+ "image",
2052
+ "audio"
2053
+ ]
2054
+ },
2055
+ "outputDelivery": {
2056
+ "title": "OutputDelivery",
2057
+ "description": "How a task's result reaches the application: 'inline' content in the result (text), 'playback' as a managed, audible effect on the device with no retrievable bytes, or 'artifact' as retrievable media.",
2058
+ "enum": [
2059
+ "inline",
2060
+ "playback",
2061
+ "artifact"
2062
+ ]
2063
+ }
2064
+ }
2065
+ };
2066
+ export const providerDynamicCapabilitiesSchema = {
2067
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
2068
+ "$id": "https://schemas.inderun.dev/1.0/provider-dynamic-capabilities.schema.json",
2069
+ "title": "ProviderDynamicCapabilities",
2070
+ "$comment": "streamingAvailable and cancellationAvailable are tri-state on purpose: true, false, or absent. Absent means 'inherit the static declaration' and is a distinct state from both booleans. They must never become nullable: null would be a fourth state no consumer handles, and bridges omit the key specifically to preserve 'absent'.",
2071
+ "description": "A provider's live capability check, evaluated on the current host when routing or when checkCapabilities() is called. Unlike the descriptor it can change between calls.",
2072
+ "type": "object",
2073
+ "additionalProperties": true,
2074
+ "required": [
2075
+ "available"
2076
+ ],
2077
+ "properties": {
2078
+ "available": {
2079
+ "description": "Whether the provider is available and functional on this host right now.",
2080
+ "type": "boolean"
2081
+ },
2082
+ "reason": {
2083
+ "description": "Why the provider is unavailable, when available is false.",
2084
+ "type": "string",
2085
+ "minLength": 1
2086
+ },
2087
+ "streamingAvailable": {
2088
+ "description": "Whether the provider can stream (Mode 2) on this host right now. Absent inherits the static descriptor.supports.streaming value; only set it when the host takes streaming away from a provider that otherwise declares it. Never null.",
2089
+ "type": "boolean"
2090
+ },
2091
+ "streamingUnavailableReason": {
2092
+ "description": "Why streaming is unavailable, when streamingAvailable is false. Absent lets the route planner synthesize a default message.",
2093
+ "type": "string",
2094
+ "minLength": 1
2095
+ },
2096
+ "cancellationAvailable": {
2097
+ "description": "Whether cancellation is honored on this host right now. Absent inherits the static descriptor.cancel value: any value other than 'none' means available. Never null.",
2098
+ "type": "boolean"
2099
+ },
2100
+ "taskCapabilities": {
2101
+ "description": "Per-task overrides of the provider-level check, for tasks whose availability differs on this host, e.g. a voice that is not installed. Every field of an entry is optional and absent inherits the provider-level value; a false at either level wins.",
2102
+ "type": "array",
2103
+ "items": {
2104
+ "$ref": "#/$defs/taskAvailability"
2105
+ }
2106
+ }
2107
+ },
2108
+ "$defs": {
2109
+ "taskAvailability": {
2110
+ "title": "ProviderTaskAvailability",
2111
+ "description": "The live check for one task kind.",
2112
+ "type": "object",
2113
+ "additionalProperties": true,
2114
+ "required": [
2115
+ "kind"
2116
+ ],
2117
+ "properties": {
2118
+ "kind": {
2119
+ "description": "The task kind this entry describes.",
2120
+ "type": "string",
2121
+ "minLength": 1
2122
+ },
2123
+ "available": {
2124
+ "description": "Whether the task can run on this host right now. Absent inherits the provider-level available. Never null.",
2125
+ "type": "boolean"
2126
+ },
2127
+ "reason": {
2128
+ "description": "Why the task is unavailable, when available is false.",
2129
+ "type": "string",
2130
+ "minLength": 1
2131
+ },
2132
+ "streamingAvailable": {
2133
+ "description": "Whether the task can stream on this host right now. Absent inherits. Never null.",
2134
+ "type": "boolean"
2135
+ },
2136
+ "streamingUnavailableReason": {
2137
+ "description": "Why streaming is unavailable for this task, when streamingAvailable is false.",
2138
+ "type": "string",
2139
+ "minLength": 1
2140
+ },
2141
+ "cancellationAvailable": {
2142
+ "description": "Whether cancellation is honored for this task right now. Absent inherits. Never null.",
2143
+ "type": "boolean"
2144
+ },
2145
+ "locales": {
2146
+ "description": "BCP 47 locales available for this task right now. Absent means the provider cannot enumerate them.",
2147
+ "type": "array",
2148
+ "items": {
2149
+ "type": "string",
2150
+ "minLength": 1
2151
+ }
2152
+ },
2153
+ "voices": {
2154
+ "description": "Voices available for this task right now. Absent means the provider cannot enumerate them; a request that requires a voice then never routes to it.",
2155
+ "type": "array",
2156
+ "items": {
2157
+ "$ref": "#/$defs/voice"
2158
+ }
2159
+ }
2160
+ }
2161
+ },
2162
+ "voice": {
2163
+ "title": "ProviderVoice",
2164
+ "description": "Provider-neutral traits of one available voice. Carries no provider voice identifier.",
2165
+ "type": "object",
2166
+ "additionalProperties": true,
2167
+ "required": [
2168
+ "locale"
2169
+ ],
2170
+ "properties": {
2171
+ "locale": {
2172
+ "description": "BCP 47 locale the voice speaks.",
2173
+ "type": "string",
2174
+ "minLength": 1
2175
+ },
2176
+ "gender": {
2177
+ "$ref": "#/$defs/voiceGender"
2178
+ },
2179
+ "networkRequired": {
2180
+ "description": "Whether using the voice sends data off the device. Absent inherits the task's privacy posture.",
2181
+ "type": "boolean"
2182
+ }
2183
+ }
2184
+ },
2185
+ "voiceGender": {
2186
+ "title": "VoiceGender",
2187
+ "description": "Perceived gender of a voice, as the platform reports it.",
2188
+ "enum": [
2189
+ "female",
2190
+ "male",
2191
+ "neutral"
2192
+ ]
2193
+ }
2194
+ }
2195
+ };
1756
2196
  export const executionProvenanceSchema = {
1757
2197
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1758
2198
  "$id": "https://schemas.inderun.dev/1.0/execution-provenance.schema.json",
@@ -1880,7 +2320,12 @@ export const executionProvenanceSchema = {
1880
2320
  "cloud_constraint",
1881
2321
  "offline",
1882
2322
  "capability_unavailable",
1883
- "not_in_model_profile"
2323
+ "not_in_model_profile",
2324
+ "input_not_supported",
2325
+ "output_delivery_not_supported",
2326
+ "output_format_not_supported",
2327
+ "locale_not_supported",
2328
+ "voice_not_available"
1884
2329
  ]
1885
2330
  }
1886
2331
  }