@vellumai/assistant 0.12.2-dev.202609211820.22f71b0 → 0.12.2-dev.202609212016.fb4c53e

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.
Files changed (62) hide show
  1. package/Dockerfile +63 -0
  2. package/docs/desktop-browser-cli.md +10 -6
  3. package/openapi.yaml +189 -1
  4. package/package.json +1 -1
  5. package/scripts/smoke-desktop-browser-cli.ts +10 -26
  6. package/src/__tests__/context-search-agent-runner.test.ts +260 -1
  7. package/src/__tests__/context-search-fanout.test.ts +1 -1
  8. package/src/__tests__/context-search-types.test.ts +7 -7
  9. package/src/__tests__/plugin-import-boundary-guard.test.ts +3 -0
  10. package/src/__tests__/server-history-render.test.ts +91 -1
  11. package/src/api/events/notification-conversation-created.ts +9 -13
  12. package/src/api/events/tool-result.ts +75 -0
  13. package/src/api/index.ts +13 -0
  14. package/src/api/remember-tool.ts +15 -0
  15. package/src/approvals/AGENTS.md +3 -1
  16. package/src/cli/commands/browser.help.ts +4 -5
  17. package/src/cli/commands/browser.ts +0 -1
  18. package/src/cli/lib/bundled-marketplace.json +13 -0
  19. package/src/daemon/conversation-tool-setup.ts +1 -1
  20. package/src/daemon/handlers/shared.ts +41 -9
  21. package/src/desktop/desktop-automation-lease.test.ts +9 -72
  22. package/src/desktop/desktop-automation-lease.ts +3 -40
  23. package/src/desktop/desktop-computer-use.test.ts +8 -9
  24. package/src/desktop/desktop-computer-use.ts +1 -2
  25. package/src/desktop/desktop-dependencies.ts +41 -354
  26. package/src/desktop/desktop-display.ts +2 -2
  27. package/src/desktop/desktop-session-manager.test.ts +1 -1
  28. package/src/desktop/desktop-stream-bridge.test.ts +11 -122
  29. package/src/desktop/desktop-stream-bridge.ts +6 -8
  30. package/src/desktop/virtual-desktop-platform.test.ts +5 -9
  31. package/src/ipc/__tests__/browser-ipc.test.ts +5 -6
  32. package/src/notifications/AGENTS.md +1 -1
  33. package/src/notifications/README.md +54 -90
  34. package/src/notifications/adapters/macos.ts +8 -8
  35. package/src/notifications/broadcaster.ts +5 -6
  36. package/src/notifications/emit-signal.ts +5 -5
  37. package/src/notifications/signal.ts +1 -1
  38. package/src/plugin-api/index.ts +10 -0
  39. package/src/plugins/defaults/memory/context-search/agent-protocol.ts +7 -3
  40. package/src/plugins/defaults/memory/context-search/agent-runner.ts +78 -22
  41. package/src/plugins/defaults/memory/context-search/format.ts +51 -7
  42. package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
  43. package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
  44. package/src/plugins/defaults/memory/context-search/search.ts +8 -14
  45. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
  46. package/src/plugins/defaults/memory/context-search/types.ts +1 -11
  47. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
  48. package/src/plugins/defaults/memory/graph/tool-handlers.ts +12 -21
  49. package/src/plugins/defaults/memory/graph/tools.ts +35 -64
  50. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +5 -0
  51. package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
  52. package/src/plugins/defaults/memory/tools.test.ts +100 -8
  53. package/src/plugins/defaults/memory/tools.ts +26 -10
  54. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +61 -1
  55. package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
  56. package/src/providers/openai/chat-completions-provider.ts +51 -14
  57. package/src/runtime/AGENTS.md +1 -1
  58. package/src/runtime/guardian-reply-router.ts +23 -21
  59. package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
  60. package/src/runtime/routes/desktop-setup-routes.ts +4 -6
  61. package/src/util/provider-error-patterns.ts +3 -0
  62. package/src/desktop/desktop-dependencies.test.ts +0 -131
package/Dockerfile CHANGED
@@ -101,6 +101,69 @@ RUN apt-get update && apt-get install -y \
101
101
  xdg-utils \
102
102
  && rm -rf /var/lib/apt/lists/*
103
103
 
104
+ # Desktop system packages persist through container replacement as image layers.
105
+ RUN set -eu; \
106
+ wezterm_version=20240203-110809-5046fc22; \
107
+ case "$(dpkg --print-architecture)" in \
108
+ amd64) wezterm_suffix=Debian12.deb; wezterm_sha256=d3a5c97093fbc0a87e8f9616e44efc4c9503cfc495fd1cfe4ffeff88578d15f8 ;; \
109
+ arm64) wezterm_suffix=Debian12.arm64.deb; wezterm_sha256=351f8791c6e9561d687afa63834a2132de84800dad6e7c3d035cc6518d6c3744 ;; \
110
+ *) echo "Unsupported desktop architecture" >&2; exit 1 ;; \
111
+ esac; \
112
+ curl --fail --location --proto '=https' --proto-redir '=https' \
113
+ --retry 2 --max-time 300 --output /tmp/wezterm.deb \
114
+ "https://github.com/wezterm/wezterm/releases/download/${wezterm_version}/wezterm-${wezterm_version}.${wezterm_suffix}"; \
115
+ printf '%s /tmp/wezterm.deb\n' "$wezterm_sha256" | sha256sum --check -; \
116
+ apt-get update; \
117
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
118
+ adwaita-icon-theme \
119
+ at-spi2-core \
120
+ bamfdaemon \
121
+ dbus-daemon \
122
+ dbus-x11 \
123
+ feh \
124
+ fonts-liberation \
125
+ gnome-mines \
126
+ gvfs \
127
+ libcurl4 \
128
+ libegl1 \
129
+ libgl1-mesa-dri \
130
+ libgtk-3-0 \
131
+ libvulkan1 \
132
+ openbox \
133
+ plank \
134
+ python3 \
135
+ python3-dbus \
136
+ scrot \
137
+ thunar \
138
+ tigervnc-common \
139
+ tigervnc-standalone-server \
140
+ tumbler \
141
+ xauth \
142
+ xcompmgr \
143
+ xdotool \
144
+ xfonts-base \
145
+ xterm \
146
+ /tmp/wezterm.deb; \
147
+ wezterm --version; \
148
+ rm -rf /tmp/wezterm.deb /var/lib/apt/lists/* /var/cache/apt/archives/*.deb
149
+
150
+ # Extract Chrome without running package scripts or registering its repository.
151
+ RUN set -eu; \
152
+ chrome_version=153.0.8010.36-1; \
153
+ chrome_arch="$(dpkg --print-architecture)"; \
154
+ case "$chrome_arch" in \
155
+ amd64) chrome_sha256=9bb44e33031c2f2857cf36b4343051a12f93058e4b781e3c76313df87f6c8d32 ;; \
156
+ arm64) chrome_sha256=1fcf6ec51a9d52e26ff1ad807225f725be55069ad2b68c5d69361a2746665188 ;; \
157
+ *) echo "Unsupported Chrome architecture" >&2; exit 1 ;; \
158
+ esac; \
159
+ curl --fail --location --proto '=https' --proto-redir '=https' \
160
+ --retry 2 --max-time 300 --output /tmp/chrome.deb \
161
+ "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${chrome_version}_${chrome_arch}.deb"; \
162
+ printf '%s /tmp/chrome.deb\n' "$chrome_sha256" | sha256sum --check -; \
163
+ dpkg-deb --extract /tmp/chrome.deb /; \
164
+ /opt/google/chrome/chrome --version; \
165
+ rm /tmp/chrome.deb
166
+
104
167
  # Copy bun binary from builder instead of re-installing
105
168
  COPY --from=builder /root/.bun/bin/bun /usr/local/bin/bun
106
169
  RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
@@ -1,6 +1,8 @@
1
1
  # Virtual desktop browser CLI
2
2
 
3
- `assistant browser --virtual-desktop` uses the browser CLI's shared operation handlers against the Chrome process owned by `DesktopSessionManager`. It requires a platform-hosted container, the `assistant-desktop` flag, completed automatic desktop installation and an identified guardian conversation. Availability is checked before starting or reusing control and after asynchronous startup; loss of the flag or installation readiness cancels active control. The first eligible browser command waits for the shared installation job, starts Chrome, and executes the original action exactly once. Cancellation and feature revocation stop the pending action while shared installation can finish for other viewers. Browser CLI requests allow ten minutes, with an eight-minute setup wait limit. Eligible web conversations receive browser guidance in the bash tool description, including the configured shell timeout; native clients retain their existing tool description. Opening the picture-in-picture panel also starts setup and shows progress automatically; failed installs retain a retry action. The persistent profile remains `data/desktop-profile`; no data migration or extension installation is required.
3
+ `assistant browser --virtual-desktop` uses the browser CLI's shared operation handlers against the Chrome process owned by `DesktopSessionManager`. It requires a platform-hosted container, the `assistant-desktop` flag, image-provided desktop components and an identified guardian conversation. Availability is checked before starting or reusing control and after asynchronous startup; losing readiness or the feature flag cancels active control. The first eligible browser command starts Chrome and executes its action without downloading or installing dependencies. Opening the picture-in-picture panel checks readiness and starts the viewer directly. The persistent profile remains `data/desktop-profile`.
4
+
5
+ The assistant Dockerfile installs desktop system packages, pinned WezTerm and pinned Google Chrome before Bun and application source. Architecture-specific SHA-256 checksums verify both downloads. Chrome is extracted to `/opt/google/chrome` without running package scripts or registering its repository. Missing components require replacing the assistant image. Runtime code only checks readiness. `POST /v1/desktop/setup` remains a read-only compatibility endpoint for released clients; current clients only use GET.
4
6
 
5
7
  Automatic browser selection in platform-hosted web conversations uses the streamed Chrome when the desktop flag is enabled and the actor is an identified guardian. The macOS and Windows apps keep their existing browser selection and fallback behavior; they use the streamed desktop only with explicit `--virtual-desktop`. Their shared renderer reports a `web` transport, so selection also reads the active turn's frozen `clientOs`; it does not change transport identity or host capability checks. Explicit `--virtual-desktop`, `--browser-mode`, `--target-client-id` and active-tab requests override the default. Existing personal-browser sessions and tab pins remain on their selected browser. Tab commands use the same streamed-browser default as page commands. `--browser-mode local` selects assistant-side Playwright, not the user's Chrome.
6
8
 
@@ -16,7 +18,7 @@ flowchart LR
16
18
  Chrome --> Stream[Existing desktop stream]
17
19
  ```
18
20
 
19
- The Terminal dock launcher opens [WezTerm](https://wezterm.org/), with a plain dark native title bar, minimize/maximize/close controls, a new-tab button and split panes. Use Ctrl+Shift+T for a tab, Ctrl+Shift+D to split side by side, and Ctrl+Shift+E to split top and bottom. The desktop seeds an editable `data/desktop-panel/wezterm/wezterm.lua` configuration with software rendering and a dark theme. The managed launcher keeps its stable `data/desktop-panel/applications/xterm.desktop` path so existing dock pins remain valid. Setup installs an exact-version, SHA-256-verified WezTerm package for Linux x64 or ARM64, plus its rendering libraries.
21
+ The Terminal dock launcher opens [WezTerm](https://wezterm.org/), with a plain dark native title bar, minimize/maximize/close controls, a new-tab button and split panes. Use Ctrl+Shift+T for a tab, Ctrl+Shift+D to split side by side, and Ctrl+Shift+E to split top and bottom. The desktop seeds an editable `data/desktop-panel/wezterm/wezterm.lua` configuration with software rendering and a dark theme. The managed launcher keeps its stable `data/desktop-panel/applications/xterm.desktop` path so existing dock pins remain valid. The image includes an exact-version, SHA-256-verified WezTerm package for Linux x64 or ARM64, plus its rendering libraries.
20
22
 
21
23
  Chrome and WezTerm use explicit desktop window classes shared with their launcher entries. The desktop session bus and Plank share `XDG_DATA_HOME` so the D-Bus-activated window matcher can resolve the generated launchers and group running windows under their pinned icons.
22
24
 
@@ -34,9 +36,9 @@ The client records key and mouse presses before dispatch. On release it opens a
34
36
 
35
37
  `--use-active-tab` and personal browser targeting are rejected with `--virtual-desktop`. Download waiting is unsupported. Browser operations are bounded to two minutes and share the desktop lease's action budget and idle expiry.
36
38
 
37
- Validation: focused client tests exercise shared snapshot/click behavior, namespace isolation, stale references, target changes, cancellation and uncertain-input cleanup. Lease tests cover browser ownership, cancellation and cleanup independently of native input. The Linux smoke script exercises real Chrome, the CLI and visible pointer feedback.
39
+ Validation: focused client tests exercise shared snapshot/click behavior, namespace isolation, stale references, target changes, cancellation and uncertain-input cleanup. Lease tests cover browser ownership, cancellation and cleanup independently of native input. The Linux smoke script exercises real Chrome, the CLI and visible pointer feedback. For image replacement coverage, run `scripts/smoke-desktop-browser-cli.ts` in two disposable containers with the same workspace volume and networking disabled from first use. Both runs require baked components to be ready before navigation and assert that no installation progress is emitted. Each run needs a temporary `ASSISTANT_IPC_SOCKET_DIR`.
38
40
 
39
- The desktop header icon pulses in the assistant's avatar accent color while a browser automation lease is active, including between browser commands. It shares the progress indicator's accent and neutral fallback. Reduced-motion clients show a solid accent. Setup status exposes the optional `automationActive` field; `desktop_activity_changed` events refresh it on acquisition and cancellation or release. Installation progress retains its `assistant:self:desktop` sync invalidations. The indicator reads status without starting installation, and reconnects refetch the current lease state.
41
+ The desktop header icon pulses in the assistant's avatar accent color while a browser automation lease is active, including between browser commands. It shares the progress indicator's accent and neutral fallback. Reduced-motion clients show a solid accent. Setup status exposes the optional `automationActive` field; `desktop_activity_changed` events refresh it on acquisition and cancellation or release. The indicator reads status, and reconnects refetch the current lease state.
40
42
 
41
43
  Desktop streaming checks the current in-memory gateway feature flags during connection startup. Once connected, frame and drain callbacks do not check feature flags or load workspace configuration. Turning the flag off prevents new connections; an existing stream continues until it closes or the desktop stops.
42
44
 
@@ -50,8 +52,10 @@ Non-platform assistants keep their connected-computer behavior.
50
52
 
51
53
  Explicit `target: "connected-computer"` or `target_client_id` selects a connected
52
54
  computer on every client. The selected target never falls back to another
53
- computer when unavailable. Virtual desktop observations return full-screen
54
- screenshots and mouse actions use screen coordinates.
55
+ computer when unavailable. The virtual desktop uses a fixed 1440x810 display.
56
+ Observations return full-screen screenshots and mouse actions use the same
57
+ screen coordinates.
58
+ Viewer resizing scales the canvas locally without changing the desktop layout.
55
59
 
56
60
  Observe first and pass the returned `observation_id` with each native action.
57
61
  Browser commands, user handoff, errors, and interruption require a fresh
package/openapi.yaml CHANGED
@@ -12012,7 +12012,7 @@ paths:
12012
12012
  additionalProperties: false
12013
12013
  post:
12014
12014
  operationId: desktop_setup_post
12015
- summary: Install virtual desktop components
12015
+ summary: Check virtual desktop readiness (legacy POST)
12016
12016
  tags:
12017
12017
  - desktop
12018
12018
  responses:
@@ -21363,6 +21363,100 @@ paths:
21363
21363
  - redirectCount
21364
21364
  - durationMs
21365
21365
  additionalProperties: false
21366
+ recall:
21367
+ type: object
21368
+ properties:
21369
+ query:
21370
+ type: string
21371
+ depth:
21372
+ type: string
21373
+ enum:
21374
+ - fast
21375
+ - standard
21376
+ - deep
21377
+ sources:
21378
+ type: array
21379
+ items:
21380
+ type: string
21381
+ enum:
21382
+ - memory
21383
+ - conversations
21384
+ - workspace
21385
+ answer:
21386
+ type: string
21387
+ evidence:
21388
+ type: array
21389
+ items:
21390
+ type: object
21391
+ properties:
21392
+ source:
21393
+ type: string
21394
+ enum:
21395
+ - memory
21396
+ - conversations
21397
+ - workspace
21398
+ title:
21399
+ type: string
21400
+ locator:
21401
+ type: string
21402
+ excerpt:
21403
+ type: string
21404
+ timestampMs:
21405
+ type: number
21406
+ path:
21407
+ type: string
21408
+ conversationId:
21409
+ type: string
21410
+ messageId:
21411
+ type: string
21412
+ required:
21413
+ - source
21414
+ - title
21415
+ - locator
21416
+ - excerpt
21417
+ additionalProperties: false
21418
+ searchedSources:
21419
+ type: array
21420
+ items:
21421
+ type: object
21422
+ properties:
21423
+ source:
21424
+ type: string
21425
+ enum:
21426
+ - memory
21427
+ - conversations
21428
+ - workspace
21429
+ status:
21430
+ type: string
21431
+ enum:
21432
+ - searched
21433
+ - degraded
21434
+ evidenceCount:
21435
+ type: number
21436
+ error:
21437
+ type: string
21438
+ required:
21439
+ - source
21440
+ - status
21441
+ - evidenceCount
21442
+ additionalProperties: false
21443
+ required:
21444
+ - query
21445
+ - depth
21446
+ - sources
21447
+ - evidence
21448
+ - searchedSources
21449
+ additionalProperties: false
21450
+ remember:
21451
+ type: object
21452
+ properties:
21453
+ facts:
21454
+ type: array
21455
+ items:
21456
+ type: string
21457
+ required:
21458
+ - facts
21459
+ additionalProperties: false
21366
21460
  additionalProperties: false
21367
21461
  scopeOptions:
21368
21462
  type: array
@@ -21883,6 +21977,100 @@ paths:
21883
21977
  - redirectCount
21884
21978
  - durationMs
21885
21979
  additionalProperties: false
21980
+ recall:
21981
+ type: object
21982
+ properties:
21983
+ query:
21984
+ type: string
21985
+ depth:
21986
+ type: string
21987
+ enum:
21988
+ - fast
21989
+ - standard
21990
+ - deep
21991
+ sources:
21992
+ type: array
21993
+ items:
21994
+ type: string
21995
+ enum:
21996
+ - memory
21997
+ - conversations
21998
+ - workspace
21999
+ answer:
22000
+ type: string
22001
+ evidence:
22002
+ type: array
22003
+ items:
22004
+ type: object
22005
+ properties:
22006
+ source:
22007
+ type: string
22008
+ enum:
22009
+ - memory
22010
+ - conversations
22011
+ - workspace
22012
+ title:
22013
+ type: string
22014
+ locator:
22015
+ type: string
22016
+ excerpt:
22017
+ type: string
22018
+ timestampMs:
22019
+ type: number
22020
+ path:
22021
+ type: string
22022
+ conversationId:
22023
+ type: string
22024
+ messageId:
22025
+ type: string
22026
+ required:
22027
+ - source
22028
+ - title
22029
+ - locator
22030
+ - excerpt
22031
+ additionalProperties: false
22032
+ searchedSources:
22033
+ type: array
22034
+ items:
22035
+ type: object
22036
+ properties:
22037
+ source:
22038
+ type: string
22039
+ enum:
22040
+ - memory
22041
+ - conversations
22042
+ - workspace
22043
+ status:
22044
+ type: string
22045
+ enum:
22046
+ - searched
22047
+ - degraded
22048
+ evidenceCount:
22049
+ type: number
22050
+ error:
22051
+ type: string
22052
+ required:
22053
+ - source
22054
+ - status
22055
+ - evidenceCount
22056
+ additionalProperties: false
22057
+ required:
22058
+ - query
22059
+ - depth
22060
+ - sources
22061
+ - evidence
22062
+ - searchedSources
22063
+ additionalProperties: false
22064
+ remember:
22065
+ type: object
22066
+ properties:
22067
+ facts:
22068
+ type: array
22069
+ items:
22070
+ type: string
22071
+ required:
22072
+ - facts
22073
+ additionalProperties: false
21886
22074
  additionalProperties: false
21887
22075
  scopeOptions:
21888
22076
  type: array
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.12.2-dev.202609211820.22f71b0",
3
+ "version": "0.12.2-dev.202609212016.fb4c53e",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -14,26 +14,18 @@ import { registerBrowserCommand } from "../src/cli/commands/browser.js";
14
14
  import { DesktopAutomationLease } from "../src/desktop/desktop-automation-lease.js";
15
15
  import {
16
16
  desktopChromePath,
17
- desktopDependencyInstaller,
17
+ desktopDependencies,
18
18
  } from "../src/desktop/desktop-dependencies.js";
19
19
  import { DesktopSessionManager } from "../src/desktop/desktop-session-manager.js";
20
20
  import { getAssistantSocketPath } from "../src/ipc/socket-path.js";
21
21
 
22
- if (
23
- process.platform !== "linux" ||
24
- !process.argv[2] ||
25
- !process.env.ASSISTANT_IPC_SOCKET_DIR
26
- ) {
22
+ if (process.platform !== "linux" || !process.env.ASSISTANT_IPC_SOCKET_DIR) {
27
23
  throw new Error(
28
- "Run in disposable Linux with desktop packages, a temporary ASSISTANT_IPC_SOCKET_DIR and a Chrome executable argument or --install for a cold install.",
24
+ "Run in a disposable Linux assistant image with a temporary ASSISTANT_IPC_SOCKET_DIR.",
29
25
  );
30
26
  }
31
- const coldInstall = process.argv[2] === "--install";
32
- const executable = coldInstall ? desktopChromePath() : process.argv[2];
33
- if (coldInstall) {
34
- assert.equal(desktopDependencyInstaller.getStatus().state, "required");
35
- assert.equal(Bun.which("Xtigervnc"), null);
36
- }
27
+ const executable = desktopChromePath();
28
+ assert.equal(desktopDependencies.getStatus().state, "ready");
37
29
  const directory = await mkdtemp(join(tmpdir(), "desktop-browser-cli-"));
38
30
  const manager = new DesktopSessionManager({
39
31
  resolveChromePath: async () => executable,
@@ -44,9 +36,7 @@ const manager = new DesktopSessionManager({
44
36
  const control = new DesktopAutomationLease({
45
37
  notify: async () => {},
46
38
  enabled: () => true,
47
- ready: () =>
48
- !coldInstall || desktopDependencyInstaller.getStatus().state === "ready",
49
- ensureReady: (signal) => desktopDependencyInstaller.ensureReady(signal),
39
+ ready: () => desktopDependencies.getStatus().state === "ready",
50
40
  manager: () => manager,
51
41
  });
52
42
  const context = {
@@ -182,16 +172,10 @@ try {
182
172
  "--allow-private-network",
183
173
  );
184
174
  assert.equal(navigations, 1);
185
- if (coldInstall) {
186
- assert.equal(desktopDependencyInstaller.getStatus().state, "ready");
187
- assert(
188
- setupNotifications >= 3,
189
- "Installation progress must reach the viewer",
190
- );
191
- console.error(
192
- "PASS: one CLI navigate installed desktop and Chrome from scratch, then loaded the requested page once",
193
- );
194
- }
175
+ assert.equal(setupNotifications, 0);
176
+ console.error(
177
+ "PASS: baked desktop opened the requested page without installation",
178
+ );
195
179
  const snapshot = await cli("snapshot");
196
180
  await cli(
197
181
  "type",