@jait/gateway 0.1.488 → 0.1.489

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.
Files changed (74) hide show
  1. package/dist/providers/acp-provider.d.ts +8 -0
  2. package/dist/providers/acp-provider.d.ts.map +1 -1
  3. package/dist/providers/acp-provider.js +88 -17
  4. package/dist/providers/acp-provider.js.map +1 -1
  5. package/dist/providers/model-fetchers.d.ts +7 -1
  6. package/dist/providers/model-fetchers.d.ts.map +1 -1
  7. package/dist/providers/model-fetchers.js +66 -7
  8. package/dist/providers/model-fetchers.js.map +1 -1
  9. package/dist/providers/provider-snapshot.d.ts +41 -0
  10. package/dist/providers/provider-snapshot.d.ts.map +1 -0
  11. package/dist/providers/provider-snapshot.js +77 -0
  12. package/dist/providers/provider-snapshot.js.map +1 -0
  13. package/dist/routes/chat.d.ts.map +1 -1
  14. package/dist/routes/chat.js +32 -11
  15. package/dist/routes/chat.js.map +1 -1
  16. package/dist/routes/providers.d.ts.map +1 -1
  17. package/dist/routes/providers.js +43 -48
  18. package/dist/routes/providers.js.map +1 -1
  19. package/package.json +1 -1
  20. package/web-dist/assets/{_basePickBy-Bs2Q2Eng.js → _basePickBy-BX6EP2I2.js} +1 -1
  21. package/web-dist/assets/{_baseUniq-C1Vgvc6k.js → _baseUniq-mde02Yrj.js} +1 -1
  22. package/web-dist/assets/{arc-B45ZD8Nx.js → arc-D-s0zwBW.js} +1 -1
  23. package/web-dist/assets/{architectureDiagram-2XIMDMQ5-Dgn58dd_.js → architectureDiagram-2XIMDMQ5-D9kwN21P.js} +1 -1
  24. package/web-dist/assets/{blockDiagram-WCTKOSBZ-DVo2YOE_.js → blockDiagram-WCTKOSBZ-QE3gI6Gw.js} +1 -1
  25. package/web-dist/assets/{c4Diagram-IC4MRINW-DGFSFQ71.js → c4Diagram-IC4MRINW-B6O4bYxU.js} +1 -1
  26. package/web-dist/assets/channel-DA3uJbj2.js +1 -0
  27. package/web-dist/assets/{chunk-4BX2VUAB-BH1NL3uc.js → chunk-4BX2VUAB-C2EGdmHK.js} +1 -1
  28. package/web-dist/assets/{chunk-55IACEB6-DXuyCFwp.js → chunk-55IACEB6-CqpQQ57q.js} +1 -1
  29. package/web-dist/assets/{chunk-FMBD7UC4-krCQHjSO.js → chunk-FMBD7UC4-BbF87I0X.js} +1 -1
  30. package/web-dist/assets/{chunk-JSJVCQXG-Db70Tfzs.js → chunk-JSJVCQXG-qh31y2A6.js} +1 -1
  31. package/web-dist/assets/{chunk-KX2RTZJC-ClwrCaPu.js → chunk-KX2RTZJC-DPNGQvtq.js} +1 -1
  32. package/web-dist/assets/{chunk-NQ4KR5QH-BgYsa0ay.js → chunk-NQ4KR5QH-Bbmtom-E.js} +1 -1
  33. package/web-dist/assets/{chunk-QZHKN3VN-DcrIkFKB.js → chunk-QZHKN3VN-CirvJD40.js} +1 -1
  34. package/web-dist/assets/{chunk-WL4C6EOR-BTf7iLVE.js → chunk-WL4C6EOR-ug4T_FDt.js} +1 -1
  35. package/web-dist/assets/classDiagram-VBA2DB6C-VslpWLk8.js +1 -0
  36. package/web-dist/assets/classDiagram-v2-RAHNMMFH-VslpWLk8.js +1 -0
  37. package/web-dist/assets/clone-CNzXP32l.js +1 -0
  38. package/web-dist/assets/{cose-bilkent-S5V4N54A-CTYlJ5P2.js → cose-bilkent-S5V4N54A-DmjRuXhy.js} +1 -1
  39. package/web-dist/assets/{dagre-KLK3FWXG-DWI1FJLN.js → dagre-KLK3FWXG-CheF4qTK.js} +1 -1
  40. package/web-dist/assets/{diagram-E7M64L7V-BUK_Kgia.js → diagram-E7M64L7V-DVjDrANA.js} +1 -1
  41. package/web-dist/assets/{diagram-IFDJBPK2-NqEaUmP3.js → diagram-IFDJBPK2-Bj1X-Hn4.js} +1 -1
  42. package/web-dist/assets/{diagram-P4PSJMXO-5Ep5l2GM.js → diagram-P4PSJMXO-Bh-33PYh.js} +1 -1
  43. package/web-dist/assets/{erDiagram-INFDFZHY-G_uvZUyt.js → erDiagram-INFDFZHY-BNKXv7-6.js} +1 -1
  44. package/web-dist/assets/{flowDiagram-PKNHOUZH-Dpx9wgBT.js → flowDiagram-PKNHOUZH-CCPg-WXi.js} +1 -1
  45. package/web-dist/assets/{ganttDiagram-A5KZAMGK-C1wksGup.js → ganttDiagram-A5KZAMGK-LhKyVQzB.js} +1 -1
  46. package/web-dist/assets/{gitGraphDiagram-K3NZZRJ6-BMRbny8s.js → gitGraphDiagram-K3NZZRJ6-t8hXDx_a.js} +1 -1
  47. package/web-dist/assets/{graph-D813FHN0.js → graph-DvBWVaKS.js} +1 -1
  48. package/web-dist/assets/{index-B0WXmsg6.js → index-BgjuDfB9.js} +1 -1
  49. package/web-dist/assets/{index-Dz5PpkSn.js → index-Bp2fJNBP.js} +333 -333
  50. package/web-dist/assets/{index-BHV3c90o.js → index-nagUEWYt.js} +1 -1
  51. package/web-dist/assets/{infoDiagram-LFFYTUFH-CRhMjd3m.js → infoDiagram-LFFYTUFH-I9RVPa8I.js} +1 -1
  52. package/web-dist/assets/{ishikawaDiagram-PHBUUO56-C0b-DmJz.js → ishikawaDiagram-PHBUUO56--GCbyStJ.js} +1 -1
  53. package/web-dist/assets/{journeyDiagram-4ABVD52K-7GAYf7qC.js → journeyDiagram-4ABVD52K-D1zvA3NV.js} +1 -1
  54. package/web-dist/assets/{kanban-definition-K7BYSVSG-DYH6GLQ_.js → kanban-definition-K7BYSVSG-qe8UA4lg.js} +1 -1
  55. package/web-dist/assets/{layout-DflnUaC-.js → layout-QdHFlRmN.js} +1 -1
  56. package/web-dist/assets/{linear-BKaIWChA.js → linear-CdHDx9DZ.js} +1 -1
  57. package/web-dist/assets/{mindmap-definition-YRQLILUH-DLKYT7in.js → mindmap-definition-YRQLILUH-6zjREe01.js} +1 -1
  58. package/web-dist/assets/{pieDiagram-SKSYHLDU-1pCzkOws.js → pieDiagram-SKSYHLDU-CBD22E_n.js} +1 -1
  59. package/web-dist/assets/{quadrantDiagram-337W2JSQ-sQvtWhE5.js → quadrantDiagram-337W2JSQ-DvAVW3XJ.js} +1 -1
  60. package/web-dist/assets/{requirementDiagram-Z7DCOOCP-DjjWn7oo.js → requirementDiagram-Z7DCOOCP-CHQV7I6H.js} +1 -1
  61. package/web-dist/assets/{sankeyDiagram-WA2Y5GQK-BmubwmS7.js → sankeyDiagram-WA2Y5GQK-Bj--2VdZ.js} +1 -1
  62. package/web-dist/assets/{sequenceDiagram-2WXFIKYE-827kzmaQ.js → sequenceDiagram-2WXFIKYE-_3F4rir3.js} +1 -1
  63. package/web-dist/assets/{stateDiagram-RAJIS63D-CVnU2rvz.js → stateDiagram-RAJIS63D-Db2kqDG6.js} +1 -1
  64. package/web-dist/assets/stateDiagram-v2-FVOUBMTO-CeIOaA92.js +1 -0
  65. package/web-dist/assets/{timeline-definition-YZTLITO2-8QfPnNpk.js → timeline-definition-YZTLITO2-DxjOEtgz.js} +1 -1
  66. package/web-dist/assets/{treemap-KZPCXAKY-D6AwuGcm.js → treemap-KZPCXAKY-DV13XNxx.js} +1 -1
  67. package/web-dist/assets/{vennDiagram-LZ73GAT5-Bjye7yJQ.js → vennDiagram-LZ73GAT5-D0eGtRUN.js} +1 -1
  68. package/web-dist/assets/{xychartDiagram-JWTSCODW-NBNTRnip.js → xychartDiagram-JWTSCODW-DZSDugcS.js} +1 -1
  69. package/web-dist/index.html +1 -1
  70. package/web-dist/assets/channel-Ct_ZzeFZ.js +0 -1
  71. package/web-dist/assets/classDiagram-VBA2DB6C-BA-sk9nf.js +0 -1
  72. package/web-dist/assets/classDiagram-v2-RAHNMMFH-BA-sk9nf.js +0 -1
  73. package/web-dist/assets/clone-SN4ZG9tU.js +0 -1
  74. package/web-dist/assets/stateDiagram-v2-FVOUBMTO-DhiBeXYZ.js +0 -1
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Provider snapshot cache.
3
+ *
4
+ * Computing a provider's availability + auth status is expensive: it spawns the
5
+ * provider CLI (and, for ACP providers, runs a full agent handshake). Doing that
6
+ * inline on every `GET /api/providers` froze the initial page load while ~7
7
+ * providers were probed.
8
+ *
9
+ * This cache computes the snapshot once, serves it immediately, and refreshes in
10
+ * the background (stale-while-revalidate). Warm it at startup so the first page
11
+ * load never pays the probe cost.
12
+ */
13
+ import type { ProviderRegistry } from "./registry.js";
14
+ import type { ProviderAuthInfo, RuntimeMode } from "./contracts.js";
15
+ export interface ProviderSnapshot {
16
+ id: string;
17
+ name: string;
18
+ description: string;
19
+ available: boolean;
20
+ unavailableReason?: string;
21
+ modes: RuntimeMode[];
22
+ auth?: ProviderAuthInfo;
23
+ }
24
+ export declare class ProviderSnapshotCache {
25
+ private readonly registry;
26
+ private snapshot;
27
+ private computedAt;
28
+ private inflight;
29
+ constructor(registry: ProviderRegistry);
30
+ /**
31
+ * Return the current snapshot. Serves cached data immediately when available;
32
+ * refreshes in the background when stale. Only blocks on a cold cache (or when
33
+ * `force` is set, e.g. an explicit user-triggered refresh).
34
+ */
35
+ get(force?: boolean): Promise<ProviderSnapshot[]>;
36
+ /** Kick a background refresh without awaiting it (used to warm at startup). */
37
+ warm(): void;
38
+ private refresh;
39
+ private compute;
40
+ }
41
+ //# sourceMappingURL=provider-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-snapshot.d.ts","sourceRoot":"","sources":["../../src/providers/provider-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAKD,qBAAa,qBAAqB;IAKpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAA4C;gBAE/B,QAAQ,EAAE,gBAAgB;IAEvD;;;;OAIG;IACG,GAAG,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAerD,+EAA+E;IAC/E,IAAI,IAAI,IAAI;IAIZ,OAAO,CAAC,OAAO;YAcD,OAAO;CAsBtB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Provider snapshot cache.
3
+ *
4
+ * Computing a provider's availability + auth status is expensive: it spawns the
5
+ * provider CLI (and, for ACP providers, runs a full agent handshake). Doing that
6
+ * inline on every `GET /api/providers` froze the initial page load while ~7
7
+ * providers were probed.
8
+ *
9
+ * This cache computes the snapshot once, serves it immediately, and refreshes in
10
+ * the background (stale-while-revalidate). Warm it at startup so the first page
11
+ * load never pays the probe cost.
12
+ */
13
+ /** How long a computed snapshot stays fresh before a background refresh. */
14
+ const SNAPSHOT_TTL_MS = 60_000;
15
+ export class ProviderSnapshotCache {
16
+ registry;
17
+ snapshot = null;
18
+ computedAt = 0;
19
+ inflight = null;
20
+ constructor(registry) {
21
+ this.registry = registry;
22
+ }
23
+ /**
24
+ * Return the current snapshot. Serves cached data immediately when available;
25
+ * refreshes in the background when stale. Only blocks on a cold cache (or when
26
+ * `force` is set, e.g. an explicit user-triggered refresh).
27
+ */
28
+ async get(force = false) {
29
+ const fresh = this.snapshot && Date.now() - this.computedAt < SNAPSHOT_TTL_MS;
30
+ if (!force && fresh)
31
+ return this.snapshot;
32
+ // Stale but present: kick a background refresh, return what we have now.
33
+ if (!force && this.snapshot) {
34
+ void this.refresh().catch(() => { });
35
+ return this.snapshot;
36
+ }
37
+ // Cold cache or forced refresh: must wait for a computation.
38
+ return this.refresh();
39
+ }
40
+ /** Kick a background refresh without awaiting it (used to warm at startup). */
41
+ warm() {
42
+ void this.refresh().catch(() => { });
43
+ }
44
+ refresh() {
45
+ if (this.inflight)
46
+ return this.inflight;
47
+ this.inflight = this.compute()
48
+ .then((snap) => {
49
+ this.snapshot = snap;
50
+ this.computedAt = Date.now();
51
+ return snap;
52
+ })
53
+ .finally(() => {
54
+ this.inflight = null;
55
+ });
56
+ return this.inflight;
57
+ }
58
+ async compute() {
59
+ const providers = this.registry.list();
60
+ return Promise.all(providers.map(async (p) => {
61
+ await p.checkAvailability().catch(() => false);
62
+ const auth = await p.getAuthStatus?.().catch(() => p.info.auth
63
+ ? { ...p.info.auth, authenticated: null, detail: "Failed to check provider auth status." }
64
+ : undefined);
65
+ return {
66
+ id: p.id,
67
+ name: p.info.name,
68
+ description: p.info.description,
69
+ available: p.info.available,
70
+ unavailableReason: p.info.unavailableReason,
71
+ modes: p.info.modes,
72
+ auth: auth ?? p.info.auth,
73
+ };
74
+ }));
75
+ }
76
+ }
77
+ //# sourceMappingURL=provider-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-snapshot.js","sourceRoot":"","sources":["../../src/providers/provider-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,4EAA4E;AAC5E,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,OAAO,qBAAqB;IAKH;IAJrB,QAAQ,GAA8B,IAAI,CAAC;IAC3C,UAAU,GAAG,CAAC,CAAC;IACf,QAAQ,GAAuC,IAAI,CAAC;IAE5D,YAA6B,QAA0B;QAA1B,aAAQ,GAAR,QAAQ,CAAkB;IAAG,CAAC;IAE3D;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC;QAE9E,IAAI,CAAC,KAAK,IAAI,KAAK;YAAE,OAAO,IAAI,CAAC,QAAS,CAAC;QAE3C,yEAAyE;QACzE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED,6DAA6D;QAC7D,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,+EAA+E;IAC/E,IAAI;QACF,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,CAAC;IAEO,OAAO;QACb,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE;aAC3B,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,GAAG,CAChB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACxB,MAAM,CAAC,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAChD,CAAC,CAAC,IAAI,CAAC,IAAI;gBACT,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,uCAAuC,EAAE;gBAC1F,CAAC,CAAC,SAAS,CACd,CAAC;YACF,OAAO;gBACL,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;gBACjB,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW;gBAC/B,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS;gBAC3B,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB;gBAC3C,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK;gBACnB,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI;aAC1B,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAA4B,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAe,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgCjE,OAAO,KAAK,EAAS,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAgGvF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBrE;AAyED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3D;AAyUD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyCtF;AAiZD,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,EAAE,CAAC,EAAE,cAAc,CAAC;IACpB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAClD,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,KACtD,OAAO,CAAC,UAAU,CAAC,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,SAAS,EACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EACjC,iBAAiB,CAAC,EAAE,cAAc,QAq5DnC"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAA4B,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAe,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgCjE,OAAO,KAAK,EAAS,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAgGvF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBrE;AAyED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3D;AAyUD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyCtF;AA0ZD,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,EAAE,CAAC,EAAE,cAAc,CAAC;IACpB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAClD,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,KACtD,OAAO,CAAC,UAAU,CAAC,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,SAAS,EACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EACjC,iBAAiB,CAAC,EAAE,cAAc,QA85DnC"}
@@ -439,6 +439,16 @@ function accumulateThinking(sessionId, content) {
439
439
  /** Record a tool call start in the streaming accumulator */
440
440
  function accumulateToolStart(sessionId, callId, tool, args, parentCallId) {
441
441
  const acc = getOrCreateAccumulator(sessionId);
442
+ // ACP agents can re-emit an enriched tool.start for the same callId
443
+ // (progressive tool_call_update). Upgrade in place rather than duplicating.
444
+ const existing = acc.toolCalls.find(t => t.callId === callId);
445
+ if (existing) {
446
+ existing.tool = tool;
447
+ existing.args = args;
448
+ if (parentCallId !== undefined)
449
+ existing.parentCallId = parentCallId;
450
+ return;
451
+ }
442
452
  acc.toolCalls.push({ callId, parentCallId, tool, args, ok: true, message: "", startedAt: Date.now() });
443
453
  const last = acc.segments[acc.segments.length - 1];
444
454
  if (last?.type === "toolGroup") {
@@ -1458,17 +1468,28 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
1458
1468
  // tokens were streamed for it.
1459
1469
  tokenBytesThisBlock = 0;
1460
1470
  const callId = event.callId ?? `cli-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1461
- // Accumulate for persistence
1462
- cliToolCalls.push({
1463
- callId,
1464
- parentCallId: event.parentCallId,
1465
- tool: event.tool,
1466
- args: event.args ?? {},
1467
- ok: true,
1468
- message: "",
1469
- startedAt: Date.now(),
1470
- });
1471
- pendingToolGroup.push(callId);
1471
+ // Accumulate for persistence. ACP agents may re-emit an enriched
1472
+ // tool.start for the same callId (progressive tool_call_update),
1473
+ // so upgrade the existing entry in place instead of duplicating.
1474
+ const existingCliCall = cliToolCalls.find(t => t.callId === callId);
1475
+ if (existingCliCall) {
1476
+ existingCliCall.tool = event.tool;
1477
+ existingCliCall.args = event.args ?? {};
1478
+ if (event.parentCallId !== undefined)
1479
+ existingCliCall.parentCallId = event.parentCallId;
1480
+ }
1481
+ else {
1482
+ cliToolCalls.push({
1483
+ callId,
1484
+ parentCallId: event.parentCallId,
1485
+ tool: event.tool,
1486
+ args: event.args ?? {},
1487
+ ok: true,
1488
+ message: "",
1489
+ startedAt: Date.now(),
1490
+ });
1491
+ pendingToolGroup.push(callId);
1492
+ }
1472
1493
  // Save backup of the original file before external providers mutate it.
1473
1494
  const mutationPath = getExternalFileMutationPath(event.tool, event.args);
1474
1495
  if (mutationPath && cliFsSurface) {