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.
- package/dist/index.js +6343 -0
- package/package.json +19 -22
- package/docs/CAPABILITY-INVENTORY.md +0 -42
- package/docs/CHAT-CORE-BOUNDARY.md +0 -47
- package/docs/CORE-APP-REALIGNMENT-WORKLOAD-2026-04-18.md +0 -86
- package/docs/SSOT-CHAT-CORE-BOUNDARY.md +0 -73
- package/docs/SSOT-CHAT-CORE-DATAFLOW.md +0 -97
- package/index.html +0 -12
- package/scripts/check.sh +0 -15
- package/src/adapters/index.js +0 -6
- package/src/adapters/message-api.adapter.js +0 -59
- package/src/adapters/session-api.adapter.js +0 -133
- package/src/adapters/session-message-api.http.js +0 -161
- package/src/adapters/session-message-api.js +0 -34
- package/src/adapters/session-message-api.normalize-source-record.test.mjs +0 -180
- package/src/adapters/session-message-api.normalizers.js +0 -153
- package/src/adapters/source-api.adapter.js +0 -135
- package/src/adapters/sse-client.js +0 -244
- package/src/adapters/sse-event-dispatcher.js +0 -121
- package/src/app/App.jsx +0 -11
- package/src/app/AppProviders.jsx +0 -12
- package/src/app/ChatWorkspaceScreen.jsx +0 -33
- package/src/app/WorkspaceLayout.jsx +0 -125
- package/src/app/components/AppCanvasPanel.jsx +0 -64
- package/src/app/components/TriggerThresholdPopoverContent.jsx +0 -122
- package/src/app/components/WorkspaceBodySection.jsx +0 -109
- package/src/app/components/WorkspaceMainPane.jsx +0 -113
- package/src/app/components/WorkspaceSessionPane.jsx +0 -48
- package/src/app/components/WorkspaceTopBarSection.jsx +0 -65
- package/src/app/core-chat-entry/ComposerSectionNode.jsx +0 -241
- package/src/app/core-chat-entry/attachmentSendRefs.js +0 -154
- package/src/app/core-chat-entry/attachmentSendRefs.test.mjs +0 -101
- package/src/app/core-chat-entry/composerActionRouter.js +0 -26
- package/src/app/core-chat-entry/constants.js +0 -108
- package/src/app/core-chat-entry/selectors.js +0 -28
- package/src/app/core-chat-entry/useAppActionErrorGuards.js +0 -68
- package/src/app/core-chat-entry/useChatCorePipelines.js +0 -110
- package/src/app/core-chat-entry/useComposerModeSuggestion.js +0 -89
- package/src/app/core-chat-entry/useDevCapabilityStatusNote.js +0 -22
- package/src/app/core-chat-entry/useProjectNameEditing.js +0 -41
- package/src/app/core-chat-entry/useProjectSourceUpload.js +0 -341
- package/src/app/core-chat-entry/useRealApiReadinessGate.js +0 -103
- package/src/app/core-chat-entry/useUnavailableActionError.js +0 -29
- package/src/app/core-chat-entry/useWorkspaceCanvasController.jsx +0 -177
- package/src/app/core-chat-entry/useWorkspaceCanvasProjection.jsx +0 -171
- package/src/app/core-chat-entry/useWorkspaceComposerController.jsx +0 -199
- package/src/app/core-chat-entry/useWorkspaceController.jsx +0 -226
- package/src/app/core-chat-entry/useWorkspacePanels.js +0 -55
- package/src/app/hooks/useComposerAttachmentSync.js +0 -223
- package/src/app/hooks/useComposerChooserHandlers.js +0 -52
- package/src/app/hooks/useSendWithContextRefs.js +0 -140
- package/src/app/hooks/useSendWithContextRefs.test.mjs +0 -29
- package/src/app/hooks/useUserThresholdProfile.js +0 -121
- package/src/app/index.js +0 -1
- package/src/app/selectors/assistantTextSelector.js +0 -73
- package/src/app/selectors/canvasEvidenceSummarySelector.js +0 -28
- package/src/app/selectors/canvasReportTemplateSelector.js +0 -28
- package/src/app/selectors/canvasTabsSelector.js +0 -58
- package/src/app/selectors/evidenceProjectionSelector.js +0 -175
- package/src/app/selectors/evidenceProjectionSelector.test.mjs +0 -107
- package/src/app/selectors/modeSuggestionSelector.js +0 -50
- package/src/chat-core/app/mockRuntime.js +0 -291
- package/src/chat-core/app/useAppStream.js +0 -187
- package/src/chat-core/app/useAppStream.refs.test.mjs +0 -44
- package/src/chat-core/app/useAppStream.request-body.test.mjs +0 -116
- package/src/chat-core/app/useCoreChatApp.js +0 -115
- package/src/chat-core/facade/useBasicConversationFacade.js +0 -280
- package/src/chat-core/index.js +0 -14
- package/src/chat-core/input/useChatInput.js +0 -103
- package/src/chat-core/messages/buildTimelineItems.analysis-route.test.mjs +0 -36
- package/src/chat-core/messages/buildTimelineItems.js +0 -233
- package/src/chat-core/messages/buildTimelineItems.knowledge-citation.test.mjs +0 -183
- package/src/chat-core/messages/contextUsageDefaults.js +0 -3
- package/src/chat-core/messages/contextUsageViewModel.js +0 -147
- package/src/chat-core/messages/contextUsageViewModel.test.mjs +0 -74
- package/src/chat-core/messages/useContextUsageViewModel.js +0 -41
- package/src/chat-core/orchestration/useBasicSendHandler.js +0 -55
- package/src/chat-core/pipelines/build-action-request.js +0 -46
- package/src/chat-core/pipelines/build-stream-request.js +0 -74
- package/src/chat-core/pipelines/entity-extraction.js +0 -159
- package/src/chat-core/pipelines/preprocess-message.js +0 -16
- package/src/chat-core/pipelines/stream-persist-utils.js +0 -32
- package/src/chat-core/pipelines/transport/send-mock-stream.js +0 -86
- package/src/chat-core/pipelines/transport/send-real-stream.js +0 -330
- package/src/chat-core/pipelines/transport/send-real-stream.test.mjs +0 -27
- package/src/chat-core/pipelines/transport/send-sourcing-search.js +0 -86
- package/src/chat-core/pipelines/transport/send-sourcing-search.test.mjs +0 -14
- package/src/chat-core/pipelines/transport/sourcing-response-templates.js +0 -55
- package/src/chat-core/pipelines/transport/sourcing-search-api.js +0 -155
- package/src/chat-core/runtime/runtimeMode.js +0 -69
- package/src/chat-core/session/chatSessionActionTypes.js +0 -24
- package/src/chat-core/session/chatSessionReducer.js +0 -352
- package/src/chat-core/session/chatSessionReducer.streaming-done.test.mjs +0 -39
- package/src/chat-core/session/index.js +0 -2
- package/src/chat-core/session/sessionActionsMessages.js +0 -44
- package/src/chat-core/session/sessionActionsSessionCrud.js +0 -131
- package/src/chat-core/session/sessionActionsStreaming.js +0 -80
- package/src/chat-core/session/sessionActionsUiState.js +0 -51
- package/src/chat-core/session/useChatSessionReducer.js +0 -131
- package/src/chat-core/session/useSessionListController.js +0 -67
- package/src/chat-core/stream/sse-client.js +0 -1
- package/src/chat-core/stream/sse-event-dispatcher.js +0 -1
- package/src/chat-core/stream/sse-events.js +0 -1
- package/src/chat-core/stream/useSSEStream.js +0 -1
- package/src/chat-core/stream/useStreamSendController.js +0 -46
- package/src/contracts/context-ssot.js +0 -47
- package/src/contracts/index.js +0 -1
- package/src/contracts/sse-events/base-parsers.js +0 -79
- package/src/contracts/sse-events/domain-parsers.js +0 -3
- package/src/contracts/sse-events/internal-normalizers.js +0 -143
- package/src/contracts/sse-events/parsers-intake.js +0 -235
- package/src/contracts/sse-events/parsers-runtime.js +0 -37
- package/src/contracts/sse-events/parsers-sourcing.js +0 -179
- package/src/contracts/sse-events/patch-event-parser.js +0 -121
- package/src/contracts/sse-events/runtime-parsers.js +0 -79
- package/src/contracts/sse-events.js +0 -4
- package/src/index.js +0 -6
- package/src/main.jsx +0 -28
- package/src/orchestration/index.js +0 -6
- package/src/orchestration/useSSEStream.js +0 -221
- package/src/state/index.js +0 -4
- package/vite.config.js +0 -36
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Compose a basic send handler from preflight/execution/recovery boundaries.
|
|
5
|
-
*
|
|
6
|
-
* @param {object} params - Hook params.
|
|
7
|
-
* @param {Function} params.resolveSendPreflight - Preflight resolver.
|
|
8
|
-
* @param {Function} params.executeSendRound - Round executor.
|
|
9
|
-
* @param {Function} params.handleSendFailureRecovery - Failure recovery handler.
|
|
10
|
-
* @param {Array<any>} params.emptyArray - Shared immutable empty array.
|
|
11
|
-
* @returns {{handleSend: Function}}
|
|
12
|
-
*/
|
|
13
|
-
export default function useBasicSendHandler({
|
|
14
|
-
resolveSendPreflight,
|
|
15
|
-
executeSendRound,
|
|
16
|
-
handleSendFailureRecovery,
|
|
17
|
-
emptyArray = [],
|
|
18
|
-
}) {
|
|
19
|
-
const handleSend = useCallback(async (options = {}) => {
|
|
20
|
-
let isFirstDraftSend = false;
|
|
21
|
-
let preserveInputOnError = false;
|
|
22
|
-
let content = '';
|
|
23
|
-
let attachedSessionFilesSnapshot = emptyArray;
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
const sendPreflight = await resolveSendPreflight?.(options);
|
|
27
|
-
if (!sendPreflight || sendPreflight.blocked) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
attachedSessionFilesSnapshot = sendPreflight.attachedSessionFilesSnapshot || emptyArray;
|
|
32
|
-
isFirstDraftSend = sendPreflight.isFirstDraftSend === true;
|
|
33
|
-
preserveInputOnError = sendPreflight.preserveInputOnError === true;
|
|
34
|
-
content = sendPreflight.content || '';
|
|
35
|
-
|
|
36
|
-
await executeSendRound?.({
|
|
37
|
-
sendPreflight,
|
|
38
|
-
isFirstDraftSend,
|
|
39
|
-
});
|
|
40
|
-
return true;
|
|
41
|
-
} catch (error) {
|
|
42
|
-
handleSendFailureRecovery?.({
|
|
43
|
-
preserveInputOnError,
|
|
44
|
-
isFirstDraftSend,
|
|
45
|
-
content,
|
|
46
|
-
attachedSessionFilesSnapshot,
|
|
47
|
-
});
|
|
48
|
-
return error;
|
|
49
|
-
}
|
|
50
|
-
}, [emptyArray, executeSendRound, handleSendFailureRecovery, resolveSendPreflight]);
|
|
51
|
-
|
|
52
|
-
return { handleSend };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export { useBasicSendHandler };
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { resolvePayloadExtra } from './build-stream-request.js';
|
|
2
|
-
|
|
3
|
-
export function buildRealActionRequestBody({
|
|
4
|
-
action = {},
|
|
5
|
-
options = {},
|
|
6
|
-
scope = {},
|
|
7
|
-
}) {
|
|
8
|
-
const normalizedAction = (
|
|
9
|
-
action
|
|
10
|
-
&& typeof action === 'object'
|
|
11
|
-
&& !Array.isArray(action)
|
|
12
|
-
) ? action : {};
|
|
13
|
-
const payloadExtra = resolvePayloadExtra(options);
|
|
14
|
-
const actionPayload = (
|
|
15
|
-
normalizedAction.payload
|
|
16
|
-
&& typeof normalizedAction.payload === 'object'
|
|
17
|
-
&& !Array.isArray(normalizedAction.payload)
|
|
18
|
-
) ? normalizedAction.payload : {};
|
|
19
|
-
const resolvedProjectId = String(scope?.projectId || '').trim();
|
|
20
|
-
const resolvedUserId = String(scope?.userId || '').trim();
|
|
21
|
-
const sessionId = String(options.sessionIdOverride || '').trim();
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
tenant_id: 'default',
|
|
25
|
-
instance_id: 'default',
|
|
26
|
-
domain_pack_version: 'v1',
|
|
27
|
-
session_id: sessionId || null,
|
|
28
|
-
intent: 'default',
|
|
29
|
-
project_id: resolvedProjectId || null,
|
|
30
|
-
user_id: resolvedUserId || null,
|
|
31
|
-
action_key: String(normalizedAction.action_key || '').trim() || null,
|
|
32
|
-
target_mode: String(
|
|
33
|
-
normalizedAction.target_mode
|
|
34
|
-
|| actionPayload.target_mode
|
|
35
|
-
|| ''
|
|
36
|
-
).trim() || null,
|
|
37
|
-
action_status: String(normalizedAction.status || '').trim() || null,
|
|
38
|
-
action_reason: String(normalizedAction.reason || '').trim() || null,
|
|
39
|
-
payload: {
|
|
40
|
-
...actionPayload,
|
|
41
|
-
...payloadExtra,
|
|
42
|
-
project_id: resolvedProjectId || null,
|
|
43
|
-
user_id: resolvedUserId || null,
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { resolveEntities } from './entity-extraction.js';
|
|
2
|
-
|
|
3
|
-
function normalizeRefs(value) {
|
|
4
|
-
if (!Array.isArray(value)) {
|
|
5
|
-
return [];
|
|
6
|
-
}
|
|
7
|
-
return value.filter((item) => item !== undefined && item !== null);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function resolvePayloadExtra(options = {}) {
|
|
11
|
-
return (
|
|
12
|
-
options?.payloadExtra
|
|
13
|
-
&& typeof options.payloadExtra === 'object'
|
|
14
|
-
&& !Array.isArray(options.payloadExtra)
|
|
15
|
-
) ? options.payloadExtra : {};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function resolveStreamRefs(options = {}) {
|
|
19
|
-
const payloadExtra = resolvePayloadExtra(options);
|
|
20
|
-
|
|
21
|
-
const contextRefs = Array.isArray(options?.context_refs)
|
|
22
|
-
? normalizeRefs(options.context_refs)
|
|
23
|
-
: normalizeRefs(payloadExtra.context_refs);
|
|
24
|
-
const knowledgeRefs = Array.isArray(options?.knowledge_refs)
|
|
25
|
-
? normalizeRefs(options.knowledge_refs)
|
|
26
|
-
: normalizeRefs(payloadExtra.knowledge_refs);
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
context_refs: contextRefs,
|
|
30
|
-
knowledge_refs: knowledgeRefs,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function buildRealStreamRequestBody({
|
|
35
|
-
content,
|
|
36
|
-
options = {},
|
|
37
|
-
scope = {},
|
|
38
|
-
}) {
|
|
39
|
-
const resolvedProjectId = String(scope?.projectId || '').trim();
|
|
40
|
-
const resolvedUserId = String(scope?.userId || '').trim();
|
|
41
|
-
const sessionId = String(options.sessionIdOverride || '').trim();
|
|
42
|
-
const payloadExtra = resolvePayloadExtra(options);
|
|
43
|
-
const modeKey = String(options?.modeKey || payloadExtra.mode || '').trim();
|
|
44
|
-
const manualModeKey = String(options?.manualModeKey || payloadExtra.manual_mode || '').trim();
|
|
45
|
-
const command = String(options?.command || payloadExtra.command || 'send_message').trim() || 'send_message';
|
|
46
|
-
const refs = resolveStreamRefs(options);
|
|
47
|
-
const entities = resolveEntities({
|
|
48
|
-
text: content,
|
|
49
|
-
entities: Array.isArray(options?.entities) ? options.entities : payloadExtra.entities,
|
|
50
|
-
});
|
|
51
|
-
return {
|
|
52
|
-
tenant_id: 'default',
|
|
53
|
-
instance_id: 'default',
|
|
54
|
-
domain_pack_version: 'v1',
|
|
55
|
-
session_id: sessionId || null,
|
|
56
|
-
command,
|
|
57
|
-
intent: 'default',
|
|
58
|
-
...(modeKey ? { mode: modeKey } : {}),
|
|
59
|
-
...(manualModeKey ? { manual_mode: manualModeKey } : {}),
|
|
60
|
-
project_id: resolvedProjectId || null,
|
|
61
|
-
user_id: resolvedUserId || null,
|
|
62
|
-
payload: {
|
|
63
|
-
message: content,
|
|
64
|
-
...(modeKey ? { mode: modeKey } : {}),
|
|
65
|
-
...(manualModeKey ? { manual_mode: manualModeKey } : {}),
|
|
66
|
-
project_id: resolvedProjectId || null,
|
|
67
|
-
user_id: resolvedUserId || null,
|
|
68
|
-
...payloadExtra,
|
|
69
|
-
entities,
|
|
70
|
-
},
|
|
71
|
-
context_refs: refs.context_refs,
|
|
72
|
-
knowledge_refs: refs.knowledge_refs,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
const ENTITY_TYPES = {
|
|
2
|
-
VENDOR: 'vendor',
|
|
3
|
-
PRODUCT: 'product',
|
|
4
|
-
ORG: 'org',
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const PRODUCT_TOKENS = [
|
|
8
|
-
'ERP',
|
|
9
|
-
'CRM',
|
|
10
|
-
'SCM',
|
|
11
|
-
'MES',
|
|
12
|
-
'PLM',
|
|
13
|
-
'SRM',
|
|
14
|
-
'WMS',
|
|
15
|
-
'HRM',
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
const KNOWN_ENTITY_DEFS = [
|
|
19
|
-
{ type: ENTITY_TYPES.VENDOR, text: '用友', aliases: ['用友', '用友网络', 'yonyou'] },
|
|
20
|
-
{ type: ENTITY_TYPES.VENDOR, text: '金蝶', aliases: ['金蝶', 'kingdee'] },
|
|
21
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'SAP', aliases: ['sap', 'sap erp', '思爱普'] },
|
|
22
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Oracle', aliases: ['oracle', 'oracle erp', '甲骨文'] },
|
|
23
|
-
{ type: ENTITY_TYPES.VENDOR, text: '鼎捷', aliases: ['鼎捷', 'digiwin'] },
|
|
24
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Microsoft Dynamics', aliases: ['microsoft dynamics', 'dynamics 365'] },
|
|
25
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Infor', aliases: ['infor'] },
|
|
26
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Workday', aliases: ['workday'] },
|
|
27
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Sage', aliases: ['sage'] },
|
|
28
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Odoo', aliases: ['odoo'] },
|
|
29
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'Epicor', aliases: ['epicor'] },
|
|
30
|
-
{ type: ENTITY_TYPES.VENDOR, text: 'IFS', aliases: ['ifs'] },
|
|
31
|
-
...PRODUCT_TOKENS.map((token) => ({ type: ENTITY_TYPES.PRODUCT, text: token, aliases: [token] })),
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
function normalizeEntityKey(value) {
|
|
35
|
-
return String(value || '')
|
|
36
|
-
.trim()
|
|
37
|
-
.toLowerCase()
|
|
38
|
-
.replace(/[\u3000\s]+/g, ' ')
|
|
39
|
-
.replace(/^[,.;:!?()[\]{}"'`~]+|[,.;:!?()[\]{}"'`~]+$/g, '');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function escapeRegExp(value) {
|
|
43
|
-
return String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function hasCjk(value) {
|
|
47
|
-
return /[\u3400-\u9fff]/.test(String(value || ''));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function includesAlias(text, alias) {
|
|
51
|
-
const sourceText = String(text || '');
|
|
52
|
-
const sourceAlias = String(alias || '').trim();
|
|
53
|
-
if (!sourceText || !sourceAlias) {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
if (hasCjk(sourceAlias)) {
|
|
57
|
-
return sourceText.includes(sourceAlias);
|
|
58
|
-
}
|
|
59
|
-
const pattern = new RegExp(`\\b${escapeRegExp(sourceAlias)}\\b`, 'i');
|
|
60
|
-
return pattern.test(sourceText);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function inferEntityType(text, fallbackType = ENTITY_TYPES.ORG) {
|
|
64
|
-
const normalized = normalizeEntityKey(text);
|
|
65
|
-
if (PRODUCT_TOKENS.some((token) => normalizeEntityKey(token) === normalized)) {
|
|
66
|
-
return ENTITY_TYPES.PRODUCT;
|
|
67
|
-
}
|
|
68
|
-
return fallbackType;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function normalizeEntityItem(item) {
|
|
72
|
-
if (typeof item === 'string') {
|
|
73
|
-
const normalized = normalizeEntityKey(item);
|
|
74
|
-
if (!normalized) return null;
|
|
75
|
-
return {
|
|
76
|
-
text: String(item).trim(),
|
|
77
|
-
normalized,
|
|
78
|
-
type: inferEntityType(item),
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
const text = String(item.text || item.name || item.value || '').trim();
|
|
85
|
-
const normalized = normalizeEntityKey(item.normalized || text);
|
|
86
|
-
if (!text && !normalized) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
text: text || normalized,
|
|
91
|
-
normalized,
|
|
92
|
-
type: String(item.type || inferEntityType(text || normalized)).trim().toLowerCase() || ENTITY_TYPES.ORG,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function dedupeEntities(list = []) {
|
|
97
|
-
const seen = new Set();
|
|
98
|
-
const normalized = [];
|
|
99
|
-
list.forEach((item) => {
|
|
100
|
-
const normalizedItem = normalizeEntityItem(item);
|
|
101
|
-
if (!normalizedItem || !normalizedItem.normalized) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const key = `${normalizedItem.type}:${normalizedItem.normalized}`;
|
|
105
|
-
if (seen.has(key)) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
seen.add(key);
|
|
109
|
-
normalized.push(normalizedItem);
|
|
110
|
-
});
|
|
111
|
-
return normalized;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function extractKnownEntities(text = '') {
|
|
115
|
-
const sourceText = String(text || '');
|
|
116
|
-
if (!sourceText.trim()) {
|
|
117
|
-
return [];
|
|
118
|
-
}
|
|
119
|
-
return KNOWN_ENTITY_DEFS
|
|
120
|
-
.filter((entity) => entity.aliases.some((alias) => includesAlias(sourceText, alias)))
|
|
121
|
-
.map((entity) => ({
|
|
122
|
-
text: entity.text,
|
|
123
|
-
normalized: normalizeEntityKey(entity.text),
|
|
124
|
-
type: entity.type,
|
|
125
|
-
}));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function extractOrgLikeEntities(text = '') {
|
|
129
|
-
const sourceText = String(text || '');
|
|
130
|
-
if (!sourceText.trim()) {
|
|
131
|
-
return [];
|
|
132
|
-
}
|
|
133
|
-
const matches = [];
|
|
134
|
-
const cnPattern = /([\u4e00-\u9fa5]{2,24}(?:公司|集团|科技|信息|股份|研究院))/g;
|
|
135
|
-
const enPattern = /\b([A-Z][A-Za-z0-9&.-]{1,}(?:\s+[A-Z][A-Za-z0-9&.-]{1,}){0,3}\s+(?:Inc|Corp|Corporation|Ltd|LLC|Group|Systems|Technologies|Technology))\b/g;
|
|
136
|
-
for (const match of sourceText.matchAll(cnPattern)) {
|
|
137
|
-
matches.push({ text: match[1], type: ENTITY_TYPES.ORG });
|
|
138
|
-
}
|
|
139
|
-
for (const match of sourceText.matchAll(enPattern)) {
|
|
140
|
-
matches.push({ text: match[1], type: ENTITY_TYPES.ORG });
|
|
141
|
-
}
|
|
142
|
-
return matches;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export function extractEntitiesFromText(text = '') {
|
|
146
|
-
return dedupeEntities([
|
|
147
|
-
...extractKnownEntities(text),
|
|
148
|
-
...extractOrgLikeEntities(text),
|
|
149
|
-
]);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function resolveEntities({ text = '', entities = [] } = {}) {
|
|
153
|
-
return dedupeEntities([
|
|
154
|
-
...(Array.isArray(entities) ? entities : []),
|
|
155
|
-
...extractEntitiesFromText(text),
|
|
156
|
-
]);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export { ENTITY_TYPES };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { extractEntitiesFromText } from './entity-extraction.js';
|
|
2
|
-
|
|
3
|
-
export function normalizeIntentText(value) {
|
|
4
|
-
return String(value || '').trim().toLowerCase();
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function detectSourcingIntent(text) {
|
|
8
|
-
const normalized = normalizeIntentText(text);
|
|
9
|
-
if (!normalized) return false;
|
|
10
|
-
const signals = ['寻源', '供应商', '比价', '采购', '招标', 'source', 'vendor', 'supplier', 'sourcing'];
|
|
11
|
-
return signals.some((token) => normalized.includes(token));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function extractMessageEntities(text) {
|
|
15
|
-
return extractEntitiesFromText(text);
|
|
16
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export function resolvePersistExchangeResult(result, fallbackSessionId = '') {
|
|
2
|
-
const fallback = String(fallbackSessionId || '').trim();
|
|
3
|
-
if (result && typeof result === 'object' && !Array.isArray(result)) {
|
|
4
|
-
return {
|
|
5
|
-
sessionId: String(result.sessionId || result.session_id || fallback).trim(),
|
|
6
|
-
title: String(result.title || '').trim(),
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
return {
|
|
10
|
-
sessionId: String(result || fallback).trim(),
|
|
11
|
-
title: '',
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function collectSourceIdsFromRefs(refs = []) {
|
|
16
|
-
if (!Array.isArray(refs)) {
|
|
17
|
-
return [];
|
|
18
|
-
}
|
|
19
|
-
const ids = [];
|
|
20
|
-
const seen = new Set();
|
|
21
|
-
refs.forEach((item) => {
|
|
22
|
-
const sourceId = typeof item === 'string'
|
|
23
|
-
? String(item).trim()
|
|
24
|
-
: String(item?.source_id || item?.id || '').trim();
|
|
25
|
-
if (!sourceId || seen.has(sourceId)) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
seen.add(sourceId);
|
|
29
|
-
ids.push(sourceId);
|
|
30
|
-
});
|
|
31
|
-
return ids;
|
|
32
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { resolvePersistExchangeResult } from '../stream-persist-utils.js';
|
|
2
|
-
|
|
3
|
-
function chunkText(content, chunkSize = 16) {
|
|
4
|
-
if (!content) {
|
|
5
|
-
return [];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const result = [];
|
|
9
|
-
for (let index = 0; index < content.length; index += chunkSize) {
|
|
10
|
-
result.push(content.slice(index, index + chunkSize));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return result;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function sendMockStreamMessage({
|
|
17
|
-
runtime,
|
|
18
|
-
content,
|
|
19
|
-
handlers = {},
|
|
20
|
-
options = {},
|
|
21
|
-
scope = {},
|
|
22
|
-
persistExchange,
|
|
23
|
-
schedule,
|
|
24
|
-
}) {
|
|
25
|
-
const sessionId = String(options.sessionIdOverride || '').trim();
|
|
26
|
-
const enabledCapabilities = Array.isArray(options.enabledCapabilities)
|
|
27
|
-
? options.enabledCapabilities
|
|
28
|
-
: [];
|
|
29
|
-
const finalReply = runtime.buildAssistantReply(content, enabledCapabilities);
|
|
30
|
-
const chunks = chunkText(finalReply);
|
|
31
|
-
const resolvedProjectId = String(scope?.projectId || '').trim();
|
|
32
|
-
const resolvedUserId = String(scope?.userId || '').trim();
|
|
33
|
-
|
|
34
|
-
await new Promise((resolve) => {
|
|
35
|
-
let delay = 120;
|
|
36
|
-
chunks.forEach((chunk) => {
|
|
37
|
-
schedule(delay, () => {
|
|
38
|
-
handlers.onContent?.(chunk);
|
|
39
|
-
});
|
|
40
|
-
delay += 70;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
schedule(delay + 40, () => {
|
|
44
|
-
const persistedResult = (typeof persistExchange === 'function'
|
|
45
|
-
? persistExchange(sessionId, content, finalReply, {
|
|
46
|
-
functionType: options.modeKey || 'chat_component_debug',
|
|
47
|
-
projectId: resolvedProjectId || null,
|
|
48
|
-
userId: resolvedUserId || null,
|
|
49
|
-
})
|
|
50
|
-
: String(sessionId || '').trim()
|
|
51
|
-
);
|
|
52
|
-
const persistedSession = resolvePersistExchangeResult(persistedResult, sessionId);
|
|
53
|
-
const resolvedSessionId = persistedSession.sessionId;
|
|
54
|
-
handlers.onPatchEvent?.({
|
|
55
|
-
session: {
|
|
56
|
-
session_id: resolvedSessionId,
|
|
57
|
-
turn_id: '',
|
|
58
|
-
},
|
|
59
|
-
payload: persistedSession.title
|
|
60
|
-
? {
|
|
61
|
-
session: {
|
|
62
|
-
title: persistedSession.title,
|
|
63
|
-
},
|
|
64
|
-
}
|
|
65
|
-
: {},
|
|
66
|
-
patch_scope: ['session'],
|
|
67
|
-
event_type: 'ack',
|
|
68
|
-
final: false,
|
|
69
|
-
invalid: false,
|
|
70
|
-
});
|
|
71
|
-
handlers.onComplete?.(finalReply, {
|
|
72
|
-
sessionId: resolvedSessionId,
|
|
73
|
-
...(persistedSession.title
|
|
74
|
-
? {
|
|
75
|
-
payload: {
|
|
76
|
-
session: {
|
|
77
|
-
title: persistedSession.title,
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
}
|
|
81
|
-
: {}),
|
|
82
|
-
});
|
|
83
|
-
resolve();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
}
|