Skip to content

Commit a8c4aa6

Browse files
committed
Add safeToRunInBrowser option to Agent constructor
1 parent 3450e2d commit a8c4aa6

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

packages/agents-core/src/agent.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ export interface AgentConfiguration<
217217
* to `true`. This ensures that the agent doesn't enter an infinite loop of tool usage.
218218
*/
219219
resetToolChoice: boolean;
220+
221+
/**
222+
* Whether the agent is safe to run in a browser environment. Defaults to false.
223+
*/
224+
safeToRunInBrowser?: boolean;
220225
}
221226

222227
export type AgentOptions<
@@ -314,6 +319,7 @@ export class Agent<
314319
outputType: TOutput = 'text' as TOutput;
315320
toolUseBehavior: ToolUseBehavior;
316321
resetToolChoice: boolean;
322+
safeToRunInBrowser: boolean;
317323

318324
constructor(config: AgentOptions<TContext, TOutput>) {
319325
super();
@@ -335,6 +341,7 @@ export class Agent<
335341
}
336342
this.toolUseBehavior = config.toolUseBehavior ?? 'run_llm_again';
337343
this.resetToolChoice = config.resetToolChoice ?? true;
344+
this.safeToRunInBrowser = config.safeToRunInBrowser ?? false;
338345

339346
// --- Runtime warning for handoff output type compatibility ---
340347
if (
@@ -437,7 +444,7 @@ export class Agent<
437444
additionalProperties: false,
438445
},
439446
strict: true,
440-
localAgentAsTool: true,
447+
safeToRunInBrowser: this.safeToRunInBrowser,
441448
execute: async (data, context) => {
442449
if (!isAgentToolInput(data)) {
443450
throw new ModelBehaviorError('Agent tool called with invalid input');

packages/agents-core/src/tool.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,9 @@ export type FunctionTool<
7575
needsApproval: ToolApprovalFunction<TParameters>;
7676

7777
/**
78-
* Whether the tool is a local agent. If true, the tool is a different agent that will be called
79-
* locally. Note that an agent running on web frontend client side does not work for RealtimeAgent.
80-
* If the property is absent, it means false.
78+
* Whether the tool is safe to run in a browser. If true, the tool can be called from a browser. Default: false
8179
*/
82-
localAgentAsTool?: boolean;
80+
safeToRunInBrowser?: boolean;
8381
};
8482

8583
/**
@@ -335,11 +333,9 @@ type StrictToolOptions<
335333
needsApproval?: boolean | ToolApprovalFunction<TParameters>;
336334

337335
/**
338-
* Whether the tool is a local agent. If true, the tool is a different agent that will be called
339-
* locally. Note that an agent running on web frontend client side does not work for RealtimeAgent.
340-
* If the property is absent, it means false.
336+
* Whether the tool is safe to run in a browser. If true, the tool can be called from a browser. Default: false
341337
*/
342-
localAgentAsTool?: boolean;
338+
safeToRunInBrowser?: boolean;
343339
};
344340

345341
/**
@@ -389,11 +385,9 @@ type NonStrictToolOptions<
389385
needsApproval?: boolean | ToolApprovalFunction<TParameters>;
390386

391387
/**
392-
* Whether the tool is a local agent. If true, the tool is a different agent that will be called
393-
* locally. Note that an agent running on web frontend client side does not work for RealtimeAgent.
394-
* If the property is absent, it means false.
388+
* Whether the tool is safe to run in a browser. If true, the tool can be called from a browser. Default: false
395389
*/
396-
localAgentAsTool?: boolean;
390+
safeToRunInBrowser?: boolean;
397391
};
398392

399393
/**
@@ -518,6 +512,6 @@ export function tool<
518512
strict: strictMode,
519513
invoke,
520514
needsApproval,
521-
localAgentAsTool: options.localAgentAsTool,
515+
safeToRunInBrowser: options.safeToRunInBrowser,
522516
};
523517
}

packages/agents-realtime/src/realtimeAgent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class RealtimeAgent<TContext = UnknownContext> extends Agent<
7676
constructor(config: RealtimeAgentConfiguration<TContext>) {
7777
if (isBrowserEnvironment() && config.tools) {
7878
for (const tool of config.tools) {
79-
if (tool.type === 'function' && tool.localAgentAsTool === true) {
79+
if (tool.type === 'function' && tool.safeToRunInBrowser !== true) {
8080
throw new UserError(
8181
`Local agent as a tool detected: ${tool.name}. Please use a tool that makes requests to your server-side agent logic, rather than converting a locally running client-side agent into a tool.`,
8282
);

packages/agents-realtime/test/realtimeAgent.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { describe, it, expect, vi } from 'vitest';
33
import { RealtimeAgent } from '../src/realtimeAgent';
44
import { Agent } from '@openai/agents-core';
55

6-
const mockResponses = [true, false];
6+
const mockResponses = [true, true, false];
77
vi.mock('@openai/agents-core/_shims', async (importOriginal) => {
88
return {
99
...(await importOriginal()),
@@ -32,6 +32,24 @@ describe('RealtimeAgent', () => {
3232
);
3333
});
3434

35+
it('accepts safeToRunInBrowser agents as tools (browser)', async () => {
36+
const localToolAgent = new Agent({
37+
name: 'local_agent',
38+
instructions: 'You are a local agent',
39+
safeToRunInBrowser: true,
40+
});
41+
const realtimeAgent = new RealtimeAgent({
42+
name: 'A',
43+
tools: [
44+
localToolAgent.asTool({
45+
toolName: 'local_agent tool',
46+
toolDescription: 'You are a local agent',
47+
}),
48+
],
49+
});
50+
expect(realtimeAgent).toBeDefined();
51+
});
52+
3553
it('does not detect local agents as tools (server)', () => {
3654
const localToolAgent = new Agent({
3755
name: 'local_agent',

0 commit comments

Comments
 (0)