@every-app/sdk 0.3.0-rc.2 → 0.3.0-rc.4

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 (110) hide show
  1. package/README.md +1 -1
  2. package/dist/cloudflare/index.d.ts +2 -2
  3. package/dist/cloudflare/index.d.ts.map +1 -1
  4. package/dist/cloudflare/index.js +1 -1
  5. package/dist/cloudflare/sentinel.d.ts +57 -2
  6. package/dist/cloudflare/sentinel.d.ts.map +1 -1
  7. package/dist/cloudflare/sentinel.js +27 -2
  8. package/dist/cloudflare/worker.d.ts +297 -5
  9. package/dist/cloudflare/worker.d.ts.map +1 -1
  10. package/dist/cloudflare/worker.js +279 -12
  11. package/dist/dev/index.d.ts +1 -1
  12. package/dist/dev/index.d.ts.map +1 -1
  13. package/dist/dev/index.js +1 -1
  14. package/dist/dev/keypair.d.ts +2 -0
  15. package/dist/dev/keypair.d.ts.map +1 -1
  16. package/dist/dev/keypair.js +2 -0
  17. package/dist/internal/aiDefault.d.ts +141 -0
  18. package/dist/internal/aiDefault.d.ts.map +1 -0
  19. package/dist/internal/aiDefault.js +204 -0
  20. package/dist/internal/aiProviders.d.ts +4 -1
  21. package/dist/internal/aiProviders.d.ts.map +1 -1
  22. package/dist/internal/aiProviders.js +5 -1
  23. package/dist/internal/appSettings.d.ts +20 -2
  24. package/dist/internal/appSettings.d.ts.map +1 -1
  25. package/dist/internal/appSettings.js +53 -7
  26. package/dist/internal/audit.d.ts +108 -0
  27. package/dist/internal/audit.d.ts.map +1 -0
  28. package/dist/internal/audit.js +235 -0
  29. package/dist/internal/capabilities.d.ts +276 -7
  30. package/dist/internal/capabilities.d.ts.map +1 -1
  31. package/dist/internal/capabilities.js +111 -0
  32. package/dist/internal/catalog/index.d.ts +39 -2
  33. package/dist/internal/catalog/index.d.ts.map +1 -1
  34. package/dist/internal/catalog/inference.d.ts +39 -2
  35. package/dist/internal/catalog/inference.d.ts.map +1 -1
  36. package/dist/internal/catalog/inference.js +36 -4
  37. package/dist/internal/devProviders.d.ts +2 -2
  38. package/dist/internal/devProviders.d.ts.map +1 -1
  39. package/dist/internal/devProviders.js +19 -1
  40. package/dist/internal/events.d.ts +13 -2
  41. package/dist/internal/events.d.ts.map +1 -1
  42. package/dist/internal/events.js +42 -4
  43. package/dist/internal/identity.d.ts +29 -3
  44. package/dist/internal/identity.d.ts.map +1 -1
  45. package/dist/internal/identity.js +37 -9
  46. package/dist/internal/index.d.ts +5 -1
  47. package/dist/internal/index.d.ts.map +1 -1
  48. package/dist/internal/index.js +5 -1
  49. package/dist/internal/members.d.ts +3 -2
  50. package/dist/internal/members.d.ts.map +1 -1
  51. package/dist/internal/oauthPresets.d.ts +29 -0
  52. package/dist/internal/oauthPresets.d.ts.map +1 -0
  53. package/dist/internal/oauthPresets.js +534 -0
  54. package/dist/internal/oauthScopes.d.ts +56 -1
  55. package/dist/internal/oauthScopes.d.ts.map +1 -1
  56. package/dist/internal/oauthScopes.js +98 -4
  57. package/dist/internal/oauthSpec.d.ts +59 -0
  58. package/dist/internal/oauthSpec.d.ts.map +1 -0
  59. package/dist/internal/oauthSpec.js +676 -0
  60. package/dist/internal/protocol.d.ts +36 -1
  61. package/dist/internal/protocol.d.ts.map +1 -1
  62. package/dist/internal/protocol.js +30 -1
  63. package/dist/internal/providerRegistry.d.ts +17 -6
  64. package/dist/internal/providerRegistry.d.ts.map +1 -1
  65. package/dist/internal/providerRegistry.js +47 -2
  66. package/dist/internal/providerSpec.d.ts +11 -7
  67. package/dist/internal/providerSpec.d.ts.map +1 -1
  68. package/dist/internal/providerSpec.js +134 -37
  69. package/dist/internal/signInProviders.d.ts.map +1 -1
  70. package/dist/internal/signInProviders.js +11 -4
  71. package/dist/server/ai.d.ts +45 -0
  72. package/dist/server/ai.d.ts.map +1 -0
  73. package/dist/server/ai.js +40 -0
  74. package/dist/server/attribution.d.ts +9 -5
  75. package/dist/server/attribution.d.ts.map +1 -1
  76. package/dist/server/attribution.js +12 -4
  77. package/dist/server/connectUrl.d.ts +21 -0
  78. package/dist/server/connectUrl.d.ts.map +1 -0
  79. package/dist/server/connectUrl.js +37 -0
  80. package/dist/server/context.d.ts +68 -0
  81. package/dist/server/context.d.ts.map +1 -0
  82. package/dist/server/context.js +117 -0
  83. package/dist/server/emit.d.ts +1 -1
  84. package/dist/server/emit.d.ts.map +1 -1
  85. package/dist/server/emit.js +4 -4
  86. package/dist/server/everyApp.d.ts +27 -7
  87. package/dist/server/everyApp.d.ts.map +1 -1
  88. package/dist/server/everyApp.js +106 -5
  89. package/dist/server/fromMcpTools.d.ts +89 -0
  90. package/dist/server/fromMcpTools.d.ts.map +1 -0
  91. package/dist/server/fromMcpTools.js +192 -0
  92. package/dist/server/gatewayFetch.d.ts +8 -6
  93. package/dist/server/gatewayFetch.d.ts.map +1 -1
  94. package/dist/server/gatewayFetch.js +78 -11
  95. package/dist/server/index.d.ts +7 -3
  96. package/dist/server/index.d.ts.map +1 -1
  97. package/dist/server/index.js +6 -2
  98. package/dist/server/integrationFetch.d.ts +55 -8
  99. package/dist/server/integrationFetch.d.ts.map +1 -1
  100. package/dist/server/integrationFetch.js +198 -18
  101. package/dist/server/listMembers.d.ts +1 -1
  102. package/dist/server/listMembers.d.ts.map +1 -1
  103. package/dist/server/listMembers.js +5 -8
  104. package/dist/server/sendEmail.d.ts +1 -1
  105. package/dist/server/sendEmail.d.ts.map +1 -1
  106. package/dist/server/sendEmail.js +4 -4
  107. package/dist/server/toolsEndpoint.d.ts.map +1 -1
  108. package/dist/server/toolsEndpoint.js +11 -5
  109. package/package.json +13 -14
  110. package/LICENSE +0 -21
@@ -0,0 +1,141 @@
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
+ * Everything here is pure: what is set is asked of the caller (`isSet`),
19
+ * which reads the Gateway's env, the Worker's secret names, or `.dev.vars`.
20
+ */
21
+ import { type AiProviderCapability, type AiRoute, type Capability, type CapabilityLookup } from "./capabilities.js";
22
+ /** The reserved provider id apps call for the default: `/api/ai/default/…`. */
23
+ export declare const AI_DEFAULT_PROVIDER = "default";
24
+ /** The catalog id of Cloudflare AI Gateway, the proxy entry. */
25
+ export declare const AI_GATEWAY_PROVIDER = "ai-gateway";
26
+ /** The settings that make AI Gateway front the providers that have a slug. */
27
+ export declare const AI_GATEWAY_SETTINGS: readonly ["AI_GATEWAY_ID", "CLOUDFLARE_ACCOUNT_ID"];
28
+ /**
29
+ * The shipped order: the provider the default resolves to when the
30
+ * operator chose none, the first of these whose settings are set.
31
+ */
32
+ export declare const AI_DEFAULT_ORDER: readonly string[];
33
+ /** The model name an app sends to mean "the default's model". */
34
+ export declare const AI_DEFAULT_MODEL = "default";
35
+ /** The paths an app calls under `/api/ai/default`, OpenAI-shaped. */
36
+ export declare const AI_DEFAULT_ROUTES: {
37
+ readonly chat: "/v1/chat/completions";
38
+ readonly embeddings: "/v1/embeddings";
39
+ };
40
+ export type AiDefaultRoute = keyof typeof AI_DEFAULT_ROUTES;
41
+ /** What the operator stored: a provider, and the model to fill in when the app names none. */
42
+ export interface AiDefaultChoice {
43
+ provider: string;
44
+ model?: string;
45
+ }
46
+ /**
47
+ * `openrouter` or `openrouter/anthropic/claude-haiku-5.5` as a choice:
48
+ * the provider id up to the first slash, the model after it (a model id
49
+ * may hold slashes of its own). Null for blank or malformed text.
50
+ */
51
+ export declare function parseAiDefaultChoice(value: string | null | undefined): AiDefaultChoice | null;
52
+ /** The stored text of a choice: `provider` or `provider/model`. */
53
+ export declare function formatAiDefaultChoice(choice: AiDefaultChoice): string;
54
+ /** Whether `name` holds a value, as the Gateway's env or a secret list says. */
55
+ export type IsSet = (name: string) => boolean;
56
+ /** An `ai` entry the default may resolve to: not the proxy, with a chat route. */
57
+ export type AiDefaultCapability = AiProviderCapability & {
58
+ chat: AiRoute;
59
+ };
60
+ export declare function canBeAiDefault(capability: Capability | undefined): capability is AiDefaultCapability;
61
+ /**
62
+ * The Gateway settings an `ai` entry needs before it serves: its key
63
+ * (unless the entry works without one, `authOptional`) and what its URL
64
+ * needs besides (`alsoNeeds`).
65
+ */
66
+ export declare function aiRequiredSettings(capability: AiProviderCapability): string[];
67
+ /** Whether every setting the entry needs is set. */
68
+ export declare function aiProviderConfigured(capability: AiProviderCapability, isSet: IsSet): boolean;
69
+ /** Whether AI Gateway fronts calls: its id and the account are set. */
70
+ export declare function aiGatewayConfigured(isSet: IsSet): boolean;
71
+ /** Whether a call to `capability` goes through AI Gateway: it is configured and the entry has a slug. */
72
+ export declare function viaAiGateway(capability: AiProviderCapability, isSet: IsSet): boolean;
73
+ /** One provider the default may resolve to, with its state on this Gateway. */
74
+ export interface AiDefaultCandidate {
75
+ id: string;
76
+ label: string;
77
+ /** The Gateway settings it needs; what to set when it isn't configured. */
78
+ settings: string[];
79
+ configured: boolean;
80
+ /** The model the Gateway fills in when the app names none. */
81
+ model: string;
82
+ /** Through Cloudflare AI Gateway, as things are set now. */
83
+ viaAiGateway: boolean;
84
+ embeddings: boolean;
85
+ }
86
+ /** Where the resolved default came from. */
87
+ export type AiDefaultSource =
88
+ /** The operator's stored choice. */
89
+ "setting"
90
+ /** The shipped order: the first provider that is configured. */
91
+ | "order"
92
+ /** Nothing is configured: the first of the order, with what to set. */
93
+ | "none";
94
+ export interface AiDefaultResolution {
95
+ provider: string;
96
+ label: string;
97
+ /** The model the default serves: the choice's, else the entry's. */
98
+ model: string;
99
+ source: AiDefaultSource;
100
+ /** Every setting the provider needs is set, so the default serves. */
101
+ configured: boolean;
102
+ /** The Gateway settings the provider needs: what to set when it isn't configured. */
103
+ settings: string[];
104
+ via: "ai-gateway" | "direct";
105
+ chat: AiRoute;
106
+ embeddings?: AiRoute;
107
+ /** Every provider the default could be, in the shipped order, the choice first. */
108
+ candidates: AiDefaultCandidate[];
109
+ /**
110
+ * The stored choice names something the default can't be (an id the
111
+ * catalog doesn't have, an entry with no chat route, the proxy): the
112
+ * order decided instead, and this says why.
113
+ */
114
+ problem?: string;
115
+ }
116
+ /**
117
+ * Every provider the default may resolve to: the shipped order first,
118
+ * then any other `ai` entry of `lookup` with a chat route (a registered
119
+ * row, one day), each with its state.
120
+ */
121
+ export declare function aiDefaultCandidates(isSet: IsSet, lookup?: CapabilityLookup): AiDefaultCandidate[];
122
+ /** Why `choice.provider` can't be the default, or null when it can. */
123
+ export declare function aiDefaultChoiceProblem(choice: AiDefaultChoice, lookup?: CapabilityLookup): string | null;
124
+ /**
125
+ * The Gateway's effective default, from the stored choice (or none) and
126
+ * what is set. A choice that names a provider which isn't configured
127
+ * still wins (the operator chose it: `configured` is false and `settings`
128
+ * says what to set); a choice the default can't be is reported as
129
+ * `problem` and the order decides.
130
+ */
131
+ export declare function resolveAiDefault(input: {
132
+ choice: AiDefaultChoice | null;
133
+ isSet: IsSet;
134
+ lookup?: CapabilityLookup;
135
+ }): AiDefaultResolution;
136
+ /**
137
+ * The sentence setup shows for an unconfigured default: the one key to
138
+ * set, and the alternatives in the order.
139
+ */
140
+ export declare function aiDefaultSetupHint(resolution: AiDefaultResolution): string;
141
+ //# 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,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
+ * Everything here is pure: what is set is asked of the caller (`isSet`),
19
+ * which reads the Gateway's env, the Worker's secret names, or `.dev.vars`.
20
+ */
21
+ import { CATALOG, } from "./capabilities.js";
22
+ /** The reserved provider id apps call for the default: `/api/ai/default/…`. */
23
+ export const AI_DEFAULT_PROVIDER = "default";
24
+ /** The catalog id of Cloudflare AI Gateway, the proxy entry. */
25
+ export const AI_GATEWAY_PROVIDER = "ai-gateway";
26
+ /** The settings that make AI Gateway front the providers that have a slug. */
27
+ export const AI_GATEWAY_SETTINGS = [
28
+ "AI_GATEWAY_ID",
29
+ "CLOUDFLARE_ACCOUNT_ID",
30
+ ];
31
+ /**
32
+ * The shipped order: the provider the default resolves to when the
33
+ * operator chose none, the first of these whose settings are set.
34
+ */
35
+ export const AI_DEFAULT_ORDER = [
36
+ "openrouter",
37
+ "workers-ai",
38
+ "openai",
39
+ "anthropic",
40
+ "groq",
41
+ "mistral",
42
+ "gemini",
43
+ ];
44
+ /** The model name an app sends to mean "the default's model". */
45
+ export const AI_DEFAULT_MODEL = "default";
46
+ /** The paths an app calls under `/api/ai/default`, OpenAI-shaped. */
47
+ export const AI_DEFAULT_ROUTES = {
48
+ chat: "/v1/chat/completions",
49
+ embeddings: "/v1/embeddings",
50
+ };
51
+ /** A stored choice must name a provider id; the model is free text after the first slash. */
52
+ const CHOICE = /^([a-z][a-z0-9-]{1,39})(?:\/(.{1,200}))?$/;
53
+ /**
54
+ * `openrouter` or `openrouter/anthropic/claude-haiku-5.5` as a choice:
55
+ * the provider id up to the first slash, the model after it (a model id
56
+ * may hold slashes of its own). Null for blank or malformed text.
57
+ */
58
+ export function parseAiDefaultChoice(value) {
59
+ if (typeof value !== "string")
60
+ return null;
61
+ const match = CHOICE.exec(value.trim());
62
+ if (!match)
63
+ return null;
64
+ const model = match[2]?.trim();
65
+ return model ? { provider: match[1], model } : { provider: match[1] };
66
+ }
67
+ /** The stored text of a choice: `provider` or `provider/model`. */
68
+ export function formatAiDefaultChoice(choice) {
69
+ return choice.model ? `${choice.provider}/${choice.model}` : choice.provider;
70
+ }
71
+ export function canBeAiDefault(capability) {
72
+ return (capability?.mode === "ai" &&
73
+ capability.kind !== "proxy" &&
74
+ capability.chat !== undefined);
75
+ }
76
+ /**
77
+ * The Gateway settings an `ai` entry needs before it serves: its key
78
+ * (unless the entry works without one, `authOptional`) and what its URL
79
+ * needs besides (`alsoNeeds`).
80
+ */
81
+ export function aiRequiredSettings(capability) {
82
+ return [
83
+ ...(capability.authOptional ? [] : [capability.auth.secret]),
84
+ ...(capability.alsoNeeds ?? []),
85
+ ];
86
+ }
87
+ /** Whether every setting the entry needs is set. */
88
+ export function aiProviderConfigured(capability, isSet) {
89
+ return aiRequiredSettings(capability).every((name) => isSet(name));
90
+ }
91
+ /** Whether AI Gateway fronts calls: its id and the account are set. */
92
+ export function aiGatewayConfigured(isSet) {
93
+ return AI_GATEWAY_SETTINGS.every((name) => isSet(name));
94
+ }
95
+ /** Whether a call to `capability` goes through AI Gateway: it is configured and the entry has a slug. */
96
+ export function viaAiGateway(capability, isSet) {
97
+ return capability.aig !== undefined && aiGatewayConfigured(isSet);
98
+ }
99
+ function candidateOf(id, capability, isSet) {
100
+ return {
101
+ id,
102
+ label: capability.label,
103
+ settings: aiRequiredSettings(capability),
104
+ configured: aiProviderConfigured(capability, isSet),
105
+ model: capability.chat.model,
106
+ viaAiGateway: viaAiGateway(capability, isSet),
107
+ embeddings: capability.embeddings !== undefined,
108
+ };
109
+ }
110
+ /**
111
+ * Every provider the default may resolve to: the shipped order first,
112
+ * then any other `ai` entry of `lookup` with a chat route (a registered
113
+ * row, one day), each with its state.
114
+ */
115
+ export function aiDefaultCandidates(isSet, lookup = CATALOG) {
116
+ const ids = [
117
+ ...AI_DEFAULT_ORDER,
118
+ ...lookup.ids().filter((id) => !AI_DEFAULT_ORDER.includes(id)),
119
+ ];
120
+ return ids.flatMap((id) => {
121
+ const capability = lookup.get(id);
122
+ return canBeAiDefault(capability)
123
+ ? [candidateOf(id, capability, isSet)]
124
+ : [];
125
+ });
126
+ }
127
+ /** Why `choice.provider` can't be the default, or null when it can. */
128
+ export function aiDefaultChoiceProblem(choice, lookup = CATALOG) {
129
+ const capability = lookup.get(choice.provider);
130
+ if (!capability)
131
+ return `${choice.provider} isn't a provider this Gateway knows`;
132
+ if (capability.mode !== "ai") {
133
+ return `${choice.provider} is an API provider, not a model provider`;
134
+ }
135
+ if (capability.kind === "proxy") {
136
+ 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`;
137
+ }
138
+ if (!capability.chat) {
139
+ 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`;
140
+ }
141
+ return null;
142
+ }
143
+ /**
144
+ * The Gateway's effective default, from the stored choice (or none) and
145
+ * what is set. A choice that names a provider which isn't configured
146
+ * still wins (the operator chose it: `configured` is false and `settings`
147
+ * says what to set); a choice the default can't be is reported as
148
+ * `problem` and the order decides.
149
+ */
150
+ export function resolveAiDefault(input) {
151
+ const lookup = input.lookup ?? CATALOG;
152
+ const { isSet } = input;
153
+ const candidates = aiDefaultCandidates(isSet, lookup);
154
+ const resolve = (id, capability, source, model, problem) => ({
155
+ provider: id,
156
+ label: capability.label,
157
+ model: model ?? capability.chat.model,
158
+ source,
159
+ configured: aiProviderConfigured(capability, isSet),
160
+ settings: aiRequiredSettings(capability),
161
+ via: viaAiGateway(capability, isSet) ? "ai-gateway" : "direct",
162
+ chat: capability.chat,
163
+ ...(capability.embeddings ? { embeddings: capability.embeddings } : {}),
164
+ candidates: [
165
+ ...candidates.filter((candidate) => candidate.id === id),
166
+ ...candidates.filter((candidate) => candidate.id !== id),
167
+ ],
168
+ ...(problem ? { problem } : {}),
169
+ });
170
+ let problem;
171
+ if (input.choice) {
172
+ const capability = lookup.get(input.choice.provider);
173
+ const why = aiDefaultChoiceProblem(input.choice, lookup);
174
+ if (!why && canBeAiDefault(capability)) {
175
+ return resolve(input.choice.provider, capability, "setting", input.choice.model);
176
+ }
177
+ problem = why ?? undefined;
178
+ }
179
+ const configured = candidates.find((candidate) => candidate.configured);
180
+ const first = configured ?? candidates[0];
181
+ if (!first) {
182
+ throw new Error("the catalog has no AI provider with a chat route");
183
+ }
184
+ const capability = lookup.get(first.id);
185
+ if (!canBeAiDefault(capability))
186
+ throw new Error("unreachable");
187
+ return resolve(first.id, capability, configured ? "order" : "none", undefined, problem);
188
+ }
189
+ /**
190
+ * The sentence setup shows for an unconfigured default: the one key to
191
+ * set, and the alternatives in the order.
192
+ */
193
+ export function aiDefaultSetupHint(resolution) {
194
+ const others = resolution.candidates
195
+ .filter((candidate) => candidate.id !== resolution.provider)
196
+ .slice(0, 3)
197
+ .map((candidate) => `${candidate.label} (${candidate.settings.join(" and ")})`);
198
+ const head = resolution.source === "setting"
199
+ ? `The Gateway's default model provider is ${resolution.label}; set ${resolution.settings.join(" and ")}.`
200
+ : `Any one model provider's key makes the app work; ${resolution.label} is first in the order: set ${resolution.settings.join(" and ")}.`;
201
+ return others.length > 0
202
+ ? `${head} Or another: ${others.join(", ")}; pick one with everyapp ai default <provider>.`
203
+ : head;
204
+ }
@@ -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`). */
@@ -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;AAE3B,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,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"}
@@ -13,6 +13,8 @@ export function devAiProviderSpec(capability) {
13
13
  const { basePath, normalize } = capability;
14
14
  return {
15
15
  origin: capability.origin,
16
+ ...(capability.chat ? { chat: capability.chat } : {}),
17
+ ...(capability.embeddings ? { embeddings: capability.embeddings } : {}),
16
18
  keyEnv: capability.auth.secret,
17
19
  auth: capability.auth,
18
20
  docs: capability.docs,
@@ -30,7 +32,9 @@ export function devAiProviderSpec(capability) {
30
32
  }
31
33
  export const DEV_AI_PROVIDERS = Object.fromEntries(CAPABILITY_IDS.flatMap((id) => {
32
34
  const capability = CAPABILITIES[id];
33
- return capability.mode === "ai"
35
+ // The proxy entry (AI Gateway) serves no models: never a dev target.
36
+ return capability.mode === "ai" &&
37
+ !("kind" in capability && capability.kind === "proxy")
34
38
  ? [[id, devAiProviderSpec(capability)]]
35
39
  : [];
36
40
  }));
@@ -23,6 +23,7 @@
23
23
  * the app Worker's secret names.
24
24
  */
25
25
  import { type ApiKeyCapability, type CapabilityLookup } from "./capabilities.js";
26
+ import { type AiDefaultChoice, type IsSet } from "./aiDefault.js";
26
27
  /** A provider as `providers` lists it: its id, or an entry with a need. */
27
28
  export interface ProviderEntry extends SettingNeedFields {
28
29
  id: string;
@@ -62,12 +63,16 @@ export interface SettingsManifestLike {
62
63
  readonly secrets?: ReadonlyArray<string | SecretEntry>;
63
64
  readonly ai?: {
64
65
  readonly routes?: readonly string[];
66
+ /** The app needs the Gateway's default chat model (`/api/ai/default`): `true`, or an entry with its need. */
67
+ readonly chat?: boolean | SettingNeedFields;
65
68
  };
66
69
  /** A remote MCP app's registration (./remoteMcp.ts): its credential is a required Gateway setting. */
67
70
  readonly remote?: unknown;
68
71
  readonly name?: string;
69
72
  }
70
73
  export type SettingKind = "provider" | "capability" | "secret" | "ai-routes"
74
+ /** The Gateway's default model provider (`ai.chat`): one key of any provider in the order, or the operator's choice. */
75
+ | "ai-default"
71
76
  /** A remote MCP app's credential (./remoteMcp.ts): one Gateway setting named by the row. */
72
77
  | "remote-mcp";
73
78
  /** Which Worker holds a setting: the Gateway's, or the app's own. */
@@ -80,6 +85,13 @@ export type SettingNeed = {
80
85
  kind: "anyOf";
81
86
  group: string;
82
87
  };
88
+ /** What `appSettings` may be told about the Gateway, for the default model provider. */
89
+ export interface AppSettingsOptions {
90
+ /** The operator's stored default (`everyapp ai default`), or none. */
91
+ aiDefault?: AiDefaultChoice | null;
92
+ /** What is set, to put the configured provider first; absent, the order decides. */
93
+ isSet?: IsSet;
94
+ }
83
95
  /** One thing the app needs set, as the manifest declares it. */
84
96
  export interface AppSetting {
85
97
  kind: SettingKind;
@@ -88,8 +100,14 @@ export interface AppSetting {
88
100
  /** "OpenRouter", "DataForSEO", "MAIN_SECRET", "AI proxy routes". */
89
101
  label: string;
90
102
  holder: SettingHolder;
91
- /** Every one of these must be set for the setting to count as set. */
103
+ /** Every one of these must be set for the setting to count as set (or any one group of `alternatives`). */
92
104
  names: string[];
105
+ /**
106
+ * For the default model provider: the settings of each provider that
107
+ * could serve it, any one group of which, all set, makes the setting
108
+ * set; `names` is the first group, what to ask for.
109
+ */
110
+ alternatives?: string[][];
93
111
  /** Read when set, never required (a capability's optional settings). */
94
112
  alsoReads: string[];
95
113
  need: SettingNeed;
@@ -157,7 +175,7 @@ export declare function secretNames(manifest: Pick<SettingsManifestLike, "secret
157
175
  * which is always set. `lookup` is where ids are found: the catalog alone
158
176
  * by default, or a gateway's registry with its registered rows.
159
177
  */
160
- export declare function appSettings(manifest: SettingsManifestLike, lookup?: CapabilityLookup): AppSetting[];
178
+ export declare function appSettings(manifest: SettingsManifestLike, lookup?: CapabilityLookup, options?: AppSettingsOptions): AppSetting[];
161
179
  export interface EvaluateOptions {
162
180
  /**
163
181
  * A capability's own readiness rule, where names alone don't say (the
@@ -1 +1 @@
1
- {"version":3,"file":"appSettings.d.ts","sourceRoot":"","sources":["../../src/internal/appSettings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appSettings.d.ts","sourceRoot":"","sources":["../../src/internal/appSettings.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@
23
23
  * the app Worker's secret names.
24
24
  */
25
25
  import { CATALOG, capabilitySettings, } from "./capabilities.js";
26
+ import { aiDefaultSetupHint, aiRequiredSettings, resolveAiDefault, } from "./aiDefault.js";
26
27
  import { isInstallOwnedGatewaySetting, isSettableGatewaySetting, } from "./gatewaySettings.js";
27
28
  import { remoteMcpAuthLabel, remoteMcpOf, remoteMcpSecretOf, } from "./remoteMcp.js";
28
29
  /** The need an entry declares; required unless it says otherwise. */
@@ -86,7 +87,8 @@ export function secretNames(manifest) {
86
87
  * registered row's are its own, so they count too.
87
88
  */
88
89
  function providerNames(capability) {
89
- return capabilitySettings(capability).filter((name) => !isInstallOwnedGatewaySetting(name));
90
+ // An optional key (AI Gateway's own token) is never a need.
91
+ return aiRequiredSettings(capability).filter((name) => !isInstallOwnedGatewaySetting(name));
90
92
  }
91
93
  /** A capability's Gateway settings: what it needs, and what it also reads. */
92
94
  function capabilityNames(capability) {
@@ -173,8 +175,37 @@ function withNeed(setting, entry, defaults = {}) {
173
175
  * which is always set. `lookup` is where ids are found: the catalog alone
174
176
  * by default, or a gateway's registry with its registered rows.
175
177
  */
176
- export function appSettings(manifest, lookup = CATALOG) {
178
+ export function appSettings(manifest, lookup = CATALOG, options = {}) {
177
179
  const settings = [];
180
+ const chat = manifest.ai?.chat;
181
+ if (chat === true || (chat && typeof chat === "object")) {
182
+ // The default resolves on what is set: with nothing set, the first of
183
+ // the order (or the operator's choice) and its settings are what to
184
+ // ask for; with one configured, that provider's. `isSet` here only
185
+ // orders the candidates; evaluateAppSettings decides what is set.
186
+ const resolution = resolveAiDefault({
187
+ choice: options.aiDefault ?? null,
188
+ isSet: options.isSet ?? (() => false),
189
+ lookup,
190
+ });
191
+ const settable = (names) => names.filter((name) => !isInstallOwnedGatewaySetting(name));
192
+ const provider = lookup.get(resolution.provider);
193
+ settings.push(withNeed({
194
+ kind: "ai-default",
195
+ id: "ai-default",
196
+ label: `A chat model (${resolution.label})`,
197
+ holder: "gateway",
198
+ names: settable(resolution.settings),
199
+ alsoReads: [],
200
+ alternatives: resolution.candidates
201
+ .map((candidate) => settable(candidate.settings))
202
+ .filter((names) => names.length > 0),
203
+ }, chat === true ? undefined : chat, {
204
+ ...(provider?.mode === "ai" ? { docs: provider.docs } : {}),
205
+ setup: "setup/ai.md",
206
+ hint: aiDefaultSetupHint(resolution),
207
+ }));
208
+ }
178
209
  for (const entry of providerEntries(manifest)) {
179
210
  const capability = lookup.get(entry.id);
180
211
  if (capability?.mode !== "ai")
@@ -259,15 +290,30 @@ export function appSettings(manifest, lookup = CATALOG) {
259
290
  }
260
291
  /** Whether each name of `setting` is set: all → true, one unset → false, else unknown. */
261
292
  function settingIsSet(setting, isSet) {
293
+ const groupIsSet = (names) => {
294
+ let unknown = false;
295
+ for (const name of names) {
296
+ const state = isSet(setting.holder, name);
297
+ if (state === false)
298
+ return false;
299
+ if (state === null)
300
+ unknown = true;
301
+ }
302
+ return unknown ? null : true;
303
+ };
304
+ if (!setting.alternatives?.length)
305
+ return groupIsSet(setting.names);
306
+ // Any one provider configured makes the default serve; unknown only
307
+ // when no group is set and one couldn't be read.
262
308
  let unknown = false;
263
- for (const name of setting.names) {
264
- const state = isSet(setting.holder, name);
265
- if (state === false)
266
- return false;
309
+ for (const names of setting.alternatives) {
310
+ const state = groupIsSet(names);
311
+ if (state === true)
312
+ return true;
267
313
  if (state === null)
268
314
  unknown = true;
269
315
  }
270
- return unknown ? null : true;
316
+ return unknown ? null : false;
271
317
  }
272
318
  /**
273
319
  * Every setting against what is set. `isSet` answers per holder and name: