@prismer/sdk 1.8.2 → 1.9.6
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/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/cli.js +397 -5
- package/dist/index.d.mts +646 -2
- package/dist/index.d.ts +646 -2
- package/dist/index.js +404 -5
- package/dist/index.mjs +5105 -50
- package/dist/webhook.d.mts +114 -0
- package/dist/webhook.d.ts +114 -0
- package/dist/webhook.js +200 -0
- package/dist/webhook.mjs +175 -0
- package/package.json +1 -1
- package/dist/chunk-BWZXMXL7.mjs +0 -4762
- package/dist/chunk-VSAVCMMZ.mjs +0 -4761
- package/dist/cli.d.mts +0 -15
- package/dist/cli.d.ts +0 -15
- package/dist/cli.mjs +0 -3838
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__require
|
|
10
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1772,6 +1773,23 @@ var AccountClient = class {
|
|
|
1772
1773
|
async refreshToken() {
|
|
1773
1774
|
return this._r("POST", "/api/im/token/refresh");
|
|
1774
1775
|
}
|
|
1776
|
+
/**
|
|
1777
|
+
* List agents owned by the current human user (v1.9.3).
|
|
1778
|
+
* Mobile clients call this on launch to populate the Profile/agent runtime card.
|
|
1779
|
+
* Returns `[]` for non-human / api-key-proxy callers without a cloudUserId.
|
|
1780
|
+
*/
|
|
1781
|
+
async listAgents() {
|
|
1782
|
+
return this._r("GET", "/api/im/me/agents");
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Self-service account deletion (v1.9.3).
|
|
1786
|
+
* Soft-deletes the IMUser, cascades owned conversations + open tasks,
|
|
1787
|
+
* revokes pc_api_keys, and blacklists the request token.
|
|
1788
|
+
* The caller can only delete themselves — there is no target id parameter.
|
|
1789
|
+
*/
|
|
1790
|
+
async deleteAccount() {
|
|
1791
|
+
return this._r("DELETE", "/api/im/me");
|
|
1792
|
+
}
|
|
1775
1793
|
};
|
|
1776
1794
|
var DirectClient = class {
|
|
1777
1795
|
constructor(_r) {
|
|
@@ -2094,6 +2112,9 @@ var TasksClient = class {
|
|
|
2094
2112
|
/** List tasks with optional filters */
|
|
2095
2113
|
async list(options) {
|
|
2096
2114
|
const query = {};
|
|
2115
|
+
query.view = options?.view ?? "board";
|
|
2116
|
+
if (options?.kind) query.kind = options.kind;
|
|
2117
|
+
if (!options?.kind && query.view === "board") query.kind = "work_item,goal";
|
|
2097
2118
|
if (options?.status) query.status = options.status;
|
|
2098
2119
|
if (options?.capability) query.capability = options.capability;
|
|
2099
2120
|
if (options?.assigneeId) query.assigneeId = options.assigneeId;
|
|
@@ -2101,12 +2122,38 @@ var TasksClient = class {
|
|
|
2101
2122
|
if (options?.scheduleType) query.scheduleType = options.scheduleType;
|
|
2102
2123
|
if (options?.limit != null) query.limit = String(options.limit);
|
|
2103
2124
|
if (options?.cursor) query.cursor = options.cursor;
|
|
2125
|
+
if (options?.workspaceId) query.workspaceId = options.workspaceId;
|
|
2126
|
+
if (options?.conversationId) query.conversationId = options.conversationId;
|
|
2104
2127
|
return this._r("GET", "/api/im/tasks", void 0, query);
|
|
2105
2128
|
}
|
|
2106
2129
|
/** Get task details with logs */
|
|
2107
2130
|
async get(taskId) {
|
|
2108
2131
|
return this._r("GET", `/api/im/tasks/${taskId}`);
|
|
2109
2132
|
}
|
|
2133
|
+
/**
|
|
2134
|
+
* Wave-9 (v1.9.4) — fetch the canonical task result.
|
|
2135
|
+
*
|
|
2136
|
+
* Replaces the legacy "list IMAssets where kind=task-result + sourceTaskId"
|
|
2137
|
+
* pattern. Returns the locked shape defined by `IMTaskResult`; in
|
|
2138
|
+
* particular `assetIds` is always an array (possibly empty) so callers
|
|
2139
|
+
* can iterate without a null-check.
|
|
2140
|
+
*
|
|
2141
|
+
* Access: creator, assignee, or marketplace visibility on the task.
|
|
2142
|
+
*/
|
|
2143
|
+
async getResult(taskId) {
|
|
2144
|
+
return this._r("GET", `/api/im/tasks/${taskId}/result`);
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Wave-9 (v1.9.4) — fetch the canonical run result.
|
|
2148
|
+
*
|
|
2149
|
+
* Same shape as `getResult` but reads from IMTaskRun.output instead of
|
|
2150
|
+
* IMTask.result. Use this for chat-mention dispatches whose result lives
|
|
2151
|
+
* on a run row rather than a board task. The `taskId` field of the
|
|
2152
|
+
* returned object is the run.id.
|
|
2153
|
+
*/
|
|
2154
|
+
async getRunResult(runId) {
|
|
2155
|
+
return this._r("GET", `/api/im/runs/${runId}/result`);
|
|
2156
|
+
}
|
|
2110
2157
|
/** Update a task */
|
|
2111
2158
|
async update(taskId, options) {
|
|
2112
2159
|
return this._r("PATCH", `/api/im/tasks/${taskId}`, options);
|
|
@@ -2185,6 +2232,18 @@ var MemoryClient = class {
|
|
|
2185
2232
|
async getKnowledgeLinks() {
|
|
2186
2233
|
return this._r("GET", "/api/im/memory/links");
|
|
2187
2234
|
}
|
|
2235
|
+
/**
|
|
2236
|
+
* Get a CC-style always-load digest of all memory files (v1.9.3).
|
|
2237
|
+
* The digest is a Markdown bundle suitable for prepending to LLM context.
|
|
2238
|
+
* Server clamps `maxLines` to 10–1000 and `maxBytes` to 500–30000.
|
|
2239
|
+
*/
|
|
2240
|
+
async digest(options) {
|
|
2241
|
+
const query = {};
|
|
2242
|
+
if (options?.scope) query.scope = options.scope;
|
|
2243
|
+
if (options?.maxLines != null) query.maxLines = String(options.maxLines);
|
|
2244
|
+
if (options?.maxBytes != null) query.maxBytes = String(options.maxBytes);
|
|
2245
|
+
return this._r("GET", "/api/im/memory/digest", void 0, query);
|
|
2246
|
+
}
|
|
2188
2247
|
};
|
|
2189
2248
|
var KnowledgeLinkClient = class {
|
|
2190
2249
|
constructor(_r) {
|
|
@@ -2722,6 +2781,226 @@ var EvolutionClient = class {
|
|
|
2722
2781
|
function safeSlug(input) {
|
|
2723
2782
|
return input.replace(/[\/\\]/g, "").replace(/\.\./g, "").replace(/\0/g, "");
|
|
2724
2783
|
}
|
|
2784
|
+
var WorkspacesClient = class {
|
|
2785
|
+
constructor(_r) {
|
|
2786
|
+
this._r = _r;
|
|
2787
|
+
}
|
|
2788
|
+
/** List active workspaces owned by the caller. */
|
|
2789
|
+
async list() {
|
|
2790
|
+
return this._r("GET", "/api/im/workspaces");
|
|
2791
|
+
}
|
|
2792
|
+
/**
|
|
2793
|
+
* Create a workspace. In 1.9.x most callers don't need this — registration
|
|
2794
|
+
* auto-creates a default workspace. The first workspace per owner is
|
|
2795
|
+
* always default; subsequent ones must omit `isDefault` (server returns 409).
|
|
2796
|
+
*/
|
|
2797
|
+
async create(options) {
|
|
2798
|
+
return this._r("POST", "/api/im/workspaces", options);
|
|
2799
|
+
}
|
|
2800
|
+
/** Daemon delta-sync workspaces since an ISO timestamp. */
|
|
2801
|
+
async sync(since) {
|
|
2802
|
+
const query = {};
|
|
2803
|
+
if (since) query.since = since;
|
|
2804
|
+
return this._r("GET", "/api/im/workspaces/sync", void 0, query);
|
|
2805
|
+
}
|
|
2806
|
+
/** Get a single workspace by id (caller must own). */
|
|
2807
|
+
async get(workspaceId) {
|
|
2808
|
+
return this._r("GET", `/api/im/workspaces/${workspaceId}`);
|
|
2809
|
+
}
|
|
2810
|
+
/** Update workspace name and/or metadata. `slug` and `isDefault` are immutable in 1.9.x. */
|
|
2811
|
+
async update(workspaceId, options) {
|
|
2812
|
+
return this._r("PATCH", `/api/im/workspaces/${workspaceId}`, options);
|
|
2813
|
+
}
|
|
2814
|
+
/**
|
|
2815
|
+
* Archive (delete) a workspace. Server returns 405 in 1.9.x — workspace
|
|
2816
|
+
* deletion equals account close, which goes through `account.deleteAccount()`.
|
|
2817
|
+
* Provided for forward-compat; will become real in 1.10+.
|
|
2818
|
+
*/
|
|
2819
|
+
async archive(workspaceId) {
|
|
2820
|
+
return this._r("DELETE", `/api/im/workspaces/${workspaceId}`);
|
|
2821
|
+
}
|
|
2822
|
+
};
|
|
2823
|
+
var WorkspaceFilesClient = class {
|
|
2824
|
+
constructor(_r) {
|
|
2825
|
+
this._r = _r;
|
|
2826
|
+
}
|
|
2827
|
+
/** List the active file tree for a workspace, or look up a single file by path. */
|
|
2828
|
+
async list(workspaceId, options) {
|
|
2829
|
+
const query = {};
|
|
2830
|
+
if (options?.path) query.path = options.path;
|
|
2831
|
+
return this._r("GET", `/api/im/workspaces/${workspaceId}/files`, void 0, query);
|
|
2832
|
+
}
|
|
2833
|
+
/**
|
|
2834
|
+
* Bind `path → assetId`. Idempotent if `(path, assetId)` matches the existing
|
|
2835
|
+
* active binding. Asset must already exist in the same workspace.
|
|
2836
|
+
*/
|
|
2837
|
+
async create(workspaceId, options) {
|
|
2838
|
+
return this._r("POST", `/api/im/workspaces/${workspaceId}/files`, options);
|
|
2839
|
+
}
|
|
2840
|
+
/** Soft-delete the active binding at `path`. */
|
|
2841
|
+
async delete(workspaceId, path4) {
|
|
2842
|
+
return this._r("DELETE", `/api/im/workspaces/${workspaceId}/files`, void 0, { path: path4 });
|
|
2843
|
+
}
|
|
2844
|
+
/** Daemon delta-sync workspace files since an ISO timestamp. */
|
|
2845
|
+
async sync(workspaceId, since) {
|
|
2846
|
+
const query = {};
|
|
2847
|
+
if (since) query.since = since;
|
|
2848
|
+
return this._r("GET", `/api/im/workspaces/${workspaceId}/files/sync`, void 0, query);
|
|
2849
|
+
}
|
|
2850
|
+
/** Get the version chain for a file (walks `parentVersionId`). */
|
|
2851
|
+
async history(workspaceId, fileId) {
|
|
2852
|
+
return this._r("GET", `/api/im/workspaces/${workspaceId}/files/${fileId}/history`);
|
|
2853
|
+
}
|
|
2854
|
+
};
|
|
2855
|
+
var AssetsClient = class {
|
|
2856
|
+
constructor(_r, _baseUrl, _fetchFn, _getAuthHeaders) {
|
|
2857
|
+
this._r = _r;
|
|
2858
|
+
this._baseUrl = _baseUrl;
|
|
2859
|
+
this._fetchFn = _fetchFn;
|
|
2860
|
+
this._getAuthHeaders = _getAuthHeaders;
|
|
2861
|
+
}
|
|
2862
|
+
/** List assets in a workspace (filterable by task and kind). */
|
|
2863
|
+
async list(options) {
|
|
2864
|
+
const query = {};
|
|
2865
|
+
if (options.workspaceId) query.workspaceId = options.workspaceId;
|
|
2866
|
+
if (options.taskId) query.taskId = options.taskId;
|
|
2867
|
+
if (options.kind) query.kind = options.kind;
|
|
2868
|
+
if (options.limit != null) query.limit = String(options.limit);
|
|
2869
|
+
return this._r("GET", "/api/im/assets", void 0, query);
|
|
2870
|
+
}
|
|
2871
|
+
/**
|
|
2872
|
+
* Look up an asset by content hash within a workspace. Useful for dedupe
|
|
2873
|
+
* checks ("do I already have this file?") before uploading.
|
|
2874
|
+
*/
|
|
2875
|
+
async byHash(hash, workspaceId) {
|
|
2876
|
+
return this._r("GET", `/api/im/assets/by-hash/${encodeURIComponent(hash)}`, void 0, { wsId: workspaceId });
|
|
2877
|
+
}
|
|
2878
|
+
/**
|
|
2879
|
+
* Get full asset metadata + a freshly-signed URL (5 min TTL, S3 backend only).
|
|
2880
|
+
* For `kind === 'photo-memory-segment'` this also includes a `photoRefs`
|
|
2881
|
+
* reverse-lookup of memory references.
|
|
2882
|
+
*/
|
|
2883
|
+
async detail(assetId) {
|
|
2884
|
+
return this._r("GET", `/api/im/assets/${assetId}/detail`);
|
|
2885
|
+
}
|
|
2886
|
+
/**
|
|
2887
|
+
* Soft-delete an asset (the underlying S3 object is retained). Idempotent.
|
|
2888
|
+
*/
|
|
2889
|
+
async delete(assetId) {
|
|
2890
|
+
return this._r("DELETE", `/api/im/assets/${assetId}`);
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* Build a download URL for an asset. Filesystem backend streams bytes
|
|
2894
|
+
* directly; S3 backend returns a 302 to a 5-minute presigned URL.
|
|
2895
|
+
* Use `download()` for a one-shot fetch returning bytes.
|
|
2896
|
+
*/
|
|
2897
|
+
url(assetId) {
|
|
2898
|
+
return `${this._baseUrl}/api/im/assets/${assetId}`;
|
|
2899
|
+
}
|
|
2900
|
+
/**
|
|
2901
|
+
* Download an asset's bytes. Authentication is forwarded; for S3 backend
|
|
2902
|
+
* the server returns a 302 which `fetch` follows automatically.
|
|
2903
|
+
*/
|
|
2904
|
+
async download(assetId) {
|
|
2905
|
+
const resp = await this._fetchFn(this.url(assetId), {
|
|
2906
|
+
method: "GET",
|
|
2907
|
+
headers: this._getAuthHeaders()
|
|
2908
|
+
});
|
|
2909
|
+
if (!resp.ok) {
|
|
2910
|
+
throw new Error(`Asset download failed (${resp.status}): ${await resp.text()}`);
|
|
2911
|
+
}
|
|
2912
|
+
const ab = await resp.arrayBuffer();
|
|
2913
|
+
const sizeHeader = resp.headers.get("content-length");
|
|
2914
|
+
return {
|
|
2915
|
+
bytes: new Uint8Array(ab),
|
|
2916
|
+
mime: resp.headers.get("content-type"),
|
|
2917
|
+
sizeBytes: sizeHeader ? Number(sizeHeader) : null
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Upload bytes as an asset (multipart). 100 MB hard cap; >50 MB returns
|
|
2922
|
+
* 413 with `USE_PRESIGNED` — use S3 presign flow for those (not yet wrapped).
|
|
2923
|
+
*/
|
|
2924
|
+
async upload(input, options) {
|
|
2925
|
+
let bytes;
|
|
2926
|
+
let fileName;
|
|
2927
|
+
if (typeof input === "string") {
|
|
2928
|
+
const fs4 = await import("fs");
|
|
2929
|
+
const path4 = await import("path");
|
|
2930
|
+
const buf = await fs4.promises.readFile(input);
|
|
2931
|
+
bytes = new Uint8Array(buf);
|
|
2932
|
+
fileName = options.fileName || path4.basename(input);
|
|
2933
|
+
} else if (typeof Blob !== "undefined" && input instanceof Blob) {
|
|
2934
|
+
const ab2 = await input.arrayBuffer();
|
|
2935
|
+
bytes = new Uint8Array(ab2);
|
|
2936
|
+
fileName = options.fileName || (input instanceof File ? input.name : "");
|
|
2937
|
+
if (!fileName) throw new Error("fileName is required when uploading Blob without name");
|
|
2938
|
+
} else if (input instanceof Uint8Array) {
|
|
2939
|
+
bytes = input;
|
|
2940
|
+
fileName = options.fileName || "";
|
|
2941
|
+
if (!fileName) throw new Error("fileName is required when uploading Buffer or Uint8Array");
|
|
2942
|
+
} else {
|
|
2943
|
+
throw new Error("Unsupported input type");
|
|
2944
|
+
}
|
|
2945
|
+
const mimeType = options.mimeType || guessMimeType(fileName);
|
|
2946
|
+
const sizeBytes = bytes.byteLength;
|
|
2947
|
+
if (sizeBytes > 100 * 1024 * 1024) {
|
|
2948
|
+
throw new Error("Asset exceeds 100 MB cap");
|
|
2949
|
+
}
|
|
2950
|
+
const formData = new FormData();
|
|
2951
|
+
const ab = new ArrayBuffer(bytes.byteLength);
|
|
2952
|
+
new Uint8Array(ab).set(bytes);
|
|
2953
|
+
formData.append("file", new Blob([ab], { type: mimeType }), fileName);
|
|
2954
|
+
formData.append("workspaceId", options.workspaceId);
|
|
2955
|
+
if (options.kind) formData.append("kind", options.kind);
|
|
2956
|
+
if (options.sourceAgentImUserId) formData.append("sourceAgentImUserId", options.sourceAgentImUserId);
|
|
2957
|
+
if (options.sourceTaskId) formData.append("sourceTaskId", options.sourceTaskId);
|
|
2958
|
+
if (options.metadata) formData.append("metadata", JSON.stringify(options.metadata));
|
|
2959
|
+
const resp = await this._fetchFn(`${this._baseUrl}/api/im/assets`, {
|
|
2960
|
+
method: "POST",
|
|
2961
|
+
body: formData,
|
|
2962
|
+
headers: this._getAuthHeaders()
|
|
2963
|
+
});
|
|
2964
|
+
options.onProgress?.(sizeBytes, sizeBytes);
|
|
2965
|
+
const data = await resp.json().catch(() => ({}));
|
|
2966
|
+
if (!resp.ok) {
|
|
2967
|
+
return {
|
|
2968
|
+
ok: false,
|
|
2969
|
+
error: data?.error || { code: "HTTP_ERROR", message: `Upload failed (${resp.status})` }
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2972
|
+
return data;
|
|
2973
|
+
}
|
|
2974
|
+
};
|
|
2975
|
+
var RuntimeInstallationsClient = class {
|
|
2976
|
+
constructor(_r) {
|
|
2977
|
+
this._r = _r;
|
|
2978
|
+
}
|
|
2979
|
+
/** List runtime installations in a workspace. */
|
|
2980
|
+
async list(workspaceId, options) {
|
|
2981
|
+
const query = { workspaceId };
|
|
2982
|
+
if (options?.limit != null) query.limit = String(options.limit);
|
|
2983
|
+
return this._r("GET", "/api/workspace/runtime-installations", void 0, query);
|
|
2984
|
+
}
|
|
2985
|
+
/**
|
|
2986
|
+
* Create a new runtime installation. Mints a durable runtime API key,
|
|
2987
|
+
* RPCs the sandbox controller, and persists an `IMContainer` row.
|
|
2988
|
+
* The daemon receives `PRISMER_API_KEY`, `PRISMER_DAEMON_ID`,
|
|
2989
|
+
* `PRISMER_BASE_URL`, `PRISMER_WORKSPACE_ID`, and
|
|
2990
|
+
* `PRISMER_RUNTIME_KIND=workspace-daemon` env vars.
|
|
2991
|
+
*/
|
|
2992
|
+
async create(options) {
|
|
2993
|
+
return this._r("POST", "/api/workspace/runtime-installations", options);
|
|
2994
|
+
}
|
|
2995
|
+
/**
|
|
2996
|
+
* Install an agent onto a runtime daemon. Resolves or creates the agent
|
|
2997
|
+
* profile, calls the controller's `installAgent` RPC, and stamps
|
|
2998
|
+
* `IMAgentCard.metadata.daemonId` + `runtimeInstallationId`.
|
|
2999
|
+
*/
|
|
3000
|
+
async installAgent(runtimeInstallationId, options) {
|
|
3001
|
+
return this._r("POST", `/api/workspace/runtime-installations/${runtimeInstallationId}/agents`, options);
|
|
3002
|
+
}
|
|
3003
|
+
};
|
|
2725
3004
|
function guessMimeType(fileName) {
|
|
2726
3005
|
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
|
2727
3006
|
const map = {
|
|
@@ -2928,8 +3207,9 @@ var FilesClient = class {
|
|
|
2928
3207
|
}
|
|
2929
3208
|
};
|
|
2930
3209
|
var IMRealtimeClient = class {
|
|
2931
|
-
constructor(_wsBase) {
|
|
3210
|
+
constructor(_wsBase, _fetchFn = fetch) {
|
|
2932
3211
|
this._wsBase = _wsBase;
|
|
3212
|
+
this._fetchFn = _fetchFn;
|
|
2933
3213
|
}
|
|
2934
3214
|
/** Get the WebSocket URL */
|
|
2935
3215
|
wsUrl(token) {
|
|
@@ -2940,6 +3220,14 @@ var IMRealtimeClient = class {
|
|
|
2940
3220
|
sseUrl(token) {
|
|
2941
3221
|
return token ? `${this._wsBase}/sse?token=${token}` : `${this._wsBase}/sse`;
|
|
2942
3222
|
}
|
|
3223
|
+
/**
|
|
3224
|
+
* Get the URL for the v1.8.2 task SSE stream
|
|
3225
|
+
* (`GET /api/im/tasks/events?token=...`).
|
|
3226
|
+
* Supports `Last-Event-ID` for replay.
|
|
3227
|
+
*/
|
|
3228
|
+
taskEventsUrl(token) {
|
|
3229
|
+
return `${this._wsBase}/api/im/tasks/events?token=${encodeURIComponent(token)}`;
|
|
3230
|
+
}
|
|
2943
3231
|
/** Create a WebSocket client. Call .connect() to establish connection. */
|
|
2944
3232
|
connectWS(config) {
|
|
2945
3233
|
return new RealtimeWSClient(this._wsBase, config);
|
|
@@ -2948,6 +3236,101 @@ var IMRealtimeClient = class {
|
|
|
2948
3236
|
connectSSE(config) {
|
|
2949
3237
|
return new RealtimeSSEClient(this._wsBase, config);
|
|
2950
3238
|
}
|
|
3239
|
+
/**
|
|
3240
|
+
* Subscribe to the task events SSE stream (v1.8.2/v1.9.3).
|
|
3241
|
+
*
|
|
3242
|
+
* Resolves with a `disconnect()` function for cleanup. Emits envelopes of
|
|
3243
|
+
* shape `{ id?, type, payload }` for each parsed `event:` block. Ignores
|
|
3244
|
+
* comment lines (`:` heartbeats).
|
|
3245
|
+
*
|
|
3246
|
+
* @example
|
|
3247
|
+
* const sub = await client.im.realtime.subscribeTaskEvents(apiKey, (evt) => {
|
|
3248
|
+
* if (evt.type === 'task.completed') console.log('done:', evt.payload);
|
|
3249
|
+
* });
|
|
3250
|
+
* // ... later:
|
|
3251
|
+
* sub.disconnect();
|
|
3252
|
+
*/
|
|
3253
|
+
async subscribeTaskEvents(token, onEvent, options) {
|
|
3254
|
+
const controller = new AbortController();
|
|
3255
|
+
const onAbort = () => controller.abort();
|
|
3256
|
+
options?.signal?.addEventListener("abort", onAbort);
|
|
3257
|
+
const headers = { Accept: "text/event-stream" };
|
|
3258
|
+
if (options?.lastEventId) headers["Last-Event-ID"] = options.lastEventId;
|
|
3259
|
+
const resp = await this._fetchFn(this.taskEventsUrl(token), {
|
|
3260
|
+
method: "GET",
|
|
3261
|
+
headers,
|
|
3262
|
+
signal: controller.signal
|
|
3263
|
+
});
|
|
3264
|
+
if (!resp.ok || !resp.body) {
|
|
3265
|
+
options?.signal?.removeEventListener("abort", onAbort);
|
|
3266
|
+
throw new Error(`Task events SSE failed: ${resp.status}`);
|
|
3267
|
+
}
|
|
3268
|
+
void (async () => {
|
|
3269
|
+
const reader = resp.body.getReader();
|
|
3270
|
+
const decoder = new TextDecoder();
|
|
3271
|
+
let buffer = "";
|
|
3272
|
+
let pending = { data: [] };
|
|
3273
|
+
const flush = () => {
|
|
3274
|
+
if (!pending.type && pending.data.length === 0) return;
|
|
3275
|
+
const dataStr = pending.data.join("\n");
|
|
3276
|
+
let payload = {};
|
|
3277
|
+
if (dataStr) {
|
|
3278
|
+
try {
|
|
3279
|
+
payload = JSON.parse(dataStr);
|
|
3280
|
+
} catch {
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
try {
|
|
3284
|
+
onEvent({
|
|
3285
|
+
id: pending.id,
|
|
3286
|
+
type: pending.type ?? "task.updated",
|
|
3287
|
+
payload
|
|
3288
|
+
});
|
|
3289
|
+
} catch {
|
|
3290
|
+
}
|
|
3291
|
+
pending = { data: [] };
|
|
3292
|
+
};
|
|
3293
|
+
try {
|
|
3294
|
+
while (true) {
|
|
3295
|
+
const { done, value } = await reader.read();
|
|
3296
|
+
if (done) break;
|
|
3297
|
+
buffer += decoder.decode(value, { stream: true });
|
|
3298
|
+
let lineEnd;
|
|
3299
|
+
while ((lineEnd = buffer.indexOf("\n")) !== -1) {
|
|
3300
|
+
const line = buffer.slice(0, lineEnd).replace(/\r$/, "");
|
|
3301
|
+
buffer = buffer.slice(lineEnd + 1);
|
|
3302
|
+
if (line === "") {
|
|
3303
|
+
flush();
|
|
3304
|
+
continue;
|
|
3305
|
+
}
|
|
3306
|
+
if (line.startsWith(":")) continue;
|
|
3307
|
+
const colon = line.indexOf(":");
|
|
3308
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
3309
|
+
const valueStr = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /, "");
|
|
3310
|
+
if (field === "event") pending.type = valueStr;
|
|
3311
|
+
else if (field === "id") pending.id = valueStr;
|
|
3312
|
+
else if (field === "data") pending.data.push(valueStr);
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
flush();
|
|
3316
|
+
} catch {
|
|
3317
|
+
} finally {
|
|
3318
|
+
try {
|
|
3319
|
+
reader.releaseLock();
|
|
3320
|
+
} catch {
|
|
3321
|
+
}
|
|
3322
|
+
options?.signal?.removeEventListener("abort", onAbort);
|
|
3323
|
+
}
|
|
3324
|
+
})();
|
|
3325
|
+
return {
|
|
3326
|
+
disconnect: () => {
|
|
3327
|
+
try {
|
|
3328
|
+
controller.abort();
|
|
3329
|
+
} catch {
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
};
|
|
3333
|
+
}
|
|
2951
3334
|
};
|
|
2952
3335
|
var IMClient = class {
|
|
2953
3336
|
constructor(request2, wsBase, fetchFn, getAuthHeaders, offlineManager, communityHubConfig) {
|
|
@@ -2960,6 +3343,10 @@ var IMClient = class {
|
|
|
2960
3343
|
this.bindings = new BindingsClient(request2);
|
|
2961
3344
|
this.credits = new CreditsClient(request2);
|
|
2962
3345
|
this.workspace = new WorkspaceClient(request2);
|
|
3346
|
+
this.workspaces = new WorkspacesClient(request2);
|
|
3347
|
+
this.workspaceFiles = new WorkspaceFilesClient(request2);
|
|
3348
|
+
this.assets = new AssetsClient(request2, wsBase, fetchFn, getAuthHeaders);
|
|
3349
|
+
this.runtimeInstallations = new RuntimeInstallationsClient(request2);
|
|
2963
3350
|
this.tasks = new TasksClient(request2);
|
|
2964
3351
|
this.memory = new MemoryClient(request2);
|
|
2965
3352
|
this.knowledge = new KnowledgeLinkClient(request2);
|
|
@@ -2968,7 +3355,7 @@ var IMClient = class {
|
|
|
2968
3355
|
this.evolution = new EvolutionClient(request2);
|
|
2969
3356
|
this.community = new CommunityHub(request2, communityHubConfig ?? void 0);
|
|
2970
3357
|
this.files = new FilesClient(request2, wsBase, fetchFn, getAuthHeaders);
|
|
2971
|
-
this.realtime = new IMRealtimeClient(wsBase);
|
|
3358
|
+
this.realtime = new IMRealtimeClient(wsBase, fetchFn);
|
|
2972
3359
|
this.offline = offlineManager ?? null;
|
|
2973
3360
|
}
|
|
2974
3361
|
/** IM health check */
|
|
@@ -3193,6 +3580,14 @@ var PrismerClient = class {
|
|
|
3193
3580
|
return this._request("GET", `/api/parse/result/${taskId}`);
|
|
3194
3581
|
}
|
|
3195
3582
|
// --------------------------------------------------------------------------
|
|
3583
|
+
// Models API (LLM proxy model listing)
|
|
3584
|
+
// --------------------------------------------------------------------------
|
|
3585
|
+
/** List LLM models exposed by the cloud LLM proxy (OpenAI format). */
|
|
3586
|
+
async listModels() {
|
|
3587
|
+
const res = await this._request("GET", "/api/v1/models");
|
|
3588
|
+
return res.data ?? [];
|
|
3589
|
+
}
|
|
3590
|
+
// --------------------------------------------------------------------------
|
|
3196
3591
|
// Convenience
|
|
3197
3592
|
// --------------------------------------------------------------------------
|
|
3198
3593
|
/** Search for content (convenience wrapper around load with query mode) */
|
|
@@ -7030,6 +7425,3 @@ program.parse(process.argv);
|
|
|
7030
7425
|
getAPIClient,
|
|
7031
7426
|
getIMClient
|
|
7032
7427
|
});
|
|
7033
|
-
,
|
|
7034
|
-
getIMClient
|
|
7035
|
-
});
|