@blaxel/core 0.2.51-preview.124 → 0.2.51

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.
@@ -310,6 +310,22 @@ export const listFunctionRevisions = (options) => {
310
310
  ...options
311
311
  });
312
312
  };
313
+ /**
314
+ * Cleanup unused images
315
+ * Deletes all unused images in the workspace. Only removes images that are not currently being used by any agents, functions, sandboxes, or jobs.
316
+ */
317
+ export const cleanupImages = (options) => {
318
+ return (options?.client ?? _heyApiClient).delete({
319
+ security: [
320
+ {
321
+ scheme: 'bearer',
322
+ type: 'http'
323
+ }
324
+ ],
325
+ url: '/images',
326
+ ...options
327
+ });
328
+ };
313
329
  /**
314
330
  * List images
315
331
  * Returns a list of all images in the workspace grouped by repository with tags.
@@ -918,111 +934,6 @@ export const updatePolicy = (options) => {
918
934
  }
919
935
  });
920
936
  };
921
- /**
922
- * List all private clusters
923
- */
924
- export const listPrivateClusters = (options) => {
925
- return (options?.client ?? _heyApiClient).get({
926
- security: [
927
- {
928
- scheme: 'bearer',
929
- type: 'http'
930
- }
931
- ],
932
- url: '/privateclusters',
933
- ...options
934
- });
935
- };
936
- /**
937
- * Create private cluster
938
- */
939
- export const createPrivateCluster = (options) => {
940
- return (options?.client ?? _heyApiClient).post({
941
- security: [
942
- {
943
- scheme: 'bearer',
944
- type: 'http'
945
- }
946
- ],
947
- url: '/privateclusters',
948
- ...options
949
- });
950
- };
951
- /**
952
- * Delete private cluster
953
- */
954
- export const deletePrivateCluster = (options) => {
955
- return (options.client ?? _heyApiClient).delete({
956
- security: [
957
- {
958
- scheme: 'bearer',
959
- type: 'http'
960
- }
961
- ],
962
- url: '/privateclusters/{privateClusterName}',
963
- ...options
964
- });
965
- };
966
- /**
967
- * Get private cluster by name
968
- */
969
- export const getPrivateCluster = (options) => {
970
- return (options.client ?? _heyApiClient).get({
971
- security: [
972
- {
973
- scheme: 'bearer',
974
- type: 'http'
975
- }
976
- ],
977
- url: '/privateclusters/{privateClusterName}',
978
- ...options
979
- });
980
- };
981
- /**
982
- * Update private cluster
983
- */
984
- export const updatePrivateCluster = (options) => {
985
- return (options.client ?? _heyApiClient).put({
986
- security: [
987
- {
988
- scheme: 'bearer',
989
- type: 'http'
990
- }
991
- ],
992
- url: '/privateclusters/{privateClusterName}',
993
- ...options
994
- });
995
- };
996
- /**
997
- * Get private cluster health
998
- */
999
- export const getPrivateClusterHealth = (options) => {
1000
- return (options.client ?? _heyApiClient).get({
1001
- security: [
1002
- {
1003
- scheme: 'bearer',
1004
- type: 'http'
1005
- }
1006
- ],
1007
- url: '/privateclusters/{privateClusterName}/health',
1008
- ...options
1009
- });
1010
- };
1011
- /**
1012
- * Update private cluster health
1013
- */
1014
- export const updatePrivateClusterHealth = (options) => {
1015
- return (options.client ?? _heyApiClient).post({
1016
- security: [
1017
- {
1018
- scheme: 'bearer',
1019
- type: 'http'
1020
- }
1021
- ],
1022
- url: '/privateclusters/{privateClusterName}/health',
1023
- ...options
1024
- });
1025
- };
1026
937
  /**
1027
938
  * List pending invitations
1028
939
  * Returns a list of all pending invitations in the workspace.
@@ -7,7 +7,7 @@ function getPackageVersion() {
7
7
  if (typeof require !== "undefined") {
8
8
  // Try to require package.json (Node.js only, gracefully fails in browser)
9
9
  // eslint-disable-next-line @typescript-eslint/no-require-imports
10
- const packageJson = {"version":"0.2.51-preview.124","commit":"89ed97c2d80630cf187a32173959949d29a59153"};
10
+ const packageJson = {"version":"0.2.51","commit":"3853140a51897f5f5d076412f419c105d7f968ab"};
11
11
  return packageJson.version || "unknown";
12
12
  }
13
13
  else {
@@ -59,7 +59,7 @@ function getCommitHash() {
59
59
  if (typeof require !== "undefined") {
60
60
  // Try to require package.json and look for commit field (set during build)
61
61
  // eslint-disable-next-line @typescript-eslint/no-require-imports
62
- const packageJson = {"version":"0.2.51-preview.124","commit":"89ed97c2d80630cf187a32173959949d29a59153"};
62
+ const packageJson = {"version":"0.2.51","commit":"3853140a51897f5f5d076412f419c105d7f968ab"};
63
63
  // Check for commit in various possible locations
64
64
  const commit = packageJson.commit || packageJson.buildInfo?.commit;
65
65
  if (commit) {
@@ -1,7 +1,8 @@
1
+ import { createJobExecution, deleteJobExecution, getJobExecution, listJobExecutions, } from "../client/index.js";
1
2
  import { getForcedUrl, getGlobalUniqueHash } from "../common/internal.js";
2
3
  import { logger } from "../common/logger.js";
3
4
  import { settings } from "../common/settings.js";
4
- import { startSpan } from '../telemetry/telemetry.js';
5
+ import { startSpan } from "../telemetry/telemetry.js";
5
6
  class BlJob {
6
7
  jobName;
7
8
  constructor(jobName) {
@@ -21,7 +22,7 @@ class BlJob {
21
22
  return new URL(`${settings.runInternalProtocol}://bl-${settings.env}-${hash}.${settings.runInternalHostname}`);
22
23
  }
23
24
  get forcedUrl() {
24
- return getForcedUrl('job', this.jobName);
25
+ return getForcedUrl("job", this.jobName);
25
26
  }
26
27
  get url() {
27
28
  if (this.forcedUrl)
@@ -32,7 +33,7 @@ class BlJob {
32
33
  }
33
34
  async call(url, tasks) {
34
35
  const body = {
35
- tasks: tasks
36
+ tasks: tasks,
36
37
  };
37
38
  const response = await fetch(url.toString() + "/executions", {
38
39
  method: "POST",
@@ -80,6 +81,105 @@ class BlJob {
80
81
  span.end();
81
82
  }
82
83
  }
84
+ /**
85
+ * Create a new execution for this job and return the execution ID
86
+ */
87
+ async createExecution(request) {
88
+ logger.debug(`Creating execution for job: ${this.jobName}`);
89
+ const { data } = await createJobExecution({
90
+ path: {
91
+ jobId: this.jobName,
92
+ },
93
+ body: request,
94
+ headers: settings.headers,
95
+ throwOnError: true,
96
+ });
97
+ const response = data;
98
+ if (!response?.executionId) {
99
+ throw new Error("No execution ID returned from create job execution");
100
+ }
101
+ logger.debug(`Created execution: ${response.executionId}`);
102
+ return response.executionId;
103
+ }
104
+ /**
105
+ * Get a specific execution by ID
106
+ */
107
+ async getExecution(executionId) {
108
+ logger.debug(`Getting execution ${executionId} for job: ${this.jobName}`);
109
+ const { data } = await getJobExecution({
110
+ path: {
111
+ jobId: this.jobName,
112
+ executionId: executionId,
113
+ },
114
+ headers: settings.headers,
115
+ throwOnError: true,
116
+ });
117
+ if (!data) {
118
+ throw new Error(`Execution '${executionId}' not found for job '${this.jobName}'`);
119
+ }
120
+ return data;
121
+ }
122
+ /**
123
+ * List all executions for this job
124
+ */
125
+ async listExecutions() {
126
+ logger.debug(`Listing executions for job: ${this.jobName}`);
127
+ const { data } = await listJobExecutions({
128
+ path: {
129
+ jobId: this.jobName,
130
+ },
131
+ headers: settings.headers,
132
+ throwOnError: true,
133
+ });
134
+ return data ?? [];
135
+ }
136
+ /**
137
+ * Get the status of a specific execution
138
+ */
139
+ async getExecutionStatus(executionId) {
140
+ const execution = await this.getExecution(executionId);
141
+ return execution.status ?? "UNKNOWN";
142
+ }
143
+ /**
144
+ * Cancel a specific execution
145
+ */
146
+ async cancelExecution(executionId) {
147
+ logger.debug(`Cancelling execution ${executionId} for job: ${this.jobName}`);
148
+ await deleteJobExecution({
149
+ path: {
150
+ jobId: this.jobName,
151
+ executionId: executionId,
152
+ },
153
+ headers: settings.headers,
154
+ throwOnError: true,
155
+ });
156
+ }
157
+ /**
158
+ * Wait for an execution to complete
159
+ * @param executionId The execution ID to wait for
160
+ * @param options.maxWait Maximum time to wait in milliseconds (default: 6 minutes)
161
+ * @param options.interval Polling interval in milliseconds (default: 3 seconds)
162
+ */
163
+ async waitForExecution(executionId, options = {}) {
164
+ const maxWait = options.maxWait ?? 360000; // 6 minutes default (jobs typically run for 5 minutes)
165
+ const interval = options.interval ?? 3000; // 3 seconds default
166
+ const startTime = Date.now();
167
+ logger.debug(`Waiting for execution ${executionId} to complete (max ${maxWait}ms)`);
168
+ while (Date.now() - startTime < maxWait) {
169
+ const execution = await this.getExecution(executionId);
170
+ const status = execution.status;
171
+ // Terminal states (Kubernetes-style: succeeded, failed, cancelled)
172
+ if (status === "succeeded" ||
173
+ status === "failed" ||
174
+ status === "cancelled") {
175
+ logger.debug(`Execution ${executionId} finished with status: ${status}`);
176
+ return execution;
177
+ }
178
+ // Wait before polling again
179
+ await new Promise((resolve) => setTimeout(resolve, interval));
180
+ }
181
+ throw new Error(`Execution ${executionId} did not complete within ${maxWait}ms`);
182
+ }
83
183
  }
84
184
  export const blJob = (jobName) => {
85
185
  return new BlJob(jobName);