@flamingo-stack/openframe-frontend-core 0.0.508 → 0.0.509
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/dist/chat-protocol/decode.d.ts +58 -0
- package/dist/chat-protocol/decode.d.ts.map +1 -0
- package/dist/chat-protocol/encode.d.ts +44 -0
- package/dist/chat-protocol/encode.d.ts.map +1 -0
- package/dist/chat-protocol/env-flag.d.ts +35 -0
- package/dist/chat-protocol/env-flag.d.ts.map +1 -0
- package/dist/chat-protocol/events.d.ts +216 -0
- package/dist/chat-protocol/events.d.ts.map +1 -0
- package/dist/chat-protocol/frames.d.ts +213 -0
- package/dist/chat-protocol/frames.d.ts.map +1 -0
- package/dist/chat-protocol/index.cjs +506 -0
- package/dist/chat-protocol/index.cjs.map +1 -0
- package/dist/chat-protocol/index.d.ts +18 -0
- package/dist/chat-protocol/index.d.ts.map +1 -0
- package/dist/chat-protocol/index.js +490 -0
- package/dist/chat-protocol/index.js.map +1 -0
- package/dist/chat-protocol/ip-normalize.d.ts +44 -0
- package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
- package/dist/chat-protocol/nats-decoder.d.ts +26 -0
- package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
- package/dist/{chunk-3SQ5KXHQ.cjs → chunk-2T4GTV25.cjs} +9 -9
- package/dist/{chunk-3SQ5KXHQ.cjs.map → chunk-2T4GTV25.cjs.map} +1 -1
- package/dist/{chunk-CWAOV2FK.cjs → chunk-3CGZPAGR.cjs} +3 -3
- package/dist/{chunk-CWAOV2FK.cjs.map → chunk-3CGZPAGR.cjs.map} +1 -1
- package/dist/{chunk-TLMJHMXJ.js → chunk-3QSR22IC.js} +12 -12
- package/dist/chunk-3QSR22IC.js.map +1 -0
- package/dist/{chunk-TWYNR4TZ.cjs → chunk-4G5TLHJD.cjs} +7141 -4799
- package/dist/chunk-4G5TLHJD.cjs.map +1 -0
- package/dist/{chunk-ADPMHWOE.js → chunk-72XAID7Y.js} +4 -4
- package/dist/{chunk-PAGKRNWK.js → chunk-7WZHBQ4J.js} +2 -2
- package/dist/{chunk-OCEKO5CW.js → chunk-AEELJC4N.js} +12106 -9764
- package/dist/chunk-AEELJC4N.js.map +1 -0
- package/dist/{chunk-Z42BGM6Q.cjs → chunk-BT2WWDFP.cjs} +5 -5
- package/dist/{chunk-Z42BGM6Q.cjs.map → chunk-BT2WWDFP.cjs.map} +1 -1
- package/dist/{chunk-7LEL3RIX.cjs → chunk-C7OY3PQP.cjs} +11 -11
- package/dist/{chunk-7LEL3RIX.cjs.map → chunk-C7OY3PQP.cjs.map} +1 -1
- package/dist/{chunk-RHGGEKPQ.cjs → chunk-CIOLOQKQ.cjs} +4 -4
- package/dist/{chunk-RHGGEKPQ.cjs.map → chunk-CIOLOQKQ.cjs.map} +1 -1
- package/dist/{chunk-TSZHM74B.js → chunk-DC2TKS7C.js} +2 -2
- package/dist/{chunk-M2GOR3XQ.cjs → chunk-DYPYR7FR.cjs} +87 -87
- package/dist/{chunk-M2GOR3XQ.cjs.map → chunk-DYPYR7FR.cjs.map} +1 -1
- package/dist/{chunk-I64ABCDX.js → chunk-I2B6X77L.js} +2 -2
- package/dist/{chunk-NIZDKTGL.cjs → chunk-K5MSCMDK.cjs} +37 -37
- package/dist/{chunk-NIZDKTGL.cjs.map → chunk-K5MSCMDK.cjs.map} +1 -1
- package/dist/{chunk-DTYRYB2N.js → chunk-K6QTZ7CZ.js} +2 -2
- package/dist/{chunk-4LTMXDUS.js → chunk-KBN7PMFT.js} +2 -2
- package/dist/{chunk-TBMV7I5N.js → chunk-KXZO2WZX.js} +2 -2
- package/dist/{chunk-QTYZMP6D.cjs → chunk-LBAKLT6T.cjs} +62 -62
- package/dist/chunk-LBAKLT6T.cjs.map +1 -0
- package/dist/{chunk-KEBYLU3U.js → chunk-LFUPI7VX.js} +2 -2
- package/dist/{chunk-LDTR4IVZ.cjs → chunk-M37PBG4N.cjs} +31 -31
- package/dist/{chunk-LDTR4IVZ.cjs.map → chunk-M37PBG4N.cjs.map} +1 -1
- package/dist/{chunk-WA7RR64F.js → chunk-PO5O654H.js} +6 -5
- package/dist/chunk-PO5O654H.js.map +1 -0
- package/dist/{chunk-WK4N5VBX.cjs → chunk-QJJISLPA.cjs} +28 -27
- package/dist/chunk-QJJISLPA.cjs.map +1 -0
- package/dist/{chunk-2F44PLTV.cjs → chunk-T7MCSA55.cjs} +26 -26
- package/dist/{chunk-2F44PLTV.cjs.map → chunk-T7MCSA55.cjs.map} +1 -1
- package/dist/{chunk-WJQHJD7J.js → chunk-TWSKTJHW.js} +2 -2
- package/dist/{chunk-ZSQHZYCO.cjs → chunk-UQDMJ6DH.cjs} +13 -13
- package/dist/{chunk-ZSQHZYCO.cjs.map → chunk-UQDMJ6DH.cjs.map} +1 -1
- package/dist/{chunk-TZRUCD56.js → chunk-V3ZAAFE3.js} +5 -5
- package/dist/{chunk-LRGHJPET.js → chunk-XGIFOHKE.js} +2 -2
- package/dist/{chunk-POOMO3PA.cjs → chunk-YQEPRYT5.cjs} +7 -7
- package/dist/{chunk-POOMO3PA.cjs.map → chunk-YQEPRYT5.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/chat/hooks/index.d.ts +0 -1
- package/dist/components/chat/hooks/index.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +10 -2
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.d.ts +1 -0
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +21 -13
- package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
- package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
- package/dist/components/chat/stream/chat-stream-reducer.d.ts +380 -0
- package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
- package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
- package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
- package/dist/components/chat/stream/index.d.ts +17 -0
- package/dist/components/chat/stream/index.d.ts.map +1 -0
- package/dist/components/chat/stream/message-mutations.d.ts +77 -0
- package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
- package/dist/components/chat/types/api.types.d.ts +1 -81
- package/dist/components/chat/types/api.types.d.ts.map +1 -1
- package/dist/components/chat/types/processing.types.d.ts +2 -93
- package/dist/components/chat/types/processing.types.d.ts.map +1 -1
- package/dist/components/chat/types/unified-chat-state.types.d.ts +15 -0
- package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
- package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
- package/dist/components/chat/utils/index.d.ts +2 -3
- package/dist/components/chat/utils/index.d.ts.map +1 -1
- package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
- package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +174 -132
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +65 -23
- package/dist/components/index.js.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +44 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +1 -2
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +55 -13
- package/dist/components/ui/markdown/base-components.d.ts +51 -0
- package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
- package/dist/components/ui/markdown/engine.d.ts +99 -0
- package/dist/components/ui/markdown/engine.d.ts.map +1 -0
- package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
- package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
- package/dist/components/ui/markdown/index.d.ts +18 -0
- package/dist/components/ui/markdown/index.d.ts.map +1 -0
- package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
- package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
- package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
- package/dist/components/ui/markdown/sanitize.d.ts +153 -0
- package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
- package/dist/components/ui/markdown/streaming.d.ts +78 -0
- package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
- package/dist/components/ui/markdown/text-size.d.ts +34 -0
- package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
- package/dist/index.cjs +60 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +71 -13
- package/dist/utils/index.cjs +169 -40
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +162 -41
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/markdown-fences.d.ts +42 -0
- package/dist/utils/markdown-fences.d.ts.map +1 -0
- package/dist/utils/markdown-heading-id.d.ts +85 -0
- package/dist/utils/markdown-heading-id.d.ts.map +1 -0
- package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +319 -0
- package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
- package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
- package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
- package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +237 -0
- package/src/chat-protocol/decode.ts +278 -0
- package/src/chat-protocol/encode.ts +71 -0
- package/src/chat-protocol/env-flag.ts +39 -0
- package/src/chat-protocol/events.ts +254 -0
- package/src/chat-protocol/frames.ts +245 -0
- package/src/chat-protocol/index.ts +21 -0
- package/src/chat-protocol/ip-normalize.ts +146 -0
- package/src/chat-protocol/nats-decoder.ts +264 -0
- package/src/components/chat/.chat-message-list.md +10 -6
- package/src/components/chat/__tests__/chat-message-list.test.tsx +450 -9
- package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
- package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
- package/src/components/chat/chat-message-enhanced.tsx +122 -20
- package/src/components/chat/chat-message-list.tsx +515 -133
- package/src/components/chat/embeddable-chat.tsx +6 -0
- package/src/components/chat/hooks/.index.md +30 -33
- package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
- package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
- package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
- package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
- package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
- package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
- package/src/components/chat/hooks/index.ts +0 -1
- package/src/components/chat/hooks/use-chat.ts +8 -0
- package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
- package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
- package/src/components/chat/index.ts +5 -0
- package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +944 -0
- package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
- package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
- package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1330 -0
- package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
- package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
- package/src/components/chat/stream/chat-dialog-store.ts +536 -0
- package/src/components/chat/stream/chat-stream-reducer.ts +1928 -0
- package/src/components/chat/stream/delta-batcher.ts +168 -0
- package/src/components/chat/stream/index.ts +55 -0
- package/src/components/chat/stream/message-mutations.ts +340 -0
- package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
- package/src/components/chat/thinking-display.tsx +1 -1
- package/src/components/chat/types/.api.types.md +39 -49
- package/src/components/chat/types/.processing.types.md +29 -58
- package/src/components/chat/types/.unified-chat-state.types.md +2 -2
- package/src/components/chat/types/api.types.ts +6 -73
- package/src/components/chat/types/processing.types.ts +11 -53
- package/src/components/chat/types/unified-chat-state.types.ts +16 -0
- package/src/components/chat/utils/.extract-incomplete-message-state.md +21 -3
- package/src/components/chat/utils/.history-merge.md +44 -3
- package/src/components/chat/utils/.index.md +31 -40
- package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
- package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
- package/src/components/chat/utils/__tests__/extract-incomplete-message-state.test.ts +106 -0
- package/src/components/chat/utils/__tests__/history-merge.test.ts +160 -0
- package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
- package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
- package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
- package/src/components/chat/utils/extract-incomplete-message-state.ts +93 -6
- package/src/components/chat/utils/history-merge.ts +85 -5
- package/src/components/chat/utils/index.ts +5 -8
- package/src/components/chat/utils/process-historical-messages.ts +361 -385
- package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
- package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
- package/src/components/shared/product-release/release-detail-page.tsx +19 -4
- package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
- package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
- package/src/components/ui/index.ts +1 -2
- package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
- package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
- package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
- package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
- package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
- package/src/components/ui/markdown/base-components.tsx +360 -0
- package/src/components/ui/markdown/engine.tsx +315 -0
- package/src/components/ui/markdown/heading-ids.ts +239 -0
- package/src/components/ui/markdown/index.ts +49 -0
- package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
- package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
- package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
- package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
- package/src/components/ui/markdown/sanitize.ts +3584 -0
- package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
- package/src/components/ui/markdown/streaming.ts +390 -0
- package/src/components/ui/markdown/text-size.ts +106 -0
- package/src/components/ui/release-changelog-section.tsx +1 -1
- package/src/components/ui/ticket-info-section.tsx +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/markdown-fences.ts +127 -0
- package/src/utils/markdown-heading-id.ts +348 -0
- package/src/utils/markdown-section-extractor.ts +41 -56
- package/dist/chunk-OCEKO5CW.js.map +0 -1
- package/dist/chunk-QTYZMP6D.cjs.map +0 -1
- package/dist/chunk-TLMJHMXJ.js.map +0 -1
- package/dist/chunk-TWYNR4TZ.cjs.map +0 -1
- package/dist/chunk-WA7RR64F.js.map +0 -1
- package/dist/chunk-WK4N5VBX.cjs.map +0 -1
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
- package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
- package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
- package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
- package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
- package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
- package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
- package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
- package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
- package/src/components/chat/utils/.chunk-parser.md +0 -62
- package/src/components/chat/utils/chunk-parser.ts +0 -262
- package/src/components/ui/.simple-markdown-renderer.md +0 -52
- package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
- package/src/components/ui/simple-markdown-renderer.tsx +0 -964
- /package/dist/{chunk-ADPMHWOE.js.map → chunk-72XAID7Y.js.map} +0 -0
- /package/dist/{chunk-PAGKRNWK.js.map → chunk-7WZHBQ4J.js.map} +0 -0
- /package/dist/{chunk-TSZHM74B.js.map → chunk-DC2TKS7C.js.map} +0 -0
- /package/dist/{chunk-I64ABCDX.js.map → chunk-I2B6X77L.js.map} +0 -0
- /package/dist/{chunk-DTYRYB2N.js.map → chunk-K6QTZ7CZ.js.map} +0 -0
- /package/dist/{chunk-4LTMXDUS.js.map → chunk-KBN7PMFT.js.map} +0 -0
- /package/dist/{chunk-TBMV7I5N.js.map → chunk-KXZO2WZX.js.map} +0 -0
- /package/dist/{chunk-KEBYLU3U.js.map → chunk-LFUPI7VX.js.map} +0 -0
- /package/dist/{chunk-WJQHJD7J.js.map → chunk-TWSKTJHW.js.map} +0 -0
- /package/dist/{chunk-TZRUCD56.js.map → chunk-V3ZAAFE3.js.map} +0 -0
- /package/dist/{chunk-LRGHJPET.js.map → chunk-XGIFOHKE.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import { forwardRef, useState } from "react"
|
|
|
4
4
|
|
|
5
5
|
import { cn } from "../../utils/cn"
|
|
6
6
|
import { DotsLoaderIcon } from "../icons-v2-generated"
|
|
7
|
-
import { SimpleMarkdownRenderer } from "../ui/simple-markdown-renderer"
|
|
7
|
+
import { SimpleMarkdownRenderer } from "../ui/markdown/simple-markdown-renderer"
|
|
8
8
|
import { ExpandChevron } from "./expand-chevron"
|
|
9
9
|
import { useCollapsible } from "./hooks/use-collapsible"
|
|
10
10
|
import type { ThinkingDisplayProps } from "./types"
|
|
@@ -1,70 +1,60 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
2
|
-
Defines TypeScript interfaces for API interactions and React hook contracts used
|
|
1
|
+
<!-- source-hash: 60ad035125eceb97fa074f58783d5bc8 -->
|
|
2
|
+
Defines TypeScript interfaces for API interactions and React hook contracts used across Flamingo's chat and dialog systems, covering NATS/JetStream subscriptions, real-time chunk processing, and REST-style request/response shapes.
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
5
5
|
|
|
6
|
-
### Hook
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
### Hook Options
|
|
7
|
+
| Interface | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `UseChunkCatchupOptions` | Configure chunk catch-up replay with optional custom fetch function |
|
|
10
|
+
| `UseNatsDialogSubscriptionOptions` | Core NATS WebSocket subscription config with reconnection backoff tuning |
|
|
11
|
+
| `UseJetStreamDialogSubscriptionOptions` | JetStream-based subscription with sequence-based resume support |
|
|
12
|
+
|
|
13
|
+
### Hook Return Types
|
|
14
|
+
| Interface | Purpose |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `UseChunkCatchupReturn` | Exposes catchup, processing, and buffering controls |
|
|
17
|
+
| `UseNatsDialogSubscriptionReturn` | Connection state and reconnection counter |
|
|
18
|
+
| `UseJetStreamDialogSubscriptionReturn` | Connection state plus current stream sequence |
|
|
19
|
+
|
|
20
|
+
### Callbacks
|
|
21
|
+
- **`RealtimeChunkCallbacks`** — Rich event callback map for streaming events: `onStreamStart`, `onStreamEnd`, `onSegmentsUpdate`, `onTokenUsage`, `onApprove`, `onReject`, `onEscalatedApproval`, `onApprovalResolved`, `onToolExecuted`, `onDialogClosed`, and more.
|
|
22
|
+
|
|
23
|
+
### API Request/Response Types
|
|
24
|
+
- **Chat** — `ChatAPIRequest` / `ChatAPIResponse`
|
|
25
|
+
- **Dialogs** — `DialogCreateRequest/Response`, `DialogListRequest/Response`
|
|
26
|
+
- **Approvals** — `ApprovalRequest` / `ApprovalResponse`
|
|
27
|
+
- **Settings** — `ChatSettings`, `UpdateSettingsRequest/Response`
|
|
20
28
|
|
|
21
29
|
## Usage Example
|
|
22
30
|
|
|
23
31
|
```typescript
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (meta?.append) appendSegments(segments)
|
|
35
|
-
else setSegments(segments)
|
|
36
|
-
},
|
|
37
|
-
onToolExecuted: (segment) => mergeToolResult(segment),
|
|
38
|
-
onApprovalResolved: (requestId, status, approvalType) => {
|
|
39
|
-
updateApprovalCard(requestId, status)
|
|
32
|
+
const options: ChatStreamReducerOptions = {
|
|
33
|
+
callbacks: {
|
|
34
|
+
onSegmentsUpdate: (segments, meta) => {
|
|
35
|
+
if (meta?.append) appendToLastMessage(segments)
|
|
36
|
+
else setSegments(segments)
|
|
37
|
+
},
|
|
38
|
+
onApprovalResolved: (requestId, status, approvalType) => {
|
|
39
|
+
updateApprovalBadge(requestId, status)
|
|
40
|
+
},
|
|
41
|
+
onTokenUsage: (data) => console.log('Tokens used:', data),
|
|
40
42
|
},
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const processorOptions: UseRealtimeChunkProcessorOptions = {
|
|
44
|
-
callbacks,
|
|
45
|
-
displayApprovalTypes: ['CLIENT'],
|
|
46
43
|
batchApprovalsEnabled: true,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
executingTools: new Map(),
|
|
50
|
-
},
|
|
44
|
+
displayApprovalTypes: ['CLIENT'],
|
|
45
|
+
enableThinking: false,
|
|
51
46
|
}
|
|
52
47
|
|
|
53
48
|
const natsOptions: UseNatsDialogSubscriptionOptions = {
|
|
54
49
|
enabled: true,
|
|
55
50
|
dialogId: 'dialog-123',
|
|
56
|
-
topics: ['message'],
|
|
57
51
|
getNatsWsUrl: () => 'wss://nats.example.com',
|
|
58
|
-
onBeforeReconnect: async () => refreshAuthToken(),
|
|
59
52
|
reconnectionBackoff: {
|
|
60
53
|
fastRetries: 3,
|
|
61
54
|
fastRetryDelayMs: 500,
|
|
62
|
-
maxDelayMs:
|
|
55
|
+
maxDelayMs: 30000,
|
|
63
56
|
multiplier: 2,
|
|
64
57
|
},
|
|
58
|
+
onBeforeReconnect: async () => refreshAuthToken(),
|
|
65
59
|
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Source
|
|
69
|
-
|
|
70
|
-
[`api.types.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/api.types.ts)
|
|
60
|
+
```
|
|
@@ -1,80 +1,51 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
2
|
-
Defines TypeScript types for
|
|
1
|
+
<!-- source-hash: 118d3a4cacf89174498282067448e4bf -->
|
|
2
|
+
Defines TypeScript types for message processing pipeline operations, including chunk parsing, accumulator state management, stream control, and buffer management for AI chat message flows.
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### Chunk Processing
|
|
17
|
-
- **`ChunkProcessor`** — Interface for stateful chunk parsing with `processChunk` and `reset`
|
|
18
|
-
- **`ChunkProcessorOptions`** — Lifecycle callbacks for chunk events (`onText`, `onToolExecution`, `onApprovalRequest`, etc.)
|
|
19
|
-
|
|
20
|
-
### Message Transformation
|
|
21
|
-
- **`MessageTransformer`** — Single and batch transform interface producing `ProcessedMessage` outputs
|
|
22
|
-
- **`TransformationOptions`** — Flags for segment merging, timestamp formatting, and metadata inclusion
|
|
23
|
-
|
|
24
|
-
### Stream & Buffer Management
|
|
25
|
-
- **`StreamProcessor`** — Lifecycle control (`start`, `stop`, `pause`, `resume`, `reset`, `getState`)
|
|
26
|
-
- **`StreamState`** — Runtime counters: active state, pause flag, processed message count, buffered chunks, error log
|
|
27
|
-
- **`BufferManager`** — FIFO buffer operations (`add`, `flush`, `clear`, `size`, `isEmpty`, `isFull`)
|
|
28
|
-
- **`BufferOptions`** — Max size, flush interval, and overflow/flush callbacks
|
|
6
|
+
| Export | Type | Description |
|
|
7
|
+
|--------|------|-------------|
|
|
8
|
+
| `AccumulatorState` | Interface | Stateful container tracking message segments, pending approvals, and executing tools during stream processing |
|
|
9
|
+
| `PendingApproval` | Interface | Represents an approval request awaiting user action (command, explanation, type) |
|
|
10
|
+
| `MessageProcessingOptions` | Interface | Configuration for assistant rendering, approval callbacks, chat filtering, and batch approval UI |
|
|
11
|
+
| `StreamProcessor` | Interface | Full lifecycle control (start/stop/pause/resume/reset) for stream consumers |
|
|
12
|
+
| `StreamState` | Interface | Snapshot of stream health: active status, buffered chunks, error log, and last activity timestamp |
|
|
13
|
+
| `BufferManager` | Interface | CRUD-style contract for managing `ChunkData` buffers |
|
|
14
|
+
| `BufferOptions` | Interface | Configuration for buffer capacity, flush intervals, and overflow handling callbacks |
|
|
29
15
|
|
|
30
16
|
## Usage Example
|
|
31
17
|
|
|
32
18
|
```typescript
|
|
33
19
|
import type {
|
|
34
|
-
ParsedChunkAction,
|
|
35
20
|
AccumulatorState,
|
|
36
21
|
MessageProcessingOptions,
|
|
37
|
-
StreamState
|
|
22
|
+
StreamState
|
|
38
23
|
} from './processing.types'
|
|
39
24
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
case 'tool_execution':
|
|
47
|
-
console.log('Tool segment:', action.segment)
|
|
48
|
-
break
|
|
49
|
-
case 'approval_batch':
|
|
50
|
-
console.log('Batch approval', action.requestId, action.toolCalls)
|
|
51
|
-
break
|
|
52
|
-
case 'error':
|
|
53
|
-
console.error(action.error, action.details)
|
|
54
|
-
break
|
|
55
|
-
}
|
|
25
|
+
|
|
26
|
+
// Initializing accumulator state
|
|
27
|
+
const state: AccumulatorState = {
|
|
28
|
+
segments: [],
|
|
29
|
+
pendingApprovals: new Map(),
|
|
30
|
+
executingTools: new Map()
|
|
56
31
|
}
|
|
57
32
|
|
|
58
|
-
//
|
|
33
|
+
// Configuring message processing
|
|
59
34
|
const options: MessageProcessingOptions = {
|
|
60
35
|
assistantName: 'Mingo',
|
|
61
36
|
assistantType: 'mingo',
|
|
62
|
-
batchApprovalsEnabled: true,
|
|
63
|
-
displayApprovalTypes: ['shell', '
|
|
37
|
+
batchApprovalsEnabled: true,
|
|
38
|
+
displayApprovalTypes: ['shell', 'file'],
|
|
64
39
|
onApprove: async (requestId) => {
|
|
65
|
-
await
|
|
66
|
-
},
|
|
67
|
-
onReject: async (requestId) => {
|
|
68
|
-
await fetch(`/api/approvals/${requestId}/reject`, { method: 'POST' })
|
|
40
|
+
await submitApproval(requestId)
|
|
69
41
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const state: AccumulatorState = {
|
|
74
|
-
segments: [],
|
|
75
|
-
pendingApprovals: new Map(),
|
|
76
|
-
executingTools: new Map(),
|
|
42
|
+
onReject: (requestId) => {
|
|
43
|
+
logRejection(requestId)
|
|
44
|
+
}
|
|
77
45
|
}
|
|
78
46
|
```
|
|
79
47
|
|
|
80
|
-
|
|
48
|
+
> NOTE: the wire-chunk vocabulary now lives in `src/chat-protocol/events.ts`
|
|
49
|
+
> (`ChatStreamEvent`, produced by `decodeNatsChunk`). The old
|
|
50
|
+
> `ParsedChunkAction` union and the `ChunkProcessor` contract were deleted
|
|
51
|
+
> together with the legacy `chunk-parser`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
1
|
+
<!-- source-hash: c1ee0588313988b2559f2016a0a5d7cf -->
|
|
2
2
|
Unified contract type definitions for the `useChat` hook's transport-agnostic return shape, shared by both the SSE (Guide mode) and NATS (Mingo mode) transport adapters.
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
@@ -9,7 +9,7 @@ Unified contract type definitions for the `useChat` hook's transport-agnostic re
|
|
|
9
9
|
| `ChatConnectionState` | Type | Transport-level connection status: `'connected' \| 'connecting' \| 'disconnected'` |
|
|
10
10
|
| `StreamingPhase` | Type | Granular streaming indicator: `'idle' \| 'thinking' \| 'streaming'` |
|
|
11
11
|
| `UnifiedUsageBreakdown` | Interface | SSE-only sub-call token costs for the Haiku rewriter/classifier/summarizer pipeline |
|
|
12
|
-
| `UnifiedChatMessage` | Interface | Transport-agnostic message shape; Guide-only fields (`sources`, `chatRefs`) are optional |
|
|
12
|
+
| `UnifiedChatMessage` | Interface | Transport-agnostic message shape; Guide-only fields (`sources`, `chatRefs`) are optional. `streamSeq` is not render input — it is the per-message coverage signal `mergeHistoryWithRealtime` decides with, and omitting it makes a mid-stream history refetch drop live bubbles |
|
|
13
13
|
| `UnifiedSendMessageOptions` | Interface | Options accepted by `sendMessage` honoured by both transports |
|
|
14
14
|
| `UnifiedChatState` | Interface | **Primary contract** — the full return shape both transport hooks must satisfy |
|
|
15
15
|
|
|
@@ -220,79 +220,12 @@ export interface RealtimeChunkCallbacks {
|
|
|
220
220
|
onDialogClosed?: () => void
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
*/
|
|
230
|
-
displayApprovalTypes?: string[]
|
|
231
|
-
/**
|
|
232
|
-
* Map of existing approval statuses
|
|
233
|
-
*/
|
|
234
|
-
approvalStatuses?: Record<string, ChatApprovalStatus>
|
|
235
|
-
/**
|
|
236
|
-
* Initialize accumulator with existing state from incomplete historical message
|
|
237
|
-
* Used to continue building messages across page refreshes or reconnections
|
|
238
|
-
*/
|
|
239
|
-
initialState?: {
|
|
240
|
-
/** Existing segments to continue building upon */
|
|
241
|
-
existingSegments?: MessageSegment[]
|
|
242
|
-
/** Pending approvals that haven't been resolved */
|
|
243
|
-
pendingApprovals?: Map<string, { command: string; explanation?: string; approvalType: string }>
|
|
244
|
-
/** Executing tools waiting for completion */
|
|
245
|
-
executingTools?: Map<string, ExecutingToolState>
|
|
246
|
-
/** Escalated approvals */
|
|
247
|
-
escalatedApprovals?: Map<
|
|
248
|
-
string,
|
|
249
|
-
{ command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
|
|
250
|
-
>
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Consumer-owned (e.g. set in `openframe-oss-tenant` chat client via the
|
|
254
|
-
* `'batch-approvals'` feature flag and forwarded here). The lib does NOT
|
|
255
|
-
* default this to a batch-on behavior — when omitted it falls back to the
|
|
256
|
-
* legacy single-card rendering.
|
|
257
|
-
*
|
|
258
|
-
* When true: `APPROVAL_REQUEST` chunks containing `toolCalls[]` are rendered
|
|
259
|
-
* as a single batch card. When false / omitted: the batch is split into N
|
|
260
|
-
* legacy approval cards (one per tool that requires approval), all sharing
|
|
261
|
-
* the same `approvalRequestId`. Tools with `requiresApproval=false` are
|
|
262
|
-
* dropped from the UI in the unfolded mode.
|
|
263
|
-
*/
|
|
264
|
-
batchApprovalsEnabled?: boolean
|
|
265
|
-
/**
|
|
266
|
-
* Engages the direct-mode barrier optimistically: once true, all AI-assistant
|
|
267
|
-
* chunks (text, thinking, tool executions, approvals, metadata, errors, etc.)
|
|
268
|
-
* are dropped and any open stream is torn down, leaving only human/control
|
|
269
|
-
* messages. A `DIRECT_MESSAGE` chunk engages the same barrier automatically
|
|
270
|
-
* regardless of this flag. Pass this from a host that already knows the dialog
|
|
271
|
-
* switched to direct mode (e.g. an optimistic mode toggle) to close the race
|
|
272
|
-
* window before the server emits the first `DIRECT_MESSAGE`.
|
|
273
|
-
*
|
|
274
|
-
* Do NOT set this when the host reconstructs history by replaying chunks
|
|
275
|
-
* through `processChunk` — a static flag would drop legitimate pre-switch AI
|
|
276
|
-
* history. Rely on the in-order `DIRECT_MESSAGE` detection instead.
|
|
277
|
-
*/
|
|
278
|
-
isDirectMode?: boolean
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
export interface UseRealtimeChunkProcessorReturn {
|
|
282
|
-
/** Process a single chunk */
|
|
283
|
-
processChunk: (chunk: unknown) => void
|
|
284
|
-
/** Get current segments */
|
|
285
|
-
getSegments: () => MessageSegment[]
|
|
286
|
-
/** Reset the accumulator */
|
|
287
|
-
reset: () => void
|
|
288
|
-
/** Update approval status for a request */
|
|
289
|
-
updateApprovalStatus: (requestId: string, status: ChatApprovalStatus, resolvedByName?: string | null) => MessageSegment[]
|
|
290
|
-
/** Get pending approval requests */
|
|
291
|
-
getPendingApprovals: () => Map<
|
|
292
|
-
string,
|
|
293
|
-
{ command: string; explanation?: string; approvalType: string; toolCalls?: PendingToolCallData[] }
|
|
294
|
-
>
|
|
295
|
-
}
|
|
223
|
+
// NOTE: `UseRealtimeChunkProcessorOptions` / `UseRealtimeChunkProcessorReturn`
|
|
224
|
+
// were DELETED along with the `useRealtimeChunkProcessor` compat hook. The
|
|
225
|
+
// equivalents are `ChatStreamReducerOptions` + `ChatStreamReducer` in
|
|
226
|
+
// `../stream/chat-stream-reducer`. `RealtimeChunkCallbacks` above SURVIVES:
|
|
227
|
+
// it is still the canonical description of the effect names/args the reducer
|
|
228
|
+
// emits via `ChatReducerEffect`.
|
|
296
229
|
|
|
297
230
|
// ========== API Request Types ==========
|
|
298
231
|
|
|
@@ -3,38 +3,14 @@
|
|
|
3
3
|
* Contains types for message parsing, accumulation, and processing
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { MessageSegment,
|
|
6
|
+
import type { MessageSegment, PendingToolCallData, ExecutingToolState } from './message.types'
|
|
7
7
|
import type { ChatApprovalStatus, AssistantType } from './chat.types'
|
|
8
|
-
import type { ChunkData
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| { action: 'message_end' }
|
|
15
|
-
| { action: 'error'; error: string; details?: string }
|
|
16
|
-
| { action: 'metadata'; modelDisplayName: string; modelName: string; providerName: string; contextWindow: number }
|
|
17
|
-
| { action: 'text'; text: string }
|
|
18
|
-
| { action: 'thinking'; text: string }
|
|
19
|
-
| { action: 'guide'; text: string }
|
|
20
|
-
| { action: 'tool_execution'; segment: ToolExecutionSegment }
|
|
21
|
-
| { action: 'approval_request'; requestId: string; command: string; explanation?: string; approvalType: string }
|
|
22
|
-
| { action: 'approval_batch'; requestId: string; approvalType: string; toolCalls: PendingToolCallData[] }
|
|
23
|
-
| { action: 'approval_result'; requestId: string; approved: boolean; approvalType: string; resolvedByName?: string | null }
|
|
24
|
-
| {
|
|
25
|
-
action: 'message_request'
|
|
26
|
-
text: string
|
|
27
|
-
ownerType?: string
|
|
28
|
-
displayName?: string
|
|
29
|
-
userId?: string
|
|
30
|
-
contextItems?: Array<{ type: string; id: string }>
|
|
31
|
-
}
|
|
32
|
-
| { action: 'token_usage'; data: TokenUsageData }
|
|
33
|
-
| { action: 'direct_message'; text: string; ownerType?: string; displayName?: string; userId?: string }
|
|
34
|
-
| { action: 'system'; text: string }
|
|
35
|
-
| { action: 'context_compaction_start' }
|
|
36
|
-
| { action: 'context_compaction_end'; summary?: string }
|
|
37
|
-
| { action: 'dialog_closed' }
|
|
8
|
+
import type { ChunkData } from './network.types'
|
|
9
|
+
|
|
10
|
+
// NOTE: the `ParsedChunkAction` union that used to live here was DELETED
|
|
11
|
+
// alongside the legacy `chunk-parser`. The wire → normalized-event
|
|
12
|
+
// vocabulary is now `ChatStreamEvent` in `src/chat-protocol/events.ts`,
|
|
13
|
+
// produced by `decodeNatsChunk`.
|
|
38
14
|
|
|
39
15
|
// ========== Accumulator State ==========
|
|
40
16
|
|
|
@@ -82,31 +58,13 @@ export interface MessageProcessingOptions {
|
|
|
82
58
|
batchApprovalsEnabled?: boolean
|
|
83
59
|
}
|
|
84
60
|
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
reset: () => void
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export interface ChunkProcessorOptions {
|
|
93
|
-
onMessageStart?: () => void
|
|
94
|
-
onMessageEnd?: () => void
|
|
95
|
-
onError?: (error: string, details?: string) => void
|
|
96
|
-
onText?: (text: string) => void
|
|
97
|
-
onToolExecution?: (segment: MessageSegment) => void
|
|
98
|
-
onApprovalRequest?: (data: any) => void
|
|
99
|
-
onApprovalResult?: (data: any) => void
|
|
100
|
-
onMetadata?: (data: any) => void
|
|
101
|
-
}
|
|
61
|
+
// NOTE: `ChunkProcessorOptions` (the options bag of the deleted
|
|
62
|
+
// `ChunkProcessor`) and `MessageTransformer` were DELETED — both were left
|
|
63
|
+
// behind by the chunk-processor removal with zero references in lib, hub, or
|
|
64
|
+
// app.
|
|
102
65
|
|
|
103
66
|
// ========== Message Transformation Types ==========
|
|
104
67
|
|
|
105
|
-
export interface MessageTransformer {
|
|
106
|
-
transform: (input: any) => ProcessedMessage | null
|
|
107
|
-
batch: (inputs: any[]) => ProcessedMessage[]
|
|
108
|
-
}
|
|
109
|
-
|
|
110
68
|
export interface TransformationOptions {
|
|
111
69
|
preserveOriginal?: boolean
|
|
112
70
|
mergeSegments?: boolean
|
|
@@ -144,6 +144,22 @@ export interface UnifiedChatMessage {
|
|
|
144
144
|
content: string
|
|
145
145
|
segments?: MessageSegment[]
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Highest chunk `streamSeq` consumed into THIS row. Not render input — it is
|
|
149
|
+
* the per-message coverage signal `mergeHistoryWithRealtime` decides with:
|
|
150
|
+
* a live synthetic is a twin of a persisted row only once history reaches
|
|
151
|
+
* its seq.
|
|
152
|
+
*
|
|
153
|
+
* Load-bearing, not bookkeeping. Without it the merge falls through to its
|
|
154
|
+
* wall-clock fallback ("created before the fetch instant ⇒ history has it"),
|
|
155
|
+
* which is wrong for every turn the backend has not finished persisting: a
|
|
156
|
+
* history refetch mid-stream then drops every live bubble except the single
|
|
157
|
+
* `streamingMessageId`, collapsing the thread to the persisted user prompt.
|
|
158
|
+
* The reducer stamps it on the rows it owns; hosts stamp the persisted value
|
|
159
|
+
* on history rows.
|
|
160
|
+
*/
|
|
161
|
+
streamSeq?: number
|
|
162
|
+
|
|
147
163
|
/**
|
|
148
164
|
* Optional host-supplied message timestamp (creation/send time). Rendered
|
|
149
165
|
* as the message-row time and, critically, fed into the memoized message's
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
1
|
+
<!-- source-hash: 954138e90e8f1d0354f644a2df37cd43 -->
|
|
2
2
|
Extracts incomplete message state from the last historical assistant message, enabling the realtime chunk processor to resume building messages across reconnected sessions.
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
@@ -10,17 +10,35 @@ Inspects a `ProcessedMessage` and returns resumable state if any in-progress seg
|
|
|
10
10
|
**Parameters:**
|
|
11
11
|
- `lastMessage` — A `ProcessedMessage` or `undefined`
|
|
12
12
|
|
|
13
|
-
**Returns:** An object with optional `existingSegments`, `pendingApprovals`, and `
|
|
13
|
+
**Returns:** An object with optional `existingSegments`, `pendingApprovals`, `executingTools`, and `agentBusy`, or `undefined` if the message is complete or ineligible.
|
|
14
14
|
|
|
15
15
|
**Incomplete state detection by segment type:**
|
|
16
16
|
|
|
17
17
|
| Segment Type | Condition Flagged Incomplete |
|
|
18
18
|
|---|---|
|
|
19
19
|
| `tool_execution` | Status is `EXECUTING_TOOL` |
|
|
20
|
-
| `approval_request` | Status is `pending` with a `requestId` |
|
|
20
|
+
| `approval_request` | Status is `pending` with a `requestId`, **or** `approved` as the trailing segment |
|
|
21
21
|
| `approval_batch` | Not `rejected` and not all tool calls have `done` executions |
|
|
22
22
|
| `context_compaction` | Status is `started` |
|
|
23
23
|
|
|
24
|
+
### `agentBusy` — incomplete ≠ working
|
|
25
|
+
|
|
26
|
+
Unfinished says nothing about WHO the turn is waiting on, and only the activity
|
|
27
|
+
indicator's answer to that is user-visible. `agentBusy` is the second, narrower
|
|
28
|
+
question, derived here so every host answers it the same way (the reducer raises
|
|
29
|
+
`idle → thinking` off it on `initializeWithState`; callback-contract hosts fire
|
|
30
|
+
`onAgentBusy`). Nothing on the wire restores this after a reload: a run's
|
|
31
|
+
EXECUTING chunk is long past and its EXECUTED one may be minutes away.
|
|
32
|
+
|
|
33
|
+
| Tail state | Busy | Why |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `EXECUTING_TOOL` with no result | ✅ | The tool is running now |
|
|
36
|
+
| `approval_batch` `approved`, calls outstanding | ✅ | Runs are recorded inside the batch, so `executingTools` is empty — gating on that map missed the whole approval path |
|
|
37
|
+
| `approval_request` `approved`, trailing | ✅ | A single request carries no execution record; work that followed it is the only "it came back" signal |
|
|
38
|
+
| `context_compaction` `started` | ✅ | Compaction is the agent's own work |
|
|
39
|
+
| Any approval still `pending` | ❌ | Blocked on the USER — spinning claims work that is not happening |
|
|
40
|
+
| `rejected` / `cancelled`, or all calls `done` | ❌ | Nothing outstanding |
|
|
41
|
+
|
|
24
42
|
## Usage Example
|
|
25
43
|
|
|
26
44
|
```typescript
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
1
|
+
<!-- source-hash: f5c3c4354e937c99e37f2acc47057b09 -->
|
|
2
2
|
Reconciles persisted dialog history (processed GraphQL pages) with realtime messages accumulated from streaming chunks, preventing both duplicate and lost turns across MSP chat interfaces (Mingo, tickets, openframe-chat).
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
@@ -49,11 +49,17 @@ store.setMessages(merged)
|
|
|
49
49
|
|
|
50
50
|
```mermaid
|
|
51
51
|
graph TD
|
|
52
|
-
A[Synthetic message] --> B{"
|
|
53
|
-
B -->|Yes|
|
|
52
|
+
A[Synthetic message] --> B{"Synthetic carries\nits own streamSeq?"}
|
|
53
|
+
B -->|Yes| B2{"Any history row\nseq-stamped?"}
|
|
54
|
+
B2 -->|Yes| C{"Same-role history\nmax seq >= synthetic seq?"}
|
|
55
|
+
B2 -->|No| I{"Global\nhistoryMaxStreamSeq > 0?"}
|
|
54
56
|
B -->|No| D{"Global seq\ncoverage known?"}
|
|
55
57
|
C -->|Yes| E[Drop synthetic]
|
|
56
58
|
C -->|No| F[Keep synthetic]
|
|
59
|
+
I -->|Yes| G2{"historyMaxStreamSeq\n>= synthetic seq?"}
|
|
60
|
+
I -->|No| F
|
|
61
|
+
G2 -->|Yes| E
|
|
62
|
+
G2 -->|No| F
|
|
57
63
|
D -->|Yes| G{"historyMaxStreamSeq\n>= realtimeSeenSeq?"}
|
|
58
64
|
D -->|No| H{"Created after\nhistoryFetchedAt?"}
|
|
59
65
|
G -->|Yes| E
|
|
@@ -62,4 +68,39 @@ graph TD
|
|
|
62
68
|
H -->|No| E
|
|
63
69
|
```
|
|
64
70
|
|
|
71
|
+
**A seq'd synthetic never falls back to wall-clock.** When nothing in history is
|
|
72
|
+
seq-stamped, `historyMaxStreamSeq === 0` is not "unknown, guess by clock" — it is
|
|
73
|
+
evidence that no persisted row has reached any seq, so the snapshot cannot
|
|
74
|
+
contain this turn. That case is the mid-stream refetch (a reconnect after the
|
|
75
|
+
window loses focus): the only persisted row of a turn in flight is the user
|
|
76
|
+
`MESSAGE_REQUEST`, which the backend does not stamp. Judging live bubbles by
|
|
77
|
+
wall-clock there read them all as "older than the fetch instant, therefore
|
|
78
|
+
persisted" and dropped every one except the single `streamingMessageId`,
|
|
79
|
+
collapsing the thread to the user's prompt.
|
|
80
|
+
|
|
81
|
+
This is why the reducer stamps `streamSeq` on the rows it owns — a live bubble
|
|
82
|
+
with no seq at all still lands in the wall-clock branch.
|
|
83
|
+
|
|
84
|
+
## Turn identity (twins whose ids differ)
|
|
85
|
+
|
|
86
|
+
Keeping a live bubble is only half the job: history may hold its own PARTIAL
|
|
87
|
+
copy of the same in-flight turn, and then the turn renders twice with the two
|
|
88
|
+
copies disagreeing (a tool row `pending` in one, `failed` in the other) because
|
|
89
|
+
each stopped at a different chunk.
|
|
90
|
+
|
|
91
|
+
Ids do not help — they converge only through adoption, and adoption happens on a
|
|
92
|
+
REPLAY (a reload re-streams the turn into the persisted row). A refetch that
|
|
93
|
+
lands mid-stream has no replay, so the live copy keeps the synthetic id the
|
|
94
|
+
reducer minted.
|
|
95
|
+
|
|
96
|
+
`turnRequestKeys` supplies the missing identity: the backend's per-call request
|
|
97
|
+
ids (tool-call ids, approval request ids, batch ids) are carried by BOTH copies.
|
|
98
|
+
When history's trailing assistant shares one with a live assistant, they are the
|
|
99
|
+
same turn, and the trailing pin keeps the live copy if it is **streaming** (the
|
|
100
|
+
chunks are landing there, so history's snapshot is stale by construction) or
|
|
101
|
+
strictly richer. Once persistence catches up the live copy is no longer richer,
|
|
102
|
+
seq coverage drops it, and the persisted row wins — self-healing, no sticky
|
|
103
|
+
state. A turn that has produced only text yields no keys, which is treated as
|
|
104
|
+
"no signal", never as a match.
|
|
105
|
+
|
|
65
106
|
> **Source:** [`history-merge.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/history-merge.ts)
|
|
@@ -1,57 +1,48 @@
|
|
|
1
|
-
<!-- source-hash:
|
|
2
|
-
Barrel export module
|
|
1
|
+
<!-- source-hash: 85c0af6cd361347beeabcd097260378a -->
|
|
2
|
+
Barrel export module that consolidates and re-exports all message processing, chat navigation, UI styling, and content utility functions for chat interfaces.
|
|
3
3
|
|
|
4
4
|
## Key Components
|
|
5
5
|
|
|
6
|
-
|
|
|
7
|
-
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
| Icon
|
|
15
|
-
|
|
|
16
|
-
| Slash
|
|
17
|
-
| Compact card | `compact-card-classes` | Shared CSS class constants and safe-href guard |
|
|
18
|
-
| Scripted stream | `scripted-stream` | Re-exported wholesale via `export *` |
|
|
6
|
+
| Category | Exports |
|
|
7
|
+
|----------|---------|
|
|
8
|
+
| **Message Accumulation** | `MessageSegmentAccumulator`, `createMessageSegmentAccumulator`, `AccumulatorCallbacks` |
|
|
9
|
+
| **Historical Messages** | `processHistoricalMessages`, `extractErrorMessages`, `processHistoricalMessagesWithErrors` |
|
|
10
|
+
| **Chat Navigation** | `handleChatNavClick`, `resolveExternalNavigation`, `decideNewTab`, `computeIsNewTab`, `buildAnchorProps` |
|
|
11
|
+
| **Proxy Auth** | `getChatProxyAuth`, `setChatProxyAuth`, `clearChatProxyAuth`, `applyProxyAuth`, `chatAuthedFetch` |
|
|
12
|
+
| **Attachments** | `formatChatAttachmentMarkdownForBubble`, `stripChatAttachmentMarkdown`, `buildChatAttachmentViewUrl` |
|
|
13
|
+
| **UI / Styling** | `chatChipClass`, compact card class constants (`COMPACT_CARD_*`), `getStatusColorScheme` |
|
|
14
|
+
| **Icon Registry** | `ICON_REGISTRY`, `getIconComponent`, `normalizeIconKey`, `getDynamicIcon` |
|
|
15
|
+
| **Source Utilities** | `getSourceIconName`, `getSourceLabel`, `resolveSourceRowCTA`, `resolveSourceIcon` |
|
|
16
|
+
| **Slash Commands** | `parseWireCommandOverride`, `sanitizeTitleForChat`, `buildDiscussAddendum` |
|
|
19
17
|
|
|
20
18
|
## Usage Example
|
|
21
19
|
|
|
22
20
|
```typescript
|
|
23
21
|
import {
|
|
24
|
-
parseChunkToAction,
|
|
25
22
|
createMessageSegmentAccumulator,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
mergeHistoryWithRealtime,
|
|
23
|
+
handleChatNavClick,
|
|
24
|
+
getChatProxyAuth,
|
|
25
|
+
getIconComponent,
|
|
30
26
|
formatChatAttachmentMarkdownForBubble,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const action = parseChunkToAction(rawChunk)
|
|
27
|
+
decideNewTab,
|
|
28
|
+
getStatusColorScheme,
|
|
29
|
+
} from '@flamingo/chat-utils'
|
|
35
30
|
|
|
36
|
-
// Accumulate message segments
|
|
31
|
+
// Accumulate streamed message segments
|
|
37
32
|
const accumulator = createMessageSegmentAccumulator({
|
|
38
|
-
onSegmentComplete: (segment) => console.log('Segment
|
|
33
|
+
onSegmentComplete: (segment) => console.log('Segment:', segment),
|
|
39
34
|
})
|
|
40
35
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
href: '/tickets/123',
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
// Resolve navigation target for a chat link
|
|
37
|
+
const { openInNewTab } = decideNewTab({
|
|
38
|
+
href: 'https://app.example.com/tickets/123',
|
|
39
|
+
surface: 'chat-bubble',
|
|
40
|
+
mode: 'web',
|
|
46
41
|
})
|
|
47
42
|
|
|
48
|
-
//
|
|
49
|
-
const Icon =
|
|
50
|
-
|
|
51
|
-
// Get agent status color scheme
|
|
52
|
-
const colors = getStatusColorScheme('online')
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Source
|
|
43
|
+
// Look up a registered icon by kebab-case key
|
|
44
|
+
const Icon = getIconComponent('clickup')
|
|
56
45
|
|
|
57
|
-
|
|
46
|
+
// Apply agent status color scheme to UI
|
|
47
|
+
const colors = getStatusColorScheme('running')
|
|
48
|
+
```
|