@parall/sdk 1.55.2 → 1.55.4

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/src/client.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { type BrowserViewerRequestOptions, browserViewerRequestOptions } from './browser-viewer.js';
2
2
  import { API_BASE, ENDPOINTS, WIKI_BASE } from './constants.js';
3
- import { TaskLabelClient } from './task-label-client.js';
3
+ import { WechatClient } from './wechat-client.js';
4
4
  import type {
5
5
  AddTeamMemberRequest,
6
6
  AgentClip,
7
7
  AgentInstructions,
8
+ AgentManager,
8
9
  AgentProviderConfigRead,
9
10
  AgentSessionDB,
10
11
  AgentStep,
@@ -211,6 +212,7 @@ import type {
211
212
  TransferChatOwnershipRequest,
212
213
  UnreadEntry,
213
214
  UpdateAgentInstructionsRequest,
215
+ UpdateAgentManagerRequest,
214
216
  UpdateAgentProviderConfigRequest,
215
217
  UpdateAgentRequest,
216
218
  UpdateAgentSessionRequest,
@@ -231,9 +233,6 @@ import type {
231
233
  UpdateTeamRequest,
232
234
  UpdateWikiChangesetRequest,
233
235
  User,
234
- WechatContactsPage,
235
- WechatProfileView,
236
- WechatStatusView,
237
236
  Wiki,
238
237
  WikiAccessStatus,
239
238
  WikiAnchorResolveRequest,
@@ -280,7 +279,7 @@ export interface ParallClientOptions {
280
279
  getFeatureFlagOverrides?: () => string | null | undefined;
281
280
  }
282
281
 
283
- export class ParallClient extends TaskLabelClient {
282
+ export class ParallClient extends WechatClient {
284
283
  private baseUrl: string;
285
284
  private wikiBaseUrl: string;
286
285
  private token: string | null;
@@ -865,6 +864,25 @@ export class ParallClient extends TaskLabelClient {
865
864
  return this.request('PATCH', ENDPOINTS.AGENT_INSTRUCTIONS(orgId, agentId), req);
866
865
  }
867
866
 
867
+ /** Agent manager state — readable by every active member. */
868
+ async getAgentManager(orgId: string, agentId: string): Promise<AgentManager> {
869
+ return this.request('GET', ENDPOINTS.AGENT_MANAGER(orgId, agentId));
870
+ }
871
+
872
+ /**
873
+ * Assign / transfer / renounce the agent's manager (manager_user_id null =
874
+ * renounce). Human org admin/owner or the current manager only; a stale
875
+ * expected_version gets 409 MANAGER_VERSION_CONFLICT with
876
+ * error.details.current_version.
877
+ */
878
+ async updateAgentManager(
879
+ orgId: string,
880
+ agentId: string,
881
+ req: UpdateAgentManagerRequest,
882
+ ): Promise<AgentManager> {
883
+ return this.request('PATCH', ENDPOINTS.AGENT_MANAGER(orgId, agentId), req);
884
+ }
885
+
868
886
  // Member activity surfaces — chats the member participates in within this org,
869
887
  // ordered by most recent activity. Powers the member profile Activity tab.
870
888
  async getMemberChats(
@@ -2520,31 +2538,6 @@ export class ParallClient extends TaskLabelClient {
2520
2538
  await this.request('POST', ENDPOINTS.SLACK_STATUS(orgId), input);
2521
2539
  }
2522
2540
 
2523
- /**
2524
- * WeChat tier-B read verb (agent-only; internal research preview): the
2525
- * account's address book — friends/chatrooms enriched with display names,
2526
- * followed official accounts. Same live gate as the send verb.
2527
- */
2528
- async listWechatContacts(orgId: string): Promise<WechatContactsPage> {
2529
- return this.request('GET', ENDPOINTS.WECHAT_CONTACTS(orgId));
2530
- }
2531
-
2532
- /**
2533
- * WeChat tier-B read verb (agent-only): the connected account's identity
2534
- * (wxid / alias / nickName / app id).
2535
- */
2536
- async wechatProfile(orgId: string): Promise<WechatProfileView> {
2537
- return this.request('GET', ENDPOINTS.WECHAT_PROFILE(orgId));
2538
- }
2539
-
2540
- /**
2541
- * WeChat tier-B read verb (agent-only): live online probe + identity +
2542
- * the platform's offline record.
2543
- */
2544
- async wechatStatus(orgId: string): Promise<WechatStatusView> {
2545
- return this.request('GET', ENDPOINTS.WECHAT_STATUS(orgId));
2546
- }
2547
-
2548
2541
  async listChannelConversations(
2549
2542
  orgId: string,
2550
2543
  connectionId: string,
@@ -3141,13 +3134,13 @@ export class ParallClient extends TaskLabelClient {
3141
3134
  async resolveRefs(
3142
3135
  orgId: string,
3143
3136
  refs: string[],
3144
- options?: { sourceMessageId?: string },
3137
+ options?: { sourceMessageId?: string; full?: boolean },
3145
3138
  ): Promise<ResolveRefsResponse> {
3146
- const body: Record<string, unknown> = { refs };
3147
- if (options?.sourceMessageId) {
3148
- body.source_message_id = options.sourceMessageId;
3149
- }
3150
- return this.request('POST', ENDPOINTS.REFS_RESOLVE(orgId), body);
3139
+ return this.request('POST', ENDPOINTS.REFS_RESOLVE(orgId), {
3140
+ refs,
3141
+ source_message_id: options?.sourceMessageId,
3142
+ full: options?.full || undefined,
3143
+ });
3151
3144
  }
3152
3145
 
3153
3146
  async getBacklinks(
package/src/constants.ts CHANGED
@@ -387,9 +387,13 @@ export const ENDPOINTS = {
387
387
  ORG_MEMBER_PROFILE: (orgId: string, userId: string) =>
388
388
  `${API_BASE}/orgs/${orgId}/members/${userId}/profile`,
389
389
  // Private agent Instructions — visibility gated server-side
390
- // (agent self + Human org admin/owner). Never cached.
390
+ // (agent self + Human org admin/owner + the agent's manager). Never cached.
391
391
  AGENT_INSTRUCTIONS: (orgId: string, agentId: string) =>
392
392
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/instructions`,
393
+ // Agent manager (agent-global relation, org-scoped authorization).
394
+ // PATCH covers assign / transfer / renounce (manager_user_id null).
395
+ AGENT_MANAGER: (orgId: string, agentId: string) =>
396
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/manager`,
393
397
  REF_SEARCH: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/search`,
394
398
 
395
399
  // Direct messages (org-scoped, atomic find-or-create + send)
@@ -682,6 +686,7 @@ export const ENDPOINTS = {
682
686
  SLACK_STATUS: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents/me/slack/status`,
683
687
  // WeChat tier-B read verbs (agent-only; internal research preview).
684
688
  WECHAT_CONTACTS: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents/me/wechat/contacts`,
689
+ WECHAT_HISTORY: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents/me/wechat/history`,
685
690
  WECHAT_PROFILE: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents/me/wechat/profile`,
686
691
  WECHAT_STATUS: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents/me/wechat/status`,
687
692
 
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ export * from './constants.js';
5
5
  export * from './subject.js';
6
6
  export * from './task-label-types.js';
7
7
  export * from './types.js';
8
+ export * from './wechat-types.js';
8
9
  export type {
9
10
  ParallWsOptions,
10
11
  WsClientEventMap,
package/src/types.ts CHANGED
@@ -486,6 +486,31 @@ export interface UpdateAgentInstructionsRequest {
486
486
  expected_version: number;
487
487
  }
488
488
 
489
+ // Agent manager state. Missing row = manager_user_id null, version 0 (legal
490
+ // unmanaged state); renounce keeps the row and bumps the monotonic version.
491
+ export interface AgentManager {
492
+ agent_user_id: string;
493
+ manager_user_id: string | null;
494
+ manager_display_name?: string;
495
+ version: number;
496
+ updated_at?: string;
497
+ updated_by?: string;
498
+ }
499
+
500
+ // Assign / transfer / renounce share this full-replacement CAS write
501
+ // (manager_user_id null = renounce). A stale expected_version gets 409
502
+ // MANAGER_VERSION_CONFLICT with error.details.current_version.
503
+ export interface UpdateAgentManagerRequest {
504
+ manager_user_id: string | null;
505
+ expected_version: number;
506
+ }
507
+
508
+ // Compact manager projection on agent list/me rows; absent when unmanaged.
509
+ export interface AgentManagerRef {
510
+ user_id: string;
511
+ display_name: string;
512
+ }
513
+
489
514
  // Team — a named group of org members, referenced in ACL rosters by its ID.
490
515
  export type TeamRole = 'member' | 'manager';
491
516
 
@@ -975,6 +1000,13 @@ export interface SendMessageRequest {
975
1000
  export interface MessageDispatchSource {
976
1001
  source_type: string;
977
1002
  source_id: string;
1003
+ /**
1004
+ * Conversation generation of the sending execution (parel v2 invocation
1005
+ * context). Required by the server for agents on the direct_session_v2
1006
+ * transport; a value older than the current New Session barrier is
1007
+ * rejected (STALE_GENERATION).
1008
+ */
1009
+ generation?: number;
978
1010
  }
979
1011
 
980
1012
  /** One WorkItem source pointer for the by-source complete surface. */
@@ -1331,6 +1363,9 @@ export interface AgentWithRuntime extends User {
1331
1363
  // request is scoped to. Runtimes read it from /agents/me to build the
1332
1364
  // public identity prompt section.
1333
1365
  public_profile?: MemberProfile | null;
1366
+ // Agent-manager projection — org-visible display data, absent when
1367
+ // unmanaged. Runtimes read it from /agents/me for the Manager prompt line.
1368
+ manager?: AgentManagerRef | null;
1334
1369
  machine?: Machine | null;
1335
1370
  presence?: AgentPresence | null;
1336
1371
  }
@@ -1702,16 +1737,25 @@ export interface UpdateTaskRequest {
1702
1737
  */
1703
1738
  label_ids?: string[] | null;
1704
1739
  /**
1705
- * Dispatch lane binding (agent senders during a typed dispatch turn).
1706
- * dispatch_lane + dispatch_event_id bind the update to the claimed typed
1707
- * lane (incumbency-checked); dispatch_effect_key — exactly
1708
- * "task_update:<dispatch_event_id>" additionally commits the update as
1740
+ * Dispatch binding (agent senders during a typed dispatch turn).
1741
+ * Lane-bound form (v1 consumers): dispatch_lane + dispatch_event_id bind
1742
+ * the update to the claimed typed lane (incumbency-checked).
1743
+ * By-id form (parel v2 converged consumers — no lane exists):
1744
+ * dispatch_event_id + dispatch_generation bind the update to the WorkItem
1745
+ * directly under the conversation-generation fence.
1746
+ * In both forms dispatch_effect_key additionally commits the update as
1709
1747
  * the dispatch's idempotent Effect and resolves the WorkItem in the same
1710
- * transaction (first update only).
1748
+ * transaction. Lane-bound: exactly "task_update:<dispatch_event_id>" —
1749
+ * first update only; later updates go fenced keyless (the CLI sidecar
1750
+ * arbitrates). By-id: "task_update:<dispatch_event_id>:<payload-hash>" —
1751
+ * content-addressed, every distinct update carries its own key; the first
1752
+ * resolves the WorkItem and later keys land as their own Effects against
1753
+ * the already-resolved row.
1711
1754
  */
1712
1755
  dispatch_lane?: string;
1713
1756
  dispatch_event_id?: string;
1714
1757
  dispatch_effect_key?: string;
1758
+ dispatch_generation?: number;
1715
1759
  }
1716
1760
 
1717
1761
  export interface CreateTaskRelationRequest {
@@ -3978,6 +4022,7 @@ export interface PresenceUpdateData {
3978
4022
  export interface ResolveRefsRequest {
3979
4023
  refs: string[];
3980
4024
  source_message_id?: string;
4025
+ full?: boolean;
3981
4026
  }
3982
4027
 
3983
4028
  export interface ResolvedRef {
@@ -0,0 +1,35 @@
1
+ import { ENDPOINTS } from './constants.js';
2
+ import { TaskLabelClient } from './task-label-client.js';
3
+ import type { WechatContactsPage, WechatProfileView, WechatStatusView } from './types.js';
4
+ import type { WechatHistoryPage, WechatHistoryQuery } from './wechat-types.js';
5
+
6
+ /** WeChat channel read methods shared by every ParallClient instance. */
7
+ export abstract class WechatClient extends TaskLabelClient {
8
+ /** Address book enriched with display names. */
9
+ async listWechatContacts(orgId: string): Promise<WechatContactsPage> {
10
+ return this.request('GET', ENDPOINTS.WECHAT_CONTACTS(orgId));
11
+ }
12
+
13
+ /** Platform-retained context in chronological page order. */
14
+ async wechatHistory(
15
+ orgId: string,
16
+ conversation: string,
17
+ query?: WechatHistoryQuery,
18
+ ): Promise<WechatHistoryPage> {
19
+ const params = new URLSearchParams({ conversation });
20
+ if (query?.before) params.set('before', query.before);
21
+ if (query?.since) params.set('since', query.since);
22
+ if (query?.limit !== undefined) params.set('limit', String(query.limit));
23
+ return this.request('GET', `${ENDPOINTS.WECHAT_HISTORY(orgId)}?${params.toString()}`);
24
+ }
25
+
26
+ /** Connected WeChat account identity. */
27
+ async wechatProfile(orgId: string): Promise<WechatProfileView> {
28
+ return this.request('GET', ENDPOINTS.WECHAT_PROFILE(orgId));
29
+ }
30
+
31
+ /** Live online probe, identity, and platform offline record. */
32
+ async wechatStatus(orgId: string): Promise<WechatStatusView> {
33
+ return this.request('GET', ENDPOINTS.WECHAT_STATUS(orgId));
34
+ }
35
+ }
@@ -0,0 +1,28 @@
1
+ /** Query for platform-retained WeChat context. */
2
+ export interface WechatHistoryQuery {
3
+ /** External message id returned as next_before by a previous page. */
4
+ before?: string;
5
+ /** Inclusive RFC3339 timestamp or YYYY-MM-DD (UTC midnight). */
6
+ since?: string;
7
+ /** Page size; defaults to 20 and is capped at 100. */
8
+ limit?: number;
9
+ }
10
+
11
+ export interface WechatHistoryMessage {
12
+ /** Vendor external message id. */
13
+ id: string;
14
+ direction: 'inbound' | 'outbound';
15
+ sender_wxid: string;
16
+ sender_name: string;
17
+ text: string;
18
+ occurred_at: string;
19
+ }
20
+
21
+ export interface WechatHistoryPage {
22
+ conversation: string;
23
+ /** Chronological order: oldest to newest within this page. */
24
+ messages: WechatHistoryMessage[];
25
+ has_more: boolean;
26
+ /** Pass back as before to continue toward older messages. */
27
+ next_before?: string;
28
+ }