void 0.9.0 → 0.9.2
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/dist/{auth-cmd-BSdoU6dB.mjs → auth-cmd-CPkWrQR9.mjs} +2 -2
- package/dist/{better-auth-shared-BxcgLiHN.d.mts → better-auth-shared-CmEQZs1T.d.mts} +2 -2
- package/dist/{cache-Cb4Vs95q.mjs → cache-1SVxZ7BK.mjs} +2 -2
- package/dist/{cancel-deploy-CLVkqGJB.mjs → cancel-deploy-JaFClLr7.mjs} +1 -1
- package/dist/cli/cli.mjs +77 -40
- package/dist/{client-CCOKwNUz.mjs → client-DIfOFf1W.mjs} +6 -1
- package/dist/{create-project-Dg5hiuDE.mjs → create-project-DCUrFJxa.mjs} +3 -3
- package/dist/{db-D7l4OGV1.mjs → db-DiddQC2v.mjs} +191 -19
- package/dist/{delete-Bi-gbEHT.mjs → delete-CYknzwXU.mjs} +2 -2
- package/dist/{deploy-iR7ug73w.mjs → deploy-CRU9fGjE.mjs} +8 -11
- package/dist/{domain-C_atK_X9.mjs → domain-B7RntQ1r.mjs} +13 -28
- package/dist/{env-Dc073Aip.mjs → env-Bvw0wMTI.mjs} +1 -1
- package/dist/{env-helpers-bupZjGHq.d.mts → env-helpers-Bd2wVdxz.d.mts} +1 -1
- package/dist/{gen-CsawhQZz.mjs → gen-CZdNWIaA.mjs} +1 -1
- package/dist/{handler-DMSGX5S6.d.mts → handler-xflsMwWM.d.mts} +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +71 -52
- package/dist/{init-CD9yg4Xt.mjs → init-BHupO7Fm.mjs} +7 -7
- package/dist/{link-27a64clx.mjs → link-7MoXUMaI.mjs} +3 -3
- package/dist/{list-C3Xt_i8a.mjs → list-N2mCHv8q.mjs} +2 -2
- package/dist/{login-BZ1Yk9Xw.mjs → login-tt1OmNVg.mjs} +1 -1
- package/dist/{logs-CktUaLEr.mjs → logs-Cl7q2CjZ.mjs} +1 -1
- package/dist/{mcp-BU7CP6gX.mjs → mcp-BXD35N2J.mjs} +1 -1
- package/dist/{node-C2HhnBO_.mjs → node-CHWVVjO6.mjs} +3 -3
- package/dist/pages/client.d.mts +1 -1
- package/dist/pages/head-client.d.mts +1 -1
- package/dist/pages/head.d.mts +1 -1
- package/dist/pages/index.d.mts +2 -2
- package/dist/pages/index.mjs +1 -1
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +1 -1
- package/dist/{prepare-BNuC8Ds9.mjs → prepare-CrlAVbWS.mjs} +1 -1
- package/dist/{preset-Lvi0ORmO.mjs → preset-CIJG2O7a.mjs} +1 -1
- package/dist/{project-cmd-DUkWHooP.mjs → project-cmd-CLrqSbqj.mjs} +8 -8
- package/dist/{protocol-hjl3Nx5x.d.mts → protocol-DYca39yJ.d.mts} +3 -3
- package/dist/proxy-M3pxItg2.mjs +5 -0
- package/dist/{rollback-CEjAG9uQ.mjs → rollback-CEbAwbHK.mjs} +1 -1
- package/dist/{runner-Cioqe5b2.mjs → runner-DLZ9E_cX.mjs} +1 -1
- package/dist/runtime/ai.d.mts +20 -100
- package/dist/runtime/ai.mjs +102 -55
- package/dist/runtime/auth.d.mts +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +3 -3
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +2 -2
- package/dist/runtime/client-react.d.mts +2 -2
- package/dist/runtime/client-react.mjs +1 -1
- package/dist/runtime/client-solid.d.mts +2 -2
- package/dist/runtime/client-solid.mjs +1 -1
- package/dist/runtime/client-svelte.d.mts +2 -2
- package/dist/runtime/client-svelte.mjs +1 -1
- package/dist/runtime/client-vue.d.mts +2 -2
- package/dist/runtime/client-vue.mjs +1 -1
- package/dist/runtime/client.d.mts +2 -2
- package/dist/runtime/client.mjs +1 -1
- package/dist/runtime/env-helpers.d.mts +1 -1
- package/dist/runtime/env-public-client.d.mts +1 -1
- package/dist/runtime/env-public.d.mts +2 -2
- package/dist/runtime/env-public.mjs +1 -1
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/fetch-stream.d.mts +1 -1
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.d.mts +1 -1
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/handler.mjs +1 -1
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/live.d.mts +2 -2
- package/dist/runtime/live.mjs +1 -1
- package/dist/runtime/migration-handler-pg.mjs +1 -1
- package/dist/runtime/sandbox.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -2
- package/dist/runtime/ws.d.mts +3 -3
- package/dist/{secret-Dab6XQdb.mjs → secret-C_uTY7xx.mjs} +2 -2
- package/dist/{skills-GPm5Kjev.mjs → skills-BRKc--As.mjs} +1 -1
- package/package.json +2 -2
- package/skills/void/docs/guide/ai.md +109 -51
- package/skills/void/docs/guide/auth.md +3 -3
- package/skills/void/docs/node_modules/void/AGENTS.md +1 -1
- package/skills/void/docs/reference/api.md +9 -2
- package/skills/void/docs/reference/cli.md +50 -30
- /package/dist/{agents-Dkgafwfr.mjs → agents-MhSzNMiC.mjs} +0 -0
- /package/dist/{auth-BL0cU_Sy.d.mts → auth-CDeb2XAl.d.mts} +0 -0
- /package/dist/{auth-migrations-DBoTUBvq.mjs → auth-migrations-CuQkjjWE.mjs} +0 -0
- /package/dist/{better-auth-shared-pR54mTD2.mjs → better-auth-shared-ChVbrq52.mjs} +0 -0
- /package/dist/{defer-BosTTQTi.mjs → defer-CouVukrf.mjs} +0 -0
- /package/dist/{drizzle-Bvhm-Uug.mjs → drizzle-2fs1qTgy.mjs} +0 -0
- /package/dist/{env-raw-DhK_myJu.mjs → env-raw-RDkMnSTC.mjs} +0 -0
- /package/dist/{fetch-error-B8GTcrQw.mjs → fetch-error-BFIoojjf.mjs} +0 -0
- /package/dist/{fetch-error-Dn-En6Wg.d.mts → fetch-error-CimrygMq.d.mts} +0 -0
- /package/dist/{head-BW_f2L_4.d.mts → head-BsSTGnIe.d.mts} +0 -0
- /package/dist/{headers-wAPJigtE.mjs → headers-Y0jshugF.mjs} +0 -0
- /package/dist/{package-json-BMdypFnO.mjs → package-json-B2TD0JLu.mjs} +0 -0
- /package/dist/{pg-C-ybKyFU.mjs → pg-CMZ_5wsC.mjs} +0 -0
- /package/dist/{project-slug-De4UjtD9.mjs → project-slug-rX3kTOfY.mjs} +0 -0
- /package/dist/{providers-BVUcW4Jo.d.mts → providers-3Kkv63Ha.d.mts} +0 -0
- /package/dist/{resolve-project-CNpUbUHd.mjs → resolve-project-D4O1_fZz.mjs} +0 -0
- /package/dist/{runner-pg-D8ciL41o.mjs → runner-pg-Cv9V7ydr.mjs} +0 -0
- /package/dist/{standard-schema-DCIm8cwQ.d.mts → standard-schema-Dnsh2vnl.d.mts} +0 -0
- /package/dist/{subcommand-prompt-DUaWltdH.mjs → subcommand-prompt-OD-x_Tsm.mjs} +0 -0
- /package/dist/{types-s2mK7ar_.d.mts → types-Dm9kep2X.d.mts} +0 -0
- /package/dist/{yarn-pnp-BdM0hoCa.mjs → yarn-pnp-0SwYgQxx.mjs} +0 -0
package/dist/runtime/env.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRawRuntimeEnv, n as asEnv, r as envContext, t as INTERNAL_BINDING_PREFIXES } from "../env-raw-
|
|
1
|
+
import { i as getRawRuntimeEnv, n as asEnv, r as envContext, t as INTERNAL_BINDING_PREFIXES } from "../env-raw-RDkMnSTC.mjs";
|
|
2
2
|
//#region src/runtime/env.ts
|
|
3
3
|
/**
|
|
4
4
|
* Public runtime env API — exposed via "void/_env".
|
package/dist/runtime/fetch.d.mts
CHANGED
package/dist/runtime/fetch.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { C as HandlerInput, S as ValidationError, _ as defineScheduled, a as QueueBatch, b as InferProps, c as RenderAssetTags, d as VoidAssetRewriteError, f as defineHandler, g as defineRender, h as defineQueue, i as CloudEnv, l as TypedHandler, m as defineMiddleware, n as CloudContext, o as QueueMessage, p as defineHead, r as CloudContextVariables, s as QueueRetryOptions, t as CloudBindings, u as TypedQueueHandler, v as Deferred, w as ValidatorSlots, x as defer } from "../handler-
|
|
2
|
+
import { C as HandlerInput, S as ValidationError, _ as defineScheduled, a as QueueBatch, b as InferProps, c as RenderAssetTags, d as VoidAssetRewriteError, f as defineHandler, g as defineRender, h as defineQueue, i as CloudEnv, l as TypedHandler, m as defineMiddleware, n as CloudContext, o as QueueMessage, p as defineHead, r as CloudContextVariables, s as QueueRetryOptions, t as CloudBindings, u as TypedQueueHandler, v as Deferred, w as ValidatorSlots, x as defer } from "../handler-xflsMwWM.mjs";
|
|
3
3
|
export { CloudBindings, CloudContext, CloudContextVariables, CloudEnv, Deferred, HandlerInput, InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, ValidatorSlots, VoidAssetRewriteError, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
package/dist/runtime/handler.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { convertReturnValue } from "./response.mjs";
|
|
2
2
|
import { runValidation } from "./validator.mjs";
|
|
3
|
-
import { i as ValidationError, n as defer } from "../defer-
|
|
3
|
+
import { i as ValidationError, n as defer } from "../defer-CouVukrf.mjs";
|
|
4
4
|
//#region src/runtime/handler.ts
|
|
5
5
|
/**
|
|
6
6
|
* Thrown when `c.rewrite()` is called with a destination whose final path
|
package/dist/runtime/isr.mjs
CHANGED
package/dist/runtime/live.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { r as AuthUser } from "../auth-
|
|
3
|
-
import { i as CloudEnv, n as CloudContext } from "../handler-
|
|
2
|
+
import { r as AuthUser } from "../auth-CDeb2XAl.mjs";
|
|
3
|
+
import { i as CloudEnv, n as CloudContext } from "../handler-xflsMwWM.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/live.d.ts
|
|
6
6
|
type MaybePromise<T> = T | Promise<T>;
|
package/dist/runtime/live.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as disablePgPassFallback } from "../pg-
|
|
1
|
+
import { t as disablePgPassFallback } from "../pg-CMZ_5wsC.mjs";
|
|
2
2
|
//#region src/runtime/migration-handler-pg.ts
|
|
3
3
|
function createMigrationHandler(env, migrations, _dialect, runAuthMigrations) {
|
|
4
4
|
return async (request) => {
|
package/dist/runtime/sandbox.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRawRuntimeEnv } from "../env-raw-
|
|
1
|
+
import { i as getRawRuntimeEnv } from "../env-raw-RDkMnSTC.mjs";
|
|
2
2
|
import { requireRuntimeBinding } from "./env.mjs";
|
|
3
3
|
import { Sandbox, getSandbox as getSandbox$1 } from "@cloudflare/sandbox";
|
|
4
4
|
//#region src/runtime/sandbox.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as HandlerInput, T as runValidation, w as ValidatorSlots } from "../handler-
|
|
1
|
+
import { C as HandlerInput, T as runValidation, w as ValidatorSlots } from "../handler-xflsMwWM.mjs";
|
|
2
2
|
export { HandlerInput, ValidatorSlots, runValidation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as AuthState } from "../auth-
|
|
2
|
-
import { i as VoidAuthRuntimeOptions, n as VoidAuthEnv } from "../better-auth-shared-
|
|
1
|
+
import { n as AuthState } from "../auth-CDeb2XAl.mjs";
|
|
2
|
+
import { i as VoidAuthRuntimeOptions, n as VoidAuthEnv } from "../better-auth-shared-CmEQZs1T.mjs";
|
|
3
3
|
import { AnyWebSocketDefinition } from "./ws.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/ws-server.d.ts
|
package/dist/runtime/ws.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as AuthUser } from "../auth-
|
|
2
|
-
import { t as StandardSchemaV1 } from "../standard-schema-
|
|
3
|
-
import { i as CloudEnv } from "../handler-
|
|
1
|
+
import { r as AuthUser } from "../auth-CDeb2XAl.mjs";
|
|
2
|
+
import { t as StandardSchemaV1 } from "../standard-schema-Dnsh2vnl.mjs";
|
|
3
|
+
import { i as CloudEnv } from "../handler-xflsMwWM.mjs";
|
|
4
4
|
import { WebSocketRouteMap } from "void/routes";
|
|
5
5
|
|
|
6
6
|
//#region src/runtime/ws.d.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as cliTitle } from "./output-DeiS4oEX.mjs";
|
|
2
|
-
import { c as getToken, n as PlatformClient } from "./client-
|
|
2
|
+
import { c as getToken, n as PlatformClient } from "./client-DIfOFf1W.mjs";
|
|
3
3
|
import { _ as me, c as R, g as ge, n as Ce, u as Se, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
|
|
4
4
|
import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
|
|
5
|
-
import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-
|
|
5
|
+
import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
|
|
6
6
|
import { readFileSync } from "node:fs";
|
|
7
7
|
//#region src/cli/secret.ts
|
|
8
8
|
async function runSecretCommand(root, args) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
|
|
2
2
|
import { c as R } from "./dist-abzUneor.mjs";
|
|
3
|
-
import { r as getPackageDir } from "./agents-
|
|
3
|
+
import { r as getPackageDir } from "./agents-MhSzNMiC.mjs";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, symlinkSync } from "node:fs";
|
|
5
5
|
//#region src/cli/skills.ts
|
|
6
6
|
function parseSkills(skillsDir) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "void",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/voidzero-dev/void.git",
|
|
@@ -353,7 +353,7 @@
|
|
|
353
353
|
"valibot": ">=1.0.0-beta.7",
|
|
354
354
|
"vite": "^8.0.0",
|
|
355
355
|
"zod": "^3.25.0 || ^4.0.0",
|
|
356
|
-
"@void/md": "0.9.
|
|
356
|
+
"@void/md": "0.9.2"
|
|
357
357
|
},
|
|
358
358
|
"peerDependenciesMeta": {
|
|
359
359
|
"@void/md": {
|
|
@@ -4,7 +4,7 @@ outline: deep
|
|
|
4
4
|
|
|
5
5
|
# AI
|
|
6
6
|
|
|
7
|
-
Void provides a typed AI client powered by Cloudflare's [AI Gateway](https://developers.cloudflare.com/ai-gateway/).
|
|
7
|
+
Void provides a typed AI client powered by Cloudflare's [AI Gateway](https://developers.cloudflare.com/ai-gateway/). Import `ai` from `void/ai` and run inference directly from your route handlers. Usage is metered through Void.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { ai } from 'void/ai';
|
|
@@ -29,7 +29,7 @@ export const POST = defineHandler(async (c) => {
|
|
|
29
29
|
});
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
You can use any model available
|
|
32
|
+
You can use any model available through Cloudflare's AI binding, including Workers AI models such as `@cf/meta/llama-3.1-8b-instruct` and Cloudflare Gateway models such as `google/gemini-2.5-flash` or `openai/gpt-4.1-mini`. The input object must match the selected Cloudflare model's schema. Models that return binary data, such as generated images, are returned as a `Blob` from `ai.run()`.
|
|
33
33
|
|
|
34
34
|
## Streaming
|
|
35
35
|
|
|
@@ -87,11 +87,52 @@ Workers AI usage is metered in [**neurons**](https://developers.cloudflare.com/w
|
|
|
87
87
|
|
|
88
88
|
On the **free tier**, AI requests return a `429` error once the limit is reached. On **paid tiers**, usage beyond the included allowance is tracked as overage on your monthly bill.
|
|
89
89
|
|
|
90
|
-
##
|
|
90
|
+
## Cloudflare Gateway Models
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
`ai.run()` mirrors Cloudflare's `env.AI.run()` model naming and input schemas. Third-party models use Cloudflare model IDs and Cloudflare-managed credentials.
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
```ts
|
|
95
|
+
const result = await ai.run('google/gemini-2.5-flash', {
|
|
96
|
+
contents: [
|
|
97
|
+
{
|
|
98
|
+
role: 'user',
|
|
99
|
+
parts: [{ text: 'Explain Durable Objects in one paragraph.' }],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
OpenAI-compatible models use OpenAI-style `messages`:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const result = await ai.run('openai/gpt-4.1-mini', {
|
|
109
|
+
messages: [{ role: 'user', content: 'Summarize this deploy.' }],
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Pass Cloudflare AI Gateway options as the third argument:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const result = await ai.run(
|
|
117
|
+
'openai/gpt-4.1-mini',
|
|
118
|
+
{
|
|
119
|
+
messages: [{ role: 'user', content: 'Summarize this deploy.' }],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
gateway: {
|
|
123
|
+
skipCache: true,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Void always injects the `void` gateway ID and project metadata for metering.
|
|
130
|
+
|
|
131
|
+
## Provider-Native Requests
|
|
132
|
+
|
|
133
|
+
Use `ai.provider(provider).fetch(path, init)` when you want to call a provider-native API with your own provider key. The request still routes through Cloudflare AI Gateway and Void metering, but the request shape is the provider's native HTTP API.
|
|
134
|
+
|
|
135
|
+
### OpenAI
|
|
95
136
|
|
|
96
137
|
```ts
|
|
97
138
|
import { defineHandler } from 'void';
|
|
@@ -100,85 +141,99 @@ import { ai } from 'void/ai';
|
|
|
100
141
|
export const POST = defineHandler(async (c) => {
|
|
101
142
|
const { prompt } = await c.req.json();
|
|
102
143
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
144
|
+
const response = await ai.provider('openai').fetch('/chat/completions', {
|
|
145
|
+
body: {
|
|
146
|
+
model: 'gpt-4o',
|
|
147
|
+
messages: [{ role: 'user', content: prompt }],
|
|
148
|
+
max_tokens: 512,
|
|
149
|
+
},
|
|
106
150
|
});
|
|
107
151
|
|
|
152
|
+
const result = await response.json();
|
|
108
153
|
return c.json(result);
|
|
109
154
|
});
|
|
110
155
|
```
|
|
111
156
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
The options follow each provider's conventions. All third-party providers use the OpenAI-compatible chat completions format, including `messages`, `max_tokens`, and `temperature`. TypeScript narrows the input and return types based on the model string: Workers AI models get per-model typed inputs from `@cloudflare/workers-types`, while third-party models such as `"provider/model"` get `ChatCompletionInputs` and `ChatCompletionResponse`.
|
|
115
|
-
|
|
116
|
-
### Vision
|
|
117
|
-
|
|
118
|
-
Third-party chat models that accept image inputs can receive OpenAI-compatible multimodal message content:
|
|
157
|
+
### Google AI Studio
|
|
119
158
|
|
|
120
159
|
```ts
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{ type: 'text', text: 'What is in this image?' },
|
|
160
|
+
const response = await ai
|
|
161
|
+
.provider('google-ai-studio')
|
|
162
|
+
.fetch('/v1/models/gemini-2.5-flash:generateContent', {
|
|
163
|
+
body: {
|
|
164
|
+
contents: [
|
|
127
165
|
{
|
|
128
|
-
|
|
129
|
-
|
|
166
|
+
role: 'user',
|
|
167
|
+
parts: [{ text: 'What is Cloudflare?' }],
|
|
130
168
|
},
|
|
131
169
|
],
|
|
132
170
|
},
|
|
133
|
-
|
|
134
|
-
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const result = await response.json();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Custom Providers
|
|
177
|
+
|
|
178
|
+
For providers that are not in Void's default key map, pass the secret name and API-key header:
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
const response = await ai
|
|
182
|
+
.provider('custom-provider', {
|
|
183
|
+
apiKeyEnv: 'CUSTOM_PROVIDER_API_KEY',
|
|
184
|
+
apiKeyHeader: 'x-api-key',
|
|
185
|
+
apiKeyPrefix: '',
|
|
186
|
+
})
|
|
187
|
+
.fetch('/v1/respond', {
|
|
188
|
+
body: { prompt: 'Hello' },
|
|
189
|
+
});
|
|
135
190
|
```
|
|
136
191
|
|
|
137
192
|
### Image Generation
|
|
138
193
|
|
|
139
|
-
Use `ai.image()` for
|
|
194
|
+
Use `ai.run()` or `ai.image()` for Cloudflare-native image models:
|
|
140
195
|
|
|
141
196
|
```ts
|
|
142
197
|
export const POST = defineHandler(async (c) => {
|
|
143
198
|
const { prompt } = await c.req.json();
|
|
144
|
-
|
|
145
|
-
return ai.image('openai/gpt-image-1.5', {
|
|
146
|
-
prompt,
|
|
147
|
-
size: '1024x1024',
|
|
148
|
-
response_format: 'b64_json',
|
|
149
|
-
});
|
|
199
|
+
return ai.image('@cf/black-forest-labs/flux-1-schnell', { prompt });
|
|
150
200
|
});
|
|
151
201
|
```
|
|
152
202
|
|
|
153
|
-
|
|
203
|
+
Use `ai.provider().fetch()` for provider-native image APIs:
|
|
154
204
|
|
|
155
205
|
```ts
|
|
156
206
|
export const POST = defineHandler(async (c) => {
|
|
157
207
|
const { prompt } = await c.req.json();
|
|
158
|
-
|
|
208
|
+
|
|
209
|
+
return ai.provider('openai').fetch('/images/generations', {
|
|
210
|
+
body: {
|
|
211
|
+
model: 'gpt-image-1.5',
|
|
212
|
+
prompt,
|
|
213
|
+
size: '1024x1024',
|
|
214
|
+
response_format: 'b64_json',
|
|
215
|
+
},
|
|
216
|
+
});
|
|
159
217
|
});
|
|
160
218
|
```
|
|
161
219
|
|
|
162
|
-
For
|
|
220
|
+
For multipart provider APIs, pass a `FormData` body. Void serializes the body through the proxy and reconstructs it before forwarding to AI Gateway:
|
|
163
221
|
|
|
164
222
|
```ts
|
|
165
223
|
export const POST = defineHandler(async (c) => {
|
|
166
224
|
const body = await c.req.parseBody();
|
|
225
|
+
const form = new FormData();
|
|
226
|
+
form.set('model', 'gpt-image-1.5');
|
|
227
|
+
form.set('prompt', String(body.prompt));
|
|
228
|
+
form.set('image', body.image as Blob, 'source.png');
|
|
167
229
|
|
|
168
|
-
return ai.
|
|
169
|
-
'openai/gpt-image-1.5',
|
|
170
|
-
{
|
|
171
|
-
prompt: String(body.prompt),
|
|
172
|
-
image: body.image as Blob,
|
|
173
|
-
},
|
|
174
|
-
{ endpoint: 'images/edits' },
|
|
175
|
-
);
|
|
230
|
+
return ai.provider('openai').fetch('/images/edits', { body: form });
|
|
176
231
|
});
|
|
177
232
|
```
|
|
178
233
|
|
|
179
234
|
### Provider Key Convention
|
|
180
235
|
|
|
181
|
-
|
|
236
|
+
Provider-native requests require an API key set as a project secret. The env var name is automatically derived from the provider name:
|
|
182
237
|
|
|
183
238
|
| Provider prefix | Env var |
|
|
184
239
|
| ------------------ | --------------------- |
|
|
@@ -203,7 +258,7 @@ Each provider requires an API key set as a project secret. The env var name is a
|
|
|
203
258
|
| `ideogram` | `IDEOGRAM_API_KEY` |
|
|
204
259
|
| `parallel` | `PARALLEL_API_KEY` |
|
|
205
260
|
|
|
206
|
-
|
|
261
|
+
OpenAI-style providers use `Authorization: Bearer <key>`. Google AI Studio uses `x-goog-api-key`. Use `apiKeyHeader` and `apiKeyPrefix` for custom providers.
|
|
207
262
|
|
|
208
263
|
For production, add your API key as a project secret:
|
|
209
264
|
|
|
@@ -217,19 +272,22 @@ For local development, add it to `.env.local` in your project root:
|
|
|
217
272
|
OPENAI_API_KEY=sk-...
|
|
218
273
|
```
|
|
219
274
|
|
|
220
|
-
If the key is missing at runtime, `ai.
|
|
275
|
+
If the key is missing at runtime, `ai.provider().fetch()` throws a descriptive error telling you which env var to set.
|
|
221
276
|
|
|
222
|
-
### Streaming with
|
|
277
|
+
### Streaming with Provider-Native APIs
|
|
223
278
|
|
|
224
|
-
|
|
279
|
+
Provider-native streaming APIs return the provider response directly:
|
|
225
280
|
|
|
226
281
|
```ts
|
|
227
282
|
export const POST = defineHandler(async (c) => {
|
|
228
283
|
const { prompt } = await c.req.json();
|
|
229
284
|
|
|
230
|
-
return ai.
|
|
231
|
-
|
|
232
|
-
|
|
285
|
+
return ai.provider('openai').fetch('/chat/completions', {
|
|
286
|
+
body: {
|
|
287
|
+
model: 'gpt-4o',
|
|
288
|
+
messages: [{ role: 'user', content: prompt }],
|
|
289
|
+
stream: true,
|
|
290
|
+
},
|
|
233
291
|
});
|
|
234
292
|
});
|
|
235
293
|
```
|
|
@@ -229,12 +229,12 @@ Localhost dev uses a built-in fallback secret automatically. Outside the managed
|
|
|
229
229
|
For advanced configuration, create `auth.ts` at the project root and export `defineAuth(...)`:
|
|
230
230
|
|
|
231
231
|
```ts
|
|
232
|
-
import { defineAuth } from
|
|
232
|
+
import { defineAuth } from 'void/auth';
|
|
233
233
|
|
|
234
234
|
export default defineAuth(({ defaults }) => ({
|
|
235
235
|
...defaults,
|
|
236
|
-
trustedOrigins: [
|
|
237
|
-
});
|
|
236
|
+
trustedOrigins: ['https://example.com'],
|
|
237
|
+
}));
|
|
238
238
|
```
|
|
239
239
|
|
|
240
240
|
`defaults` already includes Void's conventions. Extend it explicitly instead of expecting a deep merge.
|
|
@@ -101,7 +101,7 @@ src/
|
|
|
101
101
|
| `void/ws` | `defineRoom()`, `defineWebSocket()`, typed `connect()`, and WebSocket context types |
|
|
102
102
|
| `void/db` | `db` Drizzle D1 instance (auto-wired with user schema) + `createDb()` for custom D1 bindings |
|
|
103
103
|
| `void/queues` | `queues` typed proxy + `QueueMap` stub interface (augmented by generated `queues.d.ts`) |
|
|
104
|
-
| `void/ai` | `ai` proxy — `ai.run()`, `ai.
|
|
104
|
+
| `void/ai` | `ai` proxy — Cloudflare-native `ai.run()`/`ai.stream()`, provider-native `ai.provider().fetch()`, `ai.models()` |
|
|
105
105
|
| `void/log` | `logger.error/warn/info(msg, fields?)` — emits stringified JSON to `console.*` so Cloudflare Tail captures level + msg |
|
|
106
106
|
| `void/env` | `defineEnv()`, typed `env` proxy, built-in schema helpers (`string`, `number`, `oneOf`, …) + global Cloudflare types |
|
|
107
107
|
|
|
@@ -675,7 +675,7 @@ Imported from `"void/ai"`.
|
|
|
675
675
|
|
|
676
676
|
### `ai`
|
|
677
677
|
|
|
678
|
-
Typed AI client for
|
|
678
|
+
Typed AI client for Cloudflare AI models and provider-native AI Gateway requests.
|
|
679
679
|
|
|
680
680
|
```ts
|
|
681
681
|
import { ai } from 'void/ai';
|
|
@@ -683,9 +683,16 @@ import { ai } from 'void/ai';
|
|
|
683
683
|
const result = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
|
|
684
684
|
messages: [{ role: 'user', content: 'Summarize this release note.' }],
|
|
685
685
|
});
|
|
686
|
+
|
|
687
|
+
const response = await ai.provider('openai').fetch('/chat/completions', {
|
|
688
|
+
body: {
|
|
689
|
+
model: 'gpt-4o',
|
|
690
|
+
messages: [{ role: 'user', content: 'Summarize this release note.' }],
|
|
691
|
+
},
|
|
692
|
+
});
|
|
686
693
|
```
|
|
687
694
|
|
|
688
|
-
**Key exports:** `ai`, `VoidAi`,
|
|
695
|
+
**Key exports:** `ai`, `VoidAi`, provider request types. See [AI](../guide/ai.md) for provider setup and streaming examples.
|
|
689
696
|
|
|
690
697
|
## ISR
|
|
691
698
|
|
|
@@ -10,32 +10,33 @@ Use this page as a command reference. If you are setting up a project for the fi
|
|
|
10
10
|
|
|
11
11
|
## Cheat Sheet
|
|
12
12
|
|
|
13
|
-
| Command | Purpose
|
|
14
|
-
| --------------------------------- |
|
|
15
|
-
| `void deploy` | Build and deploy to Void
|
|
16
|
-
| `void prepare` | Generate `.void` artifacts without starting Vite
|
|
17
|
-
| `void gen model <name> [cols...]` | Scaffold migration + CRUD routes
|
|
18
|
-
| `void gen route <path>` | Create an API route
|
|
19
|
-
| `void db push` | Apply schema directly without migration files
|
|
20
|
-
| `void db generate` | Generate SQL migrations from schema changes
|
|
21
|
-
| `void db status` | Show local/remote migration status
|
|
22
|
-
| `void db reset` | Drop and re-apply all migrations
|
|
23
|
-
| `void db seed` | Reset + seed local database
|
|
24
|
-
| `void db
|
|
25
|
-
| `void
|
|
26
|
-
| `void secret
|
|
27
|
-
| `void secret
|
|
28
|
-
| `void
|
|
29
|
-
| `void env
|
|
30
|
-
| `void env
|
|
31
|
-
| `void
|
|
32
|
-
| `void
|
|
33
|
-
| `void project
|
|
34
|
-
| `void project
|
|
35
|
-
| `void project
|
|
36
|
-
| `void project
|
|
37
|
-
| `void
|
|
38
|
-
| `void
|
|
13
|
+
| Command | Purpose |
|
|
14
|
+
| --------------------------------- | ------------------------------------------------------------------- |
|
|
15
|
+
| `void deploy` | Build and deploy to Void |
|
|
16
|
+
| `void prepare` | Generate `.void` artifacts without starting Vite |
|
|
17
|
+
| `void gen model <name> [cols...]` | Scaffold migration + CRUD routes |
|
|
18
|
+
| `void gen route <path>` | Create an API route |
|
|
19
|
+
| `void db push` | Apply schema directly without migration files |
|
|
20
|
+
| `void db generate` | Generate SQL migrations from schema changes |
|
|
21
|
+
| `void db status` | Show local/remote migration status |
|
|
22
|
+
| `void db reset` | Drop and re-apply all migrations |
|
|
23
|
+
| `void db seed` | Reset + seed local database |
|
|
24
|
+
| `void db execute <sql>` | Run SQL against the database (--remote for deployed) |
|
|
25
|
+
| `void db studio` | Open Drizzle Studio (--remote for the deployed PostgreSQL database) |
|
|
26
|
+
| `void secret put <name=value>` | Set a production secret |
|
|
27
|
+
| `void secret list` | List production secrets |
|
|
28
|
+
| `void secret sync .env.local` | Bulk upload secrets from dotenv file |
|
|
29
|
+
| `void env check [--remote]` | Validate env.ts schema |
|
|
30
|
+
| `void env types` | Regenerate .void/env.d.ts from env.ts |
|
|
31
|
+
| `void env example` | Refresh the void-managed block in .env.example |
|
|
32
|
+
| `void auth login` | Authenticate with Void |
|
|
33
|
+
| `void project link` | Link directory to a project |
|
|
34
|
+
| `void project logs` | Show runtime logs from deployed project |
|
|
35
|
+
| `void project rollback` | Roll back to a previous deployment |
|
|
36
|
+
| `void project cancel` | Cancel an active deployment |
|
|
37
|
+
| `void project purge-cache` | Purge all cached pages |
|
|
38
|
+
| `void mcp` | Start the Void MCP server |
|
|
39
|
+
| `void init` | Setup wizard for new or existing projects |
|
|
39
40
|
|
|
40
41
|
## Binary Invocation
|
|
41
42
|
|
|
@@ -289,9 +290,17 @@ Programmatic seed modules must export either a default function or a named `seed
|
|
|
289
290
|
```
|
|
290
291
|
void db execute <sql>
|
|
291
292
|
void db execute --file <path>
|
|
293
|
+
void db execute --remote <sql>
|
|
292
294
|
```
|
|
293
295
|
|
|
294
|
-
Run ad-hoc SQL against the
|
|
296
|
+
Run ad-hoc SQL against the database. Provide SQL inline or from a file. SELECT queries display results as a formatted table; other statements execute silently.
|
|
297
|
+
|
|
298
|
+
By default, targets the local database. Pass `--remote` to run against the deployed database:
|
|
299
|
+
|
|
300
|
+
- **D1 projects**: routes the query through the Void proxy (`proxy.void.cloud/d1/query`) using your auth token. No Cloudflare credentials needed.
|
|
301
|
+
- **PostgreSQL projects**: fetches the stored connection string from the platform and connects directly. Requires that `void db set-url` has been run at least once (the platform stores the URL encrypted). If the URL isn't stored yet, you will see: _"Run `void db set-url` once to populate it, then retry."_
|
|
302
|
+
|
|
303
|
+
For destructive statements (`DELETE`, `UPDATE`, `DROP`, etc.) when running in a TTY, you will be prompted to confirm before the query is sent to the deployed database. Non-TTY environments (CI) skip the prompt.
|
|
295
304
|
|
|
296
305
|
### `void db migrate`
|
|
297
306
|
|
|
@@ -305,7 +314,16 @@ Pass `--remote` to apply pending migrations to the remote database instead. Requ
|
|
|
305
314
|
|
|
306
315
|
### `void db studio`
|
|
307
316
|
|
|
308
|
-
|
|
317
|
+
```
|
|
318
|
+
void db studio [--remote]
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Open [Drizzle Studio](https://orm.drizzle.team/docs/drizzle-kit-studio) for the database. Launches a web-based GUI for browsing and editing your data.
|
|
322
|
+
|
|
323
|
+
By default, targets the local database. Pass `--remote` to open Studio against the deployed database:
|
|
324
|
+
|
|
325
|
+
- **PostgreSQL projects**: fetches the stored connection string from the platform and opens Studio against it. Requires being logged in (`void auth login`) with a linked project. If the URL isn't stored yet, run `void db set-url` first.
|
|
326
|
+
- **D1 projects**: remote Studio is not yet supported. Use `void db execute --remote` for ad-hoc queries against your deployed D1 database.
|
|
309
327
|
|
|
310
328
|
### `void db rename-migrations`
|
|
311
329
|
|
|
@@ -554,7 +572,9 @@ See [Environment Variables](../guide/env-vars.md) for the full guide.
|
|
|
554
572
|
void domain add <hostname> [--project <name>]
|
|
555
573
|
```
|
|
556
574
|
|
|
557
|
-
Add a custom domain to a project. Prints the
|
|
575
|
+
Add a custom domain to a project. Prints the two DNS records to add at your DNS provider: a traffic **CNAME** pointing `<hostname>` at the CNAME target shown in the command output, and a non-rotating `_cf-custom-hostname` ownership **TXT**. Certificates are validated over HTTP at Cloudflare's edge and renew automatically — there are no `_acme-challenge` records to publish, at first issuance or ever. After adding the records the domain activates automatically (no polling required); run `void domain status <hostname>` to check progress.
|
|
576
|
+
|
|
577
|
+
> Wildcard custom hostnames (`*.example.com`) are not supported — register each subdomain individually.
|
|
558
578
|
|
|
559
579
|
### `void domain delete`
|
|
560
580
|
|
|
@@ -578,7 +598,7 @@ List all custom domains and their status (active/pending).
|
|
|
578
598
|
void domain status <hostname> [--project <name>] [--verbose]
|
|
579
599
|
```
|
|
580
600
|
|
|
581
|
-
Check verification and SSL status for a specific domain. Prints a rolled-up state (`awaiting_dns`, `verifying_dns`, `issuing_cert`, `deploying_cert`, `awaiting_deployment`, `active`, `error`, or `pending`) with a one-line diagnostic explaining what Cloudflare is doing and any user action required.
|
|
601
|
+
Check verification and SSL status for a specific domain. Prints a rolled-up state (`awaiting_dns`, `verifying_dns`, `issuing_cert`, `deploying_cert`, `awaiting_deployment`, `active`, `error`, or `pending`) with a one-line diagnostic explaining what Cloudflare is doing and any user action required. While the certificate is not yet active, the command also surfaces the records to configure — the traffic **CNAME** and the `_cf-custom-hostname` ownership **TXT** — so you can verify them. Activation is automatic: a background job reconciles pending domains (about every 2 minutes for the first 30 minutes after adding, then hourly), so this command is for instant feedback rather than required polling.
|
|
582
602
|
|
|
583
603
|
Pass `--verbose` to additionally print the raw multi-line status breakdown (DB status, SSL status, ownership state, verification errors) underneath the rollup.
|
|
584
604
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|