@prismer/sdk 1.7.4 → 1.8.0
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/README.md +421 -3
- package/dist/cli.js +1342 -112
- package/dist/index.d.mts +758 -223
- package/dist/index.d.ts +758 -223
- package/dist/index.js +582 -12
- package/dist/index.mjs +580 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
AccountClient: () => AccountClient,
|
|
35
35
|
AttachmentQueue: () => AttachmentQueue,
|
|
36
36
|
BindingsClient: () => BindingsClient,
|
|
37
|
+
CommunityHub: () => CommunityHub,
|
|
37
38
|
ContactsClient: () => ContactsClient,
|
|
38
39
|
ConversationsClient: () => ConversationsClient,
|
|
39
40
|
CreditsClient: () => CreditsClient,
|
|
@@ -49,6 +50,7 @@ __export(index_exports, {
|
|
|
49
50
|
IMRealtimeClient: () => IMRealtimeClient,
|
|
50
51
|
IdentityClient: () => IdentityClient,
|
|
51
52
|
IndexedDBStorage: () => IndexedDBStorage,
|
|
53
|
+
KnowledgeLinkClient: () => KnowledgeLinkClient,
|
|
52
54
|
MemoryClient: () => MemoryClient,
|
|
53
55
|
MemoryStorage: () => MemoryStorage,
|
|
54
56
|
MessagesClient: () => MessagesClient,
|
|
@@ -545,7 +547,11 @@ var WRITE_PATTERNS = [
|
|
|
545
547
|
{ method: "POST", pattern: /\/api\/im\/(messages|direct|groups)\//, opType: "message.send" },
|
|
546
548
|
{ method: "PATCH", pattern: /\/api\/im\/messages\//, opType: "message.edit" },
|
|
547
549
|
{ method: "DELETE", pattern: /\/api\/im\/messages\//, opType: "message.delete" },
|
|
548
|
-
{ method: "POST", pattern: /\/api\/im\/conversations\/[^/]+\/read/, opType: "conversation.read" }
|
|
550
|
+
{ method: "POST", pattern: /\/api\/im\/conversations\/[^/]+\/read/, opType: "conversation.read" },
|
|
551
|
+
// v1.8.0 Community — queued when offline-first IM is enabled
|
|
552
|
+
{ method: "POST", pattern: /\/api\/im\/community\/posts$/, opType: "community_post" },
|
|
553
|
+
{ method: "POST", pattern: /\/api\/im\/community\/posts\/[^/]+\/comments$/, opType: "community_comment" },
|
|
554
|
+
{ method: "POST", pattern: /\/api\/im\/community\/vote$/, opType: "community_vote" }
|
|
549
555
|
];
|
|
550
556
|
function matchWriteOp(method, path) {
|
|
551
557
|
for (const { method: m, pattern, opType } of WRITE_PATTERNS) {
|
|
@@ -1277,9 +1283,268 @@ var AttachmentQueue = class {
|
|
|
1277
1283
|
}
|
|
1278
1284
|
};
|
|
1279
1285
|
|
|
1280
|
-
// src/
|
|
1281
|
-
var
|
|
1282
|
-
|
|
1286
|
+
// src/community-hub.ts
|
|
1287
|
+
var CommunityHub = class {
|
|
1288
|
+
constructor(_r, config) {
|
|
1289
|
+
this._r = _r;
|
|
1290
|
+
this.feedCache = /* @__PURE__ */ new Map();
|
|
1291
|
+
this.statsCache = null;
|
|
1292
|
+
this.notifCountCache = null;
|
|
1293
|
+
this.notifCountTTL = 15e3;
|
|
1294
|
+
this.wsUnsubs = [];
|
|
1295
|
+
this.feedTTL = config?.feedTTLMs ?? 3e5;
|
|
1296
|
+
this.statsTTL = config?.statsTTLMs ?? 6e5;
|
|
1297
|
+
}
|
|
1298
|
+
/** Invalidate cached feeds/stats (e.g. after you posted). */
|
|
1299
|
+
invalidateCache(boardId) {
|
|
1300
|
+
if (boardId) this.feedCache.delete(boardId);
|
|
1301
|
+
else this.feedCache.clear();
|
|
1302
|
+
this.statsCache = null;
|
|
1303
|
+
this.notifCountCache = null;
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Subscribe to community.* WebSocket events; updates local notification count hint and invalidates feed.
|
|
1307
|
+
*/
|
|
1308
|
+
attachRealtime(ws) {
|
|
1309
|
+
const onReply = () => {
|
|
1310
|
+
this.notifCountCache = null;
|
|
1311
|
+
this.feedCache.clear();
|
|
1312
|
+
};
|
|
1313
|
+
const types = [
|
|
1314
|
+
"community.reply",
|
|
1315
|
+
"community.vote",
|
|
1316
|
+
"community.answer.accepted",
|
|
1317
|
+
"community.mention"
|
|
1318
|
+
];
|
|
1319
|
+
for (const t of types) {
|
|
1320
|
+
ws.on(t, onReply);
|
|
1321
|
+
this.wsUnsubs.push(() => ws.off(t, onReply));
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
detachRealtime() {
|
|
1325
|
+
for (const u of this.wsUnsubs) u();
|
|
1326
|
+
this.wsUnsubs = [];
|
|
1327
|
+
}
|
|
1328
|
+
// ─── Intent (cached reads) ─────────────────────────────────
|
|
1329
|
+
async feed(opts) {
|
|
1330
|
+
const key = opts?.boardId ?? "__all__";
|
|
1331
|
+
const hit = this.feedCache.get(key);
|
|
1332
|
+
if (hit && Date.now() - hit.at < this.feedTTL) {
|
|
1333
|
+
return { ok: true, data: hit.payload };
|
|
1334
|
+
}
|
|
1335
|
+
const res = await this.listPosts({
|
|
1336
|
+
boardId: opts?.boardId,
|
|
1337
|
+
limit: opts?.limit ?? 20,
|
|
1338
|
+
sort: "hot"
|
|
1339
|
+
});
|
|
1340
|
+
if (res.ok && res.data != null) {
|
|
1341
|
+
this.feedCache.set(key, { at: Date.now(), payload: res.data });
|
|
1342
|
+
}
|
|
1343
|
+
return res;
|
|
1344
|
+
}
|
|
1345
|
+
async aggregatedContext(opts) {
|
|
1346
|
+
const [feed, stats, unreadNotifications] = await Promise.all([
|
|
1347
|
+
this.feed({ boardId: opts?.boardId, limit: opts?.feedLimit ?? 15 }),
|
|
1348
|
+
this.statsCached(),
|
|
1349
|
+
this.unreadCountCached()
|
|
1350
|
+
]);
|
|
1351
|
+
return { feed, stats, unreadNotifications };
|
|
1352
|
+
}
|
|
1353
|
+
async statsCached() {
|
|
1354
|
+
if (this.statsCache && Date.now() - this.statsCache.at < this.statsTTL) {
|
|
1355
|
+
return { ok: true, data: this.statsCache.data };
|
|
1356
|
+
}
|
|
1357
|
+
const res = await this.getStats();
|
|
1358
|
+
if (res.ok && res.data != null) {
|
|
1359
|
+
this.statsCache = { at: Date.now(), data: res.data };
|
|
1360
|
+
}
|
|
1361
|
+
return res;
|
|
1362
|
+
}
|
|
1363
|
+
async unreadCountCached() {
|
|
1364
|
+
if (this.notifCountCache && Date.now() - this.notifCountCache.at < this.notifCountTTL) {
|
|
1365
|
+
return { ok: true, data: { unread: this.notifCountCache.count } };
|
|
1366
|
+
}
|
|
1367
|
+
const res = await this.getNotificationCount();
|
|
1368
|
+
const n = res.data?.unread;
|
|
1369
|
+
if (res.ok && typeof n === "number") {
|
|
1370
|
+
this.notifCountCache = { at: Date.now(), count: n };
|
|
1371
|
+
}
|
|
1372
|
+
return res;
|
|
1373
|
+
}
|
|
1374
|
+
/** Helpdesk question shortcut */
|
|
1375
|
+
async ask(title, content, tags) {
|
|
1376
|
+
const res = await this.createPost({
|
|
1377
|
+
boardId: "helpdesk",
|
|
1378
|
+
title,
|
|
1379
|
+
content,
|
|
1380
|
+
postType: "question",
|
|
1381
|
+
tags
|
|
1382
|
+
});
|
|
1383
|
+
if (res.ok) this.invalidateCache("helpdesk");
|
|
1384
|
+
return res;
|
|
1385
|
+
}
|
|
1386
|
+
/** Showcase battle report shortcut */
|
|
1387
|
+
async reportBattle(input) {
|
|
1388
|
+
const res = await this.createPost({
|
|
1389
|
+
boardId: "showcase",
|
|
1390
|
+
title: input.title,
|
|
1391
|
+
content: input.content,
|
|
1392
|
+
postType: "battleReport",
|
|
1393
|
+
tags: input.tags,
|
|
1394
|
+
linkedGeneIds: input.linkedGeneIds,
|
|
1395
|
+
linkedAgentId: input.linkedAgentId
|
|
1396
|
+
});
|
|
1397
|
+
if (res.ok) this.invalidateCache("showcase");
|
|
1398
|
+
return res;
|
|
1399
|
+
}
|
|
1400
|
+
// ─── Notifications & profile (auth) ────────────────────────
|
|
1401
|
+
async getNotifications(opts) {
|
|
1402
|
+
const q = {};
|
|
1403
|
+
if (opts?.unread) q.unread = "true";
|
|
1404
|
+
if (opts?.limit != null) q.limit = String(opts.limit);
|
|
1405
|
+
if (opts?.offset != null) q.offset = String(opts.offset);
|
|
1406
|
+
return this._r("GET", "/api/im/community/notifications", void 0, q);
|
|
1407
|
+
}
|
|
1408
|
+
async markNotificationsRead(notificationId) {
|
|
1409
|
+
const body = notificationId ? { notificationId } : {};
|
|
1410
|
+
return this._r("POST", "/api/im/community/notifications/read", body);
|
|
1411
|
+
}
|
|
1412
|
+
async getNotificationCount() {
|
|
1413
|
+
return this._r("GET", "/api/im/community/notifications/count");
|
|
1414
|
+
}
|
|
1415
|
+
async listBookmarks(opts) {
|
|
1416
|
+
const q = {};
|
|
1417
|
+
if (opts?.cursor) q.cursor = opts.cursor;
|
|
1418
|
+
if (opts?.limit != null) q.limit = String(opts.limit);
|
|
1419
|
+
return this._r("GET", "/api/im/community/bookmarks", void 0, q);
|
|
1420
|
+
}
|
|
1421
|
+
async followToggle(followingId, followingType) {
|
|
1422
|
+
return this._r("POST", "/api/im/community/follow", { followingId, followingType });
|
|
1423
|
+
}
|
|
1424
|
+
async listFollowing(type) {
|
|
1425
|
+
const q = {};
|
|
1426
|
+
if (type) q.type = type;
|
|
1427
|
+
return this._r("GET", "/api/im/community/following", void 0, q);
|
|
1428
|
+
}
|
|
1429
|
+
async listFollowers(userId) {
|
|
1430
|
+
return this._r("GET", `/api/im/community/followers/${encodeURIComponent(userId)}`);
|
|
1431
|
+
}
|
|
1432
|
+
async getProfile(userId) {
|
|
1433
|
+
return this._r("GET", `/api/im/community/profile/${encodeURIComponent(userId)}`);
|
|
1434
|
+
}
|
|
1435
|
+
// ─── REST (same surface as former CommunityClient) ─────────
|
|
1436
|
+
async createPost(input) {
|
|
1437
|
+
return this._r("POST", "/api/im/community/posts", input);
|
|
1438
|
+
}
|
|
1439
|
+
async listPosts(opts) {
|
|
1440
|
+
const query = {};
|
|
1441
|
+
if (opts?.boardId) query.boardId = opts.boardId;
|
|
1442
|
+
if (opts?.sort) query.sort = opts.sort;
|
|
1443
|
+
if (opts?.period) query.period = opts.period;
|
|
1444
|
+
if (opts?.authorType) query.authorType = opts.authorType;
|
|
1445
|
+
if (opts?.cursor) query.cursor = opts.cursor;
|
|
1446
|
+
if (opts?.limit != null) query.limit = String(opts.limit);
|
|
1447
|
+
return this._r("GET", "/api/im/community/posts", void 0, query);
|
|
1448
|
+
}
|
|
1449
|
+
async getPost(postId) {
|
|
1450
|
+
return this._r("GET", `/api/im/community/posts/${encodeURIComponent(postId)}`);
|
|
1451
|
+
}
|
|
1452
|
+
async updatePost(postId, input) {
|
|
1453
|
+
return this._r("PUT", `/api/im/community/posts/${encodeURIComponent(postId)}`, input);
|
|
1454
|
+
}
|
|
1455
|
+
async deletePost(postId) {
|
|
1456
|
+
return this._r("DELETE", `/api/im/community/posts/${encodeURIComponent(postId)}`);
|
|
1457
|
+
}
|
|
1458
|
+
async createComment(postId, input) {
|
|
1459
|
+
return this._r("POST", `/api/im/community/posts/${encodeURIComponent(postId)}/comments`, input);
|
|
1460
|
+
}
|
|
1461
|
+
async listComments(postId, opts) {
|
|
1462
|
+
const query = {};
|
|
1463
|
+
if (opts?.sort) query.sort = opts.sort;
|
|
1464
|
+
if (opts?.cursor) query.cursor = opts.cursor;
|
|
1465
|
+
if (opts?.limit != null) query.limit = String(opts.limit);
|
|
1466
|
+
return this._r("GET", `/api/im/community/posts/${encodeURIComponent(postId)}/comments`, void 0, query);
|
|
1467
|
+
}
|
|
1468
|
+
async markBestAnswer(commentId) {
|
|
1469
|
+
return this._r("POST", `/api/im/community/comments/${encodeURIComponent(commentId)}/best-answer`);
|
|
1470
|
+
}
|
|
1471
|
+
async vote(targetType, targetId, value) {
|
|
1472
|
+
return this._r("POST", "/api/im/community/vote", { targetType, targetId, value });
|
|
1473
|
+
}
|
|
1474
|
+
async bookmark(postId) {
|
|
1475
|
+
return this._r("POST", "/api/im/community/bookmark", { postId });
|
|
1476
|
+
}
|
|
1477
|
+
async search(query, opts) {
|
|
1478
|
+
const q = { q: query };
|
|
1479
|
+
if (opts?.boardId) q.boardId = opts.boardId;
|
|
1480
|
+
if (opts?.sort) q.sort = opts.sort;
|
|
1481
|
+
if (opts?.limit != null) q.limit = String(opts.limit);
|
|
1482
|
+
return this._r("GET", "/api/im/community/search", void 0, q);
|
|
1483
|
+
}
|
|
1484
|
+
async updateComment(commentId, input) {
|
|
1485
|
+
return this._r("PUT", `/api/im/community/comments/${encodeURIComponent(commentId)}`, input);
|
|
1486
|
+
}
|
|
1487
|
+
async deleteComment(commentId) {
|
|
1488
|
+
return this._r("DELETE", `/api/im/community/comments/${encodeURIComponent(commentId)}`);
|
|
1489
|
+
}
|
|
1490
|
+
async getStats() {
|
|
1491
|
+
return this._r("GET", "/api/im/community/stats");
|
|
1492
|
+
}
|
|
1493
|
+
async getTrendingTags(limit) {
|
|
1494
|
+
const query = {};
|
|
1495
|
+
if (limit != null) query.limit = String(limit);
|
|
1496
|
+
return this._r("GET", "/api/im/community/tags/trending", void 0, query);
|
|
1497
|
+
}
|
|
1498
|
+
async getHotPosts(opts) {
|
|
1499
|
+
const query = {};
|
|
1500
|
+
if (opts?.limit != null) query.limit = String(opts.limit);
|
|
1501
|
+
if (opts?.period) query.period = opts.period;
|
|
1502
|
+
return this._r("GET", "/api/im/community/hot", void 0, query);
|
|
1503
|
+
}
|
|
1504
|
+
async searchSuggest(q) {
|
|
1505
|
+
return this._r("GET", "/api/im/community/search/suggest", void 0, { q });
|
|
1506
|
+
}
|
|
1507
|
+
async autocompleteGenes(q, limit) {
|
|
1508
|
+
const query = { q };
|
|
1509
|
+
if (limit != null) query.limit = String(limit);
|
|
1510
|
+
return this._r("GET", "/api/im/community/autocomplete/genes", void 0, query);
|
|
1511
|
+
}
|
|
1512
|
+
async autocompleteSkills(q, limit) {
|
|
1513
|
+
const query = { q };
|
|
1514
|
+
if (limit != null) query.limit = String(limit);
|
|
1515
|
+
return this._r("GET", "/api/im/community/autocomplete/skills", void 0, query);
|
|
1516
|
+
}
|
|
1517
|
+
async createBattleReport(input) {
|
|
1518
|
+
return this.createPost({
|
|
1519
|
+
boardId: "showcase",
|
|
1520
|
+
title: `Battle Report: ${input.agentId}`,
|
|
1521
|
+
content: input.narrative || "Auto-generated battle report",
|
|
1522
|
+
postType: "battleReport",
|
|
1523
|
+
linkedGeneIds: input.geneIds,
|
|
1524
|
+
linkedAgentId: input.agentId
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
async createMilestone(input) {
|
|
1528
|
+
return this.createPost({
|
|
1529
|
+
boardId: "showcase",
|
|
1530
|
+
title: input.title,
|
|
1531
|
+
content: input.content,
|
|
1532
|
+
postType: "milestone",
|
|
1533
|
+
linkedGeneIds: input.geneIds,
|
|
1534
|
+
linkedAgentId: input.agentId,
|
|
1535
|
+
tags: input.tags
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
async createGeneRelease(input) {
|
|
1539
|
+
return this.createPost({
|
|
1540
|
+
boardId: "showcase",
|
|
1541
|
+
title: input.title,
|
|
1542
|
+
content: input.content,
|
|
1543
|
+
postType: "geneRelease",
|
|
1544
|
+
linkedGeneIds: [input.geneId],
|
|
1545
|
+
tags: input.tags
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1283
1548
|
};
|
|
1284
1549
|
|
|
1285
1550
|
// src/aip.ts
|
|
@@ -1287,6 +1552,12 @@ var import_aip_sdk = require("@prismer/aip-sdk");
|
|
|
1287
1552
|
var import_aip_sdk2 = require("@prismer/aip-sdk");
|
|
1288
1553
|
var import_aip_sdk3 = require("@prismer/aip-sdk");
|
|
1289
1554
|
var import_aip_sdk4 = require("@prismer/aip-sdk");
|
|
1555
|
+
var import_aip_sdk5 = require("@prismer/aip-sdk");
|
|
1556
|
+
|
|
1557
|
+
// src/types.ts
|
|
1558
|
+
var ENVIRONMENTS = {
|
|
1559
|
+
production: "https://prismer.cloud"
|
|
1560
|
+
};
|
|
1290
1561
|
|
|
1291
1562
|
// src/storage.ts
|
|
1292
1563
|
var MemoryStorage = class {
|
|
@@ -2992,6 +3263,53 @@ var EvolutionRuntime = class {
|
|
|
2992
3263
|
};
|
|
2993
3264
|
|
|
2994
3265
|
// src/index.ts
|
|
3266
|
+
var _fs = null;
|
|
3267
|
+
var _os = null;
|
|
3268
|
+
var _path = null;
|
|
3269
|
+
try {
|
|
3270
|
+
_fs = require("fs");
|
|
3271
|
+
_os = require("os");
|
|
3272
|
+
_path = require("path");
|
|
3273
|
+
} catch {
|
|
3274
|
+
}
|
|
3275
|
+
function resolveApiKey(explicit) {
|
|
3276
|
+
if (explicit) return explicit;
|
|
3277
|
+
try {
|
|
3278
|
+
if (typeof process !== "undefined" && process.env?.PRISMER_API_KEY) {
|
|
3279
|
+
return process.env.PRISMER_API_KEY;
|
|
3280
|
+
}
|
|
3281
|
+
} catch {
|
|
3282
|
+
}
|
|
3283
|
+
if (_fs && _os && _path) {
|
|
3284
|
+
try {
|
|
3285
|
+
const configPath = _path.join(_os.homedir(), ".prismer", "config.toml");
|
|
3286
|
+
const raw = _fs.readFileSync(configPath, "utf-8");
|
|
3287
|
+
const match = raw.match(/^api_key\s*=\s*'([^']+)'/m) || raw.match(/^api_key\s*=\s*"([^"]+)"/m);
|
|
3288
|
+
if (match?.[1]) return match[1];
|
|
3289
|
+
} catch {
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
return "";
|
|
3293
|
+
}
|
|
3294
|
+
function resolveBaseUrl(explicit) {
|
|
3295
|
+
if (explicit) return explicit;
|
|
3296
|
+
try {
|
|
3297
|
+
if (typeof process !== "undefined" && process.env?.PRISMER_BASE_URL) {
|
|
3298
|
+
return process.env.PRISMER_BASE_URL;
|
|
3299
|
+
}
|
|
3300
|
+
} catch {
|
|
3301
|
+
}
|
|
3302
|
+
if (_fs && _os && _path) {
|
|
3303
|
+
try {
|
|
3304
|
+
const configPath = _path.join(_os.homedir(), ".prismer", "config.toml");
|
|
3305
|
+
const raw = _fs.readFileSync(configPath, "utf-8");
|
|
3306
|
+
const match = raw.match(/^base_url\s*=\s*'([^']+)'/m) || raw.match(/^base_url\s*=\s*"([^"]+)"/m);
|
|
3307
|
+
if (match?.[1]) return match[1];
|
|
3308
|
+
} catch {
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
return void 0;
|
|
3312
|
+
}
|
|
2995
3313
|
var AccountClient = class {
|
|
2996
3314
|
constructor(_r) {
|
|
2997
3315
|
this._r = _r;
|
|
@@ -3004,6 +3322,10 @@ var AccountClient = class {
|
|
|
3004
3322
|
async me() {
|
|
3005
3323
|
return this._r("GET", "/api/im/me");
|
|
3006
3324
|
}
|
|
3325
|
+
/** Update own profile */
|
|
3326
|
+
async updateProfile(options) {
|
|
3327
|
+
return this._r("PATCH", "/api/im/me", options);
|
|
3328
|
+
}
|
|
3007
3329
|
/** Refresh JWT token */
|
|
3008
3330
|
async refreshToken() {
|
|
3009
3331
|
return this._r("POST", "/api/im/token/refresh");
|
|
@@ -3094,6 +3416,30 @@ var ConversationsClient = class {
|
|
|
3094
3416
|
async markAsRead(conversationId) {
|
|
3095
3417
|
return this._r("POST", `/api/im/conversations/${conversationId}/read`);
|
|
3096
3418
|
}
|
|
3419
|
+
/** Archive a conversation */
|
|
3420
|
+
async archive(conversationId) {
|
|
3421
|
+
return this._r("POST", `/api/im/conversations/${conversationId}/archive`);
|
|
3422
|
+
}
|
|
3423
|
+
/** Unarchive a conversation */
|
|
3424
|
+
async unarchive(conversationId) {
|
|
3425
|
+
return this._r("POST", `/api/im/conversations/${conversationId}/unarchive`);
|
|
3426
|
+
}
|
|
3427
|
+
/** Update conversation metadata */
|
|
3428
|
+
async update(conversationId, options) {
|
|
3429
|
+
return this._r("PATCH", `/api/im/conversations/${conversationId}`, options);
|
|
3430
|
+
}
|
|
3431
|
+
/** Pin or unpin a conversation */
|
|
3432
|
+
async pin(conversationId, pinned) {
|
|
3433
|
+
return this._r("PATCH", `/api/im/conversations/${conversationId}/pin`, { pinned });
|
|
3434
|
+
}
|
|
3435
|
+
/** Mute or unmute a conversation */
|
|
3436
|
+
async mute(conversationId, muted) {
|
|
3437
|
+
return this._r("PATCH", `/api/im/conversations/${conversationId}/mute`, { muted });
|
|
3438
|
+
}
|
|
3439
|
+
/** Delete a conversation */
|
|
3440
|
+
async delete(conversationId) {
|
|
3441
|
+
return this._r("DELETE", `/api/im/conversations/${conversationId}`);
|
|
3442
|
+
}
|
|
3097
3443
|
};
|
|
3098
3444
|
var MessagesClient = class {
|
|
3099
3445
|
constructor(_r) {
|
|
@@ -3123,6 +3469,10 @@ var MessagesClient = class {
|
|
|
3123
3469
|
async delete(conversationId, messageId) {
|
|
3124
3470
|
return this._r("DELETE", `/api/im/messages/${conversationId}/${messageId}`);
|
|
3125
3471
|
}
|
|
3472
|
+
/** Mark messages as delivered */
|
|
3473
|
+
async markDelivered(conversationId, messageIds) {
|
|
3474
|
+
return this._r("POST", "/api/im/messages/delivered", { conversationId, messageIds });
|
|
3475
|
+
}
|
|
3126
3476
|
};
|
|
3127
3477
|
var ContactsClient = class {
|
|
3128
3478
|
constructor(_r) {
|
|
@@ -3132,6 +3482,18 @@ var ContactsClient = class {
|
|
|
3132
3482
|
async list() {
|
|
3133
3483
|
return this._r("GET", "/api/im/contacts");
|
|
3134
3484
|
}
|
|
3485
|
+
/** Search users/agents by query */
|
|
3486
|
+
async search(query, options) {
|
|
3487
|
+
const params = { q: query };
|
|
3488
|
+
if (options?.type && options.type !== "all") params.type = options.type;
|
|
3489
|
+
if (options?.limit) params.limit = String(options.limit);
|
|
3490
|
+
if (options?.offset) params.offset = String(options.offset);
|
|
3491
|
+
return this._r("GET", "/api/im/discover", void 0, params);
|
|
3492
|
+
}
|
|
3493
|
+
/** Get a user's public profile */
|
|
3494
|
+
async getProfile(userId) {
|
|
3495
|
+
return this._r("GET", `/api/im/users/${userId}`);
|
|
3496
|
+
}
|
|
3135
3497
|
/** Discover agents by capability or type */
|
|
3136
3498
|
async discover(options) {
|
|
3137
3499
|
const query = {};
|
|
@@ -3139,6 +3501,67 @@ var ContactsClient = class {
|
|
|
3139
3501
|
if (options?.capability) query.capability = options.capability;
|
|
3140
3502
|
return this._r("GET", "/api/im/discover", void 0, query);
|
|
3141
3503
|
}
|
|
3504
|
+
// ─── Friend System (v1.8.0 P9) ─────────────────────────
|
|
3505
|
+
/** Send a friend request */
|
|
3506
|
+
async request(userId, opts) {
|
|
3507
|
+
return this._r("POST", "/api/im/contacts/request", { userId, ...opts });
|
|
3508
|
+
}
|
|
3509
|
+
/** List pending friend requests received */
|
|
3510
|
+
async pendingReceived(opts) {
|
|
3511
|
+
const params = {};
|
|
3512
|
+
if (opts?.limit) params.limit = String(opts.limit);
|
|
3513
|
+
if (opts?.offset) params.offset = String(opts.offset);
|
|
3514
|
+
return this._r("GET", "/api/im/contacts/requests/received", void 0, params);
|
|
3515
|
+
}
|
|
3516
|
+
/** List pending friend requests sent */
|
|
3517
|
+
async pendingSent(opts) {
|
|
3518
|
+
const params = {};
|
|
3519
|
+
if (opts?.limit) params.limit = String(opts.limit);
|
|
3520
|
+
if (opts?.offset) params.offset = String(opts.offset);
|
|
3521
|
+
return this._r("GET", "/api/im/contacts/requests/sent", void 0, params);
|
|
3522
|
+
}
|
|
3523
|
+
/** Accept a friend request */
|
|
3524
|
+
async accept(requestId) {
|
|
3525
|
+
return this._r("POST", `/api/im/contacts/requests/${requestId}/accept`);
|
|
3526
|
+
}
|
|
3527
|
+
/** Reject a friend request */
|
|
3528
|
+
async reject(requestId) {
|
|
3529
|
+
return this._r("POST", `/api/im/contacts/requests/${requestId}/reject`);
|
|
3530
|
+
}
|
|
3531
|
+
/** List friends */
|
|
3532
|
+
async friends(opts) {
|
|
3533
|
+
const params = {};
|
|
3534
|
+
if (opts?.limit) params.limit = String(opts.limit);
|
|
3535
|
+
if (opts?.offset) params.offset = String(opts.offset);
|
|
3536
|
+
return this._r("GET", "/api/im/contacts/friends", void 0, params);
|
|
3537
|
+
}
|
|
3538
|
+
/** Remove a friend */
|
|
3539
|
+
async remove(userId) {
|
|
3540
|
+
return this._r("DELETE", `/api/im/contacts/${userId}/remove`);
|
|
3541
|
+
}
|
|
3542
|
+
/** Set a remark/alias for a contact */
|
|
3543
|
+
async setRemark(userId, remark) {
|
|
3544
|
+
return this._r("PATCH", `/api/im/contacts/${userId}/remark`, { remark });
|
|
3545
|
+
}
|
|
3546
|
+
/** Block a user */
|
|
3547
|
+
async block(userId) {
|
|
3548
|
+
return this._r("POST", `/api/im/contacts/${userId}/block`, {});
|
|
3549
|
+
}
|
|
3550
|
+
/** Unblock a user */
|
|
3551
|
+
async unblock(userId) {
|
|
3552
|
+
return this._r("DELETE", `/api/im/contacts/${userId}/block`);
|
|
3553
|
+
}
|
|
3554
|
+
/** List blocked users */
|
|
3555
|
+
async blocklist(opts) {
|
|
3556
|
+
const params = {};
|
|
3557
|
+
if (opts?.limit) params.limit = String(opts.limit);
|
|
3558
|
+
if (opts?.offset) params.offset = String(opts.offset);
|
|
3559
|
+
return this._r("GET", "/api/im/contacts/blocked", void 0, params);
|
|
3560
|
+
}
|
|
3561
|
+
/** Get presence status for multiple users */
|
|
3562
|
+
async getPresence(userIds) {
|
|
3563
|
+
return this._r("POST", "/api/im/presence/batch", { userIds });
|
|
3564
|
+
}
|
|
3142
3565
|
};
|
|
3143
3566
|
var BindingsClient = class {
|
|
3144
3567
|
constructor(_r) {
|
|
@@ -3290,6 +3713,23 @@ var MemoryClient = class {
|
|
|
3290
3713
|
if (scope) query.scope = scope;
|
|
3291
3714
|
return this._r("GET", "/api/im/memory/load", void 0, query);
|
|
3292
3715
|
}
|
|
3716
|
+
/** Get memory-gene knowledge links for the authenticated user's memory files (v1.8.0) */
|
|
3717
|
+
async getKnowledgeLinks() {
|
|
3718
|
+
return this._r("GET", "/api/im/memory/links");
|
|
3719
|
+
}
|
|
3720
|
+
};
|
|
3721
|
+
var KnowledgeLinkClient = class {
|
|
3722
|
+
constructor(_r) {
|
|
3723
|
+
this._r = _r;
|
|
3724
|
+
}
|
|
3725
|
+
/**
|
|
3726
|
+
* Get all knowledge links for a given entity.
|
|
3727
|
+
* @param entityType - One of: memory, gene, capsule, signal
|
|
3728
|
+
* @param entityId - The entity ID
|
|
3729
|
+
*/
|
|
3730
|
+
async getLinks(entityType, entityId) {
|
|
3731
|
+
return this._r("GET", "/api/im/knowledge/links", void 0, { entityType, entityId });
|
|
3732
|
+
}
|
|
3293
3733
|
};
|
|
3294
3734
|
var IdentityClient = class {
|
|
3295
3735
|
constructor(_r) {
|
|
@@ -3392,6 +3832,62 @@ var EvolutionClient = class {
|
|
|
3392
3832
|
if (limit != null) query.limit = String(limit);
|
|
3393
3833
|
return this._r("GET", "/api/im/evolution/public/feed", void 0, query);
|
|
3394
3834
|
}
|
|
3835
|
+
// ── Leaderboard V2 (public, no auth required) ──
|
|
3836
|
+
/** Get hero section global stats (total agents, genes, capsules, savings) */
|
|
3837
|
+
async getLeaderboardHero() {
|
|
3838
|
+
return this._r("GET", "/api/im/evolution/leaderboard/hero");
|
|
3839
|
+
}
|
|
3840
|
+
/** Get rising stars leaderboard */
|
|
3841
|
+
async getLeaderboardRising(period, limit) {
|
|
3842
|
+
const query = {};
|
|
3843
|
+
if (period) query.period = period;
|
|
3844
|
+
if (limit != null) query.limit = String(limit);
|
|
3845
|
+
return this._r("GET", "/api/im/evolution/leaderboard/rising", void 0, query);
|
|
3846
|
+
}
|
|
3847
|
+
/** Get leaderboard summary stats (totalAgentsEvolving, totalGenesCreated, etc.) */
|
|
3848
|
+
async getLeaderboardStats() {
|
|
3849
|
+
return this._r("GET", "/api/im/evolution/leaderboard/stats");
|
|
3850
|
+
}
|
|
3851
|
+
/** Get agent improvement board */
|
|
3852
|
+
async getLeaderboardAgents(period, domain) {
|
|
3853
|
+
const query = {};
|
|
3854
|
+
if (period) query.period = period;
|
|
3855
|
+
if (domain) query.domain = domain;
|
|
3856
|
+
return this._r("GET", "/api/im/evolution/leaderboard/agents", void 0, query);
|
|
3857
|
+
}
|
|
3858
|
+
/** Get gene impact board */
|
|
3859
|
+
async getLeaderboardGenes(period, sort) {
|
|
3860
|
+
const query = {};
|
|
3861
|
+
if (period) query.period = period;
|
|
3862
|
+
if (sort) query.sort = sort;
|
|
3863
|
+
return this._r("GET", "/api/im/evolution/leaderboard/genes", void 0, query);
|
|
3864
|
+
}
|
|
3865
|
+
/** Get contributor board */
|
|
3866
|
+
async getLeaderboardContributors(period) {
|
|
3867
|
+
const query = {};
|
|
3868
|
+
if (period) query.period = period;
|
|
3869
|
+
return this._r("GET", "/api/im/evolution/leaderboard/contributors", void 0, query);
|
|
3870
|
+
}
|
|
3871
|
+
/** Get cross-environment comparison data */
|
|
3872
|
+
async getLeaderboardComparison() {
|
|
3873
|
+
return this._r("GET", "/api/im/evolution/leaderboard/comparison");
|
|
3874
|
+
}
|
|
3875
|
+
/** Get public profile page data for an agent or owner */
|
|
3876
|
+
async getPublicProfile(entityId) {
|
|
3877
|
+
return this._r("GET", `/api/im/evolution/profile/${encodeURIComponent(entityId)}`);
|
|
3878
|
+
}
|
|
3879
|
+
/** Render agent/creator card as PNG */
|
|
3880
|
+
async renderCard(input) {
|
|
3881
|
+
return this._r("POST", "/api/im/evolution/card/render", input);
|
|
3882
|
+
}
|
|
3883
|
+
/** Get benchmark data for profile FOMO section */
|
|
3884
|
+
async getBenchmark() {
|
|
3885
|
+
return this._r("GET", "/api/im/evolution/benchmark");
|
|
3886
|
+
}
|
|
3887
|
+
/** Get gene highlight capsules for profile page */
|
|
3888
|
+
async getHighlights(geneId) {
|
|
3889
|
+
return this._r("GET", `/api/im/evolution/highlights/${encodeURIComponent(geneId)}`);
|
|
3890
|
+
}
|
|
3395
3891
|
// ── Authenticated endpoints ──
|
|
3396
3892
|
/** Analyze signals and get gene recommendation */
|
|
3397
3893
|
async analyze(options) {
|
|
@@ -3548,8 +4044,8 @@ var EvolutionClient = class {
|
|
|
3548
4044
|
return this._r("GET", "/api/im/skills/stats");
|
|
3549
4045
|
}
|
|
3550
4046
|
/** Install a skill — creates Gene + returns content + install guide */
|
|
3551
|
-
async installSkill(slugOrId) {
|
|
3552
|
-
return this._r("POST", `/api/im/skills/${encodeURIComponent(slugOrId)}/install
|
|
4047
|
+
async installSkill(slugOrId, scope) {
|
|
4048
|
+
return this._r("POST", `/api/im/skills/${encodeURIComponent(slugOrId)}/install`, scope ? { scope } : void 0);
|
|
3553
4049
|
}
|
|
3554
4050
|
/** Uninstall a skill */
|
|
3555
4051
|
async uninstallSkill(slugOrId) {
|
|
@@ -3986,7 +4482,7 @@ var IMRealtimeClient = class {
|
|
|
3986
4482
|
}
|
|
3987
4483
|
};
|
|
3988
4484
|
var IMClient = class {
|
|
3989
|
-
constructor(request, wsBase, fetchFn, getAuthHeaders, offlineManager) {
|
|
4485
|
+
constructor(request, wsBase, fetchFn, getAuthHeaders, offlineManager, communityHubConfig) {
|
|
3990
4486
|
this.account = new AccountClient(request);
|
|
3991
4487
|
this.direct = new DirectClient(request);
|
|
3992
4488
|
this.groups = new GroupsClient(request);
|
|
@@ -3998,9 +4494,11 @@ var IMClient = class {
|
|
|
3998
4494
|
this.workspace = new WorkspaceClient(request);
|
|
3999
4495
|
this.tasks = new TasksClient(request);
|
|
4000
4496
|
this.memory = new MemoryClient(request);
|
|
4497
|
+
this.knowledge = new KnowledgeLinkClient(request);
|
|
4001
4498
|
this.identity = new IdentityClient(request);
|
|
4002
4499
|
this.security = new SecurityClient(request);
|
|
4003
4500
|
this.evolution = new EvolutionClient(request);
|
|
4501
|
+
this.community = new CommunityHub(request, communityHubConfig ?? void 0);
|
|
4004
4502
|
this.files = new FilesClient(request, wsBase, fetchFn, getAuthHeaders);
|
|
4005
4503
|
this.realtime = new IMRealtimeClient(wsBase);
|
|
4006
4504
|
this.offline = offlineManager ?? null;
|
|
@@ -4009,19 +4507,43 @@ var IMClient = class {
|
|
|
4009
4507
|
async health() {
|
|
4010
4508
|
return this.account["_r"]("GET", "/api/im/health");
|
|
4011
4509
|
}
|
|
4510
|
+
/** Get workspace superset view with slot filtering */
|
|
4511
|
+
async getWorkspace(scope, slots, includeContent) {
|
|
4512
|
+
const params = new URLSearchParams();
|
|
4513
|
+
if (scope) params.set("scope", scope);
|
|
4514
|
+
if (slots?.length) params.set("slots", slots.join(","));
|
|
4515
|
+
if (includeContent) params.set("includeContent", "true");
|
|
4516
|
+
return this.workspace["_r"]("GET", `/api/im/workspace/view?${params}`);
|
|
4517
|
+
}
|
|
4012
4518
|
};
|
|
4013
4519
|
var PrismerClient = class {
|
|
4014
4520
|
constructor(config = {}) {
|
|
4015
4521
|
this._offlineManager = null;
|
|
4016
|
-
|
|
4522
|
+
/** AIP identity for auto-signing (v1.8.0 S1) */
|
|
4523
|
+
this._identity = null;
|
|
4524
|
+
this._identityReady = null;
|
|
4525
|
+
const resolvedApiKey = resolveApiKey(config.apiKey);
|
|
4526
|
+
if (resolvedApiKey && !resolvedApiKey.startsWith("sk-prismer-") && !resolvedApiKey.startsWith("eyJ")) {
|
|
4017
4527
|
console.warn('Warning: API key should start with "sk-prismer-" (or "eyJ" for IM JWT)');
|
|
4018
4528
|
}
|
|
4019
|
-
this.apiKey =
|
|
4529
|
+
this.apiKey = resolvedApiKey;
|
|
4020
4530
|
const envUrl = ENVIRONMENTS[config.environment || "production"];
|
|
4021
|
-
this.baseUrl = (config.baseUrl || envUrl).replace(/\/$/, "");
|
|
4531
|
+
this.baseUrl = (resolveBaseUrl(config.baseUrl) || envUrl).replace(/\/$/, "");
|
|
4022
4532
|
this.timeout = config.timeout || 3e4;
|
|
4023
4533
|
this.fetchFn = config.fetch || fetch;
|
|
4024
4534
|
this.imAgent = config.imAgent;
|
|
4535
|
+
if (config.identity) {
|
|
4536
|
+
if (config.identity === "auto" && this.apiKey) {
|
|
4537
|
+
this._identityReady = import_aip_sdk.AIPIdentity.fromApiKey(this.apiKey).then((id) => {
|
|
4538
|
+
this._identity = id;
|
|
4539
|
+
}).catch((err) => console.warn("[PrismerSDK] Identity init failed:", err));
|
|
4540
|
+
} else if (typeof config.identity === "object" && config.identity.privateKey) {
|
|
4541
|
+
const keyBytes = typeof Buffer !== "undefined" ? new Uint8Array(Buffer.from(config.identity.privateKey, "base64")) : new Uint8Array(atob(config.identity.privateKey).split("").map((c) => c.charCodeAt(0)));
|
|
4542
|
+
this._identityReady = import_aip_sdk.AIPIdentity.fromPrivateKey(keyBytes).then((id) => {
|
|
4543
|
+
this._identity = id;
|
|
4544
|
+
}).catch((err) => console.warn("[PrismerSDK] Identity init failed:", err));
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4025
4547
|
if (config.offline) {
|
|
4026
4548
|
this._offlineManager = new OfflineManager(
|
|
4027
4549
|
config.offline.storage,
|
|
@@ -4032,14 +4554,60 @@ var PrismerClient = class {
|
|
|
4032
4554
|
(err) => console.warn("[PrismerSDK] Offline storage init failed:", err)
|
|
4033
4555
|
);
|
|
4034
4556
|
}
|
|
4035
|
-
|
|
4557
|
+
let imRequest = this._offlineManager ? (m, p, b, q) => this._offlineManager.dispatch(m, p, b, q) : (m, p, b, q) => this._request(m, p, b, q);
|
|
4558
|
+
if (config.identity) {
|
|
4559
|
+
const baseRequest = imRequest;
|
|
4560
|
+
imRequest = (method, path, body, query) => {
|
|
4561
|
+
if (method === "POST" && path.includes("/messages") && body) {
|
|
4562
|
+
const b = body;
|
|
4563
|
+
if (!b.signature && !b.skipSigning) {
|
|
4564
|
+
const ready = this._identityReady || Promise.resolve();
|
|
4565
|
+
return ready.then(() => {
|
|
4566
|
+
if (this._identity) {
|
|
4567
|
+
return this._signAndSend(baseRequest, method, path, b, query);
|
|
4568
|
+
}
|
|
4569
|
+
return baseRequest(method, path, body, query);
|
|
4570
|
+
});
|
|
4571
|
+
}
|
|
4572
|
+
}
|
|
4573
|
+
return baseRequest(method, path, body, query);
|
|
4574
|
+
};
|
|
4575
|
+
}
|
|
4036
4576
|
this.im = new IMClient(
|
|
4037
4577
|
imRequest,
|
|
4038
4578
|
this.baseUrl,
|
|
4039
4579
|
this.fetchFn,
|
|
4040
4580
|
() => this._getAuthHeaders(),
|
|
4041
|
-
this._offlineManager
|
|
4581
|
+
this._offlineManager,
|
|
4582
|
+
config.community ?? null
|
|
4583
|
+
);
|
|
4584
|
+
}
|
|
4585
|
+
/** Wait for identity to be ready (useful for tests or explicit await) */
|
|
4586
|
+
async ensureIdentity() {
|
|
4587
|
+
if (this._identityReady) await this._identityReady;
|
|
4588
|
+
return this._identity;
|
|
4589
|
+
}
|
|
4590
|
+
/** Auto-sign a message body and send (v1.8.0 S1) */
|
|
4591
|
+
async _signAndSend(baseRequest, method, path, body, query) {
|
|
4592
|
+
if (this._identityReady) await this._identityReady;
|
|
4593
|
+
if (!this._identity) return baseRequest(method, path, body, query);
|
|
4594
|
+
const content = body.content || "";
|
|
4595
|
+
const contentHashBytes = new Uint8Array(
|
|
4596
|
+
await crypto.subtle.digest("SHA-256", new TextEncoder().encode(content))
|
|
4042
4597
|
);
|
|
4598
|
+
const contentHash = Array.from(contentHashBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
4599
|
+
const timestamp = Date.now();
|
|
4600
|
+
const payload = `1|${this._identity.did}|${body.type || "text"}|${timestamp}|${contentHash}`;
|
|
4601
|
+
const payloadBytes = new TextEncoder().encode(payload);
|
|
4602
|
+
const signature = await this._identity.sign(payloadBytes);
|
|
4603
|
+
return baseRequest(method, path, {
|
|
4604
|
+
...body,
|
|
4605
|
+
secVersion: 1,
|
|
4606
|
+
senderDid: this._identity.did,
|
|
4607
|
+
contentHash,
|
|
4608
|
+
signature,
|
|
4609
|
+
signedAt: timestamp
|
|
4610
|
+
}, query);
|
|
4043
4611
|
}
|
|
4044
4612
|
/** Build auth headers for raw HTTP requests (used by file upload) */
|
|
4045
4613
|
_getAuthHeaders() {
|
|
@@ -4179,6 +4747,7 @@ function createClient(config) {
|
|
|
4179
4747
|
AccountClient,
|
|
4180
4748
|
AttachmentQueue,
|
|
4181
4749
|
BindingsClient,
|
|
4750
|
+
CommunityHub,
|
|
4182
4751
|
ContactsClient,
|
|
4183
4752
|
ConversationsClient,
|
|
4184
4753
|
CreditsClient,
|
|
@@ -4194,6 +4763,7 @@ function createClient(config) {
|
|
|
4194
4763
|
IMRealtimeClient,
|
|
4195
4764
|
IdentityClient,
|
|
4196
4765
|
IndexedDBStorage,
|
|
4766
|
+
KnowledgeLinkClient,
|
|
4197
4767
|
MemoryClient,
|
|
4198
4768
|
MemoryStorage,
|
|
4199
4769
|
MessagesClient,
|