@beeos-ai/device-agent 0.4.3 → 0.5.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/.pi/extensions/android-tools.ts +146 -15
- package/dist/adapters/agent-gateway-client.d.ts +37 -0
- package/dist/adapters/agent-gateway-client.js +45 -0
- package/dist/adapters/agent-gateway-client.js.map +1 -1
- package/dist/adapters/agentcore-pi.d.ts +22 -0
- package/dist/adapters/agentcore-pi.js +48 -0
- package/dist/adapters/agentcore-pi.js.map +1 -1
- package/dist/adapters/device-android-adb.d.ts +47 -0
- package/dist/adapters/device-android-adb.js +50 -0
- package/dist/adapters/device-android-adb.js.map +1 -1
- package/dist/adapters/device-desktop.d.ts +12 -0
- package/dist/adapters/device-desktop.js +31 -0
- package/dist/adapters/device-desktop.js.map +1 -1
- package/dist/adapters/identity-file.d.ts +33 -5
- package/dist/adapters/identity-file.js +52 -6
- package/dist/adapters/identity-file.js.map +1 -1
- package/dist/agent-runtime/adapters/base.d.ts +20 -0
- package/dist/agent-runtime/adapters/base.js.map +1 -1
- package/dist/agent-runtime/agent-runner.d.ts +4 -2
- package/dist/agent-runtime/agent-runner.js.map +1 -1
- package/dist/agent-runtime/core.d.ts +60 -0
- package/dist/agent-runtime/core.js +190 -9
- package/dist/agent-runtime/core.js.map +1 -1
- package/dist/agent-runtime/feedback.d.ts +56 -0
- package/dist/agent-runtime/feedback.js +54 -0
- package/dist/agent-runtime/feedback.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +1 -0
- package/dist/agent-runtime/index.js +1 -0
- package/dist/agent-runtime/index.js.map +1 -1
- package/dist/agent-runtime/plan-executor.js +24 -0
- package/dist/agent-runtime/plan-executor.js.map +1 -1
- package/dist/agent-runtime/planner/base.d.ts +10 -0
- package/dist/agent-runtime/planner/base.js.map +1 -1
- package/dist/agent-runtime/planner/llm-planner.js +1 -0
- package/dist/agent-runtime/planner/llm-planner.js.map +1 -1
- package/dist/agent-runtime/planner/prompts.d.ts +3 -0
- package/dist/agent-runtime/planner/prompts.js +12 -0
- package/dist/agent-runtime/planner/prompts.js.map +1 -1
- package/dist/agent-runtime/reflection.d.ts +25 -6
- package/dist/agent-runtime/reflection.js +64 -22
- package/dist/agent-runtime/reflection.js.map +1 -1
- package/dist/agent-runtime/reflectors/policy.d.ts +10 -4
- package/dist/agent-runtime/reflectors/policy.js +19 -6
- package/dist/agent-runtime/reflectors/policy.js.map +1 -1
- package/dist/agent-runtime/shortcuts/fs-store.d.ts +41 -0
- package/dist/agent-runtime/shortcuts/fs-store.js +122 -0
- package/dist/agent-runtime/shortcuts/fs-store.js.map +1 -0
- package/dist/agent-runtime/shortcuts/in-memory-store.d.ts +20 -0
- package/dist/agent-runtime/shortcuts/in-memory-store.js +64 -0
- package/dist/agent-runtime/shortcuts/in-memory-store.js.map +1 -0
- package/dist/agent-runtime/shortcuts/index.d.ts +10 -0
- package/dist/agent-runtime/shortcuts/index.js +10 -0
- package/dist/agent-runtime/shortcuts/index.js.map +1 -0
- package/dist/agent-runtime/shortcuts/types.d.ts +69 -0
- package/dist/agent-runtime/shortcuts/types.js +17 -0
- package/dist/agent-runtime/shortcuts/types.js.map +1 -0
- package/dist/app/agent-host.d.ts +83 -0
- package/dist/app/agent-host.js +345 -32
- package/dist/app/agent-host.js.map +1 -1
- package/dist/app/session-manager.d.ts +33 -4
- package/dist/app/session-manager.js +27 -5
- package/dist/app/session-manager.js.map +1 -1
- package/dist/bootstrap.js +187 -3
- package/dist/bootstrap.js.map +1 -1
- package/dist/config/loader.js +22 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +18 -0
- package/dist/config/schema.js +118 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/fleet/adapters/process/node-process-manager.js +97 -17
- package/dist/fleet/adapters/process/node-process-manager.js.map +1 -1
- package/dist/fleet/adapters/state/beeos-cli-store.d.ts +75 -9
- package/dist/fleet/adapters/state/beeos-cli-store.js +201 -17
- package/dist/fleet/adapters/state/beeos-cli-store.js.map +1 -1
- package/dist/fleet/domain/device.d.ts +9 -0
- package/dist/fleet/domain/device.js.map +1 -1
- package/dist/fleet/domain/fsm.js +34 -0
- package/dist/fleet/domain/fsm.js.map +1 -1
- package/dist/fleet/installer/spawn-env.d.ts +3 -0
- package/dist/fleet/installer/spawn-env.js +186 -3
- package/dist/fleet/installer/spawn-env.js.map +1 -1
- package/dist/fleet/state/state-json.d.ts +116 -0
- package/dist/fleet/state/state-json.js +87 -0
- package/dist/fleet/state/state-json.js.map +1 -0
- package/dist/fleet/supervisor.js +14 -2
- package/dist/fleet/supervisor.js.map +1 -1
- package/dist/inbound/acp/handlers/session.js.map +1 -1
- package/dist/mcp-client/client.d.ts +6 -0
- package/dist/mcp-client/client.js +11 -0
- package/dist/mcp-client/client.js.map +1 -1
- package/dist/mcp-client/runtime.d.ts +13 -0
- package/dist/orchestrator-system-prompt.d.ts +26 -0
- package/dist/orchestrator-system-prompt.js +118 -2
- package/dist/orchestrator-system-prompt.js.map +1 -1
- package/dist/pi-context.d.ts +50 -0
- package/dist/pi-context.js.map +1 -1
- package/dist/ports/device.d.ts +18 -0
- package/dist/resources/augmenter.d.ts +48 -0
- package/dist/resources/augmenter.js +126 -0
- package/dist/resources/augmenter.js.map +1 -0
- package/dist/resources/cache.d.ts +57 -0
- package/dist/resources/cache.js +107 -0
- package/dist/resources/cache.js.map +1 -0
- package/dist/resources/index.d.ts +17 -0
- package/dist/resources/index.js +15 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/lifecycle/disk-pressure.d.ts +75 -0
- package/dist/resources/lifecycle/disk-pressure.js +148 -0
- package/dist/resources/lifecycle/disk-pressure.js.map +1 -0
- package/dist/resources/lifecycle/index.d.ts +7 -0
- package/dist/resources/lifecycle/index.js +7 -0
- package/dist/resources/lifecycle/index.js.map +1 -0
- package/dist/resources/lifecycle/manager.d.ts +38 -0
- package/dist/resources/lifecycle/manager.js +205 -0
- package/dist/resources/lifecycle/manager.js.map +1 -0
- package/dist/resources/lifecycle/sweeper.d.ts +36 -0
- package/dist/resources/lifecycle/sweeper.js +179 -0
- package/dist/resources/lifecycle/sweeper.js.map +1 -0
- package/dist/resources/lifecycle/types.d.ts +180 -0
- package/dist/resources/lifecycle/types.js +46 -0
- package/dist/resources/lifecycle/types.js.map +1 -0
- package/dist/resources/parsers.d.ts +28 -0
- package/dist/resources/parsers.js +88 -0
- package/dist/resources/parsers.js.map +1 -0
- package/dist/resources/registry.d.ts +47 -0
- package/dist/resources/registry.js +107 -0
- package/dist/resources/registry.js.map +1 -0
- package/dist/resources/resolvers/beeos-file-resolver.d.ts +62 -0
- package/dist/resources/resolvers/beeos-file-resolver.js +109 -0
- package/dist/resources/resolvers/beeos-file-resolver.js.map +1 -0
- package/dist/resources/resolvers/errors.d.ts +11 -0
- package/dist/resources/resolvers/errors.js +23 -0
- package/dist/resources/resolvers/errors.js.map +1 -0
- package/dist/resources/resolvers/mime-table.d.ts +41 -0
- package/dist/resources/resolvers/mime-table.js +92 -0
- package/dist/resources/resolvers/mime-table.js.map +1 -0
- package/dist/resources/resolvers/url-resolver.d.ts +85 -0
- package/dist/resources/resolvers/url-resolver.js +495 -0
- package/dist/resources/resolvers/url-resolver.js.map +1 -0
- package/dist/resources/shortcut-facade.d.ts +51 -0
- package/dist/resources/shortcut-facade.js +72 -0
- package/dist/resources/shortcut-facade.js.map +1 -0
- package/dist/resources/telemetry.d.ts +52 -0
- package/dist/resources/telemetry.js +59 -0
- package/dist/resources/telemetry.js.map +1 -0
- package/dist/resources/types.d.ts +249 -0
- package/dist/resources/types.js +29 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/shortcuts/builtins/download-to-device.d.ts +83 -0
- package/dist/shortcuts/builtins/download-to-device.js +125 -0
- package/dist/shortcuts/builtins/download-to-device.js.map +1 -0
- package/dist/shortcuts/builtins/find-app-package.d.ts +79 -0
- package/dist/shortcuts/builtins/find-app-package.js +168 -0
- package/dist/shortcuts/builtins/find-app-package.js.map +1 -0
- package/dist/shortcuts/builtins/index.d.ts +32 -0
- package/dist/shortcuts/builtins/index.js +37 -0
- package/dist/shortcuts/builtins/index.js.map +1 -0
- package/dist/shortcuts/builtins/open-deeplink.d.ts +68 -0
- package/dist/shortcuts/builtins/open-deeplink.js +142 -0
- package/dist/shortcuts/builtins/open-deeplink.js.map +1 -0
- package/dist/shortcuts/builtins/set-clipboard.d.ts +65 -0
- package/dist/shortcuts/builtins/set-clipboard.js +112 -0
- package/dist/shortcuts/builtins/set-clipboard.js.map +1 -0
- package/dist/shortcuts/index.d.ts +11 -0
- package/dist/shortcuts/index.js +11 -0
- package/dist/shortcuts/index.js.map +1 -0
- package/dist/shortcuts/registry.d.ts +56 -0
- package/dist/shortcuts/registry.js +70 -0
- package/dist/shortcuts/registry.js.map +1 -0
- package/dist/shortcuts/router.d.ts +91 -0
- package/dist/shortcuts/router.js +158 -0
- package/dist/shortcuts/router.js.map +1 -0
- package/dist/shortcuts/types.d.ts +219 -0
- package/dist/shortcuts/types.js +46 -0
- package/dist/shortcuts/types.js.map +1 -0
- package/package.json +3 -3
- package/dist/agent-runtime/skills/sqlite-store.d.ts +0 -60
- package/dist/agent-runtime/skills/sqlite-store.js +0 -234
- package/dist/agent-runtime/skills/sqlite-store.js.map +0 -1
- package/dist/test-lan-autoglm.d.ts +0 -7
- package/dist/test-lan-autoglm.js +0 -46
- package/dist/test-lan-autoglm.js.map +0 -1
- package/dist/test-mem-breakdown.d.ts +0 -1
- package/dist/test-mem-breakdown.js +0 -103
- package/dist/test-mem-breakdown.js.map +0 -1
- package/dist/test-mem.d.ts +0 -1
- package/dist/test-mem.js +0 -60
- package/dist/test-mem.js.map +0 -1
- package/dist/test-mobile-use.d.ts +0 -1
- package/dist/test-mobile-use.js +0 -18
- package/dist/test-mobile-use.js.map +0 -1
- package/dist/test-screenshot-loop.d.ts +0 -1
- package/dist/test-screenshot-loop.js +0 -43
- package/dist/test-screenshot-loop.js.map +0 -1
- package/dist/test-screenshot.d.ts +0 -1
- package/dist/test-screenshot.js +0 -10
- package/dist/test-screenshot.js.map +0 -1
- package/dist/test-ui-xml-dump.d.ts +0 -15
- package/dist/test-ui-xml-dump.js +0 -49
- package/dist/test-ui-xml-dump.js.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortcut types — Phase 2 of the GUI-Shortcut Hybrid Plan
|
|
3
|
+
* (MAS-Bench 2025 SOTA alignment).
|
|
4
|
+
*
|
|
5
|
+
* A *shortcut* is a deterministic, structured-input action the outer
|
|
6
|
+
* orchestrator can call instead of (or alongside) `mobile_use`. The
|
|
7
|
+
* intent is to give the LLM a way to do things that the GUI-only VLM
|
|
8
|
+
* (AutoGLM-Phone-9B) cannot do at all (set the clipboard, open a deep
|
|
9
|
+
* link, look up an installed package, download a URL onto the device)
|
|
10
|
+
* **without** ever exposing raw `bash` / `file_write` / `execute_command`
|
|
11
|
+
* primitives — those would put us in Anthropic-Computer-Use territory,
|
|
12
|
+
* which AutoGLM-Phone-9B was not trained for.
|
|
13
|
+
*
|
|
14
|
+
* Design notes (all derived from the plan's D-decisions):
|
|
15
|
+
*
|
|
16
|
+
* D7 — Phase 2 uses **full registration** (4 shortcuts, all enabled
|
|
17
|
+
* all the time) instead of recall. The set is small enough that
|
|
18
|
+
* prompt-cache friendliness wins over conditional injection.
|
|
19
|
+
* Recall is intentionally a future (`phase 3+`) concern; we
|
|
20
|
+
* leave the registry's `match` API behind a TODO so the eventual
|
|
21
|
+
* recall layer has a natural seam to plug into.
|
|
22
|
+
* D8 — The `download_to_device` shortcut shares the **same**
|
|
23
|
+
* `ResourceResolverRegistry` and `ResourceResolutionCache` that
|
|
24
|
+
* the AgentHost auto-trigger uses (Phase 1). The two paths are
|
|
25
|
+
* distinct entry points (host-side preprocessing vs LLM
|
|
26
|
+
* tool-call) but converge on the same backend, so a fresh
|
|
27
|
+
* download primed by the host is reused if the LLM later asks
|
|
28
|
+
* for it explicitly.
|
|
29
|
+
* D9 — `runShell` / `pushFile` from the `PiExtensionContext` are
|
|
30
|
+
* **internal-only** plumbing. They are reachable from inside a
|
|
31
|
+
* shortcut's `execute(...)` body but are never advertised as
|
|
32
|
+
* outer-LLM tools. The convention is enforced by inspection:
|
|
33
|
+
* if you need to add a new shortcut that calls these, do so
|
|
34
|
+
* from inside `services/shortcuts/*.ts` only — see the
|
|
35
|
+
* file-level comment in `pi-context.ts`.
|
|
36
|
+
*
|
|
37
|
+
* Error contract:
|
|
38
|
+
*
|
|
39
|
+
* Every shortcut returns a `ShortcutResult`. We use a closed
|
|
40
|
+
* discriminated union so the calling layer (and the orchestrator
|
|
41
|
+
* prompt) can switch on `code` without reading free-form messages.
|
|
42
|
+
* Adding a new error code requires editing this file (intentional
|
|
43
|
+
* choke point — the codes are part of the public LLM contract).
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Closed vocabulary of shortcut error codes. Mirrors the plan's D2
|
|
47
|
+
* "structured errors only" requirement.
|
|
48
|
+
*
|
|
49
|
+
* - `intent_rejected` — the device acknowledged the action but
|
|
50
|
+
* the OS rejected it (e.g. permission
|
|
51
|
+
* denied at the activity manager level).
|
|
52
|
+
* - `app_not_found` — `find_app_package` couldn't match any
|
|
53
|
+
* installed package, OR a `open_deeplink`
|
|
54
|
+
* target activity does not exist.
|
|
55
|
+
* - `timeout` — execution exceeded the per-shortcut
|
|
56
|
+
* timeout. Defaults to 30 s but can be
|
|
57
|
+
* shortened on a per-shortcut basis.
|
|
58
|
+
* - `permission_denied` — the runtime (MCP / device adapter)
|
|
59
|
+
* refused to perform the action because
|
|
60
|
+
* of a missing capability. Distinct from
|
|
61
|
+
* `intent_rejected` — that's an OS-level
|
|
62
|
+
* "I heard you but no", whereas this is
|
|
63
|
+
* "we never even sent the request".
|
|
64
|
+
* - `invalid_args` — the LLM called the shortcut with args
|
|
65
|
+
* that fail the JSON schema or contextual
|
|
66
|
+
* validation (e.g. malformed deeplink URI).
|
|
67
|
+
* - `unsupported_platform` — the active device is not Android (or
|
|
68
|
+
* the shortcut is Android-only and the
|
|
69
|
+
* device is desktop / iOS).
|
|
70
|
+
* - `internal_error` — a real bug. Not part of the plan's
|
|
71
|
+
* listed codes; used as a last-resort
|
|
72
|
+
* wrapper so the LLM can still see a
|
|
73
|
+
* structured failure rather than crashing
|
|
74
|
+
* the whole orchestrator turn.
|
|
75
|
+
*/
|
|
76
|
+
export type ShortcutErrorCode = "intent_rejected" | "app_not_found" | "timeout" | "permission_denied" | "invalid_args" | "unsupported_platform" | "internal_error";
|
|
77
|
+
/** Successful shortcut output. `output` is shortcut-specific JSON. */
|
|
78
|
+
export interface ShortcutSuccess<T = unknown> {
|
|
79
|
+
ok: true;
|
|
80
|
+
output: T;
|
|
81
|
+
/** Optional metadata — duration, retry count, etc. */
|
|
82
|
+
durationMs?: number;
|
|
83
|
+
}
|
|
84
|
+
/** Failed shortcut output. `code` is closed-set; `message` is debug text. */
|
|
85
|
+
export interface ShortcutFailure {
|
|
86
|
+
ok: false;
|
|
87
|
+
code: ShortcutErrorCode;
|
|
88
|
+
message: string;
|
|
89
|
+
/** Optional metadata — duration, retry count, etc. */
|
|
90
|
+
durationMs?: number;
|
|
91
|
+
}
|
|
92
|
+
export type ShortcutResult<T = unknown> = ShortcutSuccess<T> | ShortcutFailure;
|
|
93
|
+
/**
|
|
94
|
+
* JSON schema fragment for a shortcut's parameter object. Kept as
|
|
95
|
+
* `unknown` here so callers can supply either a TypeBox / Zod schema
|
|
96
|
+
* or a hand-rolled JSON Schema; the registry forwards the value
|
|
97
|
+
* unchanged to the outer LLM tool descriptor (see
|
|
98
|
+
* `.pi/extensions/android-tools.ts`). Validation happens inside each
|
|
99
|
+
* shortcut's `execute` body — there is no central validator, both
|
|
100
|
+
* because the runtimes (TypeBox vs Zod vs raw JSON Schema) differ in
|
|
101
|
+
* how they expose `validate(input)` and because the plan intentionally
|
|
102
|
+
* keeps shortcuts thin (no shared middleware stack).
|
|
103
|
+
*/
|
|
104
|
+
export type ShortcutJsonSchema = Record<string, unknown>;
|
|
105
|
+
/** Categorical hint used by tool descriptor generators / docs / metrics. */
|
|
106
|
+
export type ShortcutKind = "api" | "deeplink" | "rpa";
|
|
107
|
+
/**
|
|
108
|
+
* Per-shortcut metadata. The descriptor is what `android-tools.ts`
|
|
109
|
+
* reads when synthesising outer-LLM tool descriptors — adding a new
|
|
110
|
+
* shortcut therefore automatically lights it up in the orchestrator
|
|
111
|
+
* prompt without touching the extension file.
|
|
112
|
+
*/
|
|
113
|
+
export interface ShortcutDescriptor {
|
|
114
|
+
/** Stable id, used for telemetry and tool-name generation. */
|
|
115
|
+
readonly id: string;
|
|
116
|
+
/** Human / LLM display name (must be unique across the registry). */
|
|
117
|
+
readonly displayName: string;
|
|
118
|
+
/** One-line LLM description for the tool descriptor. */
|
|
119
|
+
readonly description: string;
|
|
120
|
+
/** JSON schema for the input arguments. */
|
|
121
|
+
readonly jsonSchema: ShortcutJsonSchema;
|
|
122
|
+
/** Categorical hint surfaced to the orchestrator + telemetry. */
|
|
123
|
+
readonly kind: ShortcutKind;
|
|
124
|
+
/**
|
|
125
|
+
* Platforms the shortcut supports. The router rejects a call with
|
|
126
|
+
* `unsupported_platform` when the active device's `info.os` /
|
|
127
|
+
* `info.type` doesn't match any entry. `"any"` means platform-agnostic.
|
|
128
|
+
*/
|
|
129
|
+
readonly platforms: readonly ShortcutPlatform[];
|
|
130
|
+
/**
|
|
131
|
+
* Soft per-call timeout. The router enforces it via AbortSignal; the
|
|
132
|
+
* shortcut MAY also enforce a tighter budget internally. Default is
|
|
133
|
+
* 30 s when unset.
|
|
134
|
+
*/
|
|
135
|
+
readonly timeoutMs?: number;
|
|
136
|
+
}
|
|
137
|
+
/** Platform tag — kept in sync with `IDevice.getInfo().type`. */
|
|
138
|
+
export type ShortcutPlatform = "android" | "desktop" | "any";
|
|
139
|
+
/**
|
|
140
|
+
* Concrete shortcut. The execute method is given a ready-built
|
|
141
|
+
* `ShortcutContext` so individual shortcuts don't have to hand-roll
|
|
142
|
+
* MCP / device wiring (and the boundary in `pi-context.ts` stays
|
|
143
|
+
* honest — see D9).
|
|
144
|
+
*/
|
|
145
|
+
export interface Shortcut<TArgs = unknown, TOut = unknown> {
|
|
146
|
+
readonly descriptor: ShortcutDescriptor;
|
|
147
|
+
execute(args: TArgs, ctx: ShortcutContext): Promise<ShortcutResult<TOut>>;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Per-call shortcut context. Mirrors the shape the `PiExtensionContext`
|
|
151
|
+
* exposes to extensions, but pre-narrowed so shortcut authors don't
|
|
152
|
+
* touch the singleton. The router builds one of these on every
|
|
153
|
+
* `invoke(...)` and passes it in.
|
|
154
|
+
*/
|
|
155
|
+
export interface ShortcutContext {
|
|
156
|
+
/** Active MCP runtime. May be missing in tests / desktop mock. */
|
|
157
|
+
readonly mcp?: ShortcutMcpRuntime;
|
|
158
|
+
/** Active device's `IDevice` snapshot — read-only. */
|
|
159
|
+
readonly device?: ShortcutDeviceFacade;
|
|
160
|
+
/** Resource resolver — only set when `download_to_device` is wired. */
|
|
161
|
+
readonly resources?: ShortcutResourceFacade;
|
|
162
|
+
/** Merged AbortSignal honoring both per-call timeout and host cancel. */
|
|
163
|
+
readonly abortSignal: AbortSignal;
|
|
164
|
+
/** Structured logger (pino-shaped). */
|
|
165
|
+
readonly log: ShortcutLogger;
|
|
166
|
+
}
|
|
167
|
+
/** Logger surface — pino's hot keys, no `child` (forbidden inside shortcuts). */
|
|
168
|
+
export interface ShortcutLogger {
|
|
169
|
+
debug(obj: object, msg?: string): void;
|
|
170
|
+
info(obj: object, msg?: string): void;
|
|
171
|
+
warn(obj: object, msg?: string): void;
|
|
172
|
+
error(obj: object, msg?: string): void;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* MCP surface a shortcut may use. Intentionally narrower than
|
|
176
|
+
* `IMcpRuntime` so a future shortcut author can't reach for an
|
|
177
|
+
* unrelated primitive.
|
|
178
|
+
*/
|
|
179
|
+
export interface ShortcutMcpRuntime {
|
|
180
|
+
/** Run a shell command (Android: ADB shell). */
|
|
181
|
+
executeCommand(body: string, opts?: {
|
|
182
|
+
timeoutS?: number;
|
|
183
|
+
cwd?: string;
|
|
184
|
+
}): Promise<{
|
|
185
|
+
stdout: string;
|
|
186
|
+
stderr: string;
|
|
187
|
+
exitCode: number;
|
|
188
|
+
}>;
|
|
189
|
+
/** Optional file push — only used by `download_to_device`. */
|
|
190
|
+
fileWrite?(path: string, bytes: Buffer): Promise<void>;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Read-only device facade exposed to shortcuts. Hides the rest of
|
|
194
|
+
* `IDevice` (capture / apply / install) — those are reserved for the
|
|
195
|
+
* VLM path.
|
|
196
|
+
*/
|
|
197
|
+
export interface ShortcutDeviceFacade {
|
|
198
|
+
getInfo(): Promise<{
|
|
199
|
+
type: string;
|
|
200
|
+
name: string;
|
|
201
|
+
os: string;
|
|
202
|
+
capabilities: readonly string[];
|
|
203
|
+
}>;
|
|
204
|
+
resolveWellKnownDir(mime: string): Promise<string>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Resource facade reused by `download_to_device`. The router supplies
|
|
208
|
+
* a thin wrapper that delegates into the same `ResourceResolverRegistry`
|
|
209
|
+
* + cache the AgentHost uses (D8).
|
|
210
|
+
*/
|
|
211
|
+
export interface ShortcutResourceFacade {
|
|
212
|
+
resolveUrl(url: string): Promise<{
|
|
213
|
+
remotePath: string;
|
|
214
|
+
mime: string;
|
|
215
|
+
sizeBytes: number;
|
|
216
|
+
sha256: string;
|
|
217
|
+
sourceUrl: string;
|
|
218
|
+
}>;
|
|
219
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortcut types — Phase 2 of the GUI-Shortcut Hybrid Plan
|
|
3
|
+
* (MAS-Bench 2025 SOTA alignment).
|
|
4
|
+
*
|
|
5
|
+
* A *shortcut* is a deterministic, structured-input action the outer
|
|
6
|
+
* orchestrator can call instead of (or alongside) `mobile_use`. The
|
|
7
|
+
* intent is to give the LLM a way to do things that the GUI-only VLM
|
|
8
|
+
* (AutoGLM-Phone-9B) cannot do at all (set the clipboard, open a deep
|
|
9
|
+
* link, look up an installed package, download a URL onto the device)
|
|
10
|
+
* **without** ever exposing raw `bash` / `file_write` / `execute_command`
|
|
11
|
+
* primitives — those would put us in Anthropic-Computer-Use territory,
|
|
12
|
+
* which AutoGLM-Phone-9B was not trained for.
|
|
13
|
+
*
|
|
14
|
+
* Design notes (all derived from the plan's D-decisions):
|
|
15
|
+
*
|
|
16
|
+
* D7 — Phase 2 uses **full registration** (4 shortcuts, all enabled
|
|
17
|
+
* all the time) instead of recall. The set is small enough that
|
|
18
|
+
* prompt-cache friendliness wins over conditional injection.
|
|
19
|
+
* Recall is intentionally a future (`phase 3+`) concern; we
|
|
20
|
+
* leave the registry's `match` API behind a TODO so the eventual
|
|
21
|
+
* recall layer has a natural seam to plug into.
|
|
22
|
+
* D8 — The `download_to_device` shortcut shares the **same**
|
|
23
|
+
* `ResourceResolverRegistry` and `ResourceResolutionCache` that
|
|
24
|
+
* the AgentHost auto-trigger uses (Phase 1). The two paths are
|
|
25
|
+
* distinct entry points (host-side preprocessing vs LLM
|
|
26
|
+
* tool-call) but converge on the same backend, so a fresh
|
|
27
|
+
* download primed by the host is reused if the LLM later asks
|
|
28
|
+
* for it explicitly.
|
|
29
|
+
* D9 — `runShell` / `pushFile` from the `PiExtensionContext` are
|
|
30
|
+
* **internal-only** plumbing. They are reachable from inside a
|
|
31
|
+
* shortcut's `execute(...)` body but are never advertised as
|
|
32
|
+
* outer-LLM tools. The convention is enforced by inspection:
|
|
33
|
+
* if you need to add a new shortcut that calls these, do so
|
|
34
|
+
* from inside `services/shortcuts/*.ts` only — see the
|
|
35
|
+
* file-level comment in `pi-context.ts`.
|
|
36
|
+
*
|
|
37
|
+
* Error contract:
|
|
38
|
+
*
|
|
39
|
+
* Every shortcut returns a `ShortcutResult`. We use a closed
|
|
40
|
+
* discriminated union so the calling layer (and the orchestrator
|
|
41
|
+
* prompt) can switch on `code` without reading free-form messages.
|
|
42
|
+
* Adding a new error code requires editing this file (intentional
|
|
43
|
+
* choke point — the codes are part of the public LLM contract).
|
|
44
|
+
*/
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shortcuts/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beeos-ai/device-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
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",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"pino": "^10.3.1",
|
|
63
63
|
"sharp": "^0.34.5",
|
|
64
64
|
"zod": "^4.3.6",
|
|
65
|
-
"@beeos-ai/device-common": "0.
|
|
65
|
+
"@beeos-ai/device-common": "0.3.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^22.0.0",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"tsx": "^4.19.0",
|
|
72
72
|
"typescript": "^5.8.0",
|
|
73
73
|
"vitest": "^4.1.5",
|
|
74
|
-
"@beeos-ai/device-mcp-server": "0.
|
|
74
|
+
"@beeos-ai/device-mcp-server": "0.3.0"
|
|
75
75
|
},
|
|
76
76
|
"scripts": {
|
|
77
77
|
"build": "tsc -p tsconfig.json && chmod +x dist/inbound/cli/main.js",
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* agent-runtime/skills/sqlite-store — SQLite-backed
|
|
3
|
-
* {@link SkillCacheStore}.
|
|
4
|
-
*
|
|
5
|
-
* Phase 3.1 of the [device-agent reflector upgrade plan](../../../../../../.cursor/plans/device-agent-reflector-skills_d5599350.plan.md).
|
|
6
|
-
*
|
|
7
|
-
* Schema (kept verbatim with the plan):
|
|
8
|
-
* ```sql
|
|
9
|
-
* CREATE TABLE skills (
|
|
10
|
-
* id TEXT PRIMARY KEY,
|
|
11
|
-
* app_package TEXT NOT NULL,
|
|
12
|
-
* task_summary TEXT NOT NULL,
|
|
13
|
-
* task_embedding BLOB,
|
|
14
|
-
* action_sequence_json TEXT NOT NULL,
|
|
15
|
-
* success_count INTEGER NOT NULL DEFAULT 1,
|
|
16
|
-
* fail_count INTEGER NOT NULL DEFAULT 0,
|
|
17
|
-
* last_used_at INTEGER NOT NULL,
|
|
18
|
-
* created_at INTEGER NOT NULL
|
|
19
|
-
* );
|
|
20
|
-
* CREATE INDEX idx_skills_app ON skills(app_package);
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* Default DB path: `~/.beeos/device-agent/skills.sqlite`. Containerised
|
|
24
|
-
* deployments mount `/var/lib/beeos/device-agent` and override
|
|
25
|
-
* `SKILL_CACHE_PATH` accordingly.
|
|
26
|
-
*
|
|
27
|
-
* Search is implemented as a full scan over the matching app rows —
|
|
28
|
-
* the cache is intentionally small (<10k rows / device), so a brute
|
|
29
|
-
* cosine pass is cheaper than maintaining an ANN index. If profile
|
|
30
|
-
* data shows that's wrong we can plug in `sqlite-vss` / `pgvector`
|
|
31
|
-
* later behind the same {@link SkillCacheStore} interface.
|
|
32
|
-
*/
|
|
33
|
-
import type { Database as DB } from "better-sqlite3";
|
|
34
|
-
import type { NewSkillInput, Skill, SkillCacheStore, SkillMatch } from "./types.js";
|
|
35
|
-
export interface SQLiteSkillCacheStoreOptions {
|
|
36
|
-
/** Override the default DB path. Use ":memory:" for ephemeral tests. */
|
|
37
|
-
path?: string;
|
|
38
|
-
/** Pre-built better-sqlite3 Database (used by tests). */
|
|
39
|
-
db?: DB;
|
|
40
|
-
/** Skip auto-mkdir on the parent dir (when path is :memory:). */
|
|
41
|
-
noMkdir?: boolean;
|
|
42
|
-
}
|
|
43
|
-
export declare function defaultSkillCachePath(): string;
|
|
44
|
-
export declare class SQLiteSkillCacheStore implements SkillCacheStore {
|
|
45
|
-
private readonly db;
|
|
46
|
-
private readonly stmts;
|
|
47
|
-
private closed;
|
|
48
|
-
constructor(opts?: SQLiteSkillCacheStoreOptions);
|
|
49
|
-
insert(input: NewSkillInput): Skill;
|
|
50
|
-
get(id: string): Skill | undefined;
|
|
51
|
-
listByApp(appPackage: string, limit?: number): Skill[];
|
|
52
|
-
listAll(limit?: number): Skill[];
|
|
53
|
-
search(appPackage: string, query: Float32Array, k: number): SkillMatch[];
|
|
54
|
-
recordSuccess(id: string, now?: number): void;
|
|
55
|
-
recordFailure(id: string, now?: number): void;
|
|
56
|
-
delete(id: string): boolean;
|
|
57
|
-
clear(): void;
|
|
58
|
-
close(): void;
|
|
59
|
-
private applyMigrations;
|
|
60
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* agent-runtime/skills/sqlite-store — SQLite-backed
|
|
3
|
-
* {@link SkillCacheStore}.
|
|
4
|
-
*
|
|
5
|
-
* Phase 3.1 of the [device-agent reflector upgrade plan](../../../../../../.cursor/plans/device-agent-reflector-skills_d5599350.plan.md).
|
|
6
|
-
*
|
|
7
|
-
* Schema (kept verbatim with the plan):
|
|
8
|
-
* ```sql
|
|
9
|
-
* CREATE TABLE skills (
|
|
10
|
-
* id TEXT PRIMARY KEY,
|
|
11
|
-
* app_package TEXT NOT NULL,
|
|
12
|
-
* task_summary TEXT NOT NULL,
|
|
13
|
-
* task_embedding BLOB,
|
|
14
|
-
* action_sequence_json TEXT NOT NULL,
|
|
15
|
-
* success_count INTEGER NOT NULL DEFAULT 1,
|
|
16
|
-
* fail_count INTEGER NOT NULL DEFAULT 0,
|
|
17
|
-
* last_used_at INTEGER NOT NULL,
|
|
18
|
-
* created_at INTEGER NOT NULL
|
|
19
|
-
* );
|
|
20
|
-
* CREATE INDEX idx_skills_app ON skills(app_package);
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* Default DB path: `~/.beeos/device-agent/skills.sqlite`. Containerised
|
|
24
|
-
* deployments mount `/var/lib/beeos/device-agent` and override
|
|
25
|
-
* `SKILL_CACHE_PATH` accordingly.
|
|
26
|
-
*
|
|
27
|
-
* Search is implemented as a full scan over the matching app rows —
|
|
28
|
-
* the cache is intentionally small (<10k rows / device), so a brute
|
|
29
|
-
* cosine pass is cheaper than maintaining an ANN index. If profile
|
|
30
|
-
* data shows that's wrong we can plug in `sqlite-vss` / `pgvector`
|
|
31
|
-
* later behind the same {@link SkillCacheStore} interface.
|
|
32
|
-
*/
|
|
33
|
-
import { mkdirSync } from "node:fs";
|
|
34
|
-
import path from "node:path";
|
|
35
|
-
import { homedir } from "node:os";
|
|
36
|
-
import { randomUUID } from "node:crypto";
|
|
37
|
-
import Database from "better-sqlite3";
|
|
38
|
-
import { bufferToEmbedding, cosine, embeddingToBuffer, } from "./embedding.js";
|
|
39
|
-
const SCHEMA_VERSION = 1;
|
|
40
|
-
const SCHEMA_SQL = `
|
|
41
|
-
PRAGMA journal_mode=WAL;
|
|
42
|
-
PRAGMA synchronous=NORMAL;
|
|
43
|
-
PRAGMA foreign_keys=ON;
|
|
44
|
-
|
|
45
|
-
CREATE TABLE IF NOT EXISTS skills (
|
|
46
|
-
id TEXT PRIMARY KEY,
|
|
47
|
-
app_package TEXT NOT NULL,
|
|
48
|
-
task_summary TEXT NOT NULL,
|
|
49
|
-
task_embedding BLOB,
|
|
50
|
-
action_sequence_json TEXT NOT NULL,
|
|
51
|
-
success_count INTEGER NOT NULL DEFAULT 1,
|
|
52
|
-
fail_count INTEGER NOT NULL DEFAULT 0,
|
|
53
|
-
last_used_at INTEGER NOT NULL,
|
|
54
|
-
created_at INTEGER NOT NULL
|
|
55
|
-
);
|
|
56
|
-
CREATE INDEX IF NOT EXISTS idx_skills_app ON skills(app_package);
|
|
57
|
-
|
|
58
|
-
CREATE TABLE IF NOT EXISTS skill_meta (
|
|
59
|
-
key TEXT PRIMARY KEY,
|
|
60
|
-
value TEXT NOT NULL
|
|
61
|
-
);
|
|
62
|
-
`;
|
|
63
|
-
export function defaultSkillCachePath() {
|
|
64
|
-
const env = process.env.SKILL_CACHE_PATH;
|
|
65
|
-
if (env && env.length > 0)
|
|
66
|
-
return env;
|
|
67
|
-
return path.join(homedir(), ".beeos", "device-agent", "skills.sqlite");
|
|
68
|
-
}
|
|
69
|
-
export class SQLiteSkillCacheStore {
|
|
70
|
-
db;
|
|
71
|
-
stmts;
|
|
72
|
-
closed = false;
|
|
73
|
-
constructor(opts = {}) {
|
|
74
|
-
const dbPath = opts.path ?? defaultSkillCachePath();
|
|
75
|
-
if (opts.db) {
|
|
76
|
-
this.db = opts.db;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
if (!opts.noMkdir && dbPath !== ":memory:") {
|
|
80
|
-
mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
81
|
-
}
|
|
82
|
-
this.db = new Database(dbPath);
|
|
83
|
-
}
|
|
84
|
-
this.db.exec(SCHEMA_SQL);
|
|
85
|
-
this.applyMigrations();
|
|
86
|
-
this.stmts = prepareStatements(this.db);
|
|
87
|
-
}
|
|
88
|
-
insert(input) {
|
|
89
|
-
if (this.closed)
|
|
90
|
-
throw new Error("SQLiteSkillCacheStore: handle closed");
|
|
91
|
-
const now = Date.now();
|
|
92
|
-
const id = randomUUID();
|
|
93
|
-
this.stmts.insert.run({
|
|
94
|
-
id,
|
|
95
|
-
app: input.appPackage,
|
|
96
|
-
summary: input.taskSummary,
|
|
97
|
-
embed: input.taskEmbedding ? embeddingToBuffer(input.taskEmbedding) : null,
|
|
98
|
-
seq: serialiseSequence(input.actionSequence),
|
|
99
|
-
now,
|
|
100
|
-
});
|
|
101
|
-
return {
|
|
102
|
-
id,
|
|
103
|
-
appPackage: input.appPackage,
|
|
104
|
-
taskSummary: input.taskSummary,
|
|
105
|
-
taskEmbedding: input.taskEmbedding ? new Float32Array(input.taskEmbedding) : undefined,
|
|
106
|
-
actionSequence: input.actionSequence,
|
|
107
|
-
successCount: 1,
|
|
108
|
-
failCount: 0,
|
|
109
|
-
lastUsedAt: now,
|
|
110
|
-
createdAt: now,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
get(id) {
|
|
114
|
-
const row = this.stmts.getById.get({ id });
|
|
115
|
-
return row ? rowToSkill(row) : undefined;
|
|
116
|
-
}
|
|
117
|
-
listByApp(appPackage, limit = 50) {
|
|
118
|
-
const rows = this.stmts.listByApp.all({ app: appPackage, limit });
|
|
119
|
-
return rows.map(rowToSkill);
|
|
120
|
-
}
|
|
121
|
-
listAll(limit = 200) {
|
|
122
|
-
const rows = this.stmts.listAll.all({ limit });
|
|
123
|
-
return rows.map(rowToSkill);
|
|
124
|
-
}
|
|
125
|
-
search(appPackage, query, k) {
|
|
126
|
-
const rows = this.stmts.searchByApp.all({ app: appPackage });
|
|
127
|
-
const matches = [];
|
|
128
|
-
for (const row of rows) {
|
|
129
|
-
if (!row.task_embedding)
|
|
130
|
-
continue;
|
|
131
|
-
const v = bufferToEmbedding(row.task_embedding);
|
|
132
|
-
if (v.length !== query.length)
|
|
133
|
-
continue;
|
|
134
|
-
const score = cosine(query, v);
|
|
135
|
-
matches.push({ skill: rowToSkill(row), score });
|
|
136
|
-
}
|
|
137
|
-
matches.sort((a, b) => b.score - a.score);
|
|
138
|
-
return matches.slice(0, Math.max(0, k));
|
|
139
|
-
}
|
|
140
|
-
recordSuccess(id, now = Date.now()) {
|
|
141
|
-
this.stmts.success.run({ id, now });
|
|
142
|
-
}
|
|
143
|
-
recordFailure(id, now = Date.now()) {
|
|
144
|
-
this.stmts.failure.run({ id, now });
|
|
145
|
-
}
|
|
146
|
-
delete(id) {
|
|
147
|
-
const res = this.stmts.delete.run({ id });
|
|
148
|
-
return res.changes > 0;
|
|
149
|
-
}
|
|
150
|
-
clear() {
|
|
151
|
-
this.db.exec("DELETE FROM skills;");
|
|
152
|
-
}
|
|
153
|
-
close() {
|
|
154
|
-
if (this.closed)
|
|
155
|
-
return;
|
|
156
|
-
this.closed = true;
|
|
157
|
-
try {
|
|
158
|
-
this.db.close();
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
/* swallow — close is best-effort */
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
applyMigrations() {
|
|
165
|
-
const row = this.db
|
|
166
|
-
.prepare("SELECT value FROM skill_meta WHERE key = 'schema_version'")
|
|
167
|
-
.get();
|
|
168
|
-
if (!row) {
|
|
169
|
-
this.db
|
|
170
|
-
.prepare("INSERT INTO skill_meta(key, value) VALUES('schema_version', ?)")
|
|
171
|
-
.run(String(SCHEMA_VERSION));
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
// Future migrations would diff `row.value` against SCHEMA_VERSION here.
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
function prepareStatements(db) {
|
|
178
|
-
return {
|
|
179
|
-
insert: db.prepare(`INSERT INTO skills (
|
|
180
|
-
id, app_package, task_summary, task_embedding,
|
|
181
|
-
action_sequence_json, success_count, fail_count, last_used_at, created_at
|
|
182
|
-
) VALUES (
|
|
183
|
-
@id, @app, @summary, @embed,
|
|
184
|
-
@seq, 1, 0, @now, @now
|
|
185
|
-
);`),
|
|
186
|
-
getById: db.prepare(`SELECT * FROM skills WHERE id = @id`),
|
|
187
|
-
listByApp: db.prepare(`SELECT * FROM skills
|
|
188
|
-
WHERE app_package = @app
|
|
189
|
-
ORDER BY last_used_at DESC
|
|
190
|
-
LIMIT @limit`),
|
|
191
|
-
listAll: db.prepare(`SELECT * FROM skills
|
|
192
|
-
ORDER BY last_used_at DESC
|
|
193
|
-
LIMIT @limit`),
|
|
194
|
-
searchByApp: db.prepare(`SELECT * FROM skills WHERE app_package = @app`),
|
|
195
|
-
success: db.prepare(`UPDATE skills SET success_count = success_count + 1,
|
|
196
|
-
last_used_at = @now
|
|
197
|
-
WHERE id = @id`),
|
|
198
|
-
failure: db.prepare(`UPDATE skills SET fail_count = fail_count + 1,
|
|
199
|
-
last_used_at = @now
|
|
200
|
-
WHERE id = @id`),
|
|
201
|
-
delete: db.prepare(`DELETE FROM skills WHERE id = @id`),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function serialiseSequence(seq) {
|
|
205
|
-
return JSON.stringify(seq);
|
|
206
|
-
}
|
|
207
|
-
function deserialiseSequence(raw) {
|
|
208
|
-
if (!raw)
|
|
209
|
-
return [];
|
|
210
|
-
try {
|
|
211
|
-
const v = JSON.parse(raw);
|
|
212
|
-
if (Array.isArray(v)) {
|
|
213
|
-
return v;
|
|
214
|
-
}
|
|
215
|
-
return [];
|
|
216
|
-
}
|
|
217
|
-
catch {
|
|
218
|
-
return [];
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function rowToSkill(row) {
|
|
222
|
-
return {
|
|
223
|
-
id: row.id,
|
|
224
|
-
appPackage: row.app_package,
|
|
225
|
-
taskSummary: row.task_summary,
|
|
226
|
-
taskEmbedding: row.task_embedding ? bufferToEmbedding(row.task_embedding) : undefined,
|
|
227
|
-
actionSequence: deserialiseSequence(row.action_sequence_json),
|
|
228
|
-
successCount: row.success_count,
|
|
229
|
-
failCount: row.fail_count,
|
|
230
|
-
lastUsedAt: row.last_used_at,
|
|
231
|
-
createdAt: row.created_at,
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
//# sourceMappingURL=sqlite-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../../src/agent-runtime/skills/sqlite-store.ts"],"names":[],"mappings":"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"}
|
package/dist/test-lan-autoglm.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-lan-autoglm.js","sourceRoot":"","sources":["../src/test-lan-autoglm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "dotenv/config";
|