@flamingo-stack/openframe-frontend-core 0.0.490-1506.3944.1 → 0.0.490
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/{chunk-5CJR2GZ4.cjs → chunk-2MKUHJ3O.cjs} +31 -31
- package/dist/{chunk-5CJR2GZ4.cjs.map → chunk-2MKUHJ3O.cjs.map} +1 -1
- package/dist/{chunk-S2NHJDKQ.cjs → chunk-3IEVA5AO.cjs} +62 -62
- package/dist/{chunk-S2NHJDKQ.cjs.map → chunk-3IEVA5AO.cjs.map} +1 -1
- package/dist/{chunk-GTWO5NAY.js → chunk-6CFFISUC.js} +2 -2
- package/dist/{chunk-VHG6AX5V.js → chunk-6CJ2K7BD.js} +2 -2
- package/dist/{chunk-4NWARV5I.js → chunk-6QK3ONDD.js} +2 -2
- package/dist/{chunk-YHOIAA2E.cjs → chunk-7I42V2OD.cjs} +60 -60
- package/dist/chunk-7I42V2OD.cjs.map +1 -0
- package/dist/{chunk-T2EGSZFN.js → chunk-AIRNG27G.js} +5 -6
- package/dist/chunk-AIRNG27G.js.map +1 -0
- package/dist/{chunk-NWX7MMF5.cjs → chunk-AW63ET2A.cjs} +15 -15
- package/dist/{chunk-NWX7MMF5.cjs.map → chunk-AW63ET2A.cjs.map} +1 -1
- package/dist/{chunk-TKN5667N.js → chunk-BZMOEWWS.js} +10 -10
- package/dist/chunk-BZMOEWWS.js.map +1 -0
- package/dist/{chunk-DSDZ5T4P.cjs → chunk-D5LQMRPU.cjs} +5 -5
- package/dist/{chunk-DSDZ5T4P.cjs.map → chunk-D5LQMRPU.cjs.map} +1 -1
- package/dist/{chunk-CORIBKHG.js → chunk-EGXCWZYP.js} +2 -2
- package/dist/{chunk-5EYRXSY5.cjs → chunk-EJQUYZXF.cjs} +9 -9
- package/dist/{chunk-5EYRXSY5.cjs.map → chunk-EJQUYZXF.cjs.map} +1 -1
- package/dist/{chunk-P4WTZU6L.cjs → chunk-FY5XAW3H.cjs} +11 -11
- package/dist/{chunk-P4WTZU6L.cjs.map → chunk-FY5XAW3H.cjs.map} +1 -1
- package/dist/{chunk-VQ523ORK.cjs → chunk-GMPYR3MX.cjs} +26 -26
- package/dist/{chunk-VQ523ORK.cjs.map → chunk-GMPYR3MX.cjs.map} +1 -1
- package/dist/{chunk-QSCHCZL3.cjs → chunk-GUTYUMGV.cjs} +7 -7
- package/dist/{chunk-QSCHCZL3.cjs.map → chunk-GUTYUMGV.cjs.map} +1 -1
- package/dist/{chunk-Q6E7VJ4W.cjs → chunk-IEZ3YBAP.cjs} +27 -28
- package/dist/chunk-IEZ3YBAP.cjs.map +1 -0
- package/dist/{chunk-HSACATCD.js → chunk-MPYDX5WX.js} +2 -2
- package/dist/{chunk-RQLBHKXN.js → chunk-NGEFYPY7.js} +2 -2
- package/dist/{chunk-BE6DK7QY.js → chunk-OQIMH2WQ.js} +8985 -11081
- package/dist/chunk-OQIMH2WQ.js.map +1 -0
- package/dist/{chunk-CSYSYJCF.cjs → chunk-UZZT65PQ.cjs} +37 -37
- package/dist/{chunk-CSYSYJCF.cjs.map → chunk-UZZT65PQ.cjs.map} +1 -1
- package/dist/{chunk-YZ2OIYQ3.js → chunk-VDZO6IDR.js} +4 -4
- package/dist/{chunk-UUYRJPGJ.js → chunk-VL2YMDPH.js} +4 -4
- package/dist/{chunk-5LMGFI4J.cjs → chunk-VUXNXWOQ.cjs} +4946 -7042
- package/dist/chunk-VUXNXWOQ.cjs.map +1 -0
- package/dist/{chunk-XQ2B74SI.js → chunk-WLM3F3WU.js} +2 -2
- 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/guide-display.d.ts +14 -0
- package/dist/components/chat/guide-display.d.ts.map +1 -0
- package/dist/components/chat/hooks/index.d.ts +1 -0
- 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-nats-chat-adapter.d.ts +48 -15
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +6 -0
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -0
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +57 -10
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -8
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.d.ts +1 -1
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +15 -21
- package/dist/components/chat/types/api.types.d.ts +81 -1
- package/dist/components/chat/types/api.types.d.ts.map +1 -1
- package/dist/components/chat/types/component.types.d.ts +6 -0
- package/dist/components/chat/types/component.types.d.ts.map +1 -1
- package/dist/components/chat/types/message.types.d.ts +15 -2
- package/dist/components/chat/types/message.types.d.ts.map +1 -1
- package/dist/components/chat/types/processing.types.d.ts +93 -2
- package/dist/components/chat/types/processing.types.d.ts.map +1 -1
- package/dist/components/chat/utils/chunk-parser.d.ts +25 -0
- package/dist/components/chat/utils/chunk-parser.d.ts.map +1 -0
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +6 -34
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
- package/dist/components/chat/utils/index.d.ts +3 -2
- package/dist/components/chat/utils/index.d.ts.map +1 -1
- package/dist/components/chat/utils/message-segment-accumulator.d.ts +5 -0
- package/dist/components/chat/utils/message-segment-accumulator.d.ts.map +1 -1
- package/dist/components/chat/utils/process-historical-messages.d.ts +11 -59
- 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 +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +130 -170
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +23 -63
- package/dist/components/index.js.map +1 -1
- 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 +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -42
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +2 -1
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +15 -55
- package/dist/components/ui/rich-markdown-renderer.d.ts +34 -0
- package/dist/components/ui/rich-markdown-renderer.d.ts.map +1 -0
- package/dist/components/ui/simple-markdown-renderer.d.ts +73 -0
- package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -0
- package/dist/index.cjs +2 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -71
- package/dist/utils/index.cjs +40 -169
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +41 -162
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
- package/package.json +1 -7
- package/src/components/chat/__tests__/chat-message-list.test.tsx +5 -293
- package/src/components/chat/chat-message-enhanced.tsx +80 -163
- package/src/components/chat/chat-message-list.tsx +109 -358
- package/src/components/chat/embeddable-chat.tsx +0 -6
- package/src/components/chat/guide-display.tsx +44 -0
- package/src/components/chat/hooks/.index.md +33 -30
- package/src/components/chat/hooks/.use-nats-chat-adapter.md +55 -36
- package/src/components/chat/hooks/.use-realtime-chunk-processor.md +77 -0
- package/src/components/chat/hooks/index.ts +1 -0
- package/src/components/chat/hooks/use-chat.ts +0 -8
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +825 -243
- package/src/components/chat/hooks/use-realtime-chunk-processor.ts +489 -0
- package/src/components/chat/hooks/use-sse-chat-adapter.ts +684 -380
- package/src/components/chat/index.ts +1 -5
- package/src/components/chat/thinking-display.tsx +1 -1
- package/src/components/chat/types/.api.types.md +49 -39
- package/src/components/chat/types/.processing.types.md +58 -29
- package/src/components/chat/types/api.types.ts +73 -6
- package/src/components/chat/types/component.types.ts +9 -0
- package/src/components/chat/types/message.types.ts +17 -1
- package/src/components/chat/types/processing.types.ts +53 -11
- package/src/components/chat/utils/.chunk-parser.md +62 -0
- package/src/components/chat/utils/.index.md +40 -31
- package/src/components/chat/utils/chunk-parser.ts +262 -0
- package/src/components/chat/utils/extract-incomplete-message-state.ts +5 -63
- package/src/components/chat/utils/index.ts +8 -5
- package/src/components/chat/utils/message-segment-accumulator.ts +19 -0
- package/src/components/chat/utils/process-historical-messages.ts +390 -352
- package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +4 -22
- package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
- package/src/components/shared/product-release/release-detail-page.tsx +4 -19
- package/src/components/ui/.simple-markdown-renderer.md +52 -0
- package/src/components/ui/index.ts +2 -1
- package/src/components/ui/release-changelog-section.tsx +1 -1
- package/src/components/ui/rich-markdown-renderer.tsx +1223 -0
- package/src/components/ui/simple-markdown-renderer.tsx +964 -0
- package/src/components/ui/ticket-info-section.tsx +1 -1
- package/src/stories/ChatMessageEnhanced.stories.tsx +48 -1
- package/src/utils/index.ts +0 -1
- package/src/utils/markdown-section-extractor.ts +56 -41
- package/dist/chat-protocol/decode.d.ts +0 -58
- package/dist/chat-protocol/decode.d.ts.map +0 -1
- package/dist/chat-protocol/encode.d.ts +0 -44
- package/dist/chat-protocol/encode.d.ts.map +0 -1
- package/dist/chat-protocol/env-flag.d.ts +0 -35
- package/dist/chat-protocol/env-flag.d.ts.map +0 -1
- package/dist/chat-protocol/events.d.ts +0 -196
- package/dist/chat-protocol/events.d.ts.map +0 -1
- package/dist/chat-protocol/frames.d.ts +0 -213
- package/dist/chat-protocol/frames.d.ts.map +0 -1
- package/dist/chat-protocol/index.cjs +0 -494
- package/dist/chat-protocol/index.cjs.map +0 -1
- package/dist/chat-protocol/index.d.ts +0 -18
- package/dist/chat-protocol/index.d.ts.map +0 -1
- package/dist/chat-protocol/index.js +0 -478
- package/dist/chat-protocol/index.js.map +0 -1
- package/dist/chat-protocol/ip-normalize.d.ts +0 -44
- package/dist/chat-protocol/ip-normalize.d.ts.map +0 -1
- package/dist/chat-protocol/nats-decoder.d.ts +0 -26
- package/dist/chat-protocol/nats-decoder.d.ts.map +0 -1
- package/dist/chunk-5LMGFI4J.cjs.map +0 -1
- package/dist/chunk-BE6DK7QY.js.map +0 -1
- package/dist/chunk-Q6E7VJ4W.cjs.map +0 -1
- package/dist/chunk-T2EGSZFN.js.map +0 -1
- package/dist/chunk-TKN5667N.js.map +0 -1
- package/dist/chunk-YHOIAA2E.cjs.map +0 -1
- package/dist/components/chat/stream/chat-dialog-store.d.ts +0 -184
- package/dist/components/chat/stream/chat-dialog-store.d.ts.map +0 -1
- package/dist/components/chat/stream/chat-stream-reducer.d.ts +0 -367
- package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +0 -1
- package/dist/components/chat/stream/delta-batcher.d.ts +0 -51
- package/dist/components/chat/stream/delta-batcher.d.ts.map +0 -1
- package/dist/components/chat/stream/index.d.ts +0 -17
- package/dist/components/chat/stream/index.d.ts.map +0 -1
- package/dist/components/chat/stream/message-mutations.d.ts +0 -77
- package/dist/components/chat/stream/message-mutations.d.ts.map +0 -1
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +0 -22
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +0 -1
- package/dist/components/ui/markdown/base-components.d.ts +0 -51
- package/dist/components/ui/markdown/base-components.d.ts.map +0 -1
- package/dist/components/ui/markdown/engine.d.ts +0 -99
- package/dist/components/ui/markdown/engine.d.ts.map +0 -1
- package/dist/components/ui/markdown/heading-ids.d.ts +0 -65
- package/dist/components/ui/markdown/heading-ids.d.ts.map +0 -1
- package/dist/components/ui/markdown/index.d.ts +0 -18
- package/dist/components/ui/markdown/index.d.ts.map +0 -1
- package/dist/components/ui/markdown/mermaid-diagram.d.ts +0 -79
- package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +0 -1
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts +0 -14
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +0 -1
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +0 -40
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +0 -1
- package/dist/components/ui/markdown/rich/shortcodes.d.ts +0 -8
- package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +0 -1
- package/dist/components/ui/markdown/sanitize.d.ts +0 -153
- package/dist/components/ui/markdown/sanitize.d.ts.map +0 -1
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +0 -23
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +0 -1
- package/dist/components/ui/markdown/streaming.d.ts +0 -78
- package/dist/components/ui/markdown/streaming.d.ts.map +0 -1
- package/dist/components/ui/markdown/text-size.d.ts +0 -34
- package/dist/components/ui/markdown/text-size.d.ts.map +0 -1
- package/dist/utils/markdown-fences.d.ts +0 -42
- package/dist/utils/markdown-fences.d.ts.map +0 -1
- package/dist/utils/markdown-heading-id.d.ts +0 -85
- package/dist/utils/markdown-heading-id.d.ts.map +0 -1
- package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +0 -307
- package/src/chat-protocol/__tests__/chat-protocol.test.ts +0 -516
- package/src/chat-protocol/__tests__/env-flag.test.ts +0 -52
- package/src/chat-protocol/__tests__/ip-normalize.test.ts +0 -136
- package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +0 -228
- package/src/chat-protocol/decode.ts +0 -278
- package/src/chat-protocol/encode.ts +0 -71
- package/src/chat-protocol/env-flag.ts +0 -39
- package/src/chat-protocol/events.ts +0 -232
- package/src/chat-protocol/frames.ts +0 -245
- package/src/chat-protocol/index.ts +0 -21
- package/src/chat-protocol/ip-normalize.ts +0 -146
- package/src/chat-protocol/nats-decoder.ts +0 -252
- package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +0 -207
- package/src/components/chat/__tests__/chat-pending-turn.test.tsx +0 -209
- package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +0 -37
- package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
- package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +0 -438
- package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +0 -318
- package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +0 -940
- package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +0 -756
- package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +0 -460
- package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +0 -894
- package/src/components/chat/stream/__tests__/delta-batcher.test.ts +0 -255
- package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +0 -98
- package/src/components/chat/stream/chat-dialog-store.ts +0 -536
- package/src/components/chat/stream/chat-stream-reducer.ts +0 -1796
- package/src/components/chat/stream/delta-batcher.ts +0 -159
- package/src/components/chat/stream/index.ts +0 -55
- package/src/components/chat/stream/message-mutations.ts +0 -338
- package/src/components/chat/stream/use-chat-stream-reducer.ts +0 -126
- package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +0 -420
- package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +0 -605
- package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +0 -317
- package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +0 -270
- package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +0 -2420
- package/src/components/ui/__tests__/markdown-parity.test.tsx +0 -2528
- package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +0 -115
- package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +0 -95
- package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +0 -309
- package/src/components/ui/markdown/__tests__/streaming.test.tsx +0 -388
- package/src/components/ui/markdown/base-components.tsx +0 -360
- package/src/components/ui/markdown/engine.tsx +0 -315
- package/src/components/ui/markdown/heading-ids.ts +0 -239
- package/src/components/ui/markdown/index.ts +0 -49
- package/src/components/ui/markdown/mermaid-diagram.tsx +0 -291
- package/src/components/ui/markdown/rich/embed-overrides.tsx +0 -199
- package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +0 -184
- package/src/components/ui/markdown/rich/shortcodes.ts +0 -170
- package/src/components/ui/markdown/sanitize.ts +0 -3499
- package/src/components/ui/markdown/simple-markdown-renderer.tsx +0 -28
- package/src/components/ui/markdown/streaming.ts +0 -362
- package/src/components/ui/markdown/text-size.ts +0 -106
- package/src/utils/markdown-fences.ts +0 -127
- package/src/utils/markdown-heading-id.ts +0 -348
- /package/dist/{chunk-GTWO5NAY.js.map → chunk-6CFFISUC.js.map} +0 -0
- /package/dist/{chunk-VHG6AX5V.js.map → chunk-6CJ2K7BD.js.map} +0 -0
- /package/dist/{chunk-4NWARV5I.js.map → chunk-6QK3ONDD.js.map} +0 -0
- /package/dist/{chunk-CORIBKHG.js.map → chunk-EGXCWZYP.js.map} +0 -0
- /package/dist/{chunk-HSACATCD.js.map → chunk-MPYDX5WX.js.map} +0 -0
- /package/dist/{chunk-RQLBHKXN.js.map → chunk-NGEFYPY7.js.map} +0 -0
- /package/dist/{chunk-YZ2OIYQ3.js.map → chunk-VDZO6IDR.js.map} +0 -0
- /package/dist/{chunk-UUYRJPGJ.js.map → chunk-VL2YMDPH.js.map} +0 -0
- /package/dist/{chunk-XQ2B74SI.js.map → chunk-WLM3F3WU.js.map} +0 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for parsing NATS chunks into structured actions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { MESSAGE_TYPE, type ChunkData, type ParsedChunkAction, type ToolExecutionSegment, type PendingToolCallData } from '../types'
|
|
6
|
+
|
|
7
|
+
function normalizeToolCalls(raw: unknown): PendingToolCallData[] {
|
|
8
|
+
if (!Array.isArray(raw)) return []
|
|
9
|
+
return raw
|
|
10
|
+
.filter((item): item is Record<string, any> => !!item && typeof item === 'object')
|
|
11
|
+
.map((item) => ({
|
|
12
|
+
toolExecutionRequestId: String(item.toolExecutionRequestId ?? ''),
|
|
13
|
+
toolName: String(item.toolName ?? ''),
|
|
14
|
+
toolTitle: typeof item.toolTitle === 'string' ? item.toolTitle : undefined,
|
|
15
|
+
toolExplanation: typeof item.toolExplanation === 'string' ? item.toolExplanation : undefined,
|
|
16
|
+
toolType: typeof item.toolType === 'string' ? item.toolType : undefined,
|
|
17
|
+
requiresApproval: item.requiresApproval === true,
|
|
18
|
+
approvalType: typeof item.approvalType === 'string' ? item.approvalType : null,
|
|
19
|
+
toolCallArguments:
|
|
20
|
+
item.toolCallArguments && typeof item.toolCallArguments === 'object'
|
|
21
|
+
? (item.toolCallArguments as Record<string, any>)
|
|
22
|
+
: null,
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parse a raw NATS chunk into a structured action
|
|
28
|
+
*/
|
|
29
|
+
export function parseChunkToAction(chunk: unknown): ParsedChunkAction | null {
|
|
30
|
+
if (!chunk || typeof chunk !== 'object') return null
|
|
31
|
+
|
|
32
|
+
const data = chunk as ChunkData
|
|
33
|
+
const type = String(data.type || '')
|
|
34
|
+
|
|
35
|
+
switch (type) {
|
|
36
|
+
case MESSAGE_TYPE.MESSAGE_START:
|
|
37
|
+
return { action: 'message_start' }
|
|
38
|
+
|
|
39
|
+
case MESSAGE_TYPE.MESSAGE_END:
|
|
40
|
+
return { action: 'message_end' }
|
|
41
|
+
|
|
42
|
+
case MESSAGE_TYPE.AI_METADATA: {
|
|
43
|
+
const providerName = data.providerName || data.provider
|
|
44
|
+
if (typeof data.modelName === 'string' && typeof providerName === 'string') {
|
|
45
|
+
return {
|
|
46
|
+
action: 'metadata',
|
|
47
|
+
modelDisplayName: data.modelDisplayName,
|
|
48
|
+
modelName: data.modelName,
|
|
49
|
+
providerName,
|
|
50
|
+
contextWindow: typeof data.contextWindow === 'number' ? data.contextWindow : 0,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
case MESSAGE_TYPE.TEXT:
|
|
57
|
+
if (typeof data.text === 'string') {
|
|
58
|
+
return { action: 'text', text: data.text }
|
|
59
|
+
}
|
|
60
|
+
return null
|
|
61
|
+
|
|
62
|
+
case MESSAGE_TYPE.THINKING:
|
|
63
|
+
if (typeof data.text === 'string') {
|
|
64
|
+
return { action: 'thinking', text: data.text }
|
|
65
|
+
}
|
|
66
|
+
return null
|
|
67
|
+
|
|
68
|
+
case MESSAGE_TYPE.GUIDE:
|
|
69
|
+
if (typeof data.text === 'string') {
|
|
70
|
+
return { action: 'guide', text: data.text }
|
|
71
|
+
}
|
|
72
|
+
return null
|
|
73
|
+
|
|
74
|
+
case MESSAGE_TYPE.EXECUTING_TOOL:
|
|
75
|
+
return {
|
|
76
|
+
action: 'tool_execution',
|
|
77
|
+
segment: {
|
|
78
|
+
type: 'tool_execution',
|
|
79
|
+
data: {
|
|
80
|
+
type: 'EXECUTING_TOOL',
|
|
81
|
+
integratedToolType: data.integratedToolType || '',
|
|
82
|
+
toolFunction: data.toolFunction || '',
|
|
83
|
+
toolTitle: typeof data.title === 'string' ? data.title : undefined,
|
|
84
|
+
toolExplanation: typeof data.toolExplanation === 'string' ? data.toolExplanation : undefined,
|
|
85
|
+
parameters: data.parameters,
|
|
86
|
+
toolExecutionRequestId: typeof data.toolExecutionRequestId === 'string' ? data.toolExecutionRequestId : undefined,
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case MESSAGE_TYPE.EXECUTED_TOOL:
|
|
92
|
+
return {
|
|
93
|
+
action: 'tool_execution',
|
|
94
|
+
segment: {
|
|
95
|
+
type: 'tool_execution',
|
|
96
|
+
data: {
|
|
97
|
+
type: 'EXECUTED_TOOL',
|
|
98
|
+
integratedToolType: data.integratedToolType || '',
|
|
99
|
+
toolFunction: data.toolFunction || '',
|
|
100
|
+
toolTitle: typeof data.title === 'string' ? data.title : undefined,
|
|
101
|
+
parameters: data.parameters,
|
|
102
|
+
result: data.result,
|
|
103
|
+
success: data.success,
|
|
104
|
+
toolExecutionRequestId: typeof data.toolExecutionRequestId === 'string' ? data.toolExecutionRequestId : undefined,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case MESSAGE_TYPE.APPROVAL_REQUEST: {
|
|
110
|
+
const requestId = data.approvalRequestId || data.approval_request_id || ''
|
|
111
|
+
const approvalType = data.approvalType || 'USER'
|
|
112
|
+
const toolCalls = normalizeToolCalls(data.toolCalls)
|
|
113
|
+
|
|
114
|
+
if (toolCalls.length > 0) {
|
|
115
|
+
return {
|
|
116
|
+
action: 'approval_batch',
|
|
117
|
+
requestId,
|
|
118
|
+
approvalType,
|
|
119
|
+
toolCalls,
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
action: 'approval_request',
|
|
125
|
+
requestId,
|
|
126
|
+
command: data.command || '',
|
|
127
|
+
explanation: data.explanation,
|
|
128
|
+
approvalType,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case MESSAGE_TYPE.APPROVAL_RESULT: {
|
|
133
|
+
// The realtime NATS chunk carries the resolver's name as `displayName`; the
|
|
134
|
+
// persisted GraphQL message exposes the same value as `resolvedByName`. Accept
|
|
135
|
+
// either so realtime and history-replay render "by {name}" identically.
|
|
136
|
+
const resolvedByName =
|
|
137
|
+
typeof data.resolvedByName === 'string'
|
|
138
|
+
? data.resolvedByName
|
|
139
|
+
: typeof data.displayName === 'string'
|
|
140
|
+
? data.displayName
|
|
141
|
+
: undefined
|
|
142
|
+
return {
|
|
143
|
+
action: 'approval_result',
|
|
144
|
+
requestId: data.approvalRequestId || data.approval_request_id || '',
|
|
145
|
+
approved: data.approved === true,
|
|
146
|
+
approvalType: data.approvalType || 'CLIENT',
|
|
147
|
+
resolvedByName,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
case MESSAGE_TYPE.ERROR:
|
|
152
|
+
return {
|
|
153
|
+
action: 'error',
|
|
154
|
+
error: data.error || 'An error occurred',
|
|
155
|
+
details: data.details,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
case MESSAGE_TYPE.MESSAGE_REQUEST:
|
|
159
|
+
return {
|
|
160
|
+
action: 'message_request',
|
|
161
|
+
text: String(data.text || ''),
|
|
162
|
+
ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
|
|
163
|
+
displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
|
|
164
|
+
userId: typeof data.userId === 'string' ? data.userId : undefined,
|
|
165
|
+
// Entity-context refs the user attached to this message (backend
|
|
166
|
+
// `MESSAGE_REQUEST` chunk → `contextItems: [{ type, id }]`). The wire
|
|
167
|
+
// shape carries no label; the host resolves display text + icon. `label`
|
|
168
|
+
// is REQUIRED on `ChatContextItem`, so fall back to the id (same as the
|
|
169
|
+
// historical path in `process-historical-messages.ts`) — keeps both
|
|
170
|
+
// message sources producing an identical shape.
|
|
171
|
+
contextItems: Array.isArray(data.contextItems)
|
|
172
|
+
? (data.contextItems as Array<{ type?: unknown; id?: unknown }>)
|
|
173
|
+
.filter((it) => typeof it?.type === 'string' && typeof it?.id === 'string')
|
|
174
|
+
.map((it) => ({ type: it.type as string, id: it.id as string, label: it.id as string }))
|
|
175
|
+
: undefined,
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case MESSAGE_TYPE.TOKEN_USAGE:
|
|
179
|
+
return {
|
|
180
|
+
action: 'token_usage',
|
|
181
|
+
data: {
|
|
182
|
+
inputTokensSize: data.inputTokensSize ?? 0,
|
|
183
|
+
outputTokensSize: data.outputTokensSize ?? 0,
|
|
184
|
+
totalTokensSize: data.totalTokensSize ?? 0,
|
|
185
|
+
contextSize: data.contextSize ?? 0,
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
case MESSAGE_TYPE.CONTEXT_COMPACTION_START:
|
|
190
|
+
return { action: 'context_compaction_start' }
|
|
191
|
+
|
|
192
|
+
case MESSAGE_TYPE.CONTEXT_COMPACTION_END:
|
|
193
|
+
return {
|
|
194
|
+
action: 'context_compaction_end',
|
|
195
|
+
summary: typeof data.text === 'string' ? data.text : undefined,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
case MESSAGE_TYPE.SYSTEM:
|
|
199
|
+
if (typeof data.text === 'string') {
|
|
200
|
+
return { action: 'system', text: data.text }
|
|
201
|
+
}
|
|
202
|
+
return null
|
|
203
|
+
|
|
204
|
+
case MESSAGE_TYPE.DIRECT_MESSAGE:
|
|
205
|
+
if (typeof data.text === 'string') {
|
|
206
|
+
return {
|
|
207
|
+
action: 'direct_message',
|
|
208
|
+
text: data.text,
|
|
209
|
+
ownerType: typeof data.ownerType === 'string' ? data.ownerType : undefined,
|
|
210
|
+
displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
|
|
211
|
+
userId: typeof data.userId === 'string' ? data.userId : undefined,
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return null
|
|
215
|
+
|
|
216
|
+
case MESSAGE_TYPE.DIALOG_CLOSED:
|
|
217
|
+
return { action: 'dialog_closed' }
|
|
218
|
+
|
|
219
|
+
default:
|
|
220
|
+
return null
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Check if a chunk represents a control message (start/end)
|
|
226
|
+
*/
|
|
227
|
+
export function isControlChunk(chunk: unknown): boolean {
|
|
228
|
+
if (!chunk || typeof chunk !== 'object') return false
|
|
229
|
+
const data = chunk as ChunkData
|
|
230
|
+
const type = String(data.type || '')
|
|
231
|
+
return type === MESSAGE_TYPE.MESSAGE_START || type === MESSAGE_TYPE.MESSAGE_END
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Check if a chunk represents an error
|
|
236
|
+
*/
|
|
237
|
+
export function isErrorChunk(chunk: unknown): boolean {
|
|
238
|
+
if (!chunk || typeof chunk !== 'object') return false
|
|
239
|
+
const data = chunk as ChunkData
|
|
240
|
+
return data.type === MESSAGE_TYPE.ERROR
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Check if a chunk represents metadata
|
|
245
|
+
*/
|
|
246
|
+
export function isMetadataChunk(chunk: unknown): boolean {
|
|
247
|
+
if (!chunk || typeof chunk !== 'object') return false
|
|
248
|
+
const data = chunk as ChunkData
|
|
249
|
+
return data.type === MESSAGE_TYPE.AI_METADATA
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Extract text content from a chunk if it's a text chunk
|
|
254
|
+
*/
|
|
255
|
+
export function extractTextFromChunk(chunk: unknown): string | null {
|
|
256
|
+
if (!chunk || typeof chunk !== 'object') return null
|
|
257
|
+
const data = chunk as ChunkData
|
|
258
|
+
if (data.type === MESSAGE_TYPE.TEXT && typeof data.text === 'string') {
|
|
259
|
+
return data.text
|
|
260
|
+
}
|
|
261
|
+
return null
|
|
262
|
+
}
|
|
@@ -9,18 +9,6 @@ import type {
|
|
|
9
9
|
PendingApproval,
|
|
10
10
|
ExecutingToolState,
|
|
11
11
|
} from '../types'
|
|
12
|
-
import type { InitializeExtras } from '../stream/chat-stream-reducer'
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* What the realtime accumulator needs to RESUME an unfinished turn.
|
|
16
|
-
*
|
|
17
|
-
* DERIVED, not restated: this is exactly the reducer's `InitializeExtras`
|
|
18
|
-
* minus `escalatedApprovals` (which only the live stream can produce — it has
|
|
19
|
-
* no historical representation to extract). Hosts pass the result straight
|
|
20
|
-
* into `reducer.initializeWithState(messages, extras)`, so the two must not
|
|
21
|
-
* drift; a structural coincidence is not a contract.
|
|
22
|
-
*/
|
|
23
|
-
export type IncompleteMessageState = Omit<InitializeExtras, 'escalatedApprovals'>
|
|
24
12
|
|
|
25
13
|
/**
|
|
26
14
|
* Extract incomplete message state from the last historical assistant message
|
|
@@ -28,7 +16,11 @@ export type IncompleteMessageState = Omit<InitializeExtras, 'escalatedApprovals'
|
|
|
28
16
|
*/
|
|
29
17
|
export function extractIncompleteMessageState(
|
|
30
18
|
lastMessage: ProcessedMessage | undefined
|
|
31
|
-
):
|
|
19
|
+
): {
|
|
20
|
+
existingSegments?: MessageSegment[]
|
|
21
|
+
pendingApprovals?: Map<string, PendingApproval>
|
|
22
|
+
executingTools?: Map<string, ExecutingToolState>
|
|
23
|
+
} | undefined {
|
|
32
24
|
if (!lastMessage || lastMessage.role !== 'assistant' || typeof lastMessage.content === 'string') {
|
|
33
25
|
return undefined
|
|
34
26
|
}
|
|
@@ -100,54 +92,4 @@ export function extractIncompleteMessageState(
|
|
|
100
92
|
pendingApprovals: pendingApprovals.size > 0 ? pendingApprovals : undefined,
|
|
101
93
|
executingTools: executingTools.size > 0 ? executingTools : undefined,
|
|
102
94
|
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* THREAD-level generalization of `extractIncompleteMessageState`: given a
|
|
107
|
-
* processed thread, look at the TRAILING RUN of consecutive assistant
|
|
108
|
-
* messages (not just the very last row), flatten it to one segment list, and
|
|
109
|
-
* ask the single-message extractor whether that tail is unfinished.
|
|
110
|
-
*
|
|
111
|
-
* Why the run and not the last row: the backend can split one logical turn
|
|
112
|
-
* across several assistant messages (a preamble bubble, then the approval
|
|
113
|
-
* card, then the continuation). The unfinished artifact — a pending approval,
|
|
114
|
-
* an EXECUTING_TOOL with no result, an open compaction — can therefore sit in
|
|
115
|
-
* an EARLIER bubble of the same trailing run, and a last-row-only check
|
|
116
|
-
* reports "complete" while the turn is very much still in flight.
|
|
117
|
-
*
|
|
118
|
-
* SSOT for every "is the tail incomplete?" question — the NATS adapter (which
|
|
119
|
-
* used to inline the single-row check) and hosts replaying a stored thread
|
|
120
|
-
* both call this instead of re-deriving the walk.
|
|
121
|
-
*
|
|
122
|
-
* A trailing non-assistant row (user / error) means the last turn closed →
|
|
123
|
-
* `undefined`.
|
|
124
|
-
*/
|
|
125
|
-
export function extractIncompleteTailState(
|
|
126
|
-
messages: readonly ProcessedMessage[] | undefined,
|
|
127
|
-
): IncompleteMessageState | undefined {
|
|
128
|
-
if (!messages || messages.length === 0) return undefined
|
|
129
|
-
|
|
130
|
-
// Walk back over the trailing consecutive assistant run.
|
|
131
|
-
let start = messages.length
|
|
132
|
-
while (start > 0 && messages[start - 1]?.role === 'assistant') start -= 1
|
|
133
|
-
if (start === messages.length) return undefined
|
|
134
|
-
|
|
135
|
-
const segments: MessageSegment[] = []
|
|
136
|
-
for (let i = start; i < messages.length; i += 1) {
|
|
137
|
-
const content = messages[i]?.content
|
|
138
|
-
// A string-content assistant row is a plain-text bubble with nothing to
|
|
139
|
-
// resume; skip it rather than aborting — a later row in the same run may
|
|
140
|
-
// still hold the unfinished segment.
|
|
141
|
-
if (Array.isArray(content)) segments.push(...(content as MessageSegment[]))
|
|
142
|
-
}
|
|
143
|
-
if (segments.length === 0) return undefined
|
|
144
|
-
|
|
145
|
-
// Reuse the single-message extractor verbatim by handing it a synthetic
|
|
146
|
-
// assistant row carrying the flattened run — one incompleteness rule set,
|
|
147
|
-
// not two.
|
|
148
|
-
return extractIncompleteMessageState({
|
|
149
|
-
...messages[messages.length - 1],
|
|
150
|
-
role: 'assistant',
|
|
151
|
-
content: segments,
|
|
152
|
-
} as ProcessedMessage)
|
|
153
95
|
}
|
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
* Export all utilities for processing chat messages
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Chunk parsing utilities
|
|
7
|
+
export {
|
|
8
|
+
parseChunkToAction,
|
|
9
|
+
isControlChunk,
|
|
10
|
+
isErrorChunk,
|
|
11
|
+
isMetadataChunk,
|
|
12
|
+
extractTextFromChunk,
|
|
13
|
+
} from './chunk-parser'
|
|
9
14
|
|
|
10
15
|
// Segment accumulator
|
|
11
16
|
export {
|
|
@@ -19,13 +24,11 @@ export {
|
|
|
19
24
|
processHistoricalMessages,
|
|
20
25
|
extractErrorMessages,
|
|
21
26
|
processHistoricalMessagesWithErrors,
|
|
22
|
-
decodeHistoricalMessageData,
|
|
23
27
|
} from './process-historical-messages'
|
|
24
28
|
|
|
25
29
|
// Incomplete message state extraction
|
|
26
30
|
export {
|
|
27
31
|
extractIncompleteMessageState,
|
|
28
|
-
extractIncompleteTailState,
|
|
29
32
|
} from './extract-incomplete-message-state'
|
|
30
33
|
|
|
31
34
|
// History <-> realtime reconciliation
|
|
@@ -139,6 +139,22 @@ export class MessageSegmentAccumulator {
|
|
|
139
139
|
return this.getSegments()
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Append guide text to the current message.
|
|
144
|
+
* If the last segment is guide, append to it; otherwise start a new guide segment.
|
|
145
|
+
*/
|
|
146
|
+
appendGuide(text: string): MessageSegment[] {
|
|
147
|
+
const lastSegment = this.segments[this.segments.length - 1]
|
|
148
|
+
|
|
149
|
+
if (lastSegment && lastSegment.type === 'guide') {
|
|
150
|
+
this.segments[this.segments.length - 1] = { type: 'guide', text: lastSegment.text + text }
|
|
151
|
+
} else {
|
|
152
|
+
this.segments.push({ type: 'guide', text })
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return this.getSegments()
|
|
156
|
+
}
|
|
157
|
+
|
|
142
158
|
/**
|
|
143
159
|
* Add a tool execution segment.
|
|
144
160
|
*
|
|
@@ -516,6 +532,9 @@ export class MessageSegmentAccumulator {
|
|
|
516
532
|
case 'thinking':
|
|
517
533
|
if (segment.text) this.appendThinking(segment.text)
|
|
518
534
|
break
|
|
535
|
+
case 'guide':
|
|
536
|
+
if (segment.text) this.appendGuide(segment.text)
|
|
537
|
+
break
|
|
519
538
|
case 'tool_execution':
|
|
520
539
|
this.addToolExecution(segment)
|
|
521
540
|
break
|