Skip to content

Commit e0a2c77

Browse files
fix(realtime): use item id for guardrail details
1 parent bbce5a7 commit e0a2c77

File tree

5 files changed

+15
-6
lines changed

5 files changed

+15
-6
lines changed

docs/src/content/docs/guides/voice-agents/build.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Guardrails offer a way to monitor whether what the agent has said violated a set
9898

9999
The guardrails that you provide will run asynchronously as a model response is returned, allowing you to cut off the response based a predefined classification trigger, for example "mentions a specific banned word".
100100

101-
When a guardrail trips the session emits a `guardrail_tripped` event.
101+
When a guardrail trips the session emits a `guardrail_tripped` event. The event also provides a `details` object containing the `itemId` that triggered the guardrail.
102102

103103
<Code lang="typescript" code={guardrailsExample} />
104104

docs/src/content/docs/ja/guides/voice-agents/build.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Realtime Agent で使用できるのは関数ツールのみで、これらの
9292

9393
提供したガードレールは、モデルの応答が返されると同時に非同期で実行され、たとえば「特定の禁止ワードを含む」などの分類トリガーに基づいて応答を打ち切れます。
9494

95-
ガードレールが作動すると、セッションは `guardrail_tripped` イベントを発行します。
95+
ガードレールが作動すると、セッションは `guardrail_tripped` イベントを発行します。イベントには違反したアイテムの `itemId` を含む `details` オブジェクトが追加で渡されます。
9696

9797
<Code lang="typescript" code={guardrailsExample} />
9898

packages/agents-realtime/src/realtimeSession.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,11 @@ export class RealtimeSession<
447447
}
448448
}
449449

450-
async #runOutputGuardrails(output: string, responseId: string) {
450+
async #runOutputGuardrails(
451+
output: string,
452+
responseId: string,
453+
itemId: string,
454+
) {
451455
if (this.#outputGuardrails.length === 0) {
452456
return;
453457
}
@@ -475,7 +479,9 @@ export class RealtimeSession<
475479
`Output guardrail triggered: ${JSON.stringify(firstTripwireTriggered.output.outputInfo)}`,
476480
firstTripwireTriggered,
477481
);
478-
this.emit('guardrail_tripped', this.#context, this.#currentAgent, error);
482+
this.emit('guardrail_tripped', this.#context, this.#currentAgent, error, {
483+
itemId,
484+
});
479485
this.interrupt();
480486

481487
const feedbackText = getRealtimeGuardrailFeedbackMessage(
@@ -500,10 +506,11 @@ export class RealtimeSession<
500506
this.#transport.on('turn_done', (event) => {
501507
const item = event.response.output[event.response.output.length - 1];
502508
const textOutput = getLastTextFromAudioOutputMessage(item) ?? '';
509+
const itemId = item.id ?? '';
503510
this.emit('agent_end', this.#context, this.#currentAgent, textOutput);
504511
this.#currentAgent.emit('agent_end', this.#context, textOutput);
505512

506-
this.#runOutputGuardrails(textOutput, event.response.id);
513+
this.#runOutputGuardrails(textOutput, event.response.id, itemId);
507514
});
508515

509516
this.#transport.on('audio_done', () => {
@@ -537,7 +544,7 @@ export class RealtimeSession<
537544
// We don't cancel existing runs because we want the first one to fail to fail
538545
// The transport layer should upon failure handle the interruption and stop the model
539546
// from generating further
540-
this.#runOutputGuardrails(newText, responseId);
547+
this.#runOutputGuardrails(newText, responseId, itemId);
541548
}
542549
} catch (err) {
543550
this.emit('error', {

packages/agents-realtime/src/realtimeSessionEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export type RealtimeSessionEventTypes<TContext = unknown> = {
113113
context: RunContext<RealtimeContextData<TContext>>,
114114
agent: AgentWithOrWithoutHistory<TContext>,
115115
error: OutputGuardrailTripwireTriggered<RealtimeGuardrailMetadata>,
116+
details: { itemId: string },
116117
];
117118

118119
/**

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ describe('RealtimeSession', () => {
155155
await vi.waitFor(() => expect(guardrailEvents.length).toBe(1));
156156
expect(transport.interruptCalls).toBe(1);
157157
expect(transport.sendMessageCalls.at(-1)?.[0]).toContain('blocked');
158+
expect(guardrailEvents[0][3]).toEqual({ itemId: '123' });
158159
vi.restoreAllMocks();
159160
});
160161

0 commit comments

Comments
 (0)