modal 1.0.3.dev10__py3-none-any.whl → 1.2.3.dev7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

Files changed (160) hide show
  1. modal/__init__.py +0 -2
  2. modal/__main__.py +3 -4
  3. modal/_billing.py +80 -0
  4. modal/_clustered_functions.py +7 -3
  5. modal/_clustered_functions.pyi +15 -3
  6. modal/_container_entrypoint.py +51 -69
  7. modal/_functions.py +508 -240
  8. modal/_grpc_client.py +171 -0
  9. modal/_load_context.py +105 -0
  10. modal/_object.py +81 -21
  11. modal/_output.py +58 -45
  12. modal/_partial_function.py +48 -73
  13. modal/_pty.py +7 -3
  14. modal/_resolver.py +26 -46
  15. modal/_runtime/asgi.py +4 -3
  16. modal/_runtime/container_io_manager.py +358 -220
  17. modal/_runtime/container_io_manager.pyi +296 -101
  18. modal/_runtime/execution_context.py +18 -2
  19. modal/_runtime/execution_context.pyi +64 -7
  20. modal/_runtime/gpu_memory_snapshot.py +262 -57
  21. modal/_runtime/user_code_imports.py +28 -58
  22. modal/_serialization.py +90 -6
  23. modal/_traceback.py +42 -1
  24. modal/_tunnel.pyi +380 -12
  25. modal/_utils/async_utils.py +84 -29
  26. modal/_utils/auth_token_manager.py +111 -0
  27. modal/_utils/blob_utils.py +181 -58
  28. modal/_utils/deprecation.py +19 -0
  29. modal/_utils/function_utils.py +91 -47
  30. modal/_utils/grpc_utils.py +89 -66
  31. modal/_utils/mount_utils.py +26 -1
  32. modal/_utils/name_utils.py +17 -3
  33. modal/_utils/task_command_router_client.py +536 -0
  34. modal/_utils/time_utils.py +34 -6
  35. modal/app.py +256 -88
  36. modal/app.pyi +909 -92
  37. modal/billing.py +5 -0
  38. modal/builder/2025.06.txt +18 -0
  39. modal/builder/PREVIEW.txt +18 -0
  40. modal/builder/base-images.json +58 -0
  41. modal/cli/_download.py +19 -3
  42. modal/cli/_traceback.py +3 -2
  43. modal/cli/app.py +4 -4
  44. modal/cli/cluster.py +15 -7
  45. modal/cli/config.py +5 -3
  46. modal/cli/container.py +7 -6
  47. modal/cli/dict.py +22 -16
  48. modal/cli/entry_point.py +12 -5
  49. modal/cli/environment.py +5 -4
  50. modal/cli/import_refs.py +3 -3
  51. modal/cli/launch.py +102 -5
  52. modal/cli/network_file_system.py +11 -12
  53. modal/cli/profile.py +3 -2
  54. modal/cli/programs/launch_instance_ssh.py +94 -0
  55. modal/cli/programs/run_jupyter.py +1 -1
  56. modal/cli/programs/run_marimo.py +95 -0
  57. modal/cli/programs/vscode.py +1 -1
  58. modal/cli/queues.py +57 -26
  59. modal/cli/run.py +91 -23
  60. modal/cli/secret.py +48 -22
  61. modal/cli/token.py +7 -8
  62. modal/cli/utils.py +4 -7
  63. modal/cli/volume.py +31 -25
  64. modal/client.py +15 -85
  65. modal/client.pyi +183 -62
  66. modal/cloud_bucket_mount.py +5 -3
  67. modal/cloud_bucket_mount.pyi +197 -5
  68. modal/cls.py +200 -126
  69. modal/cls.pyi +446 -68
  70. modal/config.py +29 -11
  71. modal/container_process.py +319 -19
  72. modal/container_process.pyi +190 -20
  73. modal/dict.py +290 -71
  74. modal/dict.pyi +835 -83
  75. modal/environments.py +15 -27
  76. modal/environments.pyi +46 -24
  77. modal/exception.py +14 -2
  78. modal/experimental/__init__.py +194 -40
  79. modal/experimental/flash.py +618 -0
  80. modal/experimental/flash.pyi +380 -0
  81. modal/experimental/ipython.py +11 -7
  82. modal/file_io.py +29 -36
  83. modal/file_io.pyi +251 -53
  84. modal/file_pattern_matcher.py +56 -16
  85. modal/functions.pyi +673 -92
  86. modal/gpu.py +1 -1
  87. modal/image.py +528 -176
  88. modal/image.pyi +1572 -145
  89. modal/io_streams.py +458 -128
  90. modal/io_streams.pyi +433 -52
  91. modal/mount.py +216 -151
  92. modal/mount.pyi +225 -78
  93. modal/network_file_system.py +45 -62
  94. modal/network_file_system.pyi +277 -56
  95. modal/object.pyi +93 -17
  96. modal/parallel_map.py +942 -129
  97. modal/parallel_map.pyi +294 -15
  98. modal/partial_function.py +0 -2
  99. modal/partial_function.pyi +234 -19
  100. modal/proxy.py +17 -8
  101. modal/proxy.pyi +36 -3
  102. modal/queue.py +270 -65
  103. modal/queue.pyi +817 -57
  104. modal/runner.py +115 -101
  105. modal/runner.pyi +205 -49
  106. modal/sandbox.py +512 -136
  107. modal/sandbox.pyi +845 -111
  108. modal/schedule.py +1 -1
  109. modal/secret.py +300 -70
  110. modal/secret.pyi +589 -34
  111. modal/serving.py +7 -11
  112. modal/serving.pyi +7 -8
  113. modal/snapshot.py +11 -8
  114. modal/snapshot.pyi +25 -4
  115. modal/token_flow.py +4 -4
  116. modal/token_flow.pyi +28 -8
  117. modal/volume.py +416 -158
  118. modal/volume.pyi +1117 -121
  119. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +10 -9
  120. modal-1.2.3.dev7.dist-info/RECORD +195 -0
  121. modal_docs/mdmd/mdmd.py +17 -4
  122. modal_proto/api.proto +534 -79
  123. modal_proto/api_grpc.py +337 -1
  124. modal_proto/api_pb2.py +1522 -968
  125. modal_proto/api_pb2.pyi +1619 -134
  126. modal_proto/api_pb2_grpc.py +699 -4
  127. modal_proto/api_pb2_grpc.pyi +226 -14
  128. modal_proto/modal_api_grpc.py +175 -154
  129. modal_proto/sandbox_router.proto +145 -0
  130. modal_proto/sandbox_router_grpc.py +105 -0
  131. modal_proto/sandbox_router_pb2.py +149 -0
  132. modal_proto/sandbox_router_pb2.pyi +333 -0
  133. modal_proto/sandbox_router_pb2_grpc.py +203 -0
  134. modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
  135. modal_proto/task_command_router.proto +144 -0
  136. modal_proto/task_command_router_grpc.py +105 -0
  137. modal_proto/task_command_router_pb2.py +149 -0
  138. modal_proto/task_command_router_pb2.pyi +333 -0
  139. modal_proto/task_command_router_pb2_grpc.py +203 -0
  140. modal_proto/task_command_router_pb2_grpc.pyi +75 -0
  141. modal_version/__init__.py +1 -1
  142. modal/requirements/PREVIEW.txt +0 -16
  143. modal/requirements/base-images.json +0 -26
  144. modal-1.0.3.dev10.dist-info/RECORD +0 -179
  145. modal_proto/modal_options_grpc.py +0 -3
  146. modal_proto/options.proto +0 -19
  147. modal_proto/options_grpc.py +0 -3
  148. modal_proto/options_pb2.py +0 -35
  149. modal_proto/options_pb2.pyi +0 -20
  150. modal_proto/options_pb2_grpc.py +0 -4
  151. modal_proto/options_pb2_grpc.pyi +0 -7
  152. /modal/{requirements → builder}/2023.12.312.txt +0 -0
  153. /modal/{requirements → builder}/2023.12.txt +0 -0
  154. /modal/{requirements → builder}/2024.04.txt +0 -0
  155. /modal/{requirements → builder}/2024.10.txt +0 -0
  156. /modal/{requirements → builder}/README.md +0 -0
  157. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
  158. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
  159. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
  160. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal_proto/api.proto CHANGED
@@ -4,9 +4,9 @@ option go_package = "github.com/modal-labs/modal/go/proto";
4
4
 
5
5
  package modal.client;
6
6
 
7
- import "modal_proto/options.proto";
8
7
  import "google/protobuf/empty.proto";
9
8
  import "google/protobuf/struct.proto";
9
+ import "google/protobuf/timestamp.proto";
10
10
  import "google/protobuf/wrappers.proto";
11
11
 
12
12
  enum AppDeployVisibility {
@@ -85,7 +85,9 @@ enum ClientType {
85
85
  CLIENT_TYPE_CONTAINER = 3; // modal-client from inside containers
86
86
  CLIENT_TYPE_WEB_SERVER = 5; // modal-web
87
87
  CLIENT_TYPE_NOTEBOOK_KERNEL = 6; // kernelshim.py from notebooks
88
- CLIENT_TYPE_LIBMODAL = 7; // libmodal: experimental client library
88
+ CLIENT_TYPE_LIBMODAL = 7; // libmodal: experimental JS&Go client library, before version modal-js/v0.3.15, modal-go/v0.0.15
89
+ CLIENT_TYPE_LIBMODAL_JS = 8; // libmodal/modal-js: JavaScript client library, since version modal-js/v0.3.15
90
+ CLIENT_TYPE_LIBMODAL_GO = 9; // libmodal/modal-go: Go client library, since version modal-go/v0.0.15
89
91
  }
90
92
 
91
93
  enum CloudProvider {
@@ -109,6 +111,7 @@ enum DataFormat {
109
111
  DATA_FORMAT_PICKLE = 1; // Cloudpickle
110
112
  DATA_FORMAT_ASGI = 2; // "Asgi" protobuf message
111
113
  DATA_FORMAT_GENERATOR_DONE = 3; // "GeneratorDone" protobuf message
114
+ DATA_FORMAT_CBOR = 4;
112
115
  }
113
116
 
114
117
  enum DeploymentNamespace {
@@ -238,6 +241,13 @@ enum SystemErrorCode {
238
241
  SYSTEM_ERROR_CODE_NOSPC = 28; // ENOSPC: No space left on device
239
242
  }
240
243
 
244
+ enum TaskSnapshotBehavior {
245
+ TASK_SNAPSHOT_BEHAVIOR_UNSPECIFIED = 0;
246
+ TASK_SNAPSHOT_BEHAVIOR_SNAPSHOT = 1;
247
+ TASK_SNAPSHOT_BEHAVIOR_RESTORE = 2;
248
+ TASK_SNAPSHOT_BEHAVIOR_NONE = 3;
249
+ }
250
+
241
251
  enum TaskState {
242
252
  TASK_STATE_UNSPECIFIED = 0;
243
253
  TASK_STATE_CREATED = 6;
@@ -287,10 +297,11 @@ message AppClientDisconnectRequest {
287
297
  }
288
298
 
289
299
  message AppCreateRequest {
290
- string client_id = 1 [ (modal.options.audit_target_attr) = true ];
300
+ string client_id = 1;
291
301
  string description = 2; // Human readable label for the app
292
302
  string environment_name = 5;
293
303
  AppState app_state = 6;
304
+ map<string, string> tags = 7; // Additional metadata to attach to the App
294
305
  }
295
306
 
296
307
  message AppCreateResponse {
@@ -300,8 +311,8 @@ message AppCreateResponse {
300
311
  }
301
312
 
302
313
  message AppDeployRequest {
303
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
304
- DeploymentNamespace namespace = 2;
314
+ string app_id = 1;
315
+ reserved 2; // namespace
305
316
  string name = 3;
306
317
  string object_entity = 4;
307
318
  AppDeployVisibility visibility = 5;
@@ -334,7 +345,7 @@ message AppDeploymentHistoryResponse {
334
345
  }
335
346
 
336
347
  message AppGetByDeploymentNameRequest {
337
- DeploymentNamespace namespace = 1;
348
+ reserved 1; // removed namespace
338
349
  string name = 2;
339
350
  string environment_name = 4;
340
351
  }
@@ -356,10 +367,12 @@ message AppGetLogsRequest {
356
367
  float timeout = 2;
357
368
  string last_entry_id = 4;
358
369
  string function_id = 5;
370
+ string parametrized_function_id = 11;
359
371
  string input_id = 6;
360
372
  string task_id = 7;
361
373
  string function_call_id = 9;
362
374
  FileDescriptor file_descriptor = 8;
375
+ string sandbox_id = 10;
363
376
  }
364
377
 
365
378
  message AppGetObjectsItem {
@@ -387,6 +400,14 @@ message AppGetOrCreateResponse {
387
400
  string app_id = 1;
388
401
  }
389
402
 
403
+ message AppGetTagsRequest {
404
+ string app_id = 1;
405
+ }
406
+
407
+ message AppGetTagsResponse {
408
+ map<string, string> tags = 1;
409
+ }
410
+
390
411
  message AppHeartbeatRequest {
391
412
  string app_id = 1;
392
413
  }
@@ -424,7 +445,7 @@ message AppLookupResponse {
424
445
  }
425
446
 
426
447
  message AppPublishRequest {
427
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
448
+ string app_id = 1;
428
449
  string name = 2;
429
450
  string deployment_tag = 3; // Additional metadata to identify a deployment
430
451
  AppState app_state = 4; // Published app will be in this state
@@ -434,6 +455,7 @@ message AppPublishRequest {
434
455
  uint32 rollback_version = 8; // Unused by client, but used internally
435
456
  string client_version = 9; // Unused by client, but used internally
436
457
  CommitInfo commit_info = 10; // Git information for deployment tracking
458
+ map<string, string> tags = 11; // Additional metadata to attach to the App
437
459
  }
438
460
 
439
461
  message AppPublishResponse {
@@ -455,8 +477,14 @@ message AppSetObjectsRequest {
455
477
  reserved 6;
456
478
  }
457
479
 
480
+ message AppSetTagsRequest {
481
+ string app_id = 1;
482
+ map<string, string> tags = 2;
483
+ }
484
+
485
+
458
486
  message AppStopRequest {
459
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
487
+ string app_id = 1;
460
488
  AppStopSource source = 2;
461
489
  }
462
490
 
@@ -611,11 +639,33 @@ message AttemptStartResponse {
611
639
  FunctionRetryPolicy retry_policy = 2;
612
640
  }
613
641
 
642
+ message AuthTokenGetRequest {
643
+ }
644
+
645
+ message AuthTokenGetResponse {
646
+ string token = 1;
647
+ }
648
+
649
+ // Message representing the current (coalesced) state of the autoscaler configuration
650
+ // As well as the different sources that were used to create it.
651
+ message AutoscalerConfiguration {
652
+ // The settings that are currently in effect.
653
+ AutoscalerSettings settings = 1;
654
+ // For tracking the source of the overridden value; keys correspond to fields in `settings`.
655
+ map<string, UserActionInfo> override_events = 2;
656
+ // The default settings that are used when no static settings are provided and no overrides are in effect.
657
+ AutoscalerSettings default_settings = 3;
658
+ // The static settings that were used to initialize the configuration.
659
+ AutoscalerSettings static_settings = 4;
660
+ // The merge of all overrides that were used to create the current configuration.
661
+ AutoscalerSettings override_settings = 5;
662
+ }
663
+
614
664
  message AutoscalerSettings {
615
665
  // A collection of user-configurable settings for Function autoscaling
616
666
  // These are used for static configuration and for dynamic autoscaler updates
617
667
 
618
- // Minimum containers when scale-to-zero is not deisired; pka "keep_warm" or "warm_pool_size"
668
+ // Minimum containers when scale-to-zero is not desired; pka "keep_warm" or "warm_pool_size"
619
669
  optional uint32 min_containers = 1;
620
670
  // Limit on the number of containers that can be running for each Function; pka "concurrency_limit"
621
671
  optional uint32 max_containers = 2;
@@ -625,6 +675,15 @@ message AutoscalerSettings {
625
675
  optional uint32 scaleup_window = 4;
626
676
  // Maximum amount of time a container can be idle before being scaled down, in seconds; pka "container_idle_timeout"
627
677
  optional uint32 scaledown_window = 5;
678
+ reserved 6;
679
+ }
680
+
681
+ // Used for flash autoscaling
682
+ message AutoscalingMetrics {
683
+ double cpu_usage_percent = 1;
684
+ double memory_usage_percent = 2;
685
+ uint32 concurrent_requests = 3;
686
+ double timestamp = 4;
628
687
  }
629
688
 
630
689
  message BaseImage {
@@ -647,6 +706,11 @@ message BlobCreateResponse {
647
706
  string upload_url = 1;
648
707
  MultiPartUpload multipart = 3;
649
708
  }
709
+ repeated string blob_ids = 4;
710
+ oneof upload_types_oneof {
711
+ UploadUrlList upload_urls = 5;
712
+ MultiPartUploadList multiparts = 6;
713
+ }
650
714
  }
651
715
 
652
716
  message BlobGetRequest {
@@ -681,7 +745,7 @@ message CheckpointInfo {
681
745
  }
682
746
 
683
747
  message ClassCreateRequest {
684
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
748
+ string app_id = 1 ;
685
749
  string existing_class_id = 2;
686
750
  repeated ClassMethod methods = 3;
687
751
  reserved 4; // removed class_function_id
@@ -696,7 +760,7 @@ message ClassCreateResponse {
696
760
  message ClassGetRequest {
697
761
  string app_name = 1;
698
762
  string object_tag = 2;
699
- DeploymentNamespace namespace = 3;
763
+ reserved 3; // removed namespace
700
764
  string environment_name = 4;
701
765
 
702
766
  reserved 8; // lookup_published
@@ -786,6 +850,12 @@ message CloudBucketMount {
786
850
  GCP = 3;
787
851
  }
788
852
 
853
+ enum MetadataTTLType {
854
+ METADATA_TTL_TYPE_UNSPECIFIED = 0;
855
+ METADATA_TTL_TYPE_MINIMAL = 1;
856
+ METADATA_TTL_TYPE_INDEFINITE = 2;
857
+ }
858
+
789
859
  string bucket_name = 1;
790
860
  string mount_path = 2;
791
861
  string credentials_secret_id = 3;
@@ -795,6 +865,11 @@ message CloudBucketMount {
795
865
  optional string bucket_endpoint_url = 7;
796
866
  optional string key_prefix = 8;
797
867
  optional string oidc_auth_role_arn = 9;
868
+ bool force_path_style = 10;
869
+ oneof metadata_ttl_oneof {
870
+ MetadataTTLType metadata_ttl_type = 11;
871
+ uint64 metadata_ttl_seconds = 12;
872
+ }
798
873
  }
799
874
 
800
875
  message ClusterGetRequest {
@@ -843,6 +918,7 @@ message ContainerArguments { // This is used to pass data from the worker to th
843
918
  string environment_name = 13;
844
919
  optional string checkpoint_id = 14;
845
920
  AppLayout app_layout = 15;
921
+ string input_plane_server_url = 16;
846
922
  }
847
923
 
848
924
  message ContainerCheckpointRequest {
@@ -1007,13 +1083,26 @@ message ContainerLogRequest {
1007
1083
  repeated TaskLogs logs = 3;
1008
1084
  }
1009
1085
 
1086
+ message ContainerReloadVolumesRequest {
1087
+ string task_id = 1;
1088
+ }
1089
+
1090
+ message ContainerReloadVolumesResponse { }
1091
+
1010
1092
  message ContainerStopRequest {
1011
- string task_id = 1 [ (modal.options.audit_target_attr) = true ];
1093
+ string task_id = 1;
1012
1094
  }
1013
1095
 
1014
1096
  message ContainerStopResponse {
1015
1097
  }
1016
1098
 
1099
+
1100
+ message CreationInfo {
1101
+ // This message is used in metadata for resource objects like Dict, Queue, Volume, etc.
1102
+ double created_at = 1; // Timestamp of resource creation
1103
+ string created_by = 2; // User name or service name
1104
+ }
1105
+
1017
1106
  message CustomDomainConfig {
1018
1107
  string name = 1;
1019
1108
  }
@@ -1069,8 +1158,8 @@ message DictEntry {
1069
1158
  }
1070
1159
 
1071
1160
  message DictGetOrCreateRequest {
1072
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
1073
- DeploymentNamespace namespace = 2;
1161
+ string deployment_name = 1;
1162
+ reserved 2; // removed namespace
1074
1163
  string environment_name = 3;
1075
1164
  ObjectCreationType object_creation_type = 4;
1076
1165
  repeated DictEntry data = 5;
@@ -1078,6 +1167,7 @@ message DictGetOrCreateRequest {
1078
1167
 
1079
1168
  message DictGetOrCreateResponse {
1080
1169
  string dict_id = 1;
1170
+ DictMetadata metadata = 2;
1081
1171
  }
1082
1172
 
1083
1173
  message DictGetRequest {
@@ -1104,15 +1194,24 @@ message DictLenResponse {
1104
1194
 
1105
1195
  message DictListRequest {
1106
1196
  string environment_name = 1;
1197
+ ListPagination pagination = 2;
1107
1198
  }
1108
1199
 
1109
1200
  message DictListResponse {
1110
1201
  message DictInfo {
1111
1202
  string name = 1;
1112
- double created_at = 2;
1203
+ double created_at = 2; // Superseded by metadata, used by clients up to 1.1.2
1204
+ string dict_id = 3;
1205
+ DictMetadata metadata = 4;
1113
1206
  }
1114
1207
 
1115
1208
  repeated DictInfo dicts = 1;
1209
+ string environment_name = 2;
1210
+ }
1211
+
1212
+ message DictMetadata {
1213
+ string name = 1;
1214
+ CreationInfo creation_info = 2;
1116
1215
  }
1117
1216
 
1118
1217
  message DictPopRequest {
@@ -1126,7 +1225,7 @@ message DictPopResponse {
1126
1225
  }
1127
1226
 
1128
1227
  message DictUpdateRequest {
1129
- string dict_id = 1 [ (modal.options.audit_target_attr) = true ];
1228
+ string dict_id = 1;
1130
1229
  repeated DictEntry updates = 2;
1131
1230
  bool if_not_exists = 3;
1132
1231
  }
@@ -1152,7 +1251,7 @@ message DomainCertificateVerifyResponse {
1152
1251
  }
1153
1252
 
1154
1253
  message DomainCreateRequest {
1155
- string domain_name = 1 [ (modal.options.audit_target_attr) = true ];
1254
+ string domain_name = 1 ;
1156
1255
  }
1157
1256
 
1158
1257
  message DomainCreateResponse {
@@ -1168,14 +1267,14 @@ message DomainListResponse {
1168
1267
  }
1169
1268
 
1170
1269
  message EnvironmentCreateRequest {
1171
- string name = 1 [ (modal.options.audit_target_attr) = true ];
1270
+ string name = 1;
1172
1271
  }
1173
1272
 
1174
1273
  message EnvironmentDeleteRequest {
1175
- string name = 1 [ (modal.options.audit_target_attr) = true ];
1274
+ string name = 1;
1176
1275
  }
1177
1276
  message EnvironmentGetOrCreateRequest {
1178
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
1277
+ string deployment_name = 1;
1179
1278
  ObjectCreationType object_creation_type = 2;
1180
1279
  }
1181
1280
 
@@ -1189,6 +1288,12 @@ message EnvironmentListItem {
1189
1288
  string webhook_suffix = 2;
1190
1289
  double created_at = 3;
1191
1290
  bool default = 4;
1291
+ bool is_managed = 5;
1292
+ string environment_id = 6;
1293
+ optional int32 max_concurrent_tasks = 7;
1294
+ optional int32 max_concurrent_gpus = 8;
1295
+ int32 current_concurrent_tasks = 9;
1296
+ int32 current_concurrent_gpus = 10;
1192
1297
  }
1193
1298
 
1194
1299
  message EnvironmentListResponse {
@@ -1209,9 +1314,11 @@ message EnvironmentSettings {
1209
1314
  }
1210
1315
 
1211
1316
  message EnvironmentUpdateRequest {
1212
- string current_name = 1 [ (modal.options.audit_target_attr) = true ];
1317
+ string current_name = 1;
1213
1318
  google.protobuf.StringValue name = 2;
1214
1319
  google.protobuf.StringValue web_suffix = 3;
1320
+ optional int32 max_concurrent_tasks = 4;
1321
+ optional int32 max_concurrent_gpus = 5;
1215
1322
  }
1216
1323
 
1217
1324
  // A file entry when listing files in a volume or network file system.
@@ -1237,6 +1344,48 @@ message FilesystemRuntimeOutputBatch {
1237
1344
  bool eof = 4;
1238
1345
  }
1239
1346
 
1347
+ message FlashContainerDeregisterRequest {
1348
+ string service_name = 1;
1349
+ }
1350
+
1351
+ message FlashContainerListRequest {
1352
+ string function_id = 1;
1353
+ }
1354
+
1355
+ message FlashContainerListResponse {
1356
+ message Container {
1357
+ string task_id = 1;
1358
+ string host = 2;
1359
+ uint32 port = 3;
1360
+ }
1361
+ repeated Container containers = 1;
1362
+ }
1363
+
1364
+ message FlashContainerRegisterRequest {
1365
+ string service_name = 1; // not used?
1366
+ uint32 priority = 2;
1367
+ uint32 weight = 3;
1368
+ string host = 4;
1369
+ uint32 port = 5;
1370
+ }
1371
+
1372
+ message FlashContainerRegisterResponse {
1373
+ string url = 1;
1374
+ }
1375
+
1376
+ message FlashProxyUpstreamRequest {
1377
+ uint32 upstream_requests = 1;
1378
+ double timestamp = 2;
1379
+ }
1380
+
1381
+ message FlashSetTargetSlotsMetricsRequest {
1382
+ // TODO(claudia): add other metrics to use in autoscaling decisions
1383
+ string function_id = 1;
1384
+ uint32 target_slots = 2;
1385
+ }
1386
+
1387
+ message FlashSetTargetSlotsMetricsResponse {}
1388
+
1240
1389
  message Function {
1241
1390
  string module_name = 1;
1242
1391
  string function_name = 2;
@@ -1381,7 +1530,7 @@ message Function {
1381
1530
  bool _experimental_enable_gpu_snapshot = 78; // Experimental support for GPU snapshotting
1382
1531
 
1383
1532
  AutoscalerSettings autoscaler_settings = 79; // Bundle of parameters related to autoscaling
1384
- FunctionSchema function_schema = 80;
1533
+ FunctionSchema function_schema = 80; // Function schema, may be missing: client doesn't block deployment if it fails to get it
1385
1534
 
1386
1535
  // For server-side experimental functionality. Prefer using this over individual _experimental_* fields.
1387
1536
  // Note the value type as string. Internally we'll coerce all values to string with str().
@@ -1391,6 +1540,15 @@ message Function {
1391
1540
  // If set, client deps will be mounted into the container, and are
1392
1541
  // no longer expected to exist in the image itself.
1393
1542
  bool mount_client_dependencies = 82;
1543
+
1544
+ repeated string flash_service_urls = 83;
1545
+ string flash_service_label = 84;
1546
+
1547
+ bool enable_gpu_snapshot = 85; // GPU memory snapshotting (alpha)
1548
+
1549
+ uint32 startup_timeout_secs = 86;
1550
+ repeated DataFormat supported_input_formats = 87; // can be used as inputs
1551
+ repeated DataFormat supported_output_formats = 88;
1394
1552
  }
1395
1553
 
1396
1554
  message FunctionAsyncInvokeRequest {
@@ -1409,6 +1567,7 @@ message FunctionBindParamsRequest {
1409
1567
  bytes serialized_params = 2;
1410
1568
  FunctionOptions function_options = 3;
1411
1569
  string environment_name = 4;
1570
+ string auth_secret = 5; // Only used for the input plane.
1412
1571
  }
1413
1572
 
1414
1573
  message FunctionBindParamsResponse {
@@ -1426,11 +1585,26 @@ message FunctionCallCallGraphInfo {
1426
1585
  message FunctionCallCancelRequest {
1427
1586
  string function_call_id = 1;
1428
1587
  bool terminate_containers = 2;
1588
+ optional string function_id = 3; // Only provided for sync input cancellation on the input plane. Async input cancellation does not provide this field this.
1429
1589
  }
1430
1590
 
1431
- message FunctionCallGetDataRequest {
1591
+ message FunctionCallFromIdRequest {
1592
+ string function_call_id = 1;
1593
+ }
1594
+
1595
+ // Everything you need to build a FunctionCallHandler.
1596
+ message FunctionCallFromIdResponse {
1432
1597
  string function_call_id = 1;
1598
+ int32 num_inputs = 2;
1599
+ }
1600
+
1601
+ message FunctionCallGetDataRequest {
1602
+ oneof call_info {
1603
+ string function_call_id = 1;
1604
+ string attempt_token = 3;
1605
+ }
1433
1606
  uint64 last_index = 2;
1607
+ bool use_gapless_read = 4;
1434
1608
  }
1435
1609
 
1436
1610
  message FunctionCallInfo {
@@ -1457,13 +1631,16 @@ message FunctionCallListResponse {
1457
1631
  }
1458
1632
 
1459
1633
  message FunctionCallPutDataRequest {
1460
- string function_call_id = 1;
1634
+ oneof call_info {
1635
+ string function_call_id = 1;
1636
+ string attempt_token = 3;
1637
+ }
1461
1638
  repeated DataChunk data_chunks = 2;
1462
1639
  }
1463
1640
 
1464
1641
  message FunctionCreateRequest {
1465
1642
  Function function = 1;
1466
- string app_id = 2 [ (modal.options.audit_target_attr) = true ];
1643
+ string app_id = 2 ;
1467
1644
  Schedule schedule = 6 [deprecated=true]; // Deprecated: now passed in the Function definition
1468
1645
  string existing_function_id = 7;
1469
1646
  reserved 8; // defer_updates
@@ -1543,6 +1720,13 @@ message FunctionData {
1543
1720
  FunctionSchema function_schema = 32;
1544
1721
 
1545
1722
  map<string, string> experimental_options = 33;
1723
+
1724
+ repeated string flash_service_urls = 34;
1725
+ string flash_service_label = 35;
1726
+
1727
+ uint32 startup_timeout_secs = 36;
1728
+ repeated DataFormat supported_input_formats = 37;
1729
+ repeated DataFormat supported_output_formats = 38;
1546
1730
  }
1547
1731
 
1548
1732
  message FunctionExtended {
@@ -1557,6 +1741,12 @@ message FunctionExtended {
1557
1741
  }
1558
1742
  }
1559
1743
 
1744
+ message FunctionFinishInputsRequest {
1745
+ string function_id = 1;
1746
+ string function_call_id = 2;
1747
+ uint32 num_inputs = 3;
1748
+ }
1749
+
1560
1750
 
1561
1751
  message FunctionGetCallGraphRequest {
1562
1752
  // TODO: use input_id once we switch client submit API to return those.
@@ -1590,6 +1780,8 @@ message FunctionGetInputsItem {
1590
1780
  string function_call_id = 5;
1591
1781
  FunctionCallInvocationType function_call_invocation_type = 6;
1592
1782
  uint32 retry_count = 7;
1783
+ optional int32 function_map_idx = 8; // intercepted and only used by the worker.
1784
+ string attempt_token = 9;
1593
1785
  }
1594
1786
 
1595
1787
  message FunctionGetInputsRequest {
@@ -1629,6 +1821,8 @@ message FunctionGetOutputsRequest {
1629
1821
  double requested_at = 8; // Used for waypoints.
1630
1822
  // The jwts the client expects the server to be processing. This is optional and used for sync inputs only.
1631
1823
  repeated string input_jwts = 9;
1824
+ optional int32 start_idx = 10; // for async batch requests. this indicates which index to start from.
1825
+ optional int32 end_idx = 11; // for async batch requests. this indicates which index to end at.
1632
1826
  }
1633
1827
 
1634
1828
  message FunctionGetOutputsResponse {
@@ -1641,7 +1835,7 @@ message FunctionGetOutputsResponse {
1641
1835
  message FunctionGetRequest {
1642
1836
  string app_name = 1;
1643
1837
  string object_tag = 2;
1644
- DeploymentNamespace namespace = 3;
1838
+ reserved 3; // removed namespace
1645
1839
  string environment_name = 4;
1646
1840
  }
1647
1841
 
@@ -1678,6 +1872,12 @@ message FunctionHandleMetadata {
1678
1872
  map<string, FunctionHandleMetadata> method_handle_metadata = 44;
1679
1873
  FunctionSchema function_schema = 45;
1680
1874
  optional string input_plane_url = 46;
1875
+ optional string input_plane_region = 47;
1876
+ // Use optional to ensure unset values default to None instead of 0
1877
+ optional uint64 max_object_size_bytes = 48;
1878
+ repeated string _experimental_flash_urls = 49; // (Optional) urls for flash services
1879
+ repeated DataFormat supported_input_formats = 50;
1880
+ repeated DataFormat supported_output_formats = 51;
1681
1881
  }
1682
1882
 
1683
1883
  message FunctionInput {
@@ -1727,11 +1927,15 @@ message FunctionOptions {
1727
1927
  optional uint32 max_concurrent_inputs = 14;
1728
1928
  optional uint32 batch_max_size = 15;
1729
1929
  optional uint64 batch_linger_ms = 16;
1930
+ optional SchedulerPlacement scheduler_placement = 17;
1931
+ optional string cloud_provider_str = 18;
1932
+ bool replace_cloud_bucket_mounts = 19;
1933
+ repeated CloudBucketMount cloud_bucket_mounts = 20;
1730
1934
  }
1731
1935
 
1732
1936
  message FunctionPrecreateRequest {
1733
1937
  string app_id = 1;
1734
- string function_name = 2 [ (modal.options.audit_target_attr) = true ];
1938
+ string function_name = 2 ;
1735
1939
  string existing_function_id = 3;
1736
1940
  Function.FunctionType function_type = 4;
1737
1941
  WebhookConfig webhook_config = 5;
@@ -1740,6 +1944,8 @@ message FunctionPrecreateRequest {
1740
1944
  // Mapping of method names to method definitions, only non-empty for class service functions
1741
1945
  map<string, MethodDefinition> method_definitions = 8;
1742
1946
  FunctionSchema function_schema = 9;
1947
+ repeated DataFormat supported_input_formats = 10;
1948
+ repeated DataFormat supported_output_formats = 11;
1743
1949
  }
1744
1950
 
1745
1951
  message FunctionPrecreateResponse {
@@ -1750,6 +1956,9 @@ message FunctionPrecreateResponse {
1750
1956
  message FunctionPutInputsItem {
1751
1957
  int32 idx = 1;
1752
1958
  FunctionInput input = 2;
1959
+ bool r2_failed = 3;
1960
+ reserved 4; // r2_latency_ms
1961
+ uint64 r2_throughput_bytes_s = 5;
1753
1962
  }
1754
1963
 
1755
1964
  message FunctionPutInputsRequest {
@@ -1775,6 +1984,8 @@ message FunctionPutOutputsItem {
1775
1984
  double output_created_at = 4;
1776
1985
  DataFormat data_format = 7; // for result.data_oneof
1777
1986
  uint32 retry_count = 8;
1987
+ string function_call_id = 9; // injected by the worker
1988
+ optional int32 function_map_idx = 10; // injected by the worker
1778
1989
  }
1779
1990
 
1780
1991
  message FunctionPutOutputsRequest {
@@ -1855,6 +2066,8 @@ message GenericResult { // Used for both tasks and function outputs
1855
2066
  // Terminates the function and all remaining inputs.
1856
2067
  GENERIC_STATUS_INIT_FAILURE = 5;
1857
2068
  GENERIC_STATUS_INTERNAL_FAILURE = 6;
2069
+ // Used when sandboxes are terminated due to idle_timeout
2070
+ GENERIC_STATUS_IDLE_TIMEOUT = 7;
1858
2071
  }
1859
2072
 
1860
2073
  GenericStatus status = 1; // Status of the task or function output.
@@ -1894,6 +2107,12 @@ message Image {
1894
2107
  bool runtime_debug = 20;
1895
2108
 
1896
2109
  BuildFunction build_function = 21;
2110
+
2111
+ // Build arguments for the image (--build-arg) for ARG substitution in Dockerfile.
2112
+ map<string, string> build_args = 22;
2113
+
2114
+ // Volume mount for RUN commands
2115
+ repeated VolumeMount volume_mounts = 23;
1897
2116
  }
1898
2117
 
1899
2118
  message ImageContextFile {
@@ -1901,6 +2120,10 @@ message ImageContextFile {
1901
2120
  bytes data = 2;
1902
2121
  }
1903
2122
 
2123
+ message ImageDeleteRequest {
2124
+ string image_id = 1;
2125
+ }
2126
+
1904
2127
  message ImageFromIdRequest {
1905
2128
  string image_id = 1;
1906
2129
  }
@@ -1912,7 +2135,7 @@ message ImageFromIdResponse {
1912
2135
 
1913
2136
  message ImageGetOrCreateRequest {
1914
2137
  Image image = 2;
1915
- string app_id = 4 [ (modal.options.audit_target_attr) = true ];
2138
+ string app_id = 4;
1916
2139
  string existing_image_id = 5; // ignored
1917
2140
  string build_function_id = 6;
1918
2141
  bool force_build = 7;
@@ -1952,13 +2175,21 @@ message ImageJoinStreamingResponse {
1952
2175
  message ImageMetadata {
1953
2176
  // The output of `python -VV. Not set if missing
1954
2177
  optional string python_version_info = 1;
2178
+
1955
2179
  // Installed python packages, as listed by by `pip list`.
1956
2180
  // package name -> version. Empty if missing
1957
2181
  map<string, string> python_packages = 2;
1958
- // The work directory of the image, defaulting to "/". Not set if missing
2182
+
2183
+ // The working directory of the image, as an absolute file path.
2184
+ //
2185
+ // For most images, this is not set, which means to use the default workdir:
2186
+ // - On function runners, the default is `/root` (home directory).
2187
+ // - For image builds and sandbox environments, it is `/`.
1959
2188
  optional string workdir = 3;
1960
- // The image's libc version
2189
+
2190
+ // The version of glibc in this image, if any.
1961
2191
  optional string libc_version_info = 4;
2192
+
1962
2193
  // The builder version for/with which the image was created.
1963
2194
  optional string image_builder_version = 5;
1964
2195
  }
@@ -1991,6 +2222,63 @@ message InputInfo {
1991
2222
  bool task_first_input = 7;
1992
2223
  }
1993
2224
 
2225
+ message ListPagination {
2226
+ int32 max_objects = 1;
2227
+ double created_before = 2;
2228
+ }
2229
+
2230
+ message MapAwaitRequest {
2231
+ oneof call_info {
2232
+ string function_call_id = 1;
2233
+ string map_token = 5;
2234
+ }
2235
+ string last_entry_id = 2;
2236
+ double requested_at = 3; // Used for waypoints.
2237
+ float timeout = 4;
2238
+ }
2239
+
2240
+ message MapAwaitResponse {
2241
+ repeated FunctionGetOutputsItem outputs = 1;
2242
+ string last_entry_id = 2;
2243
+ }
2244
+
2245
+ message MapCheckInputsRequest {
2246
+ string last_entry_id = 1;
2247
+ float timeout = 2;
2248
+ repeated string attempt_tokens = 3;
2249
+ }
2250
+
2251
+ message MapCheckInputsResponse {
2252
+ repeated bool lost = 1;
2253
+ }
2254
+
2255
+ message MapStartOrContinueItem {
2256
+ FunctionPutInputsItem input = 1;
2257
+ optional string attempt_token = 2; // None if this is a fresh input, otherwise it is the attempt token for a retry.
2258
+ }
2259
+
2260
+ message MapStartOrContinueRequest {
2261
+ string function_id = 1;
2262
+ string parent_input_id = 2;
2263
+ // Clients will send call_info on map continue requests.
2264
+ oneof call_info {
2265
+ string function_call_id = 3;
2266
+ string map_token = 5;
2267
+ }
2268
+ repeated MapStartOrContinueItem items = 4;
2269
+ }
2270
+
2271
+ message MapStartOrContinueResponse {
2272
+ // function_id and function_call_id are not necessary if map_token is provided.
2273
+ // All 3 will be sent until it is safe to only send map_token.
2274
+ string map_token = 6;
2275
+ string function_id = 1;
2276
+ string function_call_id = 2;
2277
+ uint32 max_inputs_outstanding = 3;
2278
+ repeated string attempt_tokens = 4;
2279
+ FunctionRetryPolicy retry_policy = 5;
2280
+ }
2281
+
1994
2282
  message MethodDefinition {
1995
2283
  string function_name = 1;
1996
2284
  Function.FunctionType function_type = 2;
@@ -1999,6 +2287,8 @@ message MethodDefinition {
1999
2287
  WebUrlInfo web_url_info = 5;
2000
2288
  repeated CustomDomainInfo custom_domain_info = 6;
2001
2289
  FunctionSchema function_schema = 7;
2290
+ repeated DataFormat supported_input_formats = 8;
2291
+ repeated DataFormat supported_output_formats = 9;
2002
2292
  }
2003
2293
 
2004
2294
  message MountFile {
@@ -2045,6 +2335,10 @@ message MultiPartUpload {
2045
2335
  string completion_url = 3;
2046
2336
  }
2047
2337
 
2338
+ message MultiPartUploadList {
2339
+ repeated MultiPartUpload items = 1;
2340
+ }
2341
+
2048
2342
  message NetworkAccess {
2049
2343
  enum NetworkAccessType {
2050
2344
  UNSPECIFIED = 0;
@@ -2155,6 +2449,7 @@ message PTYInfo {
2155
2449
  PTY_TYPE_SHELL = 2; // Replace function with shell
2156
2450
  }
2157
2451
  PTYType pty_type = 7;
2452
+ bool no_terminate_on_idle_stdin = 8;
2158
2453
  }
2159
2454
 
2160
2455
  message PortSpec {
@@ -2171,12 +2466,13 @@ message Proxy {
2171
2466
  string name = 1;
2172
2467
  double created_at = 2;
2173
2468
  string environment_name = 3;
2174
- string proxy_id = 5;
2175
2469
  repeated ProxyIp proxy_ips = 4;
2470
+ string proxy_id = 5;
2471
+ string region = 6;
2176
2472
  }
2177
2473
 
2178
2474
  message ProxyAddIpRequest {
2179
- string proxy_id = 1 [ (modal.options.audit_target_attr) = true ];
2475
+ string proxy_id = 1;
2180
2476
  }
2181
2477
 
2182
2478
  message ProxyAddIpResponse {
@@ -2184,8 +2480,9 @@ message ProxyAddIpResponse {
2184
2480
  }
2185
2481
 
2186
2482
  message ProxyCreateRequest {
2187
- string name = 1 [ (modal.options.audit_target_attr) = true ];
2483
+ string name = 1;
2188
2484
  string environment_name = 2;
2485
+ string region = 3;
2189
2486
  }
2190
2487
 
2191
2488
  message ProxyCreateResponse {
@@ -2193,12 +2490,12 @@ message ProxyCreateResponse {
2193
2490
  }
2194
2491
 
2195
2492
  message ProxyDeleteRequest {
2196
- string proxy_id = 1 [ (modal.options.audit_target_attr) = true ];
2493
+ string proxy_id = 1;
2197
2494
  }
2198
2495
 
2199
2496
  message ProxyGetOrCreateRequest {
2200
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
2201
- DeploymentNamespace namespace = 2;
2497
+ string deployment_name = 1;
2498
+ reserved 2; // namespace
2202
2499
  string environment_name = 3;
2203
2500
  ObjectCreationType object_creation_type = 4; // must be UNSPECIFIED
2204
2501
  }
@@ -2208,7 +2505,7 @@ message ProxyGetOrCreateResponse {
2208
2505
  }
2209
2506
 
2210
2507
  message ProxyGetRequest {
2211
- string name = 1 [ (modal.options.audit_target_attr) = true ];
2508
+ string name = 1;
2212
2509
  string environment_name = 2;
2213
2510
  }
2214
2511
 
@@ -2236,7 +2533,7 @@ message ProxyListResponse {
2236
2533
  }
2237
2534
 
2238
2535
  message ProxyRemoveIpRequest {
2239
- string proxy_ip = 1 [ (modal.options.audit_target_attr) = true ];
2536
+ string proxy_ip = 1;
2240
2537
  }
2241
2538
 
2242
2539
  message QueueClearRequest {
@@ -2246,18 +2543,19 @@ message QueueClearRequest {
2246
2543
  }
2247
2544
 
2248
2545
  message QueueDeleteRequest {
2249
- string queue_id = 1 [ (modal.options.audit_target_attr) = true ];
2546
+ string queue_id = 1;
2250
2547
  }
2251
2548
 
2252
2549
  message QueueGetOrCreateRequest {
2253
2550
  string deployment_name = 1;
2254
- DeploymentNamespace namespace = 2;
2551
+ reserved 2; // removed namespace
2255
2552
  string environment_name = 3;
2256
2553
  ObjectCreationType object_creation_type = 4;
2257
2554
  }
2258
2555
 
2259
2556
  message QueueGetOrCreateResponse {
2260
2557
  string queue_id = 1;
2558
+ QueueMetadata metadata = 2;
2261
2559
  }
2262
2560
 
2263
2561
  message QueueGetRequest {
@@ -2292,19 +2590,27 @@ message QueueLenResponse {
2292
2590
 
2293
2591
  message QueueListRequest {
2294
2592
  string environment_name = 1;
2295
- // Allow client to report a bounded total size to reduce the number of partitions that need to be checked
2296
- int32 total_size_limit = 2;
2593
+ int32 total_size_limit = 2; // Limit on "number of partitions" reported, since checking them is costly
2594
+ ListPagination pagination = 3;
2297
2595
  }
2298
2596
 
2299
2597
  message QueueListResponse {
2300
2598
  message QueueInfo {
2301
2599
  string name = 1;
2302
- double created_at = 2;
2600
+ double created_at = 2; // Superseded by metadata, used by clients up to 1.1.2
2303
2601
  int32 num_partitions = 3;
2304
2602
  int32 total_size = 4;
2603
+ string queue_id = 5;
2604
+ QueueMetadata metadata = 6;
2305
2605
  }
2306
2606
 
2307
2607
  repeated QueueInfo queues = 1;
2608
+ string environment_name = 2;
2609
+ }
2610
+
2611
+ message QueueMetadata {
2612
+ string name = 1;
2613
+ CreationInfo creation_info = 2;
2308
2614
  }
2309
2615
 
2310
2616
  message QueueNextItemsRequest {
@@ -2381,7 +2687,7 @@ message Sandbox {
2381
2687
  Resources resources = 5;
2382
2688
  CloudProvider cloud_provider = 6; // Deprecated at some point
2383
2689
 
2384
- uint32 timeout_secs = 7;
2690
+ uint32 timeout_secs = 7; // The max lifetime of a sandbox in seconds.
2385
2691
 
2386
2692
  optional string workdir = 8;
2387
2693
 
@@ -2432,18 +2738,57 @@ message Sandbox {
2432
2738
 
2433
2739
  // If set, overrides the runtime used by the function, either "runc" or "gvisor".
2434
2740
  optional string runtime = 28;
2741
+
2742
+ // If set, the sandbox will be created with verbose logging enabled.
2743
+ bool verbose = 29;
2744
+
2745
+ // If set, the sandbox will be created with a name.
2746
+ optional string name = 30;
2747
+
2748
+ // Experimental options
2749
+ map<string, bool> experimental_options = 31;
2750
+
2751
+ repeated string preload_path_prefixes = 32; // Internal use only.
2752
+
2753
+ // Optional idle timeout in seconds. If set, the sandbox will be terminated after being idle for this duration.
2754
+ optional uint32 idle_timeout_secs = 33;
2755
+
2756
+ // If set, the sandbox will be created with direct sandbox commands enabled.
2757
+ // Exec commands for the sandbox will be issued directly to the sandbox
2758
+ // command router running on the Modal worker.
2759
+ bool direct_sandbox_commands_enabled = 34;
2760
+ }
2761
+
2762
+ message SandboxCreateConnectTokenRequest {
2763
+ string sandbox_id = 1;
2764
+ string user_metadata = 2;
2765
+ }
2766
+
2767
+ message SandboxCreateConnectTokenResponse {
2768
+ string url = 1;
2769
+ string token = 2;
2435
2770
  }
2436
2771
 
2437
2772
  message SandboxCreateRequest {
2438
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
2773
+ string app_id = 1;
2439
2774
  Sandbox definition = 2;
2440
- string environment_name = 3;
2775
+ string environment_name = 3; // *DEPRECATED* 7/16/2025
2441
2776
  }
2442
2777
 
2443
2778
  message SandboxCreateResponse {
2444
2779
  string sandbox_id = 1;
2445
2780
  }
2446
2781
 
2782
+ message SandboxGetFromNameRequest {
2783
+ string sandbox_name = 1;
2784
+ string environment_name = 2;
2785
+ string app_name = 3;
2786
+ }
2787
+
2788
+ message SandboxGetFromNameResponse {
2789
+ string sandbox_id = 1;
2790
+ }
2791
+
2447
2792
  message SandboxGetLogsRequest {
2448
2793
  string sandbox_id = 1;
2449
2794
  FileDescriptor file_descriptor = 2;
@@ -2492,6 +2837,8 @@ message SandboxInfo {
2492
2837
  double created_at = 3;
2493
2838
  TaskInfo task_info = 4;
2494
2839
  string app_id = 5;
2840
+ repeated SandboxTag tags = 6; // TODO: Not yet exposed in client library.
2841
+ string name = 7;
2495
2842
 
2496
2843
  reserved 2; // modal.client.Sandbox definition
2497
2844
  }
@@ -2509,13 +2856,34 @@ message SandboxListResponse {
2509
2856
  }
2510
2857
 
2511
2858
  message SandboxRestoreRequest {
2859
+ enum SandboxNameOverrideType {
2860
+ SANDBOX_NAME_OVERRIDE_TYPE_UNSPECIFIED = 0;
2861
+ SANDBOX_NAME_OVERRIDE_TYPE_NONE = 1;
2862
+ SANDBOX_NAME_OVERRIDE_TYPE_STRING = 2;
2863
+ }
2864
+
2512
2865
  string snapshot_id = 1;
2866
+ string sandbox_name_override = 2;
2867
+ SandboxNameOverrideType sandbox_name_override_type = 3;
2513
2868
  }
2514
2869
 
2515
2870
  message SandboxRestoreResponse {
2516
2871
  string sandbox_id = 1;
2517
2872
  }
2518
2873
 
2874
+ message SandboxSnapshotFsAsyncGetRequest {
2875
+ string image_id = 1;
2876
+ float timeout = 2;
2877
+ }
2878
+
2879
+ message SandboxSnapshotFsAsyncRequest {
2880
+ string sandbox_id = 1;
2881
+ }
2882
+
2883
+ message SandboxSnapshotFsAsyncResponse {
2884
+ string image_id = 1;
2885
+ }
2886
+
2519
2887
  message SandboxSnapshotFsRequest {
2520
2888
  string sandbox_id = 1;
2521
2889
  float timeout = 2;
@@ -2568,6 +2936,14 @@ message SandboxTag {
2568
2936
  string tag_value = 2;
2569
2937
  }
2570
2938
 
2939
+ message SandboxTagsGetRequest {
2940
+ string sandbox_id = 1;
2941
+ }
2942
+
2943
+ message SandboxTagsGetResponse {
2944
+ repeated SandboxTag tags = 1;
2945
+ }
2946
+
2571
2947
  message SandboxTagsSetRequest {
2572
2948
  string environment_name = 1;
2573
2949
  string sandbox_id = 2;
@@ -2612,23 +2988,18 @@ message Schedule {
2612
2988
  }
2613
2989
 
2614
2990
  message SchedulerPlacement {
2615
- // TODO(irfansharif):
2616
- // - Fold in cloud, resource needs here too.
2617
- // - Allow specifying list of zones, cloud, fallback and alternative
2618
- // GPU types.
2619
-
2620
2991
  repeated string regions = 4;
2621
- // TODO(irfansharif): Make these two repeated.
2622
- optional string _zone = 2; // admin-only
2623
- optional string _lifecycle = 3; // admin-only, "on-demand" or "spot", else ignored
2624
- repeated string _instance_types = 5; // admin-only
2992
+ optional string _zone = 2; // TODO: Deprecate
2993
+ optional string _lifecycle = 3; // TODO: Deprecate
2994
+ repeated string _instance_types = 5; // TODO: Deprecate
2995
+ bool nonpreemptible = 6;
2625
2996
 
2626
2997
  reserved 1;
2627
2998
  }
2628
2999
 
2629
3000
  message SecretCreateRequest { // Not used by client anymore
2630
3001
  map<string, string> env_dict = 1;
2631
- string app_id = 2 [ (modal.options.audit_target_attr) = true ];
3002
+ string app_id = 2;
2632
3003
  string template_type = 3; // todo: not used?
2633
3004
  string existing_secret_id = 4;
2634
3005
  }
@@ -2642,8 +3013,8 @@ message SecretDeleteRequest {
2642
3013
  }
2643
3014
 
2644
3015
  message SecretGetOrCreateRequest {
2645
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
2646
- DeploymentNamespace namespace = 2;
3016
+ string deployment_name = 1;
3017
+ reserved 2; // removed namespace
2647
3018
  string environment_name = 3;
2648
3019
  ObjectCreationType object_creation_type = 4; // Not used atm
2649
3020
  map<string, string> env_dict = 5;
@@ -2653,25 +3024,35 @@ message SecretGetOrCreateRequest {
2653
3024
 
2654
3025
  message SecretGetOrCreateResponse {
2655
3026
  string secret_id = 1;
3027
+ SecretMetadata metadata = 2;
2656
3028
  }
2657
3029
 
2658
3030
  message SecretListItem {
2659
3031
  string label = 1;
2660
- double created_at = 2;
3032
+ double created_at = 2; // Superseded by metadata, used by clients up to 1.1.2
2661
3033
  double last_used_at = 3;
2662
- string environment_name = 4;
3034
+ string environment_name = 4; // Unused by client
2663
3035
  string secret_id = 5;
3036
+ SecretMetadata metadata = 6;
2664
3037
  }
2665
3038
 
2666
3039
  message SecretListRequest {
2667
- string environment_name = 1; // leaving empty will assume a singular environment
3040
+ string environment_name = 1;
3041
+ ListPagination pagination = 2;
2668
3042
  }
2669
3043
 
2670
3044
  message SecretListResponse {
2671
3045
  repeated SecretListItem items = 1;
2672
- string environment_name = 2; // the environment that was listed (useful when relying on "default" logic)
3046
+ string environment_name = 2;
2673
3047
  }
2674
3048
 
3049
+ message SecretMetadata {
3050
+ string name = 1;
3051
+ CreationInfo creation_info = 2;
3052
+ }
3053
+
3054
+ // SharedVolume in the backend corresponds to NetworkFileSystem in the current API
3055
+
2675
3056
  message SharedVolumeDeleteRequest {
2676
3057
  string shared_volume_id = 1;
2677
3058
  }
@@ -2689,8 +3070,8 @@ message SharedVolumeGetFileResponse {
2689
3070
  }
2690
3071
 
2691
3072
  message SharedVolumeGetOrCreateRequest {
2692
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
2693
- DeploymentNamespace namespace = 2;
3073
+ string deployment_name = 1;
3074
+ reserved 2; // removed namespace
2694
3075
  string environment_name = 3;
2695
3076
  ObjectCreationType object_creation_type = 4;
2696
3077
  string app_id = 5; // only used with OBJECT_CREATION_TYPE_ANONYMOUS_OWNED_BY_APP
@@ -2733,11 +3114,11 @@ message SharedVolumeMount {
2733
3114
  string mount_path = 1;
2734
3115
  string shared_volume_id = 2;
2735
3116
  CloudProvider cloud_provider = 3;
2736
- bool allow_cross_region = 4;
3117
+ reserved 4; // allow_cross_region
2737
3118
  }
2738
3119
 
2739
3120
  message SharedVolumePutFileRequest {
2740
- string shared_volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3121
+ string shared_volume_id = 1;
2741
3122
  string path = 2;
2742
3123
  string sha256_hex = 3;
2743
3124
  oneof data_oneof {
@@ -2752,7 +3133,7 @@ message SharedVolumePutFileResponse {
2752
3133
  }
2753
3134
 
2754
3135
  message SharedVolumeRemoveFileRequest {
2755
- string shared_volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3136
+ string shared_volume_id = 1;
2756
3137
  string path = 2;
2757
3138
  bool recursive = 3;
2758
3139
  }
@@ -2770,14 +3151,27 @@ message TaskClusterHelloRequest {
2770
3151
  message TaskClusterHelloResponse {
2771
3152
  string cluster_id = 1;
2772
3153
  uint32 cluster_rank = 2;
2773
- // All IP addresses in cluster, ordered by cluster rank
3154
+ // All IPv6 addresses in cluster, ordered by cluster rank
2774
3155
  repeated string container_ips = 3;
3156
+ repeated string container_ipv4_ips = 4;
2775
3157
  }
2776
3158
 
2777
3159
  message TaskCurrentInputsResponse {
2778
3160
  repeated string input_ids = 1;
2779
3161
  }
2780
3162
 
3163
+ // Used to get a JWT and URL for direct access to a task command router
3164
+ // running on the modal-worker, so the client can issue exec commands (and other
3165
+ // operations as they become available) directly to the worker.
3166
+ message TaskGetCommandRouterAccessRequest {
3167
+ string task_id = 1;
3168
+ }
3169
+
3170
+ message TaskGetCommandRouterAccessResponse {
3171
+ string jwt = 1;
3172
+ string url = 2;
3173
+ }
3174
+
2781
3175
  message TaskInfo {
2782
3176
  string id = 1;
2783
3177
  double started_at = 2;
@@ -2785,6 +3179,9 @@ message TaskInfo {
2785
3179
  modal.client.GenericResult result = 4;
2786
3180
  double enqueued_at = 5;
2787
3181
  string gpu_type = 6;
3182
+ string sandbox_id = 7;
3183
+ TaskSnapshotBehavior snapshot_behavior = 8;
3184
+ GPUConfig gpu_config = 9;
2788
3185
  }
2789
3186
 
2790
3187
  message TaskListRequest {
@@ -2817,6 +3214,7 @@ message TaskLogsBatch {
2817
3214
  bool eof = 14;
2818
3215
  string pty_exec_id = 15; // Used for interactive functions
2819
3216
  string root_function_id = 16;
3217
+ uint32 ttl_days = 17;
2820
3218
  }
2821
3219
 
2822
3220
  message TaskProgress {
@@ -2903,10 +3301,20 @@ message TunnelStopResponse {
2903
3301
  bool exists = 1;
2904
3302
  }
2905
3303
 
3304
+ message UploadUrlList {
3305
+ repeated string items = 1;
3306
+ }
3307
+
3308
+ // Used for capturing context about an action performed by a user
3309
+ message UserActionInfo {
3310
+ string user_id = 1;
3311
+ double timestamp = 2;
3312
+ }
3313
+
2906
3314
  message VolumeCommitRequest {
2907
3315
  // NOTE(staffan): Mounting a volume in multiple locations is not supported, so volume_id alone uniquely identifies
2908
3316
  // a volume mount.
2909
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3317
+ string volume_id = 1;
2910
3318
  }
2911
3319
 
2912
3320
  message VolumeCommitResponse {
@@ -2964,8 +3372,8 @@ message VolumeGetFileResponse {
2964
3372
  }
2965
3373
 
2966
3374
  message VolumeGetOrCreateRequest {
2967
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
2968
- DeploymentNamespace namespace = 2;
3375
+ string deployment_name = 1;
3376
+ reserved 2; // removed namespace
2969
3377
  string environment_name = 3;
2970
3378
  ObjectCreationType object_creation_type = 4;
2971
3379
  string app_id = 5; // only used with OBJECT_CREATION_TYPE_ANONYMOUS_OWNED_BY_APP
@@ -2974,7 +3382,7 @@ message VolumeGetOrCreateRequest {
2974
3382
 
2975
3383
  message VolumeGetOrCreateResponse {
2976
3384
  string volume_id = 1;
2977
- VolumeFsVersion version = 2;
3385
+ VolumeFsVersion version = 2; // Not used directly; version is part of the metadata
2978
3386
  VolumeMetadata metadata = 3;
2979
3387
  }
2980
3388
 
@@ -3007,11 +3415,13 @@ message VolumeListFilesResponse {
3007
3415
  message VolumeListItem {
3008
3416
  string label = 1; // app name of object entity app
3009
3417
  string volume_id = 2;
3010
- double created_at = 3;
3418
+ double created_at = 3; // Superseded by metadata, used by clients up to 1.1.2
3419
+ VolumeMetadata metadata = 4;
3011
3420
  }
3012
3421
 
3013
3422
  message VolumeListRequest {
3014
3423
  string environment_name = 1;
3424
+ ListPagination pagination = 2;
3015
3425
  }
3016
3426
 
3017
3427
  message VolumeListResponse {
@@ -3021,6 +3431,8 @@ message VolumeListResponse {
3021
3431
 
3022
3432
  message VolumeMetadata {
3023
3433
  VolumeFsVersion version = 1;
3434
+ string name = 2;
3435
+ CreationInfo creation_info = 3;
3024
3436
  }
3025
3437
 
3026
3438
  message VolumeMount {
@@ -3112,19 +3524,19 @@ message VolumeReloadRequest {
3112
3524
  }
3113
3525
 
3114
3526
  message VolumeRemoveFile2Request {
3115
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3527
+ string volume_id = 1;
3116
3528
  string path = 2;
3117
3529
  bool recursive = 3;
3118
3530
  }
3119
3531
 
3120
3532
  message VolumeRemoveFileRequest {
3121
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3533
+ string volume_id = 1;
3122
3534
  string path = 2;
3123
3535
  bool recursive = 3;
3124
3536
  }
3125
3537
 
3126
3538
  message VolumeRenameRequest {
3127
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3539
+ string volume_id = 1;
3128
3540
  string name = 2;
3129
3541
  }
3130
3542
 
@@ -3148,13 +3560,31 @@ message WebUrlInfo {
3148
3560
  message WebhookConfig {
3149
3561
  WebhookType type = 1;
3150
3562
  string method = 2;
3151
- string requested_suffix = 4;
3563
+ string requested_suffix = 4; // User-supplied "label" component of URL
3152
3564
  WebhookAsyncMode async_mode = 5;
3153
3565
  repeated CustomDomainConfig custom_domains = 6;
3154
3566
  uint32 web_server_port = 7;
3155
3567
  float web_server_startup_timeout = 8;
3156
3568
  bool web_endpoint_docs = 9;
3157
3569
  bool requires_proxy_auth = 10;
3570
+ string ephemeral_suffix = 11; // Additional URL suffix added for ephemeral Apps
3571
+ }
3572
+
3573
+ message WorkspaceBillingReportItem {
3574
+ string object_id = 1;
3575
+ string description = 2;
3576
+ string environment_name = 3;
3577
+ google.protobuf.Timestamp interval = 4;
3578
+ string cost = 5;
3579
+ map<string, string> tags = 6;
3580
+ }
3581
+
3582
+ message WorkspaceBillingReportRequest {
3583
+ // Workspace ID will be implicit in the request metadata
3584
+ google.protobuf.Timestamp start_timestamp = 1;
3585
+ google.protobuf.Timestamp end_timestamp = 2;
3586
+ string resolution = 3; // e.g. 'd' or 'h'; server defines what we accept
3587
+ repeated string tag_names = 4;
3158
3588
  }
3159
3589
 
3160
3590
  message WorkspaceNameLookupResponse {
@@ -3174,21 +3604,24 @@ service ModalClient {
3174
3604
  rpc AppGetLogs(AppGetLogsRequest) returns (stream TaskLogsBatch);
3175
3605
  rpc AppGetObjects(AppGetObjectsRequest) returns (AppGetObjectsResponse);
3176
3606
  rpc AppGetOrCreate(AppGetOrCreateRequest) returns (AppGetOrCreateResponse);
3607
+ rpc AppGetTags(AppGetTagsRequest) returns (AppGetTagsResponse);
3177
3608
  rpc AppHeartbeat(AppHeartbeatRequest) returns (google.protobuf.Empty);
3178
3609
  rpc AppList(AppListRequest) returns (AppListResponse);
3179
3610
  rpc AppLookup(AppLookupRequest) returns (AppLookupResponse);
3180
3611
  rpc AppPublish(AppPublishRequest) returns (AppPublishResponse);
3181
3612
  rpc AppRollback(AppRollbackRequest) returns (google.protobuf.Empty);
3182
3613
  rpc AppSetObjects(AppSetObjectsRequest) returns (google.protobuf.Empty);
3614
+ rpc AppSetTags(AppSetTagsRequest) returns (google.protobuf.Empty);
3183
3615
  rpc AppStop(AppStopRequest) returns (google.protobuf.Empty);
3184
3616
 
3185
3617
  // Input Plane
3186
- // These RPCs are experimental, not deployed to production, and can be changed / removed
3187
- // without needing to worry about backwards compatibility.
3188
3618
  rpc AttemptAwait(AttemptAwaitRequest) returns (AttemptAwaitResponse);
3189
3619
  rpc AttemptRetry(AttemptRetryRequest) returns (AttemptRetryResponse);
3190
3620
  rpc AttemptStart(AttemptStartRequest) returns (AttemptStartResponse);
3191
3621
 
3622
+ // Auth Token
3623
+ rpc AuthTokenGet(AuthTokenGetRequest) returns (AuthTokenGetResponse);
3624
+
3192
3625
  // Blobs
3193
3626
  rpc BlobCreate(BlobCreateRequest) returns (BlobCreateResponse);
3194
3627
  rpc BlobGet(BlobGetRequest) returns (BlobGetResponse);
@@ -3215,6 +3648,7 @@ service ModalClient {
3215
3648
  rpc ContainerHeartbeat(ContainerHeartbeatRequest) returns (ContainerHeartbeatResponse);
3216
3649
  rpc ContainerHello(google.protobuf.Empty) returns (google.protobuf.Empty);
3217
3650
  rpc ContainerLog(ContainerLogRequest) returns (google.protobuf.Empty);
3651
+ rpc ContainerReloadVolumes(ContainerReloadVolumesRequest) returns (ContainerReloadVolumesResponse);
3218
3652
  rpc ContainerStop(ContainerStopRequest) returns (ContainerStopResponse);
3219
3653
 
3220
3654
  // Dicts
@@ -3242,15 +3676,23 @@ service ModalClient {
3242
3676
  rpc EnvironmentList(google.protobuf.Empty) returns (EnvironmentListResponse);
3243
3677
  rpc EnvironmentUpdate(EnvironmentUpdateRequest) returns (EnvironmentListItem);
3244
3678
 
3679
+ // Modal Flash (experimental)
3680
+ rpc FlashContainerDeregister(FlashContainerDeregisterRequest) returns (google.protobuf.Empty);
3681
+ rpc FlashContainerList(FlashContainerListRequest) returns (FlashContainerListResponse);
3682
+ rpc FlashContainerRegister(FlashContainerRegisterRequest) returns (FlashContainerRegisterResponse);
3683
+ rpc FlashSetTargetSlotsMetrics(FlashSetTargetSlotsMetricsRequest) returns (FlashSetTargetSlotsMetricsResponse);
3684
+
3245
3685
  // Functions
3246
3686
  rpc FunctionAsyncInvoke(FunctionAsyncInvokeRequest) returns (FunctionAsyncInvokeResponse);
3247
3687
  rpc FunctionBindParams(FunctionBindParamsRequest) returns (FunctionBindParamsResponse);
3248
3688
  rpc FunctionCallCancel(FunctionCallCancelRequest) returns (google.protobuf.Empty);
3689
+ rpc FunctionCallFromId(FunctionCallFromIdRequest) returns (FunctionCallFromIdResponse);
3249
3690
  rpc FunctionCallGetDataIn(FunctionCallGetDataRequest) returns (stream DataChunk);
3250
3691
  rpc FunctionCallGetDataOut(FunctionCallGetDataRequest) returns (stream DataChunk);
3251
3692
  rpc FunctionCallList(FunctionCallListRequest) returns (FunctionCallListResponse);
3252
3693
  rpc FunctionCallPutDataOut(FunctionCallPutDataRequest) returns (google.protobuf.Empty);
3253
3694
  rpc FunctionCreate(FunctionCreateRequest) returns (FunctionCreateResponse);
3695
+ rpc FunctionFinishInputs(FunctionFinishInputsRequest) returns (google.protobuf.Empty); // For map RPCs, to signal that all inputs have been sent
3254
3696
  rpc FunctionGet(FunctionGetRequest) returns (FunctionGetResponse);
3255
3697
  rpc FunctionGetCallGraph(FunctionGetCallGraphRequest) returns (FunctionGetCallGraphResponse);
3256
3698
  rpc FunctionGetCurrentStats(FunctionGetCurrentStatsRequest) returns (FunctionStats);
@@ -3267,10 +3709,16 @@ service ModalClient {
3267
3709
  rpc FunctionUpdateSchedulingParams(FunctionUpdateSchedulingParamsRequest) returns (FunctionUpdateSchedulingParamsResponse);
3268
3710
 
3269
3711
  // Images
3712
+ rpc ImageDelete(ImageDeleteRequest) returns (google.protobuf.Empty);
3270
3713
  rpc ImageFromId(ImageFromIdRequest) returns (ImageFromIdResponse);
3271
3714
  rpc ImageGetOrCreate(ImageGetOrCreateRequest) returns (ImageGetOrCreateResponse);
3272
3715
  rpc ImageJoinStreaming(ImageJoinStreamingRequest) returns (stream ImageJoinStreamingResponse);
3273
3716
 
3717
+ // Input Plane Map
3718
+ rpc MapAwait(MapAwaitRequest) returns (MapAwaitResponse);
3719
+ rpc MapCheckInputs(MapCheckInputsRequest) returns (MapCheckInputsResponse);
3720
+ rpc MapStartOrContinue(MapStartOrContinueRequest) returns (MapStartOrContinueResponse);
3721
+
3274
3722
  // Mounts
3275
3723
  rpc MountGetOrCreate(MountGetOrCreateRequest) returns (MountGetOrCreateResponse);
3276
3724
  rpc MountPutFile(MountPutFileRequest) returns (MountPutFileResponse);
@@ -3300,6 +3748,8 @@ service ModalClient {
3300
3748
 
3301
3749
  // Sandboxes
3302
3750
  rpc SandboxCreate(SandboxCreateRequest) returns (SandboxCreateResponse);
3751
+ rpc SandboxCreateConnectToken(SandboxCreateConnectTokenRequest) returns (SandboxCreateConnectTokenResponse);
3752
+ rpc SandboxGetFromName(SandboxGetFromNameRequest) returns (SandboxGetFromNameResponse);
3303
3753
  rpc SandboxGetLogs(SandboxGetLogsRequest) returns (stream TaskLogsBatch);
3304
3754
  rpc SandboxGetResourceUsage(SandboxGetResourceUsageRequest) returns (SandboxGetResourceUsageResponse);
3305
3755
  rpc SandboxGetTaskId(SandboxGetTaskIdRequest) returns (SandboxGetTaskIdResponse); // needed for modal container exec
@@ -3308,9 +3758,12 @@ service ModalClient {
3308
3758
  rpc SandboxRestore(SandboxRestoreRequest) returns (SandboxRestoreResponse);
3309
3759
  rpc SandboxSnapshot(SandboxSnapshotRequest) returns (SandboxSnapshotResponse);
3310
3760
  rpc SandboxSnapshotFs(SandboxSnapshotFsRequest) returns (SandboxSnapshotFsResponse);
3761
+ rpc SandboxSnapshotFsAsync(SandboxSnapshotFsAsyncRequest) returns (SandboxSnapshotFsAsyncResponse);
3762
+ rpc SandboxSnapshotFsAsyncGet(SandboxSnapshotFsAsyncGetRequest) returns (SandboxSnapshotFsResponse);
3311
3763
  rpc SandboxSnapshotGet(SandboxSnapshotGetRequest) returns (SandboxSnapshotGetResponse);
3312
3764
  rpc SandboxSnapshotWait(SandboxSnapshotWaitRequest) returns (SandboxSnapshotWaitResponse);
3313
3765
  rpc SandboxStdinWrite(SandboxStdinWriteRequest) returns (SandboxStdinWriteResponse);
3766
+ rpc SandboxTagsGet(SandboxTagsGetRequest) returns (SandboxTagsGetResponse);
3314
3767
  rpc SandboxTagsSet(SandboxTagsSetRequest) returns (google.protobuf.Empty);
3315
3768
  rpc SandboxTerminate(SandboxTerminateRequest) returns (SandboxTerminateResponse);
3316
3769
  rpc SandboxWait(SandboxWaitRequest) returns (SandboxWaitResponse);
@@ -3334,6 +3787,7 @@ service ModalClient {
3334
3787
  // Tasks
3335
3788
  rpc TaskClusterHello(TaskClusterHelloRequest) returns (TaskClusterHelloResponse);
3336
3789
  rpc TaskCurrentInputs(google.protobuf.Empty) returns (TaskCurrentInputsResponse);
3790
+ rpc TaskGetCommandRouterAccess(TaskGetCommandRouterAccessRequest) returns (TaskGetCommandRouterAccessResponse);
3337
3791
  rpc TaskList(TaskListRequest) returns (TaskListResponse);
3338
3792
  rpc TaskResult(TaskResultRequest) returns (google.protobuf.Empty);
3339
3793
 
@@ -3365,5 +3819,6 @@ service ModalClient {
3365
3819
  rpc VolumeRename(VolumeRenameRequest) returns (google.protobuf.Empty);
3366
3820
 
3367
3821
  // Workspaces
3822
+ rpc WorkspaceBillingReport(WorkspaceBillingReportRequest) returns (stream WorkspaceBillingReportItem);
3368
3823
  rpc WorkspaceNameLookup(google.protobuf.Empty) returns (WorkspaceNameLookupResponse);
3369
3824
  }