@nyte-ai/host 0.0.23 → 0.0.25-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/THIRD-PARTY-NOTICES.md +2 -38
- package/dist/chunks/{canvas-preview-d97wvref.js → canvas-preview-1r9sgbj3.js} +1 -1
- package/dist/chunks/{canvas-preview-gm0frf4b.js → canvas-preview-2yzyt077.js} +14 -0
- package/dist/chunks/{canvas-preview-whfdhma6.js → canvas-preview-8sv3j0vt.js} +1 -1
- package/dist/chunks/{canvas-preview-e3vnkkc5.js → canvas-preview-9bxhwjrh.js} +2 -1
- package/dist/chunks/{canvas-preview-2jwbe14k.js → canvas-preview-bg63k8n7.js} +113 -21
- package/dist/chunks/{canvas-preview-9e15hp6q.js → canvas-preview-da6dwy05.js} +4 -3
- package/dist/chunks/{canvas-preview-ayayyd43.js → canvas-preview-dt89p9pm.js} +148 -6
- package/dist/src/durable-object.d.ts +1 -1
- package/dist/src/index.js +7 -7
- package/dist/src/listen-fetch.d.ts +1 -1
- package/dist/src/listen-fetch.js +3 -3
- package/dist/src/listen.js +4 -4
- package/dist/src/local/provider.d.ts +1 -1
- package/dist/src/local/provider.js +2 -2
- package/dist/src/local/worktrees.d.ts +7 -3
- package/dist/src/local/worktrees.js +1 -2
- package/dist/src/open.js +7 -7
- package/dist/src/serve/binding.d.ts +0 -1
- package/dist/src/serve/binding.js +1 -1
- package/dist/src/serve/handler.js +2 -2
- package/package.json +8 -31
- package/src/durable-object.ts +1 -1
- package/src/listen-fetch.ts +6 -3
- package/src/local/provider.ts +3 -1
- package/src/local/worktrees.ts +165 -30
- package/src/open.ts +7 -1
- package/src/serve/binding.ts +18 -1
- package/src/usage-history.ts +0 -1
- package/dist/chunks/canvas-preview-1f8h0he1.js +0 -81
- package/dist/chunks/canvas-preview-2zdyh9ny.js +0 -26
- package/dist/chunks/canvas-preview-65xqjw7f.js +0 -20
- package/dist/chunks/canvas-preview-dsb5829c.js +0 -166
- package/dist/chunks/canvas-preview-kzmp015w.js +0 -36
- package/dist/src/deploy/cloudflare/worker.d.ts +0 -50
- package/dist/src/deploy/cloudflare/worker.js +0 -196
- package/dist/src/deploy/vercel/nitro.config.d.ts +0 -2
- package/dist/src/deploy/vercel/nitro.config.js +0 -30
- package/dist/src/deploy/vercel/server/routes/[...].d.ts +0 -2
- package/dist/src/deploy/vercel/server/routes/[...].js +0 -18
- package/dist/src/deploy/vercel/server/utils/host.d.ts +0 -13
- package/dist/src/deploy/vercel/server/utils/host.js +0 -7
- package/dist/src/deploy/vercel/server/utils/repair.d.ts +0 -1
- package/dist/src/deploy/vercel/server/utils/repair.js +0 -6
- package/dist/src/deploy/vercel/server/utils/step.d.ts +0 -10
- package/dist/src/deploy/vercel/server/utils/step.js +0 -6
- package/dist/src/deploy/vercel/server/workflows/drive.d.ts +0 -14
- package/dist/src/deploy/vercel/server/workflows/drive.js +0 -13
- package/src/deploy/cloudflare/README.md +0 -3
- package/src/deploy/cloudflare/worker.ts +0 -306
- package/src/deploy/cloudflare/wrangler.jsonc +0 -12
- package/src/deploy/vercel/README.md +0 -3
- package/src/deploy/vercel/nitro.config.ts +0 -29
- package/src/deploy/vercel/server/routes/[...].ts +0 -10
- package/src/deploy/vercel/server/utils/host.ts +0 -104
- package/src/deploy/vercel/server/utils/repair.ts +0 -35
- package/src/deploy/vercel/server/utils/step.ts +0 -25
- package/src/deploy/vercel/server/workflows/drive.ts +0 -46
- package/src/deploy/vercel/tsconfig.json +0 -9
- package/src/deploy/vercel/types/bun.d.ts +0 -2
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
answerRepair2
|
|
3
|
-
} from "./canvas-preview-2zdyh9ny.js";
|
|
4
|
-
import {
|
|
5
|
-
package_default
|
|
6
|
-
} from "./canvas-preview-dsb5829c.js";
|
|
7
|
-
|
|
8
|
-
// src/deploy/vercel/server/utils/host.ts
|
|
9
|
-
import process from "node:process";
|
|
10
|
-
import { createModels } from "@nyte-ai/ai/models";
|
|
11
|
-
import { SdkError } from "@nyte-ai/schema";
|
|
12
|
-
import { composeHost } from "@nyte-ai/core/server";
|
|
13
|
-
import { postgresStore } from "@nyte-ai/host";
|
|
14
|
-
import { credentialStore } from "@nyte-ai/host/credentials";
|
|
15
|
-
import { seedSigner } from "@nyte-ai/host/identity";
|
|
16
|
-
import { listenFetch } from "@nyte-ai/host/listen-fetch";
|
|
17
|
-
import { sandboxProvider } from "@nyte-ai/host/providers";
|
|
18
|
-
var PAGE = 100;
|
|
19
|
-
var boot = async () => {
|
|
20
|
-
throw new SdkError("unavailable", "Supply a boot over your sandbox SDK in server/utils/host.ts.");
|
|
21
|
-
};
|
|
22
|
-
var building = null;
|
|
23
|
-
function vercelHost2(dispatch) {
|
|
24
|
-
const built = building ??= build(dispatch);
|
|
25
|
-
built.catch(() => {
|
|
26
|
-
if (building === built)
|
|
27
|
-
building = null;
|
|
28
|
-
});
|
|
29
|
-
return built;
|
|
30
|
-
}
|
|
31
|
-
async function build(dispatch) {
|
|
32
|
-
const connectionString = process.env.DATABASE_URL;
|
|
33
|
-
if (connectionString === undefined || connectionString === "")
|
|
34
|
-
throw new SdkError("unavailable", "Set DATABASE_URL to the Postgres database the host keeps.");
|
|
35
|
-
const identityKey = process.env.NYTE_IDENTITY_KEY;
|
|
36
|
-
const store = postgresStore({ connectionString });
|
|
37
|
-
const secrets = secretsFrom(process.env.NYTE_SECRET_KEY);
|
|
38
|
-
const description = { name: "nyte-host", platform: "vercel", version: package_default.version };
|
|
39
|
-
const host = await composeHost({
|
|
40
|
-
store,
|
|
41
|
-
models: createModels({ credentials: credentialStore(store, secrets) }),
|
|
42
|
-
plugins: [{ id: "sandbox", environment: sandboxProvider({ boot }) }],
|
|
43
|
-
workspace: { kind: "sandbox", locator: { name: process.env.NYTE_SANDBOX ?? "nyte" } },
|
|
44
|
-
execution: { kind: "dispatch", dispatch },
|
|
45
|
-
poll: 1000,
|
|
46
|
-
secrets,
|
|
47
|
-
home: null,
|
|
48
|
-
description
|
|
49
|
-
});
|
|
50
|
-
const repair = async () => {
|
|
51
|
-
let cursor;
|
|
52
|
-
do {
|
|
53
|
-
const page = await host.execution.repair({ cursor, limit: PAGE });
|
|
54
|
-
cursor = page.next ?? undefined;
|
|
55
|
-
} while (cursor !== undefined);
|
|
56
|
-
};
|
|
57
|
-
const listener = await listenFetch(host, {
|
|
58
|
-
transport: { kind: "fetch" },
|
|
59
|
-
auth: { kind: "token", token: process.env.NYTE_TOKEN ?? "" },
|
|
60
|
-
execution: { kind: "admit-only" },
|
|
61
|
-
describe: () => description,
|
|
62
|
-
...identityKey === undefined || identityKey === "" ? {} : { identity: await seedSigner(host.hostId, Uint8Array.fromBase64(identityKey)) },
|
|
63
|
-
before: (request) => answerRepair2(request, process.env.CRON_SECRET, repair)
|
|
64
|
-
}).catch(async (error) => {
|
|
65
|
-
await host.close();
|
|
66
|
-
throw error;
|
|
67
|
-
});
|
|
68
|
-
return { host, listener };
|
|
69
|
-
}
|
|
70
|
-
function secretsFrom(key) {
|
|
71
|
-
if (key === undefined || key === "")
|
|
72
|
-
return {
|
|
73
|
-
key: async () => {
|
|
74
|
-
throw new SdkError("unavailable", "Set NYTE_SECRET_KEY to a base64 32-byte key.");
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
const bytes = new Uint8Array(Buffer.from(key, "base64"));
|
|
78
|
-
return { key: async () => bytes };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export { vercelHost2 };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// src/deploy/vercel/server/utils/repair.ts
|
|
2
|
-
import { createHash, timingSafeEqual } from "node:crypto";
|
|
3
|
-
import { SdkError } from "@nyte-ai/schema";
|
|
4
|
-
import { encodeError, errorStatus } from "@nyte-ai/protocol";
|
|
5
|
-
async function answerRepair2(request, secret, repair) {
|
|
6
|
-
if (request.method !== "GET" || new URL(request.url).pathname !== "/.nyte/repair")
|
|
7
|
-
return;
|
|
8
|
-
if (secret === undefined || secret === "")
|
|
9
|
-
return failure(new SdkError("unknown", "This deployment sets no CRON_SECRET."));
|
|
10
|
-
const given = /^Bearer\s+(\S+)\s*$/i.exec(request.headers.get("Authorization") ?? "")?.[1] ?? "";
|
|
11
|
-
if (!timingSafeEqual(digest(given), digest(secret)))
|
|
12
|
-
return failure(new SdkError("unauthenticated", "Send Authorization: Bearer <CRON_SECRET>."));
|
|
13
|
-
await repair();
|
|
14
|
-
return new Response(null, { status: 204 });
|
|
15
|
-
}
|
|
16
|
-
function digest(text) {
|
|
17
|
-
return createHash("sha256").update(text).digest();
|
|
18
|
-
}
|
|
19
|
-
function failure(error) {
|
|
20
|
-
return new Response(JSON.stringify(encodeError(error)), {
|
|
21
|
-
status: errorStatus[error.code],
|
|
22
|
-
headers: { "Content-Type": "application/json" }
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export { answerRepair2 };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// src/deploy/vercel/server/utils/step.ts
|
|
2
|
-
function stepFrom2(report, now) {
|
|
3
|
-
switch (report.kind) {
|
|
4
|
-
case "continue":
|
|
5
|
-
return { kind: "advance" };
|
|
6
|
-
case "waiting":
|
|
7
|
-
return report.until === null ? { kind: "stop" } : untilStep(report.until, now);
|
|
8
|
-
case "retry":
|
|
9
|
-
return untilStep(report.until, now);
|
|
10
|
-
case "busy":
|
|
11
|
-
case "idle":
|
|
12
|
-
case "fenced":
|
|
13
|
-
return { kind: "stop" };
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function untilStep(until, now) {
|
|
17
|
-
return until > now ? { kind: "sleep", ms: until - now } : { kind: "advance" };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export { stepFrom2 };
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
// package.json
|
|
2
|
-
var package_default = {
|
|
3
|
-
name: "@nyte-ai/host",
|
|
4
|
-
version: "0.0.23",
|
|
5
|
-
private: false,
|
|
6
|
-
license: "MIT",
|
|
7
|
-
repository: {
|
|
8
|
-
type: "git",
|
|
9
|
-
url: "git+https://github.com/interfaces-lab/nyte.git",
|
|
10
|
-
directory: "packages/host"
|
|
11
|
-
},
|
|
12
|
-
files: [
|
|
13
|
-
"dist",
|
|
14
|
-
"src",
|
|
15
|
-
"LICENSE",
|
|
16
|
-
"THIRD-PARTY-NOTICES.md"
|
|
17
|
-
],
|
|
18
|
-
type: "module",
|
|
19
|
-
exports: {
|
|
20
|
-
".": "./src/index.ts",
|
|
21
|
-
"./canvas-preview": "./src/canvas-preview.ts",
|
|
22
|
-
"./credentials": "./src/credentials.ts",
|
|
23
|
-
"./durable-object": "./src/durable-object.ts",
|
|
24
|
-
"./identity": "./src/identity.ts",
|
|
25
|
-
"./images": "./src/images/node.ts",
|
|
26
|
-
"./image-worker": "./src/images/worker.ts",
|
|
27
|
-
"./listen-fetch": "./src/listen-fetch.ts",
|
|
28
|
-
"./providers": "./src/providers.ts",
|
|
29
|
-
"./secrets": "./src/secrets.ts",
|
|
30
|
-
"./shell-env": "./src/shell-env.ts",
|
|
31
|
-
"./usage": "./src/usage.ts",
|
|
32
|
-
"./store-usage": "./src/store-usage.ts",
|
|
33
|
-
"./usage-service": "./src/usage-service.ts",
|
|
34
|
-
"./usage-scan": "./src/usage-scan.ts",
|
|
35
|
-
"./usage-worker": "./src/usage-worker.ts",
|
|
36
|
-
"./deploy/cloudflare": "./src/deploy/cloudflare/worker.ts",
|
|
37
|
-
"./deploy/vercel": "./src/deploy/vercel/nitro.config.ts"
|
|
38
|
-
},
|
|
39
|
-
publishConfig: {
|
|
40
|
-
exports: {
|
|
41
|
-
".": {
|
|
42
|
-
types: "./dist/src/index.d.ts",
|
|
43
|
-
import: "./dist/src/index.js"
|
|
44
|
-
},
|
|
45
|
-
"./canvas-preview": {
|
|
46
|
-
types: "./dist/src/canvas-preview.d.ts",
|
|
47
|
-
import: "./dist/src/canvas-preview.js"
|
|
48
|
-
},
|
|
49
|
-
"./credentials": {
|
|
50
|
-
types: "./dist/src/credentials.d.ts",
|
|
51
|
-
import: "./dist/src/credentials.js"
|
|
52
|
-
},
|
|
53
|
-
"./durable-object": {
|
|
54
|
-
types: "./dist/src/durable-object.d.ts",
|
|
55
|
-
import: "./dist/src/durable-object.js"
|
|
56
|
-
},
|
|
57
|
-
"./identity": {
|
|
58
|
-
types: "./dist/src/identity.d.ts",
|
|
59
|
-
import: "./dist/src/identity.js"
|
|
60
|
-
},
|
|
61
|
-
"./images": {
|
|
62
|
-
types: "./dist/src/images/node.d.ts",
|
|
63
|
-
import: "./dist/src/images/node.js"
|
|
64
|
-
},
|
|
65
|
-
"./image-worker": {
|
|
66
|
-
types: "./dist/src/images/worker.d.ts",
|
|
67
|
-
import: "./dist/src/images/worker.js"
|
|
68
|
-
},
|
|
69
|
-
"./listen-fetch": {
|
|
70
|
-
types: "./dist/src/listen-fetch.d.ts",
|
|
71
|
-
import: "./dist/src/listen-fetch.js"
|
|
72
|
-
},
|
|
73
|
-
"./providers": {
|
|
74
|
-
types: "./dist/src/providers.d.ts",
|
|
75
|
-
import: "./dist/src/providers.js"
|
|
76
|
-
},
|
|
77
|
-
"./secrets": {
|
|
78
|
-
types: "./dist/src/secrets.d.ts",
|
|
79
|
-
import: "./dist/src/secrets.js"
|
|
80
|
-
},
|
|
81
|
-
"./shell-env": {
|
|
82
|
-
types: "./dist/src/shell-env.d.ts",
|
|
83
|
-
import: "./dist/src/shell-env.js"
|
|
84
|
-
},
|
|
85
|
-
"./usage": {
|
|
86
|
-
types: "./dist/src/usage.d.ts",
|
|
87
|
-
import: "./dist/src/usage.js"
|
|
88
|
-
},
|
|
89
|
-
"./store-usage": {
|
|
90
|
-
types: "./dist/src/store-usage.d.ts",
|
|
91
|
-
import: "./dist/src/store-usage.js"
|
|
92
|
-
},
|
|
93
|
-
"./usage-service": {
|
|
94
|
-
types: "./dist/src/usage-service.d.ts",
|
|
95
|
-
import: "./dist/src/usage-service.js"
|
|
96
|
-
},
|
|
97
|
-
"./usage-scan": {
|
|
98
|
-
types: "./dist/src/usage-scan.d.ts",
|
|
99
|
-
import: "./dist/src/usage-scan.js"
|
|
100
|
-
},
|
|
101
|
-
"./usage-worker": {
|
|
102
|
-
types: "./dist/src/usage-worker.d.ts",
|
|
103
|
-
import: "./dist/src/usage-worker.js"
|
|
104
|
-
},
|
|
105
|
-
"./deploy/cloudflare": {
|
|
106
|
-
types: "./dist/src/deploy/cloudflare/worker.d.ts",
|
|
107
|
-
import: "./dist/src/deploy/cloudflare/worker.js"
|
|
108
|
-
},
|
|
109
|
-
"./deploy/vercel": {
|
|
110
|
-
types: "./dist/src/deploy/vercel/nitro.config.d.ts",
|
|
111
|
-
import: "./dist/src/deploy/vercel/nitro.config.js"
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
access: "public",
|
|
115
|
-
provenance: true
|
|
116
|
-
},
|
|
117
|
-
scripts: {
|
|
118
|
-
clean: "rm -rf node_modules .turbo",
|
|
119
|
-
typecheck: "tsrs --noEmit && tsrs --noEmit -p src/deploy/vercel",
|
|
120
|
-
test: "vitest --run",
|
|
121
|
-
"check:store": "node scripts/check-store.ts",
|
|
122
|
-
"build:package": "bun ../../scripts/sdk-packages.mjs build host"
|
|
123
|
-
},
|
|
124
|
-
dependencies: {
|
|
125
|
-
"@earendil-works/pi-mcp": "^1.3.0",
|
|
126
|
-
"@lydell/node-pty": "^1.2.0-beta.15",
|
|
127
|
-
"@nyte-ai/ai": "workspace:*",
|
|
128
|
-
"@nyte-ai/core": "workspace:*",
|
|
129
|
-
"@nyte-ai/plugin": "workspace:*",
|
|
130
|
-
"@nyte-ai/protocol": "workspace:*",
|
|
131
|
-
"@nyte-ai/schema": "workspace:*",
|
|
132
|
-
"@silvia-odwyer/photon": "^0.3.3",
|
|
133
|
-
fflate: "^0.8.3",
|
|
134
|
-
ignore: "^7.0.13",
|
|
135
|
-
pg: "^8.23.1",
|
|
136
|
-
typebox: "^1.4.2"
|
|
137
|
-
},
|
|
138
|
-
devDependencies: {
|
|
139
|
-
"@electric-sql/pglite": "^0.5.11",
|
|
140
|
-
"@nyte-ai/canvas": "workspace:*",
|
|
141
|
-
"@types/node": "^26.6.5",
|
|
142
|
-
"@types/pg": "^8.23.1",
|
|
143
|
-
"fast-check": "^4.10.2",
|
|
144
|
-
nitro: "^3.0.260903-beta",
|
|
145
|
-
typescript: "6.0.3",
|
|
146
|
-
vitest: "^5.0.5",
|
|
147
|
-
workflow: "^5.2.3"
|
|
148
|
-
},
|
|
149
|
-
peerDependencies: {
|
|
150
|
-
nitro: "^3.0.260903-beta",
|
|
151
|
-
workflow: "^5.2.3"
|
|
152
|
-
},
|
|
153
|
-
peerDependenciesMeta: {
|
|
154
|
-
nitro: {
|
|
155
|
-
optional: true
|
|
156
|
-
},
|
|
157
|
-
workflow: {
|
|
158
|
-
optional: true
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
engines: {
|
|
162
|
-
node: ">=26.4.0"
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export { package_default };
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
vercelHost2
|
|
3
|
-
} from "./canvas-preview-1f8h0he1.js";
|
|
4
|
-
import {
|
|
5
|
-
stepFrom2
|
|
6
|
-
} from "./canvas-preview-65xqjw7f.js";
|
|
7
|
-
|
|
8
|
-
// src/deploy/vercel/server/workflows/drive.ts
|
|
9
|
-
import { sleep } from "workflow";
|
|
10
|
-
import { start } from "workflow/api";
|
|
11
|
-
async function dispatchHead2(target) {
|
|
12
|
-
await start(driveHead2, [target]);
|
|
13
|
-
}
|
|
14
|
-
async function driveHead2(input) {
|
|
15
|
-
"use workflow";
|
|
16
|
-
for (;; ) {
|
|
17
|
-
const next = stepFrom2(await advanceHead2(input), Date.now());
|
|
18
|
-
if (next.kind === "stop")
|
|
19
|
-
return;
|
|
20
|
-
if (next.kind === "sleep")
|
|
21
|
-
await sleep(next.ms);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
async function advanceHead2(input) {
|
|
25
|
-
"use step";
|
|
26
|
-
const { host } = await vercelHost2(dispatchHead2);
|
|
27
|
-
const coverage = await host.execution.cover({ kind: "sessions", sessions: [input.session] });
|
|
28
|
-
try {
|
|
29
|
-
await host.server.tick(Date.now());
|
|
30
|
-
return await host.execution.advance(input);
|
|
31
|
-
} finally {
|
|
32
|
-
await coverage.close();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export { dispatchHead2, driveHead2, advanceHead2 };
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { AdvanceReport } from "@nyte-ai/schema";
|
|
2
|
-
import type { Models } from "@nyte-ai/ai";
|
|
3
|
-
import type { Host } from "@nyte-ai/core";
|
|
4
|
-
import type { ServerHost } from "@nyte-ai/core/server";
|
|
5
|
-
import type { DurableObjectSql } from "@nyte-ai/host/durable-object";
|
|
6
|
-
/** Returns the parts of a Durable Object's `state` `NyteHost` uses, structurally: the storage `durableObjectStore` reads with the object's one alarm, and `blockConcurrencyWhile` to hold requests until the host is composed. */
|
|
7
|
-
export type WorkerState = {
|
|
8
|
-
readonly storage: DurableObjectSql & {
|
|
9
|
-
getAlarm(): Promise<number | null>;
|
|
10
|
-
setAlarm(scheduledTime: number): Promise<void>;
|
|
11
|
-
deleteAlarm(): Promise<void>;
|
|
12
|
-
};
|
|
13
|
-
blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T>;
|
|
14
|
-
};
|
|
15
|
-
/** Returns the Worker's bindings: the `NyteHost` namespace `wrangler.jsonc` binds, the listener token it requires as a secret (`secrets.required`, set with `wrangler secret put NYTE_TOKEN`, at least 16 characters; §42l), the optional base64 secrets key (decision 10; absent, see `secretsFrom`), and the optional base64 identity seed (§50a; absent, the host answers no identity challenge). */
|
|
16
|
-
export type WorkerEnv = {
|
|
17
|
-
readonly NYTE_HOST: {
|
|
18
|
-
getByName(name: string): {
|
|
19
|
-
fetch(request: Request): Promise<Response>;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
readonly NYTE_TOKEN: string;
|
|
23
|
-
readonly NYTE_SECRET_KEY?: string;
|
|
24
|
-
readonly NYTE_IDENTITY_KEY?: string;
|
|
25
|
-
};
|
|
26
|
-
export type PassBudget = {
|
|
27
|
-
readonly heads: number;
|
|
28
|
-
readonly ms: number;
|
|
29
|
-
readonly repair: boolean;
|
|
30
|
-
};
|
|
31
|
-
export type PassHost = Pick<Host, "execution"> & {
|
|
32
|
-
readonly server: Pick<ServerHost, "tick">;
|
|
33
|
-
};
|
|
34
|
-
export declare function scheduleFrom(report: AdvanceReport, now: number): number | null;
|
|
35
|
-
export declare function pass(host: PassHost, storage: Pick<DurableObjectSql, "sql">, budget: PassBudget): Promise<number | null>;
|
|
36
|
-
/** The Durable Object that is one Nyte host, importing only the node-free subpaths (§41j): composed once per object over its own SQLite storage with a chat-only workspace, served through `listenFetch`, and driven by its alarm. */
|
|
37
|
-
export declare class NyteHost {
|
|
38
|
-
#private;
|
|
39
|
-
constructor(state: WorkerState, env: WorkerEnv, options?: {
|
|
40
|
-
readonly models?: Models;
|
|
41
|
-
});
|
|
42
|
-
/** Answers one request through the listener once the host is composed; an object whose composition failed answers its encoded `SdkError` (`unavailable`, 503) and composes again on the next request. */
|
|
43
|
-
fetch(request: Request): Promise<Response>;
|
|
44
|
-
alarm(): Promise<void>;
|
|
45
|
-
}
|
|
46
|
-
/** The Worker: routes every request to the one `NyteHost` object, `env.NYTE_HOST.getByName("host")`. */
|
|
47
|
-
declare const _default: {
|
|
48
|
-
fetch(request: Request, env: WorkerEnv): Promise<Response>;
|
|
49
|
-
};
|
|
50
|
-
export default _default;
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
package_default
|
|
3
|
-
} from "../../../chunks/canvas-preview-dsb5829c.js";
|
|
4
|
-
|
|
5
|
-
// src/deploy/cloudflare/worker.ts
|
|
6
|
-
import { asId, SdkError } from "@nyte-ai/schema";
|
|
7
|
-
import { createModels } from "@nyte-ai/ai/models";
|
|
8
|
-
import { composeHost } from "@nyte-ai/core/server";
|
|
9
|
-
import { encodeError, errorStatus } from "@nyte-ai/protocol";
|
|
10
|
-
import { Settings } from "typebox/system";
|
|
11
|
-
import { credentialStore } from "@nyte-ai/host/credentials";
|
|
12
|
-
import { durableObjectStore } from "@nyte-ai/host/durable-object";
|
|
13
|
-
import { seedSigner } from "@nyte-ai/host/identity";
|
|
14
|
-
import { listenFetch } from "@nyte-ai/host/listen-fetch";
|
|
15
|
-
import { chatOnlyProvider } from "@nyte-ai/host/providers";
|
|
16
|
-
Settings.Set({ useAcceleration: false });
|
|
17
|
-
var PASS_BUDGET = { heads: 32, ms: 1e4 };
|
|
18
|
-
var REPAIR_EVERY = 60;
|
|
19
|
-
var RETRY_MS = 30000;
|
|
20
|
-
var PAGE = 100;
|
|
21
|
-
function scheduleFrom(report, now) {
|
|
22
|
-
switch (report.kind) {
|
|
23
|
-
case "continue":
|
|
24
|
-
return now;
|
|
25
|
-
case "waiting":
|
|
26
|
-
return report.until;
|
|
27
|
-
case "retry":
|
|
28
|
-
case "busy":
|
|
29
|
-
return report.until;
|
|
30
|
-
case "idle":
|
|
31
|
-
case "fenced":
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
async function pass(host, storage, budget) {
|
|
36
|
-
const began = Date.now();
|
|
37
|
-
const schedule = openSchedule(storage);
|
|
38
|
-
await host.server.tick(began);
|
|
39
|
-
if (budget.repair) {
|
|
40
|
-
let cursor;
|
|
41
|
-
do {
|
|
42
|
-
cursor = (await host.execution.repair({ cursor, limit: PAGE })).next ?? undefined;
|
|
43
|
-
} while (cursor !== undefined);
|
|
44
|
-
}
|
|
45
|
-
const advances = [];
|
|
46
|
-
for (const entry of schedule.due(Date.now())) {
|
|
47
|
-
if (advances.length >= budget.heads || Date.now() - began >= budget.ms) {
|
|
48
|
-
schedule.write(entry.session, entry.head, began);
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
advances.push(host.execution.advance({ session: entry.session, head: entry.head }).then((report) => schedule.settle(entry, scheduleFrom(report, Date.now())), (error) => {
|
|
52
|
-
console.error(`Advancing ${entry.session}/${entry.head} failed:`, error);
|
|
53
|
-
schedule.settle(entry, Date.now() + RETRY_MS);
|
|
54
|
-
}));
|
|
55
|
-
}
|
|
56
|
-
await Promise.all(advances);
|
|
57
|
-
return schedule.earliest();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
class NyteHost {
|
|
61
|
-
#state;
|
|
62
|
-
#env;
|
|
63
|
-
#models;
|
|
64
|
-
#served = null;
|
|
65
|
-
#passes = 0;
|
|
66
|
-
constructor(state, env, options) {
|
|
67
|
-
this.#state = state;
|
|
68
|
-
this.#env = env;
|
|
69
|
-
this.#models = options?.models;
|
|
70
|
-
state.blockConcurrencyWhile(async () => {
|
|
71
|
-
await this.#serve().catch(() => {
|
|
72
|
-
return;
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
async fetch(request) {
|
|
77
|
-
let served;
|
|
78
|
-
try {
|
|
79
|
-
served = await this.#serve();
|
|
80
|
-
} catch (error) {
|
|
81
|
-
const failure = new SdkError("unavailable", `The host did not start: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
-
return new Response(JSON.stringify(encodeError(failure)), {
|
|
83
|
-
status: errorStatus[failure.code],
|
|
84
|
-
headers: { "Content-Type": "application/json" }
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
return served.listener.fetch(request);
|
|
88
|
-
}
|
|
89
|
-
async alarm() {
|
|
90
|
-
const served = await this.#serve();
|
|
91
|
-
const repair = this.#passes % REPAIR_EVERY === 0;
|
|
92
|
-
this.#passes += 1;
|
|
93
|
-
const next = await pass(served.host, this.#state.storage, { ...PASS_BUDGET, repair });
|
|
94
|
-
if (next === null)
|
|
95
|
-
await this.#state.storage.deleteAlarm();
|
|
96
|
-
else
|
|
97
|
-
await this.#state.storage.setAlarm(next);
|
|
98
|
-
}
|
|
99
|
-
#serve() {
|
|
100
|
-
const served = this.#served ??= compose(this.#state, this.#env, this.#models);
|
|
101
|
-
served.catch(() => {
|
|
102
|
-
if (this.#served === served)
|
|
103
|
-
this.#served = null;
|
|
104
|
-
});
|
|
105
|
-
return served;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
var worker_default = {
|
|
109
|
-
async fetch(request, env) {
|
|
110
|
-
return env.NYTE_HOST.getByName("host").fetch(request);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
async function compose(state, env, models) {
|
|
114
|
-
const { storage } = state;
|
|
115
|
-
const store = durableObjectStore(storage);
|
|
116
|
-
const secrets = secretsFrom(env.NYTE_SECRET_KEY);
|
|
117
|
-
const description = { name: "nyte-host", platform: "cloudflare", version: package_default.version };
|
|
118
|
-
const host = await composeHost({
|
|
119
|
-
store,
|
|
120
|
-
models: models ?? createModels({ credentials: credentialStore(store, secrets) }),
|
|
121
|
-
plugins: [{ id: "chat-only", environment: chatOnlyProvider() }],
|
|
122
|
-
workspace: { kind: "chat-only", locator: null },
|
|
123
|
-
execution: { kind: "admit-only" },
|
|
124
|
-
secrets,
|
|
125
|
-
home: null,
|
|
126
|
-
description
|
|
127
|
-
});
|
|
128
|
-
try {
|
|
129
|
-
const coverage = await host.execution.cover({ kind: "all" });
|
|
130
|
-
const schedule = openSchedule(storage);
|
|
131
|
-
host.server.onWake((session, head) => {
|
|
132
|
-
const now = Date.now();
|
|
133
|
-
schedule.write(session, head, now);
|
|
134
|
-
storage.setAlarm(now);
|
|
135
|
-
});
|
|
136
|
-
const listener = await listenFetch(host, {
|
|
137
|
-
transport: { kind: "fetch" },
|
|
138
|
-
auth: { kind: "token", token: env.NYTE_TOKEN },
|
|
139
|
-
execution: { kind: "admit-only" },
|
|
140
|
-
describe: () => description,
|
|
141
|
-
...env.NYTE_IDENTITY_KEY === undefined || env.NYTE_IDENTITY_KEY === "" ? {} : {
|
|
142
|
-
identity: await seedSigner(host.hostId, Uint8Array.fromBase64(env.NYTE_IDENTITY_KEY))
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
await storage.setAlarm(Date.now());
|
|
146
|
-
return { host, listener, coverage };
|
|
147
|
-
} catch (error) {
|
|
148
|
-
await host.close();
|
|
149
|
-
throw error;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function secretsFrom(key) {
|
|
153
|
-
if (key === undefined || key === "")
|
|
154
|
-
return {
|
|
155
|
-
key: async () => {
|
|
156
|
-
throw new SdkError("unavailable", "Set NYTE_SECRET_KEY to a base64 32-byte key.");
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
const bytes = Uint8Array.from(atob(key), (character) => character.charCodeAt(0));
|
|
160
|
-
return { key: async () => bytes };
|
|
161
|
-
}
|
|
162
|
-
function openSchedule(storage) {
|
|
163
|
-
const rows = (query, ...bindings) => storage.sql.exec(query, ...bindings).toArray();
|
|
164
|
-
rows("CREATE TABLE IF NOT EXISTS nyte_schedule (session TEXT NOT NULL, head TEXT NOT NULL, at INTEGER NOT NULL, PRIMARY KEY (session, head))");
|
|
165
|
-
const readAt = (session, head) => {
|
|
166
|
-
const at = rows("SELECT at FROM nyte_schedule WHERE session = ? AND head = ?", session, head)[0]?.at;
|
|
167
|
-
return typeof at === "number" ? at : null;
|
|
168
|
-
};
|
|
169
|
-
const write = (session, head, at) => {
|
|
170
|
-
rows("INSERT INTO nyte_schedule (session, head, at) VALUES (?, ?, ?) ON CONFLICT (session, head) DO UPDATE SET at = excluded.at", session, head, at);
|
|
171
|
-
};
|
|
172
|
-
return {
|
|
173
|
-
write,
|
|
174
|
-
due(now) {
|
|
175
|
-
return rows("SELECT session, head, at FROM nyte_schedule WHERE at <= ? ORDER BY at", now).flatMap((row) => typeof row.session === "string" && typeof row.head === "string" && typeof row.at === "number" ? [{ session: asId(row.session), head: asId(row.head), at: row.at }] : []);
|
|
176
|
-
},
|
|
177
|
-
settle(entry, next) {
|
|
178
|
-
if (readAt(entry.session, entry.head) !== entry.at)
|
|
179
|
-
return;
|
|
180
|
-
if (next === null)
|
|
181
|
-
rows("DELETE FROM nyte_schedule WHERE session = ? AND head = ?", entry.session, entry.head);
|
|
182
|
-
else
|
|
183
|
-
write(entry.session, entry.head, next);
|
|
184
|
-
},
|
|
185
|
-
earliest() {
|
|
186
|
-
const at = rows("SELECT MIN(at) AS at FROM nyte_schedule")[0]?.at;
|
|
187
|
-
return typeof at === "number" ? at : null;
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
export {
|
|
192
|
-
NyteHost,
|
|
193
|
-
worker_default as default,
|
|
194
|
-
pass,
|
|
195
|
-
scheduleFrom
|
|
196
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// src/deploy/vercel/nitro.config.ts
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
import { defineConfig } from "nitro";
|
|
4
|
-
var config = {
|
|
5
|
-
serverDir: "./server",
|
|
6
|
-
modules: ["workflow/nitro"],
|
|
7
|
-
workflow: {
|
|
8
|
-
runtime: "nodejs24.x",
|
|
9
|
-
dirs: ["./server/workflows"]
|
|
10
|
-
},
|
|
11
|
-
vercel: {
|
|
12
|
-
functions: {
|
|
13
|
-
runtime: "nodejs24.x",
|
|
14
|
-
maxDuration: 300
|
|
15
|
-
},
|
|
16
|
-
config: {
|
|
17
|
-
version: 3,
|
|
18
|
-
crons: [
|
|
19
|
-
{
|
|
20
|
-
path: "/.nyte/repair",
|
|
21
|
-
schedule: process.env.NYTE_REPAIR_SCHEDULE ?? "* * * * *"
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
var nitro_config_default = defineConfig(config);
|
|
28
|
-
export {
|
|
29
|
-
nitro_config_default as default
|
|
30
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import"../../../../../chunks/canvas-preview-2zdyh9ny.js";
|
|
2
|
-
import {
|
|
3
|
-
vercelHost2
|
|
4
|
-
} from "../../../../../chunks/canvas-preview-1f8h0he1.js";
|
|
5
|
-
import"../../../../../chunks/canvas-preview-65xqjw7f.js";
|
|
6
|
-
import {
|
|
7
|
-
dispatchHead2
|
|
8
|
-
} from "../../../../../chunks/canvas-preview-kzmp015w.js";
|
|
9
|
-
|
|
10
|
-
// src/deploy/vercel/server/routes/[...].ts
|
|
11
|
-
import { defineHandler } from "nitro/h3";
|
|
12
|
-
async function serve(event) {
|
|
13
|
-
return (await vercelHost2(dispatchHead2)).listener.fetch(event.req);
|
|
14
|
-
}
|
|
15
|
-
var ___default = defineHandler(serve);
|
|
16
|
-
export {
|
|
17
|
-
___default as default
|
|
18
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Listener, OpenOptions } from "@nyte-ai/core";
|
|
2
|
-
import type { ServedHost } from "@nyte-ai/core/server";
|
|
3
|
-
type Served = {
|
|
4
|
-
readonly host: ServedHost;
|
|
5
|
-
readonly listener: Listener;
|
|
6
|
-
};
|
|
7
|
-
/** Starts the workflow that drives a head; the host hands each wake to it. */
|
|
8
|
-
type Dispatch = Extract<NonNullable<OpenOptions["execution"]>, {
|
|
9
|
-
readonly kind: "dispatch";
|
|
10
|
-
}>["dispatch"];
|
|
11
|
-
/** This process's host, composed once, handing each wake to `dispatch`. */
|
|
12
|
-
export declare function vercelHost(dispatch: Dispatch): Promise<Served>;
|
|
13
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function answerRepair(request: Request, secret: string | undefined, repair: () => Promise<void>): Promise<Response | undefined>;
|