Skip to content

Commit a193401

Browse files
feat: add deployment field to agent dispatch (#1111)
## Summary - Add `deployment` field to `RoomAgentDispatch` for targeting specific agent deployments - Add `agentDeployment` to `TokenRequestOptions` to pass deployment through token requests - Update generated JSON serialization code The `deployment` field allows targeting a specific agent deployment (e.g., "staging"). Leave empty to target the production deployment. Related PRs: - node-sdks: livekit/node-sdks#675 - python-sdks: livekit/python-sdks#722 - rust-sdks: livekit/rust-sdks#1176 - client-sdk-swift: livekit/client-sdk-swift#1043 - client-sdk-js: livekit/client-sdk-js#1971 ## Usage ```dart final options = TokenRequestOptions( roomName: 'my-room', agentName: 'my-agent', agentDeployment: 'staging', // Optional: target specific deployment ); ``` Or directly via `RoomAgentDispatch`: ```dart final dispatch = RoomAgentDispatch( agentName: 'my-agent', metadata: 'my-metadata', deployment: 'staging', ); ``` ## Test plan ### Unit Tests ```bash flutter test flutter test test/token/token_source_test.dart -v ``` ### Manual Verification **1. Verify JSON serialization includes deployment:** ```dart final dispatch = RoomAgentDispatch( agentName: 'my-agent', deployment: 'staging', ); final json = dispatch.toJson(); print(json); // Should include 'deployment': 'staging' ``` **2. Verify TokenRequestOptions converts to request correctly:** ```dart final options = TokenRequestOptions( roomName: 'test-room', agentName: 'my-agent', agentDeployment: 'staging', ); final request = options.toRequest(); print(request.roomConfiguration?.agents?.first?.deployment); // Should print 'staging' ``` **3. Verify JSON round-trip:** ```dart final original = RoomAgentDispatch( agentName: 'my-agent', deployment: 'staging', ); final json = original.toJson(); final restored = RoomAgentDispatch.fromJson(json); assert(restored.deployment == 'staging'); ``` ### End-to-End Verification 1. Use TokenSource to get credentials with agentDeployment set 2. Connect to room - agent with matching deployment should join 3. Verify only staging agent receives the dispatch 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1c03b55 commit a193401

4 files changed

Lines changed: 16 additions & 2 deletions

File tree

lib/src/token_source/room_configuration.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ class RoomAgentDispatch {
2626
/// Metadata for the agent.
2727
final String? metadata;
2828

29+
/// Optional deployment to target. Leave empty to target the production deployment.
30+
final String? deployment;
31+
2932
const RoomAgentDispatch({
3033
this.agentName,
3134
this.metadata,
35+
this.deployment,
3236
});
3337

3438
factory RoomAgentDispatch.fromJson(Map<String, dynamic> json) => _$RoomAgentDispatchFromJson(json);

lib/src/token_source/room_configuration.g.dart

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/token_source/token_source.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ class TokenRequestOptions {
4343
/// Metadata passed to the agent job.
4444
final String? agentMetadata;
4545

46+
/// Optional deployment to target. Leave empty to target the production deployment.
47+
final String? agentDeployment;
48+
4649
const TokenRequestOptions({
4750
this.roomName,
4851
this.participantName,
@@ -51,15 +54,16 @@ class TokenRequestOptions {
5154
this.participantAttributes,
5255
this.agentName,
5356
this.agentMetadata,
57+
this.agentDeployment,
5458
});
5559

5660
factory TokenRequestOptions.fromJson(Map<String, dynamic> json) => _$TokenRequestOptionsFromJson(json);
5761
Map<String, dynamic> toJson() => _$TokenRequestOptionsToJson(this);
5862

5963
/// Converts this options object to a wire-format request.
6064
TokenSourceRequest toRequest() {
61-
final List<RoomAgentDispatch>? agents = (agentName != null || agentMetadata != null)
62-
? [RoomAgentDispatch(agentName: agentName, metadata: agentMetadata)]
65+
final List<RoomAgentDispatch>? agents = (agentName != null || agentMetadata != null || agentDeployment != null)
66+
? [RoomAgentDispatch(agentName: agentName, metadata: agentMetadata, deployment: agentDeployment)]
6367
: null;
6468

6569
return TokenSourceRequest(
@@ -83,6 +87,7 @@ class TokenRequestOptions {
8387
other.participantMetadata == participantMetadata &&
8488
other.agentName == agentName &&
8589
other.agentMetadata == agentMetadata &&
90+
other.agentDeployment == agentDeployment &&
8691
const MapEquality().equals(other.participantAttributes, participantAttributes);
8792
}
8893

@@ -95,6 +100,7 @@ class TokenRequestOptions {
95100
participantMetadata,
96101
agentName,
97102
agentMetadata,
103+
agentDeployment,
98104
const MapEquality().hash(participantAttributes),
99105
);
100106
}

lib/src/token_source/token_source.g.dart

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)