@beeos-ai/device-agent 0.7.2 → 0.8.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-runtime/skills/sqlite-store.d.ts +60 -0
- package/dist/agent-runtime/skills/sqlite-store.js +234 -0
- package/dist/agent-runtime/skills/sqlite-store.js.map +1 -0
- package/dist/bootstrap.js +11 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/config/loader.d.ts +4 -0
- package/dist/config/loader.js +18 -2
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +5 -0
- package/dist/config/schema.js +42 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/inbound/cli/main.js +12 -0
- package/dist/inbound/cli/main.js.map +1 -1
- package/dist/messaging/token-provider.d.ts +43 -0
- package/dist/messaging/token-provider.js +65 -0
- package/dist/messaging/token-provider.js.map +1 -0
- package/dist/plugins/message-bus/busy-reply.d.ts +39 -0
- package/dist/plugins/message-bus/busy-reply.js +30 -0
- package/dist/plugins/message-bus/busy-reply.js.map +1 -0
- package/dist/plugins/message-bus/inbound.d.ts +55 -0
- package/dist/plugins/message-bus/inbound.js +123 -0
- package/dist/plugins/message-bus/inbound.js.map +1 -0
- package/dist/plugins/message-bus/index.d.ts +147 -0
- package/dist/plugins/message-bus/index.js +392 -0
- package/dist/plugins/message-bus/index.js.map +1 -0
- package/dist/plugins/message-bus/outbound.d.ts +43 -0
- package/dist/plugins/message-bus/outbound.js +149 -0
- package/dist/plugins/message-bus/outbound.js.map +1 -0
- package/dist/plugins/message-bus/turn-context.d.ts +57 -0
- package/dist/plugins/message-bus/turn-context.js +53 -0
- package/dist/plugins/message-bus/turn-context.js.map +1 -0
- package/dist/test-lan-autoglm.d.ts +7 -0
- package/dist/test-lan-autoglm.js +46 -0
- package/dist/test-lan-autoglm.js.map +1 -0
- package/dist/test-mem-breakdown.d.ts +1 -0
- package/dist/test-mem-breakdown.js +103 -0
- package/dist/test-mem-breakdown.js.map +1 -0
- package/dist/test-mem.d.ts +1 -0
- package/dist/test-mem.js +60 -0
- package/dist/test-mem.js.map +1 -0
- package/dist/test-mobile-use.d.ts +1 -0
- package/dist/test-mobile-use.js +18 -0
- package/dist/test-mobile-use.js.map +1 -0
- package/dist/test-screenshot-loop.d.ts +1 -0
- package/dist/test-screenshot-loop.js +43 -0
- package/dist/test-screenshot-loop.js.map +1 -0
- package/dist/test-screenshot.d.ts +1 -0
- package/dist/test-screenshot.js +10 -0
- package/dist/test-screenshot.js.map +1 -0
- package/dist/test-ui-xml-dump.d.ts +15 -0
- package/dist/test-ui-xml-dump.js +49 -0
- package/dist/test-ui-xml-dump.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-flight Message-Service turn register.
|
|
3
|
+
*
|
|
4
|
+
* Holds the channel + reply correlator for the SINGLE turn that's
|
|
5
|
+
* currently executing on the host. Single-entry by design — device-agent
|
|
6
|
+
* runs one ACP session and the SessionManager serialises turns inside
|
|
7
|
+
* that session, so a second concurrent `chat_message` would be a logic
|
|
8
|
+
* error and is rejected via `busy-reply.ts`.
|
|
9
|
+
*
|
|
10
|
+
* The taskId is allocated by `host.submitTask(...)` and used to filter
|
|
11
|
+
* the `host.on(listener)` event stream so we never publish another
|
|
12
|
+
* turn's deltas to the wrong MS channel.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Single-entry in-flight register.
|
|
16
|
+
*
|
|
17
|
+
* Methods are intentionally synchronous — they run on the WS publication
|
|
18
|
+
* callback (low latency) and on AgentHost listener invocations.
|
|
19
|
+
*/
|
|
20
|
+
export class TurnContextRegister {
|
|
21
|
+
current = null;
|
|
22
|
+
isBusy() {
|
|
23
|
+
return this.current !== null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Claim the register for a new turn. Returns the entry on success or
|
|
27
|
+
* `null` when a previous turn is still in flight (caller MUST then
|
|
28
|
+
* use the busy-reply path).
|
|
29
|
+
*/
|
|
30
|
+
claim(entry) {
|
|
31
|
+
if (this.current)
|
|
32
|
+
return null;
|
|
33
|
+
this.current = { ...entry, startedAt: Date.now() };
|
|
34
|
+
return this.current;
|
|
35
|
+
}
|
|
36
|
+
current_() {
|
|
37
|
+
return this.current;
|
|
38
|
+
}
|
|
39
|
+
getByTaskId(taskId) {
|
|
40
|
+
return this.current && this.current.taskId === taskId ? this.current : null;
|
|
41
|
+
}
|
|
42
|
+
/** Idempotent — clearing twice is a no-op. */
|
|
43
|
+
clear(taskId) {
|
|
44
|
+
if (this.current && this.current.taskId === taskId) {
|
|
45
|
+
this.current = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Force-clear (used during plugin stop / disconnect). */
|
|
49
|
+
reset() {
|
|
50
|
+
this.current = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=turn-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-context.js","sourceRoot":"","sources":["../../../src/plugins/message-bus/turn-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAyBH;;;;;GAKG;AACH,MAAM,OAAO,mBAAmB;IACtB,OAAO,GAAgC,IAAI,CAAC;IAEpD,MAAM;QACJ,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAA8C;QAClD,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,MAAc;QAClB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 验证局域网 OpenAI 兼容 AutoGLM 与 device-agent-ts 内层链路(adapter=autoglm + OpenAIClient)。
|
|
3
|
+
* 需要:adb 已连机、本机可访问 GUI_AGENT_BASE_URL、.env 已配置。
|
|
4
|
+
*
|
|
5
|
+
* npx tsx src/test-lan-autoglm.ts
|
|
6
|
+
*/
|
|
7
|
+
import "dotenv/config";
|
|
8
|
+
import { AndroidDevice } from "./device/android.js";
|
|
9
|
+
import { OpenAIClient } from "./model/client.js";
|
|
10
|
+
const TASK = process.env.LAN_VLM_SMOKE_TASK ??
|
|
11
|
+
"看当前截图,只输出一行下一步操作(不要复述用户原话里的示例代码):用 do(action=\"Tap\", element=[x,y]) 点击你认为该点的位置,坐标 0–1000。";
|
|
12
|
+
async function main() {
|
|
13
|
+
const base = process.env.GUI_AGENT_BASE_URL ?? "";
|
|
14
|
+
const model = process.env.GUI_AGENT_MODEL ?? "";
|
|
15
|
+
if (!base || !model) {
|
|
16
|
+
console.error("请设置 GUI_AGENT_BASE_URL、GUI_AGENT_MODEL(及 API_KEY)");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
console.log(`[lan-autoglm] base=${base} model=${model} adapter=${process.env.GUI_AGENT_ADAPTER ?? "(auto)"} stream=${process.env.GUI_AGENT_STREAM ?? "1"}`);
|
|
20
|
+
const device = new AndroidDevice(process.env.GUI_AGENT_DEVICE_ID ?? undefined);
|
|
21
|
+
const ss = await device.takeScreenshot();
|
|
22
|
+
const currentApp = await device.getCurrentApp();
|
|
23
|
+
const client = new OpenAIClient({
|
|
24
|
+
adapter: process.env.GUI_AGENT_ADAPTER ?? "autoglm",
|
|
25
|
+
});
|
|
26
|
+
const screenInfo = {
|
|
27
|
+
screenshotB64: ss.base64Data,
|
|
28
|
+
width: ss.width,
|
|
29
|
+
height: ss.height,
|
|
30
|
+
currentApp,
|
|
31
|
+
uiXml: null,
|
|
32
|
+
};
|
|
33
|
+
const messages = client.buildMessages(TASK, screenInfo, [], true, (process.env.GUI_AGENT_LANG ?? "cn"));
|
|
34
|
+
console.log(`[lan-autoglm] requesting… (${messages.length} messages, jpeg b64 ~${Math.round(ss.base64Data.length / 1024)} KB)`);
|
|
35
|
+
const t0 = Date.now();
|
|
36
|
+
const resp = await client.request(messages, true);
|
|
37
|
+
const ms = Date.now() - t0;
|
|
38
|
+
console.log("\n--- raw (prefix) ---\n", resp.rawContent.slice(0, 1500), resp.rawContent.length > 1500 ? "\n…" : "");
|
|
39
|
+
console.log("\n--- parsed ---\n", JSON.stringify(client.parseResponse(resp.rawContent), null, 2));
|
|
40
|
+
console.log(`\n[lan-autoglm] ok in ${ms} ms`);
|
|
41
|
+
}
|
|
42
|
+
main().catch((e) => {
|
|
43
|
+
console.error(e);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=test-lan-autoglm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-lan-autoglm.js","sourceRoot":"","sources":["../src/test-lan-autoglm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
// Memory diagnostic: peel back each layer to see where the 200MB goes.
|
|
3
|
+
// Run with: npx tsx --expose-gc src/test-mem-breakdown.ts
|
|
4
|
+
function mb(n) { return (n / 1024 / 1024).toFixed(1); }
|
|
5
|
+
function rss() { return process.memoryUsage().rss; }
|
|
6
|
+
function heap() { return process.memoryUsage().heapUsed; }
|
|
7
|
+
function ext() { return process.memoryUsage().external; }
|
|
8
|
+
function snap(label, baseline) {
|
|
9
|
+
const m = process.memoryUsage();
|
|
10
|
+
const delta = baseline !== undefined ? ` (Δrss=${mb(m.rss - baseline)}MB)` : "";
|
|
11
|
+
console.log(`[${label.padEnd(28)}] rss=${mb(m.rss)}MB heap=${mb(m.heapUsed)}MB ext=${mb(m.external)}MB${delta}`);
|
|
12
|
+
return m.rss;
|
|
13
|
+
}
|
|
14
|
+
async function waitGc() {
|
|
15
|
+
if (global.gc) {
|
|
16
|
+
global.gc();
|
|
17
|
+
global.gc();
|
|
18
|
+
}
|
|
19
|
+
await new Promise(r => setTimeout(r, 50));
|
|
20
|
+
}
|
|
21
|
+
console.log("=".repeat(78));
|
|
22
|
+
console.log("Memory Breakdown Diagnostic");
|
|
23
|
+
console.log("=".repeat(78));
|
|
24
|
+
// ── Layer 0: bare node ──────────────────────────────────────────────────────
|
|
25
|
+
const bare = snap("0. bare node (tsx loader)");
|
|
26
|
+
// ── Layer 1: dotenv + types (already loaded at top, but measure current) ────
|
|
27
|
+
const l1 = snap("1. + dotenv", bare);
|
|
28
|
+
// ── Layer 2: load openai SDK ────────────────────────────────────────────────
|
|
29
|
+
await import("openai");
|
|
30
|
+
const l2 = snap("2. + openai sdk", l1);
|
|
31
|
+
// ── Layer 3: load sharp (triggers libvips mmap) ─────────────────────────────
|
|
32
|
+
const sharpMod = await import("sharp");
|
|
33
|
+
const l3 = snap("3. + sharp (libvips mmap)", l2);
|
|
34
|
+
// ── Layer 4: load our Device layer ──────────────────────────────────────────
|
|
35
|
+
const { AndroidDevice } = await import("./device/android.js");
|
|
36
|
+
const l4 = snap("4. + device/android", l3);
|
|
37
|
+
// ── Layer 5: instantiate device + check adb exists ──────────────────────────
|
|
38
|
+
const dev = new AndroidDevice(process.env.GUI_AGENT_DEVICE_ID);
|
|
39
|
+
const l5 = snap("5. + new AndroidDevice()", l4);
|
|
40
|
+
// ── Layer 6: load agent + model adapters ────────────────────────────────────
|
|
41
|
+
const { Agent } = await import("./agent.js");
|
|
42
|
+
const { OpenAIClient } = await import("./model/client.js");
|
|
43
|
+
await import("./model/adapters/index.js");
|
|
44
|
+
const l6 = snap("6. + agent + all adapters", l5);
|
|
45
|
+
// ── Layer 7: instantiate model client (openai client w/ keep-alive) ─────────
|
|
46
|
+
const client = new OpenAIClient({ adapter: process.env.GUI_AGENT_ADAPTER });
|
|
47
|
+
const l7 = snap("7. + new OpenAIClient()", l6);
|
|
48
|
+
// ── Layer 8: take one screenshot (triggers sharp pipeline + buffer) ─────────
|
|
49
|
+
await dev.takeScreenshot();
|
|
50
|
+
await waitGc();
|
|
51
|
+
const l8 = snap("8. + 1 screenshot (post-gc)", l7);
|
|
52
|
+
// ── Layer 9: take 5 screenshots back-to-back ────────────────────────────────
|
|
53
|
+
let peak9 = l8;
|
|
54
|
+
for (let i = 0; i < 5; i++) {
|
|
55
|
+
await dev.takeScreenshot();
|
|
56
|
+
peak9 = Math.max(peak9, rss());
|
|
57
|
+
}
|
|
58
|
+
await waitGc();
|
|
59
|
+
const l9 = snap("9. + 5 screenshots (post-gc)", l8);
|
|
60
|
+
console.log(` └─ intra-loop peak rss=${mb(peak9)}MB`);
|
|
61
|
+
// ── Layer 10: instantiate agent ─────────────────────────────────────────────
|
|
62
|
+
const agent = new Agent(client, dev, { maxSteps: 3, verbose: false });
|
|
63
|
+
const l10 = snap("10. + new Agent()", l9);
|
|
64
|
+
// ── Layer 11: run 1 full agent step (includes API call if connected) ────────
|
|
65
|
+
let peak11 = l10;
|
|
66
|
+
const before = rss();
|
|
67
|
+
try {
|
|
68
|
+
await agent.run("打开系统设置");
|
|
69
|
+
peak11 = Math.max(peak11, rss());
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
// ignore — we just want memory delta
|
|
73
|
+
}
|
|
74
|
+
await waitGc();
|
|
75
|
+
const l11 = snap("11. + agent.run() (post-gc)", l10);
|
|
76
|
+
console.log(` └─ intra-run peak rss=${mb(peak11)}MB (Δ from pre-run=${mb(peak11 - before)}MB)`);
|
|
77
|
+
// ── Summary ─────────────────────────────────────────────────────────────────
|
|
78
|
+
console.log("=".repeat(78));
|
|
79
|
+
console.log("Component Breakdown (incremental RSS additions, MB)");
|
|
80
|
+
console.log("=".repeat(78));
|
|
81
|
+
const rows = [
|
|
82
|
+
["Node.js + tsx loader baseline", bare],
|
|
83
|
+
["+ dotenv", l1 - bare],
|
|
84
|
+
["+ openai SDK", l2 - l1],
|
|
85
|
+
["+ sharp (libvips native mmap)", l3 - l2],
|
|
86
|
+
["+ device layer (adb client)", l4 - l3],
|
|
87
|
+
["+ AndroidDevice instance", l5 - l4],
|
|
88
|
+
["+ agent + all model adapters", l6 - l5],
|
|
89
|
+
["+ OpenAI client (keep-alive pool)", l7 - l6],
|
|
90
|
+
["+ first screenshot (warm cache)", l8 - l7],
|
|
91
|
+
["+ 4 more screenshots", l9 - l8],
|
|
92
|
+
["+ Agent instance", l10 - l9],
|
|
93
|
+
["+ agent.run() full cycle", l11 - l10],
|
|
94
|
+
];
|
|
95
|
+
for (const [label, delta] of rows) {
|
|
96
|
+
console.log(` ${label.padEnd(42)} ${(delta / 1024 / 1024).toFixed(1).padStart(6)} MB`);
|
|
97
|
+
}
|
|
98
|
+
console.log("-".repeat(78));
|
|
99
|
+
console.log(` TOTAL steady-state RSS: ${mb(l11).padStart(6)} MB`);
|
|
100
|
+
console.log(` Peak RSS during run: ${mb(peak11).padStart(6)} MB (transient request buffer)`);
|
|
101
|
+
console.log("=".repeat(78));
|
|
102
|
+
process.exit(0);
|
|
103
|
+
//# sourceMappingURL=test-mem-breakdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-mem-breakdown.js","sourceRoot":"","sources":["../src/test-mem-breakdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "dotenv/config";
|
package/dist/test-mem.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { mobileUse } from "./api.js";
|
|
3
|
+
const task = process.env.TASK ?? "打开系统设置,告诉我 Android 版本号";
|
|
4
|
+
const samples = [];
|
|
5
|
+
const start = Date.now();
|
|
6
|
+
function snap() {
|
|
7
|
+
const m = process.memoryUsage();
|
|
8
|
+
return {
|
|
9
|
+
t: Date.now() - start,
|
|
10
|
+
rss: m.rss,
|
|
11
|
+
heapUsed: m.heapUsed,
|
|
12
|
+
heapTotal: m.heapTotal,
|
|
13
|
+
external: m.external,
|
|
14
|
+
arrayBuffers: m.arrayBuffers,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function fmt(n) { return (n / 1024 / 1024).toFixed(1); }
|
|
18
|
+
function logSample(label, s) {
|
|
19
|
+
console.log(`[mem t=${(s.t / 1000).toFixed(1)}s ${label.padEnd(12)}] ` +
|
|
20
|
+
`rss=${fmt(s.rss)}MB heapUsed=${fmt(s.heapUsed)}MB heapTotal=${fmt(s.heapTotal)}MB ` +
|
|
21
|
+
`ext=${fmt(s.external)}MB arrBuf=${fmt(s.arrayBuffers)}MB`);
|
|
22
|
+
}
|
|
23
|
+
const initial = snap();
|
|
24
|
+
logSample("init", initial);
|
|
25
|
+
// 200ms sampling loop in background
|
|
26
|
+
const interval = setInterval(() => samples.push(snap()), 200);
|
|
27
|
+
interval.unref();
|
|
28
|
+
console.log(`[test-mobile-use] task = ${task}`);
|
|
29
|
+
console.log("=".repeat(70));
|
|
30
|
+
mobileUse(task)
|
|
31
|
+
.then((result) => {
|
|
32
|
+
const done = snap();
|
|
33
|
+
console.log("=".repeat(70));
|
|
34
|
+
logSample("done", done);
|
|
35
|
+
// Stats
|
|
36
|
+
if (global.gc) {
|
|
37
|
+
global.gc();
|
|
38
|
+
}
|
|
39
|
+
const afterGc = snap();
|
|
40
|
+
if (global.gc)
|
|
41
|
+
logSample("post-gc", afterGc);
|
|
42
|
+
const peakRss = samples.reduce((m, s) => Math.max(m, s.rss), initial.rss);
|
|
43
|
+
const peakHeap = samples.reduce((m, s) => Math.max(m, s.heapUsed), initial.heapUsed);
|
|
44
|
+
const peakExt = samples.reduce((m, s) => Math.max(m, s.external), initial.external);
|
|
45
|
+
console.log("-".repeat(70));
|
|
46
|
+
console.log(`[summary] samples=${samples.length} over ${(done.t / 1000).toFixed(1)}s`);
|
|
47
|
+
console.log(`[summary] peak rss = ${fmt(peakRss)} MB`);
|
|
48
|
+
console.log(`[summary] peak heapUsed = ${fmt(peakHeap)} MB`);
|
|
49
|
+
console.log(`[summary] peak external = ${fmt(peakExt)} MB (sharp native buffers live here)`);
|
|
50
|
+
console.log(`[summary] growth: rss ${fmt(done.rss - initial.rss)} MB, heapUsed ${fmt(done.heapUsed - initial.heapUsed)} MB`);
|
|
51
|
+
console.log("\n[result]", result);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
})
|
|
54
|
+
.catch((e) => {
|
|
55
|
+
const done = snap();
|
|
56
|
+
logSample("error", done);
|
|
57
|
+
console.error("[test-mobile-use] error:", e);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=test-mem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-mem.js","sourceRoot":"","sources":["../src/test-mem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { mobileUse } from "./api.js";
|
|
3
|
+
const task = process.env.TASK ?? "打开系统设置,然后告诉我 Android 版本号是多少";
|
|
4
|
+
const maxSteps = parseInt(process.env.GUI_AGENT_MAX_STEPS ?? "30", 10);
|
|
5
|
+
console.log(`[test-mobile-use] task = ${task}`);
|
|
6
|
+
console.log("=".repeat(60));
|
|
7
|
+
mobileUse(task, maxSteps)
|
|
8
|
+
.then((result) => {
|
|
9
|
+
console.log("=".repeat(60));
|
|
10
|
+
console.log("[test-mobile-use] result:", result);
|
|
11
|
+
process.exit(0);
|
|
12
|
+
})
|
|
13
|
+
.catch((e) => {
|
|
14
|
+
console.error("=".repeat(60));
|
|
15
|
+
console.error("[test-mobile-use] error:", e);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=test-mobile-use.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-mobile-use.js","sourceRoot":"","sources":["../src/test-mobile-use.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,6BAA6B,CAAC;AAC/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;AAEvE,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;AAChD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAE5B,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;KACtB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;IACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACX,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { AndroidDevice } from "./device/android.js";
|
|
3
|
+
const ITER = parseInt(process.env.ITER ?? "100", 10);
|
|
4
|
+
const dev = new AndroidDevice(process.env.GUI_AGENT_DEVICE_ID);
|
|
5
|
+
function fmt(n) { return (n / 1024 / 1024).toFixed(1); }
|
|
6
|
+
function snap(label, extra = "") {
|
|
7
|
+
const m = process.memoryUsage();
|
|
8
|
+
console.log(`[${label.padEnd(20)}] rss=${fmt(m.rss)}MB heap=${fmt(m.heapUsed)}/${fmt(m.heapTotal)}MB ` +
|
|
9
|
+
`ext=${fmt(m.external)}MB arrBuf=${fmt(m.arrayBuffers)}MB ${extra}`);
|
|
10
|
+
}
|
|
11
|
+
snap("boot");
|
|
12
|
+
// Prime sharp / adb
|
|
13
|
+
await dev.takeScreenshot();
|
|
14
|
+
snap("after 1 ss");
|
|
15
|
+
let totalB64 = 0;
|
|
16
|
+
let maxRss = 0;
|
|
17
|
+
const t0 = Date.now();
|
|
18
|
+
for (let i = 0; i < ITER; i++) {
|
|
19
|
+
const ss = await dev.takeScreenshot();
|
|
20
|
+
totalB64 += ss.base64Data.length;
|
|
21
|
+
const rss = process.memoryUsage().rss;
|
|
22
|
+
if (rss > maxRss)
|
|
23
|
+
maxRss = rss;
|
|
24
|
+
if (i % 10 === 9) {
|
|
25
|
+
snap(`iter ${i + 1}`, `avg b64=${Math.round(totalB64 / (i + 1) / 1024)}KB`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const dur = (Date.now() - t0) / 1000;
|
|
29
|
+
console.log("-".repeat(70));
|
|
30
|
+
console.log(`[result] iterations=${ITER}, total ${dur.toFixed(1)}s, avg ${(dur * 1000 / ITER).toFixed(0)}ms/screenshot`);
|
|
31
|
+
console.log(`[result] avg base64 length = ${Math.round(totalB64 / ITER / 1024)} KB`);
|
|
32
|
+
console.log(`[result] peak RSS observed = ${fmt(maxRss)} MB`);
|
|
33
|
+
snap("before gc");
|
|
34
|
+
if (global.gc) {
|
|
35
|
+
global.gc();
|
|
36
|
+
global.gc();
|
|
37
|
+
}
|
|
38
|
+
snap("after gc");
|
|
39
|
+
// Wait a bit for native to release
|
|
40
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
41
|
+
snap("after +1s wait");
|
|
42
|
+
process.exit(0);
|
|
43
|
+
//# sourceMappingURL=test-screenshot-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-screenshot-loop.js","sourceRoot":"","sources":["../src/test-screenshot-loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { AndroidDevice } from "./device/android.js";
|
|
3
|
+
const dev = new AndroidDevice(process.env.GUI_AGENT_DEVICE_ID);
|
|
4
|
+
const t0 = Date.now();
|
|
5
|
+
const ss = await dev.takeScreenshot();
|
|
6
|
+
const t1 = Date.now();
|
|
7
|
+
console.log(`screen w=${ss.width} h=${ss.height}`);
|
|
8
|
+
console.log(`base64 length=${ss.base64Data.length} (~${Math.round(ss.base64Data.length * 3 / 4 / 1024)} KB binary)`);
|
|
9
|
+
console.log(`elapsed=${t1 - t0}ms`);
|
|
10
|
+
//# sourceMappingURL=test-screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-screenshot.js","sourceRoot":"","sources":["../src/test-screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,GAAG,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAC/D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACtB,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,cAAc,EAAE,CAAC;AACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACtB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;AACnD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;AACrH,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dump current-screen UI XML for debugging `ui_xml` parsing.
|
|
3
|
+
*
|
|
4
|
+
* Writes under `.debug/ui-xml-dumps/` (override with UI_XML_DUMP_DIR):
|
|
5
|
+
* - `<stamp>-raw.xml` — full uiautomator dump (no truncation)
|
|
6
|
+
* - `<stamp>-tool.txt` — exact string `ui_xml` would return (same truncation / JSON rules)
|
|
7
|
+
* - `<stamp>-parsed.json` — `{ query, nodes }` from {@link searchUiXmlNodes}
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx tsx src/test-ui-xml-dump.ts # query = "" → parsed.json lists all nodes (can be large)
|
|
11
|
+
* npx tsx src/test-ui-xml-dump.ts 设置 # filter substring
|
|
12
|
+
*
|
|
13
|
+
* Requires adb + device (GUI_AGENT_DEVICE_ID if multiple).
|
|
14
|
+
*/
|
|
15
|
+
import "dotenv/config";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dump current-screen UI XML for debugging `ui_xml` parsing.
|
|
3
|
+
*
|
|
4
|
+
* Writes under `.debug/ui-xml-dumps/` (override with UI_XML_DUMP_DIR):
|
|
5
|
+
* - `<stamp>-raw.xml` — full uiautomator dump (no truncation)
|
|
6
|
+
* - `<stamp>-tool.txt` — exact string `ui_xml` would return (same truncation / JSON rules)
|
|
7
|
+
* - `<stamp>-parsed.json` — `{ query, nodes }` from {@link searchUiXmlNodes}
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx tsx src/test-ui-xml-dump.ts # query = "" → parsed.json lists all nodes (can be large)
|
|
11
|
+
* npx tsx src/test-ui-xml-dump.ts 设置 # filter substring
|
|
12
|
+
*
|
|
13
|
+
* Requires adb + device (GUI_AGENT_DEVICE_ID if multiple).
|
|
14
|
+
*/
|
|
15
|
+
import "dotenv/config";
|
|
16
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { AndroidDevice } from "./device/android.js";
|
|
19
|
+
import { formatUiXmlToolOutput, searchUiXmlNodes } from "./device/ui-xml.js";
|
|
20
|
+
const OUT_DIR = process.env.UI_XML_DUMP_DIR ?? join(process.cwd(), ".debug", "ui-xml-dumps");
|
|
21
|
+
function stamp() {
|
|
22
|
+
return new Date().toISOString().replace(/[:.]/g, "-");
|
|
23
|
+
}
|
|
24
|
+
async function main() {
|
|
25
|
+
const query = process.argv.slice(2).join(" ").trim();
|
|
26
|
+
const device = new AndroidDevice(process.env.GUI_AGENT_DEVICE_ID ?? undefined);
|
|
27
|
+
const xml = await device.getUiXml();
|
|
28
|
+
if (!xml) {
|
|
29
|
+
console.error("Failed to read UI XML (adb / uiautomator). Check device connection.");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
mkdirSync(OUT_DIR, { recursive: true });
|
|
33
|
+
const id = stamp();
|
|
34
|
+
const base = join(OUT_DIR, id);
|
|
35
|
+
writeFileSync(`${base}-raw.xml`, xml, "utf-8");
|
|
36
|
+
const toolText = formatUiXmlToolOutput(xml, query || undefined);
|
|
37
|
+
writeFileSync(`${base}-tool.txt`, toolText, "utf-8");
|
|
38
|
+
const nodes = searchUiXmlNodes(xml, query);
|
|
39
|
+
writeFileSync(`${base}-parsed.json`, `${JSON.stringify({ query: query || null, nodeCount: nodes.length, nodes }, null, 2)}\n`, "utf-8");
|
|
40
|
+
console.log(`Wrote:
|
|
41
|
+
${base}-raw.xml (${xml.length} chars)
|
|
42
|
+
${base}-tool.txt (${toolText.length} chars, same as ui_xml tool output)
|
|
43
|
+
${base}-parsed.json (${nodes.length} nodes${query ? `, query=${JSON.stringify(query)}` : ", query=null (all nodes)"})`);
|
|
44
|
+
}
|
|
45
|
+
main().catch((e) => {
|
|
46
|
+
console.error(e);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=test-ui-xml-dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-ui-xml-dump.js","sourceRoot":"","sources":["../src/test-ui-xml-dump.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AAE7F,SAAS,KAAK;IACZ,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE/B,aAAa,CAAC,GAAG,IAAI,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,EAAE,KAAK,IAAI,SAAS,CAAC,CAAC;IAChE,aAAa,CAAC,GAAG,IAAI,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAErD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC3C,aAAa,CACX,GAAG,IAAI,cAAc,EACrB,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACxF,OAAO,CACR,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC;IACV,IAAI,eAAe,GAAG,CAAC,MAAM;IAC7B,IAAI,eAAe,QAAQ,CAAC,MAAM;IAClC,IAAI,iBAAiB,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,CAAC;AAC1H,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beeos-ai/device-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "BeeOS device-agent — Android/desktop AI control agent (TypeScript) speaking ACP over Bridge WebSocket. Connects to a sibling device-mcp-server process for device control.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@beeos-ai/beeos-types": "^1.0.0",
|
|
55
55
|
"@beeos-ai/bridge-client": "^0.1.1",
|
|
56
|
+
"@beeos-ai/message-sdk": "^0.1.0",
|
|
56
57
|
"@fastify/cors": "^11.2.0",
|
|
57
58
|
"@fastify/multipart": "^10.0.0",
|
|
58
59
|
"@mariozechner/pi-coding-agent": "0.70.2",
|