@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.mjs CHANGED
@@ -2129,6 +2129,157 @@ var AbstractClient = class {
2129
2129
  }
2130
2130
  }
2131
2131
  };
2132
+ /**
2133
+ * A2A API keys namespace for managing A2A API keys
2134
+ */
2135
+ this.a2aKeys = {
2136
+ /**
2137
+ * Lists A2A API keys, optionally filtered by tenant
2138
+ * Key values are masked in list responses
2139
+ * @param params - Optional tenant filter and pagination
2140
+ * @returns A promise that resolves to the list of key records and total
2141
+ */
2142
+ list: async (params) => {
2143
+ const searchParams = new URLSearchParams();
2144
+ if (params?.tenantId)
2145
+ searchParams.set("tenantId", params.tenantId);
2146
+ if (params?.limit !== void 0)
2147
+ searchParams.set("limit", String(params.limit));
2148
+ if (params?.offset !== void 0)
2149
+ searchParams.set("offset", String(params.offset));
2150
+ const qs = searchParams.toString();
2151
+ const response = await this.makeRequest(`/api/a2a/keys${qs ? `?${qs}` : ""}`);
2152
+ return response.data;
2153
+ },
2154
+ /**
2155
+ * Creates a new A2A API key
2156
+ * The full key value is returned only from this call
2157
+ * @param input - Key creation input (tenant, project, optional assistant whitelist and label)
2158
+ * @returns A promise that resolves to the created key record (full key value)
2159
+ */
2160
+ create: async (input) => {
2161
+ const response = await this.makeRequest("/api/a2a/keys", { method: "POST", body: input });
2162
+ return response.data;
2163
+ },
2164
+ /**
2165
+ * Permanently deletes an A2A API key
2166
+ * @param id - Key identifier
2167
+ * @returns A promise that resolves when the key is deleted
2168
+ */
2169
+ delete: async (id) => {
2170
+ await this.makeRequest(`/api/a2a/keys/${id}`, {
2171
+ method: "DELETE"
2172
+ });
2173
+ },
2174
+ /**
2175
+ * Disables an A2A API key
2176
+ * @param id - Key identifier
2177
+ * @returns A promise that resolves to the updated key record
2178
+ */
2179
+ disable: async (id) => {
2180
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/disable`, { method: "POST" });
2181
+ return response.data;
2182
+ },
2183
+ /**
2184
+ * Enables a previously disabled A2A API key
2185
+ * @param id - Key identifier
2186
+ * @returns A promise that resolves to the updated key record
2187
+ */
2188
+ enable: async (id) => {
2189
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/enable`, { method: "POST" });
2190
+ return response.data;
2191
+ },
2192
+ /**
2193
+ * Rotates an A2A API key, generating a new key value
2194
+ * The full new key value is returned only from this call
2195
+ * @param id - Key identifier
2196
+ * @returns A promise that resolves to the updated key record (full new key value)
2197
+ */
2198
+ rotate: async (id) => {
2199
+ const response = await this.makeRequest(`/api/a2a/keys/${id}/rotate`, { method: "POST" });
2200
+ return response.data;
2201
+ }
2202
+ };
2203
+ /** Agent Web Apps namespace for managing React SDK publications. */
2204
+ this.webApps = {
2205
+ /**
2206
+ * Lists Agent Web Apps, optionally filtered by assistant.
2207
+ * @param params - Optional assistant filter
2208
+ * @returns A promise that resolves to the publication records and total
2209
+ */
2210
+ list: async (params) => {
2211
+ const searchParams = new URLSearchParams();
2212
+ if (params?.assistantId) {
2213
+ searchParams.set("assistantId", params.assistantId);
2214
+ }
2215
+ const query = searchParams.toString();
2216
+ const response = await this.makeRequest(`/api/web-apps${query ? `?${query}` : ""}`);
2217
+ return {
2218
+ records: response.data.records.map((record) => this.hydrateAgentWebApp(record)),
2219
+ total: response.data.total
2220
+ };
2221
+ },
2222
+ /**
2223
+ * Retrieves an Agent Web App by ID.
2224
+ * @param id - Agent Web App identifier
2225
+ * @returns A promise that resolves to the publication
2226
+ */
2227
+ get: async (id) => {
2228
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}`);
2229
+ return this.hydrateAgentWebApp(response.data);
2230
+ },
2231
+ /**
2232
+ * Creates an Agent Web App.
2233
+ * @param input - Publication configuration
2234
+ * @returns A promise that resolves to the created publication
2235
+ */
2236
+ create: async (input) => {
2237
+ const response = await this.makeRequest("/api/web-apps", { method: "POST", body: input });
2238
+ return this.hydrateAgentWebApp(response.data);
2239
+ },
2240
+ /**
2241
+ * Updates editable fields on an Agent Web App.
2242
+ * @param id - Agent Web App identifier
2243
+ * @param input - Fields to update
2244
+ * @returns A promise that resolves to the updated publication
2245
+ */
2246
+ update: async (id, input) => {
2247
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}`, {
2248
+ method: "PATCH",
2249
+ body: input
2250
+ });
2251
+ return this.hydrateAgentWebApp(response.data);
2252
+ },
2253
+ /**
2254
+ * Enables an Agent Web App.
2255
+ * @param id - Agent Web App identifier
2256
+ * @returns A promise that resolves to the enabled publication
2257
+ */
2258
+ enable: async (id) => {
2259
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}/enable`, { method: "POST" });
2260
+ return this.hydrateAgentWebApp(response.data);
2261
+ },
2262
+ /**
2263
+ * Disables an Agent Web App.
2264
+ * @param id - Agent Web App identifier
2265
+ * @returns A promise that resolves to the disabled publication
2266
+ */
2267
+ disable: async (id) => {
2268
+ const response = await this.makeRequest(`/api/web-apps/${encodeURIComponent(id)}/disable`, { method: "POST" });
2269
+ return this.hydrateAgentWebApp(response.data);
2270
+ },
2271
+ /**
2272
+ * Permanently deletes an Agent Web App.
2273
+ * @param id - Agent Web App identifier
2274
+ * @returns A promise that resolves when the publication is deleted
2275
+ */
2276
+ delete: async (id) => {
2277
+ await this.makeRequest(
2278
+ `/api/web-apps/${encodeURIComponent(id)}`,
2279
+ { method: "DELETE" }
2280
+ );
2281
+ }
2282
+ };
2132
2283
  /**
2133
2284
  * Skills namespace for managing skills
2134
2285
  */
@@ -2649,11 +2800,11 @@ var AbstractClient = class {
2649
2800
  delete: async (id) => {
2650
2801
  await this.makeRequest(`/api/tasks/${id}`, { method: "DELETE" });
2651
2802
  },
2652
- complete: async (id) => {
2653
- const response = await this.makeRequest(`/api/tasks/${id}/complete`, { method: "PATCH" });
2803
+ complete: async (id, data) => {
2804
+ const response = await this.makeRequest(`/api/tasks/${id}/complete`, { method: "PATCH", body: data });
2654
2805
  if (!response.data)
2655
2806
  throw new ApiError("Failed to complete task", 500);
2656
- return response.data;
2807
+ return response;
2657
2808
  },
2658
2809
  workItems: {
2659
2810
  list: async (taskId, params) => {
@@ -2701,6 +2852,27 @@ var AbstractClient = class {
2701
2852
  }
2702
2853
  };
2703
2854
  }
2855
+ hydrateAgentWebApp(value) {
2856
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2857
+ throw new ApiError("Invalid Agent Web App response", 500, value);
2858
+ }
2859
+ const record = value;
2860
+ const hydrateDate = (field) => {
2861
+ const raw = record[field];
2862
+ const date = raw instanceof Date ? new Date(raw.getTime()) : new Date(
2863
+ typeof raw === "string" || typeof raw === "number" ? raw : Number.NaN
2864
+ );
2865
+ if (Number.isNaN(date.getTime())) {
2866
+ throw new ApiError(`Invalid Agent Web App ${field}`, 500, value);
2867
+ }
2868
+ return date;
2869
+ };
2870
+ return {
2871
+ ...record,
2872
+ createdAt: hydrateDate("createdAt"),
2873
+ updatedAt: hydrateDate("updatedAt")
2874
+ };
2875
+ }
2704
2876
  /**
2705
2877
  * Set handler for 401 unauthorized errors
2706
2878
  * @param handler - Callback function to handle unauthorized errors
@@ -2960,6 +3132,182 @@ var ResourcesClient = class {
2960
3132
  }
2961
3133
  };
2962
3134
 
3135
+ // src/export-import.ts
3136
+ function base64ToBytes(base64) {
3137
+ if (typeof globalThis.atob === "function") {
3138
+ const binary = globalThis.atob(base64);
3139
+ const bytes = new Uint8Array(binary.length);
3140
+ for (let index = 0; index < binary.length; index += 1) {
3141
+ bytes[index] = binary.charCodeAt(index);
3142
+ }
3143
+ return bytes;
3144
+ }
3145
+ return new Uint8Array(Buffer.from(base64, "base64"));
3146
+ }
3147
+ function bytesToArrayBuffer(bytes) {
3148
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
3149
+ }
3150
+ async function archiveToBlob(archive) {
3151
+ if (typeof archive === "string") {
3152
+ return {
3153
+ blob: new Blob([bytesToArrayBuffer(base64ToBytes(archive))], { type: "application/gzip" }),
3154
+ filename: "tenant-import.tar.gz"
3155
+ };
3156
+ }
3157
+ if (archive instanceof Blob) {
3158
+ const filename = "name" in archive && typeof archive.name === "string" ? archive.name : "tenant-import.tar.gz";
3159
+ return { blob: archive, filename };
3160
+ }
3161
+ const bytes = archive instanceof Uint8Array ? archive : archive instanceof ArrayBuffer ? new Uint8Array(archive) : new Uint8Array(await archive.arrayBuffer());
3162
+ return {
3163
+ blob: new Blob([bytesToArrayBuffer(bytes)], { type: "application/gzip" }),
3164
+ filename: "tenant-import.tar.gz"
3165
+ };
3166
+ }
3167
+ function attachmentFilename(contentDisposition) {
3168
+ if (!contentDisposition)
3169
+ return "tenant-export.tar.gz";
3170
+ const encoded = contentDisposition.match(/filename\*=UTF-8''([^;]+)/i)?.[1];
3171
+ if (encoded) {
3172
+ try {
3173
+ return decodeURIComponent(encoded);
3174
+ } catch {
3175
+ return encoded;
3176
+ }
3177
+ }
3178
+ return contentDisposition.match(/filename="([^"]+)"/i)?.[1] ?? contentDisposition.match(/filename=([^;\s]+)/i)?.[1] ?? "tenant-export.tar.gz";
3179
+ }
3180
+ var ExportImportClient = class {
3181
+ /**
3182
+ * Creates an export/import client.
3183
+ *
3184
+ * @param config - Base client configuration.
3185
+ * @param headerProvider - Optional provider for headers that change after construction.
3186
+ */
3187
+ constructor(config, headerProvider) {
3188
+ this.baseURL = config.baseURL;
3189
+ this.headers = {
3190
+ "Content-Type": "application/json",
3191
+ Authorization: `Bearer ${config.apiKey}`,
3192
+ ...config.headers
3193
+ };
3194
+ this.headerProvider = headerProvider;
3195
+ }
3196
+ async request(url, options = {}) {
3197
+ const headers = {
3198
+ ...this.headers,
3199
+ ...this.headerProvider?.(),
3200
+ ...options.headers
3201
+ };
3202
+ if (options.body instanceof FormData) {
3203
+ for (const name of Object.keys(headers)) {
3204
+ if (name.toLowerCase() === "content-type")
3205
+ delete headers[name];
3206
+ }
3207
+ }
3208
+ const response = await fetch(`${this.baseURL}${url}`, {
3209
+ method: options.method ?? "GET",
3210
+ ...options,
3211
+ headers
3212
+ });
3213
+ const envelope = await response.json().catch(() => ({}));
3214
+ if (!response.ok || envelope.success === false) {
3215
+ throw new Error(
3216
+ envelope.message || envelope.error || `HTTP error! Status: ${response.status}`
3217
+ );
3218
+ }
3219
+ if (envelope.data === void 0) {
3220
+ throw new Error(envelope.message || envelope.error || "API response contained no data");
3221
+ }
3222
+ return envelope.data;
3223
+ }
3224
+ /** Returns all entity types registered for export. */
3225
+ getExportableTypes() {
3226
+ return this.request("/api/tenants/exportable-types");
3227
+ }
3228
+ /** Starts an export or returns dependencies requiring confirmation. */
3229
+ exportConfig(tenantId, entityTypes, entityIds) {
3230
+ return this.request(`/api/tenants/${tenantId}/export`, {
3231
+ method: "POST",
3232
+ body: JSON.stringify({ entityTypes, ...entityIds ? { entityIds } : {} })
3233
+ });
3234
+ }
3235
+ /** Starts an export after confirming dependency additions. */
3236
+ exportConfigConfirm(tenantId, entityTypes, entityIds) {
3237
+ return this.request(`/api/tenants/${tenantId}/export/confirm`, {
3238
+ method: "POST",
3239
+ body: JSON.stringify({ entityTypes, ...entityIds ? { entityIds } : {} })
3240
+ });
3241
+ }
3242
+ /** Lists selectable entities for the requested export types. */
3243
+ previewEntities(tenantId, entityTypes) {
3244
+ return this.request(
3245
+ `/api/tenants/${tenantId}/export/entities`,
3246
+ { method: "POST", body: JSON.stringify({ entityTypes }) }
3247
+ );
3248
+ }
3249
+ /** Returns the gateway URL for an export download job. */
3250
+ getExportDownloadUrl(tenantId, jobId) {
3251
+ return `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`;
3252
+ }
3253
+ /** Downloads an export archive as raw bytes. */
3254
+ async downloadExport(tenantId, jobId) {
3255
+ const response = await fetch(
3256
+ `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`,
3257
+ {
3258
+ method: "GET",
3259
+ headers: {
3260
+ ...this.headers,
3261
+ ...this.headerProvider?.()
3262
+ }
3263
+ }
3264
+ );
3265
+ if (!response.ok) {
3266
+ const envelope = await response.json().catch(() => ({}));
3267
+ throw new Error(
3268
+ envelope.message || envelope.error || `HTTP error! Status: ${response.status}`
3269
+ );
3270
+ }
3271
+ return {
3272
+ filename: attachmentFilename(response.headers.get("Content-Disposition")),
3273
+ data: new Uint8Array(await response.arrayBuffer())
3274
+ };
3275
+ }
3276
+ /** Previews an archive or plain JSON bundle import. */
3277
+ async importPreview(tenantId, source) {
3278
+ if (source.archive !== void 0) {
3279
+ const form = new FormData();
3280
+ const { blob, filename } = await archiveToBlob(source.archive);
3281
+ form.append("file", blob, filename);
3282
+ return this.request(`/api/tenants/${tenantId}/import/preview`, {
3283
+ method: "POST",
3284
+ body: form
3285
+ });
3286
+ }
3287
+ return this.request(`/api/tenants/${tenantId}/import/preview`, {
3288
+ method: "POST",
3289
+ body: JSON.stringify({ bundle: source.bundle })
3290
+ });
3291
+ }
3292
+ /** Applies an archive or plain JSON bundle import with conflict resolutions. */
3293
+ async importApply(tenantId, source, resolutions) {
3294
+ if (source.archive !== void 0) {
3295
+ const form = new FormData();
3296
+ const { blob, filename } = await archiveToBlob(source.archive);
3297
+ form.append("file", blob, filename);
3298
+ form.append("resolutions", JSON.stringify(resolutions));
3299
+ return this.request(`/api/tenants/${tenantId}/import/apply`, {
3300
+ method: "POST",
3301
+ body: form
3302
+ });
3303
+ }
3304
+ return this.request(`/api/tenants/${tenantId}/import/apply`, {
3305
+ method: "POST",
3306
+ body: JSON.stringify({ bundle: source.bundle, resolutions })
3307
+ });
3308
+ }
3309
+ };
3310
+
2963
3311
  // src/client.ts
2964
3312
  var _Client = class extends AbstractClient {
2965
3313
  /**
@@ -2974,6 +3322,7 @@ var _Client = class extends AbstractClient {
2974
3322
  ...this.config.headers
2975
3323
  };
2976
3324
  this.resources = new ResourcesClient(this.config.baseURL, () => this.getAllHeaders());
3325
+ this.exportImport = new ExportImportClient(this.config, () => this.getAllHeaders());
2977
3326
  }
2978
3327
  /**
2979
3328
  * Helper method to handle fetch responses and errors
@@ -3734,9 +4083,14 @@ var WorkspaceClient = class {
3734
4083
  });
3735
4084
  }
3736
4085
  // ==================== Project CRUD ====================
3737
- async listProjects(workspaceId) {
4086
+ async listProjects(workspaceId, kind) {
4087
+ const params = new URLSearchParams();
4088
+ if (kind) {
4089
+ params.set("kind", kind);
4090
+ }
4091
+ const qs = params.toString();
3738
4092
  const response = await this.request(
3739
- `/api/workspaces/${workspaceId}/projects`
4093
+ `/api/workspaces/${workspaceId}/projects${qs ? `?${qs}` : ""}`
3740
4094
  );
3741
4095
  return response.data || [];
3742
4096
  }
@@ -3875,97 +4229,6 @@ var WorkspaceClient = class {
3875
4229
  }
3876
4230
  };
3877
4231
 
3878
- // src/export-import.ts
3879
- var ExportImportClient = class {
3880
- constructor(config) {
3881
- this.baseURL = config.baseURL;
3882
- this.headers = {
3883
- "Content-Type": "application/json",
3884
- Authorization: `Bearer ${config.apiKey}`,
3885
- ...config.headers
3886
- };
3887
- }
3888
- async request(url, options = {}) {
3889
- const fullUrl = `${this.baseURL}${url}`;
3890
- const response = await fetch(fullUrl, {
3891
- ...options,
3892
- headers: {
3893
- ...this.headers,
3894
- ...options.headers
3895
- }
3896
- });
3897
- if (!response.ok) {
3898
- const err = await response.json().catch(() => ({}));
3899
- throw new Error(
3900
- err.message || `HTTP error! Status: ${response.status}`
3901
- );
3902
- }
3903
- return response.json();
3904
- }
3905
- async getExportableTypes() {
3906
- const response = await this.request(
3907
- "/api/tenants/exportable-types"
3908
- );
3909
- return response.data || [];
3910
- }
3911
- async exportConfig(tenantId, entityTypes) {
3912
- const response = await this.request(
3913
- `/api/tenants/${tenantId}/export`,
3914
- {
3915
- method: "POST",
3916
- body: JSON.stringify({ entityTypes })
3917
- }
3918
- );
3919
- return response.data;
3920
- }
3921
- async exportConfigConfirm(tenantId, entityTypes) {
3922
- const response = await this.request(
3923
- `/api/tenants/${tenantId}/export/confirm`,
3924
- {
3925
- method: "POST",
3926
- body: JSON.stringify({ entityTypes })
3927
- }
3928
- );
3929
- return response.data;
3930
- }
3931
- getExportDownloadUrl(tenantId, jobId) {
3932
- return `${this.baseURL}/api/tenants/${tenantId}/export/${jobId}/download`;
3933
- }
3934
- async importPreview(tenantId, file) {
3935
- const formData = new FormData();
3936
- formData.append("file", file);
3937
- const fullUrl = `${this.baseURL}/api/tenants/${tenantId}/import/preview`;
3938
- const headers = { ...this.headers };
3939
- delete headers["Content-Type"];
3940
- const response = await fetch(fullUrl, {
3941
- method: "POST",
3942
- headers,
3943
- body: formData
3944
- });
3945
- if (!response.ok) {
3946
- const err = await response.json().catch(() => ({}));
3947
- throw new Error(
3948
- err.message || `HTTP error! Status: ${response.status}`
3949
- );
3950
- }
3951
- const json = await response.json();
3952
- if (!json.success || !json.data) {
3953
- throw new Error(json.error || "Import preview failed");
3954
- }
3955
- return json.data;
3956
- }
3957
- async importApply(tenantId, bundle, resolutions) {
3958
- const response = await this.request(
3959
- `/api/tenants/${tenantId}/import/apply`,
3960
- {
3961
- method: "POST",
3962
- body: JSON.stringify({ bundle, resolutions })
3963
- }
3964
- );
3965
- return response.data;
3966
- }
3967
- };
3968
-
3969
4232
  // src/ChunkMessageMerger.ts
3970
4233
  import { parse } from "best-effort-json-parser";
3971
4234
  function createSimpleMessageMerger() {