@artooi/ag-ui-web-component 0.24.0 → 0.25.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.
@@ -82,9 +82,19 @@ export declare const MAX_TOOL_ROUNDS = 10;
82
82
  /**
83
83
  * Lifecycle status of a rendered tool-call card. A card opens as `PENDING`
84
84
  * while the call runs, then settles to `DONE`, `ERROR`, or `DECLINED`.
85
+ *
86
+ * `DEFERRED` is the one non-terminal state that is not "running": a server-side
87
+ * tool a `ToolGuard` gated never executed, the run finished on an interrupt, and
88
+ * the call is waiting on a person. Without it such a card sat at `PENDING` and
89
+ * read "running…" while the stream was over and the server idle — a status enum
90
+ * missing a state does not omit that state, it renders it as whichever neighbour
91
+ * is closest, and here the closest one claimed the opposite of the truth. A
92
+ * *frontend* tool waiting on its own card (`ask_user`) stays `PENDING`, because
93
+ * the browser really is running it.
85
94
  */
86
95
  export declare const TOOL_CALL_STATUS: {
87
96
  readonly PENDING: "pending";
97
+ readonly DEFERRED: "deferred";
88
98
  readonly DONE: "done";
89
99
  readonly ERROR: "error";
90
100
  readonly DECLINED: "declined";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,qCAAqC;AACrC,eAAO,MAAM,YAAY;aACvB,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,WAAW;CACd,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C,yEAAyE;AACzE,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;aAC3B,OAAO,EAAE,SAAS;aAClB,IAAI,EAAE,MAAM;aACZ,KAAK,EAAE,OAAO;aACd,QAAQ,EAAE,UAAU;CACZ,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;aAC5B,SAAS,EAAE,WAAW;aACtB,KAAK,EAAE,OAAO;aACd,KAAK,EAAE,OAAO;CACN,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,OAAO,EAAE,SAAS;aAClB,OAAO,EAAE,SAAS;aAClB,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,yHAAiH,CAAC;AAExI,yEAAyE;AACzE,eAAO,MAAM,SAAS,qJAAqI,CAAC;AAE5J,2CAA2C;AAC3C,eAAO,MAAM,WAAW,wJAAgJ,CAAC;AAEzK,yDAAyD;AACzD,eAAO,MAAM,UAAU,0MAA8L,CAAC;AAEtN,mFAAmF;AACnF,eAAO,MAAM,aAAa,2KAAmK,CAAC;AAE9L;;;;;GAKG;AACH,eAAO,MAAM,SAAS,0KAAgK,CAAC;AAEvL,sEAAsE;AACtE,eAAO,MAAM,eAAe,kOAA0M,CAAC;AAEvO,sEAAsE;AACtE,eAAO,MAAM,aAAa,iQAA2O,CAAC;AAEtQ,gDAAgD;AAChD,eAAO,MAAM,cAAc,8MAAkM,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,qCAAqC;AACrC,eAAO,MAAM,YAAY;aACvB,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,WAAW;CACd,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C,yEAAyE;AACzE,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;aAC3B,OAAO,EAAE,SAAS;aAClB,QAAQ,EAAE,UAAU;aACpB,IAAI,EAAE,MAAM;aACZ,KAAK,EAAE,OAAO;aACd,QAAQ,EAAE,UAAU;CACZ,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;aAC5B,SAAS,EAAE,WAAW;aACtB,KAAK,EAAE,OAAO;aACd,KAAK,EAAE,OAAO;CACN,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,OAAO,EAAE,SAAS;aAClB,OAAO,EAAE,SAAS;aAClB,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,yHAAiH,CAAC;AAExI,yEAAyE;AACzE,eAAO,MAAM,SAAS,qJAAqI,CAAC;AAE5J,2CAA2C;AAC3C,eAAO,MAAM,WAAW,wJAAgJ,CAAC;AAEzK,yDAAyD;AACzD,eAAO,MAAM,UAAU,0MAA8L,CAAC;AAEtN,mFAAmF;AACnF,eAAO,MAAM,aAAa,2KAAmK,CAAC;AAE9L;;;;;GAKG;AACH,eAAO,MAAM,SAAS,0KAAgK,CAAC;AAEvL,sEAAsE;AACtE,eAAO,MAAM,eAAe,kOAA0M,CAAC;AAEvO,sEAAsE;AACtE,eAAO,MAAM,aAAa,iQAA2O,CAAC;AAEtQ,gDAAgD;AAChD,eAAO,MAAM,cAAc,8MAAkM,CAAC"}
@@ -342,6 +342,15 @@ export declare class AgUiChat extends HTMLElement {
342
342
  * an empty panel.
343
343
  */
344
344
  openCheckpoints(): void;
345
+ /** Close the checkpoints panel, if it is open. */
346
+ closeCheckpoints(): void;
347
+ /**
348
+ * Open the checkpoints panel, or close it if it is already open — what the
349
+ * built-in ⭯ button does, because a control that opens a panel is read as the
350
+ * control that also dismisses it. {@link openCheckpoints} stays open-only for a
351
+ * host that means exactly that.
352
+ */
353
+ toggleCheckpoints(): void;
345
354
  /**
346
355
  * Start a fresh conversation: forget the persisted history, drop the
347
356
  * in-memory run state, clear the transcript, and mint a new thread id.
@@ -1 +1 @@
1
- {"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAsB,IAAI,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EASL,YAAY,EAWb,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,KAAK,UAAU,EAAsB,MAAM,kCAAkC,CAAC;AAGvF,OAAO,EAAyB,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,wBAAwB,CAAC;AAchC,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AASzF,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,iBAAiB,CAAC;AACzE,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,wBAAwB,CAAC;AAG5E,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,wBAAwB,CAAC;AAG9E,8CAA8C;AAC9C,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE3E,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,CAAC;CAChD;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,CAAC;IAC/C,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD;AAED,sFAAsF;AACtF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACpC;AAED,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;CACpC;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAmDD;;;;;;;;;;GAUG;AACH,qBAAa,QAAS,SAAQ,WAAW;;IACvC,wEAAwE;IACxE,YAAY,EAAE,YAAY,CAAmB;IAE7C;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAErC;;;;;;;;OAQG;IACH,UAAU,EAAE,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAQ;IAEzD;;;;;OAKG;IACH,WAAW,UAAS;IAEpB,yEAAyE;IACzE,WAAW,UAAS;IAEpB;;;;;OAKG;IACH,OAAO,UAAS;IAEhB;;;;OAIG;IACH,eAAe,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAEhD;;;;;;OAMG;IACH,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAEjD;;;;;;OAMG;IACH,gBAAgB,EACZ,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GACjF,IAAI,CAAQ;IAEhB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,IAAI,EAAE,CAOpB;IAEF;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,OAAO,EAAE,CAEzB;IAEF;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAM;IAExB;;;;OAIG;IACH,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAEjD,iEAAiE;IACjE,UAAU,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,CAAQ;IAE1C,iEAAiE;IACjE,iBAAiB,UAAQ;IAEzB;;;;OAIG;IACH,iBAAiB,EAAE,uBAAuB,CAA6B;IAEvE;;;;;;OAMG;IACH,aAAa,EAAE,aAAa,GAAG,IAAI,CAAQ;IAE3C;;;;;OAKG;IACH,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAEnD;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,OAAO,CAG5D;IAEH;;;;OAIG;IACH,YAAY,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAc;IAEzD;;;;;OAKG;IACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAE3C;;;;;OAKG;IACH,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAM;IAEjC;;;;;OAKG;IACH,iBAAiB,EAAE,iBAAiB,CAA2D;IA6G/F,cAqCC;IAqED,oEAAoE;IACpE,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAgD1F;IAED,kDAAkD;IAClD,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAEnC;IAED;;;;;;;;OAQG;IACH,IAAI,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEnD;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAKvD;IAED,6EAA6E;IAC7E,iBAAiB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAI1C;IAED;;;;OAIG;IACH,iBAAiB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAE1C;IAoJD,kEAAkE;IAClE,IAAI,QAAQ,IAAI,MAAM,CAErB;IAKD,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAEzB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAG3C;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,EAe/C;IAqCD;;;;;;;OAOG;IACH,IAAI,WAAW,IAAI,eAAe,CAUjC;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,eAAe,EAErC;IAED,iBAAiB,IAAI,IAAI,CAgDxB;IAiCD;;;;;;;;;;;;OAYG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAK5B;IAED;;;;;OAKG;IACH,oBAAoB,IAAI,IAAI,CAK3B;IAwMD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,IAAI,CAGxC;IAiHD,gFAAgF;IAChF,IAAI,SAAS,IAAI,OAAO,CAEvB;IAID,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAiBrC;IAED;;;;;OAKG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,qEAAqE;IACrE,eAAe,IAAI,IAAI,CAEtB;IAED;;;;;OAKG;IACH,WAAW,IAAI,IAAI,CAKlB;IAwJD;;;;;;;;OAQG;IACH,WAAW,IAAI,IAAI,CAGlB;IAED;;;;;;OAMG;IACH,eAAe,IAAI,IAAI,CAGtB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CASd;IA4ND;;;;;;;;;OASG;IACH,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAkBhE;IAseD;;;;;;;;;;;;;;OAcG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,SAAS,aAAa,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5F;IAED;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAM9B;CA2fF"}
1
+ {"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,16 @@ export interface RunRow {
6
6
  readonly started_at: string | null;
7
7
  /** Whether the run has a snapshot to seed from — see {@link RunIndex}. */
8
8
  readonly continuable: boolean;
9
+ /**
10
+ * The run's first user message, one line, already truncated by the server —
11
+ * the only field in a row a person recognises a conversation by.
12
+ *
13
+ * Optional because a server predating the field does not send it, and
14
+ * `null` where the run holds no words to show (seeded from history alone, or
15
+ * opened with an image and no caption). A row without one falls back to the
16
+ * time plus a short id, which is what every row used to be.
17
+ */
18
+ readonly preview?: string | null;
9
19
  }
10
20
  /** Live header source, read per request so rotated tokens / CSRF reach the server. */
11
21
  type HeadersProvider = () => Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"run_index.d.ts","sourceRoot":"","sources":["../../src/core/run_index.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,sFAAsF;AACtF,KAAK,eAAe,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD,kFAAkF;AAClF,KAAK,mBAAmB,GAAG,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,QAAQ;;IAKnB,YACE,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,eAA4B,EACrC,WAAW,GAAE,mBAAqC,EAKnD;IAED;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAoBvC;IAED,+CAA+C;IACzC,WAAW,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAE9C;IAED,wDAAwD;IACxD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/B;IAED,uFAAuF;IACvF,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7B;CAaF"}
1
+ {"version":3,"file":"run_index.d.ts","sourceRoot":"","sources":["../../src/core/run_index.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,sFAAsF;AACtF,KAAK,eAAe,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD,kFAAkF;AAClF,KAAK,mBAAmB,GAAG,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,QAAQ;;IAKnB,YACE,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,eAA4B,EACrC,WAAW,GAAE,mBAAqC,EAKnD;IAED;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAoBvC;IAED,+CAA+C;IACzC,WAAW,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAE9C;IAED,wDAAwD;IACxD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/B;IAED,uFAAuF;IACvF,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7B;CAaF"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ var READ_PAGE_TOOL = "read_page";
18
18
  var MAX_TOOL_ROUNDS = 10;
19
19
  var TOOL_CALL_STATUS = {
20
20
  PENDING: "pending",
21
+ DEFERRED: "deferred",
21
22
  DONE: "done",
22
23
  ERROR: "error",
23
24
  DECLINED: "declined"
@@ -554,6 +555,7 @@ var DEFAULT_UI_STRINGS = {
554
555
  transcribing: "Transcribing\u2026",
555
556
  transcriptionFailed: "Transcription failed",
556
557
  toolRunning: "running\u2026",
558
+ toolDeferred: "waiting for you",
557
559
  toolDone: "\u2713 done",
558
560
  toolError: "\u26A0 error",
559
561
  toolDeclined: "\u2298 declined",
@@ -1007,6 +1009,12 @@ function relativeTime(timestamp, now = Date.now(), strings = DEFAULT_UI_STRINGS)
1007
1009
  }
1008
1010
 
1009
1011
  // src/ui/checkpoint_menu.ts
1012
+ function previewOf(run) {
1013
+ return run.preview !== void 0 && run.preview !== null && run.preview !== "" ? run.preview : null;
1014
+ }
1015
+ function asShown(preview) {
1016
+ return preview.replace(/\s+/g, " ").trim();
1017
+ }
1010
1018
  var CheckpointMenu = class {
1011
1019
  /** The panel root. Append to the chat shell; hidden until opened. */
1012
1020
  element;
@@ -1114,20 +1122,62 @@ var CheckpointMenu = class {
1114
1122
  this.#list.append(empty);
1115
1123
  return;
1116
1124
  }
1125
+ const repeated = this.#repeatedPreviews();
1126
+ for (const run of this.#runs) {
1127
+ this.#list.append(this.#row(run, repeated));
1128
+ }
1129
+ }
1130
+ /**
1131
+ * The previews more than one row shows.
1132
+ *
1133
+ * A preview identifies a run only while it is that run's alone. A real index
1134
+ * answered with five runs opening on the same sentence, and those rows read
1135
+ * alike exactly as bare timestamps used to — so where the words repeat the
1136
+ * short id comes back, and where they do not the row is left as it is.
1137
+ */
1138
+ #repeatedPreviews() {
1139
+ const seen = /* @__PURE__ */ new Set();
1140
+ const repeated = /* @__PURE__ */ new Set();
1117
1141
  for (const run of this.#runs) {
1118
- this.#list.append(this.#row(run));
1142
+ const preview = previewOf(run);
1143
+ if (preview === null) {
1144
+ continue;
1145
+ }
1146
+ const shown = asShown(preview);
1147
+ if (seen.has(shown)) {
1148
+ repeated.add(shown);
1149
+ }
1150
+ seen.add(shown);
1119
1151
  }
1152
+ return repeated;
1120
1153
  }
1121
- #row(run) {
1154
+ #row(run, repeated) {
1122
1155
  const row = document.createElement("div");
1123
1156
  row.className = "checkpoint-row";
1124
1157
  row.setAttribute("part", "checkpoint-row");
1158
+ const preview = previewOf(run);
1159
+ const time = run.started_at === null ? null : relativeTime(Date.parse(run.started_at), Date.now(), this.#strings);
1125
1160
  const label = document.createElement("span");
1126
1161
  label.className = "checkpoint-label";
1127
1162
  label.setAttribute("part", "checkpoint-label");
1128
- label.textContent = run.started_at === null ? run.run_id : relativeTime(Date.parse(run.started_at), Date.now(), this.#strings);
1129
- label.title = run.run_id;
1163
+ label.textContent = preview ?? time ?? run.run_id;
1130
1164
  row.append(label);
1165
+ if (preview !== null && time !== null) {
1166
+ const when = document.createElement("span");
1167
+ when.className = "checkpoint-time";
1168
+ when.setAttribute("part", "checkpoint-time");
1169
+ when.textContent = time;
1170
+ row.append(when);
1171
+ }
1172
+ const ambiguous = preview === null ? time !== null : repeated.has(asShown(preview));
1173
+ if (ambiguous && run.run_id !== "") {
1174
+ const short = document.createElement("span");
1175
+ short.className = "checkpoint-id";
1176
+ short.setAttribute("part", "checkpoint-id");
1177
+ short.textContent = run.run_id.slice(0, 8);
1178
+ short.title = run.run_id;
1179
+ row.append(short);
1180
+ }
1131
1181
  if (run.parent_run_id !== null) {
1132
1182
  const branch = document.createElement("span");
1133
1183
  branch.className = "checkpoint-branch";
@@ -5443,6 +5493,13 @@ var STYLES = `
5443
5493
  to { transform: rotate(360deg); }
5444
5494
  }
5445
5495
 
5496
+ /* Deferred: no spinner, because nothing is spinning. A steady accent dot, since
5497
+ the state is waiting-on-you rather than an outcome. */
5498
+ .tool-call[data-status="deferred"] .tool-call-icon {
5499
+ border-radius: 50%;
5500
+ background: var(--_accent);
5501
+ }
5502
+
5446
5503
  /* Settled: a themeable glyph coloured by outcome. */
5447
5504
  .tool-call[data-status="done"] .tool-call-icon::before {
5448
5505
  content: var(--_tool-icon-done);
@@ -5485,6 +5542,10 @@ var STYLES = `
5485
5542
  color: var(--_muted);
5486
5543
  }
5487
5544
 
5545
+ .tool-call[data-status="deferred"] .tool-call-status {
5546
+ color: var(--_accent);
5547
+ }
5548
+
5488
5549
  .tool-call[data-status="done"] .tool-call-status {
5489
5550
  color: var(--_success);
5490
5551
  }
@@ -5578,12 +5639,41 @@ var STYLES = `
5578
5639
 
5579
5640
  /* A pending card has no result yet, and in the modes where the arguments are
5580
5641
  hidden too there is nothing behind the toggle. Hide the control rather than
5581
- offer one that expands onto nothing. */
5642
+ offer one that expands onto nothing. A deferred card is the same, and its
5643
+ arguments are shown unconditionally by the rules below. */
5582
5644
  .tool-call[data-status="pending"] .tool-call-toggle,
5645
+ .tool-call[data-status="deferred"] .tool-call-toggle,
5583
5646
  :host([data-tool-display="inline"]) .tool-call[data-status="pending"] .tool-call-toggle {
5584
5647
  display: none;
5585
5648
  }
5586
5649
 
5650
+ /* The approval prompt for a gated call, rendered inside that call's own card.
5651
+ Empty on every card nobody is being asked about, so it collapses instead of
5652
+ adding a gap to each one. */
5653
+ .tool-call-approval:empty {
5654
+ display: none;
5655
+ }
5656
+
5657
+ .tool-call-approval {
5658
+ margin-top: 8px;
5659
+ }
5660
+
5661
+ /* A card that is asking a question shows what it is asking about, in every
5662
+ display mode. Three gated calls of one tool ask the same words, so the
5663
+ arguments are the only thing telling them apart, and a density setting must
5664
+ not be able to hide the answer to "which one is this". */
5665
+ :host([data-tool-display="minimal"]) .tool-call[data-status="deferred"] .tool-call-body {
5666
+ display: flex;
5667
+ }
5668
+
5669
+ /* The arguments region only, never every section: the result region carries the
5670
+ hidden attribute until a result exists, and a display value here overrides it,
5671
+ framing an empty RESULT heading under the question. */
5672
+ :host([data-tool-display="compact"]) .tool-call[data-status="deferred"] .tool-call-section--args,
5673
+ :host([data-tool-display="inline"]) .tool-call[data-status="deferred"] .tool-call-section--args {
5674
+ display: flex;
5675
+ }
5676
+
5587
5677
  .tool-call-toggle {
5588
5678
  align-self: flex-start;
5589
5679
  border: none;
@@ -5803,6 +5893,20 @@ var STYLES = `
5803
5893
  opacity: 0.6;
5804
5894
  }
5805
5895
 
5896
+ /* The same trap the attachment tray carries a note about, two rules along: an
5897
+ author display beats the UA stylesheet's rule for the hidden property, so a
5898
+ button the element has explicitly hidden keeps laying out and painting. The
5899
+ clip is hidden until a host supplies an upload handler or an attachments URL,
5900
+ and without this it is a visible control that cannot do anything.
5901
+
5902
+ The mic needs no such rule, and the asymmetry is worth knowing before adding
5903
+ one: it is not hidden when unconfigured, it is never built. The voice wiring
5904
+ returns before constructing the button, leaving only an empty voice slot that
5905
+ is display: contents. A hidden-state rule for the mic would match nothing. */
5906
+ .attach-btn[hidden] {
5907
+ display: none;
5908
+ }
5909
+
5806
5910
  /* Send closes the row on the right: a circle, the only filled control in the
5807
5911
  composer, so "the thing that acts" reads at a glance. */
5808
5912
  .send {
@@ -6412,47 +6516,118 @@ var STYLES = `
6412
6516
  opacity: 0.7;
6413
6517
  }
6414
6518
 
6519
+ /* A row is a label and two buttons, and nothing about the row itself is
6520
+ pressable. It used to light up on hover, which is the affordance of something
6521
+ clickable and made the buttons look like decoration on a clickable strip. The
6522
+ resting surface groups the row instead, so hover can mean what it says: only
6523
+ the buttons respond to it.
6524
+
6525
+ It wraps for the same reason the tool-call head does. Every child but the label
6526
+ is fixed-width, so in a narrow panel the label is the only thing that can give
6527
+ -- and a flex-basis of zero lets it give everything. Adding the run id was
6528
+ enough to crush "just now" to zero pixels: present, correct, and invisible.
6529
+ Wrapping puts the buttons on their own line instead. */
6415
6530
  .checkpoint-row {
6416
6531
  display: flex;
6532
+ flex-wrap: wrap;
6417
6533
  align-items: center;
6418
6534
  gap: 0.5rem;
6419
- padding: 0.25rem;
6535
+ padding: 0.3125rem 0.4375rem;
6420
6536
  border-radius: 0.375rem;
6421
- }
6422
-
6423
- .checkpoint-row:hover {
6424
6537
  background: var(--_hover);
6425
6538
  }
6426
6539
 
6540
+ /* Grows into spare room, and refuses to shrink past the shortest thing it ever
6541
+ says. A time is short and bounded, so there is no case for eliding it. */
6427
6542
  .checkpoint-label {
6428
- flex: 1;
6543
+ flex: 1 1 auto;
6544
+ min-width: 7ch;
6429
6545
  font-size: 0.8125rem;
6430
6546
  white-space: nowrap;
6431
6547
  overflow: hidden;
6432
6548
  text-overflow: ellipsis;
6433
6549
  }
6434
6550
 
6551
+ /* When the label holds the run's first message, the time moves here: still worth
6552
+ showing, no longer what identifies the row. Muted and unshrinkable, so it does
6553
+ not compete with the words beside it. */
6554
+ .checkpoint-time {
6555
+ flex: 0 0 auto;
6556
+ font-size: 0.6875rem;
6557
+ opacity: 0.7;
6558
+ white-space: nowrap;
6559
+ }
6560
+
6561
+ /* Enough of the run id to tell two runs apart when both say "just now". Muted
6562
+ and monospaced: it is a reference, not a name. */
6563
+ .checkpoint-id {
6564
+ flex: 0 0 auto;
6565
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
6566
+ font-size: 0.6875rem;
6567
+ opacity: 0.55;
6568
+ }
6569
+
6570
+ /* On the panel's own surface, not the row's: the row now paints the hover token
6571
+ itself, and a badge the same colour as what it sits on is not a badge. */
6435
6572
  .checkpoint-branch {
6436
6573
  font-size: 0.6875rem;
6437
6574
  padding: 0 0.375rem;
6438
6575
  border-radius: 999px;
6439
- background: var(--_hover);
6576
+ background: var(--_assistant-bg);
6440
6577
  opacity: 0.8;
6441
6578
  }
6442
6579
 
6580
+ /* The two things in the row that actually do something, so they are the two
6581
+ things that look like it: a filled surface at rest rather than a transparent
6582
+ outline, which on top of the old row highlight was nearly invisible. */
6443
6583
  .checkpoint-action {
6444
6584
  font: inherit;
6445
6585
  font-size: 0.75rem;
6586
+ line-height: 1.4;
6446
6587
  cursor: pointer;
6447
- padding: 0.125rem 0.5rem;
6588
+ padding: 0.1875rem 0.5625rem;
6448
6589
  border: 1px solid var(--_border);
6449
6590
  border-radius: 0.375rem;
6450
- background: transparent;
6591
+ background: var(--_bg);
6451
6592
  color: inherit;
6593
+ transition:
6594
+ background var(--_motion) var(--_ease),
6595
+ border-color var(--_motion) var(--_ease),
6596
+ transform var(--_motion) var(--_ease);
6597
+ }
6598
+
6599
+ /* Resume is what a reader wants nine times in ten; fork is the deliberate choice
6600
+ beside it. Filled and outlined, the same pair the confirmation and approval
6601
+ cards already use for their primary and secondary action. */
6602
+ .checkpoint-resume {
6603
+ font-weight: 600;
6604
+ border-color: var(--_accent);
6605
+ background: var(--_accent);
6606
+ color: #ffffff;
6452
6607
  }
6453
6608
 
6454
- .checkpoint-action:hover {
6609
+ .checkpoint-fork:hover {
6455
6610
  background: var(--_hover);
6611
+ border-color: var(--_accent);
6612
+ }
6613
+
6614
+ /* The filled one cannot go lighter on hover without losing its contrast with the
6615
+ white label, so it dims instead. */
6616
+ .checkpoint-resume:hover {
6617
+ opacity: 0.88;
6618
+ }
6619
+
6620
+ /* Pressed: a pixel down, so the click is felt as well as seen. */
6621
+ .checkpoint-action:active {
6622
+ transform: translateY(1px);
6623
+ }
6624
+
6625
+ /* Keyboard focus was invisible here, in a panel that traps focus and is reached
6626
+ by Tab -- so the one navigation path guaranteed to land on these buttons was
6627
+ the one with nothing to show for it. */
6628
+ .checkpoint-action:focus-visible {
6629
+ outline: 2px solid var(--_accent);
6630
+ outline-offset: 2px;
6456
6631
  }
6457
6632
 
6458
6633
  .drawer-backdrop {
@@ -6949,6 +7124,7 @@ var ThreadDrawer = class {
6949
7124
  function statusLabels(strings) {
6950
7125
  return {
6951
7126
  [TOOL_CALL_STATUS.PENDING]: strings.toolRunning,
7127
+ [TOOL_CALL_STATUS.DEFERRED]: strings.toolDeferred,
6952
7128
  [TOOL_CALL_STATUS.DONE]: strings.toolDone,
6953
7129
  [TOOL_CALL_STATUS.ERROR]: strings.toolError,
6954
7130
  [TOOL_CALL_STATUS.DECLINED]: strings.toolDeclined
@@ -6971,6 +7147,20 @@ function formatPayload(text2) {
6971
7147
  var ToolCallCard = class {
6972
7148
  /** The card's root element; append this into the message list. */
6973
7149
  element;
7150
+ /**
7151
+ * Where a question about *this* call renders — the approval prompt for a
7152
+ * server-side tool the run deferred.
7153
+ *
7154
+ * It belongs to the card rather than to the transcript because a run can defer
7155
+ * several calls at once, and a prompt written per *tool* ("Add this event to
7156
+ * the board?") is identical for every one of them. Rendered into the answer
7157
+ * group they were three anonymous copies of one question, below the three
7158
+ * cards they gated; rendered here, position identifies them and the arguments
7159
+ * are already on screen above the question.
7160
+ *
7161
+ * Empty until used, and hidden while empty by the shadow CSS.
7162
+ */
7163
+ approvalSlot;
6974
7164
  #status;
6975
7165
  #decision;
6976
7166
  #toggle;
@@ -7026,7 +7216,24 @@ var ToolCallCard = class {
7026
7216
  body.className = "tool-call-body";
7027
7217
  body.setAttribute("part", "tool-card-body");
7028
7218
  body.append(argsSection.root, resultSection.root);
7029
- this.element.append(head, this.#toggle, body);
7219
+ this.approvalSlot = document.createElement("div");
7220
+ this.approvalSlot.className = "tool-call-approval";
7221
+ this.approvalSlot.setAttribute("part", "tool-card-approval");
7222
+ this.element.append(head, this.#toggle, body, this.approvalSlot);
7223
+ }
7224
+ /**
7225
+ * Move between the two states that are not an outcome — `pending` (running)
7226
+ * and `deferred` (gated, waiting on a person).
7227
+ *
7228
+ * Ignored once {@link settle} has run: a card that was declined must not be
7229
+ * talked back into looking live by a late event.
7230
+ */
7231
+ mark(status) {
7232
+ if (this.#settled) {
7233
+ return;
7234
+ }
7235
+ this.element.setAttribute("data-status", status);
7236
+ this.#status.textContent = statusLabels(this.#strings)[status];
7030
7237
  }
7031
7238
  /**
7032
7239
  * Record that a human approved or declined this call, as a line in the card.
@@ -9227,6 +9434,7 @@ var AgUiChat = class extends HTMLElement {
9227
9434
  * {@link toggleCollapsed} and {@link toggleTheme}.
9228
9435
  */
9229
9436
  openThreads() {
9437
+ this.#checkpoints.close();
9230
9438
  void this.#refreshDrawer();
9231
9439
  this.#drawer.open();
9232
9440
  }
@@ -9238,9 +9446,27 @@ var AgUiChat = class extends HTMLElement {
9238
9446
  * an empty panel.
9239
9447
  */
9240
9448
  openCheckpoints() {
9449
+ this.#drawer.close();
9241
9450
  void this.#refreshCheckpoints();
9242
9451
  this.#checkpoints.open();
9243
9452
  }
9453
+ /** Close the checkpoints panel, if it is open. */
9454
+ closeCheckpoints() {
9455
+ this.#checkpoints.close();
9456
+ }
9457
+ /**
9458
+ * Open the checkpoints panel, or close it if it is already open — what the
9459
+ * built-in ⭯ button does, because a control that opens a panel is read as the
9460
+ * control that also dismisses it. {@link openCheckpoints} stays open-only for a
9461
+ * host that means exactly that.
9462
+ */
9463
+ toggleCheckpoints() {
9464
+ if (this.#checkpoints.open_) {
9465
+ this.#checkpoints.close();
9466
+ return;
9467
+ }
9468
+ this.openCheckpoints();
9469
+ }
9244
9470
  /**
9245
9471
  * Start a fresh conversation: forget the persisted history, drop the
9246
9472
  * in-memory run state, clear the transcript, and mint a new thread id.
@@ -9505,8 +9731,8 @@ var AgUiChat = class extends HTMLElement {
9505
9731
  controls.setAttribute("part", "header-controls");
9506
9732
  const history = this.#headerButton("history", this.#strings.chatHistory, "\u2630");
9507
9733
  history.addEventListener("click", () => this.openThreads());
9508
- const checkpoints = this.#headerButton("checkpoints", this.#strings.checkpoints, "\u2B6F");
9509
- checkpoints.addEventListener("click", () => this.openCheckpoints());
9734
+ const checkpoints = this.#headerButton("checkpoints", this.#strings.checkpoints, "\u21BA");
9735
+ checkpoints.addEventListener("click", () => this.toggleCheckpoints());
9510
9736
  const newChat = this.#headerButton("new", this.#strings.newChat, "\u271A");
9511
9737
  newChat.addEventListener("click", () => this.newChat());
9512
9738
  const collapse = this.#headerButton("collapse", this.#strings.collapse, "\u2014");
@@ -9607,6 +9833,16 @@ var AgUiChat = class extends HTMLElement {
9607
9833
  this.#drawer.element,
9608
9834
  this.#checkpoints.element
9609
9835
  );
9836
+ this.#chat.addEventListener("pointerdown", (event) => {
9837
+ if (!this.#checkpoints.open_) {
9838
+ return;
9839
+ }
9840
+ const path = event.composedPath();
9841
+ if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {
9842
+ return;
9843
+ }
9844
+ this.#checkpoints.close();
9845
+ });
9610
9846
  this.#launcher.className = "launcher";
9611
9847
  this.#launcher.type = "button";
9612
9848
  this.#launcher.setAttribute("part", "launcher");
@@ -10024,40 +10260,61 @@ var AgUiChat = class extends HTMLElement {
10024
10260
  * Render an approval card per server-side-tool interrupt and collect the
10025
10261
  * user's decisions (approve → run it, deny → decline it).
10026
10262
  *
10263
+ * **One card per gated call, in that call's own tool card, all at once.** A run
10264
+ * can defer several calls, and the wire answers each independently — so the UI
10265
+ * has to let a person answer each independently, which means saying which is
10266
+ * which. The prompt cannot: it comes from the tool's `x-confirm` and is
10267
+ * identical for every call of that tool. The tool card can, by position, and it
10268
+ * is already showing the arguments. Asking them serially was the other half of
10269
+ * the problem: the second question only appeared once the first was answered,
10270
+ * so a person could neither compare them nor tell that more were coming.
10271
+ *
10272
+ * Each gated card is marked `deferred` for the wait. That is not cosmetic — at
10273
+ * `pending` it read "running…" while the stream was over and the server idle.
10274
+ *
10027
10275
  * The run is suspended on these cards. A Stop while any is open aborts the
10028
10276
  * shared {@link #confirmAbort} controller, resolving every still-open card as
10029
10277
  * denied. An approved tool runs on the follow-up resume run and streams its
10030
- * result into the same pending card; a denied one settles here, since no
10031
- * result will ever arrive.
10278
+ * result into the same card (returned to `pending`, since it now really is
10279
+ * running); a denied one settles here, as no result will ever arrive.
10032
10280
  */
10033
10281
  async #resolveInterrupts(interrupts) {
10034
- const responses = {};
10035
10282
  this.#confirmAbort = new AbortController();
10036
10283
  this.#hidePending();
10037
- for (const interrupt of interrupts) {
10038
- const request = {};
10039
- const phrase = confirmPhrase(interrupt) ?? interrupt.message;
10040
- if (phrase !== void 0) {
10041
- request.message = phrase;
10042
- }
10043
- const card = interrupt.toolCallId !== void 0 ? this.#toolCards.get(interrupt.toolCallId) : void 0;
10044
- const toolName = card?.element.getAttribute("data-tool-name");
10045
- if (toolName !== null && toolName !== void 0) {
10046
- request.toolName = toolName;
10047
- }
10048
- const signal = this.#confirmAbort.signal;
10049
- const approved = this.approvalRenderer !== null ? await this.approvalRenderer(request, { signal }) : await requestApproval(this.#ensureGroup(), request, { signal, strings: this.#strings });
10050
- this.#updateEmptyState();
10051
- this.#messages.scrollTop = this.#messages.scrollHeight;
10052
- card?.recordDecision(approved ? "approved" : "declined");
10053
- if (approved) {
10054
- responses[interrupt.id] = { status: "resolved", payload: { approved: true } };
10055
- } else {
10056
- responses[interrupt.id] = { status: "cancelled" };
10057
- card?.settle(TOOL_CALL_STATUS.DECLINED, this.#strings.declinedAction);
10058
- }
10059
- }
10284
+ const signal = this.#confirmAbort.signal;
10285
+ const answered = await Promise.all(
10286
+ interrupts.map(async (interrupt) => {
10287
+ const card = interrupt.toolCallId !== void 0 ? this.#toolCards.get(interrupt.toolCallId) : void 0;
10288
+ const request = {};
10289
+ const phrase = confirmPhrase(interrupt) ?? interrupt.message;
10290
+ if (phrase !== void 0) {
10291
+ request.message = phrase;
10292
+ }
10293
+ const toolName = card?.element.getAttribute("data-tool-name");
10294
+ if (toolName !== null && toolName !== void 0) {
10295
+ request.toolName = toolName;
10296
+ }
10297
+ card?.mark(TOOL_CALL_STATUS.DEFERRED);
10298
+ const approved = this.approvalRenderer !== null ? await this.approvalRenderer(request, { signal }) : await requestApproval(card?.approvalSlot ?? this.#ensureGroup(), request, {
10299
+ signal,
10300
+ strings: this.#strings
10301
+ });
10302
+ card?.recordDecision(approved ? "approved" : "declined");
10303
+ if (approved) {
10304
+ card?.mark(TOOL_CALL_STATUS.PENDING);
10305
+ } else {
10306
+ card?.settle(TOOL_CALL_STATUS.DECLINED, this.#strings.declinedAction);
10307
+ }
10308
+ return { id: interrupt.id, approved };
10309
+ })
10310
+ );
10311
+ this.#updateEmptyState();
10312
+ this.#messages.scrollTop = this.#messages.scrollHeight;
10060
10313
  this.#confirmAbort = null;
10314
+ const responses = {};
10315
+ for (const { id, approved } of answered) {
10316
+ responses[id] = approved ? { status: "resolved", payload: { approved: true } } : { status: "cancelled" };
10317
+ }
10061
10318
  return responses;
10062
10319
  }
10063
10320
  #handlers() {
@@ -10354,7 +10611,7 @@ function setControlValue(el, value) {
10354
10611
  }
10355
10612
 
10356
10613
  // src/version.ts
10357
- var VERSION = "0.24.0";
10614
+ var VERSION = "0.25.1";
10358
10615
  export {
10359
10616
  ATTACHMENT_EVENT,
10360
10617
  AgUiChat,