@parall/parall 1.49.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.
@@ -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,EASL,KAAK,eAAe,EAGrB,MAAM,oBAAoB,CAAC;AAqB5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA2KxD,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,CAqLtE,CAAC"}
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
- await fetchAndApplyPlatformConfig(configManagerOpts);
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, {
@@ -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`,
@@ -51609,6 +51626,11 @@ var ENDPOINTS = {
51609
51626
  SEARCH: (orgId) => `${API_BASE}/orgs/${orgId}/search`,
51610
51627
  // Feature flags (org-scoped, server-evaluated)
51611
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}`,
51612
51634
  // Billing & Credits (org-scoped)
51613
51635
  BILLING: (orgId) => `${API_BASE}/orgs/${orgId}/billing`,
51614
51636
  BILLING_TRANSACTIONS: (orgId) => `${API_BASE}/orgs/${orgId}/billing/transactions`,
@@ -52129,6 +52151,30 @@ var ParallClient = class _ParallClient {
52129
52151
  async updateOrgMember(orgId, userId, role) {
52130
52152
  return this.request("PATCH", ENDPOINTS.ORG_MEMBER(orgId, userId), { role });
52131
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
+ }
52132
52178
  // Member activity surfaces — chats the member participates in within this org,
52133
52179
  // ordered by most recent activity. Powers the member profile Activity tab.
52134
52180
  async getMemberChats(orgId, memberId, params) {
@@ -53472,6 +53518,22 @@ var ParallClient = class _ParallClient {
53472
53518
  async getFeatureFlags(orgId) {
53473
53519
  return this.request("GET", ENDPOINTS.FEATURE_FLAGS(orgId));
53474
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
+ }
53475
53537
  // ---- Billing & Credits (org-scoped) ----
53476
53538
  async getBilling(orgId) {
53477
53539
  return this.request("GET", ENDPOINTS.BILLING(orgId));
@@ -55142,6 +55204,17 @@ function buildForkResultPrefix(results) {
55142
55204
  }
55143
55205
 
55144
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
+ }
55145
55218
  var PRLL_IDENTITY_BASE = `## You on Parall
55146
55219
 
55147
55220
  Parall is a shared workspace where humans and agents work side by side as equals.
@@ -55163,11 +55236,15 @@ function buildIdentity(agent) {
55163
55236
  const name = sanitizeProfileField(agent.displayName);
55164
55237
  const lines = [PRLL_IDENTITY_BASE, "", "### Your Parall Identity", ""];
55165
55238
  lines.push(`You are **${name}** (\`prll://${agent.userId}\`).`);
55166
- if (agent.description) {
55167
- const description = sanitizeProfileBlock(agent.description);
55168
- if (description) {
55169
- lines.push("", "### Your Agent Profile", "", description);
55170
- }
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);
55171
55248
  }
55172
55249
  lines.push("", `When you see \`${agent.userId}\` or \`prll://${agent.userId}\` in messages, mentions, or events \u2014 that's you.`);
55173
55250
  return lines.join("\n");
@@ -58078,7 +58155,7 @@ var ParallAgentGateway = class {
58078
58155
  return { action: "skip" };
58079
58156
  if (chatInfo.type === "group" && chatInfo.agentRoutingMode !== "active") {
58080
58157
  const mentions = content.mentions ?? [];
58081
- const isMentioned = mentions.some((mention) => mention.user_id === this.opts.agentUserId || mention.user_id === MENTION_ALL_USER_ID);
58158
+ const isMentioned = mentions.some((mention) => mentionTargetsUser(mention.user_id, this.opts.agentUserId, "agent"));
58082
58159
  if (!isMentioned)
58083
58160
  return { action: "skip" };
58084
58161
  }
@@ -60250,7 +60327,7 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
60250
60327
  throw err;
60251
60328
  }
60252
60329
  const user = await client.getMe();
60253
- return { ...user, agent_profile: null };
60330
+ return { ...user, agent_profile: null, public_profile: null };
60254
60331
  }
60255
60332
  }
60256
60333
  function buildInboundCtx(core, accountId, event, sessionKey, bodyForAgent, earlierEvents = []) {
@@ -60531,11 +60608,7 @@ var parallGateway = {
60531
60608
  });
60532
60609
  const me = await getAgentMeWithLegacyFallback(client, config.org_id);
60533
60610
  const agentUserId = me.id;
60534
- setAgentIdentity({
60535
- userId: agentUserId,
60536
- displayName: me.display_name,
60537
- description: me.agent_profile?.description ?? void 0
60538
- });
60611
+ setAgentIdentity(identityFromMe(me));
60539
60612
  log?.info(`parall[${ctx.accountId}]: authenticated as ${me.display_name} (${agentUserId})`);
60540
60613
  const telemetry = await initAgentTelemetry("parall-openclaw-agent", "openclaw");
60541
60614
  const otelLog = createOtelLogger("agent", "openclaw-agent");
@@ -60627,7 +60700,15 @@ var parallGateway = {
60627
60700
  forkDeadlineMs: parseForkDeadlineMs(process.env.PRLL_FORK_DEADLINE_MS),
60628
60701
  dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
60629
60702
  onConfigUpdate: async () => {
60630
- await fetchAndApplyPlatformConfig(configManagerOpts);
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
+ }
60631
60712
  },
60632
60713
  onSessionReady: async ({ activeSessionId }) => {
60633
60714
  setParallAccountState(ctx.accountId, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/parall",
3
- "version": "1.49.0",
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/agent-core": "1.49.0",
20
- "@parall/sdk": "1.49.0"
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`
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
- await fetchAndApplyPlatformConfig(configManagerOpts);
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, {