@parall/parall 1.48.0 → 1.50.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/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +23 -8
- package/dist/index.bundle.mjs +187 -16
- package/package.json +3 -3
- package/skills/parall-platform/SKILL.md +9 -0
- package/skills/parall-tasks/SKILL.md +7 -1
- package/src/gateway.ts +26 -7
package/dist/gateway.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,uGAAuG;AACvG,KAAK,qBAAqB,CAAC,CAAC,GAAG,OAAO,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACnF,OAAO,
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,uGAAuG;AACvG,KAAK,qBAAqB,CAAC,CAAC,GAAG,OAAO,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACnF,OAAO,EAUL,KAAK,eAAe,EAGrB,MAAM,oBAAoB,CAAC;AAqB5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+KxD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,IAAI,EAAE,aAAa,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,eAAe,CA8KlB;AAED,eAAO,MAAM,aAAa,EAAE,qBAAqB,CAAC,qBAAqB,CAmMtE,CAAC"}
|
package/dist/gateway.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ParallAgentGateway, capabilityBinDir, dispatchLaneContextDir, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, initAgentTelemetry, createOtelLogger, } from '@parall/agent-core';
|
|
1
|
+
import { ParallAgentGateway, capabilityBinDir, dispatchLaneContextDir, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, identityFromMe, initAgentTelemetry, createOtelLogger, } from '@parall/agent-core';
|
|
2
2
|
import { appendPreparedLocalAttachmentRefs, ensureLocalAttachmentGitExclude, pinLocalAttachmentPaths, } from '@parall/agent-core/internal/attachment-input';
|
|
3
3
|
import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
|
|
4
4
|
import * as crypto from 'node:crypto';
|
|
@@ -36,9 +36,12 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
|
36
36
|
throw err;
|
|
37
37
|
}
|
|
38
38
|
const user = await client.getMe();
|
|
39
|
-
return { ...user, agent_profile: null };
|
|
39
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
+
// hooks.ts rebuilds the prompt from the process-global identity on EVERY
|
|
43
|
+
// prompt build, so a refreshed identity (via the shared identityFromMe)
|
|
44
|
+
// reaches the very next turn without any restart.
|
|
42
45
|
function buildInboundCtx(core, accountId, event, sessionKey, bodyForAgent, earlierEvents = []) {
|
|
43
46
|
const inboundHistory = earlierEvents.length > 0 ? buildInboundHistory(earlierEvents) : undefined;
|
|
44
47
|
return core.channel.reply.finalizeInboundContext({
|
|
@@ -333,11 +336,7 @@ export const parallGateway = {
|
|
|
333
336
|
});
|
|
334
337
|
const me = await getAgentMeWithLegacyFallback(client, config.org_id);
|
|
335
338
|
const agentUserId = me.id;
|
|
336
|
-
setAgentIdentity(
|
|
337
|
-
userId: agentUserId,
|
|
338
|
-
displayName: me.display_name,
|
|
339
|
-
description: me.agent_profile?.description ?? undefined,
|
|
340
|
-
});
|
|
339
|
+
setAgentIdentity(identityFromMe(me));
|
|
341
340
|
log?.info(`parall[${ctx.accountId}]: authenticated as ${me.display_name} (${agentUserId})`);
|
|
342
341
|
const telemetry = await initAgentTelemetry('parall-openclaw-agent', 'openclaw');
|
|
343
342
|
const otelLog = createOtelLogger('agent', 'openclaw-agent');
|
|
@@ -436,7 +435,23 @@ export const parallGateway = {
|
|
|
436
435
|
forkDeadlineMs: parseForkDeadlineMs(process.env.PRLL_FORK_DEADLINE_MS),
|
|
437
436
|
dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
|
|
438
437
|
onConfigUpdate: async () => {
|
|
439
|
-
|
|
438
|
+
// Identity rides the same agent_config.update nudge: refresh the
|
|
439
|
+
// process-global identity so the next prompt build (hooks.ts
|
|
440
|
+
// before_prompt_build) carries the new title / public description /
|
|
441
|
+
// instructions. The finally keeps it running even when the platform
|
|
442
|
+
// config refresh throws (their failure domains are independent);
|
|
443
|
+
// identity failure keeps the last-known-good value.
|
|
444
|
+
try {
|
|
445
|
+
await fetchAndApplyPlatformConfig(configManagerOpts);
|
|
446
|
+
}
|
|
447
|
+
finally {
|
|
448
|
+
try {
|
|
449
|
+
setAgentIdentity(identityFromMe(await getAgentMeWithLegacyFallback(client, config.org_id)));
|
|
450
|
+
}
|
|
451
|
+
catch (err) {
|
|
452
|
+
log?.warn(`parall[${ctx.accountId}]: /agents/me refetch failed (keeping last-known identity): ${String(err)}`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
440
455
|
},
|
|
441
456
|
onSessionReady: async ({ activeSessionId }) => {
|
|
442
457
|
setParallAccountState(ctx.accountId, {
|
package/dist/index.bundle.mjs
CHANGED
|
@@ -51291,6 +51291,17 @@ function laneContextFilePath(contextDir, targetUri, threadRootId) {
|
|
|
51291
51291
|
|
|
51292
51292
|
// ../sdk/dist/types.js
|
|
51293
51293
|
var MENTION_ALL_USER_ID = "all";
|
|
51294
|
+
var MENTION_ALL_HUMANS_USER_ID = "allhuman";
|
|
51295
|
+
var MENTION_ALL_AGENTS_USER_ID = "allagent";
|
|
51296
|
+
function mentionTargetsUser(mentionUserId, userId, userType) {
|
|
51297
|
+
if (mentionUserId === userId || mentionUserId === MENTION_ALL_USER_ID)
|
|
51298
|
+
return true;
|
|
51299
|
+
if (mentionUserId === MENTION_ALL_HUMANS_USER_ID)
|
|
51300
|
+
return userType === "human";
|
|
51301
|
+
if (mentionUserId === MENTION_ALL_AGENTS_USER_ID)
|
|
51302
|
+
return userType === "agent";
|
|
51303
|
+
return false;
|
|
51304
|
+
}
|
|
51294
51305
|
|
|
51295
51306
|
// ../sdk/dist/constants.js
|
|
51296
51307
|
var API_BASE = "/api/v1";
|
|
@@ -51326,6 +51337,12 @@ var ENDPOINTS = {
|
|
|
51326
51337
|
ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
|
|
51327
51338
|
ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
|
|
51328
51339
|
ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
|
|
51340
|
+
// Org-scoped public profile (title / description). GET readable by every
|
|
51341
|
+
// active member; PATCH is CAS-guarded (expected_version).
|
|
51342
|
+
ORG_MEMBER_PROFILE: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}/profile`,
|
|
51343
|
+
// Private agent Instructions — visibility gated server-side
|
|
51344
|
+
// (agent self + Human org admin/owner). Never cached.
|
|
51345
|
+
AGENT_INSTRUCTIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/instructions`,
|
|
51329
51346
|
REF_SEARCH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/search`,
|
|
51330
51347
|
// Direct messages (org-scoped, atomic find-or-create + send)
|
|
51331
51348
|
DM: (orgId) => `${API_BASE}/orgs/${orgId}/dm`,
|
|
@@ -51349,6 +51366,8 @@ var ENDPOINTS = {
|
|
|
51349
51366
|
MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
|
|
51350
51367
|
MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
|
|
51351
51368
|
MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
|
|
51369
|
+
MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
|
|
51370
|
+
MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
|
|
51352
51371
|
// Upload (org-scoped)
|
|
51353
51372
|
UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
|
|
51354
51373
|
UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
|
|
@@ -51586,11 +51605,13 @@ var ENDPOINTS = {
|
|
|
51586
51605
|
UNREAD: `${API_BASE}/me/unread`,
|
|
51587
51606
|
ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
|
|
51588
51607
|
CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
|
|
51608
|
+
CHAT_READ_ALL: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
|
|
51589
51609
|
THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
|
|
51590
51610
|
THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
|
|
51591
51611
|
// References (org-scoped)
|
|
51592
51612
|
REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
|
|
51593
51613
|
REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
|
|
51614
|
+
REFS_OUTBOUND: (orgId) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
|
|
51594
51615
|
REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
|
|
51595
51616
|
REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
|
|
51596
51617
|
// Platform config (agent-scoped, not org-scoped)
|
|
@@ -51605,6 +51626,11 @@ var ENDPOINTS = {
|
|
|
51605
51626
|
SEARCH: (orgId) => `${API_BASE}/orgs/${orgId}/search`,
|
|
51606
51627
|
// Feature flags (org-scoped, server-evaluated)
|
|
51607
51628
|
FEATURE_FLAGS: (orgId) => `${API_BASE}/orgs/${orgId}/feature-flags`,
|
|
51629
|
+
// Team templates (org-scoped, owner/admin only)
|
|
51630
|
+
TEMPLATES: (orgId) => `${API_BASE}/orgs/${orgId}/templates`,
|
|
51631
|
+
TEMPLATE: (orgId, templateId) => `${API_BASE}/orgs/${orgId}/templates/${templateId}`,
|
|
51632
|
+
TEMPLATE_DEPLOYMENTS: (orgId) => `${API_BASE}/orgs/${orgId}/template-deployments`,
|
|
51633
|
+
TEMPLATE_DEPLOYMENT: (orgId, deploymentId) => `${API_BASE}/orgs/${orgId}/template-deployments/${deploymentId}`,
|
|
51608
51634
|
// Billing & Credits (org-scoped)
|
|
51609
51635
|
BILLING: (orgId) => `${API_BASE}/orgs/${orgId}/billing`,
|
|
51610
51636
|
BILLING_TRANSACTIONS: (orgId) => `${API_BASE}/orgs/${orgId}/billing/transactions`,
|
|
@@ -51652,7 +51678,13 @@ var ENDPOINTS = {
|
|
|
51652
51678
|
ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
|
|
51653
51679
|
ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
|
|
51654
51680
|
ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
|
|
51681
|
+
// Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
|
|
51682
|
+
ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
|
|
51655
51683
|
ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
|
|
51684
|
+
// Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
|
|
51685
|
+
// Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
|
|
51686
|
+
// pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
|
|
51687
|
+
ORG_EDGE_VIEWER_COMMAND: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
|
|
51656
51688
|
CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
|
|
51657
51689
|
CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
|
|
51658
51690
|
// Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
|
|
@@ -51675,6 +51707,7 @@ var WS_EVENTS = {
|
|
|
51675
51707
|
MESSAGE_PATCH: "message.patch",
|
|
51676
51708
|
MESSAGE_EDIT: "message.edit",
|
|
51677
51709
|
MESSAGE_DELETE: "message.delete",
|
|
51710
|
+
MESSAGE_REACTION_UPDATED: "message.reaction.updated",
|
|
51678
51711
|
TYPING_UPDATE: "typing.update",
|
|
51679
51712
|
CHAT_UPDATE: "chat.update",
|
|
51680
51713
|
CHAT_DELETED: "chat.deleted",
|
|
@@ -51716,6 +51749,7 @@ var WS_EVENTS = {
|
|
|
51716
51749
|
INBOX_UPDATE: "inbox.update",
|
|
51717
51750
|
INBOX_BULK_UPDATE: "inbox.bulk_update",
|
|
51718
51751
|
READ_POSITION_UPDATED: "read_position.updated",
|
|
51752
|
+
THREAD_READ_POSITION_UPDATED: "thread_read_position.updated",
|
|
51719
51753
|
DISPATCH_NEW: "dispatch.new",
|
|
51720
51754
|
DISPATCH_RECEIVED: "dispatch.received",
|
|
51721
51755
|
DISPATCH_RESOLVED: "dispatch.resolved",
|
|
@@ -51901,7 +51935,7 @@ var ParallClient = class _ParallClient {
|
|
|
51901
51935
|
if (qs)
|
|
51902
51936
|
url += `?${qs}`;
|
|
51903
51937
|
}
|
|
51904
|
-
const headers = this.buildHeaders(path9);
|
|
51938
|
+
const headers = this.buildHeaders(path9, opts?.headers);
|
|
51905
51939
|
const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
|
|
51906
51940
|
const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
|
|
51907
51941
|
let res;
|
|
@@ -52117,6 +52151,30 @@ var ParallClient = class _ParallClient {
|
|
|
52117
52151
|
async updateOrgMember(orgId, userId, role) {
|
|
52118
52152
|
return this.request("PATCH", ENDPOINTS.ORG_MEMBER(orgId, userId), { role });
|
|
52119
52153
|
}
|
|
52154
|
+
/** Org-scoped public profile (title / description) of any active member. */
|
|
52155
|
+
async getMemberProfile(orgId, userId) {
|
|
52156
|
+
return this.request("GET", ENDPOINTS.ORG_MEMBER_PROFILE(orgId, userId));
|
|
52157
|
+
}
|
|
52158
|
+
/**
|
|
52159
|
+
* CAS full-replacement of a member's public profile. Humans edit their
|
|
52160
|
+
* own; Human org admins/owners edit agents'. A stale expected_version
|
|
52161
|
+
* gets 409 PROFILE_VERSION_CONFLICT with error.details.current_version.
|
|
52162
|
+
*/
|
|
52163
|
+
async updateMemberProfile(orgId, userId, req) {
|
|
52164
|
+
return this.request("PATCH", ENDPOINTS.ORG_MEMBER_PROFILE(orgId, userId), req);
|
|
52165
|
+
}
|
|
52166
|
+
/** Private agent Instructions — agent self or Human org admin/owner only. */
|
|
52167
|
+
async getAgentInstructions(orgId, agentId) {
|
|
52168
|
+
return this.request("GET", ENDPOINTS.AGENT_INSTRUCTIONS(orgId, agentId));
|
|
52169
|
+
}
|
|
52170
|
+
/**
|
|
52171
|
+
* CAS update of the private Instructions (Human org admin/owner only).
|
|
52172
|
+
* A stale expected_version gets 409 INSTRUCTIONS_VERSION_CONFLICT with
|
|
52173
|
+
* error.details.current_version.
|
|
52174
|
+
*/
|
|
52175
|
+
async updateAgentInstructions(orgId, agentId, req) {
|
|
52176
|
+
return this.request("PATCH", ENDPOINTS.AGENT_INSTRUCTIONS(orgId, agentId), req);
|
|
52177
|
+
}
|
|
52120
52178
|
// Member activity surfaces — chats the member participates in within this org,
|
|
52121
52179
|
// ordered by most recent activity. Powers the member profile Activity tab.
|
|
52122
52180
|
async getMemberChats(orgId, memberId, params) {
|
|
@@ -52307,6 +52365,14 @@ var ParallClient = class _ParallClient {
|
|
|
52307
52365
|
async getMessageReplies(id, params) {
|
|
52308
52366
|
return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
|
|
52309
52367
|
}
|
|
52368
|
+
// ---- Reactions ----
|
|
52369
|
+
async toggleReaction(messageId, emoji) {
|
|
52370
|
+
return this.request("PUT", ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
|
|
52371
|
+
}
|
|
52372
|
+
async listReactions(messageId) {
|
|
52373
|
+
const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
|
|
52374
|
+
return res.reactions;
|
|
52375
|
+
}
|
|
52310
52376
|
// ---- File Upload ----
|
|
52311
52377
|
async getUploadPresignUrl(orgId, req) {
|
|
52312
52378
|
return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
|
|
@@ -52682,6 +52748,15 @@ var ParallClient = class _ParallClient {
|
|
|
52682
52748
|
async browserViewerCommand(orgId, profileId, req, opts) {
|
|
52683
52749
|
return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
|
|
52684
52750
|
}
|
|
52751
|
+
/**
|
|
52752
|
+
* Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
|
|
52753
|
+
* tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
|
|
52754
|
+
* browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
|
|
52755
|
+
* viewer is unchanged.
|
|
52756
|
+
*/
|
|
52757
|
+
async edgeViewerCommand(orgId, edgeId, req, opts) {
|
|
52758
|
+
return this.request("POST", ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId), req, void 0, false, opts);
|
|
52759
|
+
}
|
|
52685
52760
|
async resizeMachine(orgId, machineId, spec) {
|
|
52686
52761
|
return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
|
|
52687
52762
|
}
|
|
@@ -52708,14 +52783,23 @@ var ParallClient = class _ParallClient {
|
|
|
52708
52783
|
}
|
|
52709
52784
|
// Wiki mount/token methods removed — wiki-service handles all wiki endpoints.
|
|
52710
52785
|
// ---- Unread ----
|
|
52711
|
-
async getUnreadCounts(orgId) {
|
|
52786
|
+
async getUnreadCounts(orgId, opts) {
|
|
52712
52787
|
const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
|
|
52713
|
-
const res = await this.request("GET", endpoint
|
|
52788
|
+
const res = await this.request("GET", endpoint, void 0, {
|
|
52789
|
+
include_thread_replies: opts?.includeThreadReplies ? "true" : void 0
|
|
52790
|
+
});
|
|
52714
52791
|
return res.data;
|
|
52715
52792
|
}
|
|
52716
52793
|
async markRead(orgId, chatId, messageId) {
|
|
52717
52794
|
return this.request("POST", ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
|
|
52718
52795
|
}
|
|
52796
|
+
/** Mark everything in a chat read: the channel cursor jumps to the latest
|
|
52797
|
+
* top-level message and every thread cursor to its latest reply, in one
|
|
52798
|
+
* idempotent call. The server echoes the same per-cursor WS events the
|
|
52799
|
+
* single-cursor routes emit and auto-clears covered inbox items. */
|
|
52800
|
+
async markAllRead(orgId, chatId) {
|
|
52801
|
+
return this.request("POST", ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
|
|
52802
|
+
}
|
|
52719
52803
|
async getThreadUnread(orgId, chatId, threadRootId) {
|
|
52720
52804
|
return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
|
|
52721
52805
|
}
|
|
@@ -53390,6 +53474,16 @@ var ParallClient = class _ParallClient {
|
|
|
53390
53474
|
async getBacklinks(orgId, params) {
|
|
53391
53475
|
return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
|
|
53392
53476
|
}
|
|
53477
|
+
/**
|
|
53478
|
+
* Outbound prll:// refs authored in a set of sources, as raw ref_links rows
|
|
53479
|
+
* (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
|
|
53480
|
+
* thread's refs (root + all replies, resolved server-side — the client's
|
|
53481
|
+
* reply window may be partial), or `{ source_type, source_ids }` for
|
|
53482
|
+
* explicit sources (max 500; v1 accepts only message sources).
|
|
53483
|
+
*/
|
|
53484
|
+
async listOutboundRefs(orgId, req) {
|
|
53485
|
+
return this.request("POST", ENDPOINTS.REFS_OUTBOUND(orgId), req);
|
|
53486
|
+
}
|
|
53393
53487
|
/**
|
|
53394
53488
|
* Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
|
|
53395
53489
|
* must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
|
|
@@ -53424,6 +53518,22 @@ var ParallClient = class _ParallClient {
|
|
|
53424
53518
|
async getFeatureFlags(orgId) {
|
|
53425
53519
|
return this.request("GET", ENDPOINTS.FEATURE_FLAGS(orgId));
|
|
53426
53520
|
}
|
|
53521
|
+
// ---- Official Template catalog (org-contextual owner/admin reads + Hire) ----
|
|
53522
|
+
async listOfficialTemplates(orgId) {
|
|
53523
|
+
const response = await this.request("GET", ENDPOINTS.TEMPLATES(orgId));
|
|
53524
|
+
return response.templates ?? [];
|
|
53525
|
+
}
|
|
53526
|
+
async getOfficialTemplate(orgId, templateId) {
|
|
53527
|
+
return this.request("GET", ENDPOINTS.TEMPLATE(orgId, templateId));
|
|
53528
|
+
}
|
|
53529
|
+
async deployTemplate(orgId, request3) {
|
|
53530
|
+
return this.request("POST", ENDPOINTS.TEMPLATE_DEPLOYMENTS(orgId), request3, void 0, false, {
|
|
53531
|
+
timeoutMs: 185e3
|
|
53532
|
+
});
|
|
53533
|
+
}
|
|
53534
|
+
async getTemplateDeployment(orgId, deploymentId) {
|
|
53535
|
+
return this.request("GET", ENDPOINTS.TEMPLATE_DEPLOYMENT(orgId, deploymentId));
|
|
53536
|
+
}
|
|
53427
53537
|
// ---- Billing & Credits (org-scoped) ----
|
|
53428
53538
|
async getBilling(orgId) {
|
|
53429
53539
|
return this.request("GET", ENDPOINTS.BILLING(orgId));
|
|
@@ -53669,6 +53779,43 @@ var ParallClient = class _ParallClient {
|
|
|
53669
53779
|
async listEdgeProfiles(orgId, edgeId) {
|
|
53670
53780
|
return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
|
|
53671
53781
|
}
|
|
53782
|
+
/**
|
|
53783
|
+
* Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
|
|
53784
|
+
* human maintainer or org admin). Sanitized — the password never comes back.
|
|
53785
|
+
* Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
|
|
53786
|
+
* validation codes as 422 when a stored config no longer passes current rules.
|
|
53787
|
+
* `can_mutate` and `lease_status` are the authoritative idle gate; device
|
|
53788
|
+
* list status is not a substitute.
|
|
53789
|
+
*/
|
|
53790
|
+
async getEdgeProfileProxy(orgId, edgeId, profileName) {
|
|
53791
|
+
return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
|
|
53792
|
+
}
|
|
53793
|
+
/**
|
|
53794
|
+
* Set/replace the profile's egress proxy (full triple every time) — IDLE
|
|
53795
|
+
* ONLY: while the profile's hosted browser is running (a viewer session is
|
|
53796
|
+
* open or a pod is otherwise live) the server answers 409
|
|
53797
|
+
* `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
|
|
53798
|
+
* retry. The next cold start uses the new egress; browser login state is
|
|
53799
|
+
* preserved across it. Other typed errors: the validation vocabulary
|
|
53800
|
+
* (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
|
|
53801
|
+
* `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
|
|
53802
|
+
* `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
|
|
53803
|
+
* and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
|
|
53804
|
+
*/
|
|
53805
|
+
async setEdgeProfileProxy(orgId, edgeId, profileName, req, expectedVersion) {
|
|
53806
|
+
return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), req, void 0, false, {
|
|
53807
|
+
headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
|
|
53808
|
+
});
|
|
53809
|
+
}
|
|
53810
|
+
/**
|
|
53811
|
+
* Clear the profile's egress proxy; the next pod start egresses directly.
|
|
53812
|
+
* Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
|
|
53813
|
+
*/
|
|
53814
|
+
async clearEdgeProfileProxy(orgId, edgeId, profileName, expectedVersion) {
|
|
53815
|
+
return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), void 0, void 0, false, {
|
|
53816
|
+
headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
|
|
53817
|
+
});
|
|
53818
|
+
}
|
|
53672
53819
|
/**
|
|
53673
53820
|
* Execute a registry clip command on an Edge device.
|
|
53674
53821
|
*
|
|
@@ -53737,6 +53884,8 @@ var ApiError = class extends Error {
|
|
|
53737
53884
|
status;
|
|
53738
53885
|
code;
|
|
53739
53886
|
extras;
|
|
53887
|
+
/** Retry-After delta seconds when the server supplies one. */
|
|
53888
|
+
retryAfterSeconds;
|
|
53740
53889
|
/** Attempted action (authorization denials) — e.g. "chat.add_member". */
|
|
53741
53890
|
action;
|
|
53742
53891
|
/** Target resource URI that was evaluated — e.g. "prll://cht_…". */
|
|
@@ -53756,6 +53905,9 @@ function buildApiError(res, rawErrorBody) {
|
|
|
53756
53905
|
const errMsg = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
|
|
53757
53906
|
const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
|
|
53758
53907
|
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
53908
|
+
const retryAfter = Number(res.headers?.get("Retry-After"));
|
|
53909
|
+
if (Number.isFinite(retryAfter) && retryAfter > 0)
|
|
53910
|
+
apiError.retryAfterSeconds = retryAfter;
|
|
53759
53911
|
const anchors = errorObj ?? errorBody;
|
|
53760
53912
|
if (typeof anchors.action === "string")
|
|
53761
53913
|
apiError.action = anchors.action;
|
|
@@ -55052,6 +55204,17 @@ function buildForkResultPrefix(results) {
|
|
|
55052
55204
|
}
|
|
55053
55205
|
|
|
55054
55206
|
// ../agent-core/dist/prompt-fragments.js
|
|
55207
|
+
function identityFromMe(me) {
|
|
55208
|
+
return {
|
|
55209
|
+
userId: me.id,
|
|
55210
|
+
displayName: me.display_name,
|
|
55211
|
+
title: me.public_profile?.title || void 0,
|
|
55212
|
+
publicDescription: me.public_profile?.description || void 0,
|
|
55213
|
+
// `||` on purpose: an empty-string instructions must also fall back to
|
|
55214
|
+
// the deprecated description alias (empty means "unset" on this wire).
|
|
55215
|
+
instructions: me.agent_profile?.instructions || me.agent_profile?.description || void 0
|
|
55216
|
+
};
|
|
55217
|
+
}
|
|
55055
55218
|
var PRLL_IDENTITY_BASE = `## You on Parall
|
|
55056
55219
|
|
|
55057
55220
|
Parall is a shared workspace where humans and agents work side by side as equals.
|
|
@@ -55073,11 +55236,15 @@ function buildIdentity(agent) {
|
|
|
55073
55236
|
const name = sanitizeProfileField(agent.displayName);
|
|
55074
55237
|
const lines = [PRLL_IDENTITY_BASE, "", "### Your Parall Identity", ""];
|
|
55075
55238
|
lines.push(`You are **${name}** (\`prll://${agent.userId}\`).`);
|
|
55076
|
-
|
|
55077
|
-
|
|
55078
|
-
|
|
55079
|
-
|
|
55080
|
-
|
|
55239
|
+
const title = agent.title ? sanitizeProfileField(agent.title) : "";
|
|
55240
|
+
if (title)
|
|
55241
|
+
lines.push(`Title: ${title}`);
|
|
55242
|
+
const about = agent.publicDescription ? sanitizeProfileField(agent.publicDescription) : "";
|
|
55243
|
+
if (about)
|
|
55244
|
+
lines.push(`About: ${about}`);
|
|
55245
|
+
const instructions = sanitizeProfileBlock(agent.instructions ?? agent.description ?? "");
|
|
55246
|
+
if (instructions) {
|
|
55247
|
+
lines.push("", "### Private instructions from your organization admins", "", instructions);
|
|
55081
55248
|
}
|
|
55082
55249
|
lines.push("", `When you see \`${agent.userId}\` or \`prll://${agent.userId}\` in messages, mentions, or events \u2014 that's you.`);
|
|
55083
55250
|
return lines.join("\n");
|
|
@@ -57988,7 +58155,7 @@ var ParallAgentGateway = class {
|
|
|
57988
58155
|
return { action: "skip" };
|
|
57989
58156
|
if (chatInfo.type === "group" && chatInfo.agentRoutingMode !== "active") {
|
|
57990
58157
|
const mentions = content.mentions ?? [];
|
|
57991
|
-
const isMentioned = mentions.some((mention) => mention.user_id
|
|
58158
|
+
const isMentioned = mentions.some((mention) => mentionTargetsUser(mention.user_id, this.opts.agentUserId, "agent"));
|
|
57992
58159
|
if (!isMentioned)
|
|
57993
58160
|
return { action: "skip" };
|
|
57994
58161
|
}
|
|
@@ -60160,7 +60327,7 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
|
60160
60327
|
throw err;
|
|
60161
60328
|
}
|
|
60162
60329
|
const user = await client.getMe();
|
|
60163
|
-
return { ...user, agent_profile: null };
|
|
60330
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
60164
60331
|
}
|
|
60165
60332
|
}
|
|
60166
60333
|
function buildInboundCtx(core, accountId, event, sessionKey, bodyForAgent, earlierEvents = []) {
|
|
@@ -60441,11 +60608,7 @@ var parallGateway = {
|
|
|
60441
60608
|
});
|
|
60442
60609
|
const me = await getAgentMeWithLegacyFallback(client, config.org_id);
|
|
60443
60610
|
const agentUserId = me.id;
|
|
60444
|
-
setAgentIdentity(
|
|
60445
|
-
userId: agentUserId,
|
|
60446
|
-
displayName: me.display_name,
|
|
60447
|
-
description: me.agent_profile?.description ?? void 0
|
|
60448
|
-
});
|
|
60611
|
+
setAgentIdentity(identityFromMe(me));
|
|
60449
60612
|
log?.info(`parall[${ctx.accountId}]: authenticated as ${me.display_name} (${agentUserId})`);
|
|
60450
60613
|
const telemetry = await initAgentTelemetry("parall-openclaw-agent", "openclaw");
|
|
60451
60614
|
const otelLog = createOtelLogger("agent", "openclaw-agent");
|
|
@@ -60537,7 +60700,15 @@ var parallGateway = {
|
|
|
60537
60700
|
forkDeadlineMs: parseForkDeadlineMs(process.env.PRLL_FORK_DEADLINE_MS),
|
|
60538
60701
|
dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
|
|
60539
60702
|
onConfigUpdate: async () => {
|
|
60540
|
-
|
|
60703
|
+
try {
|
|
60704
|
+
await fetchAndApplyPlatformConfig(configManagerOpts);
|
|
60705
|
+
} finally {
|
|
60706
|
+
try {
|
|
60707
|
+
setAgentIdentity(identityFromMe(await getAgentMeWithLegacyFallback(client, config.org_id)));
|
|
60708
|
+
} catch (err) {
|
|
60709
|
+
log?.warn(`parall[${ctx.accountId}]: /agents/me refetch failed (keeping last-known identity): ${String(err)}`);
|
|
60710
|
+
}
|
|
60711
|
+
}
|
|
60541
60712
|
},
|
|
60542
60713
|
onSessionReady: async ({ activeSessionId }) => {
|
|
60543
60714
|
setParallAccountState(ctx.accountId, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/parall",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.50.0",
|
|
4
4
|
"description": "OpenClaw channel plugin for Parall IM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"openclaw.plugin.json"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@parall/
|
|
20
|
-
"@parall/
|
|
19
|
+
"@parall/agent-core": "1.50.0",
|
|
20
|
+
"@parall/sdk": "1.50.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^22.0.0",
|
|
@@ -19,8 +19,17 @@ parall whoami
|
|
|
19
19
|
parall members list # All org members (humans + agents)
|
|
20
20
|
parall agents list # Agents only
|
|
21
21
|
parall users get prll://usr_xxx # Get user details by ID
|
|
22
|
+
parall members profile prll://usr_xxx # A member's public profile (title / about)
|
|
23
|
+
parall agents instructions # Your own private Instructions (admin-maintained)
|
|
22
24
|
```
|
|
23
25
|
|
|
26
|
+
Every member carries an org-scoped public profile: `title` (role, e.g.
|
|
27
|
+
"Platform Lead") and `description` (a short about). `members list` includes
|
|
28
|
+
both — use them to route work to the right person or agent. Your own system
|
|
29
|
+
prompt already contains your public profile and your private Instructions;
|
|
30
|
+
you cannot edit either of them — if yours should change, DM a Human org
|
|
31
|
+
admin and ask.
|
|
32
|
+
|
|
24
33
|
Create a hosted agent when the user asks for a Parall-managed runtime. Hosted
|
|
25
34
|
provisioning is asynchronous: creation means the agent identity, API key, and
|
|
26
35
|
machine record were accepted, not that the runtime is online yet. Use `--wait`
|
|
@@ -39,7 +39,7 @@ parall tasks list --assignee-id prll://usr_xxx # first page only (default 20)
|
|
|
39
39
|
parall tasks subtasks prll://tsk_xxx # children of a single parent task
|
|
40
40
|
|
|
41
41
|
# Create a task (add --parent-id to make it a SUBTASK of another task)
|
|
42
|
-
parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--due-date 2026-08-01]
|
|
42
|
+
parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--planned-start 2026-07-20] [--due-date 2026-08-01]
|
|
43
43
|
|
|
44
44
|
# Update task status — add --placement end so the task lands at the end of
|
|
45
45
|
# its NEW status column (a bare --status keeps the old column's sort_order)
|
|
@@ -50,6 +50,12 @@ parall tasks update prll://tsk_xxx --status done --placement end
|
|
|
50
50
|
parall tasks update prll://tsk_xxx --due-date 2026-08-01
|
|
51
51
|
parall tasks update prll://tsk_xxx --due-date none
|
|
52
52
|
|
|
53
|
+
# Planned start — same grammar as --due-date; must be on or before the due
|
|
54
|
+
# date when both are set. This is the planned schedule's left-edge date,
|
|
55
|
+
# NOT when work actually began (that stays on lifecycle timestamps)
|
|
56
|
+
parall tasks update prll://tsk_xxx --planned-start 2026-07-20
|
|
57
|
+
parall tasks update prll://tsk_xxx --planned-start none
|
|
58
|
+
|
|
53
59
|
# Move a task to the end of its status column
|
|
54
60
|
parall tasks update prll://tsk_xxx --placement end
|
|
55
61
|
|
package/src/gateway.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
parseShutdownDeadlineMs,
|
|
11
11
|
parseForkDeadlineMs,
|
|
12
12
|
parseDispatchDeadlineMs,
|
|
13
|
+
identityFromMe,
|
|
13
14
|
initAgentTelemetry,
|
|
14
15
|
createOtelLogger,
|
|
15
16
|
type DispatchAdapter,
|
|
@@ -73,10 +74,14 @@ async function getAgentMeWithLegacyFallback(client: ParallClient, orgId: string)
|
|
|
73
74
|
throw err;
|
|
74
75
|
}
|
|
75
76
|
const user = await client.getMe();
|
|
76
|
-
return { ...user, agent_profile: null };
|
|
77
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
// hooks.ts rebuilds the prompt from the process-global identity on EVERY
|
|
82
|
+
// prompt build, so a refreshed identity (via the shared identityFromMe)
|
|
83
|
+
// reaches the very next turn without any restart.
|
|
84
|
+
|
|
80
85
|
function buildInboundCtx(
|
|
81
86
|
core: PluginRuntime,
|
|
82
87
|
accountId: string,
|
|
@@ -408,11 +413,7 @@ export const parallGateway: ChannelGatewayAdapter<ResolvedParallAccount> = {
|
|
|
408
413
|
|
|
409
414
|
const me = await getAgentMeWithLegacyFallback(client, config.org_id);
|
|
410
415
|
const agentUserId = me.id;
|
|
411
|
-
setAgentIdentity(
|
|
412
|
-
userId: agentUserId,
|
|
413
|
-
displayName: me.display_name,
|
|
414
|
-
description: me.agent_profile?.description ?? undefined,
|
|
415
|
-
});
|
|
416
|
+
setAgentIdentity(identityFromMe(me));
|
|
416
417
|
log?.info(`parall[${ctx.accountId}]: authenticated as ${me.display_name} (${agentUserId})`);
|
|
417
418
|
|
|
418
419
|
const telemetry = await initAgentTelemetry('parall-openclaw-agent', 'openclaw');
|
|
@@ -518,7 +519,25 @@ export const parallGateway: ChannelGatewayAdapter<ResolvedParallAccount> = {
|
|
|
518
519
|
forkDeadlineMs: parseForkDeadlineMs(process.env.PRLL_FORK_DEADLINE_MS),
|
|
519
520
|
dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
|
|
520
521
|
onConfigUpdate: async () => {
|
|
521
|
-
|
|
522
|
+
// Identity rides the same agent_config.update nudge: refresh the
|
|
523
|
+
// process-global identity so the next prompt build (hooks.ts
|
|
524
|
+
// before_prompt_build) carries the new title / public description /
|
|
525
|
+
// instructions. The finally keeps it running even when the platform
|
|
526
|
+
// config refresh throws (their failure domains are independent);
|
|
527
|
+
// identity failure keeps the last-known-good value.
|
|
528
|
+
try {
|
|
529
|
+
await fetchAndApplyPlatformConfig(configManagerOpts);
|
|
530
|
+
} finally {
|
|
531
|
+
try {
|
|
532
|
+
setAgentIdentity(
|
|
533
|
+
identityFromMe(await getAgentMeWithLegacyFallback(client, config.org_id)),
|
|
534
|
+
);
|
|
535
|
+
} catch (err) {
|
|
536
|
+
log?.warn(
|
|
537
|
+
`parall[${ctx.accountId}]: /agents/me refetch failed (keeping last-known identity): ${String(err)}`,
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
522
541
|
},
|
|
523
542
|
onSessionReady: async ({ activeSessionId }) => {
|
|
524
543
|
setParallAccountState(ctx.accountId, {
|