@onkernel/cua-agent 0.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Class-first CUA runtime: `CuaAgent` and `CuaHarness` on top of pi-agent-core.
6
+ - Provider-neutral browser tool executors for canonical CUA tool names, backed by Kernel browser actions.
7
+ - Includes examples plus unit and live e2e coverage for common provider/model combinations.
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # `@onkernel/cua-agent`
2
+
3
+ Kernel browser computer-use classes built on
4
+ [`@earendil-works/pi-agent-core`](https://github.com/earendil-works/pi/tree/main/packages/agent).
5
+
6
+ This package keeps pi-agent-core semantics intact and adds browser execution
7
+ plumbing for canonical CUA tools.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @onkernel/cua-agent @onkernel/cua-ai @onkernel/sdk
13
+ ```
14
+
15
+ ## Quick Start (`CuaAgent`)
16
+
17
+ ```ts
18
+ import Kernel from "@onkernel/sdk";
19
+ import { CuaAgent } from "@onkernel/cua-agent";
20
+
21
+ const client = new Kernel({ apiKey: process.env.KERNEL_API_KEY! });
22
+ const browser = await client.browsers.create({ stealth: true });
23
+
24
+ const agent = new CuaAgent({
25
+ browser,
26
+ client,
27
+ initialState: {
28
+ model: "openai:gpt-5.5",
29
+ systemPrompt: "You are a careful browser automation agent.",
30
+ },
31
+ });
32
+
33
+ await agent.prompt("Open news.ycombinator.com and summarize the top story.");
34
+ ```
35
+
36
+ ## Quick Start (`CuaHarness`)
37
+
38
+ ```ts
39
+ import { CuaHarness } from "@onkernel/cua-agent";
40
+
41
+ const harness = new CuaHarness({
42
+ browser,
43
+ client,
44
+ model: "openai:gpt-5.5",
45
+ });
46
+
47
+ await harness.prompt("Open example.com and tell me the current URL.");
48
+ const transcript = harness.getTranscript();
49
+ console.log("messages in transcript:", transcript.length);
50
+ ```
51
+
52
+ Use `CuaAgent` when you want direct pi `Agent` control: raw transcript state,
53
+ lifecycle events, custom streaming, and explicit prompt/continue/queue control.
54
+ Reach for the harness shape when you want an app layer around the loop:
55
+ session/transcript helpers, resource and prompt entry points, provider/auth
56
+ hooks, active tool selection, compaction/tree workflows, and higher-level queue
57
+ events. `CuaHarness` is the thin CUA version of that shape today: it installs
58
+ CUA defaults, delegates runtime methods to the wrapped `Agent`, and adds
59
+ `getTranscript()`.
60
+
61
+ ## Core Concepts
62
+
63
+ ### Class-First API
64
+
65
+ - `CuaAgent extends Agent`
66
+ - `CuaHarness` wraps a pi `Agent` with a harness-style constructor and
67
+ delegated runtime methods.
68
+
69
+ Both classes mirror pi constructor shapes and behavior, with minimal additions:
70
+ - `browser` (Kernel browser response)
71
+ - `client` (Kernel SDK client)
72
+ - CUA model refs (`"provider:model"`) accepted where pi expects a concrete model
73
+
74
+ If `getApiKey` is omitted, both classes default to CUA env var conventions:
75
+ - OpenAI: `OPENAI_API_KEY`
76
+ - Anthropic: `ANTHROPIC_OAUTH_TOKEN` or `ANTHROPIC_API_KEY`
77
+ - Gemini: `GOOGLE_API_KEY` or `GEMINI_API_KEY`
78
+ - Tzafon: `TZAFON_API_KEY`
79
+ - Yutori: `YUTORI_API_KEY`
80
+
81
+ ### Tool Defaults
82
+
83
+ If tools are omitted, the classes install canonical CUA computer tool executors
84
+ using runtime specs from `@onkernel/cua-ai`. If tools are provided, they are
85
+ used exactly.
86
+
87
+ ### Tool Composition
88
+
89
+ Use `createCuaComputerTools()` to compose your own tool list from canonical
90
+ tool definitions:
91
+
92
+ ```ts
93
+ import { resolveCuaRuntimeSpec } from "@onkernel/cua-ai";
94
+ import { createCuaComputerTools } from "@onkernel/cua-agent";
95
+
96
+ const runtime = resolveCuaRuntimeSpec("openai:gpt-5.5");
97
+ const tools = [
98
+ ...createCuaComputerTools({
99
+ browser,
100
+ client,
101
+ toolDefinitions: runtime.toolDefinitions,
102
+ }),
103
+ myCustomTool,
104
+ ];
105
+ ```
106
+
107
+ For full event semantics, steering, follow-up queues, and tool execution
108
+ details, see the pi-agent-core README.
@@ -0,0 +1,46 @@
1
+ import { Agent, type AgentOptions, type AgentTool, type AgentEvent, type AgentMessage } from "@earendil-works/pi-agent-core";
2
+ import { type ImageContent, type Api, type Model, type CuaModelRef } from "@onkernel/cua-ai";
3
+ import type Kernel from "@onkernel/sdk";
4
+ import type { KernelBrowser } from "./translator/translator.js";
5
+ type CuaAgentInitialState = Omit<NonNullable<AgentOptions["initialState"]>, "model" | "tools"> & {
6
+ model: CuaModelRef | Model<Api>;
7
+ tools?: AgentTool[];
8
+ };
9
+ export type CuaAgentOptions = Omit<AgentOptions, "initialState"> & {
10
+ browser: KernelBrowser;
11
+ client: Kernel;
12
+ initialState: CuaAgentInitialState;
13
+ };
14
+ export type CuaHarnessOptions = Omit<AgentOptions, "initialState"> & {
15
+ browser: KernelBrowser;
16
+ client: Kernel;
17
+ model: CuaModelRef | Model<Api>;
18
+ tools?: AgentTool[];
19
+ systemPrompt?: string;
20
+ };
21
+ export declare class CuaAgent extends Agent {
22
+ constructor(options: CuaAgentOptions);
23
+ }
24
+ export declare class CuaHarness {
25
+ readonly agent: Agent;
26
+ constructor(options: CuaHarnessOptions);
27
+ get state(): import("@earendil-works/pi-agent-core").AgentState;
28
+ get steeringMode(): "all" | "one-at-a-time";
29
+ set steeringMode(mode: "all" | "one-at-a-time");
30
+ get followUpMode(): "all" | "one-at-a-time";
31
+ set followUpMode(mode: "all" | "one-at-a-time");
32
+ subscribe(listener: (event: AgentEvent, signal: AbortSignal) => Promise<void> | void): () => void;
33
+ prompt(message: AgentMessage | AgentMessage[]): Promise<void>;
34
+ prompt(input: string, images?: ImageContent[]): Promise<void>;
35
+ steer(message: AgentMessage): void;
36
+ followUp(message: AgentMessage): void;
37
+ continue(): Promise<void>;
38
+ clearSteeringQueue(): void;
39
+ clearFollowUpQueue(): void;
40
+ clearAllQueues(): void;
41
+ abort(): void;
42
+ waitForIdle(): Promise<void>;
43
+ getTranscript(): AgentMessage[];
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,EACL,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,GAAG,EACR,KAAK,KAAK,EACV,KAAK,WAAW,EAIhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,KAAK,oBAAoB,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG;IAChG,KAAK,EAAE,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG;IAClE,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,oBAAoB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG;IACpE,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qBAAa,QAAS,SAAQ,KAAK;gBACtB,OAAO,EAAE,eAAe;CAmBpC;AAED,qBAAa,UAAU;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;gBAEV,OAAO,EAAE,iBAAiB;IAiBtC,IAAI,KAAK,uDAER;IAED,IAAI,YAAY,IAIO,KAAK,GAAG,eAAe,CAF7C;IAED,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,EAE7C;IAED,IAAI,YAAY,IAIO,KAAK,GAAG,eAAe,CAF7C;IAED,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,EAE7C;IAED,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,IAAI;IAI3F,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASnE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIlC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAI/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,kBAAkB,IAAI,IAAI;IAI1B,kBAAkB,IAAI,IAAI;IAI1B,cAAc,IAAI,IAAI;IAItB,KAAK,IAAI,IAAI;IAIP,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC,aAAa,IAAI,YAAY,EAAE;CAG/B"}
package/dist/agent.js ADDED
@@ -0,0 +1,105 @@
1
+ import { Agent, } from "@earendil-works/pi-agent-core";
2
+ import { getCuaEnvApiKey, resolveCuaRuntimeSpec, streamSimple, } from "@onkernel/cua-ai";
3
+ import { createCuaComputerTools } from "./tools.js";
4
+ export class CuaAgent extends Agent {
5
+ constructor(options) {
6
+ const { browser, client, initialState, onPayload, streamFn, ...agentOptions } = options;
7
+ const runtimeSpec = resolveCuaRuntimeSpec(initialState.model);
8
+ const tools = initialState.tools ?? createCuaComputerTools({ browser, client, toolDefinitions: runtimeSpec.toolDefinitions });
9
+ const systemPrompt = initialState.systemPrompt ?? runtimeSpec.defaultSystemPrompt;
10
+ super({
11
+ ...agentOptions,
12
+ getApiKey: agentOptions.getApiKey ?? getCuaEnvApiKey,
13
+ streamFn: streamFn ?? streamSimple,
14
+ onPayload: composeOnPayload(runtimeSpec.onPayload, onPayload),
15
+ initialState: {
16
+ ...initialState,
17
+ model: runtimeSpec.model,
18
+ tools,
19
+ systemPrompt,
20
+ },
21
+ });
22
+ }
23
+ }
24
+ export class CuaHarness {
25
+ agent;
26
+ constructor(options) {
27
+ const { browser, client, model, tools, systemPrompt, onPayload, streamFn, ...agentOptions } = options;
28
+ const runtimeSpec = resolveCuaRuntimeSpec(model);
29
+ const resolvedTools = tools ?? createCuaComputerTools({ browser, client, toolDefinitions: runtimeSpec.toolDefinitions });
30
+ this.agent = new Agent({
31
+ ...agentOptions,
32
+ getApiKey: agentOptions.getApiKey ?? getCuaEnvApiKey,
33
+ streamFn: streamFn ?? streamSimple,
34
+ onPayload: composeOnPayload(runtimeSpec.onPayload, onPayload),
35
+ initialState: {
36
+ model: runtimeSpec.model,
37
+ tools: resolvedTools,
38
+ systemPrompt: systemPrompt ?? runtimeSpec.defaultSystemPrompt,
39
+ },
40
+ });
41
+ }
42
+ get state() {
43
+ return this.agent.state;
44
+ }
45
+ get steeringMode() {
46
+ return this.agent.steeringMode;
47
+ }
48
+ set steeringMode(mode) {
49
+ this.agent.steeringMode = mode;
50
+ }
51
+ get followUpMode() {
52
+ return this.agent.followUpMode;
53
+ }
54
+ set followUpMode(mode) {
55
+ this.agent.followUpMode = mode;
56
+ }
57
+ subscribe(listener) {
58
+ return this.agent.subscribe(listener);
59
+ }
60
+ async prompt(input, images) {
61
+ if (typeof input === "string") {
62
+ await this.agent.prompt(input, images);
63
+ return;
64
+ }
65
+ await this.agent.prompt(input);
66
+ }
67
+ steer(message) {
68
+ this.agent.steer(message);
69
+ }
70
+ followUp(message) {
71
+ this.agent.followUp(message);
72
+ }
73
+ async continue() {
74
+ await this.agent.continue();
75
+ }
76
+ clearSteeringQueue() {
77
+ this.agent.clearSteeringQueue();
78
+ }
79
+ clearFollowUpQueue() {
80
+ this.agent.clearFollowUpQueue();
81
+ }
82
+ clearAllQueues() {
83
+ this.agent.clearAllQueues();
84
+ }
85
+ abort() {
86
+ this.agent.abort();
87
+ }
88
+ async waitForIdle() {
89
+ await this.agent.waitForIdle();
90
+ }
91
+ getTranscript() {
92
+ return [...this.agent.state.messages];
93
+ }
94
+ }
95
+ function composeOnPayload(first, second) {
96
+ if (!first)
97
+ return second;
98
+ if (!second)
99
+ return first;
100
+ return async (payload, modelRef) => {
101
+ const afterFirst = await first(payload, modelRef);
102
+ return second(afterFirst ?? payload, modelRef);
103
+ };
104
+ }
105
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from "@earendil-works/pi-agent-core";
2
+ export type { KernelBrowser } from "./translator/translator.js";
3
+ export { createCuaComputerTools } from "./tools.js";
4
+ export type { BatchDetails, ComputerToolOptions, CuaExecutorTool, NavigationDetails, SupportedCuaExecutorToolName, } from "./tools.js";
5
+ export { SUPPORTED_CUA_EXECUTOR_TOOL_NAMES } from "./tools.js";
6
+ export { CuaAgent, CuaHarness } from "./agent.js";
7
+ export type { CuaAgentOptions, CuaHarnessOptions } from "./agent.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAE9C,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjD,YAAY,EACX,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,4BAA4B,GAC5B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iCAAiC,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "@earendil-works/pi-agent-core";
2
+ export { createCuaComputerTools } from "./tools.js";
3
+ export { SUPPORTED_CUA_EXECUTOR_TOOL_NAMES } from "./tools.js";
4
+ export { CuaAgent, CuaHarness } from "./agent.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAQjD,OAAO,EAAE,iCAAiC,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type Kernel from "@onkernel/sdk";
2
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
3
+ import type { Tool } from "@earendil-works/pi-ai";
4
+ import { CuaBatchSchema, CuaNavigationSchema } from "@onkernel/cua-ai";
5
+ import { type KernelBrowser } from "./translator/translator.js";
6
+ export interface ComputerToolOptions {
7
+ browser: KernelBrowser;
8
+ client: Kernel;
9
+ toolDefinitions: Tool[];
10
+ }
11
+ export declare const SUPPORTED_CUA_EXECUTOR_TOOL_NAMES: readonly ["batch_computer_actions", "computer_use_extra"];
12
+ export type SupportedCuaExecutorToolName = (typeof SUPPORTED_CUA_EXECUTOR_TOOL_NAMES)[number];
13
+ export interface BatchDetails {
14
+ statusText: string;
15
+ readResults: Array<{
16
+ type: "url";
17
+ url: string;
18
+ } | {
19
+ type: "screenshot";
20
+ bytes: number;
21
+ } | {
22
+ type: "cursor_position";
23
+ x: number;
24
+ y: number;
25
+ }>;
26
+ error?: string;
27
+ }
28
+ export interface NavigationDetails {
29
+ action: string;
30
+ statusText: string;
31
+ url?: string;
32
+ error?: string;
33
+ }
34
+ type BatchTool = AgentTool<typeof CuaBatchSchema, BatchDetails>;
35
+ type NavigationTool = AgentTool<typeof CuaNavigationSchema, NavigationDetails>;
36
+ export type CuaExecutorTool = BatchTool | NavigationTool;
37
+ export declare function createCuaComputerTools(args: ComputerToolOptions): CuaExecutorTool[];
38
+ export {};
39
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,+BAA+B,CAAC;AAChF,OAAO,KAAK,EAA6B,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAGN,cAAc,EACd,mBAAmB,EAGnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAEzF,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,IAAI,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,iCAAiC,2DAA2D,CAAC;AAC1G,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAC;AAI9F,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7I,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,KAAK,SAAS,GAAG,SAAS,CAAC,OAAO,cAAc,EAAE,YAAY,CAAC,CAAC;AAChE,KAAK,cAAc,GAAG,SAAS,CAAC,OAAO,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,cAAc,CAAC;AAEzD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,EAAE,CAGnF"}
package/dist/tools.js ADDED
@@ -0,0 +1,116 @@
1
+ import { CUA_BATCH_TOOL_NAME, CUA_NAVIGATION_TOOL_NAME, CuaBatchSchema, CuaNavigationSchema, } from "@onkernel/cua-ai";
2
+ import { InternalComputerTranslator } from "./translator/translator.js";
3
+ export const SUPPORTED_CUA_EXECUTOR_TOOL_NAMES = [CUA_BATCH_TOOL_NAME, CUA_NAVIGATION_TOOL_NAME];
4
+ export function createCuaComputerTools(args) {
5
+ const translator = new InternalComputerTranslator(args);
6
+ return args.toolDefinitions.map((definition) => createExecutorTool(definition, translator));
7
+ }
8
+ function createExecutorTool(definition, translator) {
9
+ if (definition.name === CUA_BATCH_TOOL_NAME) {
10
+ const tool = {
11
+ name: definition.name,
12
+ label: definition.name,
13
+ description: definition.description,
14
+ parameters: CuaBatchSchema,
15
+ async execute(_toolCallId, params) {
16
+ const result = await executeBatchTool(translator, asBatchInput(params));
17
+ if (result.isError)
18
+ throw Object.assign(new Error(result.details.statusText), result);
19
+ return { content: result.content, details: result.details };
20
+ },
21
+ };
22
+ return tool;
23
+ }
24
+ if (definition.name === CUA_NAVIGATION_TOOL_NAME) {
25
+ const tool = {
26
+ name: definition.name,
27
+ label: definition.name,
28
+ description: definition.description,
29
+ parameters: CuaNavigationSchema,
30
+ async execute(_toolCallId, params) {
31
+ const result = await executeNavigationTool(translator, asNavigationInput(params));
32
+ if (result.isError)
33
+ throw Object.assign(new Error(result.details.statusText), result);
34
+ return { content: result.content, details: result.details };
35
+ },
36
+ };
37
+ return tool;
38
+ }
39
+ throw new Error(`unsupported CUA computer tool definition: ${definition.name}; supported names: ${SUPPORTED_CUA_EXECUTOR_TOOL_NAMES.join(", ")}`);
40
+ }
41
+ async function executeBatchTool(translator, params) {
42
+ const content = [];
43
+ const readResults = [];
44
+ let statusText = "Actions executed successfully.";
45
+ let error;
46
+ try {
47
+ const result = await translator.executeBatch(params.actions);
48
+ for (const read of result.readResults) {
49
+ if (read.type === "url") {
50
+ readResults.push({ type: "url", url: read.url });
51
+ content.push({ type: "text", text: `url(): ${read.url}` });
52
+ }
53
+ else if (read.type === "cursor_position") {
54
+ readResults.push({ type: "cursor_position", x: read.x, y: read.y });
55
+ content.push({ type: "text", text: `cursor_position(): ${read.x},${read.y}` });
56
+ }
57
+ else {
58
+ readResults.push({ type: "screenshot", bytes: read.pngBytes.length });
59
+ content.push({ type: "image", data: read.pngBytes.toString("base64"), mimeType: "image/png" });
60
+ }
61
+ }
62
+ if (content.length === 0) {
63
+ const png = await translator.screenshotRaw();
64
+ readResults.push({ type: "screenshot", bytes: png.length });
65
+ content.push({ type: "image", data: png.toString("base64"), mimeType: "image/png" });
66
+ }
67
+ }
68
+ catch (err) {
69
+ error = err instanceof Error ? err : new Error(String(err));
70
+ statusText = `Actions failed: ${error.message}`;
71
+ content.push({ type: "text", text: statusText });
72
+ }
73
+ return { content, details: { statusText, readResults, ...(error ? { error: error.message } : {}) }, isError: Boolean(error) };
74
+ }
75
+ async function executeNavigationTool(translator, params) {
76
+ const action = params.action;
77
+ const content = [];
78
+ let statusText = "Action executed successfully.";
79
+ let url;
80
+ let error;
81
+ try {
82
+ if (action === "url") {
83
+ url = await translator.currentUrl();
84
+ statusText = `Current URL: ${url}`;
85
+ }
86
+ else {
87
+ await translator.executeBatch([{ type: action, url: params.url }]);
88
+ statusText = `${action} executed successfully.`;
89
+ }
90
+ const png = await translator.screenshotRaw();
91
+ content.push({ type: "image", data: png.toString("base64"), mimeType: "image/png" });
92
+ }
93
+ catch (err) {
94
+ error = err instanceof Error ? err : new Error(String(err));
95
+ statusText = `${action} failed: ${error.message}`;
96
+ }
97
+ content.unshift({ type: "text", text: statusText });
98
+ return { content, details: { action, statusText, ...(url ? { url } : {}), ...(error ? { error: error.message } : {}) }, isError: Boolean(error) };
99
+ }
100
+ function asBatchInput(value) {
101
+ if (value &&
102
+ typeof value === "object" &&
103
+ Array.isArray(value.actions)) {
104
+ return value;
105
+ }
106
+ throw new Error("invalid batch_computer_actions parameters");
107
+ }
108
+ function asNavigationInput(value) {
109
+ if (value &&
110
+ typeof value === "object" &&
111
+ typeof value.action === "string") {
112
+ return value;
113
+ }
114
+ throw new Error("invalid computer_use_extra parameters");
115
+ }
116
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type Kernel from "@onkernel/sdk";
2
+ import type { BrowserCreateResponse, BrowserRetrieveResponse } from "@onkernel/sdk/resources/browsers";
3
+ import type { BatchExecutionResult, ModelAction } from "./types.js";
4
+ export type KernelBrowser = BrowserCreateResponse | BrowserRetrieveResponse;
5
+ export interface InternalComputerTranslatorOptions {
6
+ browser: KernelBrowser;
7
+ client: Kernel;
8
+ }
9
+ export declare class InternalComputerTranslator {
10
+ private readonly sessionId;
11
+ private readonly client;
12
+ constructor(opts: InternalComputerTranslatorOptions);
13
+ screenshotRaw(): Promise<Buffer>;
14
+ currentUrl(): Promise<string>;
15
+ currentMousePosition(): Promise<{
16
+ x: number;
17
+ y: number;
18
+ }>;
19
+ executeBatch(actions: ModelAction[]): Promise<BatchExecutionResult>;
20
+ private runKernelBatch;
21
+ }
22
+ //# sourceMappingURL=translator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.d.ts","sourceRoot":"","sources":["../../src/translator/translator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACvG,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,qBAAqB,GAAG,uBAAuB,CAAC;AAE5E,MAAM,WAAW,iCAAiC;IACjD,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,0BAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,IAAI,EAAE,iCAAiC;IAK7C,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAS7B,oBAAoB,IAAI,OAAO,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAKzD,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;YAmD3D,cAAc;CAG5B"}
@@ -0,0 +1,170 @@
1
+ export class InternalComputerTranslator {
2
+ sessionId;
3
+ client;
4
+ constructor(opts) {
5
+ this.sessionId = opts.browser.session_id;
6
+ this.client = opts.client;
7
+ }
8
+ async screenshotRaw() {
9
+ const response = await this.client.browsers.computer.captureScreenshot(this.sessionId, {});
10
+ return Buffer.from(await response.arrayBuffer());
11
+ }
12
+ async currentUrl() {
13
+ await this.runKernelBatch([
14
+ { type: "press_key", press_key: { keys: ["Control_L", "l"] } },
15
+ { type: "press_key", press_key: { keys: ["Control_L", "c"] } },
16
+ ]);
17
+ const response = await this.client.browsers.computer.readClipboard(this.sessionId);
18
+ return (response.text ?? "").trim();
19
+ }
20
+ async currentMousePosition() {
21
+ const pos = await this.client.browsers.computer.getMousePosition(this.sessionId);
22
+ return { x: toInt(pos.x), y: toInt(pos.y) };
23
+ }
24
+ async executeBatch(actions) {
25
+ const result = { readResults: [] };
26
+ const pending = [];
27
+ const flush = async () => {
28
+ if (pending.length === 0)
29
+ return;
30
+ await this.runKernelBatch(pending.splice(0));
31
+ };
32
+ for (let i = 0; i < actions.length; i++) {
33
+ const action = actions[i];
34
+ const type = typeof action.type === "string" ? action.type : "";
35
+ if (type === "screenshot") {
36
+ await flush();
37
+ result.readResults.push({ type: "screenshot", pngBytes: await this.screenshotRaw() });
38
+ continue;
39
+ }
40
+ if (type === "url") {
41
+ await flush();
42
+ result.readResults.push({ type: "url", url: await this.currentUrl() });
43
+ continue;
44
+ }
45
+ if (type === "cursor_position") {
46
+ await flush();
47
+ const pos = await this.currentMousePosition();
48
+ result.readResults.push({ type: "cursor_position", ...pos });
49
+ continue;
50
+ }
51
+ if (type === "goto") {
52
+ pending.push({ type: "press_key", press_key: { keys: ["Control_L", "l"] } }, { type: "type_text", type_text: { text: stringOr(action.url, "") } }, { type: "press_key", press_key: { keys: ["Enter"] } });
53
+ continue;
54
+ }
55
+ if (type === "back") {
56
+ pending.push({ type: "press_key", press_key: { keys: ["Alt_L", "Left"] } });
57
+ continue;
58
+ }
59
+ if (type === "forward") {
60
+ pending.push({ type: "press_key", press_key: { keys: ["Alt_L", "Right"] } });
61
+ continue;
62
+ }
63
+ pending.push(toSdkAction(type, action));
64
+ }
65
+ await flush();
66
+ return result;
67
+ }
68
+ async runKernelBatch(actions) {
69
+ await this.client.browsers.computer.batch(this.sessionId, { actions });
70
+ }
71
+ }
72
+ function toSdkAction(type, action) {
73
+ switch (type) {
74
+ case "click":
75
+ return {
76
+ type: "click_mouse",
77
+ click_mouse: {
78
+ x: toInt(action.x),
79
+ y: toInt(action.y),
80
+ button: clickMouseButtonOr(action.button, "left"),
81
+ },
82
+ };
83
+ case "double_click":
84
+ return {
85
+ type: "click_mouse",
86
+ click_mouse: {
87
+ x: toInt(action.x),
88
+ y: toInt(action.y),
89
+ num_clicks: 2,
90
+ },
91
+ };
92
+ case "mouse_down":
93
+ case "mouse_up":
94
+ return {
95
+ type: "click_mouse",
96
+ click_mouse: {
97
+ x: toInt(action.x),
98
+ y: toInt(action.y),
99
+ button: clickMouseButtonOr(action.button, "left"),
100
+ click_type: type === "mouse_down" ? "down" : "up",
101
+ },
102
+ };
103
+ case "type":
104
+ return { type: "type_text", type_text: { text: typeof action.text === "string" ? action.text : "" } };
105
+ case "keypress":
106
+ return { type: "press_key", press_key: { keys: toStringArray(action.keys) } };
107
+ case "scroll":
108
+ return {
109
+ type: "scroll",
110
+ scroll: {
111
+ x: toInt(action.x),
112
+ y: toInt(action.y),
113
+ delta_x: toInt(action.scroll_x),
114
+ delta_y: toInt(action.scroll_y),
115
+ },
116
+ };
117
+ case "move":
118
+ return { type: "move_mouse", move_mouse: { x: toInt(action.x), y: toInt(action.y) } };
119
+ case "drag":
120
+ return { type: "drag_mouse", drag_mouse: { path: toPath(action.path), button: dragMouseButtonOr(action.button, "left") } };
121
+ case "wait":
122
+ return { type: "sleep", sleep: { duration_ms: typeof action.ms === "number" ? Math.trunc(action.ms) : 1000 } };
123
+ default:
124
+ throw new Error(`unknown computer action type: ${type}`);
125
+ }
126
+ }
127
+ function toInt(value) {
128
+ if (typeof value === "number" && Number.isFinite(value))
129
+ return Math.trunc(value);
130
+ if (typeof value === "string" && value.trim()) {
131
+ const n = Number(value);
132
+ if (Number.isFinite(n))
133
+ return Math.trunc(n);
134
+ }
135
+ return 0;
136
+ }
137
+ function stringOr(value, fallback) {
138
+ return typeof value === "string" && value.length > 0 ? value : fallback;
139
+ }
140
+ function clickMouseButtonOr(value, fallback) {
141
+ const candidate = stringOr(value, fallback);
142
+ if (candidate === "left" || candidate === "right" || candidate === "middle" || candidate === "back" || candidate === "forward") {
143
+ return candidate;
144
+ }
145
+ return fallback;
146
+ }
147
+ function dragMouseButtonOr(value, fallback) {
148
+ const candidate = stringOr(value, fallback);
149
+ if (candidate === "left" || candidate === "right" || candidate === "middle") {
150
+ return candidate;
151
+ }
152
+ return fallback;
153
+ }
154
+ function toStringArray(value) {
155
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
156
+ }
157
+ function toPath(value) {
158
+ if (!Array.isArray(value))
159
+ return [];
160
+ return value.map((point) => toPathPoint(point));
161
+ }
162
+ function toPathPoint(value) {
163
+ if (Array.isArray(value))
164
+ return [toInt(value[0]), toInt(value[1])];
165
+ if (value && typeof value === "object") {
166
+ return [toInt(value.x), toInt(value.y)];
167
+ }
168
+ return [0, 0];
169
+ }
170
+ //# sourceMappingURL=translator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.js","sourceRoot":"","sources":["../../src/translator/translator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export type ModelAction = Record<string, unknown>;
2
+ export type BatchActionType = "click_mouse" | "move_mouse" | "type_text" | "press_key" | "scroll" | "drag_mouse" | "sleep";
3
+ export interface BatchAction {
4
+ type: BatchActionType;
5
+ click_mouse?: Record<string, unknown>;
6
+ move_mouse?: Record<string, unknown>;
7
+ type_text?: Record<string, unknown>;
8
+ press_key?: Record<string, unknown>;
9
+ scroll?: Record<string, unknown>;
10
+ drag_mouse?: Record<string, unknown>;
11
+ sleep?: Record<string, unknown>;
12
+ }
13
+ export type BatchReadResult = {
14
+ type: "screenshot";
15
+ pngBytes: Buffer;
16
+ } | {
17
+ type: "url";
18
+ url: string;
19
+ } | {
20
+ type: "cursor_position";
21
+ x: number;
22
+ y: number;
23
+ };
24
+ export interface BatchExecutionResult {
25
+ readResults: BatchReadResult[];
26
+ }
27
+ export interface ComputerUseToolResult<TDetails = unknown> {
28
+ content: Array<{
29
+ type: "text";
30
+ text: string;
31
+ } | {
32
+ type: "image";
33
+ data: string;
34
+ mimeType: string;
35
+ }>;
36
+ details: TDetails;
37
+ isError?: boolean;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/translator/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,MAAM,MAAM,eAAe,GACxB,aAAa,GACb,YAAY,GACZ,WAAW,GACX,WAAW,GACX,QAAQ,GACR,YAAY,GACZ,OAAO,CAAC;AAEX,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,eAAe,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACpC,WAAW,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB,CAAC,QAAQ,GAAG,OAAO;IACxD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnG,OAAO,EAAE,QAAQ,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/translator/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import Kernel from "@onkernel/sdk";
2
+ import { requireCuaEnvApiKeyForModel, type CuaModelRef } from "@onkernel/cua-ai";
3
+ import { CuaAgent } from "../src/index";
4
+ import { SCENARIOS } from "./shared/scenarios";
5
+
6
+ const modelRef = (process.env.MODEL_REF as CuaModelRef | undefined) ?? "openai:gpt-5.5";
7
+
8
+ async function main(): Promise<void> {
9
+ const kernelApiKey = process.env.KERNEL_API_KEY;
10
+ if (!kernelApiKey) throw new Error("KERNEL_API_KEY is required");
11
+ requireCuaEnvApiKeyForModel(modelRef);
12
+ const client = new Kernel({ apiKey: kernelApiKey });
13
+ const browser = await client.browsers.create({ stealth: true });
14
+
15
+ try {
16
+ const agent = new CuaAgent({
17
+ browser,
18
+ client,
19
+ initialState: { model: modelRef },
20
+ });
21
+
22
+ agent.subscribe((event) => {
23
+ if (event.type === "tool_execution_start") {
24
+ console.log(`[tool:start] ${event.toolName}`);
25
+ }
26
+ if (event.type === "tool_execution_end") {
27
+ console.log(`[tool:end] ${event.toolName} error=${event.isError}`);
28
+ }
29
+ });
30
+
31
+ const scenario = SCENARIOS[0]!;
32
+ console.log(`running scenario: ${scenario.name}`);
33
+ await agent.prompt(scenario.prompt);
34
+ const assistant = [...agent.state.messages].reverse().find((message) => message.role === "assistant");
35
+ console.log("assistant stopReason:", assistant?.role === "assistant" ? assistant.stopReason : "unknown");
36
+ } finally {
37
+ await client.browsers.deleteByID(browser.session_id);
38
+ }
39
+ }
40
+
41
+ void main();
@@ -0,0 +1,30 @@
1
+ import Kernel from "@onkernel/sdk";
2
+ import { requireCuaEnvApiKeyForModel, type CuaModelRef } from "@onkernel/cua-ai";
3
+ import { CuaAgent } from "../src/index";
4
+ import { SCENARIOS } from "./shared/scenarios";
5
+
6
+ const modelRef = (process.env.MODEL_REF as CuaModelRef | undefined) ?? "openai:gpt-5.5";
7
+ const scenarioName = process.env.SCENARIO ?? SCENARIOS[0]!.name;
8
+
9
+ async function main(): Promise<void> {
10
+ const kernelApiKey = process.env.KERNEL_API_KEY;
11
+ if (!kernelApiKey) throw new Error("KERNEL_API_KEY is required");
12
+ requireCuaEnvApiKeyForModel(modelRef);
13
+ const client = new Kernel({ apiKey: kernelApiKey });
14
+ const browser = await client.browsers.create({ stealth: true });
15
+ const scenario = SCENARIOS.find((entry) => entry.name === scenarioName) ?? SCENARIOS[0]!;
16
+
17
+ try {
18
+ const agent = new CuaAgent({
19
+ browser,
20
+ client,
21
+ initialState: { model: modelRef },
22
+ });
23
+ console.log(`model=${modelRef} scenario=${scenario.name}`);
24
+ await agent.prompt(scenario.prompt);
25
+ } finally {
26
+ await client.browsers.deleteByID(browser.session_id);
27
+ }
28
+ }
29
+
30
+ void main();
@@ -0,0 +1,43 @@
1
+ import Kernel from "@onkernel/sdk";
2
+ import { requireCuaEnvApiKeyForModel, type CuaModelRef } from "@onkernel/cua-ai";
3
+ import { CuaHarness } from "../src/index";
4
+ import { SCENARIOS } from "./shared/scenarios";
5
+
6
+ const modelRef = (process.env.MODEL_REF as CuaModelRef | undefined) ?? "openai:gpt-5.5";
7
+
8
+ async function main(): Promise<void> {
9
+ const kernelApiKey = process.env.KERNEL_API_KEY;
10
+ if (!kernelApiKey) throw new Error("KERNEL_API_KEY is required");
11
+ requireCuaEnvApiKeyForModel(modelRef);
12
+ const client = new Kernel({ apiKey: kernelApiKey });
13
+ const browser = await client.browsers.create({ stealth: true });
14
+
15
+ try {
16
+ const harness = new CuaHarness({
17
+ browser,
18
+ client,
19
+ model: modelRef,
20
+ });
21
+
22
+ harness.subscribe((event) => {
23
+ if (event.type === "tool_execution_start") {
24
+ console.log(`[tool:start] ${event.toolName}`);
25
+ }
26
+ if (event.type === "tool_execution_end") {
27
+ console.log(`[tool:end] ${event.toolName} error=${event.isError}`);
28
+ }
29
+ });
30
+
31
+ const scenario = SCENARIOS[0]!;
32
+ console.log(`running scenario: ${scenario.name}`);
33
+ await harness.prompt(scenario.prompt);
34
+ const transcript = harness.getTranscript();
35
+ const lastAssistant = [...transcript].reverse().find((message) => message.role === "assistant");
36
+ console.log("transcript messages:", transcript.length);
37
+ console.log("assistant stopReason:", lastAssistant?.role === "assistant" ? lastAssistant.stopReason : "unknown");
38
+ } finally {
39
+ await client.browsers.deleteByID(browser.session_id);
40
+ }
41
+ }
42
+
43
+ void main();
@@ -0,0 +1,31 @@
1
+ import Kernel from "@onkernel/sdk";
2
+ import { requireCuaEnvApiKeyForModel, type CuaModelRef } from "@onkernel/cua-ai";
3
+ import { CuaHarness } from "../src/index";
4
+ import { SCENARIOS } from "./shared/scenarios";
5
+
6
+ const modelRef = (process.env.MODEL_REF as CuaModelRef | undefined) ?? "openai:gpt-5.5";
7
+ const scenarioName = process.env.SCENARIO ?? SCENARIOS[0]!.name;
8
+
9
+ async function main(): Promise<void> {
10
+ const kernelApiKey = process.env.KERNEL_API_KEY;
11
+ if (!kernelApiKey) throw new Error("KERNEL_API_KEY is required");
12
+ requireCuaEnvApiKeyForModel(modelRef);
13
+ const client = new Kernel({ apiKey: kernelApiKey });
14
+ const browser = await client.browsers.create({ stealth: true });
15
+ const scenario = SCENARIOS.find((entry) => entry.name === scenarioName) ?? SCENARIOS[0]!;
16
+
17
+ try {
18
+ const harness = new CuaHarness({
19
+ browser,
20
+ client,
21
+ model: modelRef,
22
+ });
23
+ console.log(`model=${modelRef} scenario=${scenario.name}`);
24
+ await harness.prompt(scenario.prompt);
25
+ console.log("transcript messages:", harness.getTranscript().length);
26
+ } finally {
27
+ await client.browsers.deleteByID(browser.session_id);
28
+ }
29
+ }
30
+
31
+ void main();
@@ -0,0 +1,39 @@
1
+ export interface BrowserScenario {
2
+ name: string;
3
+ prompt: string;
4
+ }
5
+
6
+ export const SCENARIOS: BrowserScenario[] = [
7
+ {
8
+ name: "example-link-and-url",
9
+ prompt: [
10
+ "Use browser tools for exactly these steps:",
11
+ "1) goto https://example.com",
12
+ "2) read current url",
13
+ "3) click the More information link",
14
+ "4) read current url",
15
+ "5) capture a screenshot",
16
+ ].join("\n"),
17
+ },
18
+ {
19
+ name: "hn-url-and-screenshot",
20
+ prompt: [
21
+ "Use browser tools for exactly these steps:",
22
+ "1) goto https://news.ycombinator.com",
23
+ "2) scroll slightly",
24
+ "3) read current url",
25
+ "4) capture a screenshot",
26
+ ].join("\n"),
27
+ },
28
+ {
29
+ name: "wikipedia-search",
30
+ prompt: [
31
+ "Use browser tools for exactly these steps:",
32
+ "1) goto https://www.wikipedia.org",
33
+ "2) click the search input",
34
+ "3) type kernel",
35
+ "4) press Enter",
36
+ "5) read current url",
37
+ ].join("\n"),
38
+ },
39
+ ];
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@onkernel/cua-agent",
3
+ "version": "0.0.1",
4
+ "description": "Kernel browser computer-use Agent and AgentHarness classes built on pi-agent-core",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/kernel/cua.git",
12
+ "directory": "packages/agent"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/kernel/cua/issues"
16
+ },
17
+ "homepage": "https://github.com/kernel/cua/tree/main/packages/agent#readme",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "source": "./src/index.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "examples",
28
+ "README.md",
29
+ "CHANGELOG.md"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -b",
36
+ "clean": "tsc -b --clean",
37
+ "example:agent": "NODE_OPTIONS=--conditions=source tsx examples/agent-openai-smoke.ts",
38
+ "example:harness": "NODE_OPTIONS=--conditions=source tsx examples/harness-openai-smoke.ts",
39
+ "test": "vitest --run"
40
+ },
41
+ "dependencies": {
42
+ "@earendil-works/pi-agent-core": "^0.74.0",
43
+ "@earendil-works/pi-ai": "^0.74.0",
44
+ "@onkernel/cua-ai": "0.0.1",
45
+ "@onkernel/sdk": "0.49.0"
46
+ },
47
+ "devDependencies": {
48
+ "vitest": "^3.2.4"
49
+ }
50
+ }