@boatdev/sdk 1.6.0 → 1.8.0
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.
- package/.openapi-generator/FILES +6 -0
- package/dist/apis/BoatApi.d.ts +47 -4
- package/dist/apis/BoatApi.js +100 -4
- package/dist/esm/apis/BoatApi.d.ts +47 -4
- package/dist/esm/apis/BoatApi.js +100 -4
- package/dist/esm/http2-fetch.d.ts +1 -0
- package/dist/esm/http2-fetch.js +203 -0
- package/dist/esm/models/Conversation.d.ts +1 -1
- package/dist/esm/models/CreateSandboxRequest.d.ts +3 -2
- package/dist/esm/models/CreateSandboxRequest.js +2 -1
- package/dist/esm/models/ForkRequest.d.ts +2 -1
- package/dist/esm/models/ForkRequest.js +2 -1
- package/dist/esm/models/PromptRequest.d.ts +2 -1
- package/dist/esm/models/PromptRequest.js +2 -1
- package/dist/esm/models/Recover200Response.d.ts +57 -0
- package/dist/esm/models/Recover200Response.js +53 -0
- package/dist/esm/models/ResumeRequest.d.ts +2 -1
- package/dist/esm/models/ResumeRequest.js +2 -1
- package/dist/esm/models/Sandbox.d.ts +21 -1
- package/dist/esm/models/Sandbox.js +9 -1
- package/dist/esm/models/SandboxUsageResponse.d.ts +2 -1
- package/dist/esm/models/SandboxUsageResponse.js +2 -1
- package/dist/esm/models/StopOperation.d.ts +72 -0
- package/dist/esm/models/StopOperation.js +72 -0
- package/dist/esm/models/StopOperationResponse.d.ts +58 -0
- package/dist/esm/models/StopOperationResponse.js +62 -0
- package/dist/esm/models/StopRequest.d.ts +1 -1
- package/dist/esm/models/UpdateSandboxRequest.d.ts +1 -1
- package/dist/esm/models/index.d.ts +3 -0
- package/dist/esm/models/index.js +3 -0
- package/dist/esm/runtime.js +2 -1
- package/dist/http2-fetch.d.ts +1 -0
- package/dist/http2-fetch.js +239 -0
- package/dist/models/Conversation.d.ts +1 -1
- package/dist/models/CreateSandboxRequest.d.ts +3 -2
- package/dist/models/CreateSandboxRequest.js +2 -1
- package/dist/models/ForkRequest.d.ts +2 -1
- package/dist/models/ForkRequest.js +2 -1
- package/dist/models/PromptRequest.d.ts +2 -1
- package/dist/models/PromptRequest.js +2 -1
- package/dist/models/Recover200Response.d.ts +57 -0
- package/dist/models/Recover200Response.js +61 -0
- package/dist/models/ResumeRequest.d.ts +2 -1
- package/dist/models/ResumeRequest.js +2 -1
- package/dist/models/Sandbox.d.ts +21 -1
- package/dist/models/Sandbox.js +9 -1
- package/dist/models/SandboxUsageResponse.d.ts +2 -1
- package/dist/models/SandboxUsageResponse.js +2 -1
- package/dist/models/StopOperation.d.ts +72 -0
- package/dist/models/StopOperation.js +80 -0
- package/dist/models/StopOperationResponse.d.ts +58 -0
- package/dist/models/StopOperationResponse.js +70 -0
- package/dist/models/StopRequest.d.ts +1 -1
- package/dist/models/UpdateSandboxRequest.d.ts +1 -1
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +3 -0
- package/dist/runtime.js +9 -8
- package/docs/BoatApi.md +160 -2
- package/docs/PromptRequest.md +1 -1
- package/docs/Recover200Response.md +38 -0
- package/docs/Sandbox.md +6 -0
- package/docs/StopOperation.md +42 -0
- package/docs/StopOperationResponse.md +38 -0
- package/package.json +1 -1
- package/src/apis/BoatApi.ts +147 -4
- package/src/http2-fetch.ts +179 -0
- package/src/models/Conversation.ts +1 -1
- package/src/models/CreateSandboxRequest.ts +4 -3
- package/src/models/ForkRequest.ts +3 -2
- package/src/models/PromptRequest.ts +3 -2
- package/src/models/Recover200Response.ts +99 -0
- package/src/models/ResumeRequest.ts +3 -2
- package/src/models/Sandbox.ts +34 -2
- package/src/models/SandboxUsageResponse.ts +3 -2
- package/src/models/StopOperation.ts +124 -0
- package/src/models/StopOperationResponse.ts +111 -0
- package/src/models/StopRequest.ts +1 -1
- package/src/models/UpdateSandboxRequest.ts +1 -1
- package/src/models/index.ts +3 -0
- package/src/runtime.ts +2 -1
package/docs/Sandbox.md
CHANGED
|
@@ -13,6 +13,8 @@ Name | Type
|
|
|
13
13
|
`health` | string
|
|
14
14
|
`healthReason` | string
|
|
15
15
|
`degradedSince` | Date
|
|
16
|
+
`hydrated` | boolean
|
|
17
|
+
`hydratedAt` | Date
|
|
16
18
|
`type` | string
|
|
17
19
|
`vcpu` | number
|
|
18
20
|
`memoryGB` | number
|
|
@@ -43,6 +45,7 @@ Name | Type
|
|
|
43
45
|
`setupError` | string
|
|
44
46
|
`environment` | string
|
|
45
47
|
`environmentVersion` | number
|
|
48
|
+
`stop` | [StopOperation](StopOperation.md)
|
|
46
49
|
|
|
47
50
|
## Example
|
|
48
51
|
|
|
@@ -58,6 +61,8 @@ const example = {
|
|
|
58
61
|
"health": null,
|
|
59
62
|
"healthReason": null,
|
|
60
63
|
"degradedSince": null,
|
|
64
|
+
"hydrated": null,
|
|
65
|
+
"hydratedAt": null,
|
|
61
66
|
"type": null,
|
|
62
67
|
"vcpu": null,
|
|
63
68
|
"memoryGB": null,
|
|
@@ -88,6 +93,7 @@ const example = {
|
|
|
88
93
|
"setupError": null,
|
|
89
94
|
"environment": null,
|
|
90
95
|
"environmentVersion": null,
|
|
96
|
+
"stop": null,
|
|
91
97
|
} satisfies Sandbox
|
|
92
98
|
|
|
93
99
|
console.log(example)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
# StopOperation
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
Name | Type
|
|
8
|
+
------------ | -------------
|
|
9
|
+
`id` | string
|
|
10
|
+
`status` | string
|
|
11
|
+
`requestedAt` | Date
|
|
12
|
+
`lastAttemptAt` | Date
|
|
13
|
+
`error` | string
|
|
14
|
+
`endedAt` | Date
|
|
15
|
+
|
|
16
|
+
## Example
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import type { StopOperation } from '@boatdev/sdk'
|
|
20
|
+
|
|
21
|
+
// TODO: Update the object below with actual values
|
|
22
|
+
const example = {
|
|
23
|
+
"id": null,
|
|
24
|
+
"status": null,
|
|
25
|
+
"requestedAt": null,
|
|
26
|
+
"lastAttemptAt": null,
|
|
27
|
+
"error": null,
|
|
28
|
+
"endedAt": null,
|
|
29
|
+
} satisfies StopOperation
|
|
30
|
+
|
|
31
|
+
console.log(example)
|
|
32
|
+
|
|
33
|
+
// Convert the instance to a JSON string
|
|
34
|
+
const exampleJSON: string = JSON.stringify(example)
|
|
35
|
+
console.log(exampleJSON)
|
|
36
|
+
|
|
37
|
+
// Parse the JSON string back to an object
|
|
38
|
+
const exampleParsed = JSON.parse(exampleJSON) as StopOperation
|
|
39
|
+
console.log(exampleParsed)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
# StopOperationResponse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
Name | Type
|
|
8
|
+
------------ | -------------
|
|
9
|
+
`ok` | boolean
|
|
10
|
+
`type` | string
|
|
11
|
+
`id` | string
|
|
12
|
+
`stop` | [StopOperation](StopOperation.md)
|
|
13
|
+
|
|
14
|
+
## Example
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import type { StopOperationResponse } from '@boatdev/sdk'
|
|
18
|
+
|
|
19
|
+
// TODO: Update the object below with actual values
|
|
20
|
+
const example = {
|
|
21
|
+
"ok": null,
|
|
22
|
+
"type": null,
|
|
23
|
+
"id": null,
|
|
24
|
+
"stop": null,
|
|
25
|
+
} satisfies StopOperationResponse
|
|
26
|
+
|
|
27
|
+
console.log(example)
|
|
28
|
+
|
|
29
|
+
// Convert the instance to a JSON string
|
|
30
|
+
const exampleJSON: string = JSON.stringify(example)
|
|
31
|
+
console.log(exampleJSON)
|
|
32
|
+
|
|
33
|
+
// Parse the JSON string back to an object
|
|
34
|
+
const exampleParsed = JSON.parse(exampleJSON) as StopOperationResponse
|
|
35
|
+
console.log(exampleParsed)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
|
package/package.json
CHANGED
package/src/apis/BoatApi.ts
CHANGED
|
@@ -228,6 +228,11 @@ import {
|
|
|
228
228
|
PromptRunResponseFromJSON,
|
|
229
229
|
PromptRunResponseToJSON,
|
|
230
230
|
} from '../models/PromptRunResponse';
|
|
231
|
+
import {
|
|
232
|
+
type Recover200Response,
|
|
233
|
+
Recover200ResponseFromJSON,
|
|
234
|
+
Recover200ResponseToJSON,
|
|
235
|
+
} from '../models/Recover200Response';
|
|
231
236
|
import {
|
|
232
237
|
type RepoSelectionRequest,
|
|
233
238
|
RepoSelectionRequestFromJSON,
|
|
@@ -348,6 +353,11 @@ import {
|
|
|
348
353
|
SteerResponseFromJSON,
|
|
349
354
|
SteerResponseToJSON,
|
|
350
355
|
} from '../models/SteerResponse';
|
|
356
|
+
import {
|
|
357
|
+
type StopOperationResponse,
|
|
358
|
+
StopOperationResponseFromJSON,
|
|
359
|
+
StopOperationResponseToJSON,
|
|
360
|
+
} from '../models/StopOperationResponse';
|
|
351
361
|
import {
|
|
352
362
|
type StopRequest,
|
|
353
363
|
StopRequestFromJSON,
|
|
@@ -545,6 +555,11 @@ export interface GetSnapshotTreeRequest {
|
|
|
545
555
|
snapshotId: string;
|
|
546
556
|
}
|
|
547
557
|
|
|
558
|
+
export interface GetStopRequest {
|
|
559
|
+
sandboxId: string;
|
|
560
|
+
stopId: string;
|
|
561
|
+
}
|
|
562
|
+
|
|
548
563
|
export interface GetWebhookRequest {
|
|
549
564
|
webhookId: string;
|
|
550
565
|
}
|
|
@@ -594,6 +609,10 @@ export interface ReadFileRequest {
|
|
|
594
609
|
encoding?: ReadFileEncodingEnum;
|
|
595
610
|
}
|
|
596
611
|
|
|
612
|
+
export interface RecoverRequest {
|
|
613
|
+
sandboxId: string;
|
|
614
|
+
}
|
|
615
|
+
|
|
597
616
|
export interface ReposRequest {
|
|
598
617
|
sync?: boolean;
|
|
599
618
|
limit?: number;
|
|
@@ -931,6 +950,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
931
950
|
}
|
|
932
951
|
|
|
933
952
|
/**
|
|
953
|
+
* Downloads one file of up to 50 MiB, under /home/user or /tmp, as raw bytes.
|
|
934
954
|
* Download a sandbox artifact
|
|
935
955
|
*/
|
|
936
956
|
async artifactRaw(requestParameters: ArtifactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Blob>> {
|
|
@@ -941,6 +961,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
941
961
|
}
|
|
942
962
|
|
|
943
963
|
/**
|
|
964
|
+
* Downloads one file of up to 50 MiB, under /home/user or /tmp, as raw bytes.
|
|
944
965
|
* Download a sandbox artifact
|
|
945
966
|
*/
|
|
946
967
|
async artifact(requestParameters: ArtifactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Blob> {
|
|
@@ -2612,6 +2633,69 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
2612
2633
|
return await response.value();
|
|
2613
2634
|
}
|
|
2614
2635
|
|
|
2636
|
+
/**
|
|
2637
|
+
* Creates request options for getStop without sending the request
|
|
2638
|
+
*/
|
|
2639
|
+
async getStopRequestOpts(requestParameters: GetStopRequest): Promise<runtime.RequestOpts> {
|
|
2640
|
+
if (requestParameters['sandboxId'] == null) {
|
|
2641
|
+
throw new runtime.RequiredError(
|
|
2642
|
+
'sandboxId',
|
|
2643
|
+
'Required parameter "sandboxId" was null or undefined when calling getStop().'
|
|
2644
|
+
);
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
if (requestParameters['stopId'] == null) {
|
|
2648
|
+
throw new runtime.RequiredError(
|
|
2649
|
+
'stopId',
|
|
2650
|
+
'Required parameter "stopId" was null or undefined when calling getStop().'
|
|
2651
|
+
);
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
const queryParameters: any = {};
|
|
2655
|
+
|
|
2656
|
+
const headerParameters: runtime.HTTPHeaders = {};
|
|
2657
|
+
|
|
2658
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
2659
|
+
const token = this.configuration.accessToken;
|
|
2660
|
+
const tokenString = await token("BoatBearerAuth", []);
|
|
2661
|
+
|
|
2662
|
+
if (tokenString) {
|
|
2663
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
let urlPath = `/sandboxes/{sandboxId}/stops/{stopId}`;
|
|
2668
|
+
urlPath = urlPath.replace('{sandboxId}', encodeURIComponent(String(requestParameters['sandboxId'])));
|
|
2669
|
+
urlPath = urlPath.replace('{stopId}', encodeURIComponent(String(requestParameters['stopId'])));
|
|
2670
|
+
|
|
2671
|
+
return {
|
|
2672
|
+
path: urlPath,
|
|
2673
|
+
method: 'GET',
|
|
2674
|
+
headers: headerParameters,
|
|
2675
|
+
query: queryParameters,
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
/**
|
|
2680
|
+
* Returns one stop of this sandbox by the id that `POST /sandboxes/{sandboxId}/stop` returned. Old stops stay readable after a resume or a later stop. Returns 404 when the id is unknown or belongs to another sandbox.
|
|
2681
|
+
* Get a stop by id
|
|
2682
|
+
*/
|
|
2683
|
+
async getStopRaw(requestParameters: GetStopRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<StopOperationResponse>> {
|
|
2684
|
+
const requestOptions = await this.getStopRequestOpts(requestParameters);
|
|
2685
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2686
|
+
|
|
2687
|
+
return new runtime.JSONApiResponse(response, (jsonValue) => StopOperationResponseFromJSON(jsonValue));
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
/**
|
|
2691
|
+
* Returns one stop of this sandbox by the id that `POST /sandboxes/{sandboxId}/stop` returned. Old stops stay readable after a resume or a later stop. Returns 404 when the id is unknown or belongs to another sandbox.
|
|
2692
|
+
* Get a stop by id
|
|
2693
|
+
*/
|
|
2694
|
+
async getStop(requestParameters: GetStopRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<StopOperationResponse> {
|
|
2695
|
+
const response = await this.getStopRaw(requestParameters, initOverrides);
|
|
2696
|
+
return await response.value();
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2615
2699
|
/**
|
|
2616
2700
|
* Creates request options for getWebhook without sending the request
|
|
2617
2701
|
*/
|
|
@@ -3345,6 +3429,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
3345
3429
|
}
|
|
3346
3430
|
|
|
3347
3431
|
/**
|
|
3432
|
+
* Files up to 5 MiB. Use `GET /sandboxes/{sandboxId}/artifacts` for files up to 50 MiB, and SCP over SSH for larger ones.
|
|
3348
3433
|
* Read a file from a sandbox
|
|
3349
3434
|
*/
|
|
3350
3435
|
async readFileRaw(requestParameters: ReadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<FileReadResponse>> {
|
|
@@ -3355,6 +3440,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
3355
3440
|
}
|
|
3356
3441
|
|
|
3357
3442
|
/**
|
|
3443
|
+
* Files up to 5 MiB. Use `GET /sandboxes/{sandboxId}/artifacts` for files up to 50 MiB, and SCP over SSH for larger ones.
|
|
3358
3444
|
* Read a file from a sandbox
|
|
3359
3445
|
*/
|
|
3360
3446
|
async readFile(requestParameters: ReadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<FileReadResponse> {
|
|
@@ -3362,6 +3448,61 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
3362
3448
|
return await response.value();
|
|
3363
3449
|
}
|
|
3364
3450
|
|
|
3451
|
+
/**
|
|
3452
|
+
* Creates request options for recover without sending the request
|
|
3453
|
+
*/
|
|
3454
|
+
async recoverRequestOpts(requestParameters: RecoverRequest): Promise<runtime.RequestOpts> {
|
|
3455
|
+
if (requestParameters['sandboxId'] == null) {
|
|
3456
|
+
throw new runtime.RequiredError(
|
|
3457
|
+
'sandboxId',
|
|
3458
|
+
'Required parameter "sandboxId" was null or undefined when calling recover().'
|
|
3459
|
+
);
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
const queryParameters: any = {};
|
|
3463
|
+
|
|
3464
|
+
const headerParameters: runtime.HTTPHeaders = {};
|
|
3465
|
+
|
|
3466
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
3467
|
+
const token = this.configuration.accessToken;
|
|
3468
|
+
const tokenString = await token("BoatBearerAuth", []);
|
|
3469
|
+
|
|
3470
|
+
if (tokenString) {
|
|
3471
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
let urlPath = `/sandboxes/{sandboxId}/recover`;
|
|
3476
|
+
urlPath = urlPath.replace('{sandboxId}', encodeURIComponent(String(requestParameters['sandboxId'])));
|
|
3477
|
+
|
|
3478
|
+
return {
|
|
3479
|
+
path: urlPath,
|
|
3480
|
+
method: 'POST',
|
|
3481
|
+
headers: headerParameters,
|
|
3482
|
+
query: queryParameters,
|
|
3483
|
+
};
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
/**
|
|
3487
|
+
* Power-cycle the machine of a sandbox that stopped answering. The disk is not touched. The sandbox usually answers again within 1-2 minutes and then saves your work by itself; `sandbox.recovered` fires when it does. Refused with `409`: - `sandbox_is_reachable`: the sandbox answers normally. - `too_soon`: a recover started less than 10 minutes ago. - `no_machine`: the sandbox has no machine. Resume it instead. - `recover_unsupported`: its machine cannot be power-cycled. Wait for it to answer, or resume it from its last snapshot. - `reset_failed`: the power-cycle failed. Reply to the incident email.
|
|
3488
|
+
* Recover a sandbox that stopped responding
|
|
3489
|
+
*/
|
|
3490
|
+
async recoverRaw(requestParameters: RecoverRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Recover200Response>> {
|
|
3491
|
+
const requestOptions = await this.recoverRequestOpts(requestParameters);
|
|
3492
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
3493
|
+
|
|
3494
|
+
return new runtime.JSONApiResponse(response, (jsonValue) => Recover200ResponseFromJSON(jsonValue));
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3497
|
+
/**
|
|
3498
|
+
* Power-cycle the machine of a sandbox that stopped answering. The disk is not touched. The sandbox usually answers again within 1-2 minutes and then saves your work by itself; `sandbox.recovered` fires when it does. Refused with `409`: - `sandbox_is_reachable`: the sandbox answers normally. - `too_soon`: a recover started less than 10 minutes ago. - `no_machine`: the sandbox has no machine. Resume it instead. - `recover_unsupported`: its machine cannot be power-cycled. Wait for it to answer, or resume it from its last snapshot. - `reset_failed`: the power-cycle failed. Reply to the incident email.
|
|
3499
|
+
* Recover a sandbox that stopped responding
|
|
3500
|
+
*/
|
|
3501
|
+
async recover(requestParameters: RecoverRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Recover200Response> {
|
|
3502
|
+
const response = await this.recoverRaw(requestParameters, initOverrides);
|
|
3503
|
+
return await response.value();
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3365
3506
|
/**
|
|
3366
3507
|
* Creates request options for repos without sending the request
|
|
3367
3508
|
*/
|
|
@@ -4259,7 +4400,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4259
4400
|
}
|
|
4260
4401
|
|
|
4261
4402
|
/**
|
|
4262
|
-
* Send a new message to a turn that is already running, without losing what the agent is doing. This is what typing into a coding agent while it works does: the instruction is taken into account and the work continues. Where the harness has a native mid-turn primitive (Claude Code, Codex, pi, Prime Agent) nothing is interrupted and the response has `native: true`. Where it does not (OpenCode), Boat interrupts that turn and immediately continues the SAME conversation with the instruction, keeping the session and its memory, and the response has `native: false`. Refused with **409 `no_running_turn`** when the conversation has nothing in flight; queue work with `POST /prompt` instead. The steer shows up in `GET /events` as a `steer` event. See [Integrated agents](/integrated-agents).
|
|
4403
|
+
* Send a new message to a turn that is already running, without losing what the agent is doing. This is what typing into a coding agent while it works does: the instruction is taken into account and the work continues. Where the harness has a native mid-turn primitive (Claude Code, Codex, pi, Prime Agent) nothing is interrupted and the response has `native: true`. Where it does not (OpenCode), Boat interrupts that turn and immediately continues the SAME conversation with the instruction, keeping the session and its memory, and the response has `native: false`. Refused with **409 `no_running_turn`** when the conversation has nothing in flight; queue work with `POST /prompt` instead. `error.details.reason` says why: `turn_ended` (with `error.details.lastTurn.status` and `.error` of the newest turn), `turn_not_started` (the turn is starting; retry in a moment), `no_turn`, `not_running` (the sandbox is not running) or `delivery_failed` (the sandbox did not accept the steer; check the turn before sending more work). The steer shows up in `GET /events` as a `steer` event. See [Integrated agents](/integrated-agents).
|
|
4263
4404
|
* Steer a running turn
|
|
4264
4405
|
*/
|
|
4265
4406
|
async steerRaw(requestParameters: SteerOperationRequest | runtime.FlatBody<SteerOperationRequest, 'steerRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SteerResponse>> {
|
|
@@ -4270,7 +4411,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4270
4411
|
}
|
|
4271
4412
|
|
|
4272
4413
|
/**
|
|
4273
|
-
* Send a new message to a turn that is already running, without losing what the agent is doing. This is what typing into a coding agent while it works does: the instruction is taken into account and the work continues. Where the harness has a native mid-turn primitive (Claude Code, Codex, pi, Prime Agent) nothing is interrupted and the response has `native: true`. Where it does not (OpenCode), Boat interrupts that turn and immediately continues the SAME conversation with the instruction, keeping the session and its memory, and the response has `native: false`. Refused with **409 `no_running_turn`** when the conversation has nothing in flight; queue work with `POST /prompt` instead. The steer shows up in `GET /events` as a `steer` event. See [Integrated agents](/integrated-agents).
|
|
4414
|
+
* Send a new message to a turn that is already running, without losing what the agent is doing. This is what typing into a coding agent while it works does: the instruction is taken into account and the work continues. Where the harness has a native mid-turn primitive (Claude Code, Codex, pi, Prime Agent) nothing is interrupted and the response has `native: true`. Where it does not (OpenCode), Boat interrupts that turn and immediately continues the SAME conversation with the instruction, keeping the session and its memory, and the response has `native: false`. Refused with **409 `no_running_turn`** when the conversation has nothing in flight; queue work with `POST /prompt` instead. `error.details.reason` says why: `turn_ended` (with `error.details.lastTurn.status` and `.error` of the newest turn), `turn_not_started` (the turn is starting; retry in a moment), `no_turn`, `not_running` (the sandbox is not running) or `delivery_failed` (the sandbox did not accept the steer; check the turn before sending more work). The steer shows up in `GET /events` as a `steer` event. See [Integrated agents](/integrated-agents).
|
|
4274
4415
|
* Steer a running turn
|
|
4275
4416
|
*/
|
|
4276
4417
|
async steer(requestParameters: SteerOperationRequest | runtime.FlatBody<SteerOperationRequest, 'steerRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SteerResponse> {
|
|
@@ -4318,7 +4459,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4318
4459
|
}
|
|
4319
4460
|
|
|
4320
4461
|
/**
|
|
4321
|
-
* Stop active work and archive/snapshot the sandbox for later resume or fork. A stop always saves the sandbox\'s disk first. If that save is failing, the stop is refused and the sandbox keeps running so your work is not discarded, we retry automatically and email you. You are not billed for time spent in that state. Set `force: true` to stop anyway,
|
|
4462
|
+
* Stop active work and archive/snapshot the sandbox for later resume or fork. A stop always saves the sandbox\'s disk first. If that save is failing, the stop is refused and the sandbox keeps running so your work is not discarded, we retry automatically and email you. You are not billed for time spent in that state. The stop is an operation: the response and the sandbox carry it as `stop`, with an `id` and a `status`. Poll `GET /sandboxes/{sandboxId}` until `stop.status` is `completed`. A failed attempt shows `failing` with its `error` and is retried until the sandbox archives; commands and prompts you send meanwhile do not cancel it. Only a resume ends it early (`superseded`). Calling stop again while one is pending returns the same `id`. Set `force: true` to stop anyway, keeping the last successful snapshot and losing everything written since then. This is irreversible; only reach for it after a stop has already failed. A force on a stop that is already pending escalates that stop.
|
|
4322
4463
|
* Stop and archive sandbox
|
|
4323
4464
|
*/
|
|
4324
4465
|
async stopRaw(requestParameters: StopOperationRequest | runtime.FlatBody<StopOperationRequest, 'stopRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SandboxActionResponse>> {
|
|
@@ -4329,7 +4470,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4329
4470
|
}
|
|
4330
4471
|
|
|
4331
4472
|
/**
|
|
4332
|
-
* Stop active work and archive/snapshot the sandbox for later resume or fork. A stop always saves the sandbox\'s disk first. If that save is failing, the stop is refused and the sandbox keeps running so your work is not discarded, we retry automatically and email you. You are not billed for time spent in that state. Set `force: true` to stop anyway,
|
|
4473
|
+
* Stop active work and archive/snapshot the sandbox for later resume or fork. A stop always saves the sandbox\'s disk first. If that save is failing, the stop is refused and the sandbox keeps running so your work is not discarded, we retry automatically and email you. You are not billed for time spent in that state. The stop is an operation: the response and the sandbox carry it as `stop`, with an `id` and a `status`. Poll `GET /sandboxes/{sandboxId}` until `stop.status` is `completed`. A failed attempt shows `failing` with its `error` and is retried until the sandbox archives; commands and prompts you send meanwhile do not cancel it. Only a resume ends it early (`superseded`). Calling stop again while one is pending returns the same `id`. Set `force: true` to stop anyway, keeping the last successful snapshot and losing everything written since then. This is irreversible; only reach for it after a stop has already failed. A force on a stop that is already pending escalates that stop.
|
|
4333
4474
|
* Stop and archive sandbox
|
|
4334
4475
|
*/
|
|
4335
4476
|
async stop(requestParameters: StopOperationRequest | runtime.FlatBody<StopOperationRequest, 'stopRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SandboxActionResponse> {
|
|
@@ -4816,6 +4957,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4816
4957
|
}
|
|
4817
4958
|
|
|
4818
4959
|
/**
|
|
4960
|
+
* Files up to 5 MiB after decoding. Use SCP over SSH for larger files.
|
|
4819
4961
|
* Write a file in a sandbox
|
|
4820
4962
|
*/
|
|
4821
4963
|
async writeFileRaw(requestParameters: WriteFileRequest | runtime.FlatBody<WriteFileRequest, 'fileWriteRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<FileWriteResponse>> {
|
|
@@ -4826,6 +4968,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
4826
4968
|
}
|
|
4827
4969
|
|
|
4828
4970
|
/**
|
|
4971
|
+
* Files up to 5 MiB after decoding. Use SCP over SSH for larger files.
|
|
4829
4972
|
* Write a file in a sandbox
|
|
4830
4973
|
*/
|
|
4831
4974
|
async writeFile(requestParameters: WriteFileRequest | runtime.FlatBody<WriteFileRequest, 'fileWriteRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<FileWriteResponse> {
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// The SDK's default fetch. On Node it sends every request to an https origin over
|
|
2
|
+
// ONE shared HTTP/2 connection. Node's global fetch speaks HTTP/1.1 only, so N
|
|
3
|
+
// concurrent calls opened N TLS connections: a burst of 200 calls from a laptop
|
|
4
|
+
// made 200 handshakes (measured 2026-10-08), and 250 creates arrived at the API
|
|
5
|
+
// over 8-14 s. Elsewhere (browsers, Deno, Bun, an origin without HTTP/2), and for
|
|
6
|
+
// any body this does not handle, it is the global fetch.
|
|
7
|
+
// Pass `fetchApi` in the Configuration to use your own fetch instead.
|
|
8
|
+
|
|
9
|
+
type Session = {
|
|
10
|
+
closed: boolean;
|
|
11
|
+
destroyed: boolean;
|
|
12
|
+
request(headers: Record<string, string>, options?: { endStream?: boolean }): any;
|
|
13
|
+
on(event: string, cb: (...args: any[]) => void): void;
|
|
14
|
+
unref(): void;
|
|
15
|
+
ref(): void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const sessions = new Map<string, Promise<Session | null>>();
|
|
19
|
+
const http1Only = new Set<string>();
|
|
20
|
+
const slots = new WeakMap<Session, { active: number; waiting: Array<() => void> }>();
|
|
21
|
+
|
|
22
|
+
// A server caps the streams open at once on a connection (boat.dev: 250; this uses
|
|
23
|
+
// at most 100). A stream past the cap is refused, so the excess waits here. Requests open
|
|
24
|
+
// or waiting keep the process alive; an idle shared connection does not.
|
|
25
|
+
async function streamSlot(s: Session, signal?: AbortSignal | null): Promise<() => void> {
|
|
26
|
+
let st = slots.get(s);
|
|
27
|
+
if (!st) { st = { active: 0, waiting: [] }; slots.set(s, st); }
|
|
28
|
+
const state = st;
|
|
29
|
+
const cap = Math.max(1, Math.min(Number((s as any).remoteSettings?.maxConcurrentStreams) || 100, 100));
|
|
30
|
+
// Already aborted: take no stream, never queue (an abort listener added now never fires).
|
|
31
|
+
if (signal?.aborted) return () => {};
|
|
32
|
+
if (state.active === 0 && state.waiting.length === 0) s.ref();
|
|
33
|
+
if (state.active >= cap) {
|
|
34
|
+
const turn = await new Promise<boolean>((wake) => {
|
|
35
|
+
const w = () => wake(true);
|
|
36
|
+
state.waiting.push(w);
|
|
37
|
+
// An aborted waiter leaves the queue without a stream; the caller rejects it.
|
|
38
|
+
signal?.addEventListener('abort', () => {
|
|
39
|
+
const i = state.waiting.indexOf(w);
|
|
40
|
+
if (i !== -1) { state.waiting.splice(i, 1); wake(false); }
|
|
41
|
+
}, { once: true });
|
|
42
|
+
});
|
|
43
|
+
if (!turn) return () => {};
|
|
44
|
+
}
|
|
45
|
+
state.active++;
|
|
46
|
+
let released = false;
|
|
47
|
+
return () => {
|
|
48
|
+
if (released) return;
|
|
49
|
+
released = true;
|
|
50
|
+
state.active--;
|
|
51
|
+
const next = state.waiting.shift();
|
|
52
|
+
if (next) next();
|
|
53
|
+
else if (state.active === 0) s.unref();
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
let nodeHttp2: Promise<any | null> | undefined;
|
|
57
|
+
|
|
58
|
+
function loadNode(): Promise<any | null> {
|
|
59
|
+
if (!nodeHttp2) {
|
|
60
|
+
const versions = (globalThis as any).process?.versions;
|
|
61
|
+
const isNode = !!versions?.node && !versions.bun && typeof (globalThis as any).Deno === 'undefined';
|
|
62
|
+
// A variable, not a literal: a browser bundler must not try to resolve it.
|
|
63
|
+
const h2 = 'node:http2';
|
|
64
|
+
nodeHttp2 = isNode
|
|
65
|
+
? import(/* webpackIgnore: true */ /* @vite-ignore */ h2).catch(() => null)
|
|
66
|
+
: Promise.resolve(null);
|
|
67
|
+
}
|
|
68
|
+
return nodeHttp2;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function session(origin: string, http2: any): Promise<Session | null> {
|
|
72
|
+
const open = sessions.get(origin);
|
|
73
|
+
if (open) return open;
|
|
74
|
+
const pending = new Promise<Session | null>((resolve) => {
|
|
75
|
+
let s: any;
|
|
76
|
+
try {
|
|
77
|
+
s = http2.connect(origin);
|
|
78
|
+
} catch {
|
|
79
|
+
resolve(null);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const drop = () => { if (sessions.get(origin) === pending) sessions.delete(origin); };
|
|
83
|
+
s.once('connect', () => {
|
|
84
|
+
// An origin that answered without h2 never gets here: the TLS layer fails the connect.
|
|
85
|
+
s.unref(); // an idle shared connection must not keep the process alive
|
|
86
|
+
resolve(s);
|
|
87
|
+
});
|
|
88
|
+
// `on`, not `once`: a session can emit more than one error, and an unhandled one kills the process.
|
|
89
|
+
s.on('error', () => { drop(); resolve(null); });
|
|
90
|
+
s.once('close', drop);
|
|
91
|
+
s.once('goaway', drop);
|
|
92
|
+
});
|
|
93
|
+
sessions.set(origin, pending);
|
|
94
|
+
return pending;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function sendableBody(body: unknown): string | Uint8Array | null | undefined {
|
|
98
|
+
if (body == null) return null;
|
|
99
|
+
if (typeof body === 'string') return body;
|
|
100
|
+
if (body instanceof Uint8Array) return body;
|
|
101
|
+
if (body instanceof ArrayBuffer) return new Uint8Array(body);
|
|
102
|
+
if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) return body.toString();
|
|
103
|
+
return undefined; // FormData, Blob, streams: the global fetch encodes these
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const HOP_BY_HOP = new Set(['connection', 'host', 'keep-alive', 'proxy-connection', 'transfer-encoding', 'upgrade']);
|
|
107
|
+
|
|
108
|
+
async function http2Fetch(input: RequestInfo | URL, init: RequestInit = {}): Promise<Response> {
|
|
109
|
+
const url = new URL(typeof input === 'string' ? input : input instanceof URL ? input.href : input.url);
|
|
110
|
+
const body = sendableBody(init.body);
|
|
111
|
+
const node = await loadNode();
|
|
112
|
+
const isRequest = typeof input !== 'string' && !(input instanceof URL);
|
|
113
|
+
if (!node || isRequest || body === undefined || url.protocol !== 'https:' || http1Only.has(url.origin)) {
|
|
114
|
+
return fetch(input as any, init);
|
|
115
|
+
}
|
|
116
|
+
const s = await session(url.origin, node);
|
|
117
|
+
if (!s || s.closed || s.destroyed) {
|
|
118
|
+
if (!s) http1Only.add(url.origin);
|
|
119
|
+
return fetch(input as any, init);
|
|
120
|
+
}
|
|
121
|
+
const headers: Record<string, string> = { ':method': (init.method || 'GET').toUpperCase(), ':path': url.pathname + url.search };
|
|
122
|
+
new Headers(init.headers).forEach((value, key) => { if (!HOP_BY_HOP.has(key)) headers[key] = value; });
|
|
123
|
+
const signal = init.signal;
|
|
124
|
+
const aborted = () => signal!.reason ?? new DOMException('This operation was aborted', 'AbortError');
|
|
125
|
+
const release = await streamSlot(s, signal);
|
|
126
|
+
return new Promise<Response>((resolve, reject) => {
|
|
127
|
+
if (signal?.aborted) { release(); reject(aborted()); return; }
|
|
128
|
+
let req: any;
|
|
129
|
+
try {
|
|
130
|
+
req = s.request(headers, { endStream: body === null });
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// The connection closed (GOAWAY) while this call waited for a stream.
|
|
133
|
+
release();
|
|
134
|
+
reject(e);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const onAbort = () => { req.close(); reject(aborted()); };
|
|
138
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
139
|
+
req.once('close', () => { release(); signal?.removeEventListener('abort', onAbort); });
|
|
140
|
+
req.on('error', reject); // after the response this errors its body stream; a no-op here
|
|
141
|
+
req.once('response', (h: Record<string, string | string[]>) => {
|
|
142
|
+
const status = Number(h[':status']);
|
|
143
|
+
const out = new Headers();
|
|
144
|
+
for (const [k, v] of Object.entries(h)) {
|
|
145
|
+
if (k.startsWith(':') || v === undefined) continue;
|
|
146
|
+
for (const one of Array.isArray(v) ? v : [v]) out.append(k, String(one));
|
|
147
|
+
}
|
|
148
|
+
const empty = status === 204 || status === 205 || status === 304 || headers[':method'] === 'HEAD';
|
|
149
|
+
if (empty) req.resume();
|
|
150
|
+
// Fed from 'data' events, not Readable.toWeb: an HTTP/2 stream the server has
|
|
151
|
+
// already closed is destroyed with its unread data, and toWeb's backpressure
|
|
152
|
+
// turned that into "Premature close" on 25 of 250 calls (prod, 2026-10-08).
|
|
153
|
+
// A slow reader (streamCommand between frames) must not let a fast command
|
|
154
|
+
// fill memory: past 4 MiB unread the stream pauses until the reader pulls.
|
|
155
|
+
const bodyStream = empty ? null : new ReadableStream<Uint8Array>({
|
|
156
|
+
start(controller) {
|
|
157
|
+
req.on('data', (chunk: Uint8Array) => {
|
|
158
|
+
controller.enqueue(new Uint8Array(chunk));
|
|
159
|
+
if ((controller.desiredSize ?? 1) <= 0) req.pause();
|
|
160
|
+
});
|
|
161
|
+
req.once('end', () => controller.close());
|
|
162
|
+
req.once('error', (e: unknown) => controller.error(e));
|
|
163
|
+
req.once('close', () => {
|
|
164
|
+
if (!req.readableEnded) { try { controller.error(new Error(`HTTP/2 stream closed before its end (code ${req.rstCode})`)); } catch {} }
|
|
165
|
+
});
|
|
166
|
+
},
|
|
167
|
+
pull() { if (req.isPaused()) req.resume(); },
|
|
168
|
+
cancel() { req.close(); },
|
|
169
|
+
}, { highWaterMark: 4 * 1024 * 1024, size: (chunk) => chunk?.byteLength ?? 0 });
|
|
170
|
+
const response = new Response(bodyStream, { status, headers: out });
|
|
171
|
+
// Response.url is read-only; the generated client never reads it, but keep it right.
|
|
172
|
+
Object.defineProperty(response, 'url', { value: url.href });
|
|
173
|
+
resolve(response);
|
|
174
|
+
});
|
|
175
|
+
if (body !== null) req.end(body);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export const defaultFetch = http2Fetch as typeof fetch;
|
|
@@ -50,7 +50,7 @@ export interface Conversation {
|
|
|
50
50
|
*/
|
|
51
51
|
running: boolean;
|
|
52
52
|
/**
|
|
53
|
-
* Harness the most recent prompt ran on (`claude`, `codex`, `pi`, `opencode`, `prime-agent`, `kimi`).
|
|
53
|
+
* Harness the most recent prompt ran on (`claude`, `codex`, `pi`, `opencode`, `prime-agent`, `kimi`, `mistral`).
|
|
54
54
|
* @type {string}
|
|
55
55
|
* @memberof Conversation
|
|
56
56
|
*/
|
|
@@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
|
|
|
20
20
|
*/
|
|
21
21
|
export interface CreateSandboxRequest {
|
|
22
22
|
/**
|
|
23
|
-
* Machine size. `small` consumes machine time at half rate and `large` at twice the default rate (see the Billing guide). A fork inherits the source sandbox's type unless the fork request passes its own, and resume and fork can move a sandbox between sizes.
|
|
23
|
+
* Machine size. `small` consumes machine time at half rate and `large` at twice the default rate (see the Billing guide). `xlarge` needs the $100/month plan or higher; lower plans get a 403 `machine_class_plan_required` on create, resume and fork. A fork inherits the source sandbox's type unless the fork request passes its own, and resume and fork can move a sandbox between sizes.
|
|
24
24
|
* @type {CreateSandboxRequestTypeEnum}
|
|
25
25
|
* @memberof CreateSandboxRequest
|
|
26
26
|
*/
|
|
@@ -62,7 +62,7 @@ export interface CreateSandboxRequest {
|
|
|
62
62
|
*/
|
|
63
63
|
failFast?: boolean;
|
|
64
64
|
/**
|
|
65
|
-
* Shell script that runs on the sandbox after it is ready. Ready means "ready to accept the user", not "setup done": the script starts in the background once provisioning completes and never blocks the sandbox becoming usable. It runs as the sandbox user via `bash`, with the sandbox's environment applied, and its output goes to a log file on the sandbox. Observe the outcome as `setupStatus` (pending/running/done/failed) and `setupError` on the sandbox. Rejected with a 400 `invalid_setup_script` error when it is not a string or exceeds 64KB.
|
|
65
|
+
* Shell script that runs on the sandbox after it is ready. Ready means "ready to accept the user", not "setup done": the script starts in the background once provisioning completes and never blocks the sandbox becoming usable. It runs as the sandbox user (`user`, not root; `sudo` needs no password) via `bash`, with the sandbox's environment applied, and its output goes to a log file on the sandbox. Observe the outcome as `setupStatus` (pending/running/done/failed) and `setupError` on the sandbox. Rejected with a 400 `invalid_setup_script` error when it is not a string or exceeds 64KB.
|
|
66
66
|
* @type {string}
|
|
67
67
|
* @memberof CreateSandboxRequest
|
|
68
68
|
*/
|
|
@@ -94,7 +94,8 @@ export interface CreateSandboxRequest {
|
|
|
94
94
|
export const CreateSandboxRequestTypeEnum = {
|
|
95
95
|
Small: 'small',
|
|
96
96
|
Default: 'default',
|
|
97
|
-
Large: 'large'
|
|
97
|
+
Large: 'large',
|
|
98
|
+
Xlarge: 'xlarge'
|
|
98
99
|
} as const;
|
|
99
100
|
export type CreateSandboxRequestTypeEnum = typeof CreateSandboxRequestTypeEnum[keyof typeof CreateSandboxRequestTypeEnum];
|
|
100
101
|
|
|
@@ -44,7 +44,7 @@ export interface ForkRequest {
|
|
|
44
44
|
*/
|
|
45
45
|
noEnv?: boolean;
|
|
46
46
|
/**
|
|
47
|
-
* Machine size for the fork. Omit to inherit the source sandbox's type. The source sandbox is never modified. Shrinking is rejected with `type_too_small` when the source's data would not fit the smaller disk.
|
|
47
|
+
* Machine size for the fork. Omit to inherit the source sandbox's type. `xlarge` needs the $100/month plan or higher (403 `machine_class_plan_required`). The source sandbox is never modified. Shrinking is rejected with `type_too_small` when the source's data would not fit the smaller disk.
|
|
48
48
|
* @type {ForkRequestTypeEnum}
|
|
49
49
|
* @memberof ForkRequest
|
|
50
50
|
*/
|
|
@@ -64,7 +64,8 @@ export interface ForkRequest {
|
|
|
64
64
|
export const ForkRequestTypeEnum = {
|
|
65
65
|
Small: 'small',
|
|
66
66
|
Default: 'default',
|
|
67
|
-
Large: 'large'
|
|
67
|
+
Large: 'large',
|
|
68
|
+
Xlarge: 'xlarge'
|
|
68
69
|
} as const;
|
|
69
70
|
export type ForkRequestTypeEnum = typeof ForkRequestTypeEnum[keyof typeof ForkRequestTypeEnum];
|
|
70
71
|
|
|
@@ -16,7 +16,7 @@ import { mapValues } from '../runtime';
|
|
|
16
16
|
/**
|
|
17
17
|
* Work item to queue inside an existing sandbox. Provider credentials must already be configured in the Boat dashboard.
|
|
18
18
|
*
|
|
19
|
-
* **Providers (harnesses):** `codex`, `claude-code` (alias `claude`), `pi`, `opencode`, `prime-agent` (alias `prime`), `kimi` (Kimi Code CLI, alias `kimi-code`). Omit `provider` to use the harness the user selected on the Agents dashboard.
|
|
19
|
+
* **Providers (harnesses):** `codex`, `claude-code` (alias `claude`), `pi`, `opencode`, `prime-agent` (alias `prime`), `kimi` (Kimi Code CLI, alias `kimi-code`), `mistral` (Mistral Vibe). Omit `provider` to use the harness the user selected on the Agents dashboard.
|
|
20
20
|
*
|
|
21
21
|
* **Models & reasoning effort** are harness- and model-specific and change over time. Fetch the live catalog (every provider's models and which reasoning-effort levels each accepts) from `GET /provider-models`. Some models accept no reasoning control. `pi`, `opencode` and `prime-agent` also expose models routed through OpenRouter and llmgateway (ids like `openrouter:anthropic/claude-sonnet-4.5`).
|
|
22
22
|
*
|
|
@@ -83,7 +83,8 @@ export const PromptRequestProviderEnum = {
|
|
|
83
83
|
PrimeAgent: 'prime-agent',
|
|
84
84
|
Prime: 'prime',
|
|
85
85
|
Kimi: 'kimi',
|
|
86
|
-
KimiCode: 'kimi-code'
|
|
86
|
+
KimiCode: 'kimi-code',
|
|
87
|
+
Mistral: 'mistral'
|
|
87
88
|
} as const;
|
|
88
89
|
export type PromptRequestProviderEnum = typeof PromptRequestProviderEnum[keyof typeof PromptRequestProviderEnum];
|
|
89
90
|
|