@harness-gw/sdk 0.4.1 → 0.5.1

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.
@@ -44,7 +44,7 @@ export declare class HgwRemoteClient {
44
44
  id: string;
45
45
  name: string;
46
46
  };
47
- status: "unavailable" | "ready" | "degraded";
47
+ status: "degraded" | "ready" | "unavailable";
48
48
  capabilities: {
49
49
  agentCatalog: {
50
50
  status: "available";
@@ -174,8 +174,8 @@ export declare class HgwRemoteClient {
174
174
  filename?: string | undefined;
175
175
  } | {
176
176
  type: "file";
177
- mimeType: string;
178
177
  filename?: string | undefined;
178
+ mimeType: string;
179
179
  })[];
180
180
  }>;
181
181
  readArtifact(sessionId: string, artifactId: string, signal?: AbortSignal): Promise<Blob>;
@@ -202,11 +202,27 @@ export declare class HgwRemoteClient {
202
202
  toolInput?: Record<string, unknown> | undefined;
203
203
  toolResult?: {
204
204
  [x: string]: unknown;
205
+ _meta?: {
206
+ [x: string]: unknown;
207
+ "io.modelcontextprotocol/serverInfo"?: {
208
+ version: string;
209
+ websiteUrl?: string | undefined;
210
+ description?: string | undefined;
211
+ icons?: {
212
+ src: string;
213
+ mimeType?: string | undefined;
214
+ sizes?: string[] | undefined;
215
+ theme?: "dark" | "light" | undefined;
216
+ }[] | undefined;
217
+ name: string;
218
+ title?: string | undefined;
219
+ } | undefined;
220
+ } | undefined;
205
221
  content: ({
206
222
  type: "text";
207
223
  text: string;
208
224
  annotations?: {
209
- audience?: ("user" | "assistant")[] | undefined;
225
+ audience?: ("assistant" | "user")[] | undefined;
210
226
  priority?: number | undefined;
211
227
  lastModified?: string | undefined;
212
228
  } | undefined;
@@ -216,7 +232,7 @@ export declare class HgwRemoteClient {
216
232
  data: string;
217
233
  mimeType: string;
218
234
  annotations?: {
219
- audience?: ("user" | "assistant")[] | undefined;
235
+ audience?: ("assistant" | "user")[] | undefined;
220
236
  priority?: number | undefined;
221
237
  lastModified?: string | undefined;
222
238
  } | undefined;
@@ -226,20 +242,18 @@ export declare class HgwRemoteClient {
226
242
  data: string;
227
243
  mimeType: string;
228
244
  annotations?: {
229
- audience?: ("user" | "assistant")[] | undefined;
245
+ audience?: ("assistant" | "user")[] | undefined;
230
246
  priority?: number | undefined;
231
247
  lastModified?: string | undefined;
232
248
  } | undefined;
233
249
  _meta?: Record<string, unknown> | undefined;
234
250
  } | {
235
251
  uri: string;
236
- name: string;
237
- type: "resource_link";
238
252
  description?: string | undefined;
239
253
  mimeType?: string | undefined;
240
254
  size?: number | undefined;
241
255
  annotations?: {
242
- audience?: ("user" | "assistant")[] | undefined;
256
+ audience?: ("assistant" | "user")[] | undefined;
243
257
  priority?: number | undefined;
244
258
  lastModified?: string | undefined;
245
259
  } | undefined;
@@ -250,45 +264,31 @@ export declare class HgwRemoteClient {
250
264
  src: string;
251
265
  mimeType?: string | undefined;
252
266
  sizes?: string[] | undefined;
253
- theme?: "light" | "dark" | undefined;
267
+ theme?: "dark" | "light" | undefined;
254
268
  }[] | undefined;
269
+ name: string;
255
270
  title?: string | undefined;
271
+ type: "resource_link";
256
272
  } | {
257
273
  type: "resource";
258
274
  resource: {
259
275
  uri: string;
260
- text: string;
261
276
  mimeType?: string | undefined;
262
277
  _meta?: Record<string, unknown> | undefined;
278
+ text: string;
263
279
  } | {
264
280
  uri: string;
265
- blob: string;
266
281
  mimeType?: string | undefined;
267
282
  _meta?: Record<string, unknown> | undefined;
283
+ blob: string;
268
284
  };
269
285
  annotations?: {
270
- audience?: ("user" | "assistant")[] | undefined;
286
+ audience?: ("assistant" | "user")[] | undefined;
271
287
  priority?: number | undefined;
272
288
  lastModified?: string | undefined;
273
289
  } | undefined;
274
290
  _meta?: Record<string, unknown> | undefined;
275
291
  })[];
276
- _meta?: {
277
- [x: string]: unknown;
278
- "io.modelcontextprotocol/serverInfo"?: {
279
- version: string;
280
- name: string;
281
- websiteUrl?: string | undefined;
282
- description?: string | undefined;
283
- icons?: {
284
- src: string;
285
- mimeType?: string | undefined;
286
- sizes?: string[] | undefined;
287
- theme?: "light" | "dark" | undefined;
288
- }[] | undefined;
289
- title?: string | undefined;
290
- } | undefined;
291
- } | undefined;
292
292
  structuredContent?: unknown;
293
293
  isError?: boolean | undefined;
294
294
  } | undefined;
@@ -305,11 +305,27 @@ export declare class HgwRemoteClient {
305
305
  /** A tool call the App view makes, answered by the proxy's MCP server. */
306
306
  callMcpAppTool(sessionId: string, toolCallId: string, request: McpAppToolCallRequest): Promise<{
307
307
  [x: string]: unknown;
308
+ _meta?: {
309
+ [x: string]: unknown;
310
+ "io.modelcontextprotocol/serverInfo"?: {
311
+ version: string;
312
+ websiteUrl?: string | undefined;
313
+ description?: string | undefined;
314
+ icons?: {
315
+ src: string;
316
+ mimeType?: string | undefined;
317
+ sizes?: string[] | undefined;
318
+ theme?: "dark" | "light" | undefined;
319
+ }[] | undefined;
320
+ name: string;
321
+ title?: string | undefined;
322
+ } | undefined;
323
+ } | undefined;
308
324
  content: ({
309
325
  type: "text";
310
326
  text: string;
311
327
  annotations?: {
312
- audience?: ("user" | "assistant")[] | undefined;
328
+ audience?: ("assistant" | "user")[] | undefined;
313
329
  priority?: number | undefined;
314
330
  lastModified?: string | undefined;
315
331
  } | undefined;
@@ -319,7 +335,7 @@ export declare class HgwRemoteClient {
319
335
  data: string;
320
336
  mimeType: string;
321
337
  annotations?: {
322
- audience?: ("user" | "assistant")[] | undefined;
338
+ audience?: ("assistant" | "user")[] | undefined;
323
339
  priority?: number | undefined;
324
340
  lastModified?: string | undefined;
325
341
  } | undefined;
@@ -329,20 +345,18 @@ export declare class HgwRemoteClient {
329
345
  data: string;
330
346
  mimeType: string;
331
347
  annotations?: {
332
- audience?: ("user" | "assistant")[] | undefined;
348
+ audience?: ("assistant" | "user")[] | undefined;
333
349
  priority?: number | undefined;
334
350
  lastModified?: string | undefined;
335
351
  } | undefined;
336
352
  _meta?: Record<string, unknown> | undefined;
337
353
  } | {
338
354
  uri: string;
339
- name: string;
340
- type: "resource_link";
341
355
  description?: string | undefined;
342
356
  mimeType?: string | undefined;
343
357
  size?: number | undefined;
344
358
  annotations?: {
345
- audience?: ("user" | "assistant")[] | undefined;
359
+ audience?: ("assistant" | "user")[] | undefined;
346
360
  priority?: number | undefined;
347
361
  lastModified?: string | undefined;
348
362
  } | undefined;
@@ -353,78 +367,64 @@ export declare class HgwRemoteClient {
353
367
  src: string;
354
368
  mimeType?: string | undefined;
355
369
  sizes?: string[] | undefined;
356
- theme?: "light" | "dark" | undefined;
370
+ theme?: "dark" | "light" | undefined;
357
371
  }[] | undefined;
372
+ name: string;
358
373
  title?: string | undefined;
374
+ type: "resource_link";
359
375
  } | {
360
376
  type: "resource";
361
377
  resource: {
362
378
  uri: string;
363
- text: string;
364
379
  mimeType?: string | undefined;
365
380
  _meta?: Record<string, unknown> | undefined;
381
+ text: string;
366
382
  } | {
367
383
  uri: string;
368
- blob: string;
369
384
  mimeType?: string | undefined;
370
385
  _meta?: Record<string, unknown> | undefined;
386
+ blob: string;
371
387
  };
372
388
  annotations?: {
373
- audience?: ("user" | "assistant")[] | undefined;
389
+ audience?: ("assistant" | "user")[] | undefined;
374
390
  priority?: number | undefined;
375
391
  lastModified?: string | undefined;
376
392
  } | undefined;
377
393
  _meta?: Record<string, unknown> | undefined;
378
394
  })[];
395
+ structuredContent?: unknown;
396
+ isError?: boolean | undefined;
397
+ }>;
398
+ /** A resource read the App view makes, answered by the proxy's MCP server. */
399
+ readMcpAppResource(sessionId: string, subject: McpAppSubject, request: McpAppResourceReadRequest): Promise<{
400
+ [x: string]: unknown;
379
401
  _meta?: {
380
402
  [x: string]: unknown;
381
403
  "io.modelcontextprotocol/serverInfo"?: {
382
404
  version: string;
383
- name: string;
384
405
  websiteUrl?: string | undefined;
385
406
  description?: string | undefined;
386
407
  icons?: {
387
408
  src: string;
388
409
  mimeType?: string | undefined;
389
410
  sizes?: string[] | undefined;
390
- theme?: "light" | "dark" | undefined;
411
+ theme?: "dark" | "light" | undefined;
391
412
  }[] | undefined;
413
+ name: string;
392
414
  title?: string | undefined;
393
415
  } | undefined;
394
416
  } | undefined;
395
- structuredContent?: unknown;
396
- isError?: boolean | undefined;
397
- }>;
398
- /** A resource read the App view makes, answered by the proxy's MCP server. */
399
- readMcpAppResource(sessionId: string, subject: McpAppSubject, request: McpAppResourceReadRequest): Promise<{
400
- [x: string]: unknown;
401
417
  contents: ({
402
418
  uri: string;
403
- text: string;
404
419
  mimeType?: string | undefined;
405
420
  _meta?: Record<string, unknown> | undefined;
421
+ text: string;
406
422
  } | {
407
423
  uri: string;
408
- blob: string;
409
424
  mimeType?: string | undefined;
410
425
  _meta?: Record<string, unknown> | undefined;
426
+ blob: string;
411
427
  })[];
412
- _meta?: {
413
- [x: string]: unknown;
414
- "io.modelcontextprotocol/serverInfo"?: {
415
- version: string;
416
- name: string;
417
- websiteUrl?: string | undefined;
418
- description?: string | undefined;
419
- icons?: {
420
- src: string;
421
- mimeType?: string | undefined;
422
- sizes?: string[] | undefined;
423
- theme?: "light" | "dark" | undefined;
424
- }[] | undefined;
425
- title?: string | undefined;
426
- } | undefined;
427
- } | undefined;
428
428
  }>;
429
429
  transcribe(sessionId: string, audio: Blob, signal?: AbortSignal): Promise<string>;
430
430
  transcribeForAgent(agentId: string, audio: Blob, signal?: AbortSignal): Promise<string>;
@@ -1518,8 +1518,15 @@ function statusFromState(update) {
1518
1518
  const stopReason = update.stopReason;
1519
1519
  return stopReason === HGW_STOP_REASONS2.error || stopReason === HGW_STOP_REASONS2.uncertain ? "failed" : "idle";
1520
1520
  }
1521
- function activityEventOf(notification) {
1522
- const { agentId, sessionId, occurredAt, type } = notification;
1521
+ var FEED_STATUS = {
1522
+ "turn-started": "running",
1523
+ "attention-requested": "waiting-for-input",
1524
+ "attention-resolved": "running",
1525
+ "turn-finished": "idle",
1526
+ "turn-failed": "failed"
1527
+ };
1528
+ function activityEventOf(notification, marksReplays) {
1529
+ const { agentId, sessionId, occurredAt, type, replayed } = notification;
1523
1530
  if (type === "unread-changed")
1524
1531
  return;
1525
1532
  const key = "turnId" in notification ? notification.turnId : ("requestId" in notification) ? notification.requestId : occurredAt;
@@ -1527,15 +1534,20 @@ function activityEventOf(notification) {
1527
1534
  id: `${sessionId}:${key}:${type}`,
1528
1535
  agentId,
1529
1536
  sessionId,
1530
- occurredAt
1537
+ occurredAt,
1538
+ ...replayed && marksReplays ? { replayed } : {}
1531
1539
  };
1532
- if (type === "attention-requested")
1540
+ if (type === "attention-requested") {
1541
+ const { requestText, requestMore } = notification;
1533
1542
  return {
1534
1543
  ...base,
1535
1544
  type,
1536
1545
  requestId: notification.requestId,
1537
- attentionKind: notification.attentionKind
1546
+ attentionKind: notification.attentionKind,
1547
+ ...requestText === undefined ? {} : { requestText },
1548
+ ...requestMore === undefined ? {} : { requestMore }
1538
1549
  };
1550
+ }
1539
1551
  if (type === "attention-resolved")
1540
1552
  return { ...base, type, requestId: notification.requestId };
1541
1553
  return { ...base, type, turnId: notification.turnId };
@@ -1553,6 +1565,9 @@ function createAcpSessionStore({
1553
1565
  const todos = new Map;
1554
1566
  const replaying = new Map;
1555
1567
  const subscriptions = new Set;
1568
+ const subscribed = new Map;
1569
+ const openRequests = new Map;
1570
+ let marksReplays = true;
1556
1571
  const todoListeners = new Map;
1557
1572
  const activityListeners = new Set;
1558
1573
  const invalidationListeners = new Map;
@@ -1660,16 +1675,43 @@ function createAcpSessionStore({
1660
1675
  update: (update, meta) => acceptUpdate(sessionId, update, meta),
1661
1676
  replay: () => holdReplayedStatus(sessionId)
1662
1677
  });
1678
+ subscribed.set(sessionId, (subscribed.get(sessionId) ?? 0) + 1);
1663
1679
  return () => {
1664
1680
  leave();
1681
+ const holders = (subscribed.get(sessionId) ?? 1) - 1;
1682
+ if (holders > 0)
1683
+ subscribed.set(sessionId, holders);
1684
+ else
1685
+ subscribed.delete(sessionId);
1665
1686
  todos.delete(sessionId);
1666
1687
  replaying.delete(sessionId);
1667
1688
  };
1668
1689
  }
1690
+ function noteActivity(notification) {
1691
+ const { sessionId, type } = notification;
1692
+ const open = openRequests.get(sessionId) ?? new Set;
1693
+ if (type === "attention-requested")
1694
+ open.add(notification.requestId);
1695
+ else if (type === "attention-resolved")
1696
+ open.delete(notification.requestId);
1697
+ else if (type === "turn-finished" || type === "turn-failed")
1698
+ open.clear();
1699
+ if (open.size > 0)
1700
+ openRequests.set(sessionId, open);
1701
+ else
1702
+ openRequests.delete(sessionId);
1703
+ const status = FEED_STATUS[type];
1704
+ if (!status || subscribed.has(sessionId))
1705
+ return;
1706
+ if (type === "attention-resolved" && open.size > 0)
1707
+ return;
1708
+ patch(sessionId, { status });
1709
+ }
1669
1710
  const leaveActivity = subscribeHgwNotification(connection, HGW_METHODS2.notify.activity, HgwActivityNotificationSchema2, (notification) => {
1670
1711
  if (notification.type === "unread-changed")
1671
1712
  return patch(notification.sessionId, { unread: notification.unread });
1672
- const event = activityEventOf(notification);
1713
+ noteActivity(notification);
1714
+ const event = activityEventOf(notification, marksReplays);
1673
1715
  if (event)
1674
1716
  emitActivity(event);
1675
1717
  });
@@ -1678,6 +1720,10 @@ function createAcpSessionStore({
1678
1720
  dispose() {
1679
1721
  leaveActivity();
1680
1722
  },
1723
+ startOver() {
1724
+ openRequests.clear();
1725
+ marksReplays = false;
1726
+ },
1681
1727
  put,
1682
1728
  rowsFor,
1683
1729
  setTitle: (sessionId, title) => titles.set(sessionId, title),
@@ -1922,8 +1968,10 @@ function createAcpWorkspaceClient({
1922
1968
  let connectionCurrentlyReady = connectionEverReady;
1923
1969
  const leaveStatus = connection.subscribeStatus((status) => {
1924
1970
  if (status === "ready") {
1925
- if (connectionEverReady && !connectionCurrentlyReady)
1971
+ if (connectionEverReady && !connectionCurrentlyReady) {
1972
+ store.startOver();
1926
1973
  scheduleSessionRelist();
1974
+ }
1927
1975
  connectionEverReady = true;
1928
1976
  connectionCurrentlyReady = true;
1929
1977
  } else {
@@ -1971,12 +2019,20 @@ function createAcpWorkspaceClient({
1971
2019
  return (await catalog()).agents.map(({ summary }) => summary);
1972
2020
  },
1973
2021
  async listAgentCatalog() {
1974
- return (await catalog()).agents.map(({ summary, visibility, selectable, editable, avatarEditable }) => ({
2022
+ return (await catalog()).agents.map(({
2023
+ summary,
2024
+ visibility,
2025
+ selectable,
2026
+ editable,
2027
+ avatarEditable,
2028
+ muteEditable
2029
+ }) => ({
1975
2030
  summary,
1976
2031
  visibility,
1977
2032
  selectable,
1978
2033
  editable,
1979
- avatarEditable
2034
+ avatarEditable,
2035
+ muteEditable
1980
2036
  }));
1981
2037
  },
1982
2038
  updateAgent,
@@ -20,11 +20,11 @@ type Json = Record<string, unknown>;
20
20
  * the message itself without its credentials.
21
21
  */
22
22
  export declare function frameFields(direction: "in" | "out", message: unknown): {
23
- frame: Json;
24
- sessionId?: string | undefined;
25
- method?: string | undefined;
23
+ direction: "in" | "out";
26
24
  requestId?: {} | null | undefined;
27
- direction: "out" | "in";
25
+ method?: string | undefined;
26
+ sessionId?: string | undefined;
27
+ frame: Json;
28
28
  };
29
29
  /** `stream` with one `acp.frame` debug line per message, each way. */
30
30
  export declare function loggedStream(stream: WireStream, logger: Logger): WireStream;
@@ -9,6 +9,8 @@ export type AgentVisibility = "visible" | "hidden";
9
9
  export type AgentUpdate = {
10
10
  visibility?: AgentVisibility;
11
11
  avatar?: string | null;
12
+ /** Mutes the Agent's notifications, or with `false` unmutes them. */
13
+ muted?: boolean;
12
14
  };
13
15
  /** Actionable Agent update refusals; all other failures remain ordinary Errors. */
14
16
  export declare class AgentUpdateError extends Error {
@@ -21,6 +23,8 @@ export type ActivityBase = {
21
23
  agentId: string;
22
24
  sessionId: string;
23
25
  occurredAt: string;
26
+ /** Re-sent on connect from what the gateway already held. */
27
+ replayed?: true;
24
28
  };
25
29
  export type WorkspaceActivityEvent = (ActivityBase & {
26
30
  type: "turn-started";
@@ -32,6 +36,10 @@ export type WorkspaceActivityEvent = (ActivityBase & {
32
36
  type: "attention-requested";
33
37
  attentionKind: "question" | "permission";
34
38
  requestId: string;
39
+ /** One masked line of what is asked; absent when nothing can be shown. */
40
+ requestText?: string;
41
+ /** How many further questions the request asks. */
42
+ requestMore?: number;
35
43
  }) | (ActivityBase & {
36
44
  type: "attention-resolved";
37
45
  requestId: string;