@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
|
@@ -1469,7 +1469,7 @@ function mirrorCapacitorWebPayloadIntoAndroidDir() {
|
|
|
1469
1469
|
fs.realpathSync(syncedAssets) === fs.realpathSync(targetAssets);
|
|
1470
1470
|
if (hasSyncedPublic && !sameTree) {
|
|
1471
1471
|
fs.mkdirSync(targetAssets, { recursive: true });
|
|
1472
|
-
|
|
1472
|
+
rmRecursive(targetPublic);
|
|
1473
1473
|
fs.cpSync(syncedPublic, targetPublic, { recursive: true });
|
|
1474
1474
|
for (const cfg of ["capacitor.config.json", "capacitor.plugins.json"]) {
|
|
1475
1475
|
const src = path.join(syncedAssets, cfg);
|
|
@@ -1508,10 +1508,7 @@ function mirrorCapacitorWebPayloadIntoAndroidDir() {
|
|
|
1508
1508
|
fs.existsSync(targetAssets)
|
|
1509
1509
|
) {
|
|
1510
1510
|
fs.mkdirSync(targetPublic, { recursive: true });
|
|
1511
|
-
|
|
1512
|
-
recursive: true,
|
|
1513
|
-
force: true,
|
|
1514
|
-
});
|
|
1511
|
+
rmRecursive(path.join(targetPublic, "assets"));
|
|
1515
1512
|
fs.cpSync(freshWeb, targetPublic, { recursive: true });
|
|
1516
1513
|
console.log(
|
|
1517
1514
|
`[mobile-build] Stale-web guard: overlaid fresh ${path.relative(repoRoot, freshWeb)} → ${path.relative(repoRoot, targetPublic)}`,
|
|
@@ -2536,7 +2533,7 @@ function removeStaleAndroidJavaSourceRoots(
|
|
|
2536
2533
|
shouldRemoveAndroidJavaSourceRoot(candidate, dstJava, protectedRoots) &&
|
|
2537
2534
|
fs.existsSync(candidate)
|
|
2538
2535
|
) {
|
|
2539
|
-
|
|
2536
|
+
rmRecursive(candidate);
|
|
2540
2537
|
}
|
|
2541
2538
|
}
|
|
2542
2539
|
}
|
|
@@ -3058,7 +3055,7 @@ function overlayAndroid({ includeAospRoleLaunchers = false } = {}) {
|
|
|
3058
3055
|
protectedJavaRoots,
|
|
3059
3056
|
)
|
|
3060
3057
|
) {
|
|
3061
|
-
|
|
3058
|
+
rmRecursive(staleJava);
|
|
3062
3059
|
}
|
|
3063
3060
|
}
|
|
3064
3061
|
fs.mkdirSync(dstJava, { recursive: true });
|
|
@@ -3135,7 +3132,7 @@ function overlayAndroid({ includeAospRoleLaunchers = false } = {}) {
|
|
|
3135
3132
|
path.resolve(srcJava) !== path.resolve(templateJava) &&
|
|
3136
3133
|
path.resolve(srcJava) !== path.resolve(dstJava)
|
|
3137
3134
|
) {
|
|
3138
|
-
|
|
3135
|
+
rmRecursive(srcJava);
|
|
3139
3136
|
}
|
|
3140
3137
|
console.log("[mobile-build] Overlaid Android Java sources.");
|
|
3141
3138
|
}
|
|
@@ -5166,7 +5163,7 @@ async function ensureIosLlamaCppVendoredFramework({
|
|
|
5166
5163
|
await ensureMtpIosTarget(simulatorTarget);
|
|
5167
5164
|
|
|
5168
5165
|
fs.mkdirSync(xcframeworksDir, { recursive: true });
|
|
5169
|
-
|
|
5166
|
+
rmRecursive(xcframeworkDir);
|
|
5170
5167
|
await run("node", [
|
|
5171
5168
|
IOS_XCFRAMEWORK_BUILD_SCRIPT,
|
|
5172
5169
|
"--output",
|
|
@@ -5197,7 +5194,7 @@ async function ensureIosLlamaCppVendoredFramework({
|
|
|
5197
5194
|
"ios",
|
|
5198
5195
|
`.${path.basename(stale, ".framework")}-stock-archive`,
|
|
5199
5196
|
);
|
|
5200
|
-
|
|
5197
|
+
rmRecursive(archived);
|
|
5201
5198
|
fs.renameSync(stale, archived);
|
|
5202
5199
|
console.log(
|
|
5203
5200
|
`[mobile-build] Archived stock npm framework: ${stale} -> ${archived} ` +
|
|
@@ -5532,7 +5529,7 @@ function stageIosFullBunEngineForPodspec(framework) {
|
|
|
5532
5529
|
console.log(
|
|
5533
5530
|
`[mobile-build] staging external iOS full Bun engine for CocoaPods: ${resolved} -> ${defaultIosBunEngineXcframework}`,
|
|
5534
5531
|
);
|
|
5535
|
-
|
|
5532
|
+
rmRecursive(defaultIosBunEngineXcframework);
|
|
5536
5533
|
fs.mkdirSync(path.dirname(defaultIosBunEngineXcframework), {
|
|
5537
5534
|
recursive: true,
|
|
5538
5535
|
});
|
|
@@ -6117,7 +6114,7 @@ export function removeInactiveAndroidJavaSourceRoots(javaRoots, activeRoot) {
|
|
|
6117
6114
|
if (resolved === active || seen.has(resolved)) continue;
|
|
6118
6115
|
seen.add(resolved);
|
|
6119
6116
|
if (!fs.existsSync(root)) continue;
|
|
6120
|
-
|
|
6117
|
+
rmRecursive(root);
|
|
6121
6118
|
removed += 1;
|
|
6122
6119
|
}
|
|
6123
6120
|
return removed;
|
|
@@ -6127,7 +6124,7 @@ function removeCloudNativeArtifacts() {
|
|
|
6127
6124
|
const assetsRoot = path.join(androidDir, "app", "src", "main", "assets");
|
|
6128
6125
|
const stagedAgentAssets = path.join(assetsRoot, "agent");
|
|
6129
6126
|
if (fs.existsSync(stagedAgentAssets)) {
|
|
6130
|
-
|
|
6127
|
+
rmRecursive(stagedAgentAssets);
|
|
6131
6128
|
console.log(
|
|
6132
6129
|
"[mobile-build] Removed staged on-device agent runtime under assets/agent/.",
|
|
6133
6130
|
);
|
|
@@ -7478,7 +7475,7 @@ function writeAndroidSystemProvenance(apkPath) {
|
|
|
7478
7475
|
);
|
|
7479
7476
|
}
|
|
7480
7477
|
} finally {
|
|
7481
|
-
|
|
7478
|
+
rmRecursive(tmpDir);
|
|
7482
7479
|
}
|
|
7483
7480
|
}
|
|
7484
7481
|
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { shouldCreateDesktopPill } from "./desktop-pill-config";
|
|
3
|
-
|
|
4
|
-
describe("desktop pill config", () => {
|
|
5
|
-
it("creates a pill window by default (voice surface)", () => {
|
|
6
|
-
expect(shouldCreateDesktopPill({})).toBe(true);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
it("supports an explicit enable flag", () => {
|
|
10
|
-
expect(shouldCreateDesktopPill({ ELIZA_DESKTOP_PILL: "1" })).toBe(true);
|
|
11
|
-
expect(shouldCreateDesktopPill({ ELIZA_DESKTOP_PILL: "true" })).toBe(true);
|
|
12
|
-
expect(shouldCreateDesktopPill({ ELIZA_DESKTOP_PILL: "yes" })).toBe(true);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("supports explicit negative and disable flags", () => {
|
|
16
|
-
expect(shouldCreateDesktopPill({ ELIZA_DESKTOP_PILL: "0" })).toBe(false);
|
|
17
|
-
expect(shouldCreateDesktopPill({ ELIZA_DESKTOP_PILL: "false" })).toBe(
|
|
18
|
-
false,
|
|
19
|
-
);
|
|
20
|
-
expect(
|
|
21
|
-
shouldCreateDesktopPill({
|
|
22
|
-
ELIZA_DESKTOP_PILL: "1",
|
|
23
|
-
ELIZA_DESKTOP_DISABLE_PILL: "1",
|
|
24
|
-
}),
|
|
25
|
-
).toBe(false);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
function parseTruthy(value: string | undefined): boolean {
|
|
2
|
-
const normalized = value?.trim().toLowerCase();
|
|
3
|
-
return normalized === "1" || normalized === "true" || normalized === "yes";
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
function parseFalsy(value: string | undefined): boolean {
|
|
7
|
-
const normalized = value?.trim().toLowerCase();
|
|
8
|
-
return normalized === "0" || normalized === "false" || normalized === "no";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Whether the floating voice-pill window should be created at startup.
|
|
13
|
-
*
|
|
14
|
-
* BEHAVIOR CHANGE (PR #8175): the pill window is now **on by default**.
|
|
15
|
-
* Previously `ELIZA_DESKTOP_PILL=1` was required to opt in; now all desktop
|
|
16
|
-
* users see the pill unless they explicitly opt out.
|
|
17
|
-
*
|
|
18
|
-
* Migration for existing users who did not set `ELIZA_DESKTOP_PILL`:
|
|
19
|
-
* - Before PR #8175: pill was hidden (opt-in OFF by default).
|
|
20
|
-
* - After PR #8175: pill is shown (opt-out, ON by default).
|
|
21
|
-
*
|
|
22
|
-
* To restore the previous hidden behaviour set either:
|
|
23
|
-
* ELIZA_DESKTOP_PILL=0 (standard off)
|
|
24
|
-
* ELIZA_DESKTOP_DISABLE_PILL=1 (legacy kill-switch; still respected)
|
|
25
|
-
*/
|
|
26
|
-
export function shouldCreateDesktopPill(
|
|
27
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
28
|
-
): boolean {
|
|
29
|
-
if (parseTruthy(env.ELIZA_DESKTOP_DISABLE_PILL)) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (parseFalsy(env.ELIZA_DESKTOP_PILL)) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Default on: the pill window is the primary voice surface. Users can
|
|
38
|
-
// suppress it with ELIZA_DESKTOP_PILL=0 or ELIZA_DESKTOP_DISABLE_PILL=1.
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const mocks = vi.hoisted(() => ({
|
|
4
|
-
createWindow: vi.fn(),
|
|
5
|
-
getPrimaryDisplay: vi.fn(),
|
|
6
|
-
info: vi.fn(),
|
|
7
|
-
warn: vi.fn(),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
vi.mock("electrobun/bun", () => ({
|
|
11
|
-
BrowserWindow: class BrowserWindow {},
|
|
12
|
-
Screen: {
|
|
13
|
-
getPrimaryDisplay: mocks.getPrimaryDisplay,
|
|
14
|
-
},
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
vi.mock("./electrobun-window-options", () => ({
|
|
18
|
-
createElectrobunBrowserWindow: mocks.createWindow,
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
|
-
vi.mock("./logger", () => ({
|
|
22
|
-
logger: {
|
|
23
|
-
debug: vi.fn(),
|
|
24
|
-
error: vi.fn(),
|
|
25
|
-
info: mocks.info,
|
|
26
|
-
success: vi.fn(),
|
|
27
|
-
warn: mocks.warn,
|
|
28
|
-
},
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
describe("pill window", () => {
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
vi.resetModules();
|
|
34
|
-
mocks.createWindow.mockReset();
|
|
35
|
-
mocks.getPrimaryDisplay.mockReset();
|
|
36
|
-
mocks.info.mockReset();
|
|
37
|
-
mocks.warn.mockReset();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("loads the OS pill into the live chat overlay shell route", async () => {
|
|
41
|
-
const { buildPillRendererUrl } = await import("./pill-window");
|
|
42
|
-
|
|
43
|
-
expect(buildPillRendererUrl("http://127.0.0.1:5174/home?old=1#hash")).toBe(
|
|
44
|
-
"http://127.0.0.1:5174/home?shellMode=chat-overlay",
|
|
45
|
-
);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("creates a bottom-centered transparent always-on-top window", async () => {
|
|
49
|
-
const closeHandlers: Array<() => void> = [];
|
|
50
|
-
const setAlwaysOnTop = vi.fn();
|
|
51
|
-
const windowMock = {
|
|
52
|
-
on: vi.fn((event: string, handler: () => void) => {
|
|
53
|
-
if (event === "close") closeHandlers.push(handler);
|
|
54
|
-
}),
|
|
55
|
-
setAlwaysOnTop,
|
|
56
|
-
};
|
|
57
|
-
mocks.createWindow.mockReturnValue(windowMock);
|
|
58
|
-
mocks.getPrimaryDisplay.mockReturnValue({
|
|
59
|
-
workArea: { x: 100, y: 50, width: 1600, height: 900 },
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const { createPillWindow, getPillWindow } = await import("./pill-window");
|
|
63
|
-
const win = createPillWindow({
|
|
64
|
-
rendererUrl: "http://127.0.0.1:5174/",
|
|
65
|
-
preload: "preload.js",
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
expect(win).toBe(windowMock);
|
|
69
|
-
expect(mocks.createWindow).toHaveBeenCalledWith(
|
|
70
|
-
expect.objectContaining({
|
|
71
|
-
title: "Eliza Pill",
|
|
72
|
-
url: "http://127.0.0.1:5174/?shellMode=chat-overlay",
|
|
73
|
-
preload: "preload.js",
|
|
74
|
-
titleBarStyle: "hidden",
|
|
75
|
-
transparent: true,
|
|
76
|
-
activate: false,
|
|
77
|
-
frame: {
|
|
78
|
-
x: 720,
|
|
79
|
-
y: 654,
|
|
80
|
-
width: 360,
|
|
81
|
-
height: 280,
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
);
|
|
85
|
-
expect(setAlwaysOnTop).toHaveBeenCalledWith(true);
|
|
86
|
-
expect(getPillWindow()).toBe(windowMock);
|
|
87
|
-
|
|
88
|
-
for (const handler of closeHandlers) handler();
|
|
89
|
-
expect(getPillWindow()).toBeNull();
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pill overlay window for Electrobun.
|
|
3
|
-
*
|
|
4
|
-
* Spawns a single borderless, transparent, always-on-top BrowserWindow
|
|
5
|
-
* docked to the bottom-center of the user's primary display. The window
|
|
6
|
-
* loads the same renderer bundle as the main shell with
|
|
7
|
-
* `?shellMode=chat-overlay`, which routes to the live assistant overlay shell.
|
|
8
|
-
*
|
|
9
|
-
* Lifecycle:
|
|
10
|
-
* - Created once at app boot, alongside the main window.
|
|
11
|
-
* - Closing the main window does NOT close the pill, and vice versa.
|
|
12
|
-
* - Quitting the app closes both (handled by Electrobun's standard
|
|
13
|
-
* `exitOnLastWindowClosed` behavior firing when both windows are gone,
|
|
14
|
-
* or by the application's quit menu).
|
|
15
|
-
*
|
|
16
|
-
* This is the persistent chat-overlay pill — created at app boot when
|
|
17
|
-
* shouldCreateDesktopPill() returns true (shellMode=chat-overlay). It is the
|
|
18
|
-
* live production voice/chat surface the user sees every day, rendering the
|
|
19
|
-
* ContinuousChatOverlay (NOT the old standalone VoicePill, which was removed).
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { type BrowserWindow, Screen } from "electrobun/bun";
|
|
23
|
-
import { createElectrobunBrowserWindow } from "./electrobun-window-options";
|
|
24
|
-
import { logger } from "./logger";
|
|
25
|
-
|
|
26
|
-
const PILL_WIDTH = 360;
|
|
27
|
-
const PILL_HEIGHT = 280;
|
|
28
|
-
const PILL_BOTTOM_MARGIN = 16;
|
|
29
|
-
|
|
30
|
-
interface PillWindowFrame {
|
|
31
|
-
x: number;
|
|
32
|
-
y: number;
|
|
33
|
-
width: number;
|
|
34
|
-
height: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function resolvePillFrame(): PillWindowFrame {
|
|
38
|
-
const display = Screen.getPrimaryDisplay();
|
|
39
|
-
const workArea = display.workArea;
|
|
40
|
-
return {
|
|
41
|
-
x: workArea.x + Math.round((workArea.width - PILL_WIDTH) / 2),
|
|
42
|
-
y: workArea.y + workArea.height - PILL_HEIGHT - PILL_BOTTOM_MARGIN,
|
|
43
|
-
width: PILL_WIDTH,
|
|
44
|
-
height: PILL_HEIGHT,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function buildPillRendererUrl(rendererUrl: string): string {
|
|
49
|
-
const url = new URL(rendererUrl);
|
|
50
|
-
url.search = "?shellMode=chat-overlay";
|
|
51
|
-
url.hash = "";
|
|
52
|
-
return url.toString();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let pillWindow: BrowserWindow | null = null;
|
|
56
|
-
|
|
57
|
-
export function createPillWindow(args: {
|
|
58
|
-
rendererUrl: string;
|
|
59
|
-
preload: string;
|
|
60
|
-
}): BrowserWindow {
|
|
61
|
-
if (pillWindow) {
|
|
62
|
-
return pillWindow;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const frame = resolvePillFrame();
|
|
66
|
-
const url = buildPillRendererUrl(args.rendererUrl);
|
|
67
|
-
|
|
68
|
-
const win = createElectrobunBrowserWindow({
|
|
69
|
-
title: "Eliza Pill",
|
|
70
|
-
url,
|
|
71
|
-
preload: args.preload,
|
|
72
|
-
frame,
|
|
73
|
-
titleBarStyle: "hidden",
|
|
74
|
-
transparent: true,
|
|
75
|
-
activate: false,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
win.setAlwaysOnTop(true);
|
|
80
|
-
} catch (err) {
|
|
81
|
-
logger.warn(
|
|
82
|
-
`[pill-window] setAlwaysOnTop failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
win.on("close", () => {
|
|
87
|
-
pillWindow = null;
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
pillWindow = win;
|
|
91
|
-
logger.info(
|
|
92
|
-
`[pill-window] Spawned pill overlay at (${frame.x},${frame.y}) ${frame.width}x${frame.height}`,
|
|
93
|
-
);
|
|
94
|
-
return win;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function getPillWindow(): BrowserWindow | null {
|
|
98
|
-
return pillWindow;
|
|
99
|
-
}
|