flare-chat-core 0.2.2 → 0.2.4

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 (122) hide show
  1. package/dist/index.js +6343 -0
  2. package/package.json +19 -22
  3. package/docs/CAPABILITY-INVENTORY.md +0 -42
  4. package/docs/CHAT-CORE-BOUNDARY.md +0 -47
  5. package/docs/CORE-APP-REALIGNMENT-WORKLOAD-2026-04-18.md +0 -86
  6. package/docs/SSOT-CHAT-CORE-BOUNDARY.md +0 -73
  7. package/docs/SSOT-CHAT-CORE-DATAFLOW.md +0 -97
  8. package/index.html +0 -12
  9. package/scripts/check.sh +0 -15
  10. package/src/adapters/index.js +0 -6
  11. package/src/adapters/message-api.adapter.js +0 -59
  12. package/src/adapters/session-api.adapter.js +0 -133
  13. package/src/adapters/session-message-api.http.js +0 -161
  14. package/src/adapters/session-message-api.js +0 -34
  15. package/src/adapters/session-message-api.normalize-source-record.test.mjs +0 -180
  16. package/src/adapters/session-message-api.normalizers.js +0 -153
  17. package/src/adapters/source-api.adapter.js +0 -135
  18. package/src/adapters/sse-client.js +0 -244
  19. package/src/adapters/sse-event-dispatcher.js +0 -121
  20. package/src/app/App.jsx +0 -11
  21. package/src/app/AppProviders.jsx +0 -12
  22. package/src/app/ChatWorkspaceScreen.jsx +0 -33
  23. package/src/app/WorkspaceLayout.jsx +0 -125
  24. package/src/app/components/AppCanvasPanel.jsx +0 -64
  25. package/src/app/components/TriggerThresholdPopoverContent.jsx +0 -122
  26. package/src/app/components/WorkspaceBodySection.jsx +0 -109
  27. package/src/app/components/WorkspaceMainPane.jsx +0 -113
  28. package/src/app/components/WorkspaceSessionPane.jsx +0 -48
  29. package/src/app/components/WorkspaceTopBarSection.jsx +0 -65
  30. package/src/app/core-chat-entry/ComposerSectionNode.jsx +0 -241
  31. package/src/app/core-chat-entry/attachmentSendRefs.js +0 -154
  32. package/src/app/core-chat-entry/attachmentSendRefs.test.mjs +0 -101
  33. package/src/app/core-chat-entry/composerActionRouter.js +0 -26
  34. package/src/app/core-chat-entry/constants.js +0 -108
  35. package/src/app/core-chat-entry/selectors.js +0 -28
  36. package/src/app/core-chat-entry/useAppActionErrorGuards.js +0 -68
  37. package/src/app/core-chat-entry/useChatCorePipelines.js +0 -110
  38. package/src/app/core-chat-entry/useComposerModeSuggestion.js +0 -89
  39. package/src/app/core-chat-entry/useDevCapabilityStatusNote.js +0 -22
  40. package/src/app/core-chat-entry/useProjectNameEditing.js +0 -41
  41. package/src/app/core-chat-entry/useProjectSourceUpload.js +0 -341
  42. package/src/app/core-chat-entry/useRealApiReadinessGate.js +0 -103
  43. package/src/app/core-chat-entry/useUnavailableActionError.js +0 -29
  44. package/src/app/core-chat-entry/useWorkspaceCanvasController.jsx +0 -177
  45. package/src/app/core-chat-entry/useWorkspaceCanvasProjection.jsx +0 -171
  46. package/src/app/core-chat-entry/useWorkspaceComposerController.jsx +0 -199
  47. package/src/app/core-chat-entry/useWorkspaceController.jsx +0 -226
  48. package/src/app/core-chat-entry/useWorkspacePanels.js +0 -55
  49. package/src/app/hooks/useComposerAttachmentSync.js +0 -223
  50. package/src/app/hooks/useComposerChooserHandlers.js +0 -52
  51. package/src/app/hooks/useSendWithContextRefs.js +0 -140
  52. package/src/app/hooks/useSendWithContextRefs.test.mjs +0 -29
  53. package/src/app/hooks/useUserThresholdProfile.js +0 -121
  54. package/src/app/index.js +0 -1
  55. package/src/app/selectors/assistantTextSelector.js +0 -73
  56. package/src/app/selectors/canvasEvidenceSummarySelector.js +0 -28
  57. package/src/app/selectors/canvasReportTemplateSelector.js +0 -28
  58. package/src/app/selectors/canvasTabsSelector.js +0 -58
  59. package/src/app/selectors/evidenceProjectionSelector.js +0 -175
  60. package/src/app/selectors/evidenceProjectionSelector.test.mjs +0 -107
  61. package/src/app/selectors/modeSuggestionSelector.js +0 -50
  62. package/src/chat-core/app/mockRuntime.js +0 -291
  63. package/src/chat-core/app/useAppStream.js +0 -187
  64. package/src/chat-core/app/useAppStream.refs.test.mjs +0 -44
  65. package/src/chat-core/app/useAppStream.request-body.test.mjs +0 -116
  66. package/src/chat-core/app/useCoreChatApp.js +0 -115
  67. package/src/chat-core/facade/useBasicConversationFacade.js +0 -280
  68. package/src/chat-core/index.js +0 -14
  69. package/src/chat-core/input/useChatInput.js +0 -103
  70. package/src/chat-core/messages/buildTimelineItems.analysis-route.test.mjs +0 -36
  71. package/src/chat-core/messages/buildTimelineItems.js +0 -233
  72. package/src/chat-core/messages/buildTimelineItems.knowledge-citation.test.mjs +0 -183
  73. package/src/chat-core/messages/contextUsageDefaults.js +0 -3
  74. package/src/chat-core/messages/contextUsageViewModel.js +0 -147
  75. package/src/chat-core/messages/contextUsageViewModel.test.mjs +0 -74
  76. package/src/chat-core/messages/useContextUsageViewModel.js +0 -41
  77. package/src/chat-core/orchestration/useBasicSendHandler.js +0 -55
  78. package/src/chat-core/pipelines/build-action-request.js +0 -46
  79. package/src/chat-core/pipelines/build-stream-request.js +0 -74
  80. package/src/chat-core/pipelines/entity-extraction.js +0 -159
  81. package/src/chat-core/pipelines/preprocess-message.js +0 -16
  82. package/src/chat-core/pipelines/stream-persist-utils.js +0 -32
  83. package/src/chat-core/pipelines/transport/send-mock-stream.js +0 -86
  84. package/src/chat-core/pipelines/transport/send-real-stream.js +0 -330
  85. package/src/chat-core/pipelines/transport/send-real-stream.test.mjs +0 -27
  86. package/src/chat-core/pipelines/transport/send-sourcing-search.js +0 -86
  87. package/src/chat-core/pipelines/transport/send-sourcing-search.test.mjs +0 -14
  88. package/src/chat-core/pipelines/transport/sourcing-response-templates.js +0 -55
  89. package/src/chat-core/pipelines/transport/sourcing-search-api.js +0 -155
  90. package/src/chat-core/runtime/runtimeMode.js +0 -69
  91. package/src/chat-core/session/chatSessionActionTypes.js +0 -24
  92. package/src/chat-core/session/chatSessionReducer.js +0 -352
  93. package/src/chat-core/session/chatSessionReducer.streaming-done.test.mjs +0 -39
  94. package/src/chat-core/session/index.js +0 -2
  95. package/src/chat-core/session/sessionActionsMessages.js +0 -44
  96. package/src/chat-core/session/sessionActionsSessionCrud.js +0 -131
  97. package/src/chat-core/session/sessionActionsStreaming.js +0 -80
  98. package/src/chat-core/session/sessionActionsUiState.js +0 -51
  99. package/src/chat-core/session/useChatSessionReducer.js +0 -131
  100. package/src/chat-core/session/useSessionListController.js +0 -67
  101. package/src/chat-core/stream/sse-client.js +0 -1
  102. package/src/chat-core/stream/sse-event-dispatcher.js +0 -1
  103. package/src/chat-core/stream/sse-events.js +0 -1
  104. package/src/chat-core/stream/useSSEStream.js +0 -1
  105. package/src/chat-core/stream/useStreamSendController.js +0 -46
  106. package/src/contracts/context-ssot.js +0 -47
  107. package/src/contracts/index.js +0 -1
  108. package/src/contracts/sse-events/base-parsers.js +0 -79
  109. package/src/contracts/sse-events/domain-parsers.js +0 -3
  110. package/src/contracts/sse-events/internal-normalizers.js +0 -143
  111. package/src/contracts/sse-events/parsers-intake.js +0 -235
  112. package/src/contracts/sse-events/parsers-runtime.js +0 -37
  113. package/src/contracts/sse-events/parsers-sourcing.js +0 -179
  114. package/src/contracts/sse-events/patch-event-parser.js +0 -121
  115. package/src/contracts/sse-events/runtime-parsers.js +0 -79
  116. package/src/contracts/sse-events.js +0 -4
  117. package/src/index.js +0 -6
  118. package/src/main.jsx +0 -28
  119. package/src/orchestration/index.js +0 -6
  120. package/src/orchestration/useSSEStream.js +0 -221
  121. package/src/state/index.js +0 -4
  122. package/vite.config.js +0 -36
@@ -1,122 +0,0 @@
1
- import React from 'react';
2
- import { InfoCircleOutlined } from '@ant-design/icons';
3
- import { Divider, Popover, Slider, Space, Switch, Typography } from 'antd';
4
-
5
- const { Text } = Typography;
6
-
7
- export default function TriggerThresholdPopoverContent({
8
- evidenceStrictMode,
9
- setEvidenceStrictMode,
10
- evidenceHitScoreThreshold,
11
- setEvidenceHitScoreThreshold,
12
- languageGuardEnabled,
13
- setLanguageGuardEnabled,
14
- friendlyToneEnabled,
15
- setFriendlyToneEnabled,
16
- questionModeSuggestionEnabled,
17
- setQuestionModeSuggestionEnabled,
18
- }) {
19
- const rowStyle = {
20
- alignItems: 'center',
21
- display: 'flex',
22
- gap: 12,
23
- justifyContent: 'space-between',
24
- minHeight: 32,
25
- };
26
- const leftColumnStyle = {
27
- flex: 1,
28
- minWidth: 0,
29
- };
30
- const rightColumnStyle = {
31
- alignItems: 'center',
32
- display: 'flex',
33
- flexShrink: 0,
34
- gap: 8,
35
- justifyContent: 'flex-end',
36
- minWidth: 116,
37
- };
38
- const infoIconStyle = {
39
- color: 'rgba(0, 0, 0, 0.35)',
40
- cursor: 'pointer',
41
- fontSize: 13,
42
- };
43
- const renderInfoIcon = (description) => (
44
- <Popover
45
- content={<Text style={{ fontSize: 12 }} type="secondary">{description}</Text>}
46
- overlayStyle={{ maxWidth: 280 }}
47
- placement="topLeft"
48
- trigger={['hover', 'click']}
49
- >
50
- <InfoCircleOutlined style={infoIconStyle} />
51
- </Popover>
52
- );
53
-
54
- return (
55
- <div style={{ maxWidth: 320, minWidth: 320, width: 320 }}>
56
- <Space direction="vertical" size={6} style={{ width: '100%' }}>
57
- <Text strong>触发阈值与文案风格</Text>
58
- <div style={rowStyle}>
59
- <div style={leftColumnStyle}>
60
- <Text>证据命中严格模式</Text>
61
- </div>
62
- <div style={rightColumnStyle}>
63
- {renderInfoIcon('开启后:仅在具体语义线索命中时展示证据,不再只靠泛关键词。')}
64
- <Switch checked={evidenceStrictMode} onChange={setEvidenceStrictMode} />
65
- </div>
66
- </div>
67
- <div style={rowStyle}>
68
- <div style={leftColumnStyle}>
69
- <Text>证据分数阈值</Text>
70
- </div>
71
- <div style={rightColumnStyle}>
72
- {renderInfoIcon('开启严格模式后,分数低于阈值的证据不会展示。')}
73
- </div>
74
- </div>
75
- <Text type="secondary" style={{ fontSize: 12, marginTop: -2 }}>
76
- {`当前值:${Number(evidenceHitScoreThreshold || 0).toFixed(2)}`}
77
- </Text>
78
- <div style={{ marginTop: -2 }}>
79
- <Slider
80
- disabled={!evidenceStrictMode}
81
- max={1}
82
- min={0}
83
- onChange={setEvidenceHitScoreThreshold}
84
- step={0.01}
85
- style={{ margin: 0, width: '100%' }}
86
- value={evidenceHitScoreThreshold}
87
- />
88
- </div>
89
- <Divider style={{ margin: '4px 0' }} />
90
- <div style={rowStyle}>
91
- <div style={leftColumnStyle}>
92
- <Text>文案去系统痕迹</Text>
93
- </div>
94
- <div style={rightColumnStyle}>
95
- {renderInfoIcon('开启后:自动隐藏 mode= / goal= / provider_status 等技术痕迹文案。')}
96
- <Switch checked={languageGuardEnabled} onChange={setLanguageGuardEnabled} />
97
- </div>
98
- </div>
99
- <Divider style={{ margin: '4px 0' }} />
100
- <div style={rowStyle}>
101
- <div style={leftColumnStyle}>
102
- <Text>友好回复风格</Text>
103
- </div>
104
- <div style={rightColumnStyle}>
105
- {renderInfoIcon('开启后:自动补充更自然的开头与结尾。')}
106
- <Switch checked={friendlyToneEnabled} onChange={setFriendlyToneEnabled} />
107
- </div>
108
- </div>
109
- <Divider style={{ margin: '4px 0' }} />
110
- <div style={rowStyle}>
111
- <div style={leftColumnStyle}>
112
- <Text>问题回复建议</Text>
113
- </div>
114
- <div style={rightColumnStyle}>
115
- {renderInfoIcon('开启后:当助手提出问题时,统一建议打开梳理模式。')}
116
- <Switch checked={questionModeSuggestionEnabled} onChange={setQuestionModeSuggestionEnabled} />
117
- </div>
118
- </div>
119
- </Space>
120
- </div>
121
- );
122
- }
@@ -1,109 +0,0 @@
1
- import React from 'react';
2
- import {
3
- ChatWorkspaceSourcesPanel,
4
- ChatWorkspaceConversationPane,
5
- ChatWorkspaceProjectInitView,
6
- } from 'flare-chat-ui';
7
-
8
- export default function WorkspaceBodySection({
9
- hasProject,
10
- activeWorkspaceTab,
11
- themeTokens,
12
- projectItems,
13
- resolvedUILabels,
14
- handleCreateProject,
15
- composerNode,
16
- contentMaxWidth,
17
- handleOpenSourcePicker,
18
- handleRemoveSource,
19
- handleRetrySource,
20
- handleViewSourceDetail,
21
- sourceActionError,
22
- sourceItems,
23
- sourceRemovingId,
24
- sourceSyncLoading,
25
- sourceUploadLoading,
26
- showCanvasPanel,
27
- canvasPanelNode,
28
- streamError,
29
- streamLoading,
30
- onStreamRetry,
31
- renderedTimelineItems,
32
- onUICardAction,
33
- registry,
34
- currentInputValue,
35
- showAllScenarios,
36
- onToggleShowAllScenarios,
37
- visibleScenarios,
38
- onScenarioCardClick,
39
- }) {
40
- if (!hasProject) {
41
- return (
42
- <ChatWorkspaceProjectInitView
43
- isCompactLayout={false}
44
- themeTokens={themeTokens}
45
- resolvedProductName="F.L.A.R.E"
46
- resolvedProductTag="项目协同工作台"
47
- hasProjectItems={projectItems.length > 0}
48
- resolvedUILabels={resolvedUILabels}
49
- handleCreateProject={handleCreateProject}
50
- />
51
- );
52
- }
53
-
54
- if (activeWorkspaceTab === 'sources') {
55
- return (
56
- <ChatWorkspaceSourcesPanel
57
- composerNode={composerNode}
58
- contentMaxWidth={contentMaxWidth}
59
- handleOpenSourcePicker={handleOpenSourcePicker}
60
- handleRemoveSource={handleRemoveSource}
61
- handleRetrySource={handleRetrySource}
62
- handleViewSourceDetail={handleViewSourceDetail}
63
- isCompactLayout={false}
64
- resolvedUILabels={resolvedUILabels}
65
- sourceActionError={sourceActionError}
66
- sourceItems={sourceItems}
67
- sourceRemovingId={sourceRemovingId}
68
- sourceSyncLoading={sourceSyncLoading}
69
- sourceUploadLoading={sourceUploadLoading}
70
- themeTokens={themeTokens}
71
- />
72
- );
73
- }
74
-
75
- return (
76
- <ChatWorkspaceConversationPane
77
- themeTokens={themeTokens}
78
- isCompactLayout={false}
79
- resolvedActiveModeKey="auto"
80
- canvasWorkspaceFullscreenMode={false}
81
- showCanvasPanel={showCanvasPanel}
82
- canvasPanelNode={canvasPanelNode}
83
- composerNode={composerNode}
84
- contentMaxWidth={contentMaxWidth}
85
- streamError={streamError}
86
- streamLoading={streamLoading}
87
- onStreamRetry={onStreamRetry}
88
- renderedTimeline={{
89
- isEmpty: renderedTimelineItems.length === 0,
90
- items: renderedTimelineItems,
91
- }}
92
- onUICardAction={onUICardAction}
93
- registry={registry}
94
- resolvedUILabels={resolvedUILabels}
95
- showWorkspaceDebugPanel={false}
96
- resolvedDevMode="full_effects"
97
- workspaceEventLog={[]}
98
- workspaceDocSnapshot={{}}
99
- shouldRenderRecommendationPanel={renderedTimelineItems.length === 0}
100
- currentInputValue={currentInputValue}
101
- recommendationPanelTitle="起步入口"
102
- canExpandScenarios
103
- showAllScenarios={showAllScenarios}
104
- onToggleShowAllScenarios={onToggleShowAllScenarios}
105
- visibleScenarios={visibleScenarios}
106
- onScenarioCardClick={onScenarioCardClick}
107
- />
108
- );
109
- }
@@ -1,113 +0,0 @@
1
- import React from 'react';
2
- import WorkspaceTopBarSection from './WorkspaceTopBarSection.jsx';
3
- import WorkspaceBodySection from './WorkspaceBodySection.jsx';
4
-
5
- export default function WorkspaceMainPane({
6
- themeTokens,
7
- hasProject,
8
- viewModel,
9
- projectSlot,
10
- projectNameEditing,
11
- projectNameDraft,
12
- setProjectNameDraft,
13
- handleProjectNameSave,
14
- handleProjectNameCancel,
15
- projectDisplayName,
16
- handleProjectNameStartEdit,
17
- activeWorkspaceTab,
18
- setActiveWorkspaceTab,
19
- resolvedUILabels,
20
- activeSession,
21
- knowledgeHubPopoverContent,
22
- knowledgeHubPopoverOpen,
23
- setKnowledgeHubPopoverOpen,
24
- handleOpenKnowledgeHub,
25
- showCanvasPanel,
26
- handleToggleWorkspacePanel,
27
- projectItems,
28
- actionGuards,
29
- composerNode,
30
- contentMaxWidth,
31
- handleOpenSourcePicker,
32
- handleRemoveSource,
33
- handleRetrySource,
34
- handleViewSourceDetail,
35
- sourceActionError,
36
- sourceItems,
37
- sourceRemovingId,
38
- sourceSyncLoading,
39
- sourceUploadLoading,
40
- canvasPanelNode,
41
- renderedTimelineItems,
42
- handleUICardAction,
43
- generativeRegistry,
44
- showAllScenarios,
45
- setShowAllScenarios,
46
- visibleScenarios,
47
- }) {
48
- const resolvedSessionDigestText = activeSession
49
- ? `当前会话:${String(activeSession.preview || activeSession.title || '').trim()}`
50
- : '';
51
- return (
52
- <div style={{ background: themeTokens.panelBg, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
53
- {hasProject ? (
54
- <WorkspaceTopBarSection
55
- hasConversationStarted={viewModel.timeline.items.length > 0}
56
- projectSlot={projectSlot}
57
- projectNameEditing={projectNameEditing}
58
- projectNameDraft={projectNameDraft}
59
- setProjectNameDraft={setProjectNameDraft}
60
- handleProjectNameSave={handleProjectNameSave}
61
- handleProjectNameCancel={handleProjectNameCancel}
62
- resolvedProjectDisplayName={projectDisplayName}
63
- handleProjectNameStartEdit={handleProjectNameStartEdit}
64
- activeWorkspaceTab={activeWorkspaceTab}
65
- setActiveWorkspaceTab={setActiveWorkspaceTab}
66
- themeTokens={themeTokens}
67
- resolvedUILabels={resolvedUILabels}
68
- hasSessionDigest={Boolean(activeSession)}
69
- resolvedSessionDigest={resolvedSessionDigestText}
70
- knowledgeHubPopoverContent={knowledgeHubPopoverContent}
71
- knowledgeHubPopoverOpen={knowledgeHubPopoverOpen}
72
- handleKnowledgeHubOpenChange={setKnowledgeHubPopoverOpen}
73
- handleOpenKnowledgeHub={handleOpenKnowledgeHub}
74
- showCanvasPanel={showCanvasPanel}
75
- handleToggleWorkspacePanel={handleToggleWorkspacePanel}
76
- />
77
- ) : null}
78
-
79
- <WorkspaceBodySection
80
- hasProject={hasProject}
81
- activeWorkspaceTab={activeWorkspaceTab}
82
- themeTokens={themeTokens}
83
- projectItems={projectItems}
84
- resolvedUILabels={resolvedUILabels}
85
- handleCreateProject={actionGuards.handleCreateProject}
86
- composerNode={composerNode}
87
- contentMaxWidth={contentMaxWidth}
88
- handleOpenSourcePicker={handleOpenSourcePicker}
89
- handleRemoveSource={handleRemoveSource}
90
- handleRetrySource={handleRetrySource}
91
- handleViewSourceDetail={handleViewSourceDetail}
92
- sourceActionError={sourceActionError}
93
- sourceItems={sourceItems}
94
- sourceRemovingId={sourceRemovingId}
95
- sourceSyncLoading={sourceSyncLoading}
96
- sourceUploadLoading={sourceUploadLoading}
97
- showCanvasPanel={showCanvasPanel}
98
- canvasPanelNode={canvasPanelNode}
99
- streamError={actionGuards.streamError}
100
- streamLoading={viewModel.timeline.loading}
101
- onStreamRetry={viewModel.toolbar.onRefreshSessions}
102
- renderedTimelineItems={renderedTimelineItems}
103
- onUICardAction={handleUICardAction}
104
- registry={generativeRegistry}
105
- currentInputValue={viewModel.composer.value}
106
- showAllScenarios={showAllScenarios}
107
- onToggleShowAllScenarios={() => setShowAllScenarios((prev) => !prev)}
108
- visibleScenarios={visibleScenarios}
109
- onScenarioCardClick={(entry) => viewModel.composer.onChange({ target: { value: entry.prompt } })}
110
- />
111
- </div>
112
- );
113
- }
@@ -1,48 +0,0 @@
1
- import React from 'react';
2
- import { SessionListPane } from 'flare-chat-ui';
3
-
4
- export default function WorkspaceSessionPane({
5
- themeTokens,
6
- viewModel,
7
- actionGuards,
8
- apiReadinessGate,
9
- hasProject,
10
- projectItems,
11
- projectSlot,
12
- sessions,
13
- resolvedUILabels,
14
- }) {
15
- return (
16
- <div style={{ minWidth: 0 }}>
17
- <SessionListPane
18
- activeSessionId={viewModel.sessionList.activeSessionId}
19
- error={actionGuards.sessionPaneError}
20
- loading={viewModel.timeline.loading || apiReadinessGate.checking}
21
- onCreateProject={actionGuards.handleCreateProject}
22
- onCreateSession={actionGuards.handleCreateSession}
23
- onNewSession={actionGuards.handleCreateSession}
24
- onOperationClick={() => {}}
25
- onProjectSelect={() => {}}
26
- onSelectSession={viewModel.sessionList.onSelectSession}
27
- onRenameSession={viewModel.sessionList.onRenameSession}
28
- onArchiveSession={viewModel.sessionList.onArchiveSession}
29
- operations={[]}
30
- operationsTitle={resolvedUILabels.sidebar_operations_title}
31
- projectItems={hasProject ? projectItems : []}
32
- projectSlot={hasProject ? projectSlot : null}
33
- compact={false}
34
- emptyProjectsLabel={resolvedUILabels.project_list_empty}
35
- emptySessionsLabel="暂无会话"
36
- loadErrorMessage={apiReadinessGate.error ? 'API 预检失败' : '加载会话列表失败'}
37
- createProjectLabel={resolvedUILabels.new_project_button}
38
- createSessionInProjectLabel={resolvedUILabels.new_session_button}
39
- newSessionLabel={resolvedUILabels.new_session_button}
40
- sessions={sessions}
41
- sortProjectsByNameLabel={resolvedUILabels.project_sort_by_name}
42
- sortProjectsLabel={resolvedUILabels.project_sort_by_updated}
43
- themeTokens={themeTokens}
44
- title={hasProject ? '会话历史' : '项目列表'}
45
- />
46
- </div>
47
- );
48
- }
@@ -1,65 +0,0 @@
1
- import React from 'react';
2
- import { Typography } from 'antd';
3
- import { ChatWorkspaceTopBar } from 'flare-chat-ui';
4
-
5
- const { Text } = Typography;
6
-
7
- export default function WorkspaceTopBarSection({
8
- hasConversationStarted,
9
- projectSlot,
10
- projectNameEditing,
11
- projectNameDraft,
12
- setProjectNameDraft,
13
- handleProjectNameSave,
14
- handleProjectNameCancel,
15
- resolvedProjectDisplayName,
16
- handleProjectNameStartEdit,
17
- activeWorkspaceTab,
18
- setActiveWorkspaceTab,
19
- themeTokens,
20
- resolvedUILabels,
21
- hasSessionDigest,
22
- resolvedSessionDigest,
23
- knowledgeHubPopoverContent,
24
- knowledgeHubPopoverOpen,
25
- handleKnowledgeHubOpenChange,
26
- handleOpenKnowledgeHub,
27
- showCanvasPanel,
28
- handleToggleWorkspacePanel,
29
- }) {
30
- return (
31
- <ChatWorkspaceTopBar
32
- hasConversationStarted={hasConversationStarted}
33
- projectSlot={projectSlot}
34
- projectNameEditing={projectNameEditing}
35
- projectNameDraft={projectNameDraft}
36
- setProjectNameDraft={setProjectNameDraft}
37
- handleProjectNameSave={handleProjectNameSave}
38
- handleProjectNameCancel={handleProjectNameCancel}
39
- resolvedProjectDisplayName={resolvedProjectDisplayName}
40
- handleProjectNameStartEdit={handleProjectNameStartEdit}
41
- isCompactLayout={false}
42
- activeWorkspaceTab={activeWorkspaceTab}
43
- setActiveWorkspaceTab={setActiveWorkspaceTab}
44
- segmentedThemeStyle={{}}
45
- themeTokens={themeTokens}
46
- resolvedUILabels={resolvedUILabels}
47
- resolvedProductName={resolvedProjectDisplayName}
48
- customerRoleFallback="FLARE"
49
- hasSessionDigest={hasSessionDigest}
50
- resolvedSessionDigest={resolvedSessionDigest}
51
- knowledgeHubPopoverContent={knowledgeHubPopoverContent}
52
- knowledgeHubPopoverOpen={knowledgeHubPopoverOpen}
53
- handleKnowledgeHubOpenChange={handleKnowledgeHubOpenChange}
54
- handleOpenKnowledgeHub={handleOpenKnowledgeHub}
55
- mcpHubPopoverContent={<Text type="secondary">MCP(演示)</Text>}
56
- mcpHubPopoverOpen={false}
57
- handleMcpHubOpenChange={() => {}}
58
- handleOpenMcpHub={() => {}}
59
- workspaceOpenButtonVisible
60
- hasUnseenWorkspaceUpdate={false}
61
- showCanvasPanel={showCanvasPanel}
62
- handleToggleWorkspacePanel={handleToggleWorkspacePanel}
63
- />
64
- );
65
- }
@@ -1,241 +0,0 @@
1
- import React, { useMemo, useState } from 'react';
2
- import { ChatWorkspaceComposerSection } from 'flare-chat-ui';
3
- import useComposerModeSuggestion from './useComposerModeSuggestion.js';
4
-
5
- const MODE_STATUS_IDLE = {
6
- requirement_canvas: 'idle',
7
- intelligent_sourcing: 'idle',
8
- analysis_mode: 'idle',
9
- };
10
-
11
- function buildModeStatusByActiveKey(modeKey) {
12
- if (!modeKey || modeKey === 'auto') {
13
- return MODE_STATUS_IDLE;
14
- }
15
- return {
16
- requirement_canvas: modeKey === 'requirement_canvas' ? 'active' : 'idle',
17
- intelligent_sourcing: modeKey === 'intelligent_sourcing' ? 'active' : 'idle',
18
- analysis_mode: modeKey === 'analysis_mode' ? 'active' : 'idle',
19
- };
20
- }
21
-
22
- export default function ComposerSectionNode({
23
- themeTokens,
24
- contentMaxWidth,
25
- streamLoading,
26
- resolvedUILabels,
27
- modeSwitchOptions,
28
- inputState,
29
- onAttachFiles,
30
- onSend,
31
- effectiveComposerChooser = null,
32
- onComposerActionSelect = () => {},
33
- onComposerChooserDismiss = () => {},
34
- runtimeComposerActions = [],
35
- initialModeKey = 'auto',
36
- onModeChanged,
37
- userId,
38
- intentEscalationPolicyPopoverContent,
39
- contextGaugePopoverContent,
40
- shouldRenderModeSuggestion = true,
41
- modeSuggestion = null,
42
- modeSuggestionAction = null,
43
- tipRules = [],
44
- suggestionContextFlags = {},
45
- }) {
46
- const [activeModeKey, setActiveModeKey] = useState(initialModeKey);
47
- const [statusOnlyTipHidden, setStatusOnlyTipHidden] = useState(false);
48
- const [intentEscalationPolicyPopoverOpen, setIntentEscalationPolicyPopoverOpen] = useState(false);
49
- React.useEffect(() => {
50
- setActiveModeKey(String(initialModeKey || 'auto').trim() || 'auto');
51
- }, [initialModeKey]);
52
- React.useEffect(() => {
53
- setStatusOnlyTipHidden(false);
54
- }, [activeModeKey, inputState?.inputValue]);
55
- const modeStatusByKey = useMemo(
56
- () => buildModeStatusByActiveKey(activeModeKey),
57
- [activeModeKey],
58
- );
59
- const {
60
- modeSuggestion: resolvedModeSuggestion,
61
- modeSuggestionAction: resolvedModeSuggestionAction,
62
- fromFallback: modeSuggestionFromFallback,
63
- } = useComposerModeSuggestion({
64
- inputValue: String(inputState?.inputValue || ''),
65
- activeModeKey,
66
- modeSuggestion,
67
- modeSuggestionAction,
68
- tipRules,
69
- contextFlags: suggestionContextFlags,
70
- });
71
- const resolvedModeKey = String(activeModeKey || '').trim();
72
- const recommendationPanelState = 'hidden';
73
- const handleModeSuggestionAction = (actionItem) => {
74
- const actionPayload = actionItem?.action && typeof actionItem.action === 'object'
75
- ? actionItem.action
76
- : null;
77
- const actionType = String(actionPayload?.action_type || actionPayload?.type || '').trim();
78
- const targetMode = String(
79
- actionPayload?.target_mode
80
- || actionPayload?.mode
81
- || actionItem?.modeKey
82
- || ''
83
- ).trim();
84
- if ((actionType === 'switch_mode' || actionType === 'activate_mode') && targetMode) {
85
- const normalizedModeKey = targetMode || 'auto';
86
- setActiveModeKey(normalizedModeKey);
87
- onModeChanged?.(normalizedModeKey);
88
- return;
89
- }
90
- onComposerActionSelect?.(actionItem);
91
- };
92
- const handleCollectingAnalysisAction = (collectingAnalysisAction) => {
93
- if (!collectingAnalysisAction) {
94
- return;
95
- }
96
- onComposerActionSelect?.({
97
- source: 'runtime_action',
98
- text: '开始需求分析',
99
- action: collectingAnalysisAction,
100
- });
101
- };
102
- const handleComposerChooserSubmit = (payload) => {
103
- const selectedChoice = payload?.selectedChoice && typeof payload.selectedChoice === 'object'
104
- ? payload.selectedChoice
105
- : null;
106
- if (!selectedChoice) {
107
- return;
108
- }
109
- const composerChooser = payload?.composerChooser && typeof payload.composerChooser === 'object'
110
- ? payload.composerChooser
111
- : null;
112
- const currentQuestion = composerChooser?.currentQuestion && typeof composerChooser.currentQuestion === 'object'
113
- ? composerChooser.currentQuestion
114
- : null;
115
- const isCustomInputChoice = selectedChoice?.allowCustomInput === true || selectedChoice?.requiresCustomInput === true;
116
- const answerValue = String(payload?.answerValue || '').trim();
117
- if (!answerValue) {
118
- return;
119
- }
120
- const fieldKey = String(currentQuestion?.fieldKey || '').trim();
121
- const questionKind = String(currentQuestion?.questionKind || 'field').trim();
122
- const branchNodeKey = String(currentQuestion?.branchNodeKey || '').trim();
123
- const questionText = String(currentQuestion?.questionText || composerChooser?.title || '').trim();
124
- const selectedOptionText = String(selectedChoice?.text || '').trim();
125
- const selectedOptionKey = String(selectedChoice?.key || '').trim();
126
- const selectedOptionValue = isCustomInputChoice
127
- ? answerValue
128
- : String(selectedChoice?.answerValue || selectedOptionText || '').trim();
129
- const selectedOptionDisplayText = isCustomInputChoice
130
- ? answerValue
131
- : selectedOptionText;
132
- const answerText = String(answerValue || selectedOptionDisplayText).trim();
133
- const hasCurrentQuestionContext = Boolean(currentQuestion && (fieldKey || branchNodeKey));
134
- if (hasCurrentQuestionContext) {
135
- const action = selectedChoice?.action && typeof selectedChoice.action === 'object'
136
- ? {
137
- ...selectedChoice.action,
138
- payload: {
139
- ...(selectedChoice.action.payload && typeof selectedChoice.action.payload === 'object'
140
- ? selectedChoice.action.payload
141
- : {}),
142
- question_answer: {
143
- field_key: fieldKey,
144
- question_kind: questionKind,
145
- branch_node_key: branchNodeKey,
146
- question_text: questionText,
147
- selected_option_key: selectedOptionKey,
148
- selected_option_text: selectedOptionDisplayText,
149
- selected_option_value: selectedOptionValue,
150
- field_value: answerValue,
151
- },
152
- prefill_prompt: answerText,
153
- },
154
- }
155
- : null;
156
- onComposerActionSelect?.({
157
- ...selectedChoice,
158
- source: 'question_answer',
159
- text: answerText,
160
- answerValue,
161
- action,
162
- });
163
- return;
164
- }
165
- onComposerActionSelect?.({
166
- ...selectedChoice,
167
- source: String(selectedChoice?.source || 'action'),
168
- text: String(selectedChoice?.text || answerValue).trim(),
169
- answerValue,
170
- action: selectedChoice?.action && typeof selectedChoice.action === 'object'
171
- ? selectedChoice.action
172
- : null,
173
- });
174
- };
175
-
176
- return (
177
- <ChatWorkspaceComposerSection
178
- canvasWorkspaceFullscreenMode={false}
179
- themeTokens={themeTokens}
180
- isCompactLayout={false}
181
- contentMaxWidth={contentMaxWidth}
182
- recommendationPanelState={recommendationPanelState}
183
- effectiveComposerChooser={effectiveComposerChooser}
184
- streamLoading={streamLoading}
185
- shouldRenderModeSuggestion={shouldRenderModeSuggestion}
186
- modeSuggestion={resolvedModeSuggestion}
187
- modeSuggestionAction={resolvedModeSuggestionAction}
188
- modeSuggestionFromFallback={modeSuggestionFromFallback}
189
- onModeSuggestionAction={handleModeSuggestionAction}
190
- handleComposerActionSelect={onComposerActionSelect}
191
- isStatusOnlyModeSuggestion={false}
192
- statusOnlyTipHidden={statusOnlyTipHidden}
193
- setStatusOnlyTipHidden={setStatusOnlyTipHidden}
194
- applyBehaviorEvent={() => {}}
195
- isRequirementCanvasMode
196
- chooserAwaitingAuthoritative={false}
197
- canonicalAwaitingReason=""
198
- patchEventHealth={{ ok: true }}
199
- showCollectingAnalysisCta={false}
200
- collectingAnalysisAction={null}
201
- onCollectingAnalysisAction={handleCollectingAnalysisAction}
202
- attachmentActionError={null}
203
- resolvedUILabels={resolvedUILabels}
204
- attachmentConstraintsHint="当前附件仅用于本次消息。最多 10 个,单个不超过 20MB。"
205
- composerInputRef={null}
206
- modeSwitchOptions={modeSwitchOptions}
207
- resolvedActiveModeKey={activeModeKey}
208
- modeStatusByKey={modeStatusByKey}
209
- handleAttachFiles={onAttachFiles}
210
- inputState={inputState}
211
- handleModeSelect={(nextModeKey) => {
212
- const normalizedModeKey = String(nextModeKey || '').trim() || 'auto';
213
- setActiveModeKey(normalizedModeKey);
214
- onModeChanged?.(normalizedModeKey);
215
- }}
216
- handleSend={() => onSend({
217
- streamOptions: {
218
- modeKey: resolvedModeKey && resolvedModeKey !== 'auto' ? resolvedModeKey : '',
219
- manualModeKey: resolvedModeKey && resolvedModeKey !== 'auto' ? resolvedModeKey : '',
220
- payloadExtra: (
221
- resolvedModeKey === 'intelligent_sourcing'
222
- ? { sourcing_enabled: true, source_scope: 'hybrid', top_k: 8 }
223
- : {}
224
- ),
225
- },
226
- })}
227
- resolvedComposerPlaceholder="请输入你的需求"
228
- runtimeComposerActions={runtimeComposerActions}
229
- onComposerChooserSubmit={handleComposerChooserSubmit}
230
- onComposerChooserDismiss={onComposerChooserDismiss}
231
- sendButtonLabel="发送"
232
- resolvedUserDisplayName={userId}
233
- intentEscalationPolicyPopoverContent={intentEscalationPolicyPopoverContent}
234
- intentEscalationPolicyPopoverOpen={intentEscalationPolicyPopoverOpen}
235
- handleIntentEscalationPolicyPopoverOpenChange={setIntentEscalationPolicyPopoverOpen}
236
- intentEscalationConfigEntryLabel="触发阈值"
237
- contextGaugePopoverContent={contextGaugePopoverContent}
238
- contextWindowPercent={8}
239
- />
240
- );
241
- }