@jait/gateway 0.1.556 → 0.1.558

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 (59) hide show
  1. package/dist/routes/chat.d.ts.map +1 -1
  2. package/dist/routes/chat.js +29 -38
  3. package/dist/routes/chat.js.map +1 -1
  4. package/package.json +1 -1
  5. package/web-dist/assets/{_basePickBy-DvI7dW8V.js → _basePickBy-CPxkGcfx.js} +1 -1
  6. package/web-dist/assets/{_baseUniq-1ihWHc9y.js → _baseUniq-DlsLfA2q.js} +1 -1
  7. package/web-dist/assets/{arc-kvIsHe11.js → arc-DEEWVHn7.js} +1 -1
  8. package/web-dist/assets/{architectureDiagram-2XIMDMQ5-CSCYhmPn.js → architectureDiagram-2XIMDMQ5-Dg5exBgn.js} +1 -1
  9. package/web-dist/assets/{blockDiagram-WCTKOSBZ-R_Y3-6lR.js → blockDiagram-WCTKOSBZ-D7_Vjqrc.js} +1 -1
  10. package/web-dist/assets/{c4Diagram-IC4MRINW-556ThiPx.js → c4Diagram-IC4MRINW-YXdjtBH8.js} +1 -1
  11. package/web-dist/assets/channel-Bsq3vM_f.js +1 -0
  12. package/web-dist/assets/{chunk-4BX2VUAB-BvXfLkWT.js → chunk-4BX2VUAB-kL1tn03O.js} +1 -1
  13. package/web-dist/assets/{chunk-55IACEB6-DieOGDSZ.js → chunk-55IACEB6-B1Psg-bR.js} +1 -1
  14. package/web-dist/assets/{chunk-FMBD7UC4-CL7tnOm_.js → chunk-FMBD7UC4-BFpLoLDq.js} +1 -1
  15. package/web-dist/assets/{chunk-JSJVCQXG-CFpbZu21.js → chunk-JSJVCQXG-Cj7ewOu5.js} +1 -1
  16. package/web-dist/assets/{chunk-KX2RTZJC-BZeqeuDy.js → chunk-KX2RTZJC-g2oSJsej.js} +1 -1
  17. package/web-dist/assets/{chunk-NQ4KR5QH-BviS_Rvb.js → chunk-NQ4KR5QH-BR3_04TS.js} +1 -1
  18. package/web-dist/assets/{chunk-QZHKN3VN-BoO08RGh.js → chunk-QZHKN3VN-0B_RY7EM.js} +1 -1
  19. package/web-dist/assets/{chunk-WL4C6EOR-BkGVNP8A.js → chunk-WL4C6EOR-DQK7z8KQ.js} +1 -1
  20. package/web-dist/assets/classDiagram-VBA2DB6C-BRBfPNfV.js +1 -0
  21. package/web-dist/assets/classDiagram-v2-RAHNMMFH-BRBfPNfV.js +1 -0
  22. package/web-dist/assets/clone-Bed7-vZ7.js +1 -0
  23. package/web-dist/assets/{cose-bilkent-S5V4N54A-aV1nXScq.js → cose-bilkent-S5V4N54A-BbDuOYRk.js} +1 -1
  24. package/web-dist/assets/{dagre-KLK3FWXG-u2jAD-hh.js → dagre-KLK3FWXG-BXvN8okK.js} +1 -1
  25. package/web-dist/assets/{diagram-E7M64L7V-DbEZsnzR.js → diagram-E7M64L7V-Df7unAQ1.js} +1 -1
  26. package/web-dist/assets/{diagram-IFDJBPK2-p34ED3DN.js → diagram-IFDJBPK2-C2Po9pyC.js} +1 -1
  27. package/web-dist/assets/{diagram-P4PSJMXO-DKLijNZg.js → diagram-P4PSJMXO-DvQN3f8Z.js} +1 -1
  28. package/web-dist/assets/{erDiagram-INFDFZHY-Cwq9W4G8.js → erDiagram-INFDFZHY-VtRHYObW.js} +1 -1
  29. package/web-dist/assets/{flowDiagram-PKNHOUZH-BbuWTEov.js → flowDiagram-PKNHOUZH-Cj4GGoOw.js} +1 -1
  30. package/web-dist/assets/{ganttDiagram-A5KZAMGK-CCX00m3B.js → ganttDiagram-A5KZAMGK-jIaBihBF.js} +1 -1
  31. package/web-dist/assets/{gitGraphDiagram-K3NZZRJ6-DJiy0306.js → gitGraphDiagram-K3NZZRJ6-DmdsAaO9.js} +1 -1
  32. package/web-dist/assets/{graph-DZb4ZtmZ.js → graph-DbZQYKkz.js} +1 -1
  33. package/web-dist/assets/{index-DwLI2BcF.js → index-CKuVMlil.js} +380 -375
  34. package/web-dist/assets/{index-CU-7VgCj.js → index-DJvw5WYl.js} +1 -1
  35. package/web-dist/assets/{index-Is4s4-P0.js → index-DbIZym32.js} +1 -1
  36. package/web-dist/assets/{infoDiagram-LFFYTUFH-BCHKrdng.js → infoDiagram-LFFYTUFH-XF_gfbhJ.js} +1 -1
  37. package/web-dist/assets/{ishikawaDiagram-PHBUUO56-ceGcqRw4.js → ishikawaDiagram-PHBUUO56-B4SATgkI.js} +1 -1
  38. package/web-dist/assets/{journeyDiagram-4ABVD52K-DILZrTC2.js → journeyDiagram-4ABVD52K-B5vY971k.js} +1 -1
  39. package/web-dist/assets/{kanban-definition-K7BYSVSG-Ce_c4wVl.js → kanban-definition-K7BYSVSG-DGErlxyh.js} +1 -1
  40. package/web-dist/assets/{layout-BhCmU-BF.js → layout-D1bk0Ryk.js} +1 -1
  41. package/web-dist/assets/{linear-Du9uBf61.js → linear--a0P8qHz.js} +1 -1
  42. package/web-dist/assets/{mindmap-definition-YRQLILUH-B8irtriU.js → mindmap-definition-YRQLILUH-DRjoXxOn.js} +1 -1
  43. package/web-dist/assets/{pieDiagram-SKSYHLDU-DRYarfMw.js → pieDiagram-SKSYHLDU-DH3R0SfR.js} +1 -1
  44. package/web-dist/assets/{quadrantDiagram-337W2JSQ-CWa9hYgm.js → quadrantDiagram-337W2JSQ-BuHU7B2h.js} +1 -1
  45. package/web-dist/assets/{requirementDiagram-Z7DCOOCP-Dr0Dh1G9.js → requirementDiagram-Z7DCOOCP-cjCWIIPZ.js} +1 -1
  46. package/web-dist/assets/{sankeyDiagram-WA2Y5GQK-CSIlj_5q.js → sankeyDiagram-WA2Y5GQK-DnaQxv8x.js} +1 -1
  47. package/web-dist/assets/{sequenceDiagram-2WXFIKYE-cvPrF5kh.js → sequenceDiagram-2WXFIKYE-tun211wW.js} +1 -1
  48. package/web-dist/assets/{stateDiagram-RAJIS63D-CcMtQOjg.js → stateDiagram-RAJIS63D-CUSdI0DO.js} +1 -1
  49. package/web-dist/assets/stateDiagram-v2-FVOUBMTO-0VaC5q-n.js +1 -0
  50. package/web-dist/assets/{timeline-definition-YZTLITO2-C6w5hhZ1.js → timeline-definition-YZTLITO2-CHAYZZNZ.js} +1 -1
  51. package/web-dist/assets/{treemap-KZPCXAKY-CcM8WExl.js → treemap-KZPCXAKY-SxAdfbRQ.js} +1 -1
  52. package/web-dist/assets/{vennDiagram-LZ73GAT5-CGlE-r2b.js → vennDiagram-LZ73GAT5-CFZRfOLg.js} +1 -1
  53. package/web-dist/assets/{xychartDiagram-JWTSCODW-DUFote5V.js → xychartDiagram-JWTSCODW-KPYWAEr4.js} +1 -1
  54. package/web-dist/index.html +1 -1
  55. package/web-dist/assets/channel-B_F9voP2.js +0 -1
  56. package/web-dist/assets/classDiagram-VBA2DB6C-DSXp3uOM.js +0 -1
  57. package/web-dist/assets/classDiagram-v2-RAHNMMFH-DSXp3uOM.js +0 -1
  58. package/web-dist/assets/clone-BndpjwTg.js +0 -1
  59. package/web-dist/assets/stateDiagram-v2-FVOUBMTO-6OPyDgAh.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AAEA,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;AAqHvF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBrE;AA8FD,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3D;AAydD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyCtF;AAmiBD,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,QAmnEnC"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AAEA,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;AAqHvF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBrE;AA8FD,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3D;AAydD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyCtF;AAmiBD,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,QA2mEnC"}
@@ -1401,21 +1401,34 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
1401
1401
  }
1402
1402
  const existingState = sessionStateService.get(sessionId, ["queued_messages"]);
1403
1403
  const queue = parseQueuedChatMessages(existingState["queued_messages"]);
1404
- const queuedMessage = {
1405
- id: `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
1406
- content,
1407
- queuedAt: Date.now(),
1408
- mode: chatMode,
1409
- ...(requestProvider ? { provider: requestProvider } : {}),
1410
- ...(requestRuntimeMode ? { runtimeMode: requestRuntimeMode } : {}),
1411
- ...(responseStyle !== "normal" ? { responseStyle } : {}),
1412
- ...(requestBodyModel ? { model: requestBodyModel } : {}),
1413
- ...(displaySegments ? { displaySegments } : {}),
1414
- ...(attachments.length ? { attachments } : {}),
1415
- };
1416
- const nextQueue = [...queue, queuedMessage];
1417
- sessionStateService.set(sessionId, { queued_messages: nextQueue });
1418
- broadcastQueuedMessagesState(sessionId, nextQueue);
1404
+ // Dedupe by normalized content: if an equivalent message is already
1405
+ // queued (the server-side drain may already be processing the same
1406
+ // content the client just re-sent), reuse the existing entry instead
1407
+ // of appending a duplicate. This is the server-side guard against the
1408
+ // client/server drain race that multiplied queued messages.
1409
+ const normalizedContent = content.trim();
1410
+ const existing = queue.find((entry) => entry.content.trim() === normalizedContent);
1411
+ let queuedMessage;
1412
+ if (existing) {
1413
+ queuedMessage = existing;
1414
+ }
1415
+ else {
1416
+ queuedMessage = {
1417
+ id: `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
1418
+ content,
1419
+ queuedAt: Date.now(),
1420
+ mode: chatMode,
1421
+ ...(requestProvider ? { provider: requestProvider } : {}),
1422
+ ...(requestRuntimeMode ? { runtimeMode: requestRuntimeMode } : {}),
1423
+ ...(responseStyle !== "normal" ? { responseStyle } : {}),
1424
+ ...(requestBodyModel ? { model: requestBodyModel } : {}),
1425
+ ...(displaySegments ? { displaySegments } : {}),
1426
+ ...(attachments.length ? { attachments } : {}),
1427
+ };
1428
+ const nextQueue = [...queue, queuedMessage];
1429
+ sessionStateService.set(sessionId, { queued_messages: nextQueue });
1430
+ broadcastQueuedMessagesState(sessionId, nextQueue);
1431
+ }
1419
1432
  const reqOrigin = request.headers.origin ?? "*";
1420
1433
  reply.raw.writeHead(202, {
1421
1434
  "Content-Type": "text/event-stream",
@@ -1429,7 +1442,7 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
1429
1442
  type: "queued",
1430
1443
  session_id: sessionId,
1431
1444
  message: queuedMessage,
1432
- queue_length: nextQueue.length,
1445
+ queue_length: queue.length + (existing ? 0 : 1),
1433
1446
  };
1434
1447
  reply.raw.write(`data: ${JSON.stringify(queuedEvent)}\n\n`);
1435
1448
  reply.raw.write(`data: ${JSON.stringify({ type: "done", session_id: sessionId, prompt_count: null, remaining_prompts: null })}\n\n`);
@@ -2023,8 +2036,6 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
2023
2036
  ].join("\n");
2024
2037
  const cliContextFlow = buildExternalProviderContextFlow(requestProvider, typeof body["model"] === "string" ? body["model"] : undefined, setupContent, cliSystemPrompt, cliUserContent, sentAt, "CLI providers keep their own session context. This captures the Jait setup metadata, the external-provider system prompt, and the user turn content. On reused CLI sessions, the system prompt is shown for inspection even though it was only sent when Jait initialized or recovered the provider session.", memoryFlow, recentContextBlock);
2025
2038
  contextFlowJson = JSON.stringify(cliContextFlow);
2026
- safeWrite(`data: ${JSON.stringify({ type: "context_flow", ...cliContextFlow })}\n\n`);
2027
- emitToSubscribers(sessionId, { type: "context_flow", ...cliContextFlow });
2028
2039
  await cliProvider.sendTurn(providerSessionId, cliContent);
2029
2040
  }
2030
2041
  catch (sendErr) {
@@ -2072,8 +2083,6 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
2072
2083
  ].join("\n");
2073
2084
  const cliContextFlow = buildExternalProviderContextFlow(requestProvider, typeof body["model"] === "string" ? body["model"] : undefined, setupContent, refreshedSystemPrompt, cliUserContent, sentAt, "CLI providers keep their own session context. This captures the Jait recovery setup metadata, the current Jait session system prompt, and the user turn content.", memoryFlow, recoveryContextBlock);
2074
2085
  contextFlowJson = JSON.stringify(cliContextFlow);
2075
- safeWrite(`data: ${JSON.stringify({ type: "context_flow", ...cliContextFlow })}\n\n`);
2076
- emitToSubscribers(sessionId, { type: "context_flow", ...cliContextFlow });
2077
2086
  await cliProvider.sendTurn(providerSessionId, recoveryContent);
2078
2087
  }
2079
2088
  // Wait for the turn-completion event (may already be resolved if
@@ -2262,15 +2271,6 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
2262
2271
  ...(contextRounds.length !== storedRounds.length ? { truncatedRounds: contextRounds.length } : {}),
2263
2272
  ...(memoryFlow ? { memory: memoryFlow } : {}),
2264
2273
  });
2265
- const event = {
2266
- type: "context_flow",
2267
- provider: "jait",
2268
- model: llmRuntime.openaiModel,
2269
- rounds: contextRounds,
2270
- ...(memoryFlow ? { memory: memoryFlow } : {}),
2271
- };
2272
- emitToSubscribers(sessionId, event);
2273
- safeWrite(`data: ${JSON.stringify(event)}\n\n`);
2274
2274
  },
2275
2275
  onPersist: (sid, role, content, tc, seg, thinking) => persistMessage(sid, role, content, tc, seg, contextFlowJson, thinking),
2276
2276
  priorFingerprints: sessionFingerprints.get(sessionId),
@@ -2306,15 +2306,6 @@ export function registerChatRoutes(app, config, depsOrDb, sessionServiceArg) {
2306
2306
  rounds: contextRounds,
2307
2307
  ...(memoryFlow ? { memory: memoryFlow } : {}),
2308
2308
  });
2309
- const finalEvent = {
2310
- type: "context_flow",
2311
- provider: "jait",
2312
- model: llmRuntime.openaiModel,
2313
- rounds: contextRounds,
2314
- ...(memoryFlow ? { memory: memoryFlow } : {}),
2315
- };
2316
- emitToSubscribers(sessionId, finalEvent);
2317
- safeWrite(`data: ${JSON.stringify(finalEvent)}\n\n`);
2318
2309
  }
2319
2310
  if (contextFlowJson) {
2320
2311
  const lastAssistant = [...history].reverse().find((msg) => msg.role === "assistant");