dsh-data-domain-knowledge 0.1.1-alpha.2 → 0.1.1-alpha.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/README.md +33 -16
- package/lib/client.js +1042 -2097
- package/lib/contract-refs.d.ts +0 -1
- package/lib/doc-page.js +1 -1
- package/lib/pages.js +2489 -1060
- package/lib/types/agent-behavior-rules.d.ts.map +1 -1
- package/lib/types/agent-behavior-rules.js +3 -2
- package/lib/types/agent-behavior-rules.js.map +1 -1
- package/lib/types/axis-contract.js +1 -1
- package/lib/types/axis-contract.js.map +1 -1
- package/lib/types/card-organize.d.ts +2 -1
- package/lib/types/card-organize.d.ts.map +1 -1
- package/lib/types/card-organize.js +5 -3
- package/lib/types/card-organize.js.map +1 -1
- package/lib/types/config-schema.d.ts +1 -1
- package/lib/types/config-schema.js +1 -1
- package/lib/types/convert/host.d.ts +2 -3
- package/lib/types/convert/host.d.ts.map +1 -1
- package/lib/types/convert/host.js +11 -2
- package/lib/types/convert/host.js.map +1 -1
- package/lib/types/convert/ingest.d.ts +14 -20
- package/lib/types/convert/ingest.d.ts.map +1 -1
- package/lib/types/convert/ingest.js +8 -5
- package/lib/types/convert/ingest.js.map +1 -1
- package/lib/types/diagnosis/store.d.ts +2 -2
- package/lib/types/diagnosis/store.d.ts.map +1 -1
- package/lib/types/diagnosis/store.js +10 -2
- package/lib/types/diagnosis/store.js.map +1 -1
- package/lib/types/diagnosis/types.d.ts +1 -1
- package/lib/types/diagnosis/types.js +1 -1
- package/lib/types/extract-model.d.ts +3 -0
- package/lib/types/extract-model.d.ts.map +1 -1
- package/lib/types/extract-model.js.map +1 -1
- package/lib/types/images.js +1 -1
- package/lib/types/index.d.ts +0 -4
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +99 -91
- package/lib/types/index.js.map +1 -1
- package/lib/types/knowledge-bases.d.ts +3 -0
- package/lib/types/knowledge-bases.d.ts.map +1 -1
- package/lib/types/knowledge-bases.js +22 -2
- package/lib/types/knowledge-bases.js.map +1 -1
- package/lib/types/knowledge-contract.d.ts +6 -0
- package/lib/types/knowledge-contract.d.ts.map +1 -1
- package/lib/types/knowledge-contract.js +6 -2
- package/lib/types/knowledge-contract.js.map +1 -1
- package/lib/types/layout.d.ts +9 -26
- package/lib/types/layout.d.ts.map +1 -1
- package/lib/types/layout.js +10 -28
- package/lib/types/layout.js.map +1 -1
- package/lib/types/materialize-snapshot.d.ts +5 -0
- package/lib/types/materialize-snapshot.d.ts.map +1 -1
- package/lib/types/migrate.d.ts +3 -1
- package/lib/types/migrate.d.ts.map +1 -1
- package/lib/types/migrate.js +3 -1
- package/lib/types/migrate.js.map +1 -1
- package/lib/types/model-text.d.ts +7 -0
- package/lib/types/model-text.d.ts.map +1 -1
- package/lib/types/model-text.js +31 -9
- package/lib/types/model-text.js.map +1 -1
- package/lib/types/organize-contract.d.ts.map +1 -1
- package/lib/types/organize-contract.js +2 -1
- package/lib/types/organize-contract.js.map +1 -1
- package/lib/types/pipeline/engine.d.ts +28 -4
- package/lib/types/pipeline/engine.d.ts.map +1 -1
- package/lib/types/pipeline/engine.js +68 -15
- package/lib/types/pipeline/engine.js.map +1 -1
- package/lib/types/pipeline/progress.d.ts +12 -0
- package/lib/types/pipeline/progress.d.ts.map +1 -0
- package/lib/types/pipeline/progress.js +37 -0
- package/lib/types/pipeline/progress.js.map +1 -0
- package/lib/types/pipeline/resumable-extract.d.ts +45 -0
- package/lib/types/pipeline/resumable-extract.d.ts.map +1 -0
- package/lib/types/pipeline/resumable-extract.js +262 -0
- package/lib/types/pipeline/resumable-extract.js.map +1 -0
- package/lib/types/pipeline/store.d.ts +8 -2
- package/lib/types/pipeline/store.d.ts.map +1 -1
- package/lib/types/pipeline/store.js +27 -5
- package/lib/types/pipeline/store.js.map +1 -1
- package/lib/types/pipeline/types.d.ts +56 -0
- package/lib/types/pipeline/types.d.ts.map +1 -1
- package/lib/types/pipeline/types.js +18 -1
- package/lib/types/pipeline/types.js.map +1 -1
- package/lib/types/present.d.ts +1 -1
- package/lib/types/present.js +1 -1
- package/lib/types/preset-ids.d.ts +0 -1
- package/lib/types/preset-ids.d.ts.map +1 -1
- package/lib/types/preset-ids.js +0 -3
- package/lib/types/preset-ids.js.map +1 -1
- package/lib/types/query-analysis.d.ts +0 -5
- package/lib/types/query-analysis.d.ts.map +1 -1
- package/lib/types/query-analysis.js +0 -16
- package/lib/types/query-analysis.js.map +1 -1
- package/lib/types/recall-delivery.d.ts +36 -0
- package/lib/types/recall-delivery.d.ts.map +1 -0
- package/lib/types/recall-delivery.js +16 -0
- package/lib/types/recall-delivery.js.map +1 -0
- package/lib/types/retrieval/scope.d.ts +17 -0
- package/lib/types/retrieval/scope.d.ts.map +1 -0
- package/lib/types/retrieval/scope.js +11 -0
- package/lib/types/retrieval/scope.js.map +1 -0
- package/lib/types/runtime.d.ts +75 -14
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/runtime.js +454 -198
- package/lib/types/runtime.js.map +1 -1
- package/lib/types/settings-volatile.d.ts +0 -7
- package/lib/types/settings-volatile.d.ts.map +1 -1
- package/lib/types/settings-volatile.js +0 -7
- package/lib/types/settings-volatile.js.map +1 -1
- package/lib/types/source-identity.d.ts +34 -0
- package/lib/types/source-identity.d.ts.map +1 -0
- package/lib/types/source-identity.js +85 -0
- package/lib/types/source-identity.js.map +1 -0
- package/lib/types/source-read.d.ts +18 -0
- package/lib/types/source-read.d.ts.map +1 -0
- package/lib/types/source-read.js +49 -0
- package/lib/types/source-read.js.map +1 -0
- package/lib/types/store/axis-references.d.ts.map +1 -1
- package/lib/types/store/axis-references.js +5 -3
- package/lib/types/store/axis-references.js.map +1 -1
- package/lib/types/store/knowledge-db.d.ts +5 -29
- package/lib/types/store/knowledge-db.d.ts.map +1 -1
- package/lib/types/store/knowledge-db.js +57 -2
- package/lib/types/store/knowledge-db.js.map +1 -1
- package/lib/types/store/source-identity.d.ts +8 -0
- package/lib/types/store/source-identity.d.ts.map +1 -0
- package/lib/types/store/source-identity.js +56 -0
- package/lib/types/store/source-identity.js.map +1 -0
- package/lib/types/types.d.ts +46 -5
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js +6 -3
- package/lib/types/types.js.map +1 -1
- package/lib/types/wiki-availability.d.ts +11 -0
- package/lib/types/wiki-availability.d.ts.map +1 -0
- package/lib/types/wiki-availability.js +39 -0
- package/lib/types/wiki-availability.js.map +1 -0
- package/lib/types/wiki-finalize.d.ts +4 -2
- package/lib/types/wiki-finalize.d.ts.map +1 -1
- package/lib/types/wiki-finalize.js +9 -27
- package/lib/types/wiki-finalize.js.map +1 -1
- package/lib/types/wiki-links.d.ts +35 -0
- package/lib/types/wiki-links.d.ts.map +1 -0
- package/lib/types/wiki-links.js +129 -0
- package/lib/types/wiki-links.js.map +1 -0
- package/lib/types/wiki-trial-types.d.ts +3 -0
- package/lib/types/wiki-trial-types.d.ts.map +1 -1
- package/lib/types/wiki-trial.d.ts +3 -3
- package/lib/types/wiki-trial.d.ts.map +1 -1
- package/lib/types/wiki-trial.js +14 -3
- package/lib/types/wiki-trial.js.map +1 -1
- package/package.json +16 -16
- package/scripts/doctor.mjs +0 -7
- package/scripts/setup-embedding.sh +0 -0
- package/src/agent-behavior-rules.ts +3 -2
- package/src/axis-contract.ts +1 -1
- package/src/card-organize.ts +5 -3
- package/src/client/AttributionEventGuide.tsx +3 -3
- package/src/client/AxisMatrix.tsx +86 -19
- package/src/client/AxisRegistrySection.tsx +1 -1
- package/src/client/CompileSettingsView.tsx +473 -0
- package/src/client/DirectoryPicker.tsx +0 -2
- package/src/client/ExtractionTasksPage.tsx +557 -423
- package/src/client/GuideArchitectureCanvas.tsx +5 -12
- package/src/client/ImportFilesDialog.tsx +1 -0
- package/src/client/InfoHint.tsx +1 -1
- package/src/client/KnowledgeBaseTab.tsx +141 -148
- package/src/client/KnowledgePanel.tsx +16 -9
- package/src/client/OperationLogTab.tsx +1 -1
- package/src/client/PipelineRunView.tsx +173 -0
- package/src/client/RecallPanel.tsx +5 -16
- package/src/client/TabGuide.tsx +3 -7
- package/src/client/WikiFlowPanel.tsx +10 -11
- package/src/client/arch/NodeLogicPanel.tsx +3 -3
- package/src/client/arch/model.ts +5 -113
- package/src/client/architecture.css +1 -1
- package/src/client/architecture.tsx +13 -27
- package/src/client/attribution/AttributionTab.tsx +141 -10
- package/src/client/pages.css +305 -180
- package/src/client/pages.tsx +7 -12
- package/src/client/styles.css +15 -96
- package/src/config-schema.ts +1 -1
- package/src/convert/host.ts +13 -5
- package/src/convert/ingest.ts +20 -7
- package/src/diagnosis/store.ts +7 -2
- package/src/diagnosis/types.ts +1 -1
- package/src/extract-model.ts +3 -0
- package/src/images.ts +1 -1
- package/src/index.ts +92 -97
- package/src/knowledge-bases.ts +23 -3
- package/src/knowledge-contract.ts +7 -2
- package/src/layout.ts +10 -32
- package/src/materialize-snapshot.ts +1 -0
- package/src/migrate.ts +3 -1
- package/src/model-text.ts +33 -11
- package/src/organize-contract.ts +2 -1
- package/src/pipeline/engine.ts +85 -22
- package/src/pipeline/progress.ts +40 -0
- package/src/pipeline/resumable-extract.ts +233 -0
- package/src/pipeline/store.ts +28 -6
- package/src/pipeline/types.ts +47 -2
- package/src/present.ts +1 -1
- package/src/preset-ids.ts +0 -4
- package/src/query-analysis.ts +0 -20
- package/src/recall-delivery.ts +19 -0
- package/src/retrieval/scope.ts +10 -0
- package/src/runtime.ts +412 -206
- package/src/settings-volatile.ts +0 -7
- package/src/source-identity.ts +85 -0
- package/src/source-read.ts +47 -0
- package/src/store/axis-references.ts +5 -3
- package/src/store/knowledge-db.ts +54 -2
- package/src/store/source-identity.ts +42 -0
- package/src/types.ts +18 -5
- package/src/wiki-availability.ts +37 -0
- package/src/wiki-finalize.ts +9 -25
- package/src/wiki-links.ts +120 -0
- package/src/wiki-trial-types.ts +3 -2
- package/src/wiki-trial.ts +17 -6
- package/lib/types/intent/engine.d.ts +0 -122
- package/lib/types/intent/engine.d.ts.map +0 -1
- package/lib/types/intent/engine.js +0 -488
- package/lib/types/intent/engine.js.map +0 -1
- package/lib/types/intent/host.d.ts +0 -68
- package/lib/types/intent/host.d.ts.map +0 -1
- package/lib/types/intent/host.js +0 -249
- package/lib/types/intent/host.js.map +0 -1
- package/lib/types/intent/scope.d.ts +0 -25
- package/lib/types/intent/scope.d.ts.map +0 -1
- package/lib/types/intent/scope.js +0 -116
- package/lib/types/intent/scope.js.map +0 -1
- package/lib/types/intent/store.d.ts +0 -33
- package/lib/types/intent/store.d.ts.map +0 -1
- package/lib/types/intent/store.js +0 -239
- package/lib/types/intent/store.js.map +0 -1
- package/lib/types/intent/tools.d.ts +0 -62
- package/lib/types/intent/tools.d.ts.map +0 -1
- package/lib/types/intent/tools.js +0 -130
- package/lib/types/intent/tools.js.map +0 -1
- package/lib/types/intent/types.d.ts +0 -170
- package/lib/types/intent/types.d.ts.map +0 -1
- package/lib/types/intent/types.js +0 -56
- package/lib/types/intent/types.js.map +0 -1
- package/src/client/IntentLogic.tsx +0 -192
- package/src/client/IntentTab.tsx +0 -343
- package/src/client/TypeDefinitionDrawer.tsx +0 -195
- package/src/intent/README.md +0 -42
- package/src/intent/engine.ts +0 -515
- package/src/intent/host.ts +0 -315
- package/src/intent/scope.ts +0 -125
- package/src/intent/store.ts +0 -218
- package/src/intent/tools.ts +0 -154
- package/src/intent/types.ts +0 -229
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
* 那一个设置抽屉,只是落到对应的分块上。
|
|
16
16
|
* 2. **设置抽屉装方案级参数**(存储 / 收录闸门 / 构建 / 召回 / 重排 / 追加行为规则):
|
|
17
17
|
* 一个 namespace,整个方案一份。
|
|
18
|
-
* 3.
|
|
19
|
-
*
|
|
18
|
+
* 3. **编译设置是知识处理整页里的一个视图**:按知识库持久化,切库就换一套。
|
|
19
|
+
* 它与面板顶部的方案级设置是**两种作用域**,所以是两个容器而不是一个 ——
|
|
20
|
+
* 见 `CompileSettingsView.tsx`。2026-10-28 前它是工具栏上的一只抽屉;
|
|
21
|
+
* 搬进整页的理由是它改的参数**紧挨着**要用它们的那几段。
|
|
20
22
|
*
|
|
21
23
|
* 产品逻辑参考腾讯 WeKnora:知识库是一等对象(独立配置、独立内容)。每个知识库有自己的
|
|
22
24
|
* 根目录与知识矩阵实体注册表;知识库下有文件列表,每个文件有详情页与版本
|
|
@@ -35,8 +37,8 @@
|
|
|
35
37
|
|
|
36
38
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ChangeEvent, type ReactNode } from 'react'
|
|
37
39
|
import {
|
|
38
|
-
AlertCircle, Check, ChevronDown, Eye, ExternalLink, FileText,
|
|
39
|
-
Layers3, RefreshCw, Sparkles,
|
|
40
|
+
AlertCircle, Check, ChevronDown, Eye, ExternalLink, FileText, FolderOpen,
|
|
41
|
+
Layers3, RefreshCw, Sparkles, Trash2, TriangleAlert, Upload, X,
|
|
40
42
|
} from '@tita-agent/ui/icons'
|
|
41
43
|
import type { LucideIcon } from '@tita-agent/ui/icons'
|
|
42
44
|
import {
|
|
@@ -44,7 +46,7 @@ import {
|
|
|
44
46
|
} from '@tita-agent/ui/components'
|
|
45
47
|
import {
|
|
46
48
|
Dialog, DialogContent, DialogHeader, DialogTitle, Drawer, DrawerBody, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle,
|
|
47
|
-
|
|
49
|
+
useFullPage,
|
|
48
50
|
} from '@tita-agent/ui/overlays'
|
|
49
51
|
import { RestoreDialog, type VersionManagerEntry } from '@tita-agent/ui/versions'
|
|
50
52
|
import { readRemembered, readRememberedId, remember } from './panel-state.ts'
|
|
@@ -77,7 +79,7 @@ import { WikiCardPreview } from './WikiCardPreview.tsx'
|
|
|
77
79
|
import { ListPager, PAGE_SIZE, pageSlice, usePage } from './ListPager.tsx'
|
|
78
80
|
import { COMPILE_STEP_TITLE, CompileConfirmDialog, CompileProgressDialog, type CompileProgressView } from './CompileDialogs.tsx'
|
|
79
81
|
import { ImportFilesDialog, type ImportItemView, type ImportStage } from './ImportFilesDialog.tsx'
|
|
80
|
-
import {
|
|
82
|
+
import { newSourceId } from '../source-identity.ts'
|
|
81
83
|
import { DeleteDocumentDialog } from './DeleteDocumentDialog.tsx'
|
|
82
84
|
import { InfoHint } from './InfoHint.tsx'
|
|
83
85
|
import { PipelineNotice } from './PipelineNotice.tsx'
|
|
@@ -93,7 +95,6 @@ export interface KnowledgeBase {
|
|
|
93
95
|
isDefault: boolean
|
|
94
96
|
/** 这一库的坐标提取备注(0068)。逐字进每一次抽取的提示词。 */
|
|
95
97
|
extractionNote?: string
|
|
96
|
-
compileModel?: CompileModelSelectionView
|
|
97
98
|
createdAt: string
|
|
98
99
|
updatedAt: string
|
|
99
100
|
sourceCount: number
|
|
@@ -442,12 +443,16 @@ export interface KnowledgeCardView {
|
|
|
442
443
|
interface CardMatrixResult {
|
|
443
444
|
view: MatrixView
|
|
444
445
|
sceneOnly: number
|
|
446
|
+
factCount: number
|
|
447
|
+
wayCount: number
|
|
448
|
+
unclassifiedCount: number
|
|
445
449
|
}
|
|
446
450
|
|
|
447
451
|
interface CardMatrixFilter {
|
|
448
452
|
objectId?: string
|
|
449
453
|
actionId?: string
|
|
450
454
|
sceneId?: string
|
|
455
|
+
wikiKind?: 'fact' | 'way' | 'unclassified'
|
|
451
456
|
}
|
|
452
457
|
|
|
453
458
|
/**
|
|
@@ -458,18 +463,37 @@ interface CardMatrixFilter {
|
|
|
458
463
|
* 不再新增一条服务端聚合接口,避免两份统计在编译刚结束时短暂不同步。
|
|
459
464
|
*/
|
|
460
465
|
function cardMatrixOf(cards: readonly KnowledgeCardView[], lookup: AxisLookup): CardMatrixResult {
|
|
461
|
-
interface Bucket { object: string | null; action: string | null; scene: string | null; count: number }
|
|
466
|
+
interface Bucket { object: string | null; action: string | null; scene: string | null; count: number; factCount: number; wayCount: number; unclassifiedCount: number }
|
|
462
467
|
const buckets = new Map<string, Bucket>()
|
|
463
468
|
let noCoordinate = 0
|
|
464
469
|
let sceneOnly = 0
|
|
465
|
-
|
|
470
|
+
let factCount = 0
|
|
471
|
+
let wayCount = 0
|
|
472
|
+
let unclassifiedCount = 0
|
|
473
|
+
const add = (coordinate: Omit<Bucket, 'count' | 'factCount' | 'wayCount' | 'unclassifiedCount'>, wikiKind: 'fact' | 'way' | 'unclassified'): void => {
|
|
466
474
|
const key = JSON.stringify([coordinate.object, coordinate.action, coordinate.scene])
|
|
467
475
|
const previous = buckets.get(key)
|
|
468
|
-
if (previous)
|
|
469
|
-
|
|
476
|
+
if (previous) {
|
|
477
|
+
previous.count += 1
|
|
478
|
+
if (wikiKind === 'fact') previous.factCount += 1
|
|
479
|
+
else if (wikiKind === 'way') previous.wayCount += 1
|
|
480
|
+
else previous.unclassifiedCount += 1
|
|
481
|
+
} else buckets.set(key, {
|
|
482
|
+
...coordinate,
|
|
483
|
+
count: 1,
|
|
484
|
+
factCount: wikiKind === 'fact' ? 1 : 0,
|
|
485
|
+
wayCount: wikiKind === 'way' ? 1 : 0,
|
|
486
|
+
unclassifiedCount: wikiKind === 'unclassified' ? 1 : 0,
|
|
487
|
+
})
|
|
470
488
|
}
|
|
471
489
|
|
|
472
490
|
for (const card of cards) {
|
|
491
|
+
const wikiKind = card.metadata?.wiki_kind === 'fact' || card.metadata?.wiki_kind === 'way'
|
|
492
|
+
? card.metadata.wiki_kind
|
|
493
|
+
: 'unclassified'
|
|
494
|
+
if (wikiKind === 'fact') factCount += 1
|
|
495
|
+
else if (wikiKind === 'way') wayCount += 1
|
|
496
|
+
else unclassifiedCount += 1
|
|
473
497
|
const coordinate = card.coordinate
|
|
474
498
|
if (coordinate === undefined) { noCoordinate += 1; continue }
|
|
475
499
|
const object = coordinate.objectId === '' ? null : lookup.nameOf('object', coordinate.objectId)
|
|
@@ -477,7 +501,7 @@ function cardMatrixOf(cards: readonly KnowledgeCardView[], lookup: AxisLookup):
|
|
|
477
501
|
const scene = coordinate.sceneId === '' ? null : lookup.nameOf('scene', coordinate.sceneId)
|
|
478
502
|
if (object === null && action === null && scene === null) { noCoordinate += 1; continue }
|
|
479
503
|
if (object === null && action === null) { sceneOnly += 1; continue }
|
|
480
|
-
add({ object, action, scene,
|
|
504
|
+
add({ object, action, scene }, wikiKind)
|
|
481
505
|
}
|
|
482
506
|
|
|
483
507
|
const totals = (pick: (bucket: Bucket) => string | null): Map<string, number> => {
|
|
@@ -493,6 +517,11 @@ function cardMatrixOf(cards: readonly KnowledgeCardView[], lookup: AxisLookup):
|
|
|
493
517
|
.map(([name]) => name)
|
|
494
518
|
const objects = rank(totals(bucket => bucket.object))
|
|
495
519
|
const actions = rank(totals(bucket => bucket.action))
|
|
520
|
+
const breakdownFor = (selected: readonly Bucket[]) => [
|
|
521
|
+
{ id: 'fact', label: 'F', title: 'Wiki Fact', count: selected.reduce((sum, bucket) => sum + bucket.factCount, 0) },
|
|
522
|
+
{ id: 'way', label: 'W', title: 'Wiki Way', count: selected.reduce((sum, bucket) => sum + bucket.wayCount, 0) },
|
|
523
|
+
{ id: 'unclassified', label: '未', title: '未归类 Wiki', count: selected.reduce((sum, bucket) => sum + bucket.unclassifiedCount, 0) },
|
|
524
|
+
].filter(item => item.count > 0)
|
|
496
525
|
const groupsFor = (object: string | null, action: string | null) => [...buckets.values()]
|
|
497
526
|
.filter(bucket => bucket.object === object && bucket.action === action)
|
|
498
527
|
.sort((left, right) => (left.scene === null ? -1 : right.scene === null ? 1 : 0)
|
|
@@ -500,15 +529,19 @@ function cardMatrixOf(cards: readonly KnowledgeCardView[], lookup: AxisLookup):
|
|
|
500
529
|
.map(bucket => ({ scene: bucket.scene ?? '', count: bucket.count }))
|
|
501
530
|
const cells = objects.flatMap(object => actions.flatMap(action => {
|
|
502
531
|
const groups = groupsFor(object, action)
|
|
503
|
-
|
|
532
|
+
if (groups.length === 0) return []
|
|
533
|
+
const cellBuckets = [...buckets.values()].filter(bucket => bucket.object === object && bucket.action === action)
|
|
534
|
+
return [{ object, action, groups, breakdown: breakdownFor(cellBuckets) }]
|
|
504
535
|
}))
|
|
505
536
|
const noAction = objects.flatMap(object => {
|
|
506
537
|
const groups = groupsFor(object, null)
|
|
507
|
-
|
|
538
|
+
const looseBuckets = [...buckets.values()].filter(bucket => bucket.object === object && bucket.action === null)
|
|
539
|
+
return groups.length > 0 ? [{ name: object, groups, breakdown: breakdownFor(looseBuckets) }] : []
|
|
508
540
|
})
|
|
509
541
|
const noObject = actions.flatMap(action => {
|
|
510
542
|
const groups = groupsFor(null, action)
|
|
511
|
-
|
|
543
|
+
const looseBuckets = [...buckets.values()].filter(bucket => bucket.object === null && bucket.action === action)
|
|
544
|
+
return groups.length > 0 ? [{ name: action, groups, breakdown: breakdownFor(looseBuckets) }] : []
|
|
512
545
|
})
|
|
513
546
|
|
|
514
547
|
return {
|
|
@@ -519,6 +552,9 @@ function cardMatrixOf(cards: readonly KnowledgeCardView[], lookup: AxisLookup):
|
|
|
519
552
|
unitLabel: '卡片',
|
|
520
553
|
},
|
|
521
554
|
sceneOnly,
|
|
555
|
+
factCount,
|
|
556
|
+
wayCount,
|
|
557
|
+
unclassifiedCount,
|
|
522
558
|
}
|
|
523
559
|
}
|
|
524
560
|
|
|
@@ -582,11 +618,11 @@ interface Props {
|
|
|
582
618
|
onActiveBaseChange?: (base: { id: string; name: string } | null) => void
|
|
583
619
|
/** 知识库设置作用域:召回 / 重排面板读它算默认参数,收录闸门读它决定能不能上传。 */
|
|
584
620
|
knowledge?: SettingsScopeLike
|
|
585
|
-
/**
|
|
586
|
-
focus?: { tab: KnowledgeTab; nonce: number }
|
|
621
|
+
/** 外部跳转落到哪一栏;可选 Wiki ID 会在目标栏加载后打开原卡片。`nonce` 变化即重新应用。 */
|
|
622
|
+
focus?: { tab: KnowledgeTab; nonce: number; wikiEntityId?: string; wikiEntityType?: string }
|
|
587
623
|
/**
|
|
588
624
|
* 卡片头的「参数」chip 落到设置抽屉的哪一块(0034)。**设置不在这一层** —— 这里只
|
|
589
|
-
*
|
|
625
|
+
* 转交一个「打开并定位」的动作,抽屉与它读写的 scope 都还在 `KnowledgePanel` 手里。
|
|
590
626
|
*/
|
|
591
627
|
onOpenSettings?: (target: SettingsNode) => void
|
|
592
628
|
}
|
|
@@ -601,6 +637,8 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
601
637
|
const [bases, setBases] = useState<KnowledgeBase[]>([])
|
|
602
638
|
const [activeId, setActiveId] = useState('')
|
|
603
639
|
const [documents, setDocuments] = useState<KnowledgeDocument[]>([])
|
|
640
|
+
/** Avoid opening a same-ID card from the previous base while a base switch is still loading. */
|
|
641
|
+
const [cardsBaseId, setCardsBaseId] = useState('')
|
|
604
642
|
/**
|
|
605
643
|
* 每份文档有几条抽取轨迹(0063)。它是**审计计数**,不是「这份文档是什么」,
|
|
606
644
|
* 所以它不进 `KnowledgeDocument`,单独一张按 docId 查的表。
|
|
@@ -750,8 +788,6 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
750
788
|
changeTab('knowledge')
|
|
751
789
|
setKnowledgeContent('event')
|
|
752
790
|
}, [changeTab])
|
|
753
|
-
/** 编译设置抽屉:本库的编译模型、坐标实体与抽取备注。 */
|
|
754
|
-
const [typeDef, setTypeDef] = useState(false)
|
|
755
791
|
const [detail, setDetail] = useState<{ document: KnowledgeDocumentDetail; versions: DocumentVersion[] } | null>(null)
|
|
756
792
|
const [detailLoading, setDetailLoading] = useState(false)
|
|
757
793
|
const [restoreTarget, setRestoreTarget] = useState<VersionManagerEntry | null>(null)
|
|
@@ -892,7 +928,11 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
892
928
|
try {
|
|
893
929
|
const payload = await requestJson<{ cards: KnowledgeCardView[] }>(`/knowledge/cards?kb=${encodeURIComponent(baseId)}`)
|
|
894
930
|
setCards(payload.data?.cards ?? [])
|
|
895
|
-
|
|
931
|
+
setCardsBaseId(baseId)
|
|
932
|
+
} catch {
|
|
933
|
+
setCards([])
|
|
934
|
+
setCardsBaseId(baseId)
|
|
935
|
+
}
|
|
896
936
|
}, [])
|
|
897
937
|
|
|
898
938
|
/**
|
|
@@ -1006,65 +1046,18 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1006
1046
|
|
|
1007
1047
|
// ----------------------------------------------------------------- actions
|
|
1008
1048
|
|
|
1009
|
-
/**
|
|
1010
|
-
* 保存坐标提取备注(0068)。
|
|
1011
|
-
*
|
|
1012
|
-
* 与知识矩阵实体**同一条写路径**(PATCH 那个库),因为它就住在同一个注册表里 ——
|
|
1013
|
-
* 同一份数据不因为多了一个入口就多一个写入口。
|
|
1014
|
-
*/
|
|
1015
|
-
const saveExtractionNote = async (note: string): Promise<void> => {
|
|
1016
|
-
const base = active
|
|
1017
|
-
if (!base) return
|
|
1018
|
-
setBusy('extraction-note')
|
|
1019
|
-
try {
|
|
1020
|
-
await requestJson(`/knowledge/bases/${encodeURIComponent(base.id)}`, {
|
|
1021
|
-
method: 'PATCH',
|
|
1022
|
-
headers: { 'content-type': 'application/json' },
|
|
1023
|
-
body: JSON.stringify({ extractionNote: note }),
|
|
1024
|
-
})
|
|
1025
|
-
await loadBases(base.id)
|
|
1026
|
-
say('success', note.trim() === ''
|
|
1027
|
-
? '备注已清空 —— 下一次抽取不再带这段约定'
|
|
1028
|
-
: `备注已保存(${note.trim().length} 字),下一次抽取会逐字带上它`)
|
|
1029
|
-
} catch (error) {
|
|
1030
|
-
say('error', error instanceof Error ? error.message : String(error))
|
|
1031
|
-
} finally {
|
|
1032
|
-
setBusy(null)
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
/** 保存本库的编译模型路由;配置落在知识库注册表,不复制 DSH 的模型目录。 */
|
|
1037
|
-
const saveCompileModel = async (selection: CompileModelSelectionView): Promise<void> => {
|
|
1038
|
-
const base = active
|
|
1039
|
-
if (!base) return
|
|
1040
|
-
setBusy('compile-model')
|
|
1041
|
-
try {
|
|
1042
|
-
await requestJson(`/knowledge/bases/${encodeURIComponent(base.id)}`, {
|
|
1043
|
-
method: 'PATCH',
|
|
1044
|
-
headers: { 'content-type': 'application/json' },
|
|
1045
|
-
body: JSON.stringify({ compileModel: selection }),
|
|
1046
|
-
})
|
|
1047
|
-
await loadBases(base.id)
|
|
1048
|
-
say('success', selection.mode === 'default' ? '编译模型已改为跟随 DSH 默认模型' : `编译模型已固定为 ${selection.provider} / ${selection.model}`)
|
|
1049
|
-
} catch (error) {
|
|
1050
|
-
say('error', error instanceof Error ? error.message : String(error))
|
|
1051
|
-
} finally {
|
|
1052
|
-
setBusy(null)
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
1049
|
/**
|
|
1057
1050
|
* @returns 写入时那些**必须让人看见**的话(图片一张都没进来、标题重复…)。
|
|
1058
1051
|
* 调用方把它挂到这个文件的 `note` 上:一份 40 张图的文档只上传了 `.md`,后果要到
|
|
1059
1052
|
* 编译之后才在卡片里显形 —— 那时人已经不知道是哪一步丢的了。
|
|
1060
1053
|
*/
|
|
1061
|
-
const writeSource = async (title: string, content: string,
|
|
1054
|
+
const writeSource = async (title: string, content: string, sourceId: string): Promise<string[]> => {
|
|
1062
1055
|
const base = active
|
|
1063
1056
|
if (!base) throw new Error('请先选择一个知识库')
|
|
1064
1057
|
const payload = await requestJson<{ assets?: { refs: number; missing: number } }>('/knowledge/sources', {
|
|
1065
1058
|
method: 'POST',
|
|
1066
1059
|
headers: { 'content-type': 'application/json' },
|
|
1067
|
-
body: JSON.stringify({ kb: base.id, title, external_id:
|
|
1060
|
+
body: JSON.stringify({ kb: base.id, source_id: sourceId, title, external_id: `upload:${sourceId}`, content, allow_duplicate_title: true, metadata: { original_filename: title } }),
|
|
1068
1061
|
})
|
|
1069
1062
|
const assets = payload.data?.assets
|
|
1070
1063
|
/*
|
|
@@ -1072,13 +1065,12 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1072
1065
|
* 长的那一句(服务端的 warning)留给处理日志与 Agent 那条路 —— 同一件事在两处的
|
|
1073
1066
|
* 篇幅本来就该不同。
|
|
1074
1067
|
*/
|
|
1075
|
-
return assets !== undefined && assets.missing > 0 && assets.missing === assets.refs
|
|
1076
|
-
? [`正文引用的 ${assets.refs} 张图片一张都没进库`]
|
|
1077
|
-
: []
|
|
1068
|
+
return [...(payload.warnings ?? []), ...(assets !== undefined && assets.missing > 0 && assets.missing === assets.refs
|
|
1069
|
+
? [`正文引用的 ${assets.refs} 张图片一张都没进库`] : [])]
|
|
1078
1070
|
}
|
|
1079
1071
|
|
|
1080
1072
|
/** Convert one file with the kernel, then ingest the delivery into the active base. */
|
|
1081
|
-
const convertAndIngest = async (file: File, onNote?: (note: string) => void): Promise<string[]> => {
|
|
1073
|
+
const convertAndIngest = async (file: File, sourceId: string, onNote?: (note: string) => void): Promise<string[]> => {
|
|
1082
1074
|
const base = active
|
|
1083
1075
|
if (!base) throw new Error('请先选择一个知识库')
|
|
1084
1076
|
const form = new FormData()
|
|
@@ -1104,7 +1096,7 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1104
1096
|
const ingested = await requestJson('/convert/api/ingest', {
|
|
1105
1097
|
method: 'POST',
|
|
1106
1098
|
headers: { 'content-type': 'application/json' },
|
|
1107
|
-
body: JSON.stringify({ task_id: taskId, kb: base.id, title: file.name }),
|
|
1099
|
+
body: JSON.stringify({ task_id: taskId, kb: base.id, title: file.name, source_id: sourceId, allow_duplicate_title: true }),
|
|
1108
1100
|
})
|
|
1109
1101
|
/*
|
|
1110
1102
|
* 内核那条路的备注取自它的 warning:那一层已经会说出「N 个图片资产未复制」这类话,
|
|
@@ -1180,6 +1172,7 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1180
1172
|
if (files.length === 0 || importRunning || busy === 'compile') return
|
|
1181
1173
|
setImportItems(current => [...current, ...files.map(file => ({
|
|
1182
1174
|
id: `import-${importSeq.current++}`,
|
|
1175
|
+
sourceId: newSourceId(),
|
|
1183
1176
|
file,
|
|
1184
1177
|
name: file.name,
|
|
1185
1178
|
ext: (file.name.slice(file.name.lastIndexOf('.') + 1) || '').toLowerCase(),
|
|
@@ -1237,14 +1230,10 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1237
1230
|
let notes: string[] = []
|
|
1238
1231
|
if (DIRECT_READ_EXT.has(ext)) {
|
|
1239
1232
|
const content = await directReadText(item.file)
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
* 选择文件的时间,不能进入 external_id;否则同一文件更新后会被当成新来源,
|
|
1243
|
-
* 随后又被同标题校验拒绝,永远进不了版本链。
|
|
1244
|
-
*/
|
|
1245
|
-
notes = await writeSource(item.name, content, `upload:${item.name}`)
|
|
1233
|
+
// Queue identity is allocated before reading; filenames never select an existing source.
|
|
1234
|
+
notes = await writeSource(item.name, content, item.sourceId)
|
|
1246
1235
|
} else {
|
|
1247
|
-
notes = await convertAndIngest(item.file, note => patchImportItem(item.id, { note }))
|
|
1236
|
+
notes = await convertAndIngest(item.file, item.sourceId, note => patchImportItem(item.id, { note }))
|
|
1248
1237
|
}
|
|
1249
1238
|
const note = notes.length === 0 ? undefined : notes.join(';')
|
|
1250
1239
|
patchImportItem(item.id, { stage: 'ingested', ...(note === undefined ? { note: undefined } : { note }) })
|
|
@@ -1630,6 +1619,19 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1630
1619
|
}
|
|
1631
1620
|
}
|
|
1632
1621
|
|
|
1622
|
+
/** 智能归因中的召回条目可以跳回 Wiki,并在这里打开同一张卡片的原始预览。 */
|
|
1623
|
+
const openedWikiFocusRef = useRef<string | null>(null)
|
|
1624
|
+
useEffect(() => {
|
|
1625
|
+
if (!visible || focus?.tab !== 'wiki' || !focus.wikiEntityId || !activeId || cardsBaseId !== activeId) return
|
|
1626
|
+
const focusKey = `${focus.nonce}:${activeId}:${focus.wikiEntityId}`
|
|
1627
|
+
if (openedWikiFocusRef.current === focusKey) return
|
|
1628
|
+
const card = cards.find(item => item.entityId === focus.wikiEntityId
|
|
1629
|
+
&& (focus.wikiEntityType === undefined || item.entityType === focus.wikiEntityType))
|
|
1630
|
+
if (!card) return
|
|
1631
|
+
openedWikiFocusRef.current = focusKey
|
|
1632
|
+
void openCard(card)
|
|
1633
|
+
}, [visible, focus?.tab, focus?.nonce, focus?.wikiEntityId, focus?.wikiEntityType, activeId, cardsBaseId, cards])
|
|
1634
|
+
|
|
1633
1635
|
const compareCardVersion = async (entry: VersionManagerEntry): Promise<void> => {
|
|
1634
1636
|
const baseId = activeIdRef.current
|
|
1635
1637
|
const current = cardDetail
|
|
@@ -1964,6 +1966,7 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1964
1966
|
const cell = {
|
|
1965
1967
|
object: cardMatrixFilter.objectId === '' ? null : axisLookup.nameOf('object', cardMatrixFilter.objectId!),
|
|
1966
1968
|
action: cardMatrixFilter.actionId === '' ? null : axisLookup.nameOf('action', cardMatrixFilter.actionId!),
|
|
1969
|
+
...(cardMatrixFilter.wikiKind ? { breakdownId: cardMatrixFilter.wikiKind } : {}),
|
|
1967
1970
|
}
|
|
1968
1971
|
return hasScene
|
|
1969
1972
|
? { cell, group: { ...cell, scene: cardMatrixFilter.sceneId === '' ? '' : axisLookup.nameOf('scene', cardMatrixFilter.sceneId!) } }
|
|
@@ -1987,6 +1990,20 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1987
1990
|
const same = cardMatrixFilter.objectId === next.objectId
|
|
1988
1991
|
&& cardMatrixFilter.actionId === next.actionId
|
|
1989
1992
|
&& cardMatrixFilter.sceneId === undefined
|
|
1993
|
+
&& cardMatrixFilter.wikiKind === undefined
|
|
1994
|
+
setCardMatrixFilter(same ? {} : next)
|
|
1995
|
+
}
|
|
1996
|
+
const pickCardBreakdown = (pick: MatrixCellPick, breakdownId: string): void => {
|
|
1997
|
+
if (breakdownId !== 'fact' && breakdownId !== 'way' && breakdownId !== 'unclassified') return
|
|
1998
|
+
const next: CardMatrixFilter = {
|
|
1999
|
+
objectId: cardAxisId('object', pick.object),
|
|
2000
|
+
actionId: cardAxisId('action', pick.action),
|
|
2001
|
+
wikiKind: breakdownId,
|
|
2002
|
+
}
|
|
2003
|
+
const same = cardMatrixFilter.objectId === next.objectId
|
|
2004
|
+
&& cardMatrixFilter.actionId === next.actionId
|
|
2005
|
+
&& cardMatrixFilter.sceneId === undefined
|
|
2006
|
+
&& cardMatrixFilter.wikiKind === next.wikiKind
|
|
1990
2007
|
setCardMatrixFilter(same ? {} : next)
|
|
1991
2008
|
}
|
|
1992
2009
|
const pickCardGroup = (pick: MatrixPick): void => {
|
|
@@ -1998,13 +2015,14 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
1998
2015
|
const same = cardMatrixFilter.objectId === next.objectId
|
|
1999
2016
|
&& cardMatrixFilter.actionId === next.actionId
|
|
2000
2017
|
&& cardMatrixFilter.sceneId === next.sceneId
|
|
2018
|
+
&& cardMatrixFilter.wikiKind === undefined
|
|
2001
2019
|
setCardMatrixFilter(same ? {} : next)
|
|
2002
2020
|
}
|
|
2003
2021
|
const pickCardAxis = (pick: MatrixAxisPick): void => {
|
|
2004
2022
|
const id = cardAxisId(pick.axis, pick.name)
|
|
2005
2023
|
const same = pick.axis === 'object'
|
|
2006
|
-
? cardMatrixFilter.objectId === id && cardMatrixFilter.actionId === undefined && cardMatrixFilter.sceneId === undefined
|
|
2007
|
-
: cardMatrixFilter.actionId === id && cardMatrixFilter.objectId === undefined && cardMatrixFilter.sceneId === undefined
|
|
2024
|
+
? cardMatrixFilter.objectId === id && cardMatrixFilter.actionId === undefined && cardMatrixFilter.sceneId === undefined && cardMatrixFilter.wikiKind === undefined
|
|
2025
|
+
: cardMatrixFilter.actionId === id && cardMatrixFilter.objectId === undefined && cardMatrixFilter.sceneId === undefined && cardMatrixFilter.wikiKind === undefined
|
|
2008
2026
|
setCardMatrixFilter(same ? {} : pick.axis === 'object' ? { objectId: id } : { actionId: id })
|
|
2009
2027
|
}
|
|
2010
2028
|
|
|
@@ -2017,6 +2035,10 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2017
2035
|
&& (cardMatrixFilter.objectId === undefined || (card.coordinate?.objectId ?? '') === cardMatrixFilter.objectId)
|
|
2018
2036
|
&& (cardMatrixFilter.actionId === undefined || (card.coordinate?.actionId ?? '') === cardMatrixFilter.actionId)
|
|
2019
2037
|
&& (cardMatrixFilter.sceneId === undefined || (card.coordinate?.sceneId ?? '') === cardMatrixFilter.sceneId)
|
|
2038
|
+
&& (cardMatrixFilter.wikiKind === undefined
|
|
2039
|
+
|| (cardMatrixFilter.wikiKind === 'unclassified'
|
|
2040
|
+
? card.metadata?.wiki_kind !== 'fact' && card.metadata?.wiki_kind !== 'way'
|
|
2041
|
+
: card.metadata?.wiki_kind === cardMatrixFilter.wikiKind))
|
|
2020
2042
|
&& (!needle || `${card.title}\n${card.entityId}\n${card.summary ?? ''}`.toLocaleLowerCase().includes(needle)))
|
|
2021
2043
|
}, [cards, cardMatrixFilter, cardQuery, cardStatus])
|
|
2022
2044
|
|
|
@@ -2198,32 +2220,34 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2198
2220
|
<AxisMatrix
|
|
2199
2221
|
view={cardMatrixView}
|
|
2200
2222
|
selection={cardMatrixSelection}
|
|
2201
|
-
ariaLabel="
|
|
2223
|
+
ariaLabel="Wiki 矩阵:对象 × 动作,显示 Wiki Fact 与 Wiki Way 数量"
|
|
2202
2224
|
frame={false}
|
|
2203
2225
|
bounded
|
|
2204
2226
|
onPickCell={pickCardCell}
|
|
2227
|
+
onPickBreakdown={pickCardBreakdown}
|
|
2205
2228
|
onPickGroup={pickCardGroup}
|
|
2206
2229
|
onPickAxis={pickCardAxis}
|
|
2207
2230
|
onExpand={() => setCardMatrixFull(true)}
|
|
2208
|
-
title={
|
|
2209
|
-
note="
|
|
2210
|
-
meta={<>{
|
|
2231
|
+
title={<>Wiki 矩阵<span className={styles.blockSub}>(对象 × 动作 × 场景)</span></>}
|
|
2232
|
+
note="总数 + 类型数:F = Wiki Fact · W = Wiki Way;点类型数筛选"
|
|
2233
|
+
meta={<>Fact {cardMatrix.factCount} · Way {cardMatrix.wayCount}</>}
|
|
2211
2234
|
footer={<>
|
|
2212
2235
|
{cardMatrix.sceneOnly > 0 && <p className={styles.trialMore}>另有 {cardMatrix.sceneOnly} 张卡片只有场景,两个主轴为空。</p>}
|
|
2213
2236
|
{cardMatrixView.noCoordinate > 0 && <p className={styles.trialMore}>另有 {cardMatrixView.noCoordinate} 张卡片没有坐标。</p>}
|
|
2237
|
+
{cardMatrix.unclassifiedCount > 0 && <p className={styles.trialMore}>其中有 {cardMatrix.unclassifiedCount} 张 Wiki 尚未归类为 Fact 或 Way;点击格内“未”可筛选有坐标的未归类 Wiki。</p>}
|
|
2214
2238
|
</>}
|
|
2215
2239
|
/>
|
|
2216
2240
|
</section> : null}
|
|
2217
2241
|
<Card className={styles.kbCard}>
|
|
2218
2242
|
<div className={styles.kbCardHead}>
|
|
2219
|
-
<div><h3><FileText size={13}
|
|
2243
|
+
<div><h3><FileText size={13} />Wiki</h3></div>
|
|
2220
2244
|
{/* 构建设置的入口落在这里(2026-10-05 随「知识图谱」分栏一起搬):构建把这批
|
|
2221
2245
|
卡片编成可召回的索引(索引版本写在步骤轨「物化」那一步的第二行),所以参数
|
|
2222
2246
|
留在它加工的东西旁边 —— 与召回、重排把参数放在自己卡头上是同一条规矩。
|
|
2223
2247
|
打开的还是那**一个**设置抽屉,只是落到「构建」分块。 */}
|
|
2224
2248
|
<span className={styles.kbCardActions}>
|
|
2225
2249
|
<span className={styles.kbCount}>
|
|
2226
|
-
{visibleCards.length === cards.length ? `${cards.length}
|
|
2250
|
+
{visibleCards.length === cards.length ? `${cards.length} 张 Wiki` : `筛出 ${visibleCards.length} / ${cards.length} 张 Wiki`}
|
|
2227
2251
|
</span>
|
|
2228
2252
|
{onOpenSettings && <SettingsChip target="build" onOpen={onOpenSettings} />}
|
|
2229
2253
|
</span>
|
|
@@ -2261,20 +2285,21 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2261
2285
|
<Dialog open={cardMatrixFull} onOpenChange={setCardMatrixFull}>
|
|
2262
2286
|
<DialogContent className={styles.matrixDialog}>
|
|
2263
2287
|
<DialogHeader>
|
|
2264
|
-
<DialogTitle className={styles.matrixDialogTitle}
|
|
2288
|
+
<DialogTitle className={styles.matrixDialogTitle}>Wiki 矩阵<span className={styles.blockSub}>(对象 × 动作 × 场景)</span></DialogTitle>
|
|
2265
2289
|
</DialogHeader>
|
|
2266
2290
|
<div className={styles.matrixDialogBody}>
|
|
2267
2291
|
<AxisMatrix
|
|
2268
2292
|
view={cardMatrixView}
|
|
2269
2293
|
selection={cardMatrixSelection}
|
|
2270
|
-
ariaLabel="
|
|
2294
|
+
ariaLabel="Wiki 矩阵:对象 × 动作,显示 Wiki Fact 与 Wiki Way 数量(全屏)"
|
|
2271
2295
|
frame={false}
|
|
2272
2296
|
onPickCell={pickCardCell}
|
|
2297
|
+
onPickBreakdown={pickCardBreakdown}
|
|
2273
2298
|
onPickGroup={pickCardGroup}
|
|
2274
2299
|
onPickAxis={pickCardAxis}
|
|
2275
|
-
title={
|
|
2276
|
-
note="
|
|
2277
|
-
meta={<>{
|
|
2300
|
+
title={<>Wiki 矩阵<span className={styles.blockSub}>(对象 × 动作 × 场景)</span></>}
|
|
2301
|
+
note="总数 + 类型数:F = Wiki Fact · W = Wiki Way;点类型数筛选"
|
|
2302
|
+
meta={<>Fact {cardMatrix.factCount} · Way {cardMatrix.wayCount}</>}
|
|
2278
2303
|
/>
|
|
2279
2304
|
</div>
|
|
2280
2305
|
</DialogContent>
|
|
@@ -2302,10 +2327,13 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2302
2327
|
* 还是在讲卡片?现在它自己一栏,Wiki 只回答后半个问题。
|
|
2303
2328
|
*/
|
|
2304
2329
|
const renderKnowledge = (): ReactNode => <Tabs value={knowledgeContent} onValueChange={value => setKnowledgeContent(value as 'knowledge' | 'procedure' | 'event')}>
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2330
|
+
{/* 三个页签同时给中文名与英文术语:英文是工具与 Wiki 里的正式名(Fact / Procedure /
|
|
2331
|
+
Case),中文是读它的人先认得的词。**页签不挂计数** —— 一栏里已经有分面计数与
|
|
2332
|
+
块头计数,页签再写一个就会变成第三个「有多少」。 */}
|
|
2333
|
+
<TabsList className={cn(styles.tabsList, styles.kbViewTabs)} aria-label="事实、方法与案例分类">
|
|
2334
|
+
<TabsTrigger value="knowledge">事实 <span className="text-[9.5px] font-normal text-tita-ink-faint">Fact</span></TabsTrigger>
|
|
2335
|
+
<TabsTrigger value="procedure">方法 <span className="text-[9.5px] font-normal text-tita-ink-faint">Procedure</span></TabsTrigger>
|
|
2336
|
+
<TabsTrigger value="event">案例 <span className="text-[9.5px] font-normal text-tita-ink-faint">Case</span></TabsTrigger>
|
|
2309
2337
|
</TabsList>
|
|
2310
2338
|
<TabsContent value="knowledge" className={styles.viewStack}>
|
|
2311
2339
|
{orphanNotice()}
|
|
@@ -2327,8 +2355,7 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2327
2355
|
<TabsContent value="event" className={styles.viewStack}>
|
|
2328
2356
|
<div className="flex min-w-0 items-center justify-between gap-2">
|
|
2329
2357
|
<div className="flex min-w-0 items-center gap-2">
|
|
2330
|
-
<h3 className="text-[12px] font-semibold text-tita-ink">Case</h3>
|
|
2331
|
-
<Badge tone="neutral">{events.length}</Badge>
|
|
2358
|
+
<h3 className="text-[12px] font-semibold text-tita-ink">案例 <span className="text-[10px] font-normal text-tita-ink-faint">Case</span></h3>
|
|
2332
2359
|
</div>
|
|
2333
2360
|
<Button variant="ghost" size="icon" aria-label="刷新 Case" title="刷新 Case" disabled={eventsLoading || !activeId} onClick={() => void loadEvents(activeId)}>
|
|
2334
2361
|
<RefreshCw size={13} className={eventsLoading ? 'animate-spin' : undefined} />
|
|
@@ -2366,8 +2393,9 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2366
2393
|
还和库选择器里那行菜单重复了一遍 —— 同一件事两个入口,就会有人改完一处
|
|
2367
2394
|
以为另一处也跟着变了。库路径也不在这里了:它是「存储位置」设置,
|
|
2368
2395
|
入口在面板顶部的齿轮里。
|
|
2369
|
-
0034
|
|
2370
|
-
|
|
2396
|
+
0034:「编译设置」曾挂在这一行 —— 它是**按库**的动作,而它**不是**第六个步骤:
|
|
2397
|
+
步骤轨是一条流水线,定义不属于任何一段。2026-10-28 起它搬进知识处理整页,
|
|
2398
|
+
与「解析内核」一起,只在那一个页面上留入口。
|
|
2371
2399
|
0035:**计数撤出这一行**,动作左对齐。计数没有丢 —— 步骤轨每一步第二行写的就是
|
|
2372
2400
|
「这一段现在有多少东西」(`stepFacts`),而这一行只回答「能对它做什么」。
|
|
2373
2401
|
2026-10-05:**知识库入口整条撤掉**(用户要求)。它原先在最左边,显示库名或选择器,
|
|
@@ -2376,41 +2404,18 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2376
2404
|
去改它,等于把一个部署级的事实伪装成一个可以随手切换的视图。默认库由
|
|
2377
2405
|
`seedDefault()` 保证存在,所以撤掉「新建」也不会留下一个建不出库的空部署。 */}
|
|
2378
2406
|
<div className={styles.kbToolbar}>
|
|
2379
|
-
{/*
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
直接 deny,表现就是「点了没有任何反应,也不报错」。
|
|
2384
|
-
现在走 `openAppPath()`:浏览器态开新标签页,桌面壳里换成 Host 的绝对地址再交给
|
|
2385
|
-
系统浏览器。**同一枚按钮,两种外壳做各自成立的那件事。**
|
|
2386
|
-
0042:「编译」原本在 wiki 栏的统计卡里(增量 + 全量两枚),现在它是**工具栏的
|
|
2387
|
-
一个动作** —— 编译是「对这个库做什么」,它和「选哪个库」「编译设置」同层,
|
|
2388
|
-
不属于任何一栏的内容。 */}
|
|
2407
|
+
{/* 一行一个动作:outline + 图标,同一个 30px 高。
|
|
2408
|
+
0042:「编译」原本在 wiki 栏的统计卡里,后来是工具栏的一个动作。
|
|
2409
|
+
2026-10-28:编译设置与解析内核的入口都搬进知识处理整页 —— 面板不再同时
|
|
2410
|
+
兼任「处理现场」与「参数 / 上游工具」两种角色。 */}
|
|
2389
2411
|
<span className={styles.kbToolbarActions}>
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
><Tags size={13} />编译设置</Button>
|
|
2397
|
-
{/* 一行顶栏里**一个入口**。此前这里是两枚(「知识处理」与「任务历史」),
|
|
2398
|
-
打开的却是同一个地址的两个位置 —— 同一样东西两个入口,人就会以为它们是两件事,
|
|
2399
|
-
点完一个再点另一个来确认「历史是不是同一份」。整合后只剩这一枚:
|
|
2400
|
-
页面上半段是四段阶段,下半段右侧就是运行记录,一屏之内都读得到。 */}
|
|
2401
|
-
<Button variant="outline" size="sm" disabled={!active} title="运行阶段、处理范围与运行记录" onClick={() => {
|
|
2402
|
-
if (active) void fullPage.open({ src: `/knowledge/pages/tasks?kb=${encodeURIComponent(active.id)}`, title: '知识处理与运行记录' })
|
|
2412
|
+
{/* 一行顶栏里**一个入口**。此前这里是三枚(编译设置 / 知识处理 / 解析内核),
|
|
2413
|
+
打开的是同一件事的三个位置 —— 编译设置改的就是这条流水线的模型与坐标,
|
|
2414
|
+
解析内核是它的上游。2026-10-28 起它们都住在知识处理整页里:
|
|
2415
|
+
面板这一行只回答「去哪处理这个库」,不再兼任设置与上游工具。 */}
|
|
2416
|
+
<Button variant="outline" size="sm" disabled={!active} title="运行阶段、处理范围、编译设置与轨迹" onClick={() => {
|
|
2417
|
+
if (active) void fullPage.open({ src: `/knowledge/pages/tasks?kb=${encodeURIComponent(active.id)}`, title: '知识处理' })
|
|
2403
2418
|
}}><Layers3 size={14} />知识处理</Button>
|
|
2404
|
-
<Button
|
|
2405
|
-
variant="outline"
|
|
2406
|
-
size="sm"
|
|
2407
|
-
title="打开解析内核控制台"
|
|
2408
|
-
onClick={() => { void openAppPath('/convert/').then(opened => {
|
|
2409
|
-
// 打不开就如实说。桌面壳拿不到 Host 地址时 `window.open` 会被静默拒绝 ——
|
|
2410
|
-
// 那种「点了没反应」正是这次要修掉的东西,不能换个地方再犯一次。
|
|
2411
|
-
if (!opened) setNotice({ tone: 'error', text: '打不开解析内核控制台:当前外壳下拿不到它的地址。' })
|
|
2412
|
-
}) }}
|
|
2413
|
-
><FileUp size={14} />解析内核</Button>
|
|
2414
2419
|
</span>
|
|
2415
2420
|
{/* 说明靠右、动作靠左:这一行的主语是一排按钮,`?` 是这一排的脚注,
|
|
2416
2421
|
所以它自己站在最右侧,而不是挤进按钮之间(挤进去会被读成某一枚按钮的附件)。 */}
|
|
@@ -2494,18 +2499,6 @@ export function KnowledgeBaseTab({ visible, onChanged, onActiveBaseChange, knowl
|
|
|
2494
2499
|
onRetryFailed={() => void runImportQueue()}
|
|
2495
2500
|
/>
|
|
2496
2501
|
|
|
2497
|
-
{/* 本库的坐标实体与抽取备注:按库持久化,和方案级设置分开。 */}
|
|
2498
|
-
{active && <TypeDefinitionDrawer
|
|
2499
|
-
open={typeDef}
|
|
2500
|
-
onOpenChange={setTypeDef}
|
|
2501
|
-
kbId={active.id}
|
|
2502
|
-
busy={busy}
|
|
2503
|
-
extractionNote={active.extractionNote ?? ''}
|
|
2504
|
-
onSaveExtractionNote={saveExtractionNote}
|
|
2505
|
-
compileModel={active.compileModel ?? { mode: 'default' }}
|
|
2506
|
-
onSaveCompileModel={saveCompileModel}
|
|
2507
|
-
/>}
|
|
2508
|
-
|
|
2509
2502
|
<RestoreDialog
|
|
2510
2503
|
open={restoreTarget !== null}
|
|
2511
2504
|
onOpenChange={open => { if (!open) setRestoreTarget(null) }}
|