@avocadostudio-ai/orchestrator-core 0.1.0 → 0.2.0
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/agent/sites-agent-context.js +3 -2
- package/dist/agent/sites-agent-shared.js +1 -0
- package/dist/chat/anthropic-planner.js +3 -3
- package/dist/chat/chat-pipeline.js +122 -20
- package/dist/chat/gemini-planner.js +3 -3
- package/dist/chat/planner.js +7 -5
- package/dist/chat/prompts.js +6 -1
- package/dist/cms/adapter.d.ts +159 -1
- package/dist/cms/adapter.js +19 -1
- package/dist/cms/bootstrap.d.ts +46 -1
- package/dist/cms/bootstrap.js +126 -2
- package/dist/cms/index.d.ts +3 -2
- package/dist/cms/index.js +2 -1
- package/dist/errors.d.ts +9 -1
- package/dist/handler/auth.d.ts +79 -0
- package/dist/handler/auth.js +113 -0
- package/dist/handler/create-orchestrator.d.ts +205 -0
- package/dist/handler/create-orchestrator.js +1599 -0
- package/dist/http/access-tokens.d.ts +58 -0
- package/dist/http/access-tokens.js +161 -0
- package/dist/http/audio-actions.d.ts +121 -0
- package/dist/http/audio-actions.js +248 -0
- package/dist/http/blocks-actions.d.ts +31 -0
- package/dist/http/blocks-actions.js +31 -0
- package/dist/http/draft-provenance.d.ts +68 -0
- package/dist/http/draft-provenance.js +101 -0
- package/dist/http/history-actions.d.ts +58 -0
- package/dist/http/history-actions.js +169 -0
- package/dist/http/image-generate-actions.d.ts +268 -0
- package/dist/http/image-generate-actions.js +546 -0
- package/dist/http/ops-actions.d.ts +51 -0
- package/dist/http/ops-actions.js +79 -0
- package/dist/http/publish-actions.d.ts +153 -0
- package/dist/http/publish-actions.js +323 -0
- package/dist/http/restore-actions.d.ts +67 -0
- package/dist/http/restore-actions.js +145 -0
- package/dist/http/screenshot-actions.d.ts +108 -0
- package/dist/http/screenshot-actions.js +181 -0
- package/dist/http/session-actions.d.ts +35 -0
- package/dist/http/session-actions.js +98 -0
- package/dist/http/telemetry-feedback-actions.d.ts +53 -0
- package/dist/http/telemetry-feedback-actions.js +68 -0
- package/dist/http/unsplash-actions.d.ts +64 -0
- package/dist/http/unsplash-actions.js +81 -0
- package/dist/http/variations-actions.d.ts +102 -0
- package/dist/http/variations-actions.js +104 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +21 -1
- package/dist/nlp/deterministic-planner-refs.d.ts +1 -1
- package/dist/nlp/deterministic-planner-suggestions.d.ts +10 -0
- package/dist/nlp/deterministic-planner-suggestions.js +37 -11
- package/dist/nlp/plan-normalizer.js +18 -2
- package/dist/ops/ops-engine.js +219 -14
- package/dist/state/session-state.d.ts +56 -1
- package/dist/state/session-state.js +92 -6
- package/dist/state/sqlite-store-singleton.d.ts +22 -0
- package/dist/state/sqlite-store-singleton.js +49 -1
- package/dist/state/sqlite-store.d.ts +5 -0
- package/dist/state/sqlite-store.js +125 -2
- package/dist/telemetry/chat-telemetry.js +6 -1
- package/package.json +12 -16
|
@@ -1,6 +1,128 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { mkdirSync } from "node:fs";
|
|
2
|
-
import { dirname, resolve } from "node:path";
|
|
3
|
-
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
/*
|
|
5
|
+
* `better-sqlite3` is loaded at runtime, through a specifier no bundler can read.
|
|
6
|
+
*
|
|
7
|
+
* A static `import Database from "better-sqlite3"` is correct for the standalone
|
|
8
|
+
* Fastify server and wrong for every library-mode consumer. `createOrchestrator()`
|
|
9
|
+
* is mounted inside the integrator's own Next app, so their bundler traces this
|
|
10
|
+
* module and tries to pack a native `.node` binding. What comes out the other side
|
|
11
|
+
* is not a constructor, and the failure surfaces far from here: PBA logged
|
|
12
|
+
* `Failed to open orchestrator SQLite store { err: "Cannot read properties of
|
|
13
|
+
* undefined (reading 'indexOf')" }` once at boot and then a persist error on every
|
|
14
|
+
* single write, while `/ops` kept answering `status: "applied"`. Draft edits lived
|
|
15
|
+
* in one module instance and vanished on the next reload, silently re-seeded from
|
|
16
|
+
* the CMS.
|
|
17
|
+
*
|
|
18
|
+
* `createRequire` gives us Node's own resolver — including the native binding
|
|
19
|
+
* lookup that a bundle cannot reproduce — and the specifier is assembled at
|
|
20
|
+
* runtime so static analysis has nothing to follow. It stays synchronous, which is
|
|
21
|
+
* what lets `getStore()` keep its signature and all eight call sites stay as they
|
|
22
|
+
* are. The alternative, telling every integrator to add `better-sqlite3` to
|
|
23
|
+
* `serverExternalPackages`, pushes our dependency's shape into their config and
|
|
24
|
+
* fails closed only if they read the docs.
|
|
25
|
+
*/
|
|
26
|
+
const SQLITE_SPECIFIER = ["better", "sqlite3"].join("-");
|
|
27
|
+
let cachedCtor = null;
|
|
28
|
+
/*
|
|
29
|
+
* How the native module is reached, and why it takes three attempts.
|
|
30
|
+
*
|
|
31
|
+
* A Next server bundle is hostile to every ordinary route in:
|
|
32
|
+
* - `require` is not defined — the emitted chunk is ESM.
|
|
33
|
+
* - `node:module` is stubbed, so an imported `createRequire` is `undefined`.
|
|
34
|
+
* - webpack special-cases the literal `createRequire(import.meta.url)` idiom
|
|
35
|
+
* and swaps in its own shim, which resolves against the bundle rather than
|
|
36
|
+
* the host and answers "Cannot find module" for a package that is installed.
|
|
37
|
+
*
|
|
38
|
+
* What survives is a dynamic `import()` whose specifier the bundler cannot read,
|
|
39
|
+
* built with `new Function` — the same technique `screenshot-actions.ts` uses to
|
|
40
|
+
* keep Playwright out of a consumer's bundle. It is async, which is why the
|
|
41
|
+
* driver is preloaded at boot (`preloadSqliteDriver`, awaited by
|
|
42
|
+
* `loadStateFromDisk`) rather than resolved lazily inside the constructor: that
|
|
43
|
+
* keeps `getStore()` synchronous and all eight of its call sites unchanged.
|
|
44
|
+
*
|
|
45
|
+
* The synchronous paths stay as fallbacks for the standalone server and for
|
|
46
|
+
* tests, which run this file as real ESM under tsx where `createRequire` is
|
|
47
|
+
* Node's own.
|
|
48
|
+
*/
|
|
49
|
+
const runtimeImport = new Function("specifier", "return import(specifier)");
|
|
50
|
+
function asCtor(loaded) {
|
|
51
|
+
if (typeof loaded === "function")
|
|
52
|
+
return loaded;
|
|
53
|
+
const candidate = loaded?.default;
|
|
54
|
+
return typeof candidate === "function" ? candidate : null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve and cache the driver. Awaited once at startup; safe to call again.
|
|
58
|
+
* Throws with every attempt's failure when the module cannot be reached at all.
|
|
59
|
+
*/
|
|
60
|
+
export async function preloadSqliteDriver() {
|
|
61
|
+
if (cachedCtor)
|
|
62
|
+
return;
|
|
63
|
+
const failures = [];
|
|
64
|
+
try {
|
|
65
|
+
const ctor = asCtor(await runtimeImport(SQLITE_SPECIFIER));
|
|
66
|
+
if (ctor) {
|
|
67
|
+
cachedCtor = ctor;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
failures.push("dynamic import: resolved to a namespace with no constructor");
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
failures.push(`dynamic import: ${err instanceof Error ? err.message : String(err)}`);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
loadDatabaseCtorSync();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
failures.push(err instanceof Error ? err.message : String(err));
|
|
81
|
+
}
|
|
82
|
+
throw new Error(driverError(failures));
|
|
83
|
+
}
|
|
84
|
+
function driverError(failures) {
|
|
85
|
+
return (`Could not load better-sqlite3 (${failures.join("; ")}). The orchestrator keeps ` +
|
|
86
|
+
"draft pages, undo stacks and the version log in SQLite; without it every edit " +
|
|
87
|
+
"is in-memory only and is lost on restart. Install it in the app that mounts " +
|
|
88
|
+
"createOrchestrator(): `npm install better-sqlite3`. A workspace link to " +
|
|
89
|
+
"orchestrator-core is not enough — a native module has to be resolvable from " +
|
|
90
|
+
"the host's own node_modules.");
|
|
91
|
+
}
|
|
92
|
+
function loadDatabaseCtorSync() {
|
|
93
|
+
if (cachedCtor)
|
|
94
|
+
return cachedCtor;
|
|
95
|
+
const failures = [];
|
|
96
|
+
const attempts = [
|
|
97
|
+
{
|
|
98
|
+
name: "createRequire(import.meta.url)",
|
|
99
|
+
load: () => createRequire(import.meta.url)(SQLITE_SPECIFIER)
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
// A plain path, not a file URL: `node:url` is stubbed in a bundle too, so
|
|
103
|
+
// `pathToFileURL` there is `undefined`. `createRequire` takes a filename.
|
|
104
|
+
name: "createRequire(cwd)",
|
|
105
|
+
load: () => createRequire(join(process.cwd(), "noop.js"))(SQLITE_SPECIFIER)
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
for (const attempt of attempts) {
|
|
109
|
+
try {
|
|
110
|
+
const ctor = asCtor(attempt.load());
|
|
111
|
+
if (ctor) {
|
|
112
|
+
cachedCtor = ctor;
|
|
113
|
+
return ctor;
|
|
114
|
+
}
|
|
115
|
+
failures.push(`${attempt.name}: no constructor`);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
failures.push(`${attempt.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
throw new Error(driverError(failures));
|
|
122
|
+
}
|
|
123
|
+
function loadDatabaseCtor() {
|
|
124
|
+
return cachedCtor ?? loadDatabaseCtorSync();
|
|
125
|
+
}
|
|
4
126
|
// ---------------------------------------------------------------------------
|
|
5
127
|
// Caps (mirrors limits used by in-memory state)
|
|
6
128
|
// ---------------------------------------------------------------------------
|
|
@@ -99,6 +221,7 @@ export class SqliteStore {
|
|
|
99
221
|
if (file !== ":memory:") {
|
|
100
222
|
mkdirSync(dirname(resolve(file)), { recursive: true });
|
|
101
223
|
}
|
|
224
|
+
const Database = loadDatabaseCtor();
|
|
102
225
|
this.db = new Database(file);
|
|
103
226
|
this.db.pragma("foreign_keys = ON");
|
|
104
227
|
if (useWal) {
|
|
@@ -174,7 +174,12 @@ export function createChatTelemetryStore(args) {
|
|
|
174
174
|
"planning_exhausted",
|
|
175
175
|
"planning_refusal",
|
|
176
176
|
"planning_incomplete",
|
|
177
|
-
"planning_missing"
|
|
177
|
+
"planning_missing",
|
|
178
|
+
// An `edit_plan` that carried no operations. It answers 200 and reads as
|
|
179
|
+
// success to the user, which is exactly why it has to count as a failure
|
|
180
|
+
// here — otherwise the one outcome nobody can see from the UI is also
|
|
181
|
+
// invisible in the numbers.
|
|
182
|
+
"empty_edit_plan"
|
|
178
183
|
]);
|
|
179
184
|
const failures = recent.filter((row) => row.phase === "result" && row.outcome && failureOutcomes.has(row.outcome));
|
|
180
185
|
const success = recent.filter((row) => row.phase === "result" && row.outcome === "applied");
|
package/package.json
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avocadostudio-ai/orchestrator-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package.json": "./package.json",
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
|
-
"import": "./dist/index.js"
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"default": "./dist/index.js"
|
|
10
11
|
},
|
|
11
12
|
"./cms": {
|
|
12
13
|
"types": "./dist/cms/index.d.ts",
|
|
13
|
-
"import": "./dist/cms/index.js"
|
|
14
|
-
|
|
15
|
-
"./*.js": {
|
|
16
|
-
"types": "./dist/*.d.ts",
|
|
17
|
-
"import": "./dist/*.js"
|
|
18
|
-
},
|
|
19
|
-
"./*": {
|
|
20
|
-
"types": "./dist/*.d.ts",
|
|
21
|
-
"import": "./dist/*.js"
|
|
14
|
+
"import": "./dist/cms/index.js",
|
|
15
|
+
"default": "./dist/cms/index.js"
|
|
22
16
|
}
|
|
23
17
|
},
|
|
24
18
|
"dependencies": {
|
|
@@ -29,15 +23,16 @@
|
|
|
29
23
|
"openai": "^4.87.1",
|
|
30
24
|
"sharp": "^0.34.5",
|
|
31
25
|
"zod": "^4.3.6",
|
|
32
|
-
"@avocadostudio-ai/
|
|
33
|
-
"@avocadostudio-ai/
|
|
26
|
+
"@avocadostudio-ai/migration-sdk": "0.2.0",
|
|
27
|
+
"@avocadostudio-ai/shared": "0.2.0"
|
|
34
28
|
},
|
|
35
29
|
"devDependencies": {
|
|
30
|
+
"@google/genai": "^1.46.0",
|
|
36
31
|
"@types/better-sqlite3": "^7.6.13",
|
|
37
32
|
"@types/node": "^22.13.10",
|
|
38
|
-
"typescript": "^5.7.3",
|
|
39
33
|
"googleapis": "^171.4.0",
|
|
40
|
-
"
|
|
34
|
+
"tsx": "^4.21.0",
|
|
35
|
+
"typescript": "^5.7.3"
|
|
41
36
|
},
|
|
42
37
|
"main": "dist/index.js",
|
|
43
38
|
"types": "dist/index.d.ts",
|
|
@@ -73,6 +68,7 @@
|
|
|
73
68
|
},
|
|
74
69
|
"scripts": {
|
|
75
70
|
"typecheck": "tsc --noEmit",
|
|
76
|
-
"build": "tsc -p tsconfig.build.json && node ./scripts/copy-assets.mjs"
|
|
71
|
+
"build": "tsc -p tsconfig.build.json && node ./scripts/copy-assets.mjs",
|
|
72
|
+
"test": "NODE_ENV=test node ../../scripts/run-tests.mjs"
|
|
77
73
|
}
|
|
78
74
|
}
|