modal 0.67.39__py3-none-any.whl → 0.67.41__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.
modal/client.pyi CHANGED
@@ -26,7 +26,7 @@ class _Client:
26
26
  _stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
27
27
 
28
28
  def __init__(
29
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.39"
29
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.41"
30
30
  ): ...
31
31
  def is_closed(self) -> bool: ...
32
32
  @property
@@ -81,7 +81,7 @@ class Client:
81
81
  _stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
82
82
 
83
83
  def __init__(
84
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.39"
84
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.41"
85
85
  ): ...
86
86
  def is_closed(self) -> bool: ...
87
87
  @property
modal/functions.py CHANGED
@@ -347,7 +347,7 @@ class _FunctionSpec:
347
347
  volumes: dict[Union[str, PurePosixPath], Union[_Volume, _CloudBucketMount]]
348
348
  gpus: Union[GPU_T, list[GPU_T]] # TODO(irfansharif): Somehow assert that it's the first kind, in sandboxes
349
349
  cloud: Optional[str]
350
- cpu: Optional[float]
350
+ cpu: Optional[Union[float, tuple[float, float]]]
351
351
  memory: Optional[Union[int, tuple[int, int]]]
352
352
  ephemeral_disk: Optional[int]
353
353
  scheduler_placement: Optional[SchedulerPlacement]
@@ -448,7 +448,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
448
448
  batch_max_size: Optional[int] = None,
449
449
  batch_wait_ms: Optional[int] = None,
450
450
  container_idle_timeout: Optional[int] = None,
451
- cpu: Optional[float] = None,
451
+ cpu: Optional[Union[float, tuple[float, float]]] = None,
452
452
  keep_warm: Optional[int] = None, # keep_warm=True is equivalent to keep_warm=1
453
453
  cloud: Optional[str] = None,
454
454
  scheduler_placement: Optional[SchedulerPlacement] = None,
modal/functions.pyi CHANGED
@@ -96,7 +96,7 @@ class _FunctionSpec:
96
96
  ]
97
97
  gpus: typing.Union[None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]]
98
98
  cloud: typing.Optional[str]
99
- cpu: typing.Optional[float]
99
+ cpu: typing.Union[float, tuple[float, float], None]
100
100
  memory: typing.Union[int, tuple[int, int], None]
101
101
  ephemeral_disk: typing.Optional[int]
102
102
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement]
@@ -117,7 +117,7 @@ class _FunctionSpec:
117
117
  None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
118
118
  ],
119
119
  cloud: typing.Optional[str],
120
- cpu: typing.Optional[float],
120
+ cpu: typing.Union[float, tuple[float, float], None],
121
121
  memory: typing.Union[int, tuple[int, int], None],
122
122
  ephemeral_disk: typing.Optional[int],
123
123
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement],
@@ -180,7 +180,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
180
180
  batch_max_size: typing.Optional[int] = None,
181
181
  batch_wait_ms: typing.Optional[int] = None,
182
182
  container_idle_timeout: typing.Optional[int] = None,
183
- cpu: typing.Optional[float] = None,
183
+ cpu: typing.Union[float, tuple[float, float], None] = None,
184
184
  keep_warm: typing.Optional[int] = None,
185
185
  cloud: typing.Optional[str] = None,
186
186
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
@@ -348,7 +348,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
348
348
  batch_max_size: typing.Optional[int] = None,
349
349
  batch_wait_ms: typing.Optional[int] = None,
350
350
  container_idle_timeout: typing.Optional[int] = None,
351
- cpu: typing.Optional[float] = None,
351
+ cpu: typing.Union[float, tuple[float, float], None] = None,
352
352
  keep_warm: typing.Optional[int] = None,
353
353
  cloud: typing.Optional[str] = None,
354
354
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
modal/sandbox.py CHANGED
@@ -196,7 +196,10 @@ class _Sandbox(_Object, type_prefix="sb"):
196
196
  gpu: GPU_T = None,
197
197
  cloud: Optional[str] = None,
198
198
  region: Optional[Union[str, Sequence[str]]] = None, # Region or regions to run the sandbox on.
199
- cpu: Optional[float] = None, # How many CPU cores to request. This is a soft limit.
199
+ # Specify, in fractional CPU cores, how many CPU cores to request.
200
+ # Or, pass (request, limit) to additionally specify a hard limit in fractional CPU cores.
201
+ # CPU throttling will prevent a container from exceeding its specified limit.
202
+ cpu: Optional[Union[float, tuple[float, float]]] = None,
200
203
  # Specify, in MiB, a memory request which is the minimum memory required.
201
204
  # Or, pass (request, limit) to additionally specify a hard limit in MiB.
202
205
  memory: Optional[Union[int, tuple[int, int]]] = None,
@@ -504,17 +507,16 @@ class _Sandbox(_Object, type_prefix="sb"):
504
507
  await secret.resolve(client=self._client)
505
508
 
506
509
  task_id = await self._get_task_id()
507
- resp = await self._client.stub.ContainerExec(
508
- api_pb2.ContainerExecRequest(
509
- task_id=task_id,
510
- command=cmds,
511
- pty_info=_pty_info or pty_info,
512
- runtime_debug=config.get("function_runtime_debug"),
513
- timeout_secs=timeout or 0,
514
- workdir=workdir,
515
- secret_ids=[secret.object_id for secret in secrets],
516
- )
510
+ req = api_pb2.ContainerExecRequest(
511
+ task_id=task_id,
512
+ command=cmds,
513
+ pty_info=_pty_info or pty_info,
514
+ runtime_debug=config.get("function_runtime_debug"),
515
+ timeout_secs=timeout or 0,
516
+ workdir=workdir,
517
+ secret_ids=[secret.object_id for secret in secrets],
517
518
  )
519
+ resp = await retry_transient_errors(self._client.stub.ContainerExec, req)
518
520
  by_line = bufsize == 1
519
521
  return _ContainerProcess(resp.exec_id, self._client, stdout=stdout, stderr=stderr, text=text, by_line=by_line)
520
522
 
modal/sandbox.pyi CHANGED
@@ -69,7 +69,7 @@ class _Sandbox(modal.object._Object):
69
69
  gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
70
70
  cloud: typing.Optional[str] = None,
71
71
  region: typing.Union[str, collections.abc.Sequence[str], None] = None,
72
- cpu: typing.Optional[float] = None,
72
+ cpu: typing.Union[float, tuple[float, float], None] = None,
73
73
  memory: typing.Union[int, tuple[int, int], None] = None,
74
74
  block_network: bool = False,
75
75
  cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
@@ -190,7 +190,7 @@ class Sandbox(modal.object.Object):
190
190
  gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
191
191
  cloud: typing.Optional[str] = None,
192
192
  region: typing.Union[str, collections.abc.Sequence[str], None] = None,
193
- cpu: typing.Optional[float] = None,
193
+ cpu: typing.Union[float, tuple[float, float], None] = None,
194
194
  memory: typing.Union[int, tuple[int, int], None] = None,
195
195
  block_network: bool = False,
196
196
  cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
@@ -221,7 +221,7 @@ class Sandbox(modal.object.Object):
221
221
  gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
222
222
  cloud: typing.Optional[str] = None,
223
223
  region: typing.Union[str, collections.abc.Sequence[str], None] = None,
224
- cpu: typing.Optional[float] = None,
224
+ cpu: typing.Union[float, tuple[float, float], None] = None,
225
225
  memory: typing.Union[int, tuple[int, int], None] = None,
226
226
  block_network: bool = False,
227
227
  cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.67.39
3
+ Version: 0.67.41
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -19,7 +19,7 @@ modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
19
19
  modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
20
20
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
21
21
  modal/client.py,sha256=cmylZhU35txmrx4nltNYuuqXRgeoMtm0ow1J9wJkEYQ,16400
22
- modal/client.pyi,sha256=D17w1r5HIlAe0QG2Xx65-Dmv-0WD1ATslnQIfXqTiTE,7354
22
+ modal/client.pyi,sha256=Ib2roAy5eGLisWtjCXqmKHgnNo1ArcJiKYb5N9TW8tQ,7354
23
23
  modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
24
24
  modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
25
25
  modal/cls.py,sha256=OJqzj_V-n1g48BY_4Jg_BOTQdftEEl4kTWN0X4FOOdg,27378
@@ -33,8 +33,8 @@ modal/environments.py,sha256=5cgA-zbm6ngKLsRA19zSOgtgo9-BarJK3FJK0BiF2Lo,6505
33
33
  modal/environments.pyi,sha256=XalNpiPkAtHWAvOU2Cotq0ozmtl-Jv0FDsR8h9mr27Q,3521
34
34
  modal/exception.py,sha256=EBkdWVved2XEPsXaoPRu56xfxFFHL9iuqvUsdj42WDA,6392
35
35
  modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
36
- modal/functions.py,sha256=Lteg8dMa8ly72-RM1ozxeGQ500pdeFyJgtflVwp3U7Q,66629
37
- modal/functions.pyi,sha256=DXodybnhZ4kD0CAFmQXRTv6FhcsHIgZ5TT_rInG3xDo,24892
36
+ modal/functions.py,sha256=3GjjFbf40XciWAa4rTmh0erkZjPzRjKHqWxUu91mHOU,66685
37
+ modal/functions.pyi,sha256=4k5CaJ9iTuEyHQ2rC5OysNHBLv1CZrD7zBMU1zXIU4w,24988
38
38
  modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
39
39
  modal/image.py,sha256=cQ6WP1xHXZT_nY8z3aEFiGwKzrTV0yxi3Ab8JzF91eo,79653
40
40
  modal/image.pyi,sha256=PIKH6JBA4L5TfdJrQu3pm2ykyIITmiP920TpP8cdyQA,24585
@@ -60,8 +60,8 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
60
60
  modal/runner.py,sha256=7obU-Gq1ocpBGCuR6pvn1T-D6ggg1T48qFo2TNUGWkU,24089
61
61
  modal/runner.pyi,sha256=RAtCvx_lXWjyFjIaZ3t9-X1c7rqpgAQlhl4Hww53OY8,5038
62
62
  modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
63
- modal/sandbox.py,sha256=5V0y7HfhfhVYY-mx-w--iKMYBPrSnu-KYOp5nPy9LkE,26097
64
- modal/sandbox.pyi,sha256=mUxo6YMJgwiWLuG-NiqhZvH7yaWmAortTlqz2Tzmc7A,18036
63
+ modal/sandbox.py,sha256=ua2z6aV_fBE_7hSCv9vcRp4U9j6lRE9uOrcen4LEJks,26316
64
+ modal/sandbox.pyi,sha256=fRl32Pt5F6TbK7aYewjlcL4WQxxmp7m6Ybktmkd2VOk,18108
65
65
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
66
66
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
67
67
  modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
@@ -142,13 +142,13 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
142
142
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
143
143
  modal_global_objects/mounts/python_standalone.py,sha256=SL_riIxpd8mP4i4CLDCWiFFNj0Ltknm9c_UIGfX5d60,1836
144
144
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
145
- modal_proto/api.proto,sha256=0AWqw9MDQvRrQTZI2xa8fVRcbs2lJG1DDt42ijBaJeY,78122
146
- modal_proto/api_grpc.py,sha256=HvNN-zBJUs6z-a1T9Jn2ECs-Fs7RnkJ4FVzPTH6xU98,100519
147
- modal_proto/api_pb2.py,sha256=hTsHAAKqmUxctck2FbpmOX4QTeF5pkNR_4BDYkrCxjk,284470
148
- modal_proto/api_pb2.pyi,sha256=n9SMpTlIG3qhNI6XBc3gez5OeSzuaRfs4jkfu8WMIRw,380221
149
- modal_proto/api_pb2_grpc.py,sha256=VFMzQ9MYmPg1XbTnmdjyw3MKhcPcqpBXtsQvtTn1uDI,217438
150
- modal_proto/api_pb2_grpc.pyi,sha256=1o_3hja-2Y0iAlZDxnIXgahZQuaM6ruWLuc_2YoFuls,50691
151
- modal_proto/modal_api_grpc.py,sha256=qUVht8AH8avTG2fm7Gw4pLwbgQTfqVgF5s_17HcrGKk,13438
145
+ modal_proto/api.proto,sha256=e1htlTwZbWpNA3khziIYetwU0Mf6dBuyFGDiv_7jbl4,78446
146
+ modal_proto/api_grpc.py,sha256=DveC4ejFYEhCLiWbQShnmY31_FWGYU675Bmr7nHhsgs,101342
147
+ modal_proto/api_pb2.py,sha256=WuaJmwcoq39U09SZu73D-rowGWxKw57GHvTgDhkQlEI,286035
148
+ modal_proto/api_pb2.pyi,sha256=W-KCpNsYftytboeYOVR7qwekOwN4htwyHWD0OMOfmA8,381838
149
+ modal_proto/api_pb2_grpc.py,sha256=2PEP6JPOoTw2rDC5qYjLNuumP68ZwAouRhCoayisAhY,219162
150
+ modal_proto/api_pb2_grpc.pyi,sha256=uWtCxVEd0cFpOZ1oOGfZNO7Dv45OP4kp09jMnNyx9D4,51098
151
+ modal_proto/modal_api_grpc.py,sha256=-8mLby_om5MYo6yu1zA_hqhz0yLsQW7k2YWBVZW1iVs,13546
152
152
  modal_proto/modal_options_grpc.py,sha256=qJ1cuwA54oRqrdTyPTbvfhFZYd9HhJKK5UCwt523r3Y,120
153
153
  modal_proto/options.proto,sha256=a-siq4swVbZPfaFRXAipRZzGP2bq8OsdUvjlyzAeodQ,488
154
154
  modal_proto/options_grpc.py,sha256=M18X3d-8F_cNYSVM3I25dUTO5rZ0rd-vCCfynfh13Nc,125
@@ -159,10 +159,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
159
159
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
160
  modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
161
161
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
162
- modal_version/_version_generated.py,sha256=66TXyta4tOwtrTM1q4q1RMzjierpXNDNticXEWERvRk,149
163
- modal-0.67.39.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
- modal-0.67.39.dist-info/METADATA,sha256=HV_U4DQAm8v0pMbjpvEXN7G5eaoCOk-Z_Jkf3f-QRuw,2329
165
- modal-0.67.39.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
- modal-0.67.39.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
- modal-0.67.39.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
- modal-0.67.39.dist-info/RECORD,,
162
+ modal_version/_version_generated.py,sha256=zLxUz4y1G_2ypx20CwyXB6ow78uz1EyykhkfvWlzC9Y,149
163
+ modal-0.67.41.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
+ modal-0.67.41.dist-info/METADATA,sha256=Nza7dGL56OkjAEN3hE333GijLaEH4DSHo7t_3KmUSy8,2329
165
+ modal-0.67.41.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
+ modal-0.67.41.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
+ modal-0.67.41.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
+ modal-0.67.41.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -1211,6 +1211,17 @@ message Function {
1211
1211
  bool _experimental_custom_scaling = 76;
1212
1212
  }
1213
1213
 
1214
+ message FunctionAsyncInvokeRequest {
1215
+ string function_id = 1;
1216
+ string parent_input_id = 2;
1217
+ FunctionInput input = 3;
1218
+ }
1219
+
1220
+ message FunctionAsyncInvokeResponse {
1221
+ bool retry_with_blob_upload = 1;
1222
+ string function_call_id = 2;
1223
+ }
1224
+
1214
1225
  message FunctionBindParamsRequest {
1215
1226
  string function_id = 1;
1216
1227
  bytes serialized_params = 2;
@@ -2705,6 +2716,7 @@ service ModalClient {
2705
2716
  rpc EnvironmentUpdate(EnvironmentUpdateRequest) returns (EnvironmentListItem);
2706
2717
 
2707
2718
  // Functions
2719
+ rpc FunctionAsyncInvoke(FunctionAsyncInvokeRequest) returns (FunctionAsyncInvokeResponse);
2708
2720
  rpc FunctionBindParams(FunctionBindParamsRequest) returns (FunctionBindParamsResponse);
2709
2721
  rpc FunctionCallCancel(FunctionCallCancelRequest) returns (google.protobuf.Empty);
2710
2722
  rpc FunctionCallGetDataIn(FunctionCallGetDataRequest) returns (stream DataChunk);
modal_proto/api_grpc.py CHANGED
@@ -217,6 +217,10 @@ class ModalClientBase(abc.ABC):
217
217
  async def EnvironmentUpdate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.EnvironmentUpdateRequest, modal_proto.api_pb2.EnvironmentListItem]') -> None:
218
218
  pass
219
219
 
220
+ @abc.abstractmethod
221
+ async def FunctionAsyncInvoke(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionAsyncInvokeRequest, modal_proto.api_pb2.FunctionAsyncInvokeResponse]') -> None:
222
+ pass
223
+
220
224
  @abc.abstractmethod
221
225
  async def FunctionBindParams(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionBindParamsRequest, modal_proto.api_pb2.FunctionBindParamsResponse]') -> None:
222
226
  pass
@@ -843,6 +847,12 @@ class ModalClientBase(abc.ABC):
843
847
  modal_proto.api_pb2.EnvironmentUpdateRequest,
844
848
  modal_proto.api_pb2.EnvironmentListItem,
845
849
  ),
850
+ '/modal.client.ModalClient/FunctionAsyncInvoke': grpclib.const.Handler(
851
+ self.FunctionAsyncInvoke,
852
+ grpclib.const.Cardinality.UNARY_UNARY,
853
+ modal_proto.api_pb2.FunctionAsyncInvokeRequest,
854
+ modal_proto.api_pb2.FunctionAsyncInvokeResponse,
855
+ ),
846
856
  '/modal.client.ModalClient/FunctionBindParams': grpclib.const.Handler(
847
857
  self.FunctionBindParams,
848
858
  grpclib.const.Cardinality.UNARY_UNARY,
@@ -1635,6 +1645,12 @@ class ModalClientStub:
1635
1645
  modal_proto.api_pb2.EnvironmentUpdateRequest,
1636
1646
  modal_proto.api_pb2.EnvironmentListItem,
1637
1647
  )
1648
+ self.FunctionAsyncInvoke = grpclib.client.UnaryUnaryMethod(
1649
+ channel,
1650
+ '/modal.client.ModalClient/FunctionAsyncInvoke',
1651
+ modal_proto.api_pb2.FunctionAsyncInvokeRequest,
1652
+ modal_proto.api_pb2.FunctionAsyncInvokeResponse,
1653
+ )
1638
1654
  self.FunctionBindParams = grpclib.client.UnaryUnaryMethod(
1639
1655
  channel,
1640
1656
  '/modal.client.ModalClient/FunctionBindParams',