@every-app/sdk 0.2.0 → 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.
- package/LICENSE +21 -0
- package/README.md +609 -3
- package/dist/cloudflare/catalogSettings.generated.d.ts +81 -0
- package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
- package/dist/cloudflare/catalogSettings.generated.js +174 -0
- package/dist/cloudflare/index.d.ts +23 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +24 -0
- package/dist/cloudflare/sentinel.d.ts +127 -0
- package/dist/cloudflare/sentinel.d.ts.map +1 -0
- package/dist/cloudflare/sentinel.js +85 -0
- package/dist/cloudflare/worker.d.ts +805 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +997 -0
- package/dist/dev/index.d.ts +8 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +7 -0
- package/dist/dev/keypair.d.ts +26 -0
- package/dist/dev/keypair.d.ts.map +1 -0
- package/dist/dev/keypair.js +62 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/internal/aiDefault.d.ts +204 -0
- package/dist/internal/aiDefault.d.ts.map +1 -0
- package/dist/internal/aiDefault.js +334 -0
- package/dist/internal/aiProviders.d.ts +72 -0
- package/dist/internal/aiProviders.d.ts.map +1 -0
- package/dist/internal/aiProviders.js +233 -0
- package/dist/internal/appSettings.d.ts +315 -0
- package/dist/internal/appSettings.d.ts.map +1 -0
- package/dist/internal/appSettings.js +549 -0
- package/dist/internal/audit.d.ts +108 -0
- package/dist/internal/audit.d.ts.map +1 -0
- package/dist/internal/audit.js +235 -0
- package/dist/internal/capabilities.d.ts +3174 -0
- package/dist/internal/capabilities.d.ts.map +1 -0
- package/dist/internal/capabilities.js +1110 -0
- package/dist/internal/catalog/commerce.d.ts +394 -0
- package/dist/internal/catalog/commerce.d.ts.map +1 -0
- package/dist/internal/catalog/commerce.js +477 -0
- package/dist/internal/catalog/comms.d.ts +375 -0
- package/dist/internal/catalog/comms.d.ts.map +1 -0
- package/dist/internal/catalog/comms.js +520 -0
- package/dist/internal/catalog/index.d.ts +1973 -0
- package/dist/internal/catalog/index.d.ts.map +1 -0
- package/dist/internal/catalog/index.js +19 -0
- package/dist/internal/catalog/inference.d.ts +393 -0
- package/dist/internal/catalog/inference.d.ts.map +1 -0
- package/dist/internal/catalog/inference.js +460 -0
- package/dist/internal/catalog/infra.d.ts +423 -0
- package/dist/internal/catalog/infra.d.ts.map +1 -0
- package/dist/internal/catalog/infra.js +543 -0
- package/dist/internal/catalog/search.d.ts +400 -0
- package/dist/internal/catalog/search.d.ts.map +1 -0
- package/dist/internal/catalog/search.js +463 -0
- package/dist/internal/devProviders.d.ts +49 -0
- package/dist/internal/devProviders.d.ts.map +1 -0
- package/dist/internal/devProviders.js +80 -0
- package/dist/internal/email.d.ts +280 -0
- package/dist/internal/email.d.ts.map +1 -0
- package/dist/internal/email.js +613 -0
- package/dist/internal/events.d.ts +193 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +367 -0
- package/dist/internal/gatewaySettings.d.ts +83 -0
- package/dist/internal/gatewaySettings.d.ts.map +1 -0
- package/dist/internal/gatewaySettings.js +215 -0
- package/dist/internal/identity.d.ts +57 -5
- package/dist/internal/identity.d.ts.map +1 -1
- package/dist/internal/identity.js +99 -22
- package/dist/internal/index.d.ts +22 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +22 -1
- package/dist/internal/members.d.ts +36 -0
- package/dist/internal/members.d.ts.map +1 -0
- package/dist/internal/members.js +7 -0
- package/dist/internal/oauthClient.d.ts +61 -0
- package/dist/internal/oauthClient.d.ts.map +1 -0
- package/dist/internal/oauthClient.js +133 -0
- package/dist/internal/oauthPresets.d.ts +33 -0
- package/dist/internal/oauthPresets.d.ts.map +1 -0
- package/dist/internal/oauthPresets.js +1064 -0
- package/dist/internal/oauthScopes.d.ts +172 -0
- package/dist/internal/oauthScopes.d.ts.map +1 -0
- package/dist/internal/oauthScopes.js +510 -0
- package/dist/internal/oauthSpec.d.ts +102 -0
- package/dist/internal/oauthSpec.d.ts.map +1 -0
- package/dist/internal/oauthSpec.js +789 -0
- package/dist/internal/organizationName.d.ts +18 -0
- package/dist/internal/organizationName.d.ts.map +1 -0
- package/dist/internal/organizationName.js +24 -0
- package/dist/internal/protocol.d.ts +150 -3
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +163 -2
- package/dist/internal/providerApps.d.ts +75 -0
- package/dist/internal/providerApps.d.ts.map +1 -0
- package/dist/internal/providerApps.js +59 -0
- package/dist/internal/providerRegistry.d.ts +218 -0
- package/dist/internal/providerRegistry.d.ts.map +1 -0
- package/dist/internal/providerRegistry.js +432 -0
- package/dist/internal/providerSpec.d.ts +66 -0
- package/dist/internal/providerSpec.d.ts.map +1 -0
- package/dist/internal/providerSpec.js +1154 -0
- package/dist/internal/remoteMcp.d.ts +188 -0
- package/dist/internal/remoteMcp.d.ts.map +1 -0
- package/dist/internal/remoteMcp.js +543 -0
- package/dist/internal/signInProviders.d.ts +104 -0
- package/dist/internal/signInProviders.d.ts.map +1 -0
- package/dist/internal/signInProviders.js +245 -0
- package/dist/internal/tools.d.ts +115 -0
- package/dist/internal/tools.d.ts.map +1 -0
- package/dist/internal/tools.js +80 -0
- package/dist/manifest.d.ts +238 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +30 -0
- package/dist/server/ai.d.ts +111 -0
- package/dist/server/ai.d.ts.map +1 -0
- package/dist/server/ai.js +145 -0
- package/dist/server/aiBinding.d.ts +68 -0
- package/dist/server/aiBinding.d.ts.map +1 -0
- package/dist/server/aiBinding.js +294 -0
- package/dist/server/attribution.d.ts +43 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +75 -0
- package/dist/server/authorizeUrl.d.ts +43 -0
- package/dist/server/authorizeUrl.d.ts.map +1 -0
- package/dist/server/authorizeUrl.js +106 -0
- package/dist/server/connectUrl.d.ts +21 -0
- package/dist/server/connectUrl.d.ts.map +1 -0
- package/dist/server/connectUrl.js +37 -0
- package/dist/server/context.d.ts +68 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +117 -0
- package/dist/server/emailBinding.d.ts +72 -0
- package/dist/server/emailBinding.d.ts.map +1 -0
- package/dist/server/emailBinding.js +124 -0
- package/dist/server/emit.d.ts +63 -0
- package/dist/server/emit.d.ts.map +1 -0
- package/dist/server/emit.js +101 -0
- package/dist/server/env.d.ts +44 -0
- package/dist/server/env.d.ts.map +1 -0
- package/dist/server/env.js +1 -0
- package/dist/server/everyApp.d.ts +65 -19
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +195 -30
- package/dist/server/fromMcpTools.d.ts +89 -0
- package/dist/server/fromMcpTools.d.ts.map +1 -0
- package/dist/server/fromMcpTools.js +192 -0
- package/dist/server/gatewayFetch.d.ts +54 -14
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +201 -37
- package/dist/server/gatewayUrl.d.ts +13 -0
- package/dist/server/gatewayUrl.d.ts.map +1 -0
- package/dist/server/gatewayUrl.js +34 -0
- package/dist/server/index.d.ts +23 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +19 -2
- package/dist/server/integrationFetch.d.ts +162 -0
- package/dist/server/integrationFetch.d.ts.map +1 -0
- package/dist/server/integrationFetch.js +688 -0
- package/dist/server/listMembers.d.ts +32 -0
- package/dist/server/listMembers.d.ts.map +1 -0
- package/dist/server/listMembers.js +71 -0
- package/dist/server/nodeServer.d.ts +48 -0
- package/dist/server/nodeServer.d.ts.map +1 -0
- package/dist/server/nodeServer.js +45 -0
- package/dist/server/refusal.d.ts +55 -0
- package/dist/server/refusal.d.ts.map +1 -0
- package/dist/server/refusal.js +193 -0
- package/dist/server/sendEmail.d.ts +39 -0
- package/dist/server/sendEmail.d.ts.map +1 -0
- package/dist/server/sendEmail.js +114 -0
- package/dist/server/tools.d.ts +184 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +347 -0
- package/dist/server/toolsEndpoint.d.ts +32 -0
- package/dist/server/toolsEndpoint.d.ts.map +1 -0
- package/dist/server/toolsEndpoint.js +237 -0
- package/dist/tanstack-start/index.d.ts +9 -0
- package/dist/tanstack-start/index.d.ts.map +1 -0
- package/dist/tanstack-start/index.js +29 -0
- package/dist/testing/index.d.ts +93 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +156 -0
- package/package.json +42 -8
- package/dist/server/mcp.d.ts +0 -66
- package/dist/server/mcp.d.ts.map +0 -1
- package/dist/server/mcp.js +0 -147
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The manifest an app author writes as `everyapp.config.ts`, typed:
|
|
3
|
+
*
|
|
4
|
+
* import { defineEveryApp } from "@every-app/sdk";
|
|
5
|
+
*
|
|
6
|
+
* export default defineEveryApp({
|
|
7
|
+
* id: "notes",
|
|
8
|
+
* name: "Notes",
|
|
9
|
+
* resources: { d1: ["DB"] },
|
|
10
|
+
* });
|
|
11
|
+
*
|
|
12
|
+
* Types only, and a leaf module: `cloudflare.config.ts` imports the manifest,
|
|
13
|
+
* and the Cloudflare Vite plugin hides from the Worker every file the config
|
|
14
|
+
* imports. The rules beyond the shape (which ids exist, which names are
|
|
15
|
+
* reserved, which scope sets a provider has) are the CLI's: `everyapp deploy`
|
|
16
|
+
* and `everyapp dev` validate the manifest and say what is wrong. The
|
|
17
|
+
* perimeter's schema (`@every-app/perimeter/manifest`) is held to this type
|
|
18
|
+
* by a test there.
|
|
19
|
+
*
|
|
20
|
+
* The Worker reads the manifest back as `env.EVERYAPP_MANIFEST`, which
|
|
21
|
+
* `everyAppWorker()` sets and `cf workers types` types from the file.
|
|
22
|
+
*/
|
|
23
|
+
/** Why a setting is needed and whether the app opens without it (the settings model). */
|
|
24
|
+
export interface EveryAppSettingNeed {
|
|
25
|
+
/** Why the app needs it, for whoever sets it. At most 200 characters. */
|
|
26
|
+
readonly why?: string;
|
|
27
|
+
/** An https page that says where the key or client comes from. */
|
|
28
|
+
readonly docs?: string;
|
|
29
|
+
/** The app opens without it; the feature using it says what is missing. */
|
|
30
|
+
readonly optional?: boolean;
|
|
31
|
+
/** The group of which one member is enough ("AI model"). */
|
|
32
|
+
readonly anyOf?: string;
|
|
33
|
+
}
|
|
34
|
+
/** A route reachable without a signed-in member. */
|
|
35
|
+
export interface EveryAppPublicRoute {
|
|
36
|
+
/** Absolute glob: `*` matches one segment, `**` one or more. */
|
|
37
|
+
readonly path: string;
|
|
38
|
+
/** The methods it answers; `["GET"]` when left out. */
|
|
39
|
+
readonly methods?: readonly string[];
|
|
40
|
+
}
|
|
41
|
+
/** A Durable Object or Workflow class: its binding, the class, and the helper Worker that defines it. */
|
|
42
|
+
export interface EveryAppClassResource {
|
|
43
|
+
readonly name: string;
|
|
44
|
+
readonly className: string;
|
|
45
|
+
readonly worker?: string;
|
|
46
|
+
}
|
|
47
|
+
/** A Cloudflare Queue's consumer settings. */
|
|
48
|
+
export interface EveryAppQueueConsumer {
|
|
49
|
+
readonly worker?: string;
|
|
50
|
+
readonly maxBatchSize?: number;
|
|
51
|
+
readonly maxBatchTimeout?: number;
|
|
52
|
+
readonly maxRetries?: number;
|
|
53
|
+
readonly maxConcurrency?: number | null;
|
|
54
|
+
readonly retryDelay?: number;
|
|
55
|
+
readonly visibilityTimeoutMs?: number;
|
|
56
|
+
readonly deadLetterQueue?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Cloudflare's limits for one of the app's Workers. */
|
|
59
|
+
export interface EveryAppWorkerLimits {
|
|
60
|
+
/** CPU milliseconds an invocation may use, up to 300000. */
|
|
61
|
+
readonly cpuMs?: number;
|
|
62
|
+
}
|
|
63
|
+
/** The Cloudflare resources the app's Workers bind; the deploy creates them. */
|
|
64
|
+
export interface EveryAppResources {
|
|
65
|
+
readonly d1?: readonly string[];
|
|
66
|
+
readonly kv?: readonly string[];
|
|
67
|
+
readonly r2?: readonly string[];
|
|
68
|
+
readonly durableObjects?: readonly EveryAppClassResource[];
|
|
69
|
+
readonly workflows?: readonly EveryAppClassResource[];
|
|
70
|
+
readonly hyperdrive?: readonly {
|
|
71
|
+
readonly name: string;
|
|
72
|
+
readonly worker?: string;
|
|
73
|
+
readonly caching?: "off" | "default";
|
|
74
|
+
}[];
|
|
75
|
+
readonly queues?: readonly {
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly consumer?: true | EveryAppQueueConsumer;
|
|
78
|
+
}[];
|
|
79
|
+
readonly ai?: readonly string[];
|
|
80
|
+
readonly browser?: readonly string[];
|
|
81
|
+
readonly images?: readonly string[];
|
|
82
|
+
readonly vectorize?: readonly {
|
|
83
|
+
readonly name: string;
|
|
84
|
+
readonly dimensions?: number;
|
|
85
|
+
readonly metric?: "cosine" | "euclidean" | "dot-product";
|
|
86
|
+
/** A Workers AI embedding model's shape, instead of `dimensions` and `metric`. */
|
|
87
|
+
readonly preset?: "@cf/baai/bge-small-en-v1.5" | "@cf/baai/bge-base-en-v1.5" | "@cf/baai/bge-large-en-v1.5" | "openai/text-embedding-ada-002" | "cohere/embed-multilingual-v2.0";
|
|
88
|
+
}[];
|
|
89
|
+
readonly aiGateway?: readonly {
|
|
90
|
+
readonly name: string;
|
|
91
|
+
readonly collectLogs?: boolean;
|
|
92
|
+
readonly cacheTtl?: number;
|
|
93
|
+
}[];
|
|
94
|
+
readonly sendEmail?: readonly {
|
|
95
|
+
readonly name: string;
|
|
96
|
+
readonly allowedSenderAddresses: readonly string[];
|
|
97
|
+
readonly destinationAddress?: string;
|
|
98
|
+
readonly allowedDestinationAddresses?: readonly string[];
|
|
99
|
+
}[];
|
|
100
|
+
readonly secretsStore?: readonly {
|
|
101
|
+
readonly name: string;
|
|
102
|
+
}[];
|
|
103
|
+
readonly analyticsEngine?: readonly {
|
|
104
|
+
readonly name: string;
|
|
105
|
+
readonly dataset?: string;
|
|
106
|
+
}[];
|
|
107
|
+
}
|
|
108
|
+
/** One capability the Gateway serves the app with keys it holds. */
|
|
109
|
+
export interface EveryAppCapabilityEntry extends EveryAppSettingNeed {
|
|
110
|
+
readonly access: "read" | "write";
|
|
111
|
+
/** An OAuth client's scope sets, by name (`["gmail.read"]`). */
|
|
112
|
+
readonly scopes?: readonly string[];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* One of the app's plain settings: a value that isn't a secret and
|
|
116
|
+
* differs per install (a PostHog host, a region), set with `everyapp
|
|
117
|
+
* configure <app>` and read from `env`.
|
|
118
|
+
*/
|
|
119
|
+
export interface EveryAppSettingEntry {
|
|
120
|
+
readonly name: string;
|
|
121
|
+
/** Why the app needs it: what whoever installs the app reads. */
|
|
122
|
+
readonly why: string;
|
|
123
|
+
readonly docs?: string;
|
|
124
|
+
readonly optional?: boolean;
|
|
125
|
+
/** What it takes; text when not given. */
|
|
126
|
+
readonly type?: "text" | "url" | "number" | "boolean";
|
|
127
|
+
/** The values a text setting may take. */
|
|
128
|
+
readonly values?: readonly string[];
|
|
129
|
+
/** What the app reads while nobody has set it; the deploy writes it. */
|
|
130
|
+
readonly default?: string;
|
|
131
|
+
}
|
|
132
|
+
/** One of the app's own secrets, with its need. */
|
|
133
|
+
export interface EveryAppSecretEntry extends EveryAppSettingNeed {
|
|
134
|
+
readonly name: string;
|
|
135
|
+
/** Its guide in the everyapp skill (`"setup/main-secret.md"`). */
|
|
136
|
+
readonly setup?: string;
|
|
137
|
+
}
|
|
138
|
+
/** `everyapp.config.ts`. */
|
|
139
|
+
export interface EveryAppManifest {
|
|
140
|
+
/** Stable id, kebab-case: the app's hostname and Worker. */
|
|
141
|
+
readonly id: string;
|
|
142
|
+
readonly name?: string;
|
|
143
|
+
/** The one line the Gateway's app library shows under the name. */
|
|
144
|
+
readonly description?: string;
|
|
145
|
+
/** The path of an SVG the app serves (`"/everyapp-icon.svg"`). */
|
|
146
|
+
readonly icon?: string;
|
|
147
|
+
/** Legacy: the entry comes from `cloudflare.config.ts`. */
|
|
148
|
+
readonly main?: string;
|
|
149
|
+
/** YYYY-MM-DD. */
|
|
150
|
+
readonly compatibilityDate?: string;
|
|
151
|
+
readonly resources?: EveryAppResources;
|
|
152
|
+
/** Helper Workers deployed beside the app's as `<app worker>--<name>`. */
|
|
153
|
+
readonly workers?: readonly {
|
|
154
|
+
readonly name: string;
|
|
155
|
+
readonly binding?: string;
|
|
156
|
+
readonly limits?: EveryAppWorkerLimits;
|
|
157
|
+
}[];
|
|
158
|
+
readonly database?: {
|
|
159
|
+
readonly provider: "d1" | "postgres";
|
|
160
|
+
/** A cloud region such as `"aws:us-east-1"`. */
|
|
161
|
+
readonly region?: string;
|
|
162
|
+
};
|
|
163
|
+
readonly limits?: EveryAppWorkerLimits;
|
|
164
|
+
/** Routes open without a signed-in member. Default: none. */
|
|
165
|
+
readonly public?: readonly EveryAppPublicRoute[];
|
|
166
|
+
/**
|
|
167
|
+
* Static files of the asset bundle anyone may fetch (favicons, icons, an
|
|
168
|
+
* OG image): path patterns, GET and HEAD, never Worker code.
|
|
169
|
+
*/
|
|
170
|
+
readonly publicAssets?: readonly string[];
|
|
171
|
+
/**
|
|
172
|
+
* Routes a bearer client (a native app, a script with a personal token)
|
|
173
|
+
* reaches with its token only: `paths` in `public`'s glob syntax, every
|
|
174
|
+
* method, and `why` the app needs them, shown to the operator. The
|
|
175
|
+
* Gateway answers 401 to a request carrying its session cookie there,
|
|
176
|
+
* and `everyapp access on` lets these paths through Cloudflare Access.
|
|
177
|
+
* Default: none.
|
|
178
|
+
*/
|
|
179
|
+
readonly bearerRoutes?: {
|
|
180
|
+
readonly paths: readonly string[];
|
|
181
|
+
readonly why: string;
|
|
182
|
+
};
|
|
183
|
+
/** AI providers the Gateway calls for the app, by id or with their need. */
|
|
184
|
+
readonly providers?: readonly (string | (EveryAppSettingNeed & {
|
|
185
|
+
readonly id: string;
|
|
186
|
+
}))[];
|
|
187
|
+
/** Capabilities by id (`members`, `email`, `dataforseo`, …). */
|
|
188
|
+
readonly capabilities?: {
|
|
189
|
+
readonly [id: string]: EveryAppCapabilityEntry;
|
|
190
|
+
};
|
|
191
|
+
/** The app's own secrets, by name or with their need. */
|
|
192
|
+
readonly secrets?: readonly (string | EveryAppSecretEntry)[];
|
|
193
|
+
/** The app's plain settings: per-install values that aren't secrets. */
|
|
194
|
+
readonly settings?: readonly EveryAppSettingEntry[];
|
|
195
|
+
readonly ai?: {
|
|
196
|
+
/** Model ids the app may request; any other is `model_not_allowed`. */
|
|
197
|
+
readonly models?: readonly string[];
|
|
198
|
+
/** OpenAI API paths beyond inference (`"/v1/files"`). */
|
|
199
|
+
readonly routes?: readonly string[];
|
|
200
|
+
/** The app takes the Gateway's default chat model (`ai()`). */
|
|
201
|
+
readonly chat?: boolean | EveryAppSettingNeed;
|
|
202
|
+
};
|
|
203
|
+
/** `inbound: true`: the Worker exports an `email()` handler. */
|
|
204
|
+
readonly email?: {
|
|
205
|
+
readonly inbound?: boolean;
|
|
206
|
+
};
|
|
207
|
+
/** Who can open the app once registered; `"admins"` by default. */
|
|
208
|
+
readonly access?: "everyone" | "admins";
|
|
209
|
+
readonly serverFnGuard?: boolean;
|
|
210
|
+
readonly serverFnBase?: string;
|
|
211
|
+
/** Shell command that builds the app; `cf build` by default. */
|
|
212
|
+
readonly build?: string;
|
|
213
|
+
/** Shell command `everyapp dev` starts; it must listen on PORT. */
|
|
214
|
+
readonly dev?: string;
|
|
215
|
+
/** Legacy: the port comes from PORT. */
|
|
216
|
+
readonly devPort?: number;
|
|
217
|
+
/** Dependency install command; false skips it. */
|
|
218
|
+
readonly install?: false | string;
|
|
219
|
+
readonly migrations?: {
|
|
220
|
+
readonly engine: "drizzle" | "d1-sql" | "prisma";
|
|
221
|
+
readonly dialect?: "sqlite" | "postgresql";
|
|
222
|
+
readonly dir?: string;
|
|
223
|
+
readonly config?: string;
|
|
224
|
+
readonly binding?: string;
|
|
225
|
+
};
|
|
226
|
+
/** Who answers `/mcp` on the app's own host, and why it needs to. */
|
|
227
|
+
readonly mcp?: {
|
|
228
|
+
readonly by: "gateway" | "app";
|
|
229
|
+
readonly why: string;
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Type `everyapp.config.ts` without widening it: the literal binding names
|
|
234
|
+
* stay, so `everyAppWorker()` types `env.DB` and `env.EVERYAPP_MANIFEST`
|
|
235
|
+
* from them. Returns the manifest as given.
|
|
236
|
+
*/
|
|
237
|
+
export declare function defineEveryApp<const M extends EveryAppManifest>(manifest: M): M;
|
|
238
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The manifest an app author writes as `everyapp.config.ts`, typed:
|
|
3
|
+
*
|
|
4
|
+
* import { defineEveryApp } from "@every-app/sdk";
|
|
5
|
+
*
|
|
6
|
+
* export default defineEveryApp({
|
|
7
|
+
* id: "notes",
|
|
8
|
+
* name: "Notes",
|
|
9
|
+
* resources: { d1: ["DB"] },
|
|
10
|
+
* });
|
|
11
|
+
*
|
|
12
|
+
* Types only, and a leaf module: `cloudflare.config.ts` imports the manifest,
|
|
13
|
+
* and the Cloudflare Vite plugin hides from the Worker every file the config
|
|
14
|
+
* imports. The rules beyond the shape (which ids exist, which names are
|
|
15
|
+
* reserved, which scope sets a provider has) are the CLI's: `everyapp deploy`
|
|
16
|
+
* and `everyapp dev` validate the manifest and say what is wrong. The
|
|
17
|
+
* perimeter's schema (`@every-app/perimeter/manifest`) is held to this type
|
|
18
|
+
* by a test there.
|
|
19
|
+
*
|
|
20
|
+
* The Worker reads the manifest back as `env.EVERYAPP_MANIFEST`, which
|
|
21
|
+
* `everyAppWorker()` sets and `cf workers types` types from the file.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Type `everyapp.config.ts` without widening it: the literal binding names
|
|
25
|
+
* stay, so `everyAppWorker()` types `env.DB` and `env.EVERYAPP_MANIFEST`
|
|
26
|
+
* from them. Returns the manifest as given.
|
|
27
|
+
*/
|
|
28
|
+
export function defineEveryApp(manifest) {
|
|
29
|
+
return manifest;
|
|
30
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ai()`: the Gateway's default chat model for an app that needs "a model"
|
|
3
|
+
* rather than one provider (docs/design/2026-10-model-providers.md). The
|
|
4
|
+
* manifest says `ai: { chat: true }` (or `{ chat: { why } }`); the Gateway's
|
|
5
|
+
* operator decides which provider and model that is (`everyapp ai
|
|
6
|
+
* default`, else OpenRouter → Workers AI → OpenAI → …, the first with its
|
|
7
|
+
* key set), and the app never names either: it sends OpenAI-shaped chat
|
|
8
|
+
* completions (and embeddings) to `/api/ai/default/v1/…` with `model:
|
|
9
|
+
* "default"` or no model at all, and the Gateway fills the model in.
|
|
10
|
+
*
|
|
11
|
+
* An OpenAI client takes `baseURL` and `fetch` as they are:
|
|
12
|
+
*
|
|
13
|
+
* const { baseURL, fetch, model } = ai({ env, for: request });
|
|
14
|
+
* const client = new OpenAI({ baseURL, fetch, apiKey: "gateway-managed" });
|
|
15
|
+
* await client.chat.completions.create({ model, messages });
|
|
16
|
+
*
|
|
17
|
+
* In local development with no Gateway, the developer's own key in
|
|
18
|
+
* `.dev.vars` decides the provider by the same order (createGatewayFetch's
|
|
19
|
+
* fallback). An app that needs one provider in particular keeps listing it
|
|
20
|
+
* under `providers` and calling `/api/ai/<provider>/…`.
|
|
21
|
+
*/
|
|
22
|
+
import { AI_DEFAULT_MODEL } from "../internal/index.js";
|
|
23
|
+
import { type GatewayCallFor } from "./attribution.js";
|
|
24
|
+
import { type CreateGatewayFetchOptions } from "./gatewayFetch.js";
|
|
25
|
+
import type { SetupInfo } from "./refusal.js";
|
|
26
|
+
export interface AiClient {
|
|
27
|
+
/** `http://every-app-gateway.internal/api/ai/default/v1`: an OpenAI client's base URL. */
|
|
28
|
+
baseURL: string;
|
|
29
|
+
/** The fetch that reaches the Gateway (or, in dev, the provider directly). */
|
|
30
|
+
fetch: typeof fetch;
|
|
31
|
+
/** The model name that means "whatever the Gateway's default is": `default`. */
|
|
32
|
+
model: typeof AI_DEFAULT_MODEL;
|
|
33
|
+
/** The default route's chat completions URL, for a plain `fetch`. */
|
|
34
|
+
chatCompletionsUrl: string;
|
|
35
|
+
/** The default route's embeddings URL, for a plain `fetch`. */
|
|
36
|
+
embeddingsUrl: string;
|
|
37
|
+
}
|
|
38
|
+
/** The base URL of the default route, as the SDK and the docs name it. */
|
|
39
|
+
export declare const AI_DEFAULT_BASE_URL = "http://every-app-gateway.internal/api/ai/default/v1";
|
|
40
|
+
/**
|
|
41
|
+
* The Gateway's default chat model as a client: a base URL, a fetch and
|
|
42
|
+
* the model name to send. Throws `ConfigurationError` where
|
|
43
|
+
* `createGatewayFetch` does (no binding and no dev key) and
|
|
44
|
+
* `AttributionError` where a shared app's call says nobody's.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ai(options: CreateGatewayFetchOptions & {
|
|
47
|
+
optional: true;
|
|
48
|
+
}): AiClient | null;
|
|
49
|
+
export declare function ai(options: CreateGatewayFetchOptions): AiClient;
|
|
50
|
+
/** Whether model calls to a provider (or the default) would go through. */
|
|
51
|
+
export interface AiStatus extends SetupInfo {
|
|
52
|
+
/** The id asked about: `default`, or a provider's (`openrouter`, `workers-ai`, …). */
|
|
53
|
+
provider: string;
|
|
54
|
+
/** The manifest asks for it: `ai.chat` for `default`, else `providers`. */
|
|
55
|
+
requested: boolean;
|
|
56
|
+
/** The Gateway (in local dev, `.dev.vars`) holds every setting it needs. */
|
|
57
|
+
configured: boolean;
|
|
58
|
+
/** Calls would go through. */
|
|
59
|
+
ready: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* For `default`: the provider and model calls go to now, or null while
|
|
62
|
+
* none is configured. Null for a named provider.
|
|
63
|
+
*/
|
|
64
|
+
resolved: {
|
|
65
|
+
provider: string;
|
|
66
|
+
label: string;
|
|
67
|
+
model: string;
|
|
68
|
+
} | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether the app can use a model right now, without calling one: gate
|
|
72
|
+
* an AI feature and show `setup` ("A chat model isn't set up on this
|
|
73
|
+
* Gateway: it needs OPENROUTER_API_KEY. An admin runs: pnpm everyapp
|
|
74
|
+
* configure inbox") up front instead of failing mid-task. `provider`
|
|
75
|
+
* defaults to `default`, the Gateway's default model (`ai: { chat: true }`);
|
|
76
|
+
* name one the manifest lists under `providers` to ask about it instead.
|
|
77
|
+
* The Gateway owns the wording: show `setup` and `command` as they are.
|
|
78
|
+
*
|
|
79
|
+
* Over the binding it sends `GET /api/ai/<provider>`; in local dev it
|
|
80
|
+
* answers from `.dev.vars` by the same rule `createGatewayFetch()` uses.
|
|
81
|
+
*/
|
|
82
|
+
export declare function aiStatus({ env, provider, for: explicitTarget, }: {
|
|
83
|
+
env: object;
|
|
84
|
+
provider?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Whom the status is for: the default resolves on that organization's
|
|
87
|
+
* choice (`everyapp ai default`). Left out, the request `everyApp()` is
|
|
88
|
+
* serving or the organization `withOrganization()` named, as on every
|
|
89
|
+
* call.
|
|
90
|
+
*/
|
|
91
|
+
for?: GatewayCallFor;
|
|
92
|
+
}): Promise<AiStatus>;
|
|
93
|
+
/**
|
|
94
|
+
* A provider's root behind the Gateway, `http://every-app-gateway.internal/api/ai/<provider>`:
|
|
95
|
+
* join the provider's own paths onto it (`/api/v1/chat/completions` for
|
|
96
|
+
* OpenRouter) and send them with `createGatewayFetch()`. For an OpenAI
|
|
97
|
+
* client's `baseURL`, use {@link aiBaseUrl}.
|
|
98
|
+
*/
|
|
99
|
+
export declare function providerBaseUrl(provider: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* The OpenAI-compatible base URL of `provider` behind the Gateway, for an
|
|
102
|
+
* OpenAI client's `baseURL` (with `fetch: createGatewayFetch(...)`):
|
|
103
|
+
* `default` (the default) is {@link AI_DEFAULT_BASE_URL},
|
|
104
|
+
* `…/api/ai/default/v1`; a catalog provider's is its root and the prefix
|
|
105
|
+
* of its chat route (`…/api/ai/openrouter/api/v1`, `…/api/ai/workers-ai/v1`,
|
|
106
|
+
* `…/api/ai/openai/v1`). Throws `ConfigurationError` for a provider with
|
|
107
|
+
* no OpenAI-compatible chat route (Cohere): call {@link providerBaseUrl}
|
|
108
|
+
* with its own paths instead.
|
|
109
|
+
*/
|
|
110
|
+
export declare function aiBaseUrl(provider?: string): string;
|
|
111
|
+
//# sourceMappingURL=ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/server/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,gBAAgB,EAOjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,QAAQ;IACvB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,gFAAgF;IAChF,KAAK,EAAE,OAAO,gBAAgB,CAAC;IAC/B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,wDAAuD,CAAC;AAExF;;;;;GAKG;AACH,wBAAgB,EAAE,CAChB,OAAO,EAAE,yBAAyB,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GACtD,QAAQ,GAAG,IAAI,CAAC;AACnB,wBAAgB,EAAE,CAAC,OAAO,EAAE,yBAAyB,GAAG,QAAQ,CAAC;AAajE,2EAA2E;AAC3E,MAAM,WAAW,QAAS,SAAQ,SAAS;IACzC,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,UAAU,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,EAC7B,GAAG,EACH,QAA8B,EAC9B,GAAG,EAAE,cAAc,GACpB,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA+EpB;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,QAAQ,GAAE,MAA4B,GAAG,MAAM,CAaxE"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ai()`: the Gateway's default chat model for an app that needs "a model"
|
|
3
|
+
* rather than one provider (docs/design/2026-10-model-providers.md). The
|
|
4
|
+
* manifest says `ai: { chat: true }` (or `{ chat: { why } }`); the Gateway's
|
|
5
|
+
* operator decides which provider and model that is (`everyapp ai
|
|
6
|
+
* default`, else OpenRouter → Workers AI → OpenAI → …, the first with its
|
|
7
|
+
* key set), and the app never names either: it sends OpenAI-shaped chat
|
|
8
|
+
* completions (and embeddings) to `/api/ai/default/v1/…` with `model:
|
|
9
|
+
* "default"` or no model at all, and the Gateway fills the model in.
|
|
10
|
+
*
|
|
11
|
+
* An OpenAI client takes `baseURL` and `fetch` as they are:
|
|
12
|
+
*
|
|
13
|
+
* const { baseURL, fetch, model } = ai({ env, for: request });
|
|
14
|
+
* const client = new OpenAI({ baseURL, fetch, apiKey: "gateway-managed" });
|
|
15
|
+
* await client.chat.completions.create({ model, messages });
|
|
16
|
+
*
|
|
17
|
+
* In local development with no Gateway, the developer's own key in
|
|
18
|
+
* `.dev.vars` decides the provider by the same order (createGatewayFetch's
|
|
19
|
+
* fallback). An app that needs one provider in particular keeps listing it
|
|
20
|
+
* under `providers` and calling `/api/ai/<provider>/…`.
|
|
21
|
+
*/
|
|
22
|
+
import { AI_DEFAULT_MODEL, AI_DEFAULT_PROVIDER, CATALOG, ConfigurationError, aiProviderSettings, devAiProvider, resolveAiDefault, } from "../internal/index.js";
|
|
23
|
+
import { applyAttribution, attributionFor, } from "./attribution.js";
|
|
24
|
+
import { BINDING_ORIGIN, createGatewayFetch, gatewayBinding, } from "./gatewayFetch.js";
|
|
25
|
+
/** The base URL of the default route, as the SDK and the docs name it. */
|
|
26
|
+
export const AI_DEFAULT_BASE_URL = `${BINDING_ORIGIN}/api/ai/${AI_DEFAULT_PROVIDER}/v1`;
|
|
27
|
+
export function ai(options) {
|
|
28
|
+
const fetch = createGatewayFetch(options);
|
|
29
|
+
if (!fetch)
|
|
30
|
+
return null;
|
|
31
|
+
return {
|
|
32
|
+
baseURL: AI_DEFAULT_BASE_URL,
|
|
33
|
+
fetch,
|
|
34
|
+
model: AI_DEFAULT_MODEL,
|
|
35
|
+
chatCompletionsUrl: `${AI_DEFAULT_BASE_URL}/chat/completions`,
|
|
36
|
+
embeddingsUrl: `${AI_DEFAULT_BASE_URL}/embeddings`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether the app can use a model right now, without calling one: gate
|
|
41
|
+
* an AI feature and show `setup` ("A chat model isn't set up on this
|
|
42
|
+
* Gateway: it needs OPENROUTER_API_KEY. An admin runs: pnpm everyapp
|
|
43
|
+
* configure inbox") up front instead of failing mid-task. `provider`
|
|
44
|
+
* defaults to `default`, the Gateway's default model (`ai: { chat: true }`);
|
|
45
|
+
* name one the manifest lists under `providers` to ask about it instead.
|
|
46
|
+
* The Gateway owns the wording: show `setup` and `command` as they are.
|
|
47
|
+
*
|
|
48
|
+
* Over the binding it sends `GET /api/ai/<provider>`; in local dev it
|
|
49
|
+
* answers from `.dev.vars` by the same rule `createGatewayFetch()` uses.
|
|
50
|
+
*/
|
|
51
|
+
export async function aiStatus({ env, provider = AI_DEFAULT_PROVIDER, for: explicitTarget, }) {
|
|
52
|
+
const target = attributionFor(env, explicitTarget, "aiStatus");
|
|
53
|
+
const values = env;
|
|
54
|
+
const binding = gatewayBinding(env);
|
|
55
|
+
const unavailable = {
|
|
56
|
+
provider,
|
|
57
|
+
requested: false,
|
|
58
|
+
configured: false,
|
|
59
|
+
ready: false,
|
|
60
|
+
resolved: null,
|
|
61
|
+
settings: [],
|
|
62
|
+
setup: null,
|
|
63
|
+
command: null,
|
|
64
|
+
};
|
|
65
|
+
if (binding && typeof binding.fetch === "function") {
|
|
66
|
+
const headers = new Headers();
|
|
67
|
+
if (target !== undefined)
|
|
68
|
+
applyAttribution(headers, target);
|
|
69
|
+
const response = await binding.fetch(`${BINDING_ORIGIN}/api/ai/${encodeURIComponent(provider)}`, { headers });
|
|
70
|
+
if (!response.ok)
|
|
71
|
+
return unavailable;
|
|
72
|
+
const body = (await response.json());
|
|
73
|
+
return {
|
|
74
|
+
...unavailable,
|
|
75
|
+
...body,
|
|
76
|
+
provider,
|
|
77
|
+
settings: Array.isArray(body.settings) ? body.settings : [],
|
|
78
|
+
setup: typeof body.setup === "string" ? body.setup : null,
|
|
79
|
+
command: typeof body.command === "string" ? body.command : null,
|
|
80
|
+
resolved: body.resolved ?? null,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!values["EVERYAPP_DEV"])
|
|
84
|
+
return unavailable;
|
|
85
|
+
const isSet = (name) => typeof values[name] === "string" && values[name].trim() !== "";
|
|
86
|
+
const dev = (label, settings, configured, resolved, also = "") => ({
|
|
87
|
+
provider,
|
|
88
|
+
requested: true,
|
|
89
|
+
configured,
|
|
90
|
+
ready: configured,
|
|
91
|
+
resolved,
|
|
92
|
+
settings: configured ? [] : [...settings],
|
|
93
|
+
setup: configured
|
|
94
|
+
? null
|
|
95
|
+
: `${label} isn't set up for local development: set ${settings.join(" and ")}${also} in .dev.vars.`,
|
|
96
|
+
command: null,
|
|
97
|
+
});
|
|
98
|
+
if (provider === AI_DEFAULT_PROVIDER) {
|
|
99
|
+
const resolution = resolveAiDefault({ provider: null, isSet });
|
|
100
|
+
return dev("A chat model", resolution.settings, resolution.configured, resolution.configured
|
|
101
|
+
? {
|
|
102
|
+
provider: resolution.provider,
|
|
103
|
+
label: resolution.label,
|
|
104
|
+
model: resolution.model,
|
|
105
|
+
}
|
|
106
|
+
: null, " (or another model provider's key)");
|
|
107
|
+
}
|
|
108
|
+
const spec = devAiProvider(provider);
|
|
109
|
+
if (!spec)
|
|
110
|
+
return unavailable;
|
|
111
|
+
const settings = aiProviderSettings(spec);
|
|
112
|
+
return dev(CATALOG.get(provider)?.label ?? provider, settings, settings.every(isSet), null);
|
|
113
|
+
}
|
|
114
|
+
const CHAT_COMPLETIONS = "/chat/completions";
|
|
115
|
+
/**
|
|
116
|
+
* A provider's root behind the Gateway, `http://every-app-gateway.internal/api/ai/<provider>`:
|
|
117
|
+
* join the provider's own paths onto it (`/api/v1/chat/completions` for
|
|
118
|
+
* OpenRouter) and send them with `createGatewayFetch()`. For an OpenAI
|
|
119
|
+
* client's `baseURL`, use {@link aiBaseUrl}.
|
|
120
|
+
*/
|
|
121
|
+
export function providerBaseUrl(provider) {
|
|
122
|
+
return `${BINDING_ORIGIN}/api/ai/${encodeURIComponent(provider)}`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The OpenAI-compatible base URL of `provider` behind the Gateway, for an
|
|
126
|
+
* OpenAI client's `baseURL` (with `fetch: createGatewayFetch(...)`):
|
|
127
|
+
* `default` (the default) is {@link AI_DEFAULT_BASE_URL},
|
|
128
|
+
* `…/api/ai/default/v1`; a catalog provider's is its root and the prefix
|
|
129
|
+
* of its chat route (`…/api/ai/openrouter/api/v1`, `…/api/ai/workers-ai/v1`,
|
|
130
|
+
* `…/api/ai/openai/v1`). Throws `ConfigurationError` for a provider with
|
|
131
|
+
* no OpenAI-compatible chat route (Cohere): call {@link providerBaseUrl}
|
|
132
|
+
* with its own paths instead.
|
|
133
|
+
*/
|
|
134
|
+
export function aiBaseUrl(provider = AI_DEFAULT_PROVIDER) {
|
|
135
|
+
if (provider === AI_DEFAULT_PROVIDER)
|
|
136
|
+
return AI_DEFAULT_BASE_URL;
|
|
137
|
+
const capability = CATALOG.get(provider);
|
|
138
|
+
const chat = capability?.mode === "ai" && "chat" in capability
|
|
139
|
+
? capability.chat
|
|
140
|
+
: undefined;
|
|
141
|
+
if (!chat?.path.endsWith(CHAT_COMPLETIONS)) {
|
|
142
|
+
throw new ConfigurationError(`${provider} has no OpenAI-compatible chat route in the catalog: join its own paths onto providerBaseUrl("${provider}") instead.`);
|
|
143
|
+
}
|
|
144
|
+
return `${providerBaseUrl(provider)}${chat.path.slice(0, -CHAT_COMPLETIONS.length)}`;
|
|
145
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `gatewayAiBinding(env)`: the Gateway's AI providers as a Workers AI
|
|
3
|
+
* binding, for code written against `env.AI.run(model, inputs, options)`.
|
|
4
|
+
*
|
|
5
|
+
* An app on Every App needs no `ai` binding of its own to call models: the
|
|
6
|
+
* Gateway holds the keys, counts the calls and keeps the app to `ai.models`.
|
|
7
|
+
* Code that already calls `env.AI.run()` (upstream code a port keeps, the
|
|
8
|
+
* Agents SDK, `workers-ai-provider`) gets this object in its place:
|
|
9
|
+
*
|
|
10
|
+
* const AI = gatewayAiBinding(env, { for: request });
|
|
11
|
+
* await AI.run("@cf/meta/llama-3.1-8b-instruct-fast", { messages });
|
|
12
|
+
*
|
|
13
|
+
* Each `run()` becomes an OpenAI-compatible call on the provider's route
|
|
14
|
+
* through the Gateway (`createGatewayFetch`): text generation (`messages`
|
|
15
|
+
* or `prompt`) on its chat completions route, text embeddings (`text`) on
|
|
16
|
+
* its embeddings route, answered in Workers AI's shapes (`{ response,
|
|
17
|
+
* tool_calls, usage }`, `{ shape, data }`, or a stream of `data:
|
|
18
|
+
* {"response": …}` events with `stream: true`). In local development
|
|
19
|
+
* without a Gateway, the developer's own key in `.dev.vars` is used, as
|
|
20
|
+
* `createGatewayFetch` does (WORKERS_AI_API_TOKEN and CLOUDFLARE_ACCOUNT_ID
|
|
21
|
+
* for Workers AI).
|
|
22
|
+
*/
|
|
23
|
+
import { AI_DEFAULT_PROVIDER, type AiProviderId } from "../internal/index.js";
|
|
24
|
+
import type { GatewayCallFor } from "./attribution.js";
|
|
25
|
+
export interface GatewayAiBindingOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Whom the calls are for: the inbound request, or `{ background: true,
|
|
28
|
+
* organizationId }` (createGatewayFetch's `for`).
|
|
29
|
+
*/
|
|
30
|
+
for?: GatewayCallFor;
|
|
31
|
+
/**
|
|
32
|
+
* The Gateway provider the calls go to: an `ai` entry of the catalog
|
|
33
|
+
* with OpenAI-compatible routes (`workers-ai`, `openrouter`, `openai`,
|
|
34
|
+
* …), or `default`, the operator's model (`ai: { chat: true }`).
|
|
35
|
+
* Default: `workers-ai`, the provider `env.AI` reaches, so `@cf/…` model
|
|
36
|
+
* ids work as they are. The manifest lists the provider under
|
|
37
|
+
* `providers` (or says `ai.chat` for `default`).
|
|
38
|
+
*/
|
|
39
|
+
provider?: AiProviderId | typeof AI_DEFAULT_PROVIDER;
|
|
40
|
+
/**
|
|
41
|
+
* The model id to send for a model the code names, e.g.
|
|
42
|
+
* `{ "@cf/meta/llama-3.1-8b-instruct-fast": "meta-llama/llama-3.1-8b-instruct" }`
|
|
43
|
+
* with `provider: "openrouter"`. A model not listed is sent as it is,
|
|
44
|
+
* except that on `default` an `@cf/…` id becomes `default` (the
|
|
45
|
+
* operator's model).
|
|
46
|
+
*/
|
|
47
|
+
models?: Readonly<Record<string, string>>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A Workers AI binding (`Ai`) over the Gateway: pass it where code takes
|
|
51
|
+
* `env.AI`. `run()` covers text generation (messages or prompt; tools;
|
|
52
|
+
* `stream: true`; `returnRawResponse`, which returns the provider's
|
|
53
|
+
* OpenAI-shaped `Response`) and text embeddings; the binding's other
|
|
54
|
+
* methods (`gateway()`, `autorag()`, `models()`, `toMarkdown()`, …) and
|
|
55
|
+
* other tasks (images, audio, batches, websockets) throw
|
|
56
|
+
* `ConfigurationError`. `options.gateway` is ignored: the Gateway's
|
|
57
|
+
* operator decides whether calls go through Cloudflare AI Gateway
|
|
58
|
+
* (`everyapp ai gateway on`).
|
|
59
|
+
*
|
|
60
|
+
* Errors are thrown as a binding throws them: `GatewayRefusalError` when
|
|
61
|
+
* the Gateway refused (`ai_provider_not_configured`, `model_not_allowed`,
|
|
62
|
+
* …), `ConfigurationError` where createGatewayFetch throws one (no binding
|
|
63
|
+
* and no dev key), and an `Error` naming the status when the provider
|
|
64
|
+
* answered with an error. Nothing is checked when the binding is made, so
|
|
65
|
+
* making one per request costs nothing.
|
|
66
|
+
*/
|
|
67
|
+
export declare function gatewayAiBinding(env: object, options?: GatewayAiBindingOptions): Ai;
|
|
68
|
+
//# sourceMappingURL=aiBinding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiBinding.d.ts","sourceRoot":"","sources":["../../src/server/aiBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAEL,mBAAmB,EAInB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIvD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,mBAAmB,CAAC;IACrD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C;AAUD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,EAAE,CAoEJ"}
|