@elizaos/app-core 2.0.3-beta.5 → 2.0.3-beta.7
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/package.json +37 -36
- package/platforms/electrobun/electrobun.config.ts +31 -1
- package/platforms/electrobun/package.json +10 -10
- package/platforms/electrobun/remotes/fs/README.md +0 -1
- package/platforms/electrobun/remotes/fs/package.json +0 -1
- package/platforms/electrobun/remotes/git/README.md +1 -2
- package/platforms/electrobun/remotes/git/package.json +0 -1
- package/platforms/electrobun/remotes/local-model/README.md +0 -1
- package/platforms/electrobun/remotes/local-model/package.json +0 -1
- package/platforms/electrobun/remotes/pty/README.md +1 -2
- package/platforms/electrobun/remotes/pty/package.json +0 -1
- package/platforms/electrobun/remotes/runtime/README.md +1 -5
- package/platforms/electrobun/remotes/runtime/package.json +0 -1
- package/platforms/electrobun/remotes/surface/README.md +1 -2
- package/platforms/electrobun/remotes/surface/package.json +0 -1
- package/platforms/electrobun/scripts/sync-web-assets.mjs +31 -2
- package/platforms/electrobun/src/api-base.ts +11 -2
- package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +15 -1
- package/platforms/electrobun/src/index.ts +25 -28
- package/platforms/electrobun/src/lifecycle/api-base-owner.test.ts +67 -5
- package/platforms/electrobun/src/lifecycle/api-base-owner.ts +36 -6
- package/platforms/electrobun/src/native/desktop.ts +1 -1
- package/platforms/electrobun/src/onboarding-overlay-window.ts +7 -8
- package/platforms/electrobun/src/preload.js +1 -1
- package/platforms/electrobun/src/rpc-schema.ts +5 -1
- package/runtime/voice-warmup.d.ts.map +1 -1
- package/runtime/voice-warmup.js +8 -2
- package/scripts/benchmark-preflight.mjs +31 -2
- package/scripts/build-image.sh +5 -2
- package/scripts/bun-riscv64/build.sh +12 -6
- package/scripts/bun-riscv64/run-build.sh +10 -1
- package/scripts/dev-platform.mjs +19 -10
- package/scripts/ios-xcframework/README.md +15 -9
- package/scripts/ios-xcframework/run-physical-device-smoke.mjs +5 -3
- package/scripts/playwright-ui-live-stack.ts +32 -8
- package/scripts/run-mobile-build.mjs +11 -14
- package/platforms/electrobun/src/desktop-pill-config.test.ts +0 -27
- package/platforms/electrobun/src/desktop-pill-config.ts +0 -40
- package/platforms/electrobun/src/pill-window.test.ts +0 -91
- package/platforms/electrobun/src/pill-window.ts +0 -99
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/app-core",
|
|
3
|
-
"version": "2.0.3-beta.
|
|
3
|
+
"version": "2.0.3-beta.7",
|
|
4
4
|
"description": "Shared application core for elizaOS white-label agent apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -155,22 +155,22 @@
|
|
|
155
155
|
"three": "^0.184.0"
|
|
156
156
|
},
|
|
157
157
|
"optionalDependencies": {
|
|
158
|
-
"@elizaos/capacitor-appblocker": "2.0.3-beta.
|
|
159
|
-
"@elizaos/capacitor-bun-runtime": "2.0.3-beta.
|
|
160
|
-
"@elizaos/capacitor-camera": "2.0.3-beta.
|
|
161
|
-
"@elizaos/capacitor-canvas": "2.0.3-beta.
|
|
162
|
-
"@elizaos/capacitor-contacts": "2.0.3-beta.
|
|
163
|
-
"@elizaos/capacitor-gateway": "2.0.3-beta.
|
|
164
|
-
"@elizaos/capacitor-location": "2.0.3-beta.
|
|
165
|
-
"@elizaos/capacitor-messages": "2.0.3-beta.
|
|
166
|
-
"@elizaos/capacitor-mobile-agent-bridge": "2.0.3-beta.
|
|
167
|
-
"@elizaos/capacitor-mobile-signals": "2.0.3-beta.
|
|
168
|
-
"@elizaos/capacitor-phone": "2.0.3-beta.
|
|
169
|
-
"@elizaos/capacitor-screencapture": "2.0.3-beta.
|
|
170
|
-
"@elizaos/capacitor-swabble": "2.0.3-beta.
|
|
171
|
-
"@elizaos/capacitor-system": "2.0.3-beta.
|
|
172
|
-
"@elizaos/capacitor-talkmode": "2.0.3-beta.
|
|
173
|
-
"@elizaos/capacitor-websiteblocker": "2.0.3-beta.
|
|
158
|
+
"@elizaos/capacitor-appblocker": "2.0.3-beta.7",
|
|
159
|
+
"@elizaos/capacitor-bun-runtime": "2.0.3-beta.7",
|
|
160
|
+
"@elizaos/capacitor-camera": "2.0.3-beta.7",
|
|
161
|
+
"@elizaos/capacitor-canvas": "2.0.3-beta.7",
|
|
162
|
+
"@elizaos/capacitor-contacts": "2.0.3-beta.7",
|
|
163
|
+
"@elizaos/capacitor-gateway": "2.0.3-beta.7",
|
|
164
|
+
"@elizaos/capacitor-location": "2.0.3-beta.7",
|
|
165
|
+
"@elizaos/capacitor-messages": "2.0.3-beta.7",
|
|
166
|
+
"@elizaos/capacitor-mobile-agent-bridge": "2.0.3-beta.7",
|
|
167
|
+
"@elizaos/capacitor-mobile-signals": "2.0.3-beta.7",
|
|
168
|
+
"@elizaos/capacitor-phone": "2.0.3-beta.7",
|
|
169
|
+
"@elizaos/capacitor-screencapture": "2.0.3-beta.7",
|
|
170
|
+
"@elizaos/capacitor-swabble": "2.0.3-beta.7",
|
|
171
|
+
"@elizaos/capacitor-system": "2.0.3-beta.7",
|
|
172
|
+
"@elizaos/capacitor-talkmode": "2.0.3-beta.7",
|
|
173
|
+
"@elizaos/capacitor-websiteblocker": "2.0.3-beta.7",
|
|
174
174
|
"sharp": "^0.34.5"
|
|
175
175
|
},
|
|
176
176
|
"dependencies": {
|
|
@@ -184,24 +184,25 @@
|
|
|
184
184
|
"@capacitor/preferences": "^8.0.1",
|
|
185
185
|
"@capacitor/push-notifications": "^8.0.0",
|
|
186
186
|
"@clack/prompts": "^1.0.0",
|
|
187
|
-
"@elizaos/
|
|
188
|
-
"@elizaos/
|
|
189
|
-
"@elizaos/plugin-
|
|
190
|
-
"@elizaos/plugin-
|
|
191
|
-
"@elizaos/plugin-
|
|
192
|
-
"@elizaos/plugin-
|
|
193
|
-
"@elizaos/plugin-
|
|
194
|
-
"@elizaos/plugin-
|
|
195
|
-
"@elizaos/plugin-
|
|
196
|
-
"@elizaos/plugin-
|
|
197
|
-
"@elizaos/plugin-
|
|
198
|
-
"@elizaos/plugin-
|
|
199
|
-
"@elizaos/plugin-
|
|
200
|
-
"@elizaos/
|
|
201
|
-
"@elizaos/
|
|
202
|
-
"@elizaos/
|
|
203
|
-
"@elizaos/
|
|
204
|
-
"@elizaos/
|
|
187
|
+
"@elizaos/agent": "2.0.3-beta.7",
|
|
188
|
+
"@elizaos/core": "2.0.3-beta.7",
|
|
189
|
+
"@elizaos/plugin-anthropic": "2.0.3-beta.7",
|
|
190
|
+
"@elizaos/plugin-browser": "2.0.3-beta.7",
|
|
191
|
+
"@elizaos/plugin-edge-tts": "2.0.3-beta.7",
|
|
192
|
+
"@elizaos/plugin-elizacloud": "2.0.3-beta.7",
|
|
193
|
+
"@elizaos/plugin-groq": "2.0.3-beta.7",
|
|
194
|
+
"@elizaos/plugin-health": "2.0.3-beta.7",
|
|
195
|
+
"@elizaos/plugin-local-inference": "2.0.3-beta.7",
|
|
196
|
+
"@elizaos/plugin-openai": "2.0.3-beta.7",
|
|
197
|
+
"@elizaos/plugin-registry": "2.0.3-beta.7",
|
|
198
|
+
"@elizaos/plugin-sql": "2.0.3-beta.7",
|
|
199
|
+
"@elizaos/plugin-wechat": "2.0.3-beta.7",
|
|
200
|
+
"@elizaos/plugin-workflow": "2.0.3-beta.7",
|
|
201
|
+
"@elizaos/registry": "2.0.3-beta.7",
|
|
202
|
+
"@elizaos/shared": "2.0.3-beta.7",
|
|
203
|
+
"@elizaos/skills": "2.0.3-beta.7",
|
|
204
|
+
"@elizaos/ui": "2.0.3-beta.7",
|
|
205
|
+
"@elizaos/vault": "2.0.3-beta.7",
|
|
205
206
|
"@node-rs/argon2": "^2.0.2",
|
|
206
207
|
"@upstash/redis": "^1.37.0",
|
|
207
208
|
"chalk": "^5.3.0",
|
|
@@ -222,5 +223,5 @@
|
|
|
222
223
|
},
|
|
223
224
|
"module": "./index.js",
|
|
224
225
|
"types": "./index.d.ts",
|
|
225
|
-
"gitHead": "
|
|
226
|
+
"gitHead": "61094f10458d11055c75b3dd0bae374e3f66bac5"
|
|
226
227
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -178,6 +179,13 @@ const workspacePackagesRoot = fs.existsSync(
|
|
|
178
179
|
)
|
|
179
180
|
? path.join(repoRoot, "packages")
|
|
180
181
|
: path.join(repoRoot, "eliza", "packages");
|
|
182
|
+
const elizaWorkspaceRoot = path.dirname(workspacePackagesRoot);
|
|
183
|
+
const rmPathRecursiveScript = path.join(
|
|
184
|
+
elizaWorkspaceRoot,
|
|
185
|
+
"packages",
|
|
186
|
+
"scripts",
|
|
187
|
+
"rm-path-recursive.mjs",
|
|
188
|
+
);
|
|
181
189
|
const sharedSourceDir = path.join(workspacePackagesRoot, "shared", "src");
|
|
182
190
|
const coreNodeEntry = fs.existsSync(
|
|
183
191
|
path.join(workspacePackagesRoot, "core", "dist", "node", "index.node.js"),
|
|
@@ -216,7 +224,7 @@ function resolveRuntimeBundleSourcePath(rootDir: string): string {
|
|
|
216
224
|
".generated",
|
|
217
225
|
"runtime-dist",
|
|
218
226
|
);
|
|
219
|
-
|
|
227
|
+
rmRecursive(sanitizedDistPath);
|
|
220
228
|
fs.mkdirSync(sanitizedDistPath, { recursive: true });
|
|
221
229
|
for (const entry of fs.readdirSync(runtimeDistPath)) {
|
|
222
230
|
if (entry === "node_modules") continue;
|
|
@@ -232,6 +240,28 @@ function resolveRuntimeBundleSourcePath(rootDir: string): string {
|
|
|
232
240
|
return sanitizedDistPath;
|
|
233
241
|
}
|
|
234
242
|
|
|
243
|
+
function rmRecursive(pathToRemove: string): void {
|
|
244
|
+
const result = spawnSync(
|
|
245
|
+
process.execPath,
|
|
246
|
+
[rmPathRecursiveScript, path.resolve(pathToRemove)],
|
|
247
|
+
{
|
|
248
|
+
cwd: elizaWorkspaceRoot,
|
|
249
|
+
encoding: "utf8",
|
|
250
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
251
|
+
},
|
|
252
|
+
);
|
|
253
|
+
if (result.status !== 0) {
|
|
254
|
+
const reason =
|
|
255
|
+
result.stderr?.trim() ||
|
|
256
|
+
result.stdout?.trim() ||
|
|
257
|
+
result.error?.message ||
|
|
258
|
+
`exit status ${String(result.status)}`;
|
|
259
|
+
throw new Error(
|
|
260
|
+
`Failed to recursively remove sanitized Electrobun runtime dist ${pathToRemove}: ${reason}`,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
235
265
|
const runtimeBundleSourcePath = resolveRuntimeBundleSourcePath(repoRoot);
|
|
236
266
|
const runtimeBundleDistDir = path.relative(
|
|
237
267
|
electrobunDir,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/electrobun",
|
|
3
|
-
"version": "2.0.3-beta.
|
|
3
|
+
"version": "2.0.3-beta.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"assets",
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
"build:native-effects": "bash scripts/build-macos-effects.sh"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@elizaos/agent": "2.0.3-beta.
|
|
29
|
-
"@elizaos/app-core": "2.0.3-beta.
|
|
30
|
-
"@elizaos/plugin-browser": "2.0.3-beta.
|
|
31
|
-
"@elizaos/plugin-capacitor-bridge": "2.0.3-beta.
|
|
32
|
-
"@elizaos/plugin-registry": "2.0.3-beta.
|
|
33
|
-
"@elizaos/plugin-remote-manifest": "2.0.3-beta.
|
|
34
|
-
"@elizaos/plugin-streaming": "2.0.3-beta.
|
|
35
|
-
"@elizaos/shared": "2.0.3-beta.
|
|
28
|
+
"@elizaos/agent": "2.0.3-beta.7",
|
|
29
|
+
"@elizaos/app-core": "2.0.3-beta.7",
|
|
30
|
+
"@elizaos/plugin-browser": "2.0.3-beta.7",
|
|
31
|
+
"@elizaos/plugin-capacitor-bridge": "2.0.3-beta.7",
|
|
32
|
+
"@elizaos/plugin-registry": "2.0.3-beta.7",
|
|
33
|
+
"@elizaos/plugin-remote-manifest": "2.0.3-beta.7",
|
|
34
|
+
"@elizaos/plugin-streaming": "2.0.3-beta.7",
|
|
35
|
+
"@elizaos/shared": "2.0.3-beta.7",
|
|
36
36
|
"bonjour-service": "1.4.2",
|
|
37
37
|
"electrobun": "^1.18.1"
|
|
38
38
|
},
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "61094f10458d11055c75b3dd0bae374e3f66bac5"
|
|
50
50
|
}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase5-smoke.ts --outdir dist --target bun",
|
|
8
7
|
"smoke": "bun run src/dev/phase5-smoke.ts",
|
|
9
8
|
"smoke:phase5": "bun run src/dev/phase5-smoke.ts",
|
|
10
9
|
"typecheck": "tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM --types bun-types --allowImportingTsExtensions src/bun/protocol.ts src/bun/errors.ts src/bun/file-limits.ts src/bun/path-guard.ts src/bun/fs-service.ts src/bun/worker.ts src/dev/phase5-smoke.ts"
|
|
@@ -57,11 +57,10 @@ Each operation includes:
|
|
|
57
57
|
- `ELIZA_GIT_COMMAND_TIMEOUT_MS` defaults to `120000`
|
|
58
58
|
- `ELIZA_GIT_MAX_OPERATIONS` defaults to `200`
|
|
59
59
|
|
|
60
|
-
##
|
|
60
|
+
## Typecheck And Smoke
|
|
61
61
|
|
|
62
62
|
```sh
|
|
63
63
|
bun run --cwd elizalaunch/remotes/git typecheck
|
|
64
|
-
bun run --cwd elizalaunch/remotes/git build
|
|
65
64
|
bun run --cwd elizalaunch/remotes/git smoke
|
|
66
65
|
bun run --cwd elizalaunch/remotes/git smoke:phase7
|
|
67
66
|
```
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase7-smoke.ts --outdir dist --target bun",
|
|
8
7
|
"smoke": "bun run src/dev/phase7-smoke.ts",
|
|
9
8
|
"smoke:phase7": "bun run src/dev/phase7-smoke.ts",
|
|
10
9
|
"typecheck": "tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM --types bun-types --allowImportingTsExtensions src/bun/protocol.ts src/bun/errors.ts src/bun/operation-history.ts src/bun/git-command.ts src/bun/git-service.ts src/bun/worker.ts src/dev/phase7-smoke.ts"
|
|
@@ -94,7 +94,6 @@ The current route file does not expose direct local generation or direct embeddi
|
|
|
94
94
|
|
|
95
95
|
```sh
|
|
96
96
|
bun run --cwd elizalaunch/remotes/local-model typecheck
|
|
97
|
-
bun run --cwd elizalaunch/remotes/local-model build
|
|
98
97
|
bun run --cwd elizalaunch/remotes/local-model smoke
|
|
99
98
|
bun run --cwd elizalaunch/remotes/local-model smoke:phase8
|
|
100
99
|
```
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase8-smoke.ts --outdir dist --target bun",
|
|
8
7
|
"smoke": "bun run src/dev/phase8-smoke.ts",
|
|
9
8
|
"smoke:phase8": "bun run src/dev/phase8-smoke.ts",
|
|
10
9
|
"typecheck": "tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM --types bun-types --allowImportingTsExtensions src/bun/protocol.ts src/bun/errors.ts src/bun/eliza1-catalog.ts src/bun/hf-eliza1-client.ts src/bun/local-inference-api-client.ts src/bun/download-state.ts src/bun/model-service.ts src/bun/worker.ts src/dev/phase8-smoke.ts"
|
|
@@ -52,10 +52,9 @@ Output polling through `pty.session.output.tail` is sufficient for Phase 6 when
|
|
|
52
52
|
|
|
53
53
|
Session environment inherits `process.env` and merges per-session env overrides.
|
|
54
54
|
|
|
55
|
-
##
|
|
55
|
+
## Smoke
|
|
56
56
|
|
|
57
57
|
```sh
|
|
58
|
-
bun run --cwd elizalaunch/remotes/pty build
|
|
59
58
|
bun run --cwd elizalaunch/remotes/pty smoke
|
|
60
59
|
bun run --cwd elizalaunch/remotes/pty smoke:phase6
|
|
61
60
|
```
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase6-smoke.ts --outdir dist --target bun",
|
|
8
7
|
"smoke": "bun run src/dev/phase6-smoke.ts",
|
|
9
8
|
"smoke:phase6": "bun run src/dev/phase6-smoke.ts",
|
|
10
9
|
"typecheck": "tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM --types bun-types --allowImportingTsExtensions src/bun/protocol.ts src/bun/errors.ts src/bun/output-buffer.ts src/bun/pty-service.ts src/bun/worker.ts src/dev/phase6-smoke.ts"
|
|
@@ -206,11 +206,7 @@ Git:
|
|
|
206
206
|
|
|
207
207
|
## Run
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
```sh
|
|
212
|
-
bun run --cwd elizalaunch/remotes/runtime build
|
|
213
|
-
```
|
|
209
|
+
Remotes run from source (the runtime loads `src/bun/worker.ts` / `src/web/index.html` directly); there is no build step.
|
|
214
210
|
|
|
215
211
|
Phase 1 smoke:
|
|
216
212
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase1-smoke.ts src/dev/phase2-smoke.ts src/dev/phase3-smoke.ts --outdir dist --target bun",
|
|
8
7
|
"smoke": "bun src/dev/phase1-smoke.ts",
|
|
9
8
|
"smoke:phase1": "bun src/dev/phase1-smoke.ts",
|
|
10
9
|
"smoke:phase2": "bun src/dev/phase2-smoke.ts",
|
|
@@ -106,10 +106,9 @@ It consumes:
|
|
|
106
106
|
- `agent.message.stream.done`
|
|
107
107
|
- `agent.message.stream.cancelled`
|
|
108
108
|
|
|
109
|
-
##
|
|
109
|
+
## Smoke
|
|
110
110
|
|
|
111
111
|
```sh
|
|
112
|
-
bun run --cwd elizalaunch/remotes/surface build
|
|
113
112
|
bun run --cwd elizalaunch/remotes/surface smoke
|
|
114
113
|
bun run --cwd elizalaunch/remotes/surface smoke:phase4
|
|
115
114
|
```
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "bun build src/bun/worker.ts src/dev/phase4-smoke.ts --outdir dist --target bun && bun build src/web/index.ts --outdir dist/web --target browser",
|
|
8
7
|
"smoke": "bun run src/dev/phase4-smoke.ts",
|
|
9
8
|
"smoke:phase4": "bun run src/dev/phase4-smoke.ts",
|
|
10
9
|
"typecheck": "tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM,DOM.Iterable --types bun-types --allowImportingTsExtensions src/protocol/event-types.ts src/protocol/runtime-client.ts src/web/state.ts src/web/render.ts src/web/app.ts src/web/index.ts src/bun/worker.ts src/dev/phase4-smoke.ts"
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* Resolves the host app via the standard elizaOS layout; run after
|
|
10
10
|
* `bun run build:web` (or equivalent).
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { cp, mkdir, stat } from "node:fs/promises";
|
|
13
14
|
import path from "node:path";
|
|
14
15
|
import {
|
|
15
16
|
resolveElectrobunDir,
|
|
@@ -22,6 +23,12 @@ const appRoot = resolveMainAppDir(repoRoot, "app");
|
|
|
22
23
|
const electrobunRoot = resolveElectrobunDir(repoRoot);
|
|
23
24
|
const sourceDir = path.join(appRoot, "dist");
|
|
24
25
|
const targetDir = path.join(electrobunRoot, "app");
|
|
26
|
+
const rmPathRecursiveScript = path.join(
|
|
27
|
+
repoRoot,
|
|
28
|
+
"packages",
|
|
29
|
+
"scripts",
|
|
30
|
+
"rm-path-recursive.mjs",
|
|
31
|
+
);
|
|
25
32
|
const LOG_PREFIX = "[Electrobun]";
|
|
26
33
|
|
|
27
34
|
async function ensureDirExists(dir) {
|
|
@@ -33,6 +40,28 @@ async function ensureDirExists(dir) {
|
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
|
|
43
|
+
function rmRecursive(pathToRemove) {
|
|
44
|
+
const result = spawnSync(
|
|
45
|
+
process.execPath,
|
|
46
|
+
[rmPathRecursiveScript, path.resolve(pathToRemove)],
|
|
47
|
+
{
|
|
48
|
+
cwd: repoRoot,
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
if (result.status !== 0) {
|
|
54
|
+
const reason =
|
|
55
|
+
result.stderr?.trim() ||
|
|
56
|
+
result.stdout?.trim() ||
|
|
57
|
+
result.error?.message ||
|
|
58
|
+
`exit status ${String(result.status)}`;
|
|
59
|
+
throw new Error(
|
|
60
|
+
`${LOG_PREFIX} failed to recursively remove ${pathToRemove}: ${reason}`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
36
65
|
if (!(await ensureDirExists(sourceDir))) {
|
|
37
66
|
console.error(`${LOG_PREFIX} Web build output not found: ${sourceDir}`);
|
|
38
67
|
console.error(
|
|
@@ -41,7 +70,7 @@ if (!(await ensureDirExists(sourceDir))) {
|
|
|
41
70
|
process.exit(1);
|
|
42
71
|
}
|
|
43
72
|
|
|
44
|
-
|
|
73
|
+
rmRecursive(targetDir);
|
|
45
74
|
await mkdir(targetDir, { recursive: true });
|
|
46
75
|
await cp(sourceDir, targetDir, { recursive: true, force: true });
|
|
47
76
|
|
|
@@ -256,7 +256,11 @@ export function resolveRendererFacingApiBase(
|
|
|
256
256
|
*/
|
|
257
257
|
type ApiBaseUpdateRpc = {
|
|
258
258
|
send?: {
|
|
259
|
-
apiBaseUpdate?: (payload: {
|
|
259
|
+
apiBaseUpdate?: (payload: {
|
|
260
|
+
base: string;
|
|
261
|
+
token?: string;
|
|
262
|
+
externalApiBase?: string | null;
|
|
263
|
+
}) => void;
|
|
260
264
|
};
|
|
261
265
|
};
|
|
262
266
|
|
|
@@ -264,9 +268,14 @@ export function pushApiBaseToRenderer(
|
|
|
264
268
|
win: { webview: { rpc?: unknown } },
|
|
265
269
|
base: string,
|
|
266
270
|
apiToken?: string,
|
|
271
|
+
externalApiBase?: string | null,
|
|
267
272
|
): void {
|
|
268
273
|
const trimmedToken = apiToken?.trim();
|
|
269
|
-
const payload = {
|
|
274
|
+
const payload = {
|
|
275
|
+
base,
|
|
276
|
+
token: trimmedToken || undefined,
|
|
277
|
+
externalApiBase: externalApiBase ?? null,
|
|
278
|
+
};
|
|
270
279
|
try {
|
|
271
280
|
const rpcSend = (win.webview.rpc as ApiBaseUpdateRpc | undefined)?.send;
|
|
272
281
|
rpcSend?.apiBaseUpdate?.(payload);
|
|
@@ -63,8 +63,21 @@ ensureElectrobunGlobal();
|
|
|
63
63
|
|
|
64
64
|
function dispatchMessage(messageName: string, payload: unknown): void {
|
|
65
65
|
if (messageName === "apiBaseUpdate") {
|
|
66
|
-
const apiBaseUpdate = payload as {
|
|
66
|
+
const apiBaseUpdate = payload as {
|
|
67
|
+
base: string;
|
|
68
|
+
token?: string;
|
|
69
|
+
externalApiBase?: string | null;
|
|
70
|
+
};
|
|
67
71
|
window.__ELIZA_API_BASE__ = apiBaseUpdate.base;
|
|
72
|
+
if (
|
|
73
|
+
typeof apiBaseUpdate.externalApiBase === "string" &&
|
|
74
|
+
apiBaseUpdate.externalApiBase.trim()
|
|
75
|
+
) {
|
|
76
|
+
window.__ELIZA_DESKTOP_EXTERNAL_API_BASE__ =
|
|
77
|
+
apiBaseUpdate.externalApiBase.trim();
|
|
78
|
+
} else {
|
|
79
|
+
Reflect.deleteProperty(window, "__ELIZA_DESKTOP_EXTERNAL_API_BASE__");
|
|
80
|
+
}
|
|
68
81
|
if (apiBaseUpdate.token) {
|
|
69
82
|
Object.defineProperty(window, "__ELIZA_API_TOKEN__", {
|
|
70
83
|
value: apiBaseUpdate.token,
|
|
@@ -196,6 +209,7 @@ declare global {
|
|
|
196
209
|
interface Window {
|
|
197
210
|
__ELIZA_API_BASE__?: string;
|
|
198
211
|
__ELIZA_API_TOKEN__: string;
|
|
212
|
+
__ELIZA_DESKTOP_EXTERNAL_API_BASE__?: string;
|
|
199
213
|
__ELIZA_ELECTROBUN_RPC__?: typeof electrobunRpc;
|
|
200
214
|
}
|
|
201
215
|
}
|
|
@@ -34,7 +34,6 @@ import { getBrandConfig } from "./brand-config";
|
|
|
34
34
|
import { startBrowserWorkspaceBridgeServer } from "./browser-workspace-bridge-server";
|
|
35
35
|
import { readNavigationEventUrl } from "./cloud-auth-window";
|
|
36
36
|
import { readOpenUrlEventUrl } from "./desktop-deep-link-events";
|
|
37
|
-
import { shouldCreateDesktopPill } from "./desktop-pill-config";
|
|
38
37
|
import { startDesktopTestBridgeServer } from "./desktop-test-bridge-server";
|
|
39
38
|
import {
|
|
40
39
|
shouldCreateDesktopTray,
|
|
@@ -96,7 +95,6 @@ import {
|
|
|
96
95
|
getOnboardingOverlayWindow,
|
|
97
96
|
} from "./onboarding-overlay-window";
|
|
98
97
|
import { getPersistedDeployment } from "./persisted-deployment";
|
|
99
|
-
import { createPillWindow, getPillWindow } from "./pill-window";
|
|
100
98
|
import { printElectrobunDevSettingsBanner } from "./print-electrobun-dev-settings-banner";
|
|
101
99
|
import {
|
|
102
100
|
createRendererApiProxyRequestInit,
|
|
@@ -944,11 +942,32 @@ async function resolveRendererUrl(): Promise<string> {
|
|
|
944
942
|
return rendererUrl;
|
|
945
943
|
}
|
|
946
944
|
|
|
945
|
+
function appendApiBaseParam(rendererUrl: string, apiBase: string): string {
|
|
946
|
+
try {
|
|
947
|
+
const url = new URL(rendererUrl);
|
|
948
|
+
if (!url.searchParams.has("apiBase")) {
|
|
949
|
+
url.searchParams.set("apiBase", apiBase);
|
|
950
|
+
}
|
|
951
|
+
return url.toString();
|
|
952
|
+
} catch {
|
|
953
|
+
return rendererUrl;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
async function resolveRendererUrlForCurrentRuntime(): Promise<string> {
|
|
958
|
+
const rendererUrl = await resolveRendererUrl();
|
|
959
|
+
const runtime = resolveDesktopRuntime();
|
|
960
|
+
if (runtime.mode === "external" && runtime.externalApi.base) {
|
|
961
|
+
return appendApiBaseParam(rendererUrl, runtime.externalApi.base);
|
|
962
|
+
}
|
|
963
|
+
return rendererUrl;
|
|
964
|
+
}
|
|
965
|
+
|
|
947
966
|
async function createMainWindow(rpc: ElizaDesktopRpc): Promise<BrowserWindow> {
|
|
948
967
|
const kiosk = isKioskShellMode();
|
|
949
968
|
const rendererUrl = kiosk
|
|
950
|
-
? appendKioskShellModeParam(await
|
|
951
|
-
: await
|
|
969
|
+
? appendKioskShellModeParam(await resolveRendererUrlForCurrentRuntime())
|
|
970
|
+
: await resolveRendererUrlForCurrentRuntime();
|
|
952
971
|
const buildInfo = await BuildConfig.get();
|
|
953
972
|
const mainWindowPartition = resolveMainWindowPartition(process.env, {
|
|
954
973
|
platform: process.platform,
|
|
@@ -1251,7 +1270,7 @@ async function openOnboardingOverlayWindow(): Promise<BrowserWindow> {
|
|
|
1251
1270
|
return existing;
|
|
1252
1271
|
}
|
|
1253
1272
|
const { rpc } = createDesktopRpc("onboarding-overlay");
|
|
1254
|
-
const rendererUrl = await
|
|
1273
|
+
const rendererUrl = await resolveRendererUrlForCurrentRuntime();
|
|
1255
1274
|
let preload = "";
|
|
1256
1275
|
try {
|
|
1257
1276
|
preload = readResolvedPreloadScript(import.meta.dir);
|
|
@@ -1692,11 +1711,6 @@ function injectApiBaseIntoOpenRendererWindows(): void {
|
|
|
1692
1711
|
injectApiBase(currentWindow);
|
|
1693
1712
|
}
|
|
1694
1713
|
|
|
1695
|
-
const pillWindow = getPillWindow();
|
|
1696
|
-
if (pillWindow && pillWindow !== currentWindow) {
|
|
1697
|
-
injectApiBase(pillWindow);
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
1714
|
surfaceWindowManager?.forEachWindow((w) => {
|
|
1701
1715
|
injectApiBase(w as BrowserWindow);
|
|
1702
1716
|
});
|
|
@@ -1712,10 +1726,6 @@ function collectOpenRendererWindows(): BrowserWindow[] {
|
|
|
1712
1726
|
if (currentWindow) {
|
|
1713
1727
|
windows.push(currentWindow);
|
|
1714
1728
|
}
|
|
1715
|
-
const pillWindow = getPillWindow();
|
|
1716
|
-
if (pillWindow && pillWindow !== currentWindow) {
|
|
1717
|
-
windows.push(pillWindow);
|
|
1718
|
-
}
|
|
1719
1729
|
surfaceWindowManager?.forEachWindow((w) => {
|
|
1720
1730
|
windows.push(w as BrowserWindow);
|
|
1721
1731
|
});
|
|
@@ -2479,7 +2489,7 @@ async function main(): Promise<void> {
|
|
|
2479
2489
|
// The agent rebound to a different loopback port (or recovered from a
|
|
2480
2490
|
// crash) — the cookies we installed during _startAgent were scoped to
|
|
2481
2491
|
// the old origin. Re-prime so every renderer's next /api request stays
|
|
2482
|
-
// authenticated, including
|
|
2492
|
+
// authenticated, including any open secondary renderer windows.
|
|
2483
2493
|
markDesktopSessionStale();
|
|
2484
2494
|
const apiBase = `http://127.0.0.1:${status.port}`;
|
|
2485
2495
|
const rendererBase = resolveRendererFacingApiBase(
|
|
@@ -2617,19 +2627,6 @@ async function main(): Promise<void> {
|
|
|
2617
2627
|
/* non-fatal */
|
|
2618
2628
|
}
|
|
2619
2629
|
getFloatingChatManager().configure(url, preload);
|
|
2620
|
-
// In kiosk mode the chat pill lives in-canvas on the KioskShell, so we
|
|
2621
|
-
// never spawn the separate native pill toplevel. Outside kiosk, the pill
|
|
2622
|
-
// loads the same renderer in chat-overlay shell mode so the assistant
|
|
2623
|
-
// lives in its own OS-level window instead of inside the app.
|
|
2624
|
-
if (!isKioskShellMode() && shouldCreateDesktopPill()) {
|
|
2625
|
-
try {
|
|
2626
|
-
createPillWindow({ rendererUrl: url, preload });
|
|
2627
|
-
} catch (err) {
|
|
2628
|
-
logger.warn(
|
|
2629
|
-
`[Main] Failed to spawn pill window: ${err instanceof Error ? err.message : String(err)}`,
|
|
2630
|
-
);
|
|
2631
|
-
}
|
|
2632
|
-
}
|
|
2633
2630
|
});
|
|
2634
2631
|
|
|
2635
2632
|
// Per-window RPC tracking: surface windows each get their own typed
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
-
import {
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
getCurrent,
|
|
7
|
+
injectIntoHtml,
|
|
8
|
+
pushToWindow,
|
|
9
|
+
setCurrent,
|
|
10
|
+
} from "./api-base-owner";
|
|
6
11
|
|
|
7
12
|
const ENV_KEYS = [
|
|
13
|
+
"ELIZA_API_BASE",
|
|
14
|
+
"ELIZA_API_BASE_URL",
|
|
15
|
+
"ELIZA_DESKTOP_API_BASE",
|
|
16
|
+
"ELIZA_DESKTOP_CLOUD_AGENT_BASE",
|
|
17
|
+
"ELIZA_DESKTOP_CLOUD_ONLY",
|
|
18
|
+
"ELIZA_DESKTOP_RUNTIME_MODE",
|
|
19
|
+
"ELIZA_DESKTOP_SKIP_EMBEDDED_AGENT",
|
|
20
|
+
"ELIZA_DESKTOP_TEST_API_BASE",
|
|
8
21
|
"ELIZA_STARTUP_SESSION_ID",
|
|
9
22
|
"ELIZA_STARTUP_STATE_FILE",
|
|
10
23
|
"ELIZA_STARTUP_EVENTS_FILE",
|
|
@@ -17,12 +30,10 @@ let tempHome: string | null = null;
|
|
|
17
30
|
beforeEach(() => {
|
|
18
31
|
for (const key of ENV_KEYS) {
|
|
19
32
|
originalEnv.set(key, process.env[key]);
|
|
33
|
+
if (key !== "HOME") delete process.env[key];
|
|
20
34
|
}
|
|
21
35
|
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "eliza-api-base-owner-"));
|
|
22
36
|
process.env.HOME = tempHome;
|
|
23
|
-
delete process.env.ELIZA_STARTUP_SESSION_ID;
|
|
24
|
-
delete process.env.ELIZA_STARTUP_STATE_FILE;
|
|
25
|
-
delete process.env.ELIZA_STARTUP_EVENTS_FILE;
|
|
26
37
|
setCurrent(null);
|
|
27
38
|
});
|
|
28
39
|
|
|
@@ -80,4 +91,55 @@ describe("api-base-owner", () => {
|
|
|
80
91
|
expect(injected).toContain('"__ELIZA_API_TOKEN__"');
|
|
81
92
|
expect(injected).toContain("elizaos.app.boot-config");
|
|
82
93
|
});
|
|
94
|
+
|
|
95
|
+
it("marks a non-loopback current API base as an external desktop API base", () => {
|
|
96
|
+
setCurrent("https://agent.example.com", "cloud-token");
|
|
97
|
+
|
|
98
|
+
const injected = injectIntoHtml("<html><head></head><body></body></html>");
|
|
99
|
+
|
|
100
|
+
expect(injected).toContain(
|
|
101
|
+
'window.__ELIZA_API_BASE__="https://agent.example.com";',
|
|
102
|
+
);
|
|
103
|
+
expect(injected).toContain(
|
|
104
|
+
'window.__ELIZA_DESKTOP_EXTERNAL_API_BASE__="https://agent.example.com";',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("pushes the external desktop API base to already-open renderer windows", () => {
|
|
109
|
+
setCurrent("https://agent.example.com", "cloud-token");
|
|
110
|
+
const apiBaseUpdate = vi.fn();
|
|
111
|
+
|
|
112
|
+
pushToWindow({
|
|
113
|
+
webview: {
|
|
114
|
+
rpc: {
|
|
115
|
+
send: { apiBaseUpdate },
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(apiBaseUpdate).toHaveBeenCalledWith({
|
|
121
|
+
base: "https://agent.example.com",
|
|
122
|
+
token: "cloud-token",
|
|
123
|
+
externalApiBase: "https://agent.example.com",
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("does not mark loopback API bases as external", () => {
|
|
128
|
+
setCurrent("http://127.0.0.1:31337", "dev-token");
|
|
129
|
+
const apiBaseUpdate = vi.fn();
|
|
130
|
+
|
|
131
|
+
pushToWindow({
|
|
132
|
+
webview: {
|
|
133
|
+
rpc: {
|
|
134
|
+
send: { apiBaseUpdate },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
expect(apiBaseUpdate).toHaveBeenCalledWith({
|
|
140
|
+
base: "http://127.0.0.1:31337",
|
|
141
|
+
token: "dev-token",
|
|
142
|
+
externalApiBase: null,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
83
145
|
});
|