@parall/daemon 1.56.2 → 1.57.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.56.2",
3
- "built_at": "2026-08-21T14:21:02.917Z",
2
+ "version": "1.57.2",
3
+ "built_at": "2026-08-26T07:35:41.010Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,29 +16,29 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-browser-pod.js": {
19
- "sha256": "d7cd22077f1c4bb49e2d52c220f092015f5feb44732943ee57b4350c88c6dc68",
20
- "size": 2964867
19
+ "sha256": "81a136935d0fa9ded798144cda124e4de3c3d22d2c24d2af0a2105365b3c3891",
20
+ "size": 2969047
21
21
  },
22
22
  "parall-channel-exec.js": {
23
23
  "sha256": "7c2a6e12483a45e9eb4a42cd7d4cdd3c4fa21dd09ac1347d9a3e177b4ddee930",
24
24
  "size": 7220
25
25
  },
26
26
  "parall-claude-agent.js": {
27
- "sha256": "62f6d64a5a6ee8b46a1d2505cbe05226420128b59bcaa10c2ec9d5b0637dd460",
28
- "size": 2844167
27
+ "sha256": "abca61cfc6fa086584781ffc300f493b8fe818b168da379dd0638afa9582d9db",
28
+ "size": 2849176
29
29
  },
30
30
  "parall-codex-agent.js": {
31
- "sha256": "11d4c536300daeef09e471f28c474dddd0ebcb91cc18c9a34828f6756de75d5f",
32
- "size": 2876114
31
+ "sha256": "0f41b9dd43be175c6f7e5a8989f799004588732d2a81674656add743c524ea11",
32
+ "size": 2881123
33
33
  },
34
34
  "parall-daemon.js": {
35
- "sha256": "bd184a0cf0c6f026ce4c9e3b6630973e109e4d232994a8199791b0418e9384ce",
36
- "size": 3032407
35
+ "sha256": "79e558e4e69e73db93029418e82c607dcb18e9d1891342a974af7c1f35f9cec6",
36
+ "size": 3037422
37
37
  },
38
38
  "parall-openclaw-agent.js": {
39
39
  "sha256": "856a1c3a9ae0ffef8efe2481fa1171dbeb1d67cccb88616aa9bf16da96a69355",
40
40
  "size": 9923
41
41
  }
42
42
  },
43
- "signature": "o7p9D5wm97kql2R2fN4lHpJfUQdCWAIaz8UUUVcYZ0gQsqZzS8AmnjsJguD0NpfuZZagmM2SrVKjs62QfbCBCA=="
43
+ "signature": "s7/Y06qvTX2tprHtamtkdVNBDk1CBafGArPkoJDAKbO6gNrcSYcONmDGpP0/gcHvLTeuabt82mW5mGRE9Pq8Bg=="
44
44
  }
@@ -63579,6 +63579,24 @@ var ENDPOINTS = {
63579
63579
  TEAM_MEMBERS: (orgId, teamId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members`,
63580
63580
  TEAM_MEMBER: (orgId, teamId, userId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members/${userId}`,
63581
63581
  ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
63582
+ LLM_PROVIDERS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-providers`,
63583
+ LLM_PROVIDER: (orgId, providerId) => `${API_BASE}/orgs/${orgId}/llm-providers/${providerId}`,
63584
+ ORG_LLM_MODELS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-models`,
63585
+ ORG_LLM_MODEL: (orgId, modelRowId) => `${API_BASE}/orgs/${orgId}/llm-models/${modelRowId}`,
63586
+ /**
63587
+ * Platform catalog merged with this org's own model rows. Pass `runtime` to
63588
+ * filter org-added models to the ones that runtime can actually reach —
63589
+ * without it a picker can offer a model the write path rejects.
63590
+ */
63591
+ ORG_MODEL_CATALOG: (orgId, runtime, includeModel) => {
63592
+ const params = new URLSearchParams();
63593
+ if (runtime)
63594
+ params.set("runtime", runtime);
63595
+ if (includeModel)
63596
+ params.set("include_model", includeModel);
63597
+ const qs = params.toString();
63598
+ return `${API_BASE}/orgs/${orgId}/models${qs ? `?${qs}` : ""}`;
63599
+ },
63582
63600
  ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
63583
63601
  ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
63584
63602
  ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
@@ -63805,6 +63823,7 @@ var ENDPOINTS = {
63805
63823
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
63806
63824
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
63807
63825
  WIKI_TREE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
63826
+ WIKI_TREE_LAST_COMMITS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree/last-commits`,
63808
63827
  WIKI_BLOB: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
63809
63828
  WIKI_COPY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
63810
63829
  WIKI_NODE_SECTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
@@ -64241,6 +64260,55 @@ var WechatClient = class extends TaskLabelClient {
64241
64260
  }
64242
64261
  };
64243
64262
 
64263
+ // ts/sdk/dist/llm-provider-client.js
64264
+ var LLMProviderClient = class extends WechatClient {
64265
+ async getLLMProviders(orgId) {
64266
+ const response = await this.request("GET", ENDPOINTS.LLM_PROVIDERS(orgId));
64267
+ return response.data;
64268
+ }
64269
+ async createLLMProvider(orgId, data2) {
64270
+ return this.request("POST", ENDPOINTS.LLM_PROVIDERS(orgId), data2);
64271
+ }
64272
+ /** Omitting `api_key` leaves the stored credential untouched. */
64273
+ async updateLLMProvider(orgId, providerId, data2) {
64274
+ return this.request("PATCH", ENDPOINTS.LLM_PROVIDER(orgId, providerId), data2);
64275
+ }
64276
+ /** Fails with PROVIDER_IN_USE while model rows still point at it. */
64277
+ async deleteLLMProvider(orgId, providerId) {
64278
+ return this.request("DELETE", ENDPOINTS.LLM_PROVIDER(orgId, providerId));
64279
+ }
64280
+ async getOrgLLMModels(orgId) {
64281
+ const response = await this.request("GET", ENDPOINTS.ORG_LLM_MODELS(orgId));
64282
+ return response.data;
64283
+ }
64284
+ async createOrgLLMModel(orgId, data2) {
64285
+ return this.request("POST", ENDPOINTS.ORG_LLM_MODELS(orgId), data2);
64286
+ }
64287
+ /**
64288
+ * Patches a model row in place. Repointing a provider or fixing an upstream
64289
+ * name this way avoids the delete-and-recreate window, during which an
64290
+ * org-only model has no upstream at all and its pinned agents fail.
64291
+ */
64292
+ async updateOrgLLMModel(orgId, modelRowId, data2) {
64293
+ return this.request("PATCH", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId), data2);
64294
+ }
64295
+ async deleteOrgLLMModel(orgId, modelRowId) {
64296
+ return this.request("DELETE", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId));
64297
+ }
64298
+ /**
64299
+ * The catalog as this org sees it: platform models with the org's rows
64300
+ * merged in. Distinct from the public model catalog, which stays org-agnostic
64301
+ * and cacheable — use this one wherever an org context exists.
64302
+ *
64303
+ * Pass `runtime` on a picker: org-added models are then filtered to what that
64304
+ * runtime's protocol can reach, matching the server-side pin validation.
64305
+ */
64306
+ async getOrgModelCatalog(orgId, runtime, includeModel) {
64307
+ const response = await this.request("GET", ENDPOINTS.ORG_MODEL_CATALOG(orgId, runtime, includeModel));
64308
+ return response.data;
64309
+ }
64310
+ };
64311
+
64244
64312
  // ts/sdk/dist/attachment-client.js
64245
64313
  var COMPLETION_RETRY_DELAYS_MS = [250, 750];
64246
64314
  function isRetryableCompletionError(error2) {
@@ -64249,7 +64317,7 @@ function isRetryableCompletionError(error2) {
64249
64317
  const status = error2.status;
64250
64318
  return status === 0 || typeof status === "number" && status >= 500;
64251
64319
  }
64252
- var AttachmentClient = class extends WechatClient {
64320
+ var AttachmentClient = class extends LLMProviderClient {
64253
64321
  async getUploadPresignUrl(orgId, req) {
64254
64322
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
64255
64323
  }
@@ -65806,8 +65874,27 @@ var ParallClient = class _ParallClient extends AttachmentClient {
65806
65874
  const res = await this.request("GET", ENDPOINTS.WIKIS_DELETED(orgId));
65807
65875
  return res.data;
65808
65876
  }
65809
- async getWikiTree(orgId, wikiId, params) {
65810
- return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params);
65877
+ /**
65878
+ * List the direct children of a wiki directory. The response carries
65879
+ * `head_sha`, the immutable commit it was read at; render the rows first
65880
+ * and fetch their dates with `getWikiTreeLastCommits` pinned to it.
65881
+ * `last_commit: true` is the legacy single-request form (dates composed
65882
+ * server-side); prefer the two-phase flow so the structure is never held
65883
+ * back by history reads. Pass `signal` to abort on navigation.
65884
+ */
65885
+ async getWikiTree(orgId, wikiId, params, opts) {
65886
+ return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params, false, opts);
65887
+ }
65888
+ /**
65889
+ * Second phase of a directory listing: last-commit dates for the direct
65890
+ * children of `path` at `ref`, which must be the `head_sha` a
65891
+ * `getWikiTree` response carried (a branch name is rejected). Merge the
65892
+ * dates only while the returned `head_sha` still matches the rows on
65893
+ * screen; a failure just leaves the dates blank. Pass `signal` to abort
65894
+ * on navigation.
65895
+ */
65896
+ async getWikiTreeLastCommits(orgId, wikiId, params, opts) {
65897
+ return this.request("GET", ENDPOINTS.WIKI_TREE_LAST_COMMITS(orgId, wikiId), void 0, params, false, opts);
65811
65898
  }
65812
65899
  /**
65813
65900
  * Resolve a server-returned, host-relative media URL (a wiki `signed_url`
@@ -51487,6 +51487,9 @@ function formatApprovalDecisionReason(status, reason) {
51487
51487
  return "";
51488
51488
  return `Reason (JSON): ${JSON.stringify(normalized)}`;
51489
51489
  }
51490
+ function threadWatcherHint(threadRootId) {
51491
+ return `[Hint: watcher \u2014 you were not addressed in this reply. Reply only if you add something new; otherwise run \`parall no-reply\`. If this thread is not relevant to you, or you have nothing more to contribute, run \`parall messages unwatch prll://${threadRootId}\` so later replies stop waking you.]`;
51492
+ }
51490
51493
  function buildEventBody(event) {
51491
51494
  const lines = [];
51492
51495
  if (event.type === "message") {
@@ -51506,6 +51509,9 @@ function buildEventBody(event) {
51506
51509
  }
51507
51510
  if (event.deliveryReason)
51508
51511
  lines.push(`[Delivery: ${sanitizeMeta(event.deliveryReason)}]`);
51512
+ if (event.deliveryReason === "watcher" && event.threadRootId) {
51513
+ lines.push(threadWatcherHint(sanitizeMeta(event.threadRootId)));
51514
+ }
51509
51515
  if (event.unreadCount != null && event.unreadCount > 1) {
51510
51516
  const countStr = event.unreadCount >= 1e3 ? "999+" : String(event.unreadCount);
51511
51517
  const sinceStr = event.unreadSince ? ` | since: prll://${event.unreadSince}` : "";
@@ -51566,7 +51572,10 @@ function buildEventBody(event) {
51566
51572
  } else if (event.type === "channel_message") {
51567
51573
  lines.push(`[Event: channel.message]`);
51568
51574
  const providerLabel = sanitizeMeta(event.channelProvider ?? "external IM");
51569
- const convLabel = event.channelExternalConversationId ? `${sanitizeMeta(event.channelExternalConversationId)} (${sanitizeMeta(event.channelConversationType ?? "conversation")})` : sanitizeMeta(event.channelConversationType ?? "conversation");
51575
+ const convType = sanitizeMeta(event.channelConversationType ?? "conversation");
51576
+ const convId = event.channelExternalConversationId ? sanitizeMeta(event.channelExternalConversationId) : void 0;
51577
+ const convName = event.channelExternalConversationName ? sanitizeMeta(event.channelExternalConversationName) : void 0;
51578
+ const convLabel = convName ? `${convName} (${convId ? `${convId}, ` : ""}${convType})` : convId ? `${convId} (${convType})` : convType;
51570
51579
  lines.push(`[Channel: ${providerLabel} | conversation: ${convLabel}]`);
51571
51580
  lines.push(`[From: ${sanitizeMeta(event.senderName)} (external user, not a Parall member)]`);
51572
51581
  if (event.channelExternalMessageId) {
@@ -51755,6 +51764,24 @@ var ENDPOINTS = {
51755
51764
  TEAM_MEMBERS: (orgId, teamId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members`,
51756
51765
  TEAM_MEMBER: (orgId, teamId, userId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members/${userId}`,
51757
51766
  ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
51767
+ LLM_PROVIDERS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-providers`,
51768
+ LLM_PROVIDER: (orgId, providerId) => `${API_BASE}/orgs/${orgId}/llm-providers/${providerId}`,
51769
+ ORG_LLM_MODELS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-models`,
51770
+ ORG_LLM_MODEL: (orgId, modelRowId) => `${API_BASE}/orgs/${orgId}/llm-models/${modelRowId}`,
51771
+ /**
51772
+ * Platform catalog merged with this org's own model rows. Pass `runtime` to
51773
+ * filter org-added models to the ones that runtime can actually reach —
51774
+ * without it a picker can offer a model the write path rejects.
51775
+ */
51776
+ ORG_MODEL_CATALOG: (orgId, runtime, includeModel) => {
51777
+ const params = new URLSearchParams();
51778
+ if (runtime)
51779
+ params.set("runtime", runtime);
51780
+ if (includeModel)
51781
+ params.set("include_model", includeModel);
51782
+ const qs = params.toString();
51783
+ return `${API_BASE}/orgs/${orgId}/models${qs ? `?${qs}` : ""}`;
51784
+ },
51758
51785
  ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
51759
51786
  ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
51760
51787
  ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
@@ -51981,6 +52008,7 @@ var ENDPOINTS = {
51981
52008
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
51982
52009
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
51983
52010
  WIKI_TREE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
52011
+ WIKI_TREE_LAST_COMMITS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree/last-commits`,
51984
52012
  WIKI_BLOB: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
51985
52013
  WIKI_COPY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
51986
52014
  WIKI_NODE_SECTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
@@ -52508,6 +52536,55 @@ var WechatClient = class extends TaskLabelClient {
52508
52536
  }
52509
52537
  };
52510
52538
 
52539
+ // ts/sdk/dist/llm-provider-client.js
52540
+ var LLMProviderClient = class extends WechatClient {
52541
+ async getLLMProviders(orgId) {
52542
+ const response = await this.request("GET", ENDPOINTS.LLM_PROVIDERS(orgId));
52543
+ return response.data;
52544
+ }
52545
+ async createLLMProvider(orgId, data) {
52546
+ return this.request("POST", ENDPOINTS.LLM_PROVIDERS(orgId), data);
52547
+ }
52548
+ /** Omitting `api_key` leaves the stored credential untouched. */
52549
+ async updateLLMProvider(orgId, providerId, data) {
52550
+ return this.request("PATCH", ENDPOINTS.LLM_PROVIDER(orgId, providerId), data);
52551
+ }
52552
+ /** Fails with PROVIDER_IN_USE while model rows still point at it. */
52553
+ async deleteLLMProvider(orgId, providerId) {
52554
+ return this.request("DELETE", ENDPOINTS.LLM_PROVIDER(orgId, providerId));
52555
+ }
52556
+ async getOrgLLMModels(orgId) {
52557
+ const response = await this.request("GET", ENDPOINTS.ORG_LLM_MODELS(orgId));
52558
+ return response.data;
52559
+ }
52560
+ async createOrgLLMModel(orgId, data) {
52561
+ return this.request("POST", ENDPOINTS.ORG_LLM_MODELS(orgId), data);
52562
+ }
52563
+ /**
52564
+ * Patches a model row in place. Repointing a provider or fixing an upstream
52565
+ * name this way avoids the delete-and-recreate window, during which an
52566
+ * org-only model has no upstream at all and its pinned agents fail.
52567
+ */
52568
+ async updateOrgLLMModel(orgId, modelRowId, data) {
52569
+ return this.request("PATCH", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId), data);
52570
+ }
52571
+ async deleteOrgLLMModel(orgId, modelRowId) {
52572
+ return this.request("DELETE", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId));
52573
+ }
52574
+ /**
52575
+ * The catalog as this org sees it: platform models with the org's rows
52576
+ * merged in. Distinct from the public model catalog, which stays org-agnostic
52577
+ * and cacheable — use this one wherever an org context exists.
52578
+ *
52579
+ * Pass `runtime` on a picker: org-added models are then filtered to what that
52580
+ * runtime's protocol can reach, matching the server-side pin validation.
52581
+ */
52582
+ async getOrgModelCatalog(orgId, runtime, includeModel) {
52583
+ const response = await this.request("GET", ENDPOINTS.ORG_MODEL_CATALOG(orgId, runtime, includeModel));
52584
+ return response.data;
52585
+ }
52586
+ };
52587
+
52511
52588
  // ts/sdk/dist/attachment-client.js
52512
52589
  var COMPLETION_RETRY_DELAYS_MS = [250, 750];
52513
52590
  function isRetryableCompletionError(error) {
@@ -52516,7 +52593,7 @@ function isRetryableCompletionError(error) {
52516
52593
  const status = error.status;
52517
52594
  return status === 0 || typeof status === "number" && status >= 500;
52518
52595
  }
52519
- var AttachmentClient = class extends WechatClient {
52596
+ var AttachmentClient = class extends LLMProviderClient {
52520
52597
  async getUploadPresignUrl(orgId, req) {
52521
52598
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
52522
52599
  }
@@ -54073,8 +54150,27 @@ var ParallClient = class _ParallClient extends AttachmentClient {
54073
54150
  const res = await this.request("GET", ENDPOINTS.WIKIS_DELETED(orgId));
54074
54151
  return res.data;
54075
54152
  }
54076
- async getWikiTree(orgId, wikiId, params) {
54077
- return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params);
54153
+ /**
54154
+ * List the direct children of a wiki directory. The response carries
54155
+ * `head_sha`, the immutable commit it was read at; render the rows first
54156
+ * and fetch their dates with `getWikiTreeLastCommits` pinned to it.
54157
+ * `last_commit: true` is the legacy single-request form (dates composed
54158
+ * server-side); prefer the two-phase flow so the structure is never held
54159
+ * back by history reads. Pass `signal` to abort on navigation.
54160
+ */
54161
+ async getWikiTree(orgId, wikiId, params, opts) {
54162
+ return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params, false, opts);
54163
+ }
54164
+ /**
54165
+ * Second phase of a directory listing: last-commit dates for the direct
54166
+ * children of `path` at `ref`, which must be the `head_sha` a
54167
+ * `getWikiTree` response carried (a branch name is rejected). Merge the
54168
+ * dates only while the returned `head_sha` still matches the rows on
54169
+ * screen; a failure just leaves the dates blank. Pass `signal` to abort
54170
+ * on navigation.
54171
+ */
54172
+ async getWikiTreeLastCommits(orgId, wikiId, params, opts) {
54173
+ return this.request("GET", ENDPOINTS.WIKI_TREE_LAST_COMMITS(orgId, wikiId), void 0, params, false, opts);
54078
54174
  }
54079
54175
  /**
54080
54176
  * Resolve a server-returned, host-relative media URL (a wiki `signed_url`
@@ -59538,7 +59634,7 @@ var ParallAgentGateway = class {
59538
59634
  const event = {
59539
59635
  type: "channel_message",
59540
59636
  targetId: conv.id,
59541
- targetName: conv.external_user_name || conv.external_conversation_id,
59637
+ targetName: conv.external_conversation_name || conv.external_user_name || conv.external_conversation_id,
59542
59638
  targetType: "channel_conversation",
59543
59639
  senderId: msg.external_user_id || "external",
59544
59640
  senderName: msg.external_user_name || msg.external_user_id || "external user",
@@ -59548,6 +59644,7 @@ var ParallAgentGateway = class {
59548
59644
  channelProvider: provider,
59549
59645
  channelConversationType: conv.conversation_type || void 0,
59550
59646
  channelExternalConversationId: conv.external_conversation_id,
59647
+ channelExternalConversationName: conv.external_conversation_name || void 0,
59551
59648
  channelExternalMessageId: msg.external_message_id,
59552
59649
  channelCliCapable: cliCapable,
59553
59650
  ackSourceType: "channel_message",
@@ -51487,6 +51487,9 @@ function formatApprovalDecisionReason(status, reason) {
51487
51487
  return "";
51488
51488
  return `Reason (JSON): ${JSON.stringify(normalized)}`;
51489
51489
  }
51490
+ function threadWatcherHint(threadRootId) {
51491
+ return `[Hint: watcher \u2014 you were not addressed in this reply. Reply only if you add something new; otherwise run \`parall no-reply\`. If this thread is not relevant to you, or you have nothing more to contribute, run \`parall messages unwatch prll://${threadRootId}\` so later replies stop waking you.]`;
51492
+ }
51490
51493
  function buildEventBody(event) {
51491
51494
  const lines = [];
51492
51495
  if (event.type === "message") {
@@ -51506,6 +51509,9 @@ function buildEventBody(event) {
51506
51509
  }
51507
51510
  if (event.deliveryReason)
51508
51511
  lines.push(`[Delivery: ${sanitizeMeta(event.deliveryReason)}]`);
51512
+ if (event.deliveryReason === "watcher" && event.threadRootId) {
51513
+ lines.push(threadWatcherHint(sanitizeMeta(event.threadRootId)));
51514
+ }
51509
51515
  if (event.unreadCount != null && event.unreadCount > 1) {
51510
51516
  const countStr = event.unreadCount >= 1e3 ? "999+" : String(event.unreadCount);
51511
51517
  const sinceStr = event.unreadSince ? ` | since: prll://${event.unreadSince}` : "";
@@ -51566,7 +51572,10 @@ function buildEventBody(event) {
51566
51572
  } else if (event.type === "channel_message") {
51567
51573
  lines.push(`[Event: channel.message]`);
51568
51574
  const providerLabel = sanitizeMeta(event.channelProvider ?? "external IM");
51569
- const convLabel = event.channelExternalConversationId ? `${sanitizeMeta(event.channelExternalConversationId)} (${sanitizeMeta(event.channelConversationType ?? "conversation")})` : sanitizeMeta(event.channelConversationType ?? "conversation");
51575
+ const convType = sanitizeMeta(event.channelConversationType ?? "conversation");
51576
+ const convId = event.channelExternalConversationId ? sanitizeMeta(event.channelExternalConversationId) : void 0;
51577
+ const convName = event.channelExternalConversationName ? sanitizeMeta(event.channelExternalConversationName) : void 0;
51578
+ const convLabel = convName ? `${convName} (${convId ? `${convId}, ` : ""}${convType})` : convId ? `${convId} (${convType})` : convType;
51570
51579
  lines.push(`[Channel: ${providerLabel} | conversation: ${convLabel}]`);
51571
51580
  lines.push(`[From: ${sanitizeMeta(event.senderName)} (external user, not a Parall member)]`);
51572
51581
  if (event.channelExternalMessageId) {
@@ -51755,6 +51764,24 @@ var ENDPOINTS = {
51755
51764
  TEAM_MEMBERS: (orgId, teamId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members`,
51756
51765
  TEAM_MEMBER: (orgId, teamId, userId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members/${userId}`,
51757
51766
  ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
51767
+ LLM_PROVIDERS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-providers`,
51768
+ LLM_PROVIDER: (orgId, providerId) => `${API_BASE}/orgs/${orgId}/llm-providers/${providerId}`,
51769
+ ORG_LLM_MODELS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-models`,
51770
+ ORG_LLM_MODEL: (orgId, modelRowId) => `${API_BASE}/orgs/${orgId}/llm-models/${modelRowId}`,
51771
+ /**
51772
+ * Platform catalog merged with this org's own model rows. Pass `runtime` to
51773
+ * filter org-added models to the ones that runtime can actually reach —
51774
+ * without it a picker can offer a model the write path rejects.
51775
+ */
51776
+ ORG_MODEL_CATALOG: (orgId, runtime, includeModel) => {
51777
+ const params = new URLSearchParams();
51778
+ if (runtime)
51779
+ params.set("runtime", runtime);
51780
+ if (includeModel)
51781
+ params.set("include_model", includeModel);
51782
+ const qs = params.toString();
51783
+ return `${API_BASE}/orgs/${orgId}/models${qs ? `?${qs}` : ""}`;
51784
+ },
51758
51785
  ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
51759
51786
  ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
51760
51787
  ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
@@ -51981,6 +52008,7 @@ var ENDPOINTS = {
51981
52008
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
51982
52009
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
51983
52010
  WIKI_TREE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
52011
+ WIKI_TREE_LAST_COMMITS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree/last-commits`,
51984
52012
  WIKI_BLOB: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
51985
52013
  WIKI_COPY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
51986
52014
  WIKI_NODE_SECTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
@@ -52508,6 +52536,55 @@ var WechatClient = class extends TaskLabelClient {
52508
52536
  }
52509
52537
  };
52510
52538
 
52539
+ // ts/sdk/dist/llm-provider-client.js
52540
+ var LLMProviderClient = class extends WechatClient {
52541
+ async getLLMProviders(orgId) {
52542
+ const response = await this.request("GET", ENDPOINTS.LLM_PROVIDERS(orgId));
52543
+ return response.data;
52544
+ }
52545
+ async createLLMProvider(orgId, data) {
52546
+ return this.request("POST", ENDPOINTS.LLM_PROVIDERS(orgId), data);
52547
+ }
52548
+ /** Omitting `api_key` leaves the stored credential untouched. */
52549
+ async updateLLMProvider(orgId, providerId, data) {
52550
+ return this.request("PATCH", ENDPOINTS.LLM_PROVIDER(orgId, providerId), data);
52551
+ }
52552
+ /** Fails with PROVIDER_IN_USE while model rows still point at it. */
52553
+ async deleteLLMProvider(orgId, providerId) {
52554
+ return this.request("DELETE", ENDPOINTS.LLM_PROVIDER(orgId, providerId));
52555
+ }
52556
+ async getOrgLLMModels(orgId) {
52557
+ const response = await this.request("GET", ENDPOINTS.ORG_LLM_MODELS(orgId));
52558
+ return response.data;
52559
+ }
52560
+ async createOrgLLMModel(orgId, data) {
52561
+ return this.request("POST", ENDPOINTS.ORG_LLM_MODELS(orgId), data);
52562
+ }
52563
+ /**
52564
+ * Patches a model row in place. Repointing a provider or fixing an upstream
52565
+ * name this way avoids the delete-and-recreate window, during which an
52566
+ * org-only model has no upstream at all and its pinned agents fail.
52567
+ */
52568
+ async updateOrgLLMModel(orgId, modelRowId, data) {
52569
+ return this.request("PATCH", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId), data);
52570
+ }
52571
+ async deleteOrgLLMModel(orgId, modelRowId) {
52572
+ return this.request("DELETE", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId));
52573
+ }
52574
+ /**
52575
+ * The catalog as this org sees it: platform models with the org's rows
52576
+ * merged in. Distinct from the public model catalog, which stays org-agnostic
52577
+ * and cacheable — use this one wherever an org context exists.
52578
+ *
52579
+ * Pass `runtime` on a picker: org-added models are then filtered to what that
52580
+ * runtime's protocol can reach, matching the server-side pin validation.
52581
+ */
52582
+ async getOrgModelCatalog(orgId, runtime, includeModel) {
52583
+ const response = await this.request("GET", ENDPOINTS.ORG_MODEL_CATALOG(orgId, runtime, includeModel));
52584
+ return response.data;
52585
+ }
52586
+ };
52587
+
52511
52588
  // ts/sdk/dist/attachment-client.js
52512
52589
  var COMPLETION_RETRY_DELAYS_MS = [250, 750];
52513
52590
  function isRetryableCompletionError(error) {
@@ -52516,7 +52593,7 @@ function isRetryableCompletionError(error) {
52516
52593
  const status = error.status;
52517
52594
  return status === 0 || typeof status === "number" && status >= 500;
52518
52595
  }
52519
- var AttachmentClient = class extends WechatClient {
52596
+ var AttachmentClient = class extends LLMProviderClient {
52520
52597
  async getUploadPresignUrl(orgId, req) {
52521
52598
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
52522
52599
  }
@@ -54073,8 +54150,27 @@ var ParallClient = class _ParallClient extends AttachmentClient {
54073
54150
  const res = await this.request("GET", ENDPOINTS.WIKIS_DELETED(orgId));
54074
54151
  return res.data;
54075
54152
  }
54076
- async getWikiTree(orgId, wikiId, params) {
54077
- return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params);
54153
+ /**
54154
+ * List the direct children of a wiki directory. The response carries
54155
+ * `head_sha`, the immutable commit it was read at; render the rows first
54156
+ * and fetch their dates with `getWikiTreeLastCommits` pinned to it.
54157
+ * `last_commit: true` is the legacy single-request form (dates composed
54158
+ * server-side); prefer the two-phase flow so the structure is never held
54159
+ * back by history reads. Pass `signal` to abort on navigation.
54160
+ */
54161
+ async getWikiTree(orgId, wikiId, params, opts) {
54162
+ return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params, false, opts);
54163
+ }
54164
+ /**
54165
+ * Second phase of a directory listing: last-commit dates for the direct
54166
+ * children of `path` at `ref`, which must be the `head_sha` a
54167
+ * `getWikiTree` response carried (a branch name is rejected). Merge the
54168
+ * dates only while the returned `head_sha` still matches the rows on
54169
+ * screen; a failure just leaves the dates blank. Pass `signal` to abort
54170
+ * on navigation.
54171
+ */
54172
+ async getWikiTreeLastCommits(orgId, wikiId, params, opts) {
54173
+ return this.request("GET", ENDPOINTS.WIKI_TREE_LAST_COMMITS(orgId, wikiId), void 0, params, false, opts);
54078
54174
  }
54079
54175
  /**
54080
54176
  * Resolve a server-returned, host-relative media URL (a wiki `signed_url`
@@ -59538,7 +59634,7 @@ var ParallAgentGateway = class {
59538
59634
  const event = {
59539
59635
  type: "channel_message",
59540
59636
  targetId: conv.id,
59541
- targetName: conv.external_user_name || conv.external_conversation_id,
59637
+ targetName: conv.external_conversation_name || conv.external_user_name || conv.external_conversation_id,
59542
59638
  targetType: "channel_conversation",
59543
59639
  senderId: msg.external_user_id || "external",
59544
59640
  senderName: msg.external_user_name || msg.external_user_id || "external user",
@@ -59548,6 +59644,7 @@ var ParallAgentGateway = class {
59548
59644
  channelProvider: provider,
59549
59645
  channelConversationType: conv.conversation_type || void 0,
59550
59646
  channelExternalConversationId: conv.external_conversation_id,
59647
+ channelExternalConversationName: conv.external_conversation_name || void 0,
59551
59648
  channelExternalMessageId: msg.external_message_id,
59552
59649
  channelCliCapable: cliCapable,
59553
59650
  ackSourceType: "channel_message",
@@ -178,6 +178,13 @@ var init_browser_viewer = __esm({
178
178
  }
179
179
  });
180
180
 
181
+ // ts/sdk/dist/browser-use.js
182
+ var init_browser_use = __esm({
183
+ "ts/sdk/dist/browser-use.js"() {
184
+ "use strict";
185
+ }
186
+ });
187
+
181
188
  // ts/sdk/dist/attachment-types.js
182
189
  var init_attachment_types = __esm({
183
190
  "ts/sdk/dist/attachment-types.js"() {
@@ -241,6 +248,24 @@ var init_constants = __esm({
241
248
  TEAM_MEMBERS: (orgId, teamId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members`,
242
249
  TEAM_MEMBER: (orgId, teamId, userId) => `${API_BASE}/orgs/${orgId}/teams/${teamId}/members/${userId}`,
243
250
  ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
251
+ LLM_PROVIDERS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-providers`,
252
+ LLM_PROVIDER: (orgId, providerId) => `${API_BASE}/orgs/${orgId}/llm-providers/${providerId}`,
253
+ ORG_LLM_MODELS: (orgId) => `${API_BASE}/orgs/${orgId}/llm-models`,
254
+ ORG_LLM_MODEL: (orgId, modelRowId) => `${API_BASE}/orgs/${orgId}/llm-models/${modelRowId}`,
255
+ /**
256
+ * Platform catalog merged with this org's own model rows. Pass `runtime` to
257
+ * filter org-added models to the ones that runtime can actually reach —
258
+ * without it a picker can offer a model the write path rejects.
259
+ */
260
+ ORG_MODEL_CATALOG: (orgId, runtime, includeModel) => {
261
+ const params = new URLSearchParams();
262
+ if (runtime)
263
+ params.set("runtime", runtime);
264
+ if (includeModel)
265
+ params.set("include_model", includeModel);
266
+ const qs = params.toString();
267
+ return `${API_BASE}/orgs/${orgId}/models${qs ? `?${qs}` : ""}`;
268
+ },
244
269
  ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
245
270
  ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
246
271
  ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
@@ -467,6 +492,7 @@ var init_constants = __esm({
467
492
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
468
493
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
469
494
  WIKI_TREE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
495
+ WIKI_TREE_LAST_COMMITS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree/last-commits`,
470
496
  WIKI_BLOB: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
471
497
  WIKI_COPY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
472
498
  WIKI_NODE_SECTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
@@ -1019,6 +1045,63 @@ var init_wechat_client = __esm({
1019
1045
  }
1020
1046
  });
1021
1047
 
1048
+ // ts/sdk/dist/llm-provider-client.js
1049
+ var LLMProviderClient;
1050
+ var init_llm_provider_client = __esm({
1051
+ "ts/sdk/dist/llm-provider-client.js"() {
1052
+ "use strict";
1053
+ init_constants();
1054
+ init_wechat_client();
1055
+ LLMProviderClient = class extends WechatClient {
1056
+ async getLLMProviders(orgId) {
1057
+ const response = await this.request("GET", ENDPOINTS.LLM_PROVIDERS(orgId));
1058
+ return response.data;
1059
+ }
1060
+ async createLLMProvider(orgId, data) {
1061
+ return this.request("POST", ENDPOINTS.LLM_PROVIDERS(orgId), data);
1062
+ }
1063
+ /** Omitting `api_key` leaves the stored credential untouched. */
1064
+ async updateLLMProvider(orgId, providerId, data) {
1065
+ return this.request("PATCH", ENDPOINTS.LLM_PROVIDER(orgId, providerId), data);
1066
+ }
1067
+ /** Fails with PROVIDER_IN_USE while model rows still point at it. */
1068
+ async deleteLLMProvider(orgId, providerId) {
1069
+ return this.request("DELETE", ENDPOINTS.LLM_PROVIDER(orgId, providerId));
1070
+ }
1071
+ async getOrgLLMModels(orgId) {
1072
+ const response = await this.request("GET", ENDPOINTS.ORG_LLM_MODELS(orgId));
1073
+ return response.data;
1074
+ }
1075
+ async createOrgLLMModel(orgId, data) {
1076
+ return this.request("POST", ENDPOINTS.ORG_LLM_MODELS(orgId), data);
1077
+ }
1078
+ /**
1079
+ * Patches a model row in place. Repointing a provider or fixing an upstream
1080
+ * name this way avoids the delete-and-recreate window, during which an
1081
+ * org-only model has no upstream at all and its pinned agents fail.
1082
+ */
1083
+ async updateOrgLLMModel(orgId, modelRowId, data) {
1084
+ return this.request("PATCH", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId), data);
1085
+ }
1086
+ async deleteOrgLLMModel(orgId, modelRowId) {
1087
+ return this.request("DELETE", ENDPOINTS.ORG_LLM_MODEL(orgId, modelRowId));
1088
+ }
1089
+ /**
1090
+ * The catalog as this org sees it: platform models with the org's rows
1091
+ * merged in. Distinct from the public model catalog, which stays org-agnostic
1092
+ * and cacheable — use this one wherever an org context exists.
1093
+ *
1094
+ * Pass `runtime` on a picker: org-added models are then filtered to what that
1095
+ * runtime's protocol can reach, matching the server-side pin validation.
1096
+ */
1097
+ async getOrgModelCatalog(orgId, runtime, includeModel) {
1098
+ const response = await this.request("GET", ENDPOINTS.ORG_MODEL_CATALOG(orgId, runtime, includeModel));
1099
+ return response.data;
1100
+ }
1101
+ };
1102
+ }
1103
+ });
1104
+
1022
1105
  // ts/sdk/dist/attachment-client.js
1023
1106
  function isRetryableCompletionError(error) {
1024
1107
  if (!error || typeof error !== "object" || !("status" in error))
@@ -1031,9 +1114,9 @@ var init_attachment_client = __esm({
1031
1114
  "ts/sdk/dist/attachment-client.js"() {
1032
1115
  "use strict";
1033
1116
  init_constants();
1034
- init_wechat_client();
1117
+ init_llm_provider_client();
1035
1118
  COMPLETION_RETRY_DELAYS_MS = [250, 750];
1036
- AttachmentClient = class extends WechatClient {
1119
+ AttachmentClient = class extends LLMProviderClient {
1037
1120
  async getUploadPresignUrl(orgId, req) {
1038
1121
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
1039
1122
  }
@@ -2641,8 +2724,27 @@ var init_client = __esm({
2641
2724
  const res = await this.request("GET", ENDPOINTS.WIKIS_DELETED(orgId));
2642
2725
  return res.data;
2643
2726
  }
2644
- async getWikiTree(orgId, wikiId, params) {
2645
- return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params);
2727
+ /**
2728
+ * List the direct children of a wiki directory. The response carries
2729
+ * `head_sha`, the immutable commit it was read at; render the rows first
2730
+ * and fetch their dates with `getWikiTreeLastCommits` pinned to it.
2731
+ * `last_commit: true` is the legacy single-request form (dates composed
2732
+ * server-side); prefer the two-phase flow so the structure is never held
2733
+ * back by history reads. Pass `signal` to abort on navigation.
2734
+ */
2735
+ async getWikiTree(orgId, wikiId, params, opts) {
2736
+ return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params, false, opts);
2737
+ }
2738
+ /**
2739
+ * Second phase of a directory listing: last-commit dates for the direct
2740
+ * children of `path` at `ref`, which must be the `head_sha` a
2741
+ * `getWikiTree` response carried (a branch name is rejected). Merge the
2742
+ * dates only while the returned `head_sha` still matches the rows on
2743
+ * screen; a failure just leaves the dates blank. Pass `signal` to abort
2744
+ * on navigation.
2745
+ */
2746
+ async getWikiTreeLastCommits(orgId, wikiId, params, opts) {
2747
+ return this.request("GET", ENDPOINTS.WIKI_TREE_LAST_COMMITS(orgId, wikiId), void 0, params, false, opts);
2646
2748
  }
2647
2749
  /**
2648
2750
  * Resolve a server-returned, host-relative media URL (a wiki `signed_url`
@@ -3653,6 +3755,13 @@ var init_client = __esm({
3653
3755
  }
3654
3756
  });
3655
3757
 
3758
+ // ts/sdk/dist/llm-provider-types.js
3759
+ var init_llm_provider_types = __esm({
3760
+ "ts/sdk/dist/llm-provider-types.js"() {
3761
+ "use strict";
3762
+ }
3763
+ });
3764
+
3656
3765
  // ts/sdk/dist/subject.js
3657
3766
  var init_subject = __esm({
3658
3767
  "ts/sdk/dist/subject.js"() {
@@ -4026,9 +4135,11 @@ var init_dist = __esm({
4026
4135
  "ts/sdk/dist/index.js"() {
4027
4136
  "use strict";
4028
4137
  init_browser_viewer();
4138
+ init_browser_use();
4029
4139
  init_attachment_types();
4030
4140
  init_client();
4031
4141
  init_constants();
4142
+ init_llm_provider_types();
4032
4143
  init_subject();
4033
4144
  init_task_label_types();
4034
4145
  init_types();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.56.2",
3
+ "version": "1.57.2",
4
4
  "description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,11 +33,11 @@
33
33
  "@aws-sdk/client-s3": "3.984.0",
34
34
  "@pinixai/bb-browser-pro": "0.15.0",
35
35
  "ws": "^8.18.0",
36
- "@parall/agent-core": "1.56.2",
37
- "@parall/claude-agent": "1.56.2",
38
- "@parall/codex-agent": "1.56.2",
39
- "@parall/sdk": "1.56.2",
40
- "@parall/openclaw-agent": "1.56.2"
36
+ "@parall/agent-core": "1.57.2",
37
+ "@parall/sdk": "1.57.2",
38
+ "@parall/codex-agent": "1.57.2",
39
+ "@parall/claude-agent": "1.57.2",
40
+ "@parall/openclaw-agent": "1.57.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.0.0",