@discomedia/utils 1.0.71 → 1.0.74

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.
@@ -7,6 +7,7 @@ const OPENAI_MODELS = [
7
7
  'gpt-5',
8
8
  'gpt-5-mini',
9
9
  'gpt-5.4-mini',
10
+ 'gpt-5.4-nano',
10
11
  'gpt-5-nano',
11
12
  'gpt-5.1',
12
13
  'gpt-5.4',
@@ -49,6 +50,7 @@ const OPENROUTER_MODELS = [
49
50
  'openai/gpt-5',
50
51
  'openai/gpt-5-mini',
51
52
  'openai/gpt-5.4-mini',
53
+ 'openai/gpt-5.4-nano',
52
54
  'openai/gpt-5-nano',
53
55
  'openai/gpt-5.1',
54
56
  'openai/gpt-5.4',
@@ -346,7 +348,7 @@ const safeJSON = (text) => {
346
348
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
347
349
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
348
350
 
349
- const VERSION = '6.37.0'; // x-release-please-version
351
+ const VERSION = '6.39.0'; // x-release-please-version
350
352
 
351
353
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
352
354
  const isRunningInBrowser = () => {
@@ -1795,19 +1797,22 @@ class WorkloadIdentityAuth {
1795
1797
  }
1796
1798
  async refreshToken() {
1797
1799
  const subjectToken = await this.config.provider.getToken();
1800
+ const body = {
1801
+ grant_type: TOKEN_EXCHANGE_GRANT_TYPE,
1802
+ subject_token: subjectToken,
1803
+ subject_token_type: SUBJECT_TOKEN_TYPES[this.config.provider.tokenType],
1804
+ identity_provider_id: this.config.identityProviderId,
1805
+ service_account_id: this.config.serviceAccountId,
1806
+ };
1807
+ if (this.config.clientId) {
1808
+ body['client_id'] = this.config.clientId;
1809
+ }
1798
1810
  const response = await this.fetch(this.tokenExchangeUrl, {
1799
1811
  method: 'POST',
1800
1812
  headers: {
1801
1813
  'Content-Type': 'application/json',
1802
1814
  },
1803
- body: JSON.stringify({
1804
- grant_type: TOKEN_EXCHANGE_GRANT_TYPE,
1805
- client_id: this.config.clientId,
1806
- subject_token: subjectToken,
1807
- subject_token_type: SUBJECT_TOKEN_TYPES[this.config.provider.tokenType],
1808
- identity_provider_id: this.config.identityProviderId,
1809
- service_account_id: this.config.serviceAccountId,
1810
- }),
1815
+ body: JSON.stringify(body),
1811
1816
  });
1812
1817
  if (!response.ok) {
1813
1818
  const errorText = await response.text();
@@ -3879,6 +3884,43 @@ let Certificates$1 = class Certificates extends APIResource {
3879
3884
  }
3880
3885
  };
3881
3886
 
3887
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3888
+ let DataRetention$1 = class DataRetention extends APIResource {
3889
+ /**
3890
+ * Retrieves organization data retention controls.
3891
+ *
3892
+ * @example
3893
+ * ```ts
3894
+ * const organizationDataRetention =
3895
+ * await client.admin.organization.dataRetention.retrieve();
3896
+ * ```
3897
+ */
3898
+ retrieve(options) {
3899
+ return this._client.get('/organization/data_retention', {
3900
+ ...options,
3901
+ __security: { adminAPIKeyAuth: true },
3902
+ });
3903
+ }
3904
+ /**
3905
+ * Updates organization data retention controls.
3906
+ *
3907
+ * @example
3908
+ * ```ts
3909
+ * const organizationDataRetention =
3910
+ * await client.admin.organization.dataRetention.update({
3911
+ * retention_type: 'zero_data_retention',
3912
+ * });
3913
+ * ```
3914
+ */
3915
+ update(body, options) {
3916
+ return this._client.post('/organization/data_retention', {
3917
+ body,
3918
+ ...options,
3919
+ __security: { adminAPIKeyAuth: true },
3920
+ });
3921
+ }
3922
+ };
3923
+
3882
3924
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3883
3925
  class Invites extends APIResource {
3884
3926
  /**
@@ -3975,6 +4017,22 @@ let Roles$5 = class Roles extends APIResource {
3975
4017
  __security: { adminAPIKeyAuth: true },
3976
4018
  });
3977
4019
  }
4020
+ /**
4021
+ * Retrieves an organization role.
4022
+ *
4023
+ * @example
4024
+ * ```ts
4025
+ * const role = await client.admin.organization.roles.retrieve(
4026
+ * 'role_id',
4027
+ * );
4028
+ * ```
4029
+ */
4030
+ retrieve(roleID, options) {
4031
+ return this._client.get(path `/organization/roles/${roleID}`, {
4032
+ ...options,
4033
+ __security: { adminAPIKeyAuth: true },
4034
+ });
4035
+ }
3978
4036
  /**
3979
4037
  * Updates an existing organization role.
3980
4038
  *
@@ -4028,6 +4086,92 @@ let Roles$5 = class Roles extends APIResource {
4028
4086
  }
4029
4087
  };
4030
4088
 
4089
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4090
+ let SpendAlerts$1 = class SpendAlerts extends APIResource {
4091
+ /**
4092
+ * Creates an organization spend alert.
4093
+ *
4094
+ * @example
4095
+ * ```ts
4096
+ * const organizationSpendAlert =
4097
+ * await client.admin.organization.spendAlerts.create({
4098
+ * currency: 'USD',
4099
+ * interval: 'month',
4100
+ * notification_channel: {
4101
+ * recipients: ['string'],
4102
+ * type: 'email',
4103
+ * },
4104
+ * threshold_amount: 0,
4105
+ * });
4106
+ * ```
4107
+ */
4108
+ create(body, options) {
4109
+ return this._client.post('/organization/spend_alerts', {
4110
+ body,
4111
+ ...options,
4112
+ __security: { adminAPIKeyAuth: true },
4113
+ });
4114
+ }
4115
+ /**
4116
+ * Updates an organization spend alert.
4117
+ *
4118
+ * @example
4119
+ * ```ts
4120
+ * const organizationSpendAlert =
4121
+ * await client.admin.organization.spendAlerts.update(
4122
+ * 'alert_id',
4123
+ * {
4124
+ * currency: 'USD',
4125
+ * interval: 'month',
4126
+ * notification_channel: {
4127
+ * recipients: ['string'],
4128
+ * type: 'email',
4129
+ * },
4130
+ * threshold_amount: 0,
4131
+ * },
4132
+ * );
4133
+ * ```
4134
+ */
4135
+ update(alertID, body, options) {
4136
+ return this._client.post(path `/organization/spend_alerts/${alertID}`, {
4137
+ body,
4138
+ ...options,
4139
+ __security: { adminAPIKeyAuth: true },
4140
+ });
4141
+ }
4142
+ /**
4143
+ * Lists organization spend alerts.
4144
+ *
4145
+ * @example
4146
+ * ```ts
4147
+ * // Automatically fetches more pages as needed.
4148
+ * for await (const organizationSpendAlert of client.admin.organization.spendAlerts.list()) {
4149
+ * // ...
4150
+ * }
4151
+ * ```
4152
+ */
4153
+ list(query = {}, options) {
4154
+ return this._client.getAPIList('/organization/spend_alerts', (ConversationCursorPage), { query, ...options, __security: { adminAPIKeyAuth: true } });
4155
+ }
4156
+ /**
4157
+ * Deletes an organization spend alert.
4158
+ *
4159
+ * @example
4160
+ * ```ts
4161
+ * const organizationSpendAlertDeleted =
4162
+ * await client.admin.organization.spendAlerts.delete(
4163
+ * 'alert_id',
4164
+ * );
4165
+ * ```
4166
+ */
4167
+ delete(alertID, options) {
4168
+ return this._client.delete(path `/organization/spend_alerts/${alertID}`, {
4169
+ ...options,
4170
+ __security: { adminAPIKeyAuth: true },
4171
+ });
4172
+ }
4173
+ };
4174
+
4031
4175
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4032
4176
  class Usage extends APIResource {
4033
4177
  /**
@@ -4138,6 +4282,24 @@ class Usage extends APIResource {
4138
4282
  __security: { adminAPIKeyAuth: true },
4139
4283
  });
4140
4284
  }
4285
+ /**
4286
+ * Get file search calls usage details for the organization.
4287
+ *
4288
+ * @example
4289
+ * ```ts
4290
+ * const response =
4291
+ * await client.admin.organization.usage.fileSearchCalls({
4292
+ * start_time: 0,
4293
+ * });
4294
+ * ```
4295
+ */
4296
+ fileSearchCalls(query, options) {
4297
+ return this._client.get('/organization/usage/file_search_calls', {
4298
+ query,
4299
+ ...options,
4300
+ __security: { adminAPIKeyAuth: true },
4301
+ });
4302
+ }
4141
4303
  /**
4142
4304
  * Get images usage details for the organization.
4143
4305
  *
@@ -4192,6 +4354,24 @@ class Usage extends APIResource {
4192
4354
  __security: { adminAPIKeyAuth: true },
4193
4355
  });
4194
4356
  }
4357
+ /**
4358
+ * Get web search calls usage details for the organization.
4359
+ *
4360
+ * @example
4361
+ * ```ts
4362
+ * const response =
4363
+ * await client.admin.organization.usage.webSearchCalls({
4364
+ * start_time: 0,
4365
+ * });
4366
+ * ```
4367
+ */
4368
+ webSearchCalls(query, options) {
4369
+ return this._client.get('/organization/usage/web_search_calls', {
4370
+ query,
4371
+ ...options,
4372
+ __security: { adminAPIKeyAuth: true },
4373
+ });
4374
+ }
4195
4375
  }
4196
4376
 
4197
4377
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
@@ -4215,6 +4395,25 @@ let Roles$4 = class Roles extends APIResource {
4215
4395
  __security: { adminAPIKeyAuth: true },
4216
4396
  });
4217
4397
  }
4398
+ /**
4399
+ * Retrieves an organization role assigned to a group.
4400
+ *
4401
+ * @example
4402
+ * ```ts
4403
+ * const role =
4404
+ * await client.admin.organization.groups.roles.retrieve(
4405
+ * 'role_id',
4406
+ * { group_id: 'group_id' },
4407
+ * );
4408
+ * ```
4409
+ */
4410
+ retrieve(roleID, params, options) {
4411
+ const { group_id } = params;
4412
+ return this._client.get(path `/organization/groups/${group_id}/roles/${roleID}`, {
4413
+ ...options,
4414
+ __security: { adminAPIKeyAuth: true },
4415
+ });
4416
+ }
4218
4417
  /**
4219
4418
  * Lists the organization roles assigned to a group within the organization.
4220
4419
  *
@@ -4273,6 +4472,25 @@ let Users$2 = class Users extends APIResource {
4273
4472
  __security: { adminAPIKeyAuth: true },
4274
4473
  });
4275
4474
  }
4475
+ /**
4476
+ * Retrieves a user in a group.
4477
+ *
4478
+ * @example
4479
+ * ```ts
4480
+ * const user =
4481
+ * await client.admin.organization.groups.users.retrieve(
4482
+ * 'user_id',
4483
+ * { group_id: 'group_id' },
4484
+ * );
4485
+ * ```
4486
+ */
4487
+ retrieve(userID, params, options) {
4488
+ const { group_id } = params;
4489
+ return this._client.get(path `/organization/groups/${group_id}/users/${userID}`, {
4490
+ ...options,
4491
+ __security: { adminAPIKeyAuth: true },
4492
+ });
4493
+ }
4276
4494
  /**
4277
4495
  * Lists the users assigned to a group.
4278
4496
  *
@@ -4334,6 +4552,23 @@ let Groups$1 = class Groups extends APIResource {
4334
4552
  __security: { adminAPIKeyAuth: true },
4335
4553
  });
4336
4554
  }
4555
+ /**
4556
+ * Retrieves a group.
4557
+ *
4558
+ * @example
4559
+ * ```ts
4560
+ * const group =
4561
+ * await client.admin.organization.groups.retrieve(
4562
+ * 'group_id',
4563
+ * );
4564
+ * ```
4565
+ */
4566
+ retrieve(groupID, options) {
4567
+ return this._client.get(path `/organization/groups/${groupID}`, {
4568
+ ...options,
4569
+ __security: { adminAPIKeyAuth: true },
4570
+ });
4571
+ }
4337
4572
  /**
4338
4573
  * Updates a group's information.
4339
4574
  *
@@ -4508,6 +4743,142 @@ class Certificates extends APIResource {
4508
4743
  }
4509
4744
  }
4510
4745
 
4746
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4747
+ class DataRetention extends APIResource {
4748
+ /**
4749
+ * Retrieves project data retention controls.
4750
+ *
4751
+ * @example
4752
+ * ```ts
4753
+ * const projectDataRetention =
4754
+ * await client.admin.organization.projects.dataRetention.retrieve(
4755
+ * 'project_id',
4756
+ * );
4757
+ * ```
4758
+ */
4759
+ retrieve(projectID, options) {
4760
+ return this._client.get(path `/organization/projects/${projectID}/data_retention`, {
4761
+ ...options,
4762
+ __security: { adminAPIKeyAuth: true },
4763
+ });
4764
+ }
4765
+ /**
4766
+ * Updates project data retention controls.
4767
+ *
4768
+ * @example
4769
+ * ```ts
4770
+ * const projectDataRetention =
4771
+ * await client.admin.organization.projects.dataRetention.update(
4772
+ * 'project_id',
4773
+ * { retention_type: 'organization_default' },
4774
+ * );
4775
+ * ```
4776
+ */
4777
+ update(projectID, body, options) {
4778
+ return this._client.post(path `/organization/projects/${projectID}/data_retention`, {
4779
+ body,
4780
+ ...options,
4781
+ __security: { adminAPIKeyAuth: true },
4782
+ });
4783
+ }
4784
+ }
4785
+
4786
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4787
+ class HostedToolPermissions extends APIResource {
4788
+ /**
4789
+ * Returns hosted tool permissions for a project.
4790
+ *
4791
+ * @example
4792
+ * ```ts
4793
+ * const projectHostedToolPermissions =
4794
+ * await client.admin.organization.projects.hostedToolPermissions.retrieve(
4795
+ * 'project_id',
4796
+ * );
4797
+ * ```
4798
+ */
4799
+ retrieve(projectID, options) {
4800
+ return this._client.get(path `/organization/projects/${projectID}/hosted_tool_permissions`, {
4801
+ ...options,
4802
+ __security: { adminAPIKeyAuth: true },
4803
+ });
4804
+ }
4805
+ /**
4806
+ * Updates hosted tool permissions for a project.
4807
+ *
4808
+ * @example
4809
+ * ```ts
4810
+ * const projectHostedToolPermissions =
4811
+ * await client.admin.organization.projects.hostedToolPermissions.update(
4812
+ * 'project_id',
4813
+ * );
4814
+ * ```
4815
+ */
4816
+ update(projectID, body, options) {
4817
+ return this._client.post(path `/organization/projects/${projectID}/hosted_tool_permissions`, {
4818
+ body,
4819
+ ...options,
4820
+ __security: { adminAPIKeyAuth: true },
4821
+ });
4822
+ }
4823
+ }
4824
+
4825
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4826
+ class ModelPermissions extends APIResource {
4827
+ /**
4828
+ * Returns model permissions for a project.
4829
+ *
4830
+ * @example
4831
+ * ```ts
4832
+ * const projectModelPermissions =
4833
+ * await client.admin.organization.projects.modelPermissions.retrieve(
4834
+ * 'project_id',
4835
+ * );
4836
+ * ```
4837
+ */
4838
+ retrieve(projectID, options) {
4839
+ return this._client.get(path `/organization/projects/${projectID}/model_permissions`, {
4840
+ ...options,
4841
+ __security: { adminAPIKeyAuth: true },
4842
+ });
4843
+ }
4844
+ /**
4845
+ * Updates model permissions for a project.
4846
+ *
4847
+ * @example
4848
+ * ```ts
4849
+ * const projectModelPermissions =
4850
+ * await client.admin.organization.projects.modelPermissions.update(
4851
+ * 'project_id',
4852
+ * { mode: 'allow_list', model_ids: ['string'] },
4853
+ * );
4854
+ * ```
4855
+ */
4856
+ update(projectID, body, options) {
4857
+ return this._client.post(path `/organization/projects/${projectID}/model_permissions`, {
4858
+ body,
4859
+ ...options,
4860
+ __security: { adminAPIKeyAuth: true },
4861
+ });
4862
+ }
4863
+ /**
4864
+ * Deletes model permissions for a project.
4865
+ *
4866
+ * @example
4867
+ * ```ts
4868
+ * const projectModelPermissionsDeleted =
4869
+ * await client.admin.organization.projects.modelPermissions.delete(
4870
+ * 'project_id',
4871
+ * );
4872
+ * ```
4873
+ */
4874
+ delete(projectID, options) {
4875
+ return this._client.delete(path `/organization/projects/${projectID}/model_permissions`, {
4876
+ ...options,
4877
+ __security: { adminAPIKeyAuth: true },
4878
+ });
4879
+ }
4880
+ }
4881
+
4511
4882
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4512
4883
  class RateLimits extends APIResource {
4513
4884
  /**
@@ -4569,6 +4940,25 @@ let Roles$3 = class Roles extends APIResource {
4569
4940
  __security: { adminAPIKeyAuth: true },
4570
4941
  });
4571
4942
  }
4943
+ /**
4944
+ * Retrieves a project role.
4945
+ *
4946
+ * @example
4947
+ * ```ts
4948
+ * const role =
4949
+ * await client.admin.organization.projects.roles.retrieve(
4950
+ * 'role_id',
4951
+ * { project_id: 'project_id' },
4952
+ * );
4953
+ * ```
4954
+ */
4955
+ retrieve(roleID, params, options) {
4956
+ const { project_id } = params;
4957
+ return this._client.get(path `/projects/${project_id}/roles/${roleID}`, {
4958
+ ...options,
4959
+ __security: { adminAPIKeyAuth: true },
4960
+ });
4961
+ }
4572
4962
  /**
4573
4963
  * Updates an existing project role.
4574
4964
  *
@@ -4671,6 +5061,22 @@ class ServiceAccounts extends APIResource {
4671
5061
  __security: { adminAPIKeyAuth: true },
4672
5062
  });
4673
5063
  }
5064
+ /**
5065
+ * Updates a service account in the project.
5066
+ *
5067
+ * @example
5068
+ * ```ts
5069
+ * const projectServiceAccount =
5070
+ * await client.admin.organization.projects.serviceAccounts.update(
5071
+ * 'service_account_id',
5072
+ * { project_id: 'project_id' },
5073
+ * );
5074
+ * ```
5075
+ */
5076
+ update(serviceAccountID, params, options) {
5077
+ const { project_id, ...body } = params;
5078
+ return this._client.post(path `/organization/projects/${project_id}/service_accounts/${serviceAccountID}`, { body, ...options, __security: { adminAPIKeyAuth: true } });
5079
+ }
4674
5080
  /**
4675
5081
  * Returns a list of service accounts in the project.
4676
5082
  *
@@ -4708,6 +5114,101 @@ class ServiceAccounts extends APIResource {
4708
5114
  }
4709
5115
  }
4710
5116
 
5117
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5118
+ class SpendAlerts extends APIResource {
5119
+ /**
5120
+ * Creates a project spend alert.
5121
+ *
5122
+ * @example
5123
+ * ```ts
5124
+ * const projectSpendAlert =
5125
+ * await client.admin.organization.projects.spendAlerts.create(
5126
+ * 'project_id',
5127
+ * {
5128
+ * currency: 'USD',
5129
+ * interval: 'month',
5130
+ * notification_channel: {
5131
+ * recipients: ['string'],
5132
+ * type: 'email',
5133
+ * },
5134
+ * threshold_amount: 0,
5135
+ * },
5136
+ * );
5137
+ * ```
5138
+ */
5139
+ create(projectID, body, options) {
5140
+ return this._client.post(path `/organization/projects/${projectID}/spend_alerts`, {
5141
+ body,
5142
+ ...options,
5143
+ __security: { adminAPIKeyAuth: true },
5144
+ });
5145
+ }
5146
+ /**
5147
+ * Updates a project spend alert.
5148
+ *
5149
+ * @example
5150
+ * ```ts
5151
+ * const projectSpendAlert =
5152
+ * await client.admin.organization.projects.spendAlerts.update(
5153
+ * 'alert_id',
5154
+ * {
5155
+ * project_id: 'project_id',
5156
+ * currency: 'USD',
5157
+ * interval: 'month',
5158
+ * notification_channel: {
5159
+ * recipients: ['string'],
5160
+ * type: 'email',
5161
+ * },
5162
+ * threshold_amount: 0,
5163
+ * },
5164
+ * );
5165
+ * ```
5166
+ */
5167
+ update(alertID, params, options) {
5168
+ const { project_id, ...body } = params;
5169
+ return this._client.post(path `/organization/projects/${project_id}/spend_alerts/${alertID}`, {
5170
+ body,
5171
+ ...options,
5172
+ __security: { adminAPIKeyAuth: true },
5173
+ });
5174
+ }
5175
+ /**
5176
+ * Lists project spend alerts.
5177
+ *
5178
+ * @example
5179
+ * ```ts
5180
+ * // Automatically fetches more pages as needed.
5181
+ * for await (const projectSpendAlert of client.admin.organization.projects.spendAlerts.list(
5182
+ * 'project_id',
5183
+ * )) {
5184
+ * // ...
5185
+ * }
5186
+ * ```
5187
+ */
5188
+ list(projectID, query = {}, options) {
5189
+ return this._client.getAPIList(path `/organization/projects/${projectID}/spend_alerts`, (ConversationCursorPage), { query, ...options, __security: { adminAPIKeyAuth: true } });
5190
+ }
5191
+ /**
5192
+ * Deletes a project spend alert.
5193
+ *
5194
+ * @example
5195
+ * ```ts
5196
+ * const projectSpendAlertDeleted =
5197
+ * await client.admin.organization.projects.spendAlerts.delete(
5198
+ * 'alert_id',
5199
+ * { project_id: 'project_id' },
5200
+ * );
5201
+ * ```
5202
+ */
5203
+ delete(alertID, params, options) {
5204
+ const { project_id } = params;
5205
+ return this._client.delete(path `/organization/projects/${project_id}/spend_alerts/${alertID}`, {
5206
+ ...options,
5207
+ __security: { adminAPIKeyAuth: true },
5208
+ });
5209
+ }
5210
+ }
5211
+
4711
5212
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4712
5213
  let Roles$2 = class Roles extends APIResource {
4713
5214
  /**
@@ -4730,6 +5231,25 @@ let Roles$2 = class Roles extends APIResource {
4730
5231
  __security: { adminAPIKeyAuth: true },
4731
5232
  });
4732
5233
  }
5234
+ /**
5235
+ * Retrieves a project role assigned to a group.
5236
+ *
5237
+ * @example
5238
+ * ```ts
5239
+ * const role =
5240
+ * await client.admin.organization.projects.groups.roles.retrieve(
5241
+ * 'role_id',
5242
+ * { project_id: 'project_id', group_id: 'group_id' },
5243
+ * );
5244
+ * ```
5245
+ */
5246
+ retrieve(roleID, params, options) {
5247
+ const { project_id, group_id } = params;
5248
+ return this._client.get(path `/projects/${project_id}/groups/${group_id}/roles/${roleID}`, {
5249
+ ...options,
5250
+ __security: { adminAPIKeyAuth: true },
5251
+ });
5252
+ }
4733
5253
  /**
4734
5254
  * Lists the project roles assigned to a group within a project.
4735
5255
  *
@@ -4794,6 +5314,26 @@ class Groups extends APIResource {
4794
5314
  __security: { adminAPIKeyAuth: true },
4795
5315
  });
4796
5316
  }
5317
+ /**
5318
+ * Retrieves a project's group.
5319
+ *
5320
+ * @example
5321
+ * ```ts
5322
+ * const projectGroup =
5323
+ * await client.admin.organization.projects.groups.retrieve(
5324
+ * 'group_id',
5325
+ * { project_id: 'project_id' },
5326
+ * );
5327
+ * ```
5328
+ */
5329
+ retrieve(groupID, params, options) {
5330
+ const { project_id, ...query } = params;
5331
+ return this._client.get(path `/organization/projects/${project_id}/groups/${groupID}`, {
5332
+ query,
5333
+ ...options,
5334
+ __security: { adminAPIKeyAuth: true },
5335
+ });
5336
+ }
4797
5337
  /**
4798
5338
  * Lists the groups that have access to a project.
4799
5339
  *
@@ -4854,6 +5394,25 @@ let Roles$1 = class Roles extends APIResource {
4854
5394
  __security: { adminAPIKeyAuth: true },
4855
5395
  });
4856
5396
  }
5397
+ /**
5398
+ * Retrieves a project role assigned to a user.
5399
+ *
5400
+ * @example
5401
+ * ```ts
5402
+ * const role =
5403
+ * await client.admin.organization.projects.users.roles.retrieve(
5404
+ * 'role_id',
5405
+ * { project_id: 'project_id', user_id: 'user_id' },
5406
+ * );
5407
+ * ```
5408
+ */
5409
+ retrieve(roleID, params, options) {
5410
+ const { project_id, user_id } = params;
5411
+ return this._client.get(path `/projects/${project_id}/users/${user_id}/roles/${roleID}`, {
5412
+ ...options,
5413
+ __security: { adminAPIKeyAuth: true },
5414
+ });
5415
+ }
4857
5416
  /**
4858
5417
  * Lists the project roles assigned to a user within a project.
4859
5418
  *
@@ -5007,8 +5566,12 @@ class Projects extends APIResource {
5007
5566
  this.serviceAccounts = new ServiceAccounts(this._client);
5008
5567
  this.apiKeys = new APIKeys(this._client);
5009
5568
  this.rateLimits = new RateLimits(this._client);
5569
+ this.modelPermissions = new ModelPermissions(this._client);
5570
+ this.hostedToolPermissions = new HostedToolPermissions(this._client);
5010
5571
  this.groups = new Groups(this._client);
5011
5572
  this.roles = new Roles$3(this._client);
5573
+ this.dataRetention = new DataRetention(this._client);
5574
+ this.spendAlerts = new SpendAlerts(this._client);
5012
5575
  this.certificates = new Certificates(this._client);
5013
5576
  }
5014
5577
  /**
@@ -5106,8 +5669,12 @@ Projects.Users = Users$1;
5106
5669
  Projects.ServiceAccounts = ServiceAccounts;
5107
5670
  Projects.APIKeys = APIKeys;
5108
5671
  Projects.RateLimits = RateLimits;
5672
+ Projects.ModelPermissions = ModelPermissions;
5673
+ Projects.HostedToolPermissions = HostedToolPermissions;
5109
5674
  Projects.Groups = Groups;
5110
5675
  Projects.Roles = Roles$3;
5676
+ Projects.DataRetention = DataRetention;
5677
+ Projects.SpendAlerts = SpendAlerts;
5111
5678
  Projects.Certificates = Certificates;
5112
5679
 
5113
5680
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
@@ -5131,6 +5698,25 @@ class Roles extends APIResource {
5131
5698
  __security: { adminAPIKeyAuth: true },
5132
5699
  });
5133
5700
  }
5701
+ /**
5702
+ * Retrieves an organization role assigned to a user.
5703
+ *
5704
+ * @example
5705
+ * ```ts
5706
+ * const role =
5707
+ * await client.admin.organization.users.roles.retrieve(
5708
+ * 'role_id',
5709
+ * { user_id: 'user_id' },
5710
+ * );
5711
+ * ```
5712
+ */
5713
+ retrieve(roleID, params, options) {
5714
+ const { user_id } = params;
5715
+ return this._client.get(path `/organization/users/${user_id}/roles/${roleID}`, {
5716
+ ...options,
5717
+ __security: { adminAPIKeyAuth: true },
5718
+ });
5719
+ }
5134
5720
  /**
5135
5721
  * Lists the organization roles assigned to a user within the organization.
5136
5722
  *
@@ -5253,6 +5839,8 @@ class Organization extends APIResource {
5253
5839
  this.users = new Users(this._client);
5254
5840
  this.groups = new Groups$1(this._client);
5255
5841
  this.roles = new Roles$5(this._client);
5842
+ this.dataRetention = new DataRetention$1(this._client);
5843
+ this.spendAlerts = new SpendAlerts$1(this._client);
5256
5844
  this.certificates = new Certificates$1(this._client);
5257
5845
  this.projects = new Projects(this._client);
5258
5846
  }
@@ -5264,6 +5852,8 @@ Organization.Invites = Invites;
5264
5852
  Organization.Users = Users;
5265
5853
  Organization.Groups = Groups$1;
5266
5854
  Organization.Roles = Roles$5;
5855
+ Organization.DataRetention = DataRetention$1;
5856
+ Organization.SpendAlerts = SpendAlerts$1;
5267
5857
  Organization.Certificates = Certificates$1;
5268
5858
  Organization.Projects = Projects;
5269
5859
 
@@ -12254,11 +12844,11 @@ function zodTextFormat(zodObject, name, props) {
12254
12844
  }, (content) => zodObject.parse(JSON.parse(content)));
12255
12845
  }
12256
12846
 
12257
- const DEFAULT_MODEL = 'gpt-5-mini';
12847
+ const DEFAULT_MODEL = 'gpt-5.4-mini';
12258
12848
  const GPT_5_HIGH_CONTEXT_THRESHOLD_TOKENS = 272_000;
12259
12849
  const GPT_5_HIGH_CONTEXT_INPUT_MULTIPLIER = 2;
12260
12850
  const GPT_5_HIGH_CONTEXT_OUTPUT_MULTIPLIER = 1.5;
12261
- /** Token costs in USD per 1M tokens. Last updated May 2026. */
12851
+ /** Token costs in USD per 1M tokens. Last updated May 2026 from the OpenAI API pricing page. */
12262
12852
  const openAiModelCosts = {
12263
12853
  'gpt-5': {
12264
12854
  inputCost: 1.25 / 1_000_000,
@@ -12271,9 +12861,14 @@ const openAiModelCosts = {
12271
12861
  outputCost: 2 / 1_000_000,
12272
12862
  },
12273
12863
  'gpt-5.4-mini': {
12274
- inputCost: 0.25 / 1_000_000,
12275
- cacheHitCost: 0.025 / 1_000_000,
12276
- outputCost: 2 / 1_000_000,
12864
+ inputCost: 0.75 / 1_000_000,
12865
+ cacheHitCost: 0.075 / 1_000_000,
12866
+ outputCost: 4.5 / 1_000_000,
12867
+ },
12868
+ 'gpt-5.4-nano': {
12869
+ inputCost: 0.2 / 1_000_000,
12870
+ cacheHitCost: 0.02 / 1_000_000,
12871
+ outputCost: 1.25 / 1_000_000,
12277
12872
  },
12278
12873
  'gpt-5-nano': {
12279
12874
  inputCost: 0.05 / 1_000_000,
@@ -12892,6 +13487,7 @@ async function parseResponse(content, responseFormat) {
12892
13487
  }
12893
13488
 
12894
13489
  // llm-openai.ts
13490
+ const DEFAULT_IMAGE_MIME_TYPE = 'image/webp';
12895
13491
  /**
12896
13492
  * Checks if the given direct OpenAI model supports the temperature parameter.
12897
13493
  * @param model The model to check.
@@ -12926,6 +13522,135 @@ function buildJsonSchemaFormat(schema, schemaName, schemaDescription, schemaStri
12926
13522
  ...(schemaStrict !== undefined ? { strict: schemaStrict } : {}),
12927
13523
  };
12928
13524
  }
13525
+ function resolveOpenAIApiKey(apiKey) {
13526
+ const resolvedApiKey = apiKey || process.env.OPENAI_API_KEY;
13527
+ if (!resolvedApiKey) {
13528
+ throw new Error('OpenAI API key is not provided and OPENAI_API_KEY environment variable is not set');
13529
+ }
13530
+ return resolvedApiKey;
13531
+ }
13532
+ function createOpenAIClient(apiKey) {
13533
+ return new OpenAI({
13534
+ apiKey,
13535
+ });
13536
+ }
13537
+ function normalizeImageDataUrl(imageData, mimeType = DEFAULT_IMAGE_MIME_TYPE) {
13538
+ return imageData.startsWith('data:') ? imageData : `data:${mimeType};base64,${imageData}`;
13539
+ }
13540
+ function getFilenameFromPath(filePath) {
13541
+ const normalizedPath = filePath.replace(/\\/g, '/');
13542
+ const pathSegments = normalizedPath.split('/');
13543
+ const filename = pathSegments[pathSegments.length - 1];
13544
+ if (!filename) {
13545
+ throw new Error(`Could not determine a filename from file path: ${filePath}`);
13546
+ }
13547
+ return filename;
13548
+ }
13549
+ function inferImageMimeType(filePath) {
13550
+ const normalizedPath = filePath.toLowerCase();
13551
+ if (normalizedPath.endsWith('.png')) {
13552
+ return 'image/png';
13553
+ }
13554
+ if (normalizedPath.endsWith('.jpg') || normalizedPath.endsWith('.jpeg')) {
13555
+ return 'image/jpeg';
13556
+ }
13557
+ if (normalizedPath.endsWith('.webp')) {
13558
+ return 'image/webp';
13559
+ }
13560
+ if (normalizedPath.endsWith('.gif')) {
13561
+ return 'image/gif';
13562
+ }
13563
+ return undefined;
13564
+ }
13565
+ async function readLocalFileBytes(filePath) {
13566
+ try {
13567
+ const dynamicImport = new Function('specifier', 'return import(specifier);');
13568
+ const { readFile } = await dynamicImport('node:fs/promises');
13569
+ return await readFile(filePath);
13570
+ }
13571
+ catch {
13572
+ throw new Error('Local image file uploads require a Node.js runtime with access to node:fs/promises');
13573
+ }
13574
+ }
13575
+ async function uploadVisionFileFromPath(openai, filePath, filename, mimeType) {
13576
+ const fileBytes = await readLocalFileBytes(filePath);
13577
+ const resolvedFilename = filename || getFilenameFromPath(filePath);
13578
+ const resolvedMimeType = mimeType || inferImageMimeType(filePath);
13579
+ const uploadableFile = await OpenAI.toFile(fileBytes, resolvedFilename, resolvedMimeType ? { type: resolvedMimeType } : undefined);
13580
+ const uploadedFile = await openai.files.create({
13581
+ file: uploadableFile,
13582
+ purpose: 'vision',
13583
+ });
13584
+ return uploadedFile.id;
13585
+ }
13586
+ function collectImageInputs(image, images, imageBase64) {
13587
+ const collectedImages = [];
13588
+ if (image) {
13589
+ collectedImages.push(image);
13590
+ }
13591
+ if (images && images.length > 0) {
13592
+ collectedImages.push(...images);
13593
+ }
13594
+ if (imageBase64) {
13595
+ collectedImages.push({ base64: imageBase64 });
13596
+ }
13597
+ return collectedImages;
13598
+ }
13599
+ function hasLocalFileImage(images) {
13600
+ return images.some((image) => 'filePath' in image);
13601
+ }
13602
+ async function buildImageContentPart(image, defaultDetail, openai) {
13603
+ const detail = image.detail ?? defaultDetail;
13604
+ if ('url' in image) {
13605
+ return {
13606
+ type: 'input_image',
13607
+ detail,
13608
+ image_url: image.url,
13609
+ };
13610
+ }
13611
+ if ('dataUrl' in image) {
13612
+ return {
13613
+ type: 'input_image',
13614
+ detail,
13615
+ image_url: image.dataUrl,
13616
+ };
13617
+ }
13618
+ if ('base64' in image) {
13619
+ return {
13620
+ type: 'input_image',
13621
+ detail,
13622
+ image_url: normalizeImageDataUrl(image.base64, image.mimeType),
13623
+ };
13624
+ }
13625
+ if ('fileId' in image) {
13626
+ return {
13627
+ type: 'input_image',
13628
+ detail,
13629
+ file_id: image.fileId,
13630
+ };
13631
+ }
13632
+ if (!openai) {
13633
+ throw new Error('A local image file path was provided, but no OpenAI client is available to upload it');
13634
+ }
13635
+ const fileId = await uploadVisionFileFromPath(openai, image.filePath, image.filename, image.mimeType);
13636
+ return {
13637
+ type: 'input_image',
13638
+ detail,
13639
+ file_id: fileId,
13640
+ };
13641
+ }
13642
+ async function buildPromptContent(input, imageInputs, imageDetail, openai) {
13643
+ if (imageInputs.length === 0) {
13644
+ return input;
13645
+ }
13646
+ const imageContent = await Promise.all(imageInputs.map((image) => buildImageContentPart(image, imageDetail, openai)));
13647
+ return [{ type: 'input_text', text: input }, ...imageContent];
13648
+ }
13649
+ async function uploadVisionFile(filePath, options = {}) {
13650
+ const resolvedApiKey = resolveOpenAIApiKey(options.apiKey);
13651
+ const openai = createOpenAIClient(resolvedApiKey);
13652
+ return await uploadVisionFileFromPath(openai, filePath, options.filename, options.mimeType);
13653
+ }
12929
13654
  /**
12930
13655
  * Makes a call to OpenAI's Responses API for more advanced use cases with built-in tools.
12931
13656
  *
@@ -12957,13 +13682,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
12957
13682
  if (!isOpenAIModel(normalizedModel)) {
12958
13683
  throw new Error(`Unsupported OpenAI model: ${normalizedModel}. Please use a supported GPT-5 model.`);
12959
13684
  }
12960
- const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
12961
- if (!apiKey) {
12962
- throw new Error('OpenAI API key is not provided and OPENAI_API_KEY environment variable is not set');
12963
- }
12964
- const openai = new OpenAI({
12965
- apiKey: apiKey,
12966
- });
13685
+ const apiKey = resolveOpenAIApiKey(options.apiKey);
13686
+ const openai = createOpenAIClient(apiKey);
12967
13687
  // Remove apiKey from options before creating request body
12968
13688
  const { apiKey: _, model: __, ...cleanOptions } = options;
12969
13689
  const requestBody = {
@@ -13074,12 +13794,16 @@ const makeResponsesAPICall = async (input, options = {}) => {
13074
13794
  * });
13075
13795
  */
13076
13796
  async function makeLLMCall(input, options = {}) {
13077
- const { apiKey, model = DEFAULT_MODEL, responseFormat = 'text', schema, schemaName = 'response', schemaDescription, schemaStrict, tools, useCodeInterpreter = false, useWebSearch = false, imageBase64, imageDetail = 'high', context, } = options;
13797
+ const { apiKey, model = DEFAULT_MODEL, responseFormat = 'text', schema, schemaName = 'response', schemaDescription, schemaStrict, tools, useCodeInterpreter = false, useWebSearch = false, image, images, imageBase64, imageDetail = 'high', context, } = options;
13078
13798
  // Validate model
13079
13799
  const normalizedModel = normalizeModelName(model);
13080
13800
  if (!isOpenAIModel(normalizedModel)) {
13081
13801
  throw new Error(`Unsupported OpenAI model: ${normalizedModel}. Please use a supported GPT-5 model.`);
13082
13802
  }
13803
+ const resolvedApiKey = resolveOpenAIApiKey(apiKey);
13804
+ const imageInputs = collectImageInputs(image, images, imageBase64);
13805
+ const openai = hasLocalFileImage(imageInputs) ? createOpenAIClient(resolvedApiKey) : undefined;
13806
+ const promptContent = await buildPromptContent(input, imageInputs, imageDetail, openai);
13083
13807
  // Process input for conversation context and image analysis
13084
13808
  let processedInput;
13085
13809
  if (context && context.length > 0) {
@@ -13094,18 +13818,11 @@ async function makeLLMCall(input, options = {}) {
13094
13818
  });
13095
13819
  }
13096
13820
  // Add current input message
13097
- if (imageBase64) {
13098
- // Current message includes both text and image
13821
+ if (imageInputs.length > 0) {
13822
+ // Current message includes text and one or more images
13099
13823
  conversationMessages.push({
13100
13824
  role: 'user',
13101
- content: [
13102
- { type: 'input_text', text: input },
13103
- {
13104
- type: 'input_image',
13105
- detail: imageDetail,
13106
- image_url: imageBase64.startsWith('data:') ? imageBase64 : `data:image/webp;base64,${imageBase64}`,
13107
- },
13108
- ],
13825
+ content: promptContent,
13109
13826
  type: 'message',
13110
13827
  });
13111
13828
  }
@@ -13119,19 +13836,12 @@ async function makeLLMCall(input, options = {}) {
13119
13836
  }
13120
13837
  processedInput = conversationMessages;
13121
13838
  }
13122
- else if (imageBase64) {
13123
- // No context, but has image - use the original image logic
13839
+ else if (imageInputs.length > 0) {
13840
+ // No context, but has image(s)
13124
13841
  processedInput = [
13125
13842
  {
13126
13843
  role: 'user',
13127
- content: [
13128
- { type: 'input_text', text: input },
13129
- {
13130
- type: 'input_image',
13131
- detail: imageDetail,
13132
- image_url: imageBase64.startsWith('data:') ? imageBase64 : `data:image/webp;base64,${imageBase64}`,
13133
- },
13134
- ],
13844
+ content: promptContent,
13135
13845
  type: 'message',
13136
13846
  },
13137
13847
  ];
@@ -13142,7 +13852,7 @@ async function makeLLMCall(input, options = {}) {
13142
13852
  }
13143
13853
  // Build the options object for makeResponsesAPICall
13144
13854
  let responsesOptions = {
13145
- apiKey,
13855
+ apiKey: resolvedApiKey,
13146
13856
  model: normalizedModel,
13147
13857
  parallel_tool_calls: false,
13148
13858
  tools,
@@ -14628,6 +15338,7 @@ const disco = {
14628
15338
  types: Types,
14629
15339
  llm: {
14630
15340
  call: makeLLMCall,
15341
+ uploadVisionFile: uploadVisionFile,
14631
15342
  seek: makeDeepseekCall,
14632
15343
  images: makeImagesCall,
14633
15344
  },
@@ -14642,4 +15353,5 @@ exports.isOpenAIImageModel = isOpenAIImageModel;
14642
15353
  exports.isOpenAIModel = isOpenAIModel;
14643
15354
  exports.isOpenRouterModel = isOpenRouterModel;
14644
15355
  exports.supportsTemperature = supportsTemperature;
15356
+ exports.uploadVisionFile = uploadVisionFile;
14645
15357
  //# sourceMappingURL=index-frontend.cjs.map