Files
oh-my-pi/packages/coding-agent/test/slash-commands/computer.test.ts
T
can1357 681d7daf65 feat(computer): unified native addon, /computer toggle, function tool
- Replaced the separate GUI-linked pi_natives.desktop.linux-x64 addon with
  a pure-Rust X11 backend (x11rb RustConnection capture via RandR/GetImage,
  XTest input with keysym mapping) compiled into the core addon on every
  published target; Linux arm64 and musl are now supported and headless
  hosts load the addon unaffected.
- Removed the native-desktop-linux cargo feature, desktop_unsupported.rs,
  lazy desktop loader, second napi build, desktop packaging/CI steps, GUI
  build dependencies, and the now-unreferenced vendored libspa crate;
  reverted setup-system-deps to main.
- Preserved the desktop input hardening semantics on the unified backend:
  XTest layouts reject negative origins and coordinates beyond 0..=32767,
  batch coordinates stay bound to the frame last returned to JS with
  intermediate screenshots deferred, coordinate input requires a
  previously returned frame, and failed chord releases still release
  every held key.
- Enforced a 60s worker-side execute deadline (DESKTOP_DEADLINE_EXCEEDED):
  no input is emitted after expiry and wait-heavy batches are rejected
  upfront.
- Added int32 fail-closed validation for coordinates, drag points, and
  scroll deltas at the JS ingress and gateway schema.
- Exposed computer to models without native OpenAI computer-use support as
  a regular function tool with a typed GA action schema across OpenAI,
  Azure, and Codex Responses providers, including named forced choice.
- Added the /computer slash command (on/off/status/toggle) for
  session-only enablement via runtime tool registration in SessionTools.
- Updated docs, changelogs, and contract tests accordingly.
2026-07-24 01:40:05 +00:00

85 lines
3.5 KiB
TypeScript

import { describe, expect, it, vi } from "bun:test";
import { executeAcpBuiltinSlashCommand } from "@oh-my-pi/pi-coding-agent/slash-commands/acp-builtins";
import type { SlashCommandRuntime } from "@oh-my-pi/pi-coding-agent/slash-commands/types";
function acpRuntime(options?: { enabled?: boolean; applyResult?: boolean }) {
const store = { "computer.enabled": options?.enabled ?? false };
const get = vi.fn((path: string) => store[path as keyof typeof store]);
const override = vi.fn((path: string, value: boolean) => {
store[path as keyof typeof store] = value;
});
const set = vi.fn();
const setComputerToolEnabled = vi.fn(async () => options?.applyResult ?? true);
const output = vi.fn();
const runtime = {
session: { settings: { get, override, set }, setComputerToolEnabled },
output,
} as unknown as SlashCommandRuntime;
return { get, override, set, setComputerToolEnabled, output, runtime };
}
describe("/computer slash command", () => {
it("toggles a disabled session on: slate refresh first, then session-only override", async () => {
const h = acpRuntime({ enabled: false });
const result = await executeAcpBuiltinSlashCommand("/computer", h.runtime);
expect(result).toEqual({ consumed: true });
expect(h.setComputerToolEnabled).toHaveBeenCalledWith(true);
expect(h.override).toHaveBeenCalledWith("computer.enabled", true);
expect(h.set).not.toHaveBeenCalled();
expect(h.output).toHaveBeenCalledWith("Computer use enabled for this session.");
});
it("toggles an enabled session off", async () => {
const h = acpRuntime({ enabled: true });
await executeAcpBuiltinSlashCommand("/computer", h.runtime);
expect(h.setComputerToolEnabled).toHaveBeenCalledWith(false);
expect(h.override).toHaveBeenCalledWith("computer.enabled", false);
expect(h.output).toHaveBeenCalledWith("Computer use disabled for this session.");
});
it("honors explicit on/off regardless of current state", async () => {
const on = acpRuntime({ enabled: true });
await executeAcpBuiltinSlashCommand("/computer on", on.runtime);
expect(on.setComputerToolEnabled).toHaveBeenCalledWith(true);
expect(on.override).toHaveBeenCalledWith("computer.enabled", true);
const off = acpRuntime({ enabled: false });
await executeAcpBuiltinSlashCommand("/computer off", off.runtime);
expect(off.setComputerToolEnabled).toHaveBeenCalledWith(false);
expect(off.override).toHaveBeenCalledWith("computer.enabled", false);
});
it("reports status without touching the tool slate or settings", async () => {
const h = acpRuntime({ enabled: true });
await executeAcpBuiltinSlashCommand("/computer status", h.runtime);
expect(h.setComputerToolEnabled).not.toHaveBeenCalled();
expect(h.override).not.toHaveBeenCalled();
expect(h.output).toHaveBeenCalledWith("Computer use is on.");
});
it("leaves the override untouched when the session cannot build the tool", async () => {
const h = acpRuntime({ enabled: false, applyResult: false });
await executeAcpBuiltinSlashCommand("/computer on", h.runtime);
expect(h.setComputerToolEnabled).toHaveBeenCalledWith(true);
expect(h.override).not.toHaveBeenCalled();
expect(h.output).toHaveBeenCalledWith("Computer use is unavailable in this session.");
});
it("rejects unknown arguments with usage", async () => {
const h = acpRuntime();
await executeAcpBuiltinSlashCommand("/computer bogus", h.runtime);
expect(h.setComputerToolEnabled).not.toHaveBeenCalled();
expect(h.output).toHaveBeenCalledWith("Usage: /computer [on|off|status]");
});
});