|
1 | 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. |
2 | 2 |
|
| 3 | +import { sleep } from '../../internal/utils'; |
3 | 4 | import { APIResource } from '../../core/resource'; |
4 | 5 | import * as AgentsAPI from './agents'; |
5 | 6 | import * as Shared from '../shared'; |
6 | 7 | import * as APIKeysAPI from './api-keys'; |
| 8 | +import { GradientError } from '../../core/error'; |
7 | 9 | import { |
8 | 10 | APIKeyCreateParams, |
9 | 11 | APIKeyCreateResponse, |
@@ -106,7 +108,33 @@ import { |
106 | 108 | import { APIPromise } from '../../core/api-promise'; |
107 | 109 | import { RequestOptions } from '../../internal/request-options'; |
108 | 110 | import { path } from '../../internal/utils/path'; |
109 | | -import { waitForAgentReady } from './wait-for-agent'; |
| 111 | + |
| 112 | +type AgentStatus = NonNullable<APIAgent.Deployment['status']>; |
| 113 | + |
| 114 | +export interface WaitForAgentOptions extends RequestOptions { |
| 115 | + /** Check interval in ms (default: 3000) */ |
| 116 | + interval?: number; |
| 117 | +} |
| 118 | + |
| 119 | +export class AgentTimeoutError extends GradientError { |
| 120 | + constructor( |
| 121 | + public agentId: string, |
| 122 | + public timeoutMs: number, |
| 123 | + ) { |
| 124 | + super(`Agent ${agentId} did not become ready within ${timeoutMs}ms`); |
| 125 | + this.name = 'AgentTimeoutError'; |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +export class AgentDeploymentError extends GradientError { |
| 130 | + constructor( |
| 131 | + public agentId: string, |
| 132 | + public status: AgentStatus, |
| 133 | + ) { |
| 134 | + super(`Agent ${agentId} deployment failed with status: ${status}`); |
| 135 | + this.name = 'AgentDeploymentError'; |
| 136 | + } |
| 137 | +} |
110 | 138 |
|
111 | 139 | export class Agents extends APIResource { |
112 | 140 | apiKeys: APIKeysAPI.APIKeys = new APIKeysAPI.APIKeys(this._client); |
@@ -278,11 +306,33 @@ export class Agents extends APIResource { |
278 | 306 | * }); |
279 | 307 | * ``` |
280 | 308 | */ |
281 | | - waitForReady( |
282 | | - uuid: string, |
283 | | - options: import('./wait-for-agent').WaitForAgentOptions, |
284 | | - ): Promise<AgentReadinessResponse> { |
285 | | - return waitForAgentReady(this._client, uuid, options); |
| 309 | + async waitForReady(uuid: string, options: WaitForAgentOptions): Promise<AgentReadinessResponse> { |
| 310 | + const { interval = 3000, timeout = 180000, signal } = options; |
| 311 | + const start = Date.now(); |
| 312 | + |
| 313 | + while (true) { |
| 314 | + signal?.throwIfAborted(); |
| 315 | + |
| 316 | + const elapsed = Date.now() - start; |
| 317 | + |
| 318 | + // ⏰ Check timeout BEFORE making the API call |
| 319 | + if (elapsed > timeout) { |
| 320 | + throw new AgentTimeoutError(uuid, timeout); |
| 321 | + } |
| 322 | + |
| 323 | + const agent = await this.retrieve(uuid, options); |
| 324 | + const status = (agent.agent?.deployment?.status as AgentStatus) || 'STATUS_UNKNOWN'; |
| 325 | + |
| 326 | + if (status === 'STATUS_RUNNING') { |
| 327 | + return agent; |
| 328 | + } |
| 329 | + |
| 330 | + if (status === 'STATUS_FAILED' || status === 'STATUS_UNDEPLOYMENT_FAILED') { |
| 331 | + throw new AgentDeploymentError(uuid, status); |
| 332 | + } |
| 333 | + |
| 334 | + await sleep(interval); |
| 335 | + } |
286 | 336 | } |
287 | 337 | } |
288 | 338 |
|
|
0 commit comments