@every-app/sdk 0.3.0-rc.1 → 0.3.0-rc.10

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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/cloudflare/catalogSettings.generated.d.ts +81 -0
  4. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  5. package/dist/cloudflare/catalogSettings.generated.js +174 -0
  6. package/dist/cloudflare/index.d.ts +3 -2
  7. package/dist/cloudflare/index.d.ts.map +1 -1
  8. package/dist/cloudflare/index.js +4 -1
  9. package/dist/cloudflare/sentinel.d.ts +60 -2
  10. package/dist/cloudflare/sentinel.d.ts.map +1 -1
  11. package/dist/cloudflare/sentinel.js +37 -2
  12. package/dist/cloudflare/worker.d.ts +357 -63
  13. package/dist/cloudflare/worker.d.ts.map +1 -1
  14. package/dist/cloudflare/worker.js +363 -104
  15. package/dist/dev/index.d.ts +1 -1
  16. package/dist/dev/index.d.ts.map +1 -1
  17. package/dist/dev/index.js +1 -1
  18. package/dist/dev/keypair.d.ts +2 -0
  19. package/dist/dev/keypair.d.ts.map +1 -1
  20. package/dist/dev/keypair.js +2 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/internal/aiDefault.d.ts +204 -0
  25. package/dist/internal/aiDefault.d.ts.map +1 -0
  26. package/dist/internal/aiDefault.js +334 -0
  27. package/dist/internal/aiProviders.d.ts +7 -2
  28. package/dist/internal/aiProviders.d.ts.map +1 -1
  29. package/dist/internal/aiProviders.js +17 -4
  30. package/dist/internal/appSettings.d.ts +82 -4
  31. package/dist/internal/appSettings.d.ts.map +1 -1
  32. package/dist/internal/appSettings.js +204 -29
  33. package/dist/internal/audit.d.ts +108 -0
  34. package/dist/internal/audit.d.ts.map +1 -0
  35. package/dist/internal/audit.js +235 -0
  36. package/dist/internal/capabilities.d.ts +2268 -438
  37. package/dist/internal/capabilities.d.ts.map +1 -1
  38. package/dist/internal/capabilities.js +128 -539
  39. package/dist/internal/catalog/commerce.d.ts +394 -0
  40. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  41. package/dist/internal/catalog/commerce.js +477 -0
  42. package/dist/internal/catalog/comms.d.ts +375 -0
  43. package/dist/internal/catalog/comms.d.ts.map +1 -0
  44. package/dist/internal/catalog/comms.js +520 -0
  45. package/dist/internal/catalog/index.d.ts +1973 -0
  46. package/dist/internal/catalog/index.d.ts.map +1 -0
  47. package/dist/internal/catalog/index.js +19 -0
  48. package/dist/internal/catalog/inference.d.ts +393 -0
  49. package/dist/internal/catalog/inference.d.ts.map +1 -0
  50. package/dist/internal/catalog/inference.js +460 -0
  51. package/dist/internal/catalog/infra.d.ts +423 -0
  52. package/dist/internal/catalog/infra.d.ts.map +1 -0
  53. package/dist/internal/catalog/infra.js +543 -0
  54. package/dist/internal/catalog/search.d.ts +400 -0
  55. package/dist/internal/catalog/search.d.ts.map +1 -0
  56. package/dist/internal/catalog/search.js +463 -0
  57. package/dist/internal/devProviders.d.ts +2 -2
  58. package/dist/internal/devProviders.d.ts.map +1 -1
  59. package/dist/internal/devProviders.js +19 -1
  60. package/dist/internal/events.d.ts +13 -2
  61. package/dist/internal/events.d.ts.map +1 -1
  62. package/dist/internal/events.js +47 -4
  63. package/dist/internal/gatewaySettings.d.ts +3 -2
  64. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  65. package/dist/internal/gatewaySettings.js +12 -6
  66. package/dist/internal/identity.d.ts +41 -4
  67. package/dist/internal/identity.d.ts.map +1 -1
  68. package/dist/internal/identity.js +48 -10
  69. package/dist/internal/index.d.ts +6 -1
  70. package/dist/internal/index.d.ts.map +1 -1
  71. package/dist/internal/index.js +6 -1
  72. package/dist/internal/members.d.ts +3 -2
  73. package/dist/internal/members.d.ts.map +1 -1
  74. package/dist/internal/oauthClient.d.ts +10 -12
  75. package/dist/internal/oauthClient.d.ts.map +1 -1
  76. package/dist/internal/oauthClient.js +20 -81
  77. package/dist/internal/oauthPresets.d.ts +33 -0
  78. package/dist/internal/oauthPresets.d.ts.map +1 -0
  79. package/dist/internal/oauthPresets.js +1064 -0
  80. package/dist/internal/oauthScopes.d.ts +56 -1
  81. package/dist/internal/oauthScopes.d.ts.map +1 -1
  82. package/dist/internal/oauthScopes.js +98 -4
  83. package/dist/internal/oauthSpec.d.ts +102 -0
  84. package/dist/internal/oauthSpec.d.ts.map +1 -0
  85. package/dist/internal/oauthSpec.js +789 -0
  86. package/dist/internal/protocol.d.ts +64 -1
  87. package/dist/internal/protocol.d.ts.map +1 -1
  88. package/dist/internal/protocol.js +51 -1
  89. package/dist/internal/providerRegistry.d.ts +77 -6
  90. package/dist/internal/providerRegistry.d.ts.map +1 -1
  91. package/dist/internal/providerRegistry.js +178 -8
  92. package/dist/internal/providerSpec.d.ts +18 -7
  93. package/dist/internal/providerSpec.d.ts.map +1 -1
  94. package/dist/internal/providerSpec.js +442 -34
  95. package/dist/internal/signInProviders.d.ts +104 -0
  96. package/dist/internal/signInProviders.d.ts.map +1 -0
  97. package/dist/internal/signInProviders.js +245 -0
  98. package/dist/manifest.d.ts +238 -0
  99. package/dist/manifest.d.ts.map +1 -0
  100. package/dist/manifest.js +30 -0
  101. package/dist/server/ai.d.ts +111 -0
  102. package/dist/server/ai.d.ts.map +1 -0
  103. package/dist/server/ai.js +145 -0
  104. package/dist/server/aiBinding.d.ts +68 -0
  105. package/dist/server/aiBinding.d.ts.map +1 -0
  106. package/dist/server/aiBinding.js +294 -0
  107. package/dist/server/attribution.d.ts +9 -5
  108. package/dist/server/attribution.d.ts.map +1 -1
  109. package/dist/server/attribution.js +12 -4
  110. package/dist/server/authorizeUrl.d.ts +1 -1
  111. package/dist/server/authorizeUrl.d.ts.map +1 -1
  112. package/dist/server/authorizeUrl.js +2 -6
  113. package/dist/server/connectUrl.d.ts +21 -0
  114. package/dist/server/connectUrl.d.ts.map +1 -0
  115. package/dist/server/connectUrl.js +37 -0
  116. package/dist/server/context.d.ts +68 -0
  117. package/dist/server/context.d.ts.map +1 -0
  118. package/dist/server/context.js +117 -0
  119. package/dist/server/emailBinding.d.ts +72 -0
  120. package/dist/server/emailBinding.d.ts.map +1 -0
  121. package/dist/server/emailBinding.js +124 -0
  122. package/dist/server/emit.d.ts +1 -1
  123. package/dist/server/emit.d.ts.map +1 -1
  124. package/dist/server/emit.js +7 -7
  125. package/dist/server/env.d.ts +44 -0
  126. package/dist/server/env.d.ts.map +1 -0
  127. package/dist/server/env.js +1 -0
  128. package/dist/server/everyApp.d.ts +27 -7
  129. package/dist/server/everyApp.d.ts.map +1 -1
  130. package/dist/server/everyApp.js +106 -5
  131. package/dist/server/fromMcpTools.d.ts +89 -0
  132. package/dist/server/fromMcpTools.d.ts.map +1 -0
  133. package/dist/server/fromMcpTools.js +192 -0
  134. package/dist/server/gatewayFetch.d.ts +42 -18
  135. package/dist/server/gatewayFetch.d.ts.map +1 -1
  136. package/dist/server/gatewayFetch.js +138 -19
  137. package/dist/server/gatewayUrl.d.ts +13 -0
  138. package/dist/server/gatewayUrl.d.ts.map +1 -0
  139. package/dist/server/gatewayUrl.js +34 -0
  140. package/dist/server/index.d.ts +15 -4
  141. package/dist/server/index.d.ts.map +1 -1
  142. package/dist/server/index.js +12 -2
  143. package/dist/server/integrationFetch.d.ts +70 -39
  144. package/dist/server/integrationFetch.d.ts.map +1 -1
  145. package/dist/server/integrationFetch.js +244 -82
  146. package/dist/server/listMembers.d.ts +1 -1
  147. package/dist/server/listMembers.d.ts.map +1 -1
  148. package/dist/server/listMembers.js +8 -11
  149. package/dist/server/refusal.d.ts +55 -0
  150. package/dist/server/refusal.d.ts.map +1 -0
  151. package/dist/server/refusal.js +193 -0
  152. package/dist/server/sendEmail.d.ts +1 -1
  153. package/dist/server/sendEmail.d.ts.map +1 -1
  154. package/dist/server/sendEmail.js +7 -7
  155. package/dist/server/toolsEndpoint.d.ts.map +1 -1
  156. package/dist/server/toolsEndpoint.js +11 -5
  157. package/dist/tanstack-start/index.d.ts +9 -0
  158. package/dist/tanstack-start/index.d.ts.map +1 -0
  159. package/dist/tanstack-start/index.js +29 -0
  160. package/dist/testing/index.d.ts +93 -0
  161. package/dist/testing/index.d.ts.map +1 -0
  162. package/dist/testing/index.js +156 -0
  163. package/package.json +35 -14
@@ -17,6 +17,8 @@
17
17
  */
18
18
  /** Issuer of locally minted dev identity tokens. */
19
19
  export declare const DEV_ISSUER = "https://gateway.dev.localhost";
20
+ /** The organization the dev gateway's seeded user belongs to (`everyAppWorker()` sets it as `EVERY_APP_ORG_ID` in dev). */
21
+ export declare const DEV_ORG_ID = "dev-org";
20
22
  /** SPKI PEM public half of the dev keypair. */
21
23
  export declare const DEV_PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh40zWf+QK3rJdMTNoy+X\nF9iydV5raWSeEt4DXyeY98c8IZHRjy2UXaaYejweebRsv9Az+bZuL3cfJ0E7pOGd\n4VCOiSG1BjJglmTC1whV4Md6qhLDVOP6iztUJSxDwnlR85UtOyNJ4G5dYY6RrAWl\nPMMXPSYdGWqAP4n5QXAw+7uTFmJMdWy1W8KLbTj//NSGn3DCm+EZJIC8q9yDhMSc\nM0ejJnBVColvp4T8k8dt2kYGu2Wd7dCMrHv/lxUoqD58avpdMOzbaZtwsQ7BAaIa\nmIeQ1AKxmnCj1np23uWvYQmoaZocvupLSALK7fWGUyVDZ+RW4HtN5KqzZypfiyZ8\nkQIDAQAB\n-----END PUBLIC KEY-----\n";
22
24
  /** PKCS#8 PEM private half of the dev keypair. Public, see above. */
@@ -1 +1 @@
1
- {"version":3,"file":"keypair.d.ts","sourceRoot":"","sources":["../../src/dev/keypair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,oDAAoD;AACpD,eAAO,MAAM,UAAU,kCAAkC,CAAC;AAE1D,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,idAS9B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,ysDA4B/B,CAAC"}
1
+ {"version":3,"file":"keypair.d.ts","sourceRoot":"","sources":["../../src/dev/keypair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,oDAAoD;AACpD,eAAO,MAAM,UAAU,kCAAkC,CAAC;AAC1D,2HAA2H;AAC3H,eAAO,MAAM,UAAU,YAAY,CAAC;AAEpC,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,idAS9B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,ysDA4B/B,CAAC"}
@@ -17,6 +17,8 @@
17
17
  */
18
18
  /** Issuer of locally minted dev identity tokens. */
19
19
  export const DEV_ISSUER = "https://gateway.dev.localhost";
20
+ /** The organization the dev gateway's seeded user belongs to (`everyAppWorker()` sets it as `EVERY_APP_ORG_ID` in dev). */
21
+ export const DEV_ORG_ID = "dev-org";
20
22
  /** SPKI PEM public half of the dev keypair. */
21
23
  export const DEV_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
22
24
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh40zWf+QK3rJdMTNoy+X
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @every-app/sdk — what `everyapp.config.ts` imports: `defineEveryApp` and
3
+ * the manifest's types. A leaf, like the config itself (see ./manifest.ts).
4
+ */
5
+ export { defineEveryApp, type EveryAppCapabilityEntry, type EveryAppClassResource, type EveryAppManifest, type EveryAppPublicRoute, type EveryAppQueueConsumer, type EveryAppResources, type EveryAppSecretEntry, type EveryAppSettingEntry, type EveryAppSettingNeed, type EveryAppWorkerLimits, } from "./manifest.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @every-app/sdk — what `everyapp.config.ts` imports: `defineEveryApp` and
3
+ * the manifest's types. A leaf, like the config itself (see ./manifest.ts).
4
+ */
5
+ export { defineEveryApp, } from "./manifest.js";
@@ -0,0 +1,204 @@
1
+ /**
2
+ * The Gateway's default model provider: what an app that says "I need a
3
+ * chat model" (manifest `ai: { chat: true }`, the SDK's `ai()`, the route
4
+ * `/api/ai/default/…`) is served (docs/design/2026-10-model-providers.md).
5
+ *
6
+ * The default is resolved, never assumed: the operator's choice when one
7
+ * is stored (`everyapp ai default <provider>[/<model>]`, Manage workspace
8
+ * → Usage → AI default), else the shipped order below, first provider
9
+ * whose Gateway settings are all set; with none set, the first of the
10
+ * order with the settings it needs, so "Needs setup" asks for one key.
11
+ * OpenRouter comes first because one key reaches many models; Workers AI
12
+ * second because it needs no provider account (the Gateway's own
13
+ * Cloudflare token), with weaker models; then the single-vendor keys.
14
+ * Cloudflare AI Gateway is never a default: it has no models of its own
15
+ * and fronts whichever provider the default resolves to when
16
+ * `AI_GATEWAY_ID` is set (./capabilities.ts, `aig`).
17
+ *
18
+ * The models resolve the same way: the operator's model setting for the
19
+ * provider (`everyapp ai model <provider> --chat … --embeddings …`,
20
+ * `org_settings.ai_models`), else the catalog entry's seed (`chat.seedModel`,
21
+ * `embeddings.seedModel`). Nothing reads a seed except through here.
22
+ *
23
+ * Everything here is pure: what is set is asked of the caller (`isSet`),
24
+ * which reads the Gateway's env, the Worker's secret names, or `.dev.vars`.
25
+ */
26
+ import { type AiProviderCapability, type AiRoute, type Capability, type CapabilityLookup } from "./capabilities.js";
27
+ /** The reserved provider id apps call for the default: `/api/ai/default/…`. */
28
+ export declare const AI_DEFAULT_PROVIDER = "default";
29
+ /** The catalog id of Cloudflare AI Gateway, the proxy entry. */
30
+ export declare const AI_GATEWAY_PROVIDER = "ai-gateway";
31
+ /** The settings that make AI Gateway front the providers that have a slug. */
32
+ export declare const AI_GATEWAY_SETTINGS: readonly ["AI_GATEWAY_ID", "CLOUDFLARE_ACCOUNT_ID"];
33
+ /**
34
+ * The shipped order: the provider the default resolves to when the
35
+ * operator chose none, the first of these whose settings are set.
36
+ */
37
+ export declare const AI_DEFAULT_ORDER: readonly string[];
38
+ /** The model name an app sends to mean "the default's model". */
39
+ export declare const AI_DEFAULT_MODEL = "default";
40
+ /** The paths an app calls under `/api/ai/default`, OpenAI-shaped. */
41
+ export declare const AI_DEFAULT_ROUTES: {
42
+ readonly chat: "/v1/chat/completions";
43
+ readonly embeddings: "/v1/embeddings";
44
+ };
45
+ export type AiDefaultRoute = keyof typeof AI_DEFAULT_ROUTES;
46
+ /**
47
+ * A choice as typed (`everyapp ai default openrouter/anthropic/claude-sonnet-5.5`,
48
+ * the Usage page's dialog, `everyapp_ai_default`): the provider, and the
49
+ * chat model to store for it. The provider goes to `org_settings.ai_default`,
50
+ * the model to that provider's `chat` in `org_settings.ai_models`.
51
+ */
52
+ export interface AiDefaultChoice {
53
+ provider: string;
54
+ model?: string;
55
+ }
56
+ /** The operator's models for one provider; a field left out serves the seed. */
57
+ export interface AiModelSetting {
58
+ chat?: string;
59
+ embeddings?: string;
60
+ }
61
+ /** The operator's models by provider id (`org_settings.ai_models`, JSON). */
62
+ export type AiModelSettings = Readonly<Record<string, AiModelSetting>>;
63
+ /** A change to one provider's models: a name sets it, null puts the seed back, absent leaves it. */
64
+ export interface AiModelPatch {
65
+ chat?: string | null;
66
+ embeddings?: string | null;
67
+ }
68
+ /** Whether `value` can be a model id: 1 to 200 characters, no surrounding or control whitespace. */
69
+ export declare function isAiModelName(value: string): boolean;
70
+ /**
71
+ * `org_settings.ai_models` as stored: a JSON object of provider id →
72
+ * `{ chat?, embeddings? }`. Anything else (null, malformed JSON, a field
73
+ * that isn't a model name) reads as no setting, so the seed serves.
74
+ */
75
+ export declare function parseAiModelSettings(value: string | null | undefined): AiModelSettings;
76
+ /** The stored text of the settings, providers sorted; null when nothing is set. */
77
+ export declare function formatAiModelSettings(settings: AiModelSettings): string | null;
78
+ /** `settings` with one provider's models changed by `patch`. */
79
+ export declare function withAiModelSetting(settings: AiModelSettings, provider: string, patch: AiModelPatch): AiModelSettings;
80
+ /**
81
+ * `openrouter` or `openrouter/anthropic/claude-haiku-5.5` as typed:
82
+ * the provider id up to the first slash, the model after it (a model id
83
+ * may hold slashes of its own). Null for blank or malformed text.
84
+ */
85
+ export declare function parseAiDefaultChoice(value: string | null | undefined): AiDefaultChoice | null;
86
+ /** The text of a choice: `provider` or `provider/model`. */
87
+ export declare function formatAiDefaultChoice(choice: AiDefaultChoice): string;
88
+ /**
89
+ * The provider id `org_settings.ai_default` holds, or null. The column
90
+ * holds the provider alone (its models are in `ai_models`); text after a
91
+ * first slash is not read.
92
+ */
93
+ export declare function parseAiDefaultProvider(value: string | null | undefined): string | null;
94
+ /** Whether `name` holds a value, as the Gateway's env or a secret list says. */
95
+ export type IsSet = (name: string) => boolean;
96
+ /** An `ai` entry the default may resolve to: not the proxy, with a chat route. */
97
+ export type AiDefaultCapability = AiProviderCapability & {
98
+ chat: AiRoute;
99
+ };
100
+ export declare function canBeAiDefault(capability: Capability | undefined): capability is AiDefaultCapability;
101
+ /**
102
+ * The Gateway settings an `ai` entry needs before it serves: its key
103
+ * (unless the entry works without one, `authOptional`) and what its URL
104
+ * needs besides (`alsoNeeds`).
105
+ */
106
+ export declare function aiRequiredSettings(capability: AiProviderCapability): string[];
107
+ /** Whether every setting the entry needs is set. */
108
+ export declare function aiProviderConfigured(capability: AiProviderCapability, isSet: IsSet): boolean;
109
+ /** Whether AI Gateway fronts calls: its id and the account are set. */
110
+ export declare function aiGatewayConfigured(isSet: IsSet): boolean;
111
+ /** Whether a call to `capability` goes through AI Gateway: it is configured and the entry has a slug. */
112
+ export declare function viaAiGateway(capability: AiProviderCapability, isSet: IsSet): boolean;
113
+ /** One provider the default may resolve to, with its state on this Gateway. */
114
+ export interface AiDefaultCandidate {
115
+ id: string;
116
+ label: string;
117
+ /** The Gateway settings it needs; what to set when it isn't configured. */
118
+ settings: string[];
119
+ configured: boolean;
120
+ /** The chat model the Gateway fills in when the app names none: the operator's setting, else the seed. */
121
+ model: string;
122
+ /** The embeddings model, the same way; absent when the entry has no embeddings route. */
123
+ embeddingsModel?: string;
124
+ /** The catalog's seeds: what serves where the operator set no model. */
125
+ seed: {
126
+ chat: string;
127
+ embeddings?: string;
128
+ };
129
+ /** Through Cloudflare AI Gateway, as things are set now. */
130
+ viaAiGateway: boolean;
131
+ embeddings: boolean;
132
+ }
133
+ /** Where the resolved default came from. */
134
+ export type AiDefaultSource =
135
+ /** The operator's stored choice. */
136
+ "setting"
137
+ /** The shipped order: the first provider that is configured. */
138
+ | "order"
139
+ /** Nothing is configured: the first of the order, with what to set. */
140
+ | "none";
141
+ export interface AiDefaultResolution {
142
+ provider: string;
143
+ label: string;
144
+ /** The chat model the default serves: the operator's setting for the provider, else the seed. */
145
+ model: string;
146
+ /** The embeddings model, the same way; absent when the provider has no embeddings route. */
147
+ embeddingsModel?: string;
148
+ /** The provider's seeds. */
149
+ seed: {
150
+ chat: string;
151
+ embeddings?: string;
152
+ };
153
+ source: AiDefaultSource;
154
+ /** Every setting the provider needs is set, so the default serves. */
155
+ configured: boolean;
156
+ /** The Gateway settings the provider needs: what to set when it isn't configured. */
157
+ settings: string[];
158
+ via: "ai-gateway" | "direct";
159
+ chat: AiRoute;
160
+ embeddings?: AiRoute;
161
+ /** Every provider the default could be, in the shipped order, the choice first. */
162
+ candidates: AiDefaultCandidate[];
163
+ /**
164
+ * The stored choice names something the default can't be (an id the
165
+ * catalog doesn't have, an entry with no chat route, the proxy): the
166
+ * order decided instead, and this says why.
167
+ */
168
+ problem?: string;
169
+ }
170
+ /**
171
+ * Every provider the default may resolve to: the shipped order first,
172
+ * then any other `ai` entry of `lookup` with a chat route (a registered
173
+ * row, one day), each with its state.
174
+ */
175
+ export declare function aiDefaultCandidates(isSet: IsSet, lookup?: CapabilityLookup, models?: AiModelSettings): AiDefaultCandidate[];
176
+ /** Why `choice.provider` can't be the default, or null when it can. */
177
+ export declare function aiDefaultChoiceProblem(choice: AiDefaultChoice, lookup?: CapabilityLookup): string | null;
178
+ /**
179
+ * Why `patch` can't be stored for `provider`, or null when it can: the
180
+ * provider must be one the default can be, a model name must be a model
181
+ * name, and an embeddings model needs the entry's embeddings route.
182
+ */
183
+ export declare function aiModelPatchProblem(provider: string, patch: AiModelPatch, lookup?: CapabilityLookup): string | null;
184
+ /**
185
+ * The Gateway's effective default, from the stored choice (or none) and
186
+ * what is set. A choice that names a provider which isn't configured
187
+ * still wins (the operator chose it: `configured` is false and `settings`
188
+ * says what to set); a choice the default can't be is reported as
189
+ * `problem` and the order decides.
190
+ */
191
+ export declare function resolveAiDefault(input: {
192
+ /** The stored provider (`org_settings.ai_default`), or null for the shipped order. */
193
+ provider: string | null;
194
+ /** The operator's models by provider (`org_settings.ai_models`); none: the seeds serve. */
195
+ models?: AiModelSettings;
196
+ isSet: IsSet;
197
+ lookup?: CapabilityLookup;
198
+ }): AiDefaultResolution;
199
+ /**
200
+ * The sentence setup shows for an unconfigured default: the one key to
201
+ * set, and the alternatives in the order.
202
+ */
203
+ export declare function aiDefaultSetupHint(resolution: AiDefaultResolution): string;
204
+ //# sourceMappingURL=aiDefault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiDefault.d.ts","sourceRoot":"","sources":["../../src/internal/aiDefault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,334 @@
1
+ /**
2
+ * The Gateway's default model provider: what an app that says "I need a
3
+ * chat model" (manifest `ai: { chat: true }`, the SDK's `ai()`, the route
4
+ * `/api/ai/default/…`) is served (docs/design/2026-10-model-providers.md).
5
+ *
6
+ * The default is resolved, never assumed: the operator's choice when one
7
+ * is stored (`everyapp ai default <provider>[/<model>]`, Manage workspace
8
+ * → Usage → AI default), else the shipped order below, first provider
9
+ * whose Gateway settings are all set; with none set, the first of the
10
+ * order with the settings it needs, so "Needs setup" asks for one key.
11
+ * OpenRouter comes first because one key reaches many models; Workers AI
12
+ * second because it needs no provider account (the Gateway's own
13
+ * Cloudflare token), with weaker models; then the single-vendor keys.
14
+ * Cloudflare AI Gateway is never a default: it has no models of its own
15
+ * and fronts whichever provider the default resolves to when
16
+ * `AI_GATEWAY_ID` is set (./capabilities.ts, `aig`).
17
+ *
18
+ * The models resolve the same way: the operator's model setting for the
19
+ * provider (`everyapp ai model <provider> --chat … --embeddings …`,
20
+ * `org_settings.ai_models`), else the catalog entry's seed (`chat.seedModel`,
21
+ * `embeddings.seedModel`). Nothing reads a seed except through here.
22
+ *
23
+ * Everything here is pure: what is set is asked of the caller (`isSet`),
24
+ * which reads the Gateway's env, the Worker's secret names, or `.dev.vars`.
25
+ */
26
+ import { CATALOG, } from "./capabilities.js";
27
+ /** The reserved provider id apps call for the default: `/api/ai/default/…`. */
28
+ export const AI_DEFAULT_PROVIDER = "default";
29
+ /** The catalog id of Cloudflare AI Gateway, the proxy entry. */
30
+ export const AI_GATEWAY_PROVIDER = "ai-gateway";
31
+ /** The settings that make AI Gateway front the providers that have a slug. */
32
+ export const AI_GATEWAY_SETTINGS = [
33
+ "AI_GATEWAY_ID",
34
+ "CLOUDFLARE_ACCOUNT_ID",
35
+ ];
36
+ /**
37
+ * The shipped order: the provider the default resolves to when the
38
+ * operator chose none, the first of these whose settings are set.
39
+ */
40
+ export const AI_DEFAULT_ORDER = [
41
+ "openrouter",
42
+ "workers-ai",
43
+ "openai",
44
+ "anthropic",
45
+ "groq",
46
+ "mistral",
47
+ "gemini",
48
+ ];
49
+ /** The model name an app sends to mean "the default's model". */
50
+ export const AI_DEFAULT_MODEL = "default";
51
+ /** The paths an app calls under `/api/ai/default`, OpenAI-shaped. */
52
+ export const AI_DEFAULT_ROUTES = {
53
+ chat: "/v1/chat/completions",
54
+ embeddings: "/v1/embeddings",
55
+ };
56
+ /** Whether `value` can be a model id: 1 to 200 characters, no surrounding or control whitespace. */
57
+ export function isAiModelName(value) {
58
+ return (value.length >= 1 &&
59
+ value.length <= 200 &&
60
+ value.trim() === value &&
61
+ !/[\u0000-\u001f\u007f]/.test(value));
62
+ }
63
+ /**
64
+ * `org_settings.ai_models` as stored: a JSON object of provider id →
65
+ * `{ chat?, embeddings? }`. Anything else (null, malformed JSON, a field
66
+ * that isn't a model name) reads as no setting, so the seed serves.
67
+ */
68
+ export function parseAiModelSettings(value) {
69
+ if (typeof value !== "string" || value.trim() === "")
70
+ return {};
71
+ let parsed;
72
+ try {
73
+ parsed = JSON.parse(value);
74
+ }
75
+ catch {
76
+ return {};
77
+ }
78
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
79
+ return {};
80
+ const settings = {};
81
+ for (const [provider, entry] of Object.entries(parsed)) {
82
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
83
+ continue;
84
+ const setting = {};
85
+ for (const kind of ["chat", "embeddings"]) {
86
+ const model = entry[kind];
87
+ if (typeof model === "string" && isAiModelName(model)) {
88
+ setting[kind] = model;
89
+ }
90
+ }
91
+ if (setting.chat !== undefined || setting.embeddings !== undefined) {
92
+ settings[provider] = setting;
93
+ }
94
+ }
95
+ return settings;
96
+ }
97
+ /** The stored text of the settings, providers sorted; null when nothing is set. */
98
+ export function formatAiModelSettings(settings) {
99
+ const providers = Object.keys(settings)
100
+ .filter((id) => settings[id]?.chat !== undefined ||
101
+ settings[id]?.embeddings !== undefined)
102
+ .sort();
103
+ if (providers.length === 0)
104
+ return null;
105
+ return JSON.stringify(Object.fromEntries(providers.map((id) => {
106
+ const { chat, embeddings } = settings[id];
107
+ return [
108
+ id,
109
+ {
110
+ ...(chat === undefined ? {} : { chat }),
111
+ ...(embeddings === undefined ? {} : { embeddings }),
112
+ },
113
+ ];
114
+ })));
115
+ }
116
+ /** `settings` with one provider's models changed by `patch`. */
117
+ export function withAiModelSetting(settings, provider, patch) {
118
+ const next = { ...settings[provider] };
119
+ for (const kind of ["chat", "embeddings"]) {
120
+ const value = patch[kind];
121
+ if (value === null)
122
+ delete next[kind];
123
+ else if (value !== undefined)
124
+ next[kind] = value;
125
+ }
126
+ const rest = Object.fromEntries(Object.entries(settings).filter(([id]) => id !== provider));
127
+ return next.chat === undefined && next.embeddings === undefined
128
+ ? rest
129
+ : { ...rest, [provider]: next };
130
+ }
131
+ /** A choice must name a provider id; the model is free text after the first slash. */
132
+ const CHOICE = /^([a-z][a-z0-9-]{1,39})(?:\/(.{1,200}))?$/;
133
+ /**
134
+ * `openrouter` or `openrouter/anthropic/claude-haiku-5.5` as typed:
135
+ * the provider id up to the first slash, the model after it (a model id
136
+ * may hold slashes of its own). Null for blank or malformed text.
137
+ */
138
+ export function parseAiDefaultChoice(value) {
139
+ if (typeof value !== "string")
140
+ return null;
141
+ const match = CHOICE.exec(value.trim());
142
+ if (!match)
143
+ return null;
144
+ const model = match[2]?.trim();
145
+ return model ? { provider: match[1], model } : { provider: match[1] };
146
+ }
147
+ /** The text of a choice: `provider` or `provider/model`. */
148
+ export function formatAiDefaultChoice(choice) {
149
+ return choice.model ? `${choice.provider}/${choice.model}` : choice.provider;
150
+ }
151
+ /**
152
+ * The provider id `org_settings.ai_default` holds, or null. The column
153
+ * holds the provider alone (its models are in `ai_models`); text after a
154
+ * first slash is not read.
155
+ */
156
+ export function parseAiDefaultProvider(value) {
157
+ return parseAiDefaultChoice(value)?.provider ?? null;
158
+ }
159
+ export function canBeAiDefault(capability) {
160
+ return (capability?.mode === "ai" &&
161
+ capability.kind !== "proxy" &&
162
+ capability.chat !== undefined);
163
+ }
164
+ /**
165
+ * The Gateway settings an `ai` entry needs before it serves: its key
166
+ * (unless the entry works without one, `authOptional`) and what its URL
167
+ * needs besides (`alsoNeeds`).
168
+ */
169
+ export function aiRequiredSettings(capability) {
170
+ return [
171
+ ...(capability.authOptional ? [] : [capability.auth.secret]),
172
+ ...(capability.alsoNeeds ?? []),
173
+ ];
174
+ }
175
+ /** Whether every setting the entry needs is set. */
176
+ export function aiProviderConfigured(capability, isSet) {
177
+ return aiRequiredSettings(capability).every((name) => isSet(name));
178
+ }
179
+ /** Whether AI Gateway fronts calls: its id and the account are set. */
180
+ export function aiGatewayConfigured(isSet) {
181
+ return AI_GATEWAY_SETTINGS.every((name) => isSet(name));
182
+ }
183
+ /** Whether a call to `capability` goes through AI Gateway: it is configured and the entry has a slug. */
184
+ export function viaAiGateway(capability, isSet) {
185
+ return capability.aig !== undefined && aiGatewayConfigured(isSet);
186
+ }
187
+ /** The provider's models: the operator's setting, else the seed. */
188
+ function modelsOf(id, capability, models) {
189
+ const setting = models[id];
190
+ const { chat, embeddings } = capability;
191
+ return {
192
+ model: setting?.chat ?? chat.seedModel,
193
+ ...(embeddings
194
+ ? { embeddingsModel: setting?.embeddings ?? embeddings.seedModel }
195
+ : {}),
196
+ seed: {
197
+ chat: chat.seedModel,
198
+ ...(embeddings ? { embeddings: embeddings.seedModel } : {}),
199
+ },
200
+ };
201
+ }
202
+ function candidateOf(id, capability, isSet, models) {
203
+ return {
204
+ id,
205
+ label: capability.label,
206
+ settings: aiRequiredSettings(capability),
207
+ configured: aiProviderConfigured(capability, isSet),
208
+ ...modelsOf(id, capability, models),
209
+ viaAiGateway: viaAiGateway(capability, isSet),
210
+ embeddings: capability.embeddings !== undefined,
211
+ };
212
+ }
213
+ /**
214
+ * Every provider the default may resolve to: the shipped order first,
215
+ * then any other `ai` entry of `lookup` with a chat route (a registered
216
+ * row, one day), each with its state.
217
+ */
218
+ export function aiDefaultCandidates(isSet, lookup = CATALOG, models = {}) {
219
+ const ids = [
220
+ ...AI_DEFAULT_ORDER,
221
+ ...lookup.ids().filter((id) => !AI_DEFAULT_ORDER.includes(id)),
222
+ ];
223
+ return ids.flatMap((id) => {
224
+ const capability = lookup.get(id);
225
+ // A registered row whose key isn't bound to the hosts it has now reads
226
+ // as unset everywhere (`providers.value-bound-to-hosts`).
227
+ const set = lookup.bound && !lookup.bound(id) ? () => false : isSet;
228
+ return canBeAiDefault(capability)
229
+ ? [candidateOf(id, capability, set, models)]
230
+ : [];
231
+ });
232
+ }
233
+ /** Why `choice.provider` can't be the default, or null when it can. */
234
+ export function aiDefaultChoiceProblem(choice, lookup = CATALOG) {
235
+ const capability = lookup.get(choice.provider);
236
+ if (!capability)
237
+ return `${choice.provider} isn't a provider this Gateway knows`;
238
+ if (capability.mode !== "ai") {
239
+ return `${choice.provider} is an API provider, not a model provider`;
240
+ }
241
+ if (capability.kind === "proxy") {
242
+ return `${capability.label} fronts the model providers and serves no models of its own; set a provider, and turn the gateway on with everyapp ai gateway on`;
243
+ }
244
+ if (!capability.chat) {
245
+ return `${capability.label} has no OpenAI-shaped chat route, so it can't serve the default; an app pins it by listing it under providers`;
246
+ }
247
+ return null;
248
+ }
249
+ /**
250
+ * Why `patch` can't be stored for `provider`, or null when it can: the
251
+ * provider must be one the default can be, a model name must be a model
252
+ * name, and an embeddings model needs the entry's embeddings route.
253
+ */
254
+ export function aiModelPatchProblem(provider, patch, lookup = CATALOG) {
255
+ const why = aiDefaultChoiceProblem({ provider }, lookup);
256
+ if (why)
257
+ return why;
258
+ const capability = lookup.get(provider);
259
+ if (!canBeAiDefault(capability))
260
+ return `${provider} can't serve the default`;
261
+ for (const kind of ["chat", "embeddings"]) {
262
+ const value = patch[kind];
263
+ if (typeof value === "string" && !isAiModelName(value)) {
264
+ return `${JSON.stringify(value)} isn't a model id: 1 to 200 characters, no surrounding spaces`;
265
+ }
266
+ }
267
+ if (typeof patch.embeddings === "string" && !capability.embeddings) {
268
+ return `${capability.label} has no embeddings route, so it serves no embeddings model`;
269
+ }
270
+ return null;
271
+ }
272
+ /**
273
+ * The Gateway's effective default, from the stored choice (or none) and
274
+ * what is set. A choice that names a provider which isn't configured
275
+ * still wins (the operator chose it: `configured` is false and `settings`
276
+ * says what to set); a choice the default can't be is reported as
277
+ * `problem` and the order decides.
278
+ */
279
+ export function resolveAiDefault(input) {
280
+ const lookup = input.lookup ?? CATALOG;
281
+ const models = input.models ?? {};
282
+ const { isSet } = input;
283
+ const candidates = aiDefaultCandidates(isSet, lookup, models);
284
+ const resolve = (id, capability, source, problem) => ({
285
+ provider: id,
286
+ label: capability.label,
287
+ ...modelsOf(id, capability, models),
288
+ source,
289
+ configured: aiProviderConfigured(capability, isSet),
290
+ settings: aiRequiredSettings(capability),
291
+ via: viaAiGateway(capability, isSet) ? "ai-gateway" : "direct",
292
+ chat: capability.chat,
293
+ ...(capability.embeddings ? { embeddings: capability.embeddings } : {}),
294
+ candidates: [
295
+ ...candidates.filter((candidate) => candidate.id === id),
296
+ ...candidates.filter((candidate) => candidate.id !== id),
297
+ ],
298
+ ...(problem ? { problem } : {}),
299
+ });
300
+ let problem;
301
+ if (input.provider) {
302
+ const capability = lookup.get(input.provider);
303
+ const why = aiDefaultChoiceProblem({ provider: input.provider }, lookup);
304
+ if (!why && canBeAiDefault(capability)) {
305
+ return resolve(input.provider, capability, "setting");
306
+ }
307
+ problem = why ?? undefined;
308
+ }
309
+ const configured = candidates.find((candidate) => candidate.configured);
310
+ const first = configured ?? candidates[0];
311
+ if (!first) {
312
+ throw new Error("the catalog has no AI provider with a chat route");
313
+ }
314
+ const capability = lookup.get(first.id);
315
+ if (!canBeAiDefault(capability))
316
+ throw new Error("unreachable");
317
+ return resolve(first.id, capability, configured ? "order" : "none", problem);
318
+ }
319
+ /**
320
+ * The sentence setup shows for an unconfigured default: the one key to
321
+ * set, and the alternatives in the order.
322
+ */
323
+ export function aiDefaultSetupHint(resolution) {
324
+ const others = resolution.candidates
325
+ .filter((candidate) => candidate.id !== resolution.provider)
326
+ .slice(0, 3)
327
+ .map((candidate) => `${candidate.label} (${candidate.settings.join(" and ")})`);
328
+ const head = resolution.source === "setting"
329
+ ? `The Gateway's default model provider is ${resolution.label}; set ${resolution.settings.join(" and ")}.`
330
+ : `Any one model provider's key makes the app work; ${resolution.label} is first in the order: set ${resolution.settings.join(" and ")}.`;
331
+ return others.length > 0
332
+ ? `${head} Or another: ${others.join(", ")}; pick one with everyapp ai default <provider>.`
333
+ : head;
334
+ }
@@ -7,9 +7,12 @@
7
7
  * this derives the fallback's view of each, and holds the one response
8
8
  * rewrite the gateway has (Workers AI's numeric tokens).
9
9
  */
10
- import { type AiProviderCapability, type AiProviderId, type ApiKeyAuth, type CapabilitySettings } from "./capabilities.js";
10
+ import { type AiProviderCapability, type AiProviderId, type AiRoute, type ApiKeyAuth, type CapabilitySettings } from "./capabilities.js";
11
11
  export interface DevAiProviderSpec {
12
12
  origin: string;
13
+ /** The routes the default maps onto in dev, with the model filled in (the entry's `chat` and `embeddings`). */
14
+ chat?: AiRoute;
15
+ embeddings?: AiRoute;
13
16
  /** The gateway secret holding the provider key; in local dev, the `.dev.vars` name. */
14
17
  keyEnv: string;
15
18
  /** Where the key goes on a request (`authorizationOf`). */
@@ -29,7 +32,9 @@ export type DevAiProvider = AiProviderId;
29
32
  /** The fallback's view of one `ai` catalog entry. */
30
33
  export declare function devAiProviderSpec(capability: AiProviderCapability): DevAiProviderSpec;
31
34
  export declare const DEV_AI_PROVIDERS: Readonly<Record<DevAiProvider, DevAiProviderSpec>>;
32
- export declare function devAiProvider(name: string): DevAiProviderSpec | undefined;
35
+ export declare function devAiProvider(name: string,
36
+ /** The dev Worker's bindings: a registered `ai` spec under `.everyapp/providers/<id>.json` resolves from them. */
37
+ values?: Readonly<Record<string, unknown>>): DevAiProviderSpec | undefined;
33
38
  /** Every setting a provider needs, its key first: the names `.dev.vars` and the gateway use. */
34
39
  export declare function aiProviderSettings(spec: DevAiProviderSpec): string[];
35
40
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"aiProviders.d.ts","sourceRoot":"","sources":["../../src/internal/aiProviders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,IAAI,EAAE,UAAU,CAAC;IACjB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC;IAClE,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC;CACpE;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,qDAAqD;AACrD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,oBAAoB,GAC/B,iBAAiB,CAkBnB;AAED,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CACrC,MAAM,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAQG,CAAC;AAE9C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAIzE;AAED,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,GAAG,GAAG,IAAI,CAOZ;AAWD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,QAAQ,CAqBV"}
1
+ {"version":3,"file":"aiProviders.d.ts","sourceRoot":"","sources":["../../src/internal/aiProviders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,+GAA+G;IAC/G,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,IAAI,EAAE,UAAU,CAAC;IACjB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC;IAClE,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC;CACpE;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,qDAAqD;AACrD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,oBAAoB,GAC/B,iBAAiB,CAoBnB;AAED,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CACrC,MAAM,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAUG,CAAC;AAE9C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM;AACZ,kHAAkH;AAClH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,iBAAiB,GAAG,SAAS,CAS/B;AAED,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,GAAG,GAAG,IAAI,CAOZ;AAWD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,QAAQ,CAqBV"}