Skip to content

Commit 5c70593

Browse files
committed
Parameterize local CUA template tasks and centralize the computer tool shape.
This makes local smoke tests easier to target while keeping the OpenAI computer tool definition consistent across the Python and TypeScript templates. Made-with: Cursor
1 parent ff8d0c1 commit 5c70593

4 files changed

Lines changed: 30 additions & 10 deletions

File tree

pkg/templates/python/openai-computer-use/agent/agent.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@
117117
"strict": False,
118118
}
119119

120+
# Keep this shape aligned with CUA and current OpenAI Responses API.
121+
OPENAI_COMPUTER_TOOL = {"type": "computer"}
122+
120123

121124
class Agent:
122125
"""An agent that uses OpenAI CUA with Kernel's native computer control API."""
@@ -140,9 +143,7 @@ def __init__(
140143

141144
if computer:
142145
self.tools += [
143-
{
144-
"type": "computer",
145-
},
146+
dict(OPENAI_COMPUTER_TOOL),
146147
BATCH_TOOL,
147148
EXTRA_TOOL,
148149
]

pkg/templates/python/openai-computer-use/run_local.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
No Kernel app deployment needed.
44
55
Usage:
6-
KERNEL_API_KEY=... OPENAI_API_KEY=... uv run run_local.py --output text
6+
KERNEL_API_KEY=... OPENAI_API_KEY=... uv run run_local.py --task "go to example.com and summarize it"
77
"""
88

99
import argparse
@@ -26,6 +26,8 @@
2626
)
2727
from computers.kernel_computer import KernelComputer
2828

29+
DEFAULT_TASK = "go to example.com and summarize what the page says"
30+
2931

3032
def parse_args():
3133
parser = argparse.ArgumentParser(description="Run OpenAI CUA local test")
@@ -40,6 +42,11 @@ def parse_args():
4042
action="store_true",
4143
help="Enable verbose debug payload logging",
4244
)
45+
parser.add_argument(
46+
"--task",
47+
default=DEFAULT_TASK,
48+
help="User task prompt to run in the browser session",
49+
)
4350
return parser.parse_args()
4451

4552

@@ -74,7 +81,7 @@ def main():
7481
},
7582
{
7683
"role": "user",
77-
"content": "go to ebay.com and look up oberheim ob-x prices and give me a report",
84+
"content": args.task,
7885
},
7986
]
8087

pkg/templates/typescript/openai-computer-use/lib/agent.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import type { CuaAction, KernelComputer } from './kernel-computer';
1717

1818
const BATCH_FUNC_NAME = 'batch_computer_actions';
1919
const EXTRA_FUNC_NAME = 'computer_use_extra';
20+
// Keep this shape aligned with CUA and current OpenAI Responses API.
21+
const OPENAI_COMPUTER_TOOL = { type: 'computer' } as unknown as Tool;
2022

2123
export class Agent {
2224
private model: string;
@@ -40,9 +42,7 @@ export class Agent {
4042
this.ackCb = opts.acknowledge_safety_check_callback ?? ((): boolean => true);
4143

4244
this.tools = [
43-
{
44-
type: 'computer',
45-
} as unknown as Tool,
45+
OPENAI_COMPUTER_TOOL,
4646
batchComputerTool,
4747
computerUseExtraTool,
4848
...(opts.tools ?? []),

pkg/templates/typescript/openai-computer-use/run_local.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@ dotenv.config({ override: true, quiet: true });
2121
* No Kernel app deployment needed.
2222
*
2323
* Usage:
24-
* KERNEL_API_KEY=... OPENAI_API_KEY=... npx tsx run_local.ts
24+
* KERNEL_API_KEY=... OPENAI_API_KEY=... npx tsx run_local.ts --task "go to example.com and summarize it"
2525
*/
2626

27+
const DEFAULT_TASK = 'go to example.com and summarize what the page says';
28+
2729
export async function runLocalTest(args: string[] = process.argv.slice(2)): Promise<void> {
2830
if (!process.env.KERNEL_API_KEY) throw new Error('KERNEL_API_KEY is not set');
2931
if (!process.env.OPENAI_API_KEY) throw new Error('OPENAI_API_KEY is not set');
3032

3133
const client = new Kernel({ apiKey: process.env.KERNEL_API_KEY });
3234
const outputMode = parseOutputMode(args);
35+
const task = parseTask(args);
3336
const debug = args.includes('--debug');
3437
const onEvent = createEventLogger({ output: outputMode, verbose: debug });
3538

@@ -69,7 +72,7 @@ export async function runLocalTest(args: string[] = process.argv.slice(2)): Prom
6972
content: [
7073
{
7174
type: 'input_text',
72-
text: 'go to ebay.com and look up oberheim ob-x prices and give me a report',
75+
text: task,
7376
},
7477
],
7578
},
@@ -100,6 +103,15 @@ function parseOutputMode(args: string[]): OutputMode {
100103
return output === 'jsonl' ? 'jsonl' : 'text';
101104
}
102105

106+
function parseTask(args: string[]): string {
107+
const taskFromEquals = args.find((arg) => arg.startsWith('--task='))?.slice('--task='.length).trim();
108+
const taskFlagIndex = args.findIndex((arg) => arg === '--task');
109+
const nextArg = taskFlagIndex >= 0 ? args[taskFlagIndex + 1] : undefined;
110+
const taskFromNext = nextArg && !nextArg.startsWith('--') ? nextArg.trim() : undefined;
111+
const task = taskFromEquals || taskFromNext;
112+
return task && task.length > 0 ? task : DEFAULT_TASK;
113+
}
114+
103115
function isDirectRun(): boolean {
104116
const entry = process.argv[1];
105117
if (!entry) return false;

0 commit comments

Comments
 (0)