@pnds/sdk 1.9.0 → 1.10.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/src/client.ts CHANGED
@@ -42,11 +42,11 @@ import type {
42
42
  Project,
43
43
  CreateProjectRequest,
44
44
  UpdateProjectRequest,
45
- AgentRunDB,
45
+ AgentSessionDB,
46
46
  AgentStep,
47
- CreateAgentRunRequest,
47
+ CreateAgentSessionRequest,
48
48
  CreateAgentStepRequest,
49
- UpdateAgentRunRequest,
49
+ UpdateAgentSessionRequest,
50
50
  OrgInvitation,
51
51
  InvitationPublicInfo,
52
52
  PlatformConfigResponse,
@@ -55,6 +55,10 @@ import type {
55
55
  WikiChangeset,
56
56
  WikiTreeResponse,
57
57
  WikiNodeSectionArtifact,
58
+ WikiSearchResponse,
59
+ WikiPageIndex,
60
+ WikiRefsResponse,
61
+ WikiRefsCheckResponse,
58
62
  WikiDiff,
59
63
  WikiPathScope,
60
64
  WikiAccessStatus,
@@ -73,6 +77,9 @@ import type {
73
77
  ResolveRefsResponse,
74
78
  BacklinksResponse,
75
79
  BrokenRefsResponse,
80
+ PushSubscribeRequest,
81
+ NotifPrefs,
82
+ NotificationPreferences,
76
83
  } from './types.js';
77
84
 
78
85
  export interface PondClientOptions {
@@ -81,6 +88,7 @@ export interface PondClientOptions {
81
88
  onTokenExpired?: () => void;
82
89
  getRefreshToken?: () => string | null;
83
90
  setTokens?: (tokens: { access_token: string; refresh_token: string }) => void;
91
+ swimlaneName?: string;
84
92
  }
85
93
 
86
94
  export class PondClient {
@@ -90,6 +98,7 @@ export class PondClient {
90
98
  private getRefreshToken?: () => string | null;
91
99
  private setTokens?: (tokens: { access_token: string; refresh_token: string }) => void;
92
100
  private refreshPromise: Promise<AuthTokens> | null = null;
101
+ private swimlaneName?: string;
93
102
 
94
103
  /** Auth endpoints excluded from automatic 401 refresh to prevent recursion. */
95
104
  private static readonly AUTH_PATHS = new Set([
@@ -100,12 +109,28 @@ export class PondClient {
100
109
  /** Proactive refresh when token expires within this window (seconds). */
101
110
  private static readonly REFRESH_THRESHOLD_S = 5 * 60;
102
111
 
112
+ /** Build headers common to all requests (auth, swimlane). */
113
+ private buildHeaders(extra?: Record<string, string>): Record<string, string> {
114
+ const headers: Record<string, string> = {
115
+ 'Content-Type': 'application/json',
116
+ ...extra,
117
+ };
118
+ if (this.token) {
119
+ headers['Authorization'] = `Bearer ${this.token}`;
120
+ }
121
+ if (this.swimlaneName) {
122
+ headers['X-Pnds-Swimlane'] = this.swimlaneName;
123
+ }
124
+ return headers;
125
+ }
126
+
103
127
  constructor(options: PondClientOptions = {}) {
104
128
  this.baseUrl = options.baseUrl ?? '';
105
129
  this.token = options.token ?? null;
106
130
  this.onTokenExpired = options.onTokenExpired;
107
131
  this.getRefreshToken = options.getRefreshToken;
108
132
  this.setTokens = options.setTokens;
133
+ this.swimlaneName = options.swimlaneName;
109
134
  }
110
135
 
111
136
  setToken(token: string | null) {
@@ -197,12 +222,7 @@ export class PondClient {
197
222
  if (qs) url += `?${qs}`;
198
223
  }
199
224
 
200
- const headers: Record<string, string> = {
201
- 'Content-Type': 'application/json',
202
- };
203
- if (this.token) {
204
- headers['Authorization'] = `Bearer ${this.token}`;
205
- }
225
+ const headers = this.buildHeaders();
206
226
 
207
227
  let res: Response;
208
228
  try {
@@ -535,31 +555,31 @@ export class PondClient {
535
555
  return this.request('GET', ENDPOINTS.AGENT_ME(orgId));
536
556
  }
537
557
 
538
- // ---- Agent Runs (org-scoped) ----
558
+ // ---- Agent Sessions (org-scoped) ----
539
559
 
540
- async createAgentRun(orgId: string, agentId: string, req: CreateAgentRunRequest): Promise<AgentRunDB> {
541
- return this.request('POST', ENDPOINTS.AGENT_RUNS(orgId, agentId), req);
560
+ async createAgentSession(orgId: string, agentId: string, req: CreateAgentSessionRequest): Promise<AgentSessionDB> {
561
+ return this.request('POST', ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
542
562
  }
543
563
 
544
- async getAgentRuns(orgId: string, agentId: string, params?: { limit?: number }): Promise<AgentRunDB[]> {
545
- const res = await this.request<{ data: AgentRunDB[] }>('GET', ENDPOINTS.AGENT_RUNS(orgId, agentId), undefined, params);
564
+ async getAgentSessions(orgId: string, agentId: string, params?: { limit?: number; status?: string }): Promise<AgentSessionDB[]> {
565
+ const res = await this.request<{ data: AgentSessionDB[] }>('GET', ENDPOINTS.AGENT_SESSIONS(orgId, agentId), undefined, params);
546
566
  return res.data;
547
567
  }
548
568
 
549
- async getAgentRun(orgId: string, agentId: string, runId: string): Promise<AgentRunDB> {
550
- return this.request('GET', ENDPOINTS.AGENT_RUN(orgId, agentId, runId));
569
+ async getAgentSession(orgId: string, agentId: string, sessionId: string): Promise<AgentSessionDB> {
570
+ return this.request('GET', ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId));
551
571
  }
552
572
 
553
- async updateAgentRun(orgId: string, agentId: string, runId: string, req: UpdateAgentRunRequest): Promise<AgentRunDB> {
554
- return this.request('PATCH', ENDPOINTS.AGENT_RUN(orgId, agentId, runId), req);
573
+ async updateAgentSession(orgId: string, agentId: string, sessionId: string, req: UpdateAgentSessionRequest): Promise<AgentSessionDB> {
574
+ return this.request('PATCH', ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId), req);
555
575
  }
556
576
 
557
- async createAgentStep(orgId: string, agentId: string, runId: string, req: CreateAgentStepRequest): Promise<AgentStep> {
558
- return this.request('POST', ENDPOINTS.AGENT_RUN_STEPS(orgId, agentId, runId), req);
577
+ async createAgentStep(orgId: string, agentId: string, sessionId: string, req: CreateAgentStepRequest): Promise<AgentStep> {
578
+ return this.request('POST', ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), req);
559
579
  }
560
580
 
561
- async getAgentRunSteps(orgId: string, agentId: string, runId: string, params?: { limit?: number }): Promise<AgentStep[]> {
562
- const res = await this.request<{ data: AgentStep[] }>('GET', ENDPOINTS.AGENT_RUN_STEPS(orgId, agentId, runId), undefined, params);
581
+ async getAgentSessionSteps(orgId: string, agentId: string, sessionId: string, params?: { limit?: number }): Promise<AgentStep[]> {
582
+ const res = await this.request<{ data: AgentStep[] }>('GET', ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), undefined, params);
563
583
  return res.data;
564
584
  }
565
585
 
@@ -702,15 +722,11 @@ export class PondClient {
702
722
  */
703
723
  async getPlatformConfig(currentVersion?: string): Promise<PlatformConfigResponse | null> {
704
724
  const url = `${this.baseUrl}${ENDPOINTS.PLATFORM_CONFIG}`;
705
- const headers: Record<string, string> = {
706
- 'Content-Type': 'application/json',
707
- };
708
- if (this.token) {
709
- headers['Authorization'] = `Bearer ${this.token}`;
710
- }
725
+ const extra: Record<string, string> = {};
711
726
  if (currentVersion !== undefined) {
712
- headers['If-None-Match'] = currentVersion;
727
+ extra['If-None-Match'] = currentVersion;
713
728
  }
729
+ const headers = this.buildHeaders(extra);
714
730
 
715
731
  const res = await fetch(url, {
716
732
  method: 'GET',
@@ -863,6 +879,22 @@ export class PondClient {
863
879
  return this.request('GET', ENDPOINTS.WIKI_NODE_SECTIONS(orgId, wikiId), undefined, params);
864
880
  }
865
881
 
882
+ async searchWiki(orgId: string, wikiId: string, params: { q: string; limit?: number; path_prefix?: string; ref?: string }): Promise<WikiSearchResponse> {
883
+ return this.request('GET', ENDPOINTS.WIKI_SEARCH(orgId, wikiId), undefined, params);
884
+ }
885
+
886
+ async getWikiPageIndex(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiPageIndex> {
887
+ return this.request('GET', ENDPOINTS.WIKI_PAGE_INDEX(orgId, wikiId), undefined, params);
888
+ }
889
+
890
+ async getWikiRefs(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiRefsResponse> {
891
+ return this.request('GET', ENDPOINTS.WIKI_REFS(orgId, wikiId), undefined, params);
892
+ }
893
+
894
+ async checkWikiRefs(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiRefsCheckResponse> {
895
+ return this.request('GET', ENDPOINTS.WIKI_REFS_CHECK(orgId, wikiId), undefined, params);
896
+ }
897
+
866
898
  async createWikiChangeset(orgId: string, wikiId: string, data: CreateWikiChangesetRequest): Promise<WikiChangeset> {
867
899
  return normalizeWikiChangeset(await this.request('POST', ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId), data));
868
900
  }
@@ -982,6 +1014,30 @@ export class PondClient {
982
1014
  async checkBrokenRefs(orgId: string): Promise<BrokenRefsResponse> {
983
1015
  return this.request('GET', ENDPOINTS.REFS_CHECK(orgId));
984
1016
  }
1017
+
1018
+ // ---- Push Notifications ----
1019
+
1020
+ async subscribePush(body: PushSubscribeRequest): Promise<void> {
1021
+ return this.request('POST', ENDPOINTS.PUSH_SUBSCRIBE, body);
1022
+ }
1023
+
1024
+ async unsubscribePush(token: string): Promise<void> {
1025
+ return this.request('DELETE', ENDPOINTS.PUSH_UNSUBSCRIBE, { token });
1026
+ }
1027
+
1028
+ async getVapidKey(): Promise<{ vapid_public_key: string }> {
1029
+ return this.request('GET', ENDPOINTS.PUSH_VAPID_KEY);
1030
+ }
1031
+
1032
+ // ---- Notification Preferences ----
1033
+
1034
+ async getNotificationPreferences(): Promise<NotificationPreferences> {
1035
+ return this.request('GET', ENDPOINTS.NOTIFICATION_PREFERENCES);
1036
+ }
1037
+
1038
+ async updateNotificationPreferences(prefs: Partial<NotifPrefs>): Promise<NotificationPreferences> {
1039
+ return this.request('PATCH', ENDPOINTS.NOTIFICATION_PREFERENCES, { prefs });
1040
+ }
985
1041
  }
986
1042
 
987
1043
  function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
package/src/constants.ts CHANGED
@@ -70,12 +70,12 @@ export const ENDPOINTS = {
70
70
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
71
71
  AGENT_ME: (orgId: string) =>
72
72
  `${API_BASE}/orgs/${orgId}/agents/me`,
73
- AGENT_RUNS: (orgId: string, agentId: string) =>
74
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs`,
75
- AGENT_RUN: (orgId: string, agentId: string, runId: string) =>
76
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs/${runId}`,
77
- AGENT_RUN_STEPS: (orgId: string, agentId: string, runId: string) =>
78
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs/${runId}/steps`,
73
+ AGENT_SESSIONS: (orgId: string, agentId: string) =>
74
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
75
+ AGENT_SESSION: (orgId: string, agentId: string, sessionId: string) =>
76
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
77
+ AGENT_SESSION_STEPS: (orgId: string, agentId: string, sessionId: string) =>
78
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
79
79
  AGENT_TASKS: (orgId: string, agentId: string) =>
80
80
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/tasks`,
81
81
  // Machines (org-scoped)
@@ -135,6 +135,10 @@ export const ENDPOINTS = {
135
135
  WIKI_TREE: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
136
136
  WIKI_BLOB: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
137
137
  WIKI_NODE_SECTIONS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
138
+ WIKI_SEARCH: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/search`,
139
+ WIKI_PAGE_INDEX: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/page-index`,
140
+ WIKI_REFS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/refs`,
141
+ WIKI_REFS_CHECK: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/refs/check`,
138
142
  WIKI_CHANGESETS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/changesets`,
139
143
  WIKI_CHANGESET: (orgId: string, wikiId: string, changesetId: string) =>
140
144
  `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/changesets/${changesetId}`,
@@ -199,6 +203,14 @@ export const ENDPOINTS = {
199
203
  // Platform config (agent-scoped, not org-scoped)
200
204
  PLATFORM_CONFIG: `${API_BASE}/agents/platform-config`,
201
205
 
206
+ // Push notifications
207
+ PUSH_SUBSCRIBE: `${API_BASE}/push/subscribe`,
208
+ PUSH_UNSUBSCRIBE: `${API_BASE}/push/unsubscribe`,
209
+ PUSH_VAPID_KEY: `${API_BASE}/push/vapid-key`,
210
+
211
+ // Notification preferences
212
+ NOTIFICATION_PREFERENCES: `${API_BASE}/notification-preferences`,
213
+
202
214
  } as const;
203
215
 
204
216
  // WebSocket event types
@@ -206,8 +218,6 @@ export const WS_EVENTS = {
206
218
  // Client -> Server
207
219
  PING: 'ping',
208
220
  TYPING: 'typing',
209
- ACK: 'ack',
210
- READ: 'read',
211
221
  WATCH: 'watch',
212
222
  AGENT_HEARTBEAT: 'agent.heartbeat',
213
223
 
@@ -234,8 +244,8 @@ export const WS_EVENTS = {
234
244
  PROJECT_CREATED: 'project.created',
235
245
  PROJECT_UPDATED: 'project.updated',
236
246
  PROJECT_DELETED: 'project.deleted',
237
- AGENT_RUN_NEW: 'agent_run.new',
238
- AGENT_RUN_UPDATE: 'agent_run.update',
247
+ AGENT_SESSION_NEW: 'agent_session.new',
248
+ AGENT_SESSION_UPDATE: 'agent_session.update',
239
249
  AGENT_STEP_NEW: 'agent_step.new',
240
250
  INVITATION_NEW: 'invitation.new',
241
251
  INVITATION_ACCEPTED: 'invitation.accepted',
@@ -247,5 +257,6 @@ export const WS_EVENTS = {
247
257
  INBOX_NEW: 'inbox.new',
248
258
  INBOX_UPDATE: 'inbox.update',
249
259
  INBOX_BULK_UPDATE: 'inbox.bulk_update',
260
+ READ_POSITION_UPDATED: 'read_position.updated',
250
261
  DISPATCH_NEW: 'dispatch.new',
251
262
  } as const;
package/src/types.ts CHANGED
@@ -41,6 +41,26 @@ export type ChatMemberRole = 'owner' | 'admin' | 'member';
41
41
 
42
42
  export type NotificationLevel = 'all' | 'mentions_only' | 'none';
43
43
 
44
+ // Push notification subscription
45
+ export interface PushSubscribeRequest {
46
+ platform: 'web' | 'ios' | 'android';
47
+ token: string;
48
+ device_id?: string;
49
+ }
50
+
51
+ // Notification preferences
52
+ export interface NotifPrefs {
53
+ dm?: boolean;
54
+ mention?: boolean;
55
+ task_assign?: boolean;
56
+ }
57
+
58
+ export interface NotificationPreferences {
59
+ scope: string;
60
+ prefs: NotifPrefs;
61
+ updated_at: string;
62
+ }
63
+
44
64
  export interface ChatMember {
45
65
  chat_id: string;
46
66
  user_id: string;
@@ -184,7 +204,7 @@ export interface Message {
184
204
  deleted_at: string | null;
185
205
  created_at: string;
186
206
  idempotency_key: string | null;
187
- agent_run_id?: string | null;
207
+ agent_step_id?: string | null;
188
208
  hints?: MessageHints | null;
189
209
  }
190
210
 
@@ -365,7 +385,7 @@ export interface SendMessageRequest {
365
385
  content: MessageContent;
366
386
  thread_root_id?: string;
367
387
  idempotency_key?: string;
368
- agent_run_id?: string;
388
+ agent_step_id?: string;
369
389
  hints?: MessageHints;
370
390
  }
371
391
 
@@ -375,7 +395,7 @@ export interface SendDirectMessageRequest {
375
395
  content: MessageContent;
376
396
  thread_root_id?: string;
377
397
  idempotency_key?: string;
378
- agent_run_id?: string;
398
+ agent_step_id?: string;
379
399
  hints?: MessageHints;
380
400
  }
381
401
 
@@ -446,17 +466,10 @@ export interface AgentProfile {
446
466
  created_at: string;
447
467
  }
448
468
 
449
- export interface AgentRun {
450
- target_id: string;
451
- status: string;
452
- started_at: string;
453
- }
454
-
455
469
  export interface AgentPresence {
456
470
  online: boolean;
457
471
  status: string; // "online" | "busy" | "error" | "offline"
458
472
  session_id?: string;
459
- run?: AgentRun;
460
473
  telemetry?: Record<string, unknown>;
461
474
  }
462
475
 
@@ -483,7 +496,7 @@ export interface FileUrlResponse {
483
496
 
484
497
  export type TaskStatus = 'todo' | 'in_progress' | 'in_review' | 'done' | 'canceled';
485
498
  export type TaskPriority = 'high' | 'normal' | 'low';
486
- export type TaskRelationTargetType = 'task' | 'message' | 'chat' | 'agent_run';
499
+ export type TaskRelationTargetType = 'task' | 'message' | 'chat' | 'agent_session';
487
500
  export type TaskRelationType = 'blocks' | 'related' | 'duplicate' | 'source' | 'reference' | 'discussion' | 'execution';
488
501
 
489
502
  export interface Task {
@@ -698,6 +711,82 @@ export interface WikiNodeSectionArtifact {
698
711
  nodes: WikiNodeSection[];
699
712
  }
700
713
 
714
+ export interface WikiSearchResult {
715
+ wiki_id: string;
716
+ wiki_slug: string;
717
+ wiki_name: string;
718
+ node_id: string;
719
+ path: string;
720
+ title: string;
721
+ heading_path?: string[];
722
+ section_path: string;
723
+ level: number;
724
+ start_line: number;
725
+ end_line: number;
726
+ score: number;
727
+ snippet: string;
728
+ }
729
+
730
+ export interface WikiSearchResponse {
731
+ wiki_id: string;
732
+ wiki_slug: string;
733
+ wiki_name: string;
734
+ query: string;
735
+ ref: string;
736
+ results: WikiSearchResult[];
737
+ }
738
+
739
+ export interface WikiPageIndexEntry {
740
+ path: string;
741
+ title: string;
742
+ top_headings: string[];
743
+ size_bytes: number;
744
+ section_count: number;
745
+ }
746
+
747
+ export interface WikiPageIndex {
748
+ wiki_id: string;
749
+ wiki_slug: string;
750
+ wiki_name: string;
751
+ ref: string;
752
+ generated_at: string;
753
+ page_count: number;
754
+ pages: WikiPageIndexEntry[];
755
+ }
756
+
757
+ export interface WikiFileRef {
758
+ source_path: string;
759
+ uri: string;
760
+ context?: string;
761
+ prefix: string;
762
+ entity_id: string;
763
+ target_path?: string;
764
+ fragment?: string;
765
+ line: number;
766
+ }
767
+
768
+ export interface WikiRefsResponse {
769
+ wiki_id: string;
770
+ wiki_slug: string;
771
+ wiki_name: string;
772
+ ref: string;
773
+ total: number;
774
+ refs: WikiFileRef[];
775
+ }
776
+
777
+ export interface WikiBrokenRef extends WikiFileRef {
778
+ reason: string;
779
+ }
780
+
781
+ export interface WikiRefsCheckResponse {
782
+ wiki_id: string;
783
+ wiki_slug: string;
784
+ wiki_name: string;
785
+ ref: string;
786
+ total: number;
787
+ broken: WikiBrokenRef[];
788
+ }
789
+
701
790
  export interface WikiDiffFile {
702
791
  path: string;
703
792
  action?: string; // "create" | "update" | "delete"
@@ -858,7 +947,7 @@ export interface MessageNewData {
858
947
  edited_at?: string | null;
859
948
  deleted_at?: string | null;
860
949
  idempotency_key?: string | null;
861
- agent_run_id?: string | null;
950
+ agent_step_id?: string | null;
862
951
  hints?: MessageHints | null;
863
952
  }
864
953
 
@@ -932,7 +1021,7 @@ export interface TaskComment {
932
1021
  author_id: string;
933
1022
  body: string;
934
1023
  mentions?: Mention[];
935
- agent_run_id?: string | null;
1024
+ agent_step_id?: string | null;
936
1025
  created_at: string;
937
1026
  updated_at: string;
938
1027
  author?: User;
@@ -984,17 +1073,16 @@ export interface ProjectDeletedData {
984
1073
  org_id: string;
985
1074
  }
986
1075
 
987
- // ---- Agent Run / Step ----
1076
+ // ---- Agent Session / Step ----
988
1077
 
989
- export interface AgentRunDB {
1078
+ export interface AgentSessionDB {
990
1079
  id: string;
991
1080
  agent_id: string;
992
1081
  org_id: string;
993
- status: string;
994
- trigger_type: string;
995
- trigger_ref: Record<string, unknown> | null;
996
- default_target_type: string;
997
- default_target_id: string | null;
1082
+ status: string; // active | completed | failed | cancelled
1083
+ runtime_type: string;
1084
+ runtime_key: string | null;
1085
+ runtime_ref: Record<string, unknown> | null;
998
1086
  started_at: string;
999
1087
  finished_at: string | null;
1000
1088
  created_at: string;
@@ -1002,47 +1090,48 @@ export interface AgentRunDB {
1002
1090
 
1003
1091
  export interface AgentStep {
1004
1092
  id: string;
1005
- run_id: string;
1093
+ session_id: string;
1006
1094
  step_type: string;
1095
+ target_type: string;
1096
+ target_id: string | null;
1007
1097
  content: Record<string, unknown>;
1098
+ group_key: string | null;
1099
+ runtime_key: string | null;
1008
1100
  idempotency_key?: string;
1009
1101
  created_at: string;
1010
1102
  }
1011
1103
 
1012
- export interface CreateAgentRunRequest {
1013
- trigger_type: string;
1014
- trigger_ref?: Record<string, unknown>;
1015
- chat_id?: string; // backward compat alias for default_target_type=chat
1016
- default_target_type?: string;
1017
- default_target_id?: string;
1104
+ export interface CreateAgentSessionRequest {
1105
+ runtime_type?: string;
1106
+ runtime_key?: string;
1107
+ runtime_ref?: Record<string, unknown>;
1018
1108
  }
1019
1109
 
1020
1110
  export interface CreateAgentStepRequest {
1021
1111
  step_type: string;
1022
1112
  content: Record<string, unknown>;
1113
+ target_type?: string;
1114
+ target_id?: string;
1115
+ group_key?: string;
1116
+ runtime_key?: string;
1023
1117
  idempotency_key?: string;
1024
- projection?: boolean;
1025
- chat_projection?: boolean; // backward compat alias for projection
1118
+ projection?: boolean; // project text steps to chat message or task comment (controlled by agent's run_config)
1026
1119
  }
1027
1120
 
1028
- export interface UpdateAgentRunRequest {
1121
+ export interface UpdateAgentSessionRequest {
1029
1122
  status: string;
1030
- emit_fallback_message?: boolean;
1031
1123
  }
1032
1124
 
1033
- // Agent run WS event data
1034
- export type AgentRunNewData = AgentRunDB;
1125
+ // Agent session WS event data
1126
+ export type AgentSessionNewData = AgentSessionDB;
1035
1127
 
1036
- export interface AgentRunUpdateData {
1037
- run_id: string;
1128
+ export interface AgentSessionUpdateData {
1129
+ session_id: string;
1038
1130
  status: string;
1039
1131
  finished_at?: string;
1040
1132
  }
1041
1133
 
1042
- export interface AgentStepNewData extends AgentStep {
1043
- target_type?: string;
1044
- target_id?: string;
1045
- }
1134
+ export interface AgentStepNewData extends AgentStep {}
1046
1135
 
1047
1136
  export type WikiChangesetCreatedData = WikiChangeset & { org_id: string };
1048
1137
  export type WikiChangesetUpdatedData = WikiChangeset & { org_id: string };
@@ -1119,6 +1208,11 @@ export interface InboxUnreadCountResponse {
1119
1208
  count: number;
1120
1209
  }
1121
1210
 
1211
+ export interface ReadPositionUpdateData {
1212
+ chat_id: string;
1213
+ last_read_message_id: string;
1214
+ }
1215
+
1122
1216
  export type WsEventMap = {
1123
1217
  'hello': HelloData;
1124
1218
  'message.new': MessageNewData;
@@ -1144,8 +1238,8 @@ export type WsEventMap = {
1144
1238
  'project.created': ProjectCreatedData;
1145
1239
  'project.updated': ProjectUpdatedData;
1146
1240
  'project.deleted': ProjectDeletedData;
1147
- 'agent_run.new': AgentRunNewData;
1148
- 'agent_run.update': AgentRunUpdateData;
1241
+ 'agent_session.new': AgentSessionNewData;
1242
+ 'agent_session.update': AgentSessionUpdateData;
1149
1243
  'agent_step.new': AgentStepNewData;
1150
1244
  'invitation.new': InvitationNewEventData;
1151
1245
  'invitation.accepted': InvitationAcceptedEventData;
@@ -1157,6 +1251,7 @@ export type WsEventMap = {
1157
1251
  'inbox.new': InboxNewData;
1158
1252
  'inbox.update': InboxUpdateData;
1159
1253
  'inbox.bulk_update': InboxBulkUpdateData;
1254
+ 'read_position.updated': ReadPositionUpdateData;
1160
1255
  'dispatch.new': DispatchNewData;
1161
1256
  };
1162
1257
 
package/src/ws.ts CHANGED
@@ -7,8 +7,6 @@ export type WsEventHandler<T extends WsEventType> = (data: WsEventMap[T], seq?:
7
7
  export type WsClientEventMap = {
8
8
  'ping': { ts: number };
9
9
  'typing': { chat_id: string; thread_root_id: string | null; action: 'start' | 'stop' };
10
- 'ack': { message_id: string };
11
- 'read': { chat_id: string; last_read_id: string };
12
10
  'watch': { chat_ids: string[] };
13
11
  'agent.heartbeat': { session_id: string; telemetry?: Record<string, unknown> };
14
12
  };
@@ -81,12 +79,15 @@ export class PondWs {
81
79
  return;
82
80
  }
83
81
 
84
- const params = new URLSearchParams({ ticket: ticket.ticket });
82
+ // wsUrl may already contain query params (e.g. ?swimlane=pr-42 for
83
+ // swimlane routing). Use URL API to merge params correctly.
84
+ const url = new URL(wsUrl);
85
+ url.searchParams.set('ticket', ticket.ticket);
85
86
  if (this.lastSeq > 0) {
86
- params.set('last_seq', String(this.lastSeq));
87
+ url.searchParams.set('last_seq', String(this.lastSeq));
87
88
  }
88
89
 
89
- this.ws = new WebSocket(`${wsUrl}?${params.toString()}`);
90
+ this.ws = new WebSocket(url.toString());
90
91
 
91
92
  // Force-reconnect if not connected within 15s.
92
93
  // Handles edge case where Node 22 WebSocket transitions to CLOSED without
@@ -171,14 +172,6 @@ export class PondWs {
171
172
  });
172
173
  }
173
174
 
174
- sendAck(messageId: string) {
175
- this.send({ type: WS_EVENTS.ACK, data: { message_id: messageId } });
176
- }
177
-
178
- sendRead(chatId: string, lastReadId: string) {
179
- this.send({ type: WS_EVENTS.READ, data: { chat_id: chatId, last_read_id: lastReadId } });
180
- }
181
-
182
175
  /** Send an agent heartbeat with telemetry data. */
183
176
  sendAgentHeartbeat(sessionId: string, telemetry?: Record<string, unknown>) {
184
177
  this.send({