@axiom-lattice/client-sdk 3.0.6 → 4.0.1

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.
Files changed (46) hide show
  1. package/README.md +37 -0
  2. package/dist/__tests__/a2a-keys.test.d.ts +8 -0
  3. package/dist/__tests__/a2a-keys.test.d.ts.map +1 -0
  4. package/dist/__tests__/a2a-keys.test.js +110 -0
  5. package/dist/__tests__/a2a-keys.test.js.map +1 -0
  6. package/dist/__tests__/export-import.test.d.ts +2 -0
  7. package/dist/__tests__/export-import.test.d.ts.map +1 -0
  8. package/dist/__tests__/export-import.test.js +245 -0
  9. package/dist/__tests__/export-import.test.js.map +1 -0
  10. package/dist/__tests__/tasks.test.d.ts +2 -0
  11. package/dist/__tests__/tasks.test.d.ts.map +1 -0
  12. package/dist/__tests__/tasks.test.js +67 -0
  13. package/dist/__tests__/tasks.test.js.map +1 -0
  14. package/dist/__tests__/web-apps.test.d.ts +8 -0
  15. package/dist/__tests__/web-apps.test.d.ts.map +1 -0
  16. package/dist/__tests__/web-apps.test.js +166 -0
  17. package/dist/__tests__/web-apps.test.js.map +1 -0
  18. package/dist/__tests__/workspace-client.test.d.ts +10 -0
  19. package/dist/__tests__/workspace-client.test.d.ts.map +1 -0
  20. package/dist/__tests__/workspace-client.test.js +56 -0
  21. package/dist/__tests__/workspace-client.test.js.map +1 -0
  22. package/dist/abstract-client.d.ts +106 -2
  23. package/dist/abstract-client.d.ts.map +1 -1
  24. package/dist/abstract-client.js +170 -3
  25. package/dist/abstract-client.js.map +1 -1
  26. package/dist/client.d.ts +2 -0
  27. package/dist/client.d.ts.map +1 -1
  28. package/dist/client.js +2 -0
  29. package/dist/client.js.map +1 -1
  30. package/dist/export-import.d.ts +136 -24
  31. package/dist/export-import.d.ts.map +1 -1
  32. package/dist/export-import.js +142 -48
  33. package/dist/export-import.js.map +1 -1
  34. package/dist/index.d.ts +322 -35
  35. package/dist/index.js +359 -96
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +359 -96
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/types.d.ts +72 -1
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/types.js.map +1 -1
  42. package/dist/workspace-client.d.ts +2 -2
  43. package/dist/workspace-client.d.ts.map +1 -1
  44. package/dist/workspace-client.js +7 -2
  45. package/dist/workspace-client.js.map +1 -1
  46. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -2153,6 +2153,157 @@ var AbstractClient = class {
2153
2153
  }
2154
2154
  }
2155
2155
  };
2156
+ /**
2157
+ * A2A API keys namespace for managing A2A API keys
2158
+ */
2159
+ this.a2aKeys = {
2160
+ /**
2161
+ * Lists A2A API keys, optionally filtered by tenant
2162
+ * Key values are masked in list responses
2163
+ * @param params - Optional tenant filter and pagination
2164
+ * @returns A promise that resolves to the list of key records and total
2165
+ */
2166
+ list: async (params) => {
2167
+ const searchParams = new URLSearchParams();
2168
+ if (params?.tenantId)
2169
+ searchParams.set("tenantId", params.tenantId);
2170
+ if (params?.limit !== void 0)
2171
+ searchParams.set("limit", String(params.limit));
2172
+ if (params?.offset !== void 0)
2173
+ searchParams.set("offset", String(params.offset));
2174
+ const qs = searchParams.toString();
2175
+ const response = await this.makeRequest(`/api/a2a/keys${qs ? `?${qs}` : ""}`);
2176
+ return response.data;
2177
+ },
2178
+ /**
2179
+ * Creates a new A2A API key
2180
+ * The full key value is returned only from this call
2181
+ * @param input - Key creation input (tenant, project, optional assistant whitelist and label)
2182
+ * @returns A promise that resolves to the created key record (full key value)
2183
+ */
2184
+ create: async (input) => {
2185
+ const response = await this.makeRequest("/api/a2a/keys", { method: "POST", body: input });
2186
+ return response.data;
2187
+ },
2188
+ /**
2189
+ * Permanently deletes an A2A API key
2190
+ * @param id - Key identifier
2191
+ * @returns A promise that resolves when the key is deleted
2192
+ */
2193
+ delete: async (id) => {
2194
+ await this.makeRequest(`/api/a2a/keys/${id}`, {
2195
+ method: "DELETE"
2196
+ });
2197
+ },
2198
+ /**
2199
+ * Disables an A2A API key
2200
+ * @param id - Key identifier
2201
+ * @returns A promise that resolves to the updated key record
2202
+ */
2203
+ disable: async (id) => {
2204
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/disable`, { method: "POST" });
2205
+ return response.data;
2206
+ },
2207
+ /**
2208
+ * Enables a previously disabled A2A API key
2209
+ * @param id - Key identifier
2210
+ * @returns A promise that resolves to the updated key record
2211
+ */
2212
+ enable: async (id) => {
2213
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/enable`, { method: "POST" });
2214
+ return response.data;
2215
+ },
2216
+ /**
2217
+ * Rotates an A2A API key, generating a new key value
2218
+ * The full new key value is returned only from this call
2219
+ * @param id - Key identifier
2220
+ * @returns A promise that resolves to the updated key record (full new key value)
2221
+ */
2222
+ rotate: async (id) => {
2223
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/rotate`, { method: "POST" });
2224
+ return response.data;
2225
+ }
2226
+ };
2227
+ /** Agent Web Apps namespace for managing React SDK publications. */
2228
+ this.webApps = {
2229
+ /**
2230
+ * Lists Agent Web Apps, optionally filtered by assistant.
2231
+ * @param params - Optional assistant filter
2232
+ * @returns A promise that resolves to the publication records and total
2233
+ */
2234
+ list: async (params) => {
2235
+ const searchParams = new URLSearchParams();
2236
+ if (params?.assistantId) {
2237
+ searchParams.set("assistantId", params.assistantId);
2238
+ }
2239
+ const query = searchParams.toString();
2240
+ const response = await this.makeRequest(`/api/web-apps${query ? `?${query}` : ""}`);
2241
+ return {
2242
+ records: response.data.records.map((record) => this.hydrateAgentWebApp(record)),
2243
+ total: response.data.total
2244
+ };
2245
+ },
2246
+ /**
2247
+ * Retrieves an Agent Web App by ID.
2248
+ * @param id - Agent Web App identifier
2249
+ * @returns A promise that resolves to the publication
2250
+ */
2251
+ get: async (id) => {
2252
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}`);
2253
+ return this.hydrateAgentWebApp(response.data);
2254
+ },
2255
+ /**
2256
+ * Creates an Agent Web App.
2257
+ * @param input - Publication configuration
2258
+ * @returns A promise that resolves to the created publication
2259
+ */
2260
+ create: async (input) => {
2261
+ const response = await this.makeRequest("/api/web-apps", { method: "POST", body: input });
2262
+ return this.hydrateAgentWebApp(response.data);
2263
+ },
2264
+ /**
2265
+ * Updates editable fields on an Agent Web App.
2266
+ * @param id - Agent Web App identifier
2267
+ * @param input - Fields to update
2268
+ * @returns A promise that resolves to the updated publication
2269
+ */
2270
+ update: async (id, input) => {
2271
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}`, {
2272
+ method: "PATCH",
2273
+ body: input
2274
+ });
2275
+ return this.hydrateAgentWebApp(response.data);
2276
+ },
2277
+ /**
2278
+ * Enables an Agent Web App.
2279
+ * @param id - Agent Web App identifier
2280
+ * @returns A promise that resolves to the enabled publication
2281
+ */
2282
+ enable: async (id) => {
2283
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}/enable`, { method: "POST" });
2284
+ return this.hydrateAgentWebApp(response.data);
2285
+ },
2286
+ /**
2287
+ * Disables an Agent Web App.
2288
+ * @param id - Agent Web App identifier
2289
+ * @returns A promise that resolves to the disabled publication
2290
+ */
2291
+ disable: async (id) => {
2292
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}/disable`, { method: "POST" });
2293
+ return this.hydrateAgentWebApp(response.data);
2294
+ },
2295
+ /**
2296
+ * Permanently deletes an Agent Web App.
2297
+ * @param id - Agent Web App identifier
2298
+ * @returns A promise that resolves when the publication is deleted
2299
+ */
2300
+ delete: async (id) => {
2301
+ await this.makeRequest(
2302
+ `/api/web-apps/${encodeURIComponent(id)}`,
2303
+ { method: "DELETE" }
2304
+ );
2305
+ }
2306
+ };
2156
2307
  /**
2157
2308
  * Skills namespace for managing skills
2158
2309
  */
@@ -2673,11 +2824,11 @@ var AbstractClient = class {
2673
2824
  delete: async (id) => {
2674
2825
  await this.makeRequest(`/api/tasks/${id}`, { method: "DELETE" });
2675
2826
  },
2676
- complete: async (id) => {
2677
- const response = await this.makeRequest(`/api/tasks/${id}/complete`, { method: "PATCH" });
2827
+ complete: async (id, data) => {
2828
+ const response = await this.makeRequest(`/api/tasks/${id}/complete`, { method: "PATCH", body: data });
2678
2829
  if (!response.data)
2679
2830
  throw new ApiError("Failed to complete task", 500);
2680
- return response.data;
2831
+ return response;
2681
2832
  },
2682
2833
  workItems: {
2683
2834
  list: async (taskId, params) => {
@@ -2725,6 +2876,27 @@ var AbstractClient = class {
2725
2876
  }
2726
2877
  };
2727
2878
  }
2879
+ hydrateAgentWebApp(value) {
2880
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2881
+ throw new ApiError("Invalid Agent Web App response", 500, value);
2882
+ }
2883
+ const record = value;
2884
+ const hydrateDate = (field) => {
2885
+ const raw = record[field];
2886
+ const date = raw instanceof Date ? new Date(raw.getTime()) : new Date(
2887
+ typeof raw === "string" || typeof raw === "number" ? raw : Number.NaN
2888
+ );
2889
+ if (Number.isNaN(date.getTime())) {
2890
+ throw new ApiError(`Invalid Agent Web App ${field}`, 500, value);
2891
+ }
2892
+ return date;
2893
+ };
2894
+ return {
2895
+ ...record,
2896
+ createdAt: hydrateDate("createdAt"),
2897
+ updatedAt: hydrateDate("updatedAt")
2898
+ };
2899
+ }
2728
2900
  /**
2729
2901
  * Set handler for 401 unauthorized errors
2730
2902
  * @param handler - Callback function to handle unauthorized errors
@@ -2984,6 +3156,182 @@ var ResourcesClient = class {
2984
3156
  }
2985
3157
  };
2986
3158
 
3159
+ // src/export-import.ts
3160
+ function base64ToBytes(base64) {
3161
+ if (typeof globalThis.atob === "function") {
3162
+ const binary = globalThis.atob(base64);
3163
+ const bytes = new Uint8Array(binary.length);
3164
+ for (let index = 0; index < binary.length; index += 1) {
3165
+ bytes[index] = binary.charCodeAt(index);
3166
+ }
3167
+ return bytes;
3168
+ }
3169
+ return new Uint8Array(Buffer.from(base64, "base64"));
3170
+ }
3171
+ function bytesToArrayBuffer(bytes) {
3172
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
3173
+ }
3174
+ async function archiveToBlob(archive) {
3175
+ if (typeof archive === "string") {
3176
+ return {
3177
+ blob: new Blob([bytesToArrayBuffer(base64ToBytes(archive))], { type: "application/gzip" }),
3178
+ filename: "tenant-import.tar.gz"
3179
+ };
3180
+ }
3181
+ if (archive instanceof Blob) {
3182
+ const filename = "name" in archive && typeof archive.name === "string" ? archive.name : "tenant-import.tar.gz";
3183
+ return { blob: archive, filename };
3184
+ }
3185
+ const bytes = archive instanceof Uint8Array ? archive : archive instanceof ArrayBuffer ? new Uint8Array(archive) : new Uint8Array(await archive.arrayBuffer());
3186
+ return {
3187
+ blob: new Blob([bytesToArrayBuffer(bytes)], { type: "application/gzip" }),
3188
+ filename: "tenant-import.tar.gz"
3189
+ };
3190
+ }
3191
+ function attachmentFilename(contentDisposition) {
3192
+ if (!contentDisposition)
3193
+ return "tenant-export.tar.gz";
3194
+ const encoded = contentDisposition.match(/filename\*=UTF-8''([^;]+)/i)?.[1];
3195
+ if (encoded) {
3196
+ try {
3197
+ return decodeURIComponent(encoded);
3198
+ } catch {
3199
+ return encoded;
3200
+ }
3201
+ }
3202
+ return contentDisposition.match(/filename="([^"]+)"/i)?.[1] ?? contentDisposition.match(/filename=([^;\s]+)/i)?.[1] ?? "tenant-export.tar.gz";
3203
+ }
3204
+ var ExportImportClient = class {
3205
+ /**
3206
+ * Creates an export/import client.
3207
+ *
3208
+ * @param config - Base client configuration.
3209
+ * @param headerProvider - Optional provider for headers that change after construction.
3210
+ */
3211
+ constructor(config, headerProvider) {
3212
+ this.baseURL = config.baseURL;
3213
+ this.headers = {
3214
+ "Content-Type": "application/json",
3215
+ Authorization: `Bearer ${config.apiKey}`,
3216
+ ...config.headers
3217
+ };
3218
+ this.headerProvider = headerProvider;
3219
+ }
3220
+ async request(url, options = {}) {
3221
+ const headers = {
3222
+ ...this.headers,
3223
+ ...this.headerProvider?.(),
3224
+ ...options.headers
3225
+ };
3226
+ if (options.body instanceof FormData) {
3227
+ for (const name of Object.keys(headers)) {
3228
+ if (name.toLowerCase() === "content-type")
3229
+ delete headers[name];
3230
+ }
3231
+ }
3232
+ const response = await fetch(`${this.baseURL}${url}`, {
3233
+ method: options.method ?? "GET",
3234
+ ...options,
3235
+ headers
3236
+ });
3237
+ const envelope = await response.json().catch(() => ({}));
3238
+ if (!response.ok || envelope.success === false) {
3239
+ throw new Error(
3240
+ envelope.message || envelope.error || `HTTP error! Status: ${response.status}`
3241
+ );
3242
+ }
3243
+ if (envelope.data === void 0) {
3244
+ throw new Error(envelope.message || envelope.error || "API response contained no data");
3245
+ }
3246
+ return envelope.data;
3247
+ }
3248
+ /** Returns all entity types registered for export. */
3249
+ getExportableTypes() {
3250
+ return this.request("/api/tenants/exportable-types");
3251
+ }
3252
+ /** Starts an export or returns dependencies requiring confirmation. */
3253
+ exportConfig(tenantId, entityTypes, entityIds) {
3254
+ return this.request(`/api/tenants/${tenantId}/export`, {
3255
+ method: "POST",
3256
+ body: JSON.stringify({ entityTypes, ...entityIds ? { entityIds } : {} })
3257
+ });
3258
+ }
3259
+ /** Starts an export after confirming dependency additions. */
3260
+ exportConfigConfirm(tenantId, entityTypes, entityIds) {
3261
+ return this.request(`/api/tenants/${tenantId}/export/confirm`, {
3262
+ method: "POST",
3263
+ body: JSON.stringify({ entityTypes, ...entityIds ? { entityIds } : {} })
3264
+ });
3265
+ }
3266
+ /** Lists selectable entities for the requested export types. */
3267
+ previewEntities(tenantId, entityTypes) {
3268
+ return this.request(
3269
+ `/api/tenants/${tenantId}/export/entities`,
3270
+ { method: "POST", body: JSON.stringify({ entityTypes }) }
3271
+ );
3272
+ }
3273
+ /** Returns the gateway URL for an export download job. */
3274
+ getExportDownloadUrl(tenantId, jobId) {
3275
+ return `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`;
3276
+ }
3277
+ /** Downloads an export archive as raw bytes. */
3278
+ async downloadExport(tenantId, jobId) {
3279
+ const response = await fetch(
3280
+ `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`,
3281
+ {
3282
+ method: "GET",
3283
+ headers: {
3284
+ ...this.headers,
3285
+ ...this.headerProvider?.()
3286
+ }
3287
+ }
3288
+ );
3289
+ if (!response.ok) {
3290
+ const envelope = await response.json().catch(() => ({}));
3291
+ throw new Error(
3292
+ envelope.message || envelope.error || `HTTP error! Status: ${response.status}`
3293
+ );
3294
+ }
3295
+ return {
3296
+ filename: attachmentFilename(response.headers.get("Content-Disposition")),
3297
+ data: new Uint8Array(await response.arrayBuffer())
3298
+ };
3299
+ }
3300
+ /** Previews an archive or plain JSON bundle import. */
3301
+ async importPreview(tenantId, source) {
3302
+ if (source.archive !== void 0) {
3303
+ const form = new FormData();
3304
+ const { blob, filename } = await archiveToBlob(source.archive);
3305
+ form.append("file", blob, filename);
3306
+ return this.request(`/api/tenants/${tenantId}/import/preview`, {
3307
+ method: "POST",
3308
+ body: form
3309
+ });
3310
+ }
3311
+ return this.request(`/api/tenants/${tenantId}/import/preview`, {
3312
+ method: "POST",
3313
+ body: JSON.stringify({ bundle: source.bundle })
3314
+ });
3315
+ }
3316
+ /** Applies an archive or plain JSON bundle import with conflict resolutions. */
3317
+ async importApply(tenantId, source, resolutions) {
3318
+ if (source.archive !== void 0) {
3319
+ const form = new FormData();
3320
+ const { blob, filename } = await archiveToBlob(source.archive);
3321
+ form.append("file", blob, filename);
3322
+ form.append("resolutions", JSON.stringify(resolutions));
3323
+ return this.request(`/api/tenants/${tenantId}/import/apply`, {
3324
+ method: "POST",
3325
+ body: form
3326
+ });
3327
+ }
3328
+ return this.request(`/api/tenants/${tenantId}/import/apply`, {
3329
+ method: "POST",
3330
+ body: JSON.stringify({ bundle: source.bundle, resolutions })
3331
+ });
3332
+ }
3333
+ };
3334
+
2987
3335
  // src/client.ts
2988
3336
  var _Client = class extends AbstractClient {
2989
3337
  /**
@@ -2998,6 +3346,7 @@ var _Client = class extends AbstractClient {
2998
3346
  ...this.config.headers
2999
3347
  };
3000
3348
  this.resources = new ResourcesClient(this.config.baseURL, () => this.getAllHeaders());
3349
+ this.exportImport = new ExportImportClient(this.config, () => this.getAllHeaders());
3001
3350
  }
3002
3351
  /**
3003
3352
  * Helper method to handle fetch responses and errors
@@ -3758,9 +4107,14 @@ var WorkspaceClient = class {
3758
4107
  });
3759
4108
  }
3760
4109
  // ==================== Project CRUD ====================
3761
- async listProjects(workspaceId) {
4110
+ async listProjects(workspaceId, kind) {
4111
+ const params = new URLSearchParams();
4112
+ if (kind) {
4113
+ params.set("kind", kind);
4114
+ }
4115
+ const qs = params.toString();
3762
4116
  const response = await this.request(
3763
- `/api/workspaces/${workspaceId}/projects`
4117
+ `/api/workspaces/${workspaceId}/projects${qs ? `?${qs}` : ""}`
3764
4118
  );
3765
4119
  return response.data || [];
3766
4120
  }
@@ -3899,97 +4253,6 @@ var WorkspaceClient = class {
3899
4253
  }
3900
4254
  };
3901
4255
 
3902
- // src/export-import.ts
3903
- var ExportImportClient = class {
3904
- constructor(config) {
3905
- this.baseURL = config.baseURL;
3906
- this.headers = {
3907
- "Content-Type": "application/json",
3908
- Authorization: `Bearer ${config.apiKey}`,
3909
- ...config.headers
3910
- };
3911
- }
3912
- async request(url, options = {}) {
3913
- const fullUrl = `${this.baseURL}${url}`;
3914
- const response = await fetch(fullUrl, {
3915
- ...options,
3916
- headers: {
3917
- ...this.headers,
3918
- ...options.headers
3919
- }
3920
- });
3921
- if (!response.ok) {
3922
- const err = await response.json().catch(() => ({}));
3923
- throw new Error(
3924
- err.message || `HTTP error! Status: ${response.status}`
3925
- );
3926
- }
3927
- return response.json();
3928
- }
3929
- async getExportableTypes() {
3930
- const response = await this.request(
3931
- "/api/tenants/exportable-types"
3932
- );
3933
- return response.data || [];
3934
- }
3935
- async exportConfig(tenantId, entityTypes) {
3936
- const response = await this.request(
3937
- `/api/tenants/${tenantId}/export`,
3938
- {
3939
- method: "POST",
3940
- body: JSON.stringify({ entityTypes })
3941
- }
3942
- );
3943
- return response.data;
3944
- }
3945
- async exportConfigConfirm(tenantId, entityTypes) {
3946
- const response = await this.request(
3947
- `/api/tenants/${tenantId}/export/confirm`,
3948
- {
3949
- method: "POST",
3950
- body: JSON.stringify({ entityTypes })
3951
- }
3952
- );
3953
- return response.data;
3954
- }
3955
- getExportDownloadUrl(tenantId, jobId) {
3956
- return `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`;
3957
- }
3958
- async importPreview(tenantId, file) {
3959
- const formData = new FormData();
3960
- formData.append("file", file);
3961
- const fullUrl = `${this.baseURL}/api/tenants/${tenantId}/import/preview`;
3962
- const headers = { ...this.headers };
3963
- delete headers["Content-Type"];
3964
- const response = await fetch(fullUrl, {
3965
- method: "POST",
3966
- headers,
3967
- body: formData
3968
- });
3969
- if (!response.ok) {
3970
- const err = await response.json().catch(() => ({}));
3971
- throw new Error(
3972
- err.message || `HTTP error! Status: ${response.status}`
3973
- );
3974
- }
3975
- const json = await response.json();
3976
- if (!json.success || !json.data) {
3977
- throw new Error(json.error || "Import preview failed");
3978
- }
3979
- return json.data;
3980
- }
3981
- async importApply(tenantId, bundle, resolutions) {
3982
- const response = await this.request(
3983
- `/api/tenants/${tenantId}/import/apply`,
3984
- {
3985
- method: "POST",
3986
- body: JSON.stringify({ bundle, resolutions })
3987
- }
3988
- );
3989
- return response.data;
3990
- }
3991
- };
3992
-
3993
4256
  // src/ChunkMessageMerger.ts
3994
4257
  var import_best_effort_json_parser = require("best-effort-json-parser");
3995
4258
  function createSimpleMessageMerger() {