@vellumai/cli 0.8.10-dev.202606110422.8c0e9aa → 0.8.10-dev.202606110544.2aed335
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/package.json +1 -1
- package/src/commands/backup.ts +3 -2
- package/src/commands/client.ts +3 -2
- package/src/commands/devices.ts +3 -2
- package/src/commands/pair.ts +2 -1
- package/src/commands/restore.ts +3 -2
- package/src/commands/retire.ts +2 -1
- package/src/commands/roadmap.ts +2 -1
- package/src/commands/upgrade.ts +3 -2
- package/src/lib/assistant-client.ts +3 -2
- package/src/lib/backup-ops.ts +5 -4
- package/src/lib/docker.ts +2 -1
- package/src/lib/guardian-token.ts +3 -2
- package/src/lib/hatch-local.ts +2 -1
- package/src/lib/http-client.ts +3 -1
- package/src/lib/local-runtime-client.ts +5 -4
- package/src/lib/ngrok.ts +2 -1
- package/src/lib/platform-releases.ts +3 -2
- package/src/lib/terminal-client.ts +6 -5
- package/src/lib/upgrade-lifecycle.ts +9 -8
package/package.json
CHANGED
package/src/commands/backup.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
platformRequestSignedUrl,
|
|
17
17
|
readPlatformToken,
|
|
18
18
|
} from "../lib/platform-client.js";
|
|
19
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
19
20
|
|
|
20
21
|
export async function backup(): Promise<void> {
|
|
21
22
|
const args = process.argv.slice(3);
|
|
@@ -112,7 +113,7 @@ export async function backup(): Promise<void> {
|
|
|
112
113
|
// Call the export endpoint
|
|
113
114
|
let response: Response;
|
|
114
115
|
try {
|
|
115
|
-
response = await
|
|
116
|
+
response = await loopbackSafeFetch(`${entry.runtimeUrl}/v1/migrations/export`, {
|
|
116
117
|
method: "POST",
|
|
117
118
|
headers: {
|
|
118
119
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -138,7 +139,7 @@ export async function backup(): Promise<void> {
|
|
|
138
139
|
}
|
|
139
140
|
if (refreshedToken) {
|
|
140
141
|
accessToken = refreshedToken;
|
|
141
|
-
response = await
|
|
142
|
+
response = await loopbackSafeFetch(`${entry.runtimeUrl}/v1/migrations/export`, {
|
|
142
143
|
method: "POST",
|
|
143
144
|
headers: {
|
|
144
145
|
Authorization: `Bearer ${accessToken}`,
|
package/src/commands/client.ts
CHANGED
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
readPlatformToken,
|
|
57
57
|
} from "../lib/platform-client";
|
|
58
58
|
import { tuiLog } from "../lib/tui-log";
|
|
59
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
59
60
|
|
|
60
61
|
const SUPPORTED_INTERFACES = ["cli", "web"] as const;
|
|
61
62
|
type SupportedInterface = (typeof SUPPORTED_INTERFACES)[number];
|
|
@@ -619,7 +620,7 @@ async function handleLocalEndpoints(
|
|
|
619
620
|
|
|
620
621
|
try {
|
|
621
622
|
const hasBody = req.method !== "GET" && req.method !== "HEAD";
|
|
622
|
-
const proxyRes = await
|
|
623
|
+
const proxyRes = await loopbackSafeFetch(targetUrl, {
|
|
623
624
|
method: req.method,
|
|
624
625
|
headers,
|
|
625
626
|
body: hasBody ? req.body : undefined,
|
|
@@ -760,7 +761,7 @@ async function runWebInterface(
|
|
|
760
761
|
try {
|
|
761
762
|
const hasBody = req.method !== "GET" && req.method !== "HEAD";
|
|
762
763
|
const body = hasBody ? await req.arrayBuffer() : undefined;
|
|
763
|
-
const proxyRes = await
|
|
764
|
+
const proxyRes = await loopbackSafeFetch(target.toString(), {
|
|
764
765
|
method: req.method,
|
|
765
766
|
headers,
|
|
766
767
|
body,
|
package/src/commands/devices.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
canPromptForConfirmation,
|
|
29
29
|
confirmAction,
|
|
30
30
|
} from "../lib/confirm-action.js";
|
|
31
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
31
32
|
|
|
32
33
|
interface DeviceRecord {
|
|
33
34
|
hashedDeviceId: string;
|
|
@@ -108,7 +109,7 @@ async function listDevices(entry: AssistantEntry, base: string): Promise<void> {
|
|
|
108
109
|
|
|
109
110
|
let response: Response;
|
|
110
111
|
try {
|
|
111
|
-
response = await
|
|
112
|
+
response = await loopbackSafeFetch(`${base}/v1/devices`, {
|
|
112
113
|
method: "GET",
|
|
113
114
|
headers: getClientRegistrationHeaders(CLI_INTERFACE_ID),
|
|
114
115
|
});
|
|
@@ -186,7 +187,7 @@ async function revokeDevice(
|
|
|
186
187
|
|
|
187
188
|
let response: Response;
|
|
188
189
|
try {
|
|
189
|
-
response = await
|
|
190
|
+
response = await loopbackSafeFetch(`${base}/v1/devices/revoke`, {
|
|
190
191
|
method: "POST",
|
|
191
192
|
headers: {
|
|
192
193
|
"Content-Type": "application/json",
|
package/src/commands/pair.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
} from "../lib/client-identity.js";
|
|
27
27
|
import { GATEWAY_PORT } from "../lib/constants.js";
|
|
28
28
|
import { getLocalLanIPv4 } from "../lib/local.js";
|
|
29
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
29
30
|
|
|
30
31
|
function isLoopbackHost(url: string): boolean {
|
|
31
32
|
try {
|
|
@@ -154,7 +155,7 @@ export async function pair(): Promise<void> {
|
|
|
154
155
|
|
|
155
156
|
let response: Response;
|
|
156
157
|
try {
|
|
157
|
-
response = await
|
|
158
|
+
response = await loopbackSafeFetch(`${mintUrl}/v1/pair`, {
|
|
158
159
|
method: "POST",
|
|
159
160
|
headers: {
|
|
160
161
|
"Content-Type": "application/json",
|
package/src/commands/restore.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
platformPollJobStatus,
|
|
17
17
|
} from "../lib/platform-client.js";
|
|
18
18
|
import { performDockerRollback } from "../lib/upgrade-lifecycle.js";
|
|
19
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
19
20
|
|
|
20
21
|
function printUsage(): void {
|
|
21
22
|
console.log(
|
|
@@ -588,7 +589,7 @@ export async function restore(): Promise<void> {
|
|
|
588
589
|
|
|
589
590
|
let response: Response;
|
|
590
591
|
try {
|
|
591
|
-
response = await
|
|
592
|
+
response = await loopbackSafeFetch(
|
|
592
593
|
`${entry.runtimeUrl}/v1/migrations/import-preflight`,
|
|
593
594
|
{
|
|
594
595
|
method: "POST",
|
|
@@ -694,7 +695,7 @@ export async function restore(): Promise<void> {
|
|
|
694
695
|
|
|
695
696
|
let response: Response;
|
|
696
697
|
try {
|
|
697
|
-
response = await
|
|
698
|
+
response = await loopbackSafeFetch(`${entry.runtimeUrl}/v1/migrations/import`, {
|
|
698
699
|
method: "POST",
|
|
699
700
|
headers: {
|
|
700
701
|
Authorization: `Bearer ${accessToken}`,
|
package/src/commands/retire.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
resetLogFile,
|
|
37
37
|
writeToLogFile,
|
|
38
38
|
} from "../lib/xdg-log.js";
|
|
39
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
39
40
|
|
|
40
41
|
export { retireLocal };
|
|
41
42
|
|
|
@@ -96,7 +97,7 @@ async function retireVellum(
|
|
|
96
97
|
|
|
97
98
|
const platformUrl = runtimeUrl || getPlatformUrl();
|
|
98
99
|
const url = `${platformUrl}/v1/assistants/${encodeURIComponent(assistantId)}/retire/`;
|
|
99
|
-
const response = await
|
|
100
|
+
const response = await loopbackSafeFetch(url, {
|
|
100
101
|
method: "DELETE",
|
|
101
102
|
headers: await authHeaders(token, runtimeUrl),
|
|
102
103
|
});
|
package/src/commands/roadmap.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readPlatformToken, getWebUrl } from "../lib/platform-client.js";
|
|
2
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
2
3
|
|
|
3
4
|
function printUsage(): void {
|
|
4
5
|
console.log("Usage: vellum roadmap <subcommand>");
|
|
@@ -88,7 +89,7 @@ async function apiFetch(
|
|
|
88
89
|
if (options.token) headers["X-Session-Token"] = options.token;
|
|
89
90
|
if (options.body) headers["Content-Type"] = "application/json";
|
|
90
91
|
|
|
91
|
-
return
|
|
92
|
+
return loopbackSafeFetch(url, {
|
|
92
93
|
method: options.method ?? "GET",
|
|
93
94
|
headers,
|
|
94
95
|
body: options.body ? JSON.stringify(options.body) : undefined,
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
waitForReady,
|
|
48
48
|
} from "../lib/upgrade-lifecycle.js";
|
|
49
49
|
import { compareVersions } from "../lib/version-compat.js";
|
|
50
|
+
import { loopbackSafeFetch } from "../lib/loopback-fetch.js";
|
|
50
51
|
|
|
51
52
|
interface UpgradeArgs {
|
|
52
53
|
name: string | null;
|
|
@@ -230,7 +231,7 @@ async function upgradeDocker(
|
|
|
230
231
|
lastWorkspaceMigrationId?: string;
|
|
231
232
|
} = {};
|
|
232
233
|
try {
|
|
233
|
-
const healthResp = await
|
|
234
|
+
const healthResp = await loopbackSafeFetch(
|
|
234
235
|
`${entry.runtimeUrl}/healthz?include=migrations`,
|
|
235
236
|
{
|
|
236
237
|
signal: AbortSignal.timeout(5000),
|
|
@@ -695,7 +696,7 @@ async function upgradePlatform(
|
|
|
695
696
|
body.version = version;
|
|
696
697
|
}
|
|
697
698
|
|
|
698
|
-
const response = await
|
|
699
|
+
const response = await loopbackSafeFetch(url, {
|
|
699
700
|
method: "POST",
|
|
700
701
|
headers,
|
|
701
702
|
body: JSON.stringify(body),
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
refreshGuardianToken,
|
|
20
20
|
guardianTokenDueForRenewal,
|
|
21
21
|
} from "./guardian-token.js";
|
|
22
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
22
23
|
|
|
23
24
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
24
25
|
const FALLBACK_RUNTIME_URL = `http://127.0.0.1:${GATEWAY_PORT}`;
|
|
@@ -203,7 +204,7 @@ export class AssistantClient {
|
|
|
203
204
|
const doFetch = (): Promise<Response> => {
|
|
204
205
|
const headers = buildHeaders();
|
|
205
206
|
if (opts?.signal) {
|
|
206
|
-
return
|
|
207
|
+
return loopbackSafeFetch(url, {
|
|
207
208
|
method,
|
|
208
209
|
headers,
|
|
209
210
|
body: jsonBody,
|
|
@@ -213,7 +214,7 @@ export class AssistantClient {
|
|
|
213
214
|
const timeout = opts?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
214
215
|
const controller = new AbortController();
|
|
215
216
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
216
|
-
return
|
|
217
|
+
return loopbackSafeFetch(url, {
|
|
217
218
|
method,
|
|
218
219
|
headers,
|
|
219
220
|
body: jsonBody,
|
package/src/lib/backup-ops.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
loadGuardianToken,
|
|
14
14
|
refreshGuardianToken,
|
|
15
15
|
} from "./guardian-token.js";
|
|
16
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
16
17
|
|
|
17
18
|
/** Default backup directory following XDG convention */
|
|
18
19
|
export function getBackupsDir(): string {
|
|
@@ -66,7 +67,7 @@ export async function createBackup(
|
|
|
66
67
|
return null;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
let response = await
|
|
70
|
+
let response = await loopbackSafeFetch(`${runtimeUrl}/v1/migrations/export`, {
|
|
70
71
|
method: "POST",
|
|
71
72
|
headers: {
|
|
72
73
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -87,7 +88,7 @@ export async function createBackup(
|
|
|
87
88
|
return null;
|
|
88
89
|
}
|
|
89
90
|
accessToken = refreshed.accessToken;
|
|
90
|
-
response = await
|
|
91
|
+
response = await loopbackSafeFetch(`${runtimeUrl}/v1/migrations/export`, {
|
|
91
92
|
method: "POST",
|
|
92
93
|
headers: {
|
|
93
94
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -152,7 +153,7 @@ export async function restoreBackup(
|
|
|
152
153
|
return false;
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
let response = await
|
|
156
|
+
let response = await loopbackSafeFetch(`${runtimeUrl}/v1/migrations/import`, {
|
|
156
157
|
method: "POST",
|
|
157
158
|
headers: {
|
|
158
159
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -171,7 +172,7 @@ export async function restoreBackup(
|
|
|
171
172
|
return false;
|
|
172
173
|
}
|
|
173
174
|
accessToken = refreshed.accessToken;
|
|
174
|
-
response = await
|
|
175
|
+
response = await loopbackSafeFetch(`${runtimeUrl}/v1/migrations/import`, {
|
|
175
176
|
method: "POST",
|
|
176
177
|
headers: {
|
|
177
178
|
Authorization: `Bearer ${accessToken}`,
|
package/src/lib/docker.ts
CHANGED
|
@@ -67,6 +67,7 @@ export {
|
|
|
67
67
|
ASSISTANT_INTERNAL_PORT,
|
|
68
68
|
GATEWAY_INTERNAL_PORT,
|
|
69
69
|
} from "./environments/paths.js";
|
|
70
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
70
71
|
|
|
71
72
|
/** Max time to wait for the assistant container to emit the readiness sentinel. */
|
|
72
73
|
export const DOCKER_READY_TIMEOUT_MS = 5 * 60 * 1000;
|
|
@@ -1530,7 +1531,7 @@ async function waitForGatewayAndLease(opts: {
|
|
|
1530
1531
|
|
|
1531
1532
|
while (Date.now() - start < DOCKER_READY_TIMEOUT_MS) {
|
|
1532
1533
|
try {
|
|
1533
|
-
const resp = await
|
|
1534
|
+
const resp = await loopbackSafeFetch(readyUrl, {
|
|
1534
1535
|
signal: AbortSignal.timeout(5000),
|
|
1535
1536
|
});
|
|
1536
1537
|
if (resp.ok) {
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
|
|
25
25
|
import { getConfigDir } from "./environments/paths.js";
|
|
26
26
|
import { getCurrentEnvironment } from "./environments/resolve.js";
|
|
27
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
27
28
|
|
|
28
29
|
const DEVICE_ID_SALT = "vellum-assistant-host-id";
|
|
29
30
|
|
|
@@ -346,7 +347,7 @@ export async function refreshGuardianToken(
|
|
|
346
347
|
|
|
347
348
|
const tokenData = current ?? before;
|
|
348
349
|
|
|
349
|
-
const response = await
|
|
350
|
+
const response = await loopbackSafeFetch(`${gatewayUrl}/v1/guardian/refresh`, {
|
|
350
351
|
method: "POST",
|
|
351
352
|
headers: {
|
|
352
353
|
"Content-Type": "application/json",
|
|
@@ -406,7 +407,7 @@ export async function leaseGuardianToken(
|
|
|
406
407
|
if (bootstrapSecret) {
|
|
407
408
|
headers["x-bootstrap-secret"] = bootstrapSecret;
|
|
408
409
|
}
|
|
409
|
-
const response = await
|
|
410
|
+
const response = await loopbackSafeFetch(`${gatewayUrl}/v1/guardian/init`, {
|
|
410
411
|
method: "POST",
|
|
411
412
|
headers,
|
|
412
413
|
body: JSON.stringify({ platform: "cli", deviceId }),
|
package/src/lib/hatch-local.ts
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
} from "./provider-secrets.js";
|
|
45
45
|
import { logHatchNextSteps } from "./hatch-next-steps.js";
|
|
46
46
|
import { checkProviderApiKey } from "./api-key-check.js";
|
|
47
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Attempts to place a symlink at the given path pointing to cliBinary.
|
|
@@ -358,7 +359,7 @@ export async function hatchLocal(
|
|
|
358
359
|
while (true) {
|
|
359
360
|
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
360
361
|
try {
|
|
361
|
-
const res = await
|
|
362
|
+
const res = await loopbackSafeFetch(healthUrl, {
|
|
362
363
|
signal: AbortSignal.timeout(3000),
|
|
363
364
|
});
|
|
364
365
|
if (res.ok) {
|
package/src/lib/http-client.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Build the base URL for the daemon HTTP server.
|
|
3
5
|
*/
|
|
@@ -15,7 +17,7 @@ export async function httpHealthCheck(
|
|
|
15
17
|
): Promise<boolean> {
|
|
16
18
|
try {
|
|
17
19
|
const url = `${buildDaemonUrl(port)}/healthz`;
|
|
18
|
-
const response = await
|
|
20
|
+
const response = await loopbackSafeFetch(url, {
|
|
19
21
|
signal: AbortSignal.timeout(timeoutMs),
|
|
20
22
|
});
|
|
21
23
|
return response.ok;
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
resolveRuntimeMigrationUrl,
|
|
10
10
|
resolveRuntimeUrl,
|
|
11
11
|
} from "./runtime-url.js";
|
|
12
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Thrown when the local runtime returns 409 for an export/import request
|
|
@@ -122,7 +123,7 @@ export async function localRuntimeExportToGcs(
|
|
|
122
123
|
body.description = params.description;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
const response = await
|
|
126
|
+
const response = await loopbackSafeFetch(
|
|
126
127
|
resolveRuntimeMigrationUrl(entry, "export-to-gcs"),
|
|
127
128
|
{
|
|
128
129
|
method: "POST",
|
|
@@ -166,7 +167,7 @@ export async function localRuntimeImportFromGcs(
|
|
|
166
167
|
token: string,
|
|
167
168
|
params: { bundleUrl: string },
|
|
168
169
|
): Promise<{ jobId: string }> {
|
|
169
|
-
const response = await
|
|
170
|
+
const response = await loopbackSafeFetch(
|
|
170
171
|
resolveRuntimeMigrationUrl(entry, "import-from-gcs"),
|
|
171
172
|
{
|
|
172
173
|
method: "POST",
|
|
@@ -211,7 +212,7 @@ export async function localRuntimePollJobStatus(
|
|
|
211
212
|
token: string,
|
|
212
213
|
jobId: string,
|
|
213
214
|
): Promise<UnifiedJobStatus> {
|
|
214
|
-
const response = await
|
|
215
|
+
const response = await loopbackSafeFetch(
|
|
215
216
|
resolveRuntimeMigrationUrl(entry, `jobs/${jobId}`),
|
|
216
217
|
{
|
|
217
218
|
headers: await migrationRequestHeaders(entry, token),
|
|
@@ -285,7 +286,7 @@ export async function localRuntimeIdentity(
|
|
|
285
286
|
): Promise<RuntimeIdentity> {
|
|
286
287
|
const url = resolveRuntimeUrl(entry, "health");
|
|
287
288
|
const doRequest = async (): Promise<Response> =>
|
|
288
|
-
|
|
289
|
+
loopbackSafeFetch(url, {
|
|
289
290
|
method: "GET",
|
|
290
291
|
headers: await migrationRequestHeaders(entry, token),
|
|
291
292
|
});
|
package/src/lib/ngrok.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { homedir } from "node:os";
|
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
|
|
13
13
|
import { GATEWAY_PORT } from "./constants";
|
|
14
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
14
15
|
|
|
15
16
|
function getDefaultWorkspaceDir(): string {
|
|
16
17
|
return (
|
|
@@ -78,7 +79,7 @@ export function getNgrokVersion(): string | null {
|
|
|
78
79
|
*/
|
|
79
80
|
async function queryNgrokTunnels(): Promise<NgrokTunnel[] | null> {
|
|
80
81
|
try {
|
|
81
|
-
const res = await
|
|
82
|
+
const res = await loopbackSafeFetch(NGROK_API_URL, {
|
|
82
83
|
signal: AbortSignal.timeout(2_000),
|
|
83
84
|
});
|
|
84
85
|
if (!res.ok) return null;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getPlatformUrl } from "./platform-client.js";
|
|
2
2
|
import { DOCKERHUB_IMAGES } from "./docker.js";
|
|
3
3
|
import type { ServiceName } from "./docker.js";
|
|
4
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
4
5
|
|
|
5
6
|
export interface ResolvedImageRefs {
|
|
6
7
|
imageTags: Record<ServiceName, string>;
|
|
@@ -15,7 +16,7 @@ export interface ResolvedImageRefs {
|
|
|
15
16
|
export async function fetchLatestStableVersion(): Promise<string | null> {
|
|
16
17
|
try {
|
|
17
18
|
const platformUrl = getPlatformUrl();
|
|
18
|
-
const response = await
|
|
19
|
+
const response = await loopbackSafeFetch(`${platformUrl}/v1/releases/?stable=true`, {
|
|
19
20
|
signal: AbortSignal.timeout(10_000),
|
|
20
21
|
});
|
|
21
22
|
if (!response.ok) return null;
|
|
@@ -80,7 +81,7 @@ async function fetchPlatformImageRefs(
|
|
|
80
81
|
|
|
81
82
|
log?.(`Fetching releases from ${url}`);
|
|
82
83
|
|
|
83
|
-
const response = await
|
|
84
|
+
const response = await loopbackSafeFetch(url, {
|
|
84
85
|
signal: AbortSignal.timeout(10_000),
|
|
85
86
|
});
|
|
86
87
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { authHeaders, getPlatformUrl } from "./platform-client.js";
|
|
10
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
10
11
|
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
12
13
|
// Create / Close
|
|
@@ -25,7 +26,7 @@ export async function createTerminalSession(
|
|
|
25
26
|
if (service) {
|
|
26
27
|
body.service = service;
|
|
27
28
|
}
|
|
28
|
-
const response = await
|
|
29
|
+
const response = await loopbackSafeFetch(
|
|
29
30
|
`${baseUrl}/v1/assistants/${assistantId}/terminal/sessions/`,
|
|
30
31
|
{
|
|
31
32
|
method: "POST",
|
|
@@ -49,7 +50,7 @@ export async function closeTerminalSession(
|
|
|
49
50
|
platformUrl?: string,
|
|
50
51
|
): Promise<void> {
|
|
51
52
|
const baseUrl = platformUrl || getPlatformUrl();
|
|
52
|
-
const response = await
|
|
53
|
+
const response = await loopbackSafeFetch(
|
|
53
54
|
`${baseUrl}/v1/assistants/${assistantId}/terminal/sessions/${sessionId}/`,
|
|
54
55
|
{
|
|
55
56
|
method: "DELETE",
|
|
@@ -76,7 +77,7 @@ export async function sendTerminalInput(
|
|
|
76
77
|
platformUrl?: string,
|
|
77
78
|
): Promise<void> {
|
|
78
79
|
const baseUrl = platformUrl || getPlatformUrl();
|
|
79
|
-
const response = await
|
|
80
|
+
const response = await loopbackSafeFetch(
|
|
80
81
|
`${baseUrl}/v1/assistants/${assistantId}/terminal/sessions/${sessionId}/input/`,
|
|
81
82
|
{
|
|
82
83
|
method: "POST",
|
|
@@ -100,7 +101,7 @@ export async function resizeTerminalSession(
|
|
|
100
101
|
platformUrl?: string,
|
|
101
102
|
): Promise<void> {
|
|
102
103
|
const baseUrl = platformUrl || getPlatformUrl();
|
|
103
|
-
const response = await
|
|
104
|
+
const response = await loopbackSafeFetch(
|
|
104
105
|
`${baseUrl}/v1/assistants/${assistantId}/terminal/sessions/${sessionId}/resize/`,
|
|
105
106
|
{
|
|
106
107
|
method: "POST",
|
|
@@ -137,7 +138,7 @@ export async function* subscribeTerminalEvents(
|
|
|
137
138
|
signal?: AbortSignal,
|
|
138
139
|
): AsyncGenerator<TerminalOutputEvent> {
|
|
139
140
|
const baseUrl = platformUrl || getPlatformUrl();
|
|
140
|
-
const response = await
|
|
141
|
+
const response = await loopbackSafeFetch(
|
|
141
142
|
`${baseUrl}/v1/assistants/${assistantId}/terminal/sessions/${sessionId}/events/`,
|
|
142
143
|
{
|
|
143
144
|
headers: await authHeaders(token, platformUrl),
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "./statefulset.js";
|
|
28
28
|
import { exec, execOutput } from "./step-runner.js";
|
|
29
29
|
import { compareVersions } from "./version-compat.js";
|
|
30
|
+
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
30
31
|
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
// Failure log capture
|
|
@@ -274,7 +275,7 @@ export async function fetchCurrentVersion(
|
|
|
274
275
|
runtimeUrl: string,
|
|
275
276
|
): Promise<string | undefined> {
|
|
276
277
|
try {
|
|
277
|
-
const resp = await
|
|
278
|
+
const resp = await loopbackSafeFetch(`${runtimeUrl}/healthz`, {
|
|
278
279
|
signal: AbortSignal.timeout(5000),
|
|
279
280
|
});
|
|
280
281
|
if (resp.ok) {
|
|
@@ -299,7 +300,7 @@ export async function fetchAssistantIngressUrl(
|
|
|
299
300
|
): Promise<string | undefined> {
|
|
300
301
|
if (!bearerToken) return undefined;
|
|
301
302
|
try {
|
|
302
|
-
const resp = await
|
|
303
|
+
const resp = await loopbackSafeFetch(`${runtimeUrl}/integrations/ingress/config`, {
|
|
303
304
|
headers: { Authorization: `Bearer ${bearerToken}` },
|
|
304
305
|
signal: AbortSignal.timeout(5000),
|
|
305
306
|
});
|
|
@@ -341,7 +342,7 @@ export async function fetchPreviousVersion(
|
|
|
341
342
|
try {
|
|
342
343
|
const { getPlatformUrl } = await import("./platform-client.js");
|
|
343
344
|
const platformUrl = getPlatformUrl();
|
|
344
|
-
const resp = await
|
|
345
|
+
const resp = await loopbackSafeFetch(`${platformUrl}/v1/releases/?stable=true`, {
|
|
345
346
|
signal: AbortSignal.timeout(10_000),
|
|
346
347
|
});
|
|
347
348
|
if (!resp.ok) return undefined;
|
|
@@ -373,7 +374,7 @@ export async function waitForReady(runtimeUrl: string): Promise<boolean> {
|
|
|
373
374
|
|
|
374
375
|
while (Date.now() - start < DOCKER_READY_TIMEOUT_MS) {
|
|
375
376
|
try {
|
|
376
|
-
const resp = await
|
|
377
|
+
const resp = await loopbackSafeFetch(readyUrl, {
|
|
377
378
|
signal: AbortSignal.timeout(5000),
|
|
378
379
|
});
|
|
379
380
|
if (resp.ok) {
|
|
@@ -419,7 +420,7 @@ export async function broadcastUpgradeEvent(
|
|
|
419
420
|
if (token?.accessToken) {
|
|
420
421
|
headers["Authorization"] = `Bearer ${token.accessToken}`;
|
|
421
422
|
}
|
|
422
|
-
await
|
|
423
|
+
await loopbackSafeFetch(`${gatewayUrl}/v1/admin/upgrade-broadcast`, {
|
|
423
424
|
method: "POST",
|
|
424
425
|
headers,
|
|
425
426
|
body: JSON.stringify(event),
|
|
@@ -448,7 +449,7 @@ export async function commitWorkspaceViaGateway(
|
|
|
448
449
|
if (token?.accessToken) {
|
|
449
450
|
headers["Authorization"] = `Bearer ${token.accessToken}`;
|
|
450
451
|
}
|
|
451
|
-
await
|
|
452
|
+
await loopbackSafeFetch(`${gatewayUrl}/v1/admin/workspace-commit`, {
|
|
452
453
|
method: "POST",
|
|
453
454
|
headers,
|
|
454
455
|
body: JSON.stringify({ message }),
|
|
@@ -491,7 +492,7 @@ export async function rollbackMigrations(
|
|
|
491
492
|
body.targetWorkspaceMigrationId = targetWorkspaceMigrationId;
|
|
492
493
|
if (rollbackToRegistryCeiling) body.rollbackToRegistryCeiling = true;
|
|
493
494
|
|
|
494
|
-
const resp = await
|
|
495
|
+
const resp = await loopbackSafeFetch(`${gatewayUrl}/v1/admin/rollback-migrations`, {
|
|
495
496
|
method: "POST",
|
|
496
497
|
headers,
|
|
497
498
|
body: JSON.stringify(body),
|
|
@@ -572,7 +573,7 @@ export async function performDockerRollback(
|
|
|
572
573
|
lastWorkspaceMigrationId?: string;
|
|
573
574
|
} = {};
|
|
574
575
|
try {
|
|
575
|
-
const healthResp = await
|
|
576
|
+
const healthResp = await loopbackSafeFetch(
|
|
576
577
|
`${entry.runtimeUrl}/healthz?include=migrations`,
|
|
577
578
|
{ signal: AbortSignal.timeout(5000) },
|
|
578
579
|
);
|