Skip to content

Commit 657fafc

Browse files
committed
use actual cua clients in test instead of duplicating logic
1 parent 7f579ce commit 657fafc

File tree

1 file changed

+92
-74
lines changed

1 file changed

+92
-74
lines changed

packages/core/tests/safety-confirmation.test.ts

Lines changed: 92 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,50 @@
11
import { describe, it, expect, vi } from "vitest";
2-
3-
// Mock types to test the safety confirmation logic in isolation
4-
type SafetyCheck = {
5-
id: string;
6-
code: string;
7-
message: string;
8-
};
9-
10-
type SafetyConfirmationResponse = {
11-
acknowledged: boolean;
12-
};
13-
14-
type SafetyConfirmationHandler = (
15-
checks: SafetyCheck[],
16-
) => Promise<SafetyConfirmationResponse>;
17-
18-
// Extracted logic that mirrors OpenAICUAClient.handleSafetyConfirmation
19-
async function handleSafetyConfirmation(
20-
pendingSafetyChecks: SafetyCheck[],
21-
handler: SafetyConfirmationHandler | undefined,
22-
): Promise<SafetyCheck[] | undefined> {
23-
if (handler) {
24-
const response = await handler(pendingSafetyChecks);
25-
if (response.acknowledged) {
26-
return pendingSafetyChecks;
27-
} else {
28-
return undefined;
29-
}
2+
import { OpenAICUAClient } from "../lib/v3/agent/OpenAICUAClient";
3+
import { GoogleCUAClient } from "../lib/v3/agent/GoogleCUAClient";
4+
import type {
5+
SafetyCheck,
6+
SafetyConfirmationHandler,
7+
} from "../lib/v3/types/public/agent";
8+
import type { LogLine } from "../lib/v3/types/public/logs";
9+
10+
type LoggerMock = (message: LogLine) => void;
11+
12+
const openAISafetyInvoker = (
13+
OpenAICUAClient.prototype as unknown as {
14+
handleSafetyConfirmation: (
15+
this: OpenAICUAClient,
16+
pendingSafetyChecks: SafetyCheck[],
17+
logger: LoggerMock,
18+
) => Promise<SafetyCheck[] | undefined>;
19+
}
20+
).handleSafetyConfirmation;
21+
22+
const googleSafetyInvoker = (
23+
GoogleCUAClient.prototype as unknown as {
24+
handleSafetyConfirmation: (
25+
this: GoogleCUAClient,
26+
safetyDecision: unknown,
27+
logger: LoggerMock,
28+
) => Promise<string | undefined>;
3029
}
31-
// Auto-acknowledge when no handler
32-
return pendingSafetyChecks;
30+
).handleSafetyConfirmation;
31+
32+
function createOpenAIClient(): OpenAICUAClient {
33+
return new OpenAICUAClient(
34+
"openai",
35+
"openai/computer-use-preview",
36+
"test instructions",
37+
{ apiKey: "test" },
38+
);
3339
}
3440

35-
// Extracted logic that mirrors GoogleCUAClient.handleSafetyConfirmation
36-
async function handleGoogleSafetyConfirmation(
37-
safetyDecision: unknown,
38-
handler: SafetyConfirmationHandler | undefined,
39-
): Promise<string | undefined> {
40-
const safetyMessage =
41-
typeof safetyDecision === "object"
42-
? JSON.stringify(safetyDecision, null, 2)
43-
: String(safetyDecision);
44-
45-
const safetyChecks: SafetyCheck[] = [
46-
{
47-
id: "google-safety-decision",
48-
code: "safety_decision",
49-
message: safetyMessage,
50-
},
51-
];
52-
53-
if (handler) {
54-
const response = await handler(safetyChecks);
55-
if (response.acknowledged) {
56-
return "true";
57-
} else {
58-
return undefined;
59-
}
60-
}
61-
// Auto-acknowledge when no handler
62-
return "true";
41+
function createGoogleClient(): GoogleCUAClient {
42+
return new GoogleCUAClient(
43+
"google",
44+
"google/gemini-2.5-computer-use-preview-10-2025",
45+
"test instructions",
46+
{ apiKey: "test" },
47+
);
6348
}
6449

6550
describe("Safety Confirmation Handler", () => {
@@ -73,23 +58,35 @@ describe("Safety Confirmation Handler", () => {
7358
];
7459

7560
it("returns checks when handler acknowledges", async () => {
76-
const handler = vi.fn().mockResolvedValue({ acknowledged: true });
77-
const result = await handleSafetyConfirmation(mockChecks, handler);
61+
const client = createOpenAIClient();
62+
const handler: SafetyConfirmationHandler = vi.fn(async () => ({
63+
acknowledged: true,
64+
}));
65+
client.setSafetyConfirmationHandler(handler);
66+
const logger = vi.fn<LoggerMock>();
67+
const result = await openAISafetyInvoker.call(client, mockChecks, logger);
7868

7969
expect(handler).toHaveBeenCalledWith(mockChecks);
8070
expect(result).toEqual(mockChecks);
8171
});
8272

8373
it("returns undefined when handler rejects", async () => {
84-
const handler = vi.fn().mockResolvedValue({ acknowledged: false });
85-
const result = await handleSafetyConfirmation(mockChecks, handler);
74+
const client = createOpenAIClient();
75+
const handler: SafetyConfirmationHandler = vi.fn(async () => ({
76+
acknowledged: false,
77+
}));
78+
client.setSafetyConfirmationHandler(handler);
79+
const logger = vi.fn<LoggerMock>();
80+
const result = await openAISafetyInvoker.call(client, mockChecks, logger);
8681

8782
expect(handler).toHaveBeenCalledWith(mockChecks);
8883
expect(result).toBeUndefined();
8984
});
9085

9186
it("auto-acknowledges when no handler is set", async () => {
92-
const result = await handleSafetyConfirmation(mockChecks, undefined);
87+
const client = createOpenAIClient();
88+
const logger = vi.fn<LoggerMock>();
89+
const result = await openAISafetyInvoker.call(client, mockChecks, logger);
9390
expect(result).toEqual(mockChecks);
9491
});
9592
});
@@ -101,10 +98,16 @@ describe("Safety Confirmation Handler", () => {
10198
};
10299

103100
it("returns 'true' when handler acknowledges", async () => {
104-
const handler = vi.fn().mockResolvedValue({ acknowledged: true });
105-
const result = await handleGoogleSafetyConfirmation(
101+
const client = createGoogleClient();
102+
const handler: SafetyConfirmationHandler = vi.fn(async () => ({
103+
acknowledged: true,
104+
}));
105+
client.setSafetyConfirmationHandler(handler);
106+
const logger = vi.fn<LoggerMock>();
107+
const result = await googleSafetyInvoker.call(
108+
client,
106109
mockDecision,
107-
handler,
110+
logger,
108111
);
109112

110113
expect(handler).toHaveBeenCalledWith([
@@ -118,29 +121,44 @@ describe("Safety Confirmation Handler", () => {
118121
});
119122

120123
it("returns undefined when handler rejects", async () => {
121-
const handler = vi.fn().mockResolvedValue({ acknowledged: false });
122-
const result = await handleGoogleSafetyConfirmation(
124+
const client = createGoogleClient();
125+
const handler: SafetyConfirmationHandler = vi.fn(async () => ({
126+
acknowledged: false,
127+
}));
128+
client.setSafetyConfirmationHandler(handler);
129+
const logger = vi.fn<LoggerMock>();
130+
const result = await googleSafetyInvoker.call(
131+
client,
123132
mockDecision,
124-
handler,
133+
logger,
125134
);
126135

127136
expect(handler).toHaveBeenCalled();
128137
expect(result).toBeUndefined();
129138
});
130139

131140
it("auto-acknowledges when no handler is set", async () => {
132-
const result = await handleGoogleSafetyConfirmation(
141+
const client = createGoogleClient();
142+
const logger = vi.fn<LoggerMock>();
143+
const result = await googleSafetyInvoker.call(
144+
client,
133145
mockDecision,
134-
undefined,
146+
logger,
135147
);
136148
expect(result).toBe("true");
137149
});
138150

139151
it("handles string safety decisions", async () => {
140-
const handler = vi.fn().mockResolvedValue({ acknowledged: true });
141-
const result = await handleGoogleSafetyConfirmation(
152+
const client = createGoogleClient();
153+
const handler: SafetyConfirmationHandler = vi.fn(async () => ({
154+
acknowledged: true,
155+
}));
156+
client.setSafetyConfirmationHandler(handler);
157+
const logger = vi.fn<LoggerMock>();
158+
const result = await googleSafetyInvoker.call(
159+
client,
142160
"Simple string decision",
143-
handler,
161+
logger,
144162
);
145163

146164
expect(handler).toHaveBeenCalledWith([

0 commit comments

Comments
 (0)