dsh-data-domain-knowledge 0.1.0-alpha.9 → 0.1.1-alpha.2
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 +118 -567
- package/cordis.patch.yml +5 -418
- package/eval/README.md +19 -8
- package/eval/benchmark-extraction-format.mjs +20 -0
- package/eval/evaluate-retrieval.mjs +17 -8
- package/eval/queries.example.jsonl +1 -0
- package/lib/client.js +4181 -3239
- package/lib/contract-envelope.d.ts +91 -0
- package/lib/contract-envelope.js +106 -0
- package/lib/contract-layout.d.ts +130 -0
- package/lib/contract-layout.js +138 -0
- package/lib/contract-refs.d.ts +39 -0
- package/lib/contract-refs.js +9 -0
- package/lib/contract-version.d.ts +311 -0
- package/lib/contract-version.js +270 -0
- package/lib/contract-wire.d.ts +147 -0
- package/lib/contract-wire.js +99 -0
- package/lib/contracts.d.ts +12 -0
- package/lib/contracts.js +12 -0
- package/lib/doc-page.js +2 -2
- package/lib/pages.js +3329 -1296
- package/lib/types/agent-behavior-rules.d.ts +10 -0
- package/lib/types/agent-behavior-rules.d.ts.map +1 -0
- package/lib/types/agent-behavior-rules.js +28 -0
- package/lib/types/agent-behavior-rules.js.map +1 -0
- package/lib/types/axis-registry.d.ts +37 -5
- package/lib/types/axis-registry.d.ts.map +1 -1
- package/lib/types/axis-registry.js +234 -26
- package/lib/types/axis-registry.js.map +1 -1
- package/lib/types/card-organize.d.ts +27 -12
- package/lib/types/card-organize.d.ts.map +1 -1
- package/lib/types/card-organize.js +58 -73
- package/lib/types/card-organize.js.map +1 -1
- package/lib/types/compiler/embedding-identity.d.ts +3 -0
- package/lib/types/compiler/embedding-identity.d.ts.map +1 -0
- package/lib/types/compiler/embedding-identity.js +24 -0
- package/lib/types/compiler/embedding-identity.js.map +1 -0
- package/lib/types/compiler/snapshot.d.ts +16 -0
- package/lib/types/compiler/snapshot.d.ts.map +1 -0
- package/lib/types/compiler/snapshot.js +2 -0
- package/lib/types/compiler/snapshot.js.map +1 -0
- package/lib/types/config-schema.d.ts +6 -3
- package/lib/types/config-schema.d.ts.map +1 -1
- package/lib/types/config-schema.js +6 -2
- package/lib/types/config-schema.js.map +1 -1
- package/lib/types/convert/host.d.ts +6 -5
- package/lib/types/convert/host.d.ts.map +1 -1
- package/lib/types/convert/host.js +58 -18
- package/lib/types/convert/host.js.map +1 -1
- package/lib/types/convert/ingest.d.ts +10 -1
- package/lib/types/convert/ingest.d.ts.map +1 -1
- package/lib/types/convert/ingest.js +68 -9
- package/lib/types/convert/ingest.js.map +1 -1
- package/lib/types/derive-contract.d.ts +3 -0
- package/lib/types/derive-contract.d.ts.map +1 -0
- package/lib/types/derive-contract.js +15 -0
- package/lib/types/derive-contract.js.map +1 -0
- package/lib/types/diagnosis/cards.d.ts +7 -3
- package/lib/types/diagnosis/cards.d.ts.map +1 -1
- package/lib/types/diagnosis/cards.js +13 -8
- package/lib/types/diagnosis/cards.js.map +1 -1
- package/lib/types/diagnosis/run.d.ts +4 -13
- package/lib/types/diagnosis/run.d.ts.map +1 -1
- package/lib/types/diagnosis/run.js +26 -16
- package/lib/types/diagnosis/run.js.map +1 -1
- package/lib/types/diagnosis/schema.js +2 -2
- package/lib/types/diagnosis/schema.js.map +1 -1
- package/lib/types/diagnosis/seed-source.d.ts +1 -1
- package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
- package/lib/types/diagnosis/seed-source.js +5 -4
- package/lib/types/diagnosis/seed-source.js.map +1 -1
- package/lib/types/diagnosis/seed.d.ts +4 -4
- package/lib/types/diagnosis/seed.d.ts.map +1 -1
- package/lib/types/diagnosis/seed.js +6 -8
- package/lib/types/diagnosis/seed.js.map +1 -1
- package/lib/types/diagnosis/store.d.ts +24 -18
- package/lib/types/diagnosis/store.d.ts.map +1 -1
- package/lib/types/diagnosis/store.js +130 -65
- package/lib/types/diagnosis/store.js.map +1 -1
- package/lib/types/diagnosis/types.d.ts +47 -15
- package/lib/types/diagnosis/types.d.ts.map +1 -1
- package/lib/types/diagnosis/types.js.map +1 -1
- package/lib/types/environment/dsh-python.d.ts +77 -0
- package/lib/types/environment/dsh-python.d.ts.map +1 -0
- package/lib/types/environment/dsh-python.js +139 -0
- package/lib/types/environment/dsh-python.js.map +1 -0
- package/lib/types/environment/install.d.ts +15 -0
- package/lib/types/environment/install.d.ts.map +1 -0
- package/lib/types/environment/install.js +297 -0
- package/lib/types/environment/install.js.map +1 -0
- package/lib/types/environment/manifest.d.ts +208 -0
- package/lib/types/environment/manifest.d.ts.map +1 -0
- package/lib/types/environment/manifest.js +26 -0
- package/lib/types/environment/manifest.js.map +1 -0
- package/lib/types/environment/model-catalog.d.ts +223 -0
- package/lib/types/environment/model-catalog.d.ts.map +1 -0
- package/lib/types/environment/model-catalog.js +129 -0
- package/lib/types/environment/model-catalog.js.map +1 -0
- package/lib/types/environment/process.d.ts +10 -0
- package/lib/types/environment/process.d.ts.map +1 -0
- package/lib/types/environment/process.js +54 -0
- package/lib/types/environment/process.js.map +1 -0
- package/lib/types/environment/selection.d.ts +9 -0
- package/lib/types/environment/selection.d.ts.map +1 -0
- package/lib/types/environment/selection.js +29 -0
- package/lib/types/environment/selection.js.map +1 -0
- package/lib/types/environment/service.d.ts +64 -0
- package/lib/types/environment/service.d.ts.map +1 -0
- package/lib/types/environment/service.js +424 -0
- package/lib/types/environment/service.js.map +1 -0
- package/lib/types/environment/types.d.ts +56 -0
- package/lib/types/environment/types.d.ts.map +1 -0
- package/lib/types/environment/types.js +2 -0
- package/lib/types/environment/types.js.map +1 -0
- package/lib/types/events.d.ts +76 -0
- package/lib/types/events.d.ts.map +1 -0
- package/lib/types/events.js +52 -0
- package/lib/types/events.js.map +1 -0
- package/lib/types/extract-contract.d.ts +3 -0
- package/lib/types/extract-contract.d.ts.map +1 -0
- package/lib/types/extract-contract.js +41 -0
- package/lib/types/extract-contract.js.map +1 -0
- package/lib/types/extract-model.d.ts +5 -0
- package/lib/types/extract-model.d.ts.map +1 -1
- package/lib/types/extract-model.js.map +1 -1
- package/lib/types/extract-table-contract.d.ts +3 -0
- package/lib/types/extract-table-contract.d.ts.map +1 -0
- package/lib/types/extract-table-contract.js +27 -0
- package/lib/types/extract-table-contract.js.map +1 -0
- package/lib/types/extract-table.d.ts +8 -0
- package/lib/types/extract-table.d.ts.map +1 -0
- package/lib/types/extract-table.js +158 -0
- package/lib/types/extract-table.js.map +1 -0
- package/lib/types/extraction-runs.d.ts +30 -6
- package/lib/types/extraction-runs.d.ts.map +1 -1
- package/lib/types/extraction-runs.js +69 -8
- package/lib/types/extraction-runs.js.map +1 -1
- package/lib/types/fs-atomic.d.ts +0 -7
- package/lib/types/fs-atomic.d.ts.map +1 -1
- package/lib/types/fs-atomic.js +17 -2
- package/lib/types/fs-atomic.js.map +1 -1
- package/lib/types/images.d.ts +26 -0
- package/lib/types/images.d.ts.map +1 -0
- package/lib/types/images.js +196 -0
- package/lib/types/images.js.map +1 -0
- package/lib/types/index.d.ts +2 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +598 -209
- package/lib/types/index.js.map +1 -1
- package/lib/types/intent/engine.d.ts +12 -4
- package/lib/types/intent/engine.d.ts.map +1 -1
- package/lib/types/intent/engine.js +43 -5
- package/lib/types/intent/engine.js.map +1 -1
- package/lib/types/intent/host.d.ts +5 -8
- package/lib/types/intent/host.d.ts.map +1 -1
- package/lib/types/intent/host.js +56 -11
- package/lib/types/intent/host.js.map +1 -1
- package/lib/types/intent/scope.d.ts +25 -0
- package/lib/types/intent/scope.d.ts.map +1 -0
- package/lib/types/intent/scope.js +116 -0
- package/lib/types/intent/scope.js.map +1 -0
- package/lib/types/intent/tools.d.ts +24 -20
- package/lib/types/intent/tools.d.ts.map +1 -1
- package/lib/types/intent/tools.js +65 -23
- package/lib/types/intent/tools.js.map +1 -1
- package/lib/types/intent/types.d.ts +11 -4
- package/lib/types/intent/types.d.ts.map +1 -1
- package/lib/types/knowledge-bases.d.ts +11 -5
- package/lib/types/knowledge-bases.d.ts.map +1 -1
- package/lib/types/knowledge-bases.js +52 -20
- package/lib/types/knowledge-bases.js.map +1 -1
- package/lib/types/knowledge-contract.d.ts +32 -0
- package/lib/types/knowledge-contract.d.ts.map +1 -0
- package/lib/types/knowledge-contract.js +116 -0
- package/lib/types/knowledge-contract.js.map +1 -0
- package/lib/types/knowledge.d.ts +31 -9
- package/lib/types/knowledge.d.ts.map +1 -1
- package/lib/types/knowledge.js +137 -60
- package/lib/types/knowledge.js.map +1 -1
- package/lib/types/layout.d.ts +10 -29
- package/lib/types/layout.d.ts.map +1 -1
- package/lib/types/layout.js +17 -36
- package/lib/types/layout.js.map +1 -1
- package/lib/types/materialize-snapshot.d.ts +49 -0
- package/lib/types/materialize-snapshot.d.ts.map +1 -0
- package/lib/types/materialize-snapshot.js +2 -0
- package/lib/types/materialize-snapshot.js.map +1 -0
- package/lib/types/migrate.d.ts +11 -0
- package/lib/types/migrate.d.ts.map +1 -1
- package/lib/types/migrate.js +83 -2
- package/lib/types/migrate.js.map +1 -1
- package/lib/types/model-text.d.ts +58 -1
- package/lib/types/model-text.d.ts.map +1 -1
- package/lib/types/model-text.js +85 -30
- package/lib/types/model-text.js.map +1 -1
- package/lib/types/oplog.d.ts.map +1 -1
- package/lib/types/oplog.js +7 -0
- package/lib/types/oplog.js.map +1 -1
- package/lib/types/organize-contract.d.ts +18 -0
- package/lib/types/organize-contract.d.ts.map +1 -0
- package/lib/types/organize-contract.js +82 -0
- package/lib/types/organize-contract.js.map +1 -0
- package/lib/types/pipeline/engine.d.ts +66 -0
- package/lib/types/pipeline/engine.d.ts.map +1 -0
- package/lib/types/pipeline/engine.js +352 -0
- package/lib/types/pipeline/engine.js.map +1 -0
- package/lib/types/pipeline/store.d.ts +73 -0
- package/lib/types/pipeline/store.d.ts.map +1 -0
- package/lib/types/pipeline/store.js +143 -0
- package/lib/types/pipeline/store.js.map +1 -0
- package/lib/types/pipeline/types.d.ts +102 -0
- package/lib/types/pipeline/types.d.ts.map +1 -0
- package/lib/types/pipeline/types.js +5 -0
- package/lib/types/pipeline/types.js.map +1 -0
- package/lib/types/present.d.ts +2 -0
- package/lib/types/present.d.ts.map +1 -1
- package/lib/types/present.js +9 -4
- package/lib/types/present.js.map +1 -1
- package/lib/types/preset-ids.d.ts +4 -0
- package/lib/types/preset-ids.d.ts.map +1 -0
- package/lib/types/preset-ids.js +6 -0
- package/lib/types/preset-ids.js.map +1 -0
- package/lib/types/query-analysis.d.ts +13 -1
- package/lib/types/query-analysis.d.ts.map +1 -1
- package/lib/types/query-analysis.js +62 -6
- package/lib/types/query-analysis.js.map +1 -1
- package/lib/types/recall-rank.d.ts +3 -3
- package/lib/types/recall-rank.d.ts.map +1 -1
- package/lib/types/recall-rank.js +4 -4
- package/lib/types/recall-rank.js.map +1 -1
- package/lib/types/retention.d.ts +39 -0
- package/lib/types/retention.d.ts.map +1 -0
- package/lib/types/retention.js +42 -0
- package/lib/types/retention.js.map +1 -0
- package/lib/types/retrieval/vector-index.d.ts +32 -0
- package/lib/types/retrieval/vector-index.d.ts.map +1 -0
- package/lib/types/retrieval/vector-index.js +15 -0
- package/lib/types/retrieval/vector-index.js.map +1 -0
- package/lib/types/retrieval/visibility.d.ts +6 -0
- package/lib/types/retrieval/visibility.d.ts.map +1 -0
- package/lib/types/retrieval/visibility.js +11 -0
- package/lib/types/retrieval/visibility.js.map +1 -0
- package/lib/types/runtime.d.ts +272 -27
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/runtime.js +2751 -537
- package/lib/types/runtime.js.map +1 -1
- package/lib/types/settings-schema.d.ts +17 -15
- package/lib/types/settings-schema.d.ts.map +1 -1
- package/lib/types/settings-schema.js +50 -47
- package/lib/types/settings-schema.js.map +1 -1
- package/lib/types/settings-volatile.d.ts +4 -4
- package/lib/types/settings-volatile.js +4 -4
- package/lib/types/source-evidence.d.ts +14 -0
- package/lib/types/source-evidence.d.ts.map +1 -0
- package/lib/types/source-evidence.js +36 -0
- package/lib/types/source-evidence.js.map +1 -0
- package/lib/types/store/axis-references.d.ts +5 -0
- package/lib/types/store/axis-references.d.ts.map +1 -0
- package/lib/types/store/axis-references.js +106 -0
- package/lib/types/store/axis-references.js.map +1 -0
- package/lib/types/store/derived.d.ts +12 -1
- package/lib/types/store/derived.d.ts.map +1 -1
- package/lib/types/store/derived.js +71 -12
- package/lib/types/store/derived.js.map +1 -1
- package/lib/types/store/knowledge-db.d.ts +31 -1
- package/lib/types/store/knowledge-db.d.ts.map +1 -1
- package/lib/types/store/knowledge-db.js +252 -18
- package/lib/types/store/knowledge-db.js.map +1 -1
- package/lib/types/store/migrate.d.ts.map +1 -1
- package/lib/types/store/migrate.js +17 -6
- package/lib/types/store/migrate.js.map +1 -1
- package/lib/types/trajectory-types.d.ts +172 -0
- package/lib/types/trajectory-types.d.ts.map +1 -0
- package/lib/types/trajectory-types.js +36 -0
- package/lib/types/trajectory-types.js.map +1 -0
- package/lib/types/types.d.ts +59 -27
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js +6 -15
- package/lib/types/types.js.map +1 -1
- package/lib/types/wiki-finalize.d.ts +16 -0
- package/lib/types/wiki-finalize.d.ts.map +1 -1
- package/lib/types/wiki-finalize.js +26 -0
- package/lib/types/wiki-finalize.js.map +1 -1
- package/lib/types/wiki-materialize.d.ts +4 -0
- package/lib/types/wiki-materialize.d.ts.map +1 -1
- package/lib/types/wiki-materialize.js +21 -7
- package/lib/types/wiki-materialize.js.map +1 -1
- package/lib/types/wiki-trial-types.d.ts +87 -0
- package/lib/types/wiki-trial-types.d.ts.map +1 -1
- package/lib/types/wiki-trial-types.js +0 -16
- package/lib/types/wiki-trial-types.js.map +1 -1
- package/lib/types/wiki-trial.d.ts +40 -16
- package/lib/types/wiki-trial.d.ts.map +1 -1
- package/lib/types/wiki-trial.js +337 -224
- package/lib/types/wiki-trial.js.map +1 -1
- package/package.json +29 -20
- package/python/prepare-models.py +19 -0
- package/python/requirements.txt +8 -6
- package/scripts/doctor.mjs +13 -19
- package/scripts/environment.mjs +29 -0
- package/scripts/setup-embedding.sh +15 -5
- package/src/agent-behavior-rules.ts +37 -0
- package/src/axis-registry.ts +234 -27
- package/src/card-organize.ts +69 -75
- package/src/client/AgentBehaviorRulesCard.tsx +65 -0
- package/src/client/AttributionEventGuide.tsx +41 -39
- package/src/client/AxisRegistrySection.tsx +204 -164
- package/src/client/CompileDialogs.tsx +44 -29
- package/src/client/DeleteDocumentDialog.tsx +36 -5
- package/src/client/DirectoryPicker.tsx +0 -10
- package/src/client/EnvironmentSetup.tsx +243 -0
- package/src/client/ExpansionGraph.tsx +13 -7
- package/src/client/ExtractionTasksPage.tsx +578 -0
- package/src/client/GuideArchitectureCanvas.tsx +470 -0
- package/src/client/ImportFilesDialog.tsx +2 -13
- package/src/client/IntentLogic.tsx +2 -2
- package/src/client/IntentTab.tsx +118 -47
- package/src/client/KnowledgeBaseTab.tsx +277 -197
- package/src/client/KnowledgeLayerSection.tsx +24 -6
- package/src/client/KnowledgePanel.tsx +58 -93
- package/src/client/KnowledgeSettingsDrawer.tsx +90 -0
- package/src/client/ListPager.tsx +15 -5
- package/src/client/MaterializeTrajectoryView.tsx +124 -0
- package/src/client/NodeSettings.tsx +210 -89
- package/src/client/NormalizeTrajectoryView.tsx +136 -0
- package/src/client/PipelineNotice.tsx +26 -0
- package/src/client/PreviewSections.tsx +118 -51
- package/src/client/RecallPanel.tsx +89 -85
- package/src/client/TabGuide.tsx +159 -184
- package/src/client/TrialReportView.tsx +391 -214
- package/src/client/TypeDefinitionDrawer.tsx +150 -23
- package/src/client/WikiCardPreview.tsx +62 -16
- package/src/client/WikiFlowPanel.tsx +4 -4
- package/src/client/arch/NodeLogicPanel.tsx +3 -4
- package/src/client/arch/model.ts +6 -9
- package/src/client/architecture.tsx +23 -33
- package/src/client/attribution/AttributionGraph.tsx +10 -6
- package/src/client/attribution/AttributionTab.tsx +136 -84
- package/src/client/attribution/CaseView.tsx +3 -1
- package/src/client/attribution/EventView.tsx +108 -0
- package/src/client/attribution/RunView.tsx +2 -2
- package/src/client/attribution/StageChrome.tsx +34 -3
- package/src/client/attribution/ViewSwitch.tsx +20 -5
- package/src/client/attribution/graph-options.ts +47 -39
- package/src/client/attribution/model.ts +17 -10
- package/src/client/config-scope.ts +3 -3
- package/src/client/graph/palette.ts +165 -0
- package/src/client/index.ts +49 -42
- package/src/client/pages.css +459 -135
- package/src/client/pages.tsx +37 -9
- package/src/client/problem-domains.ts +1 -1
- package/src/client/session-remote.ts +9 -0
- package/src/client/styles.css +205 -62
- package/src/client/wiki-trial.ts +44 -3
- package/src/compiler/embedding-identity.ts +21 -0
- package/src/compiler/snapshot.ts +17 -0
- package/src/config-schema.ts +8 -3
- package/src/convert/host.ts +56 -21
- package/src/convert/ingest.ts +74 -10
- package/src/derive-contract.ts +14 -0
- package/src/diagnosis/cards.ts +13 -8
- package/src/diagnosis/run.ts +27 -17
- package/src/diagnosis/schema.ts +2 -2
- package/src/diagnosis/seed-source.ts +5 -4
- package/src/diagnosis/seed.ts +6 -8
- package/src/diagnosis/store.ts +138 -69
- package/src/diagnosis/types.ts +34 -15
- package/src/environment/dsh-python.ts +156 -0
- package/src/environment/install.ts +244 -0
- package/src/environment/manifest.ts +28 -0
- package/src/environment/model-catalog.ts +147 -0
- package/src/environment/process.ts +54 -0
- package/src/environment/selection.ts +29 -0
- package/src/environment/service.ts +348 -0
- package/src/environment/types.ts +45 -0
- package/src/events.ts +108 -0
- package/src/extract-contract.ts +42 -0
- package/src/extract-model.ts +10 -1
- package/src/extract-table-contract.ts +26 -0
- package/src/extract-table.ts +132 -0
- package/src/extraction-runs.ts +70 -11
- package/src/fs-atomic.ts +19 -2
- package/src/images.ts +203 -0
- package/src/index.ts +553 -205
- package/src/intent/README.md +8 -6
- package/src/intent/engine.ts +44 -6
- package/src/intent/host.ts +59 -18
- package/src/intent/scope.ts +125 -0
- package/src/intent/tools.ts +70 -28
- package/src/intent/types.ts +11 -4
- package/src/knowledge-bases.ts +56 -20
- package/src/knowledge-contract.ts +114 -0
- package/src/knowledge.ts +138 -69
- package/src/layout.ts +17 -37
- package/src/materialize-snapshot.ts +46 -0
- package/src/migrate.ts +75 -2
- package/src/model-text.ts +109 -4
- package/src/oplog.ts +7 -0
- package/src/organize-contract.ts +83 -0
- package/src/pipeline/engine.ts +323 -0
- package/src/pipeline/store.ts +147 -0
- package/src/pipeline/types.ts +93 -0
- package/src/present.ts +10 -4
- package/src/preset-ids.ts +6 -0
- package/src/python/embedding_worker.py +66 -2
- package/src/query-analysis.ts +68 -8
- package/src/recall-rank.ts +5 -5
- package/src/retention.ts +76 -0
- package/src/retrieval/vector-index.ts +45 -0
- package/src/retrieval/visibility.ts +14 -0
- package/src/runtime.ts +2708 -567
- package/src/settings-schema.ts +11 -8
- package/src/settings-volatile.ts +4 -4
- package/src/source-evidence.ts +37 -0
- package/src/store/axis-references.ts +96 -0
- package/src/store/derived.ts +70 -12
- package/src/store/knowledge-db.ts +248 -17
- package/src/store/migrate.ts +16 -6
- package/src/trajectory-types.ts +142 -0
- package/src/types.ts +61 -35
- package/src/wiki-finalize.ts +28 -0
- package/src/wiki-materialize.ts +25 -6
- package/src/wiki-trial-types.ts +83 -1
- package/src/wiki-trial.ts +357 -185
- package/lib/types/intent/preset-tools.d.ts +0 -37
- package/lib/types/intent/preset-tools.d.ts.map +0 -1
- package/lib/types/intent/preset-tools.js +0 -45
- package/lib/types/intent/preset-tools.js.map +0 -1
- package/preset/tita-data-agent/agent.cordis.yml +0 -394
- package/preset/tita-data-agent/preset.yml +0 -3
- package/scripts/install-agent-preset.mjs +0 -92
- package/scripts/sync-agent-preset.mjs +0 -188
- package/src/client/AgentPresetCard.tsx +0 -247
- package/src/client/agent-preset.ts +0 -121
- package/src/client/convert/ConvertPanel.tsx +0 -583
- package/src/client/convert/styles.css +0 -138
- package/src/client/convert/styles.ts +0 -49
- package/src/intent/preset-tools.ts +0 -48
|
@@ -49,6 +49,8 @@ export interface CompileProgressView {
|
|
|
49
49
|
* 那里才同时看得到两种类型。
|
|
50
50
|
*/
|
|
51
51
|
runId: string
|
|
52
|
+
state?: 'queued' | 'running' | 'pausing' | 'paused' | 'cancelling' | 'succeeded' | 'failed' | 'cancelled'
|
|
53
|
+
queuedAt?: string
|
|
52
54
|
only: string
|
|
53
55
|
startedAt: string
|
|
54
56
|
finishedAt?: string
|
|
@@ -82,6 +84,26 @@ export const COMPILE_STEP_TITLE: Record<string, string> = {
|
|
|
82
84
|
build: '构建(向量 + 图谱)',
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
/** 编译弹窗与任务页共用同一份步骤展示。 */
|
|
88
|
+
export function CompileStepList({ steps }: { steps: CompileStepView[] }): ReactNode {
|
|
89
|
+
return <ul className={styles.compileSteps}>
|
|
90
|
+
{steps.map((step, index) => <li key={step.id} className={cn(styles.compileStep, step.state === 'done' && styles.compileStepDone)}>
|
|
91
|
+
<span className={cn(styles.compileDot, step.state === 'done' && styles.compileDotDone, step.state === 'running' && styles.compileDotRunning)} aria-hidden="true">
|
|
92
|
+
{step.state === 'done' ? <Check size={12} /> : step.state === 'running' ? <RefreshCw size={11} className={styles.compileSpin} /> : index + 1}
|
|
93
|
+
</span>
|
|
94
|
+
<span className={styles.compileStepBody}>
|
|
95
|
+
<span className={styles.compileStepTitle}>step{index + 1} · {COMPILE_STEP_TITLE[step.id] ?? step.id}</span>
|
|
96
|
+
<span className={styles.compileFacts}>
|
|
97
|
+
{step.facts.map((fact, at) => <span key={at}>{fact}</span>)}
|
|
98
|
+
</span>
|
|
99
|
+
</span>
|
|
100
|
+
<span className={styles.compileState}>
|
|
101
|
+
{step.state === 'done' ? '已完成' : step.state === 'running' ? '进行中' : '待执行'}
|
|
102
|
+
</span>
|
|
103
|
+
</li>)}
|
|
104
|
+
</ul>
|
|
105
|
+
}
|
|
106
|
+
|
|
85
107
|
/** `00:42` / `01:12`。超过一小时也只是多两位,不做「1 小时 2 分」。 */
|
|
86
108
|
function elapsed(from: string, to: number): string {
|
|
87
109
|
const ms = to - new Date(from).getTime()
|
|
@@ -99,8 +121,16 @@ function elapsed(from: string, to: number): string {
|
|
|
99
121
|
* 条形只是让人一眼看出「大概到哪了」,精确的账在文字里。没有这一行文字,那条按阶段均分
|
|
100
122
|
* 的进度条就会被当成精确值,而在「抽取」这一段特别慢的库里它会显得长期不动。
|
|
101
123
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
124
|
+
/**
|
|
125
|
+
* 编译进度 → 0..1 的比例。**这是唯一一份**(0070)。
|
|
126
|
+
*
|
|
127
|
+
* 曾经有两个副本,而它们对「已结束」的处理不一致:一个只要 `finishedAt` 存在就返回
|
|
128
|
+
* 满格(把 failed / cancelled 也画成「完成」),另一个排除了这两种状态。同一个失败在
|
|
129
|
+
* 导入对话框里是满格主色、在编译对话框里是红色未完成 —— 两屏说两件事。
|
|
130
|
+
* 所以导出它,让两个消费者用同一份判断。
|
|
131
|
+
*/
|
|
132
|
+
export function compileRatio(progress: CompileProgressView): number {
|
|
133
|
+
if (progress.finishedAt !== undefined && progress.state !== 'cancelled' && progress.state !== 'failed') return 1
|
|
104
134
|
const total = progress.steps.length || 1
|
|
105
135
|
const done = progress.steps.filter(step => step.state === 'done').length
|
|
106
136
|
const running = progress.steps.find(step => step.state === 'running')
|
|
@@ -134,7 +164,7 @@ export function CompileProgressDialog({ open, onOpenChange, progress, mine, queu
|
|
|
134
164
|
* 不是「从这个框出现开始算」。跑完之后停表,不再继续跳。
|
|
135
165
|
*/
|
|
136
166
|
const [now, setNow] = useState(() => Date.now())
|
|
137
|
-
const running = progress !== null && progress.finishedAt === undefined
|
|
167
|
+
const running = progress !== null && progress.finishedAt === undefined && progress.state !== 'paused'
|
|
138
168
|
useEffect(() => {
|
|
139
169
|
if (!open || !running) return undefined
|
|
140
170
|
const timer = window.setInterval(() => setNow(Date.now()), 1000)
|
|
@@ -143,7 +173,10 @@ export function CompileProgressDialog({ open, onOpenChange, progress, mine, queu
|
|
|
143
173
|
|
|
144
174
|
if (!open) return null
|
|
145
175
|
const done = progress?.finishedAt !== undefined
|
|
146
|
-
const
|
|
176
|
+
const completed = done && progress?.state !== 'cancelled' && progress?.state !== 'failed'
|
|
177
|
+
const stopped = progress?.state === 'cancelled'
|
|
178
|
+
const failed = progress?.state === 'failed'
|
|
179
|
+
const ratio = progress === null ? 0 : compileRatio(progress)
|
|
147
180
|
const doneSteps = progress?.steps.filter(step => step.state === 'done').length ?? 0
|
|
148
181
|
const finishedText = progress?.outcome
|
|
149
182
|
?? (progress === null ? (queued === true ? '排在前面那一次编译之后,轮到它就会开始。' : '正在建立编译任务…') : '编译结束。')
|
|
@@ -152,7 +185,7 @@ export function CompileProgressDialog({ open, onOpenChange, progress, mine, queu
|
|
|
152
185
|
<DialogContent className={styles.compileDialog}>
|
|
153
186
|
<DialogHeader>
|
|
154
187
|
<div className={styles.compileHead}>
|
|
155
|
-
|
|
188
|
+
<DialogTitle>{stopped ? '任务已停止' : failed ? '编译失败' : done ? '编译完成' : '全量重新编译'}</DialogTitle>
|
|
156
189
|
{/* 钟与控制点同一行:用时是这一屏唯一的「长了多久」,它不该另占一行。 */}
|
|
157
190
|
<span className={styles.compileClock}>
|
|
158
191
|
<Clock3 size={13} aria-hidden="true" />
|
|
@@ -169,38 +202,20 @@ export function CompileProgressDialog({ open, onOpenChange, progress, mine, queu
|
|
|
169
202
|
|
|
170
203
|
<div className={styles.compileBar} role="progressbar" aria-valuemin={0} aria-valuemax={100}
|
|
171
204
|
aria-valuenow={Math.round(ratio * 100)} aria-label="编译总进度">
|
|
172
|
-
<span style={{ inlineSize: `${Math.round(ratio * 100)}%` }} className={
|
|
205
|
+
<span style={{ inlineSize: `${Math.round(ratio * 100)}%` }} className={completed ? styles.compileBarDone : undefined} />
|
|
173
206
|
</div>
|
|
174
207
|
<p className={styles.compileRatio}>
|
|
175
208
|
已完成 {doneSteps} / {progress?.steps.length ?? 5} 段
|
|
176
209
|
{progress !== null && progress.sourcesTotal > 0 && !done && <> · 读取文档 {progress.sourcesDone}/{progress.sourcesTotal}</>}
|
|
177
210
|
</p>
|
|
178
211
|
|
|
179
|
-
<
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
{step.state === 'done' ? <Check size={12} /> : step.state === 'running' ? <RefreshCw size={11} className={styles.compileSpin} /> : index + 1}
|
|
183
|
-
</span>
|
|
184
|
-
<span className={styles.compileStepBody}>
|
|
185
|
-
<span className={styles.compileStepTitle}>
|
|
186
|
-
step{index + 1} · {COMPILE_STEP_TITLE[step.id] ?? step.id}
|
|
187
|
-
</span>
|
|
188
|
-
{/* 子事实一行一条:它们回答的是「这一段现在是多少」,是这一步唯一的账。
|
|
189
|
-
逐条显示而不是连成一句 —— 连成一句之后,窄栏下会被截断,而截断的正好是末尾
|
|
190
|
-
那个最该看的数。 */}
|
|
191
|
-
<span className={styles.compileFacts}>
|
|
192
|
-
{step.facts.map((fact, at) => <span key={at}>{fact}</span>)}
|
|
193
|
-
</span>
|
|
194
|
-
</span>
|
|
195
|
-
<span className={styles.compileState}>
|
|
196
|
-
{step.state === 'done' ? '已完成' : step.state === 'running' ? '进行中' : '待执行'}
|
|
197
|
-
</span>
|
|
198
|
-
</li>)}
|
|
199
|
-
{progress === null && <li className={styles.compileStep}>
|
|
212
|
+
<CompileStepList steps={progress?.steps ?? []} />
|
|
213
|
+
{progress === null && <ul className={styles.compileSteps}>
|
|
214
|
+
<li className={styles.compileStep}>
|
|
200
215
|
<span className={cn(styles.compileDot, styles.compileDotRunning)} aria-hidden="true"><RefreshCw size={11} className={styles.compileSpin} /></span>
|
|
201
216
|
<span className={styles.compileStepBody}><span className={styles.compileStepTitle}>正在建立编译任务…</span></span>
|
|
202
|
-
</li>
|
|
203
|
-
</ul>
|
|
217
|
+
</li>
|
|
218
|
+
</ul>}
|
|
204
219
|
|
|
205
220
|
{done && <p className={cn(styles.compileOutcome, progress?.failed === true && styles.compileOutcomeBad)}>
|
|
206
221
|
{progress?.failed === true ? '编译失败:' : ''}{finishedText}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import type { ReactNode } from 'react'
|
|
34
|
-
import { FileText, Layers3, LoaderCircle, Quote, TriangleAlert, Trash2 } from '@tita-agent/ui/icons'
|
|
34
|
+
import { CircleDot, FileText, Layers3, LoaderCircle, Quote, TriangleAlert, Trash2 } from '@tita-agent/ui/icons'
|
|
35
35
|
import { Button } from '@tita-agent/ui/components'
|
|
36
36
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@tita-agent/ui/overlays'
|
|
37
37
|
import type { DocumentDeleteImpact } from './wiki-trial.ts'
|
|
@@ -86,8 +86,10 @@ export function DeleteDocumentDialog({
|
|
|
86
86
|
const knowledgeKept = impact?.knowledge.items.filter(item => !item.exclusive).slice(0, ITEM_CAP) ?? []
|
|
87
87
|
const cardsDoomed = impact?.cards.items.filter(item => item.exclusive).slice(0, ITEM_CAP) ?? []
|
|
88
88
|
const cardsKept = impact?.cards.items.filter(item => !item.exclusive).slice(0, ITEM_CAP) ?? []
|
|
89
|
+
const eventsDoomed = impact?.events.items.filter(item => item.exclusive).slice(0, ITEM_CAP) ?? []
|
|
90
|
+
const eventsKept = impact?.events.items.filter(item => !item.exclusive).slice(0, ITEM_CAP) ?? []
|
|
89
91
|
const nothing = impact !== null
|
|
90
|
-
&& impact.knowledge.total === 0 && impact.cards.total === 0 && impact.extractionRuns === 0
|
|
92
|
+
&& impact.knowledge.total === 0 && impact.cards.total === 0 && impact.events.total === 0 && impact.extractionRuns === 0
|
|
91
93
|
|
|
92
94
|
return <Dialog open={open} onOpenChange={onOpenChange}>
|
|
93
95
|
<DialogContent className={styles.delDialog}>
|
|
@@ -109,15 +111,15 @@ export function DeleteDocumentDialog({
|
|
|
109
111
|
<TriangleAlert size={14} aria-hidden="true" />
|
|
110
112
|
<div className={styles.delWarningBody}>
|
|
111
113
|
<b>这项操作不可撤销</b>
|
|
112
|
-
<span
|
|
113
|
-
<small
|
|
114
|
+
<span>将删除原始文档,以及只依赖它的 Knowledge、Event 和 WikiCard。</span>
|
|
115
|
+
<small>重新编译也无法恢复已经删除的 Knowledge 或 Event。</small>
|
|
114
116
|
</div>
|
|
115
117
|
</div>
|
|
116
118
|
|
|
117
119
|
<div className={styles.delScroll}>
|
|
118
120
|
{nothing
|
|
119
121
|
? <p className={styles.delNothing}>
|
|
120
|
-
|
|
122
|
+
这份文档没有生成 Knowledge、Event、WikiCard 或抽取记录。删除后只会移除原始文档。
|
|
121
123
|
</p>
|
|
122
124
|
: <>
|
|
123
125
|
<section className={styles.delSection}>
|
|
@@ -145,6 +147,35 @@ export function DeleteDocumentDialog({
|
|
|
145
147
|
</>}
|
|
146
148
|
</section>
|
|
147
149
|
|
|
150
|
+
<section className={styles.delSection}>
|
|
151
|
+
<h4 className={styles.delSectionHead}>
|
|
152
|
+
<span><CircleDot size={12} />Event</span>
|
|
153
|
+
<small className={styles.delSectionTotal}>共 {impact.events.total} 条</small>
|
|
154
|
+
</h4>
|
|
155
|
+
{impact.events.total === 0
|
|
156
|
+
? <p className={styles.delEmpty}>没有 Event 引用这份文档。</p>
|
|
157
|
+
: <>
|
|
158
|
+
<Tier tone="danger" count={impact.events.exclusive}
|
|
159
|
+
unit="条" label="只由这份文档支撑" description="文档删除后 Event 一并删除"
|
|
160
|
+
items={<ul className={styles.delItems}>
|
|
161
|
+
{eventsDoomed.map(event => <li key={event.id}>
|
|
162
|
+
{event.title}<span className={styles.delItemMeta}>{event.occurredAt ?? event.id}</span>
|
|
163
|
+
</li>)}
|
|
164
|
+
{impact.events.exclusive > eventsDoomed.length
|
|
165
|
+
&& <li className={styles.delMore}>另有 {impact.events.exclusive - eventsDoomed.length} 条同类。</li>}
|
|
166
|
+
</ul>} />
|
|
167
|
+
<Tier tone="keep" count={impact.events.shared}
|
|
168
|
+
unit="条" label="还有其他来源" description="保留 Event,只移除这份来源记录"
|
|
169
|
+
items={<ul className={styles.delItems}>
|
|
170
|
+
{eventsKept.map(event => <li key={event.id}>
|
|
171
|
+
{event.title}<span className={styles.delItemMeta}>{event.occurredAt ?? event.id}</span>
|
|
172
|
+
</li>)}
|
|
173
|
+
{impact.events.shared > eventsKept.length
|
|
174
|
+
&& <li className={styles.delMore}>另有 {impact.events.shared - eventsKept.length} 条同类。</li>}
|
|
175
|
+
</ul>} />
|
|
176
|
+
</>}
|
|
177
|
+
</section>
|
|
178
|
+
|
|
148
179
|
<section className={styles.delSection}>
|
|
149
180
|
<h4 className={styles.delSectionHead}>
|
|
150
181
|
<span><Layers3 size={12} />WikiCard</span>
|
|
@@ -89,16 +89,6 @@ export interface AgentLayoutView {
|
|
|
89
89
|
*/
|
|
90
90
|
settingsError?: string
|
|
91
91
|
pickerKind: string | null
|
|
92
|
-
/**
|
|
93
|
-
* preset 的**真源目录**(`<包根>/preset/tita-data-agent/`)。
|
|
94
|
-
*
|
|
95
|
-
* 提示词的唯一真源就在这个目录里的 `agent.cordis.yml`。0.1.7 起 DSH 那边 preset
|
|
96
|
-
* 不再是一个目录(它是组合里的一条声明行),所以「打开 preset 目录」打开的是
|
|
97
|
-
* 这个随插件分发的真源目录 —— 服务端算好给出来,客户端不拼路径。
|
|
98
|
-
*/
|
|
99
|
-
presetDir?: string
|
|
100
|
-
/** 真源目录在不在。不在时界面如实说,而不是给一个弹空目录的按钮。 */
|
|
101
|
-
presetDirExists?: boolean
|
|
102
92
|
}
|
|
103
93
|
|
|
104
94
|
interface MigrationView {
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react'
|
|
2
|
+
import { Button, cn, Select, SelectContent, SelectItem, SelectLabel, SelectGroup, SelectTrigger, SelectValue } from '@tita-agent/ui/components'
|
|
3
|
+
import { AlertCircle, Check, ChevronDown, Download, LoaderCircle, RefreshCw } from '@tita-agent/ui/icons'
|
|
4
|
+
import { downloadBytes, formatBytes, type ModelSelection, type ModelOptionView } from '../environment/model-catalog.js'
|
|
5
|
+
import type { EnvironmentCurrentModel, EnvironmentView } from '../environment/types.js'
|
|
6
|
+
|
|
7
|
+
async function environmentRequest(init?: RequestInit): Promise<EnvironmentView> {
|
|
8
|
+
const response = await fetch(init?.method ? '/knowledge/environment/prepare' : '/knowledge/environment', { ...init, signal: init?.signal ?? AbortSignal.timeout(20_000) })
|
|
9
|
+
const text = await response.text()
|
|
10
|
+
let payload: { ok?: boolean; data?: EnvironmentView; error?: { message?: string } }
|
|
11
|
+
try { payload = JSON.parse(text) }
|
|
12
|
+
catch { throw new Error(`环境服务未返回有效数据(HTTP ${response.status}),请确认知识插件已加载。`) }
|
|
13
|
+
if (!response.ok || !payload.ok || !payload.data) throw new Error(payload.error?.message ?? `环境服务响应失败(${response.status})`)
|
|
14
|
+
return payload.data
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useKnowledgeEnvironment(visible: boolean, revision: number) {
|
|
18
|
+
const [view, setView] = useState<EnvironmentView>()
|
|
19
|
+
const [error, setError] = useState<string>()
|
|
20
|
+
const [submitting, setSubmitting] = useState(false)
|
|
21
|
+
const sequence = useRef(0)
|
|
22
|
+
const mounted = useRef(true)
|
|
23
|
+
const mutation = useRef(false)
|
|
24
|
+
const reading = useRef(false)
|
|
25
|
+
useEffect(() => { mounted.current = true; return () => { mounted.current = false; sequence.current++ } }, [])
|
|
26
|
+
const refresh = useCallback(async (): Promise<void> => {
|
|
27
|
+
if (mutation.current || reading.current) return
|
|
28
|
+
reading.current = true
|
|
29
|
+
const ticket = ++sequence.current
|
|
30
|
+
try {
|
|
31
|
+
const next = await environmentRequest()
|
|
32
|
+
if (mounted.current && ticket === sequence.current) { setView(next); setError(undefined) }
|
|
33
|
+
} catch (cause) {
|
|
34
|
+
if (mounted.current && ticket === sequence.current) setError(cause instanceof Error ? cause.message : String(cause))
|
|
35
|
+
} finally { reading.current = false }
|
|
36
|
+
}, [])
|
|
37
|
+
const busy = submitting || view?.job?.state === 'running' || view?.report.state === 'checking'
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!visible) return
|
|
40
|
+
void refresh()
|
|
41
|
+
const onFocus = (): void => { void refresh() }
|
|
42
|
+
window.addEventListener('focus', onFocus)
|
|
43
|
+
const timer = busy ? setInterval(() => { void refresh() }, 1500) : undefined
|
|
44
|
+
return () => { if (timer) clearInterval(timer); window.removeEventListener('focus', onFocus) }
|
|
45
|
+
}, [visible, revision, busy, refresh])
|
|
46
|
+
const prepare = useCallback(async (action: 'install' | 'check' | 'cancel', selection?: ModelSelection): Promise<void> => {
|
|
47
|
+
if (mutation.current) return
|
|
48
|
+
mutation.current = true
|
|
49
|
+
const ticket = ++sequence.current
|
|
50
|
+
setSubmitting(true)
|
|
51
|
+
try {
|
|
52
|
+
const next = await environmentRequest({ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action, ...(selection ? { selection } : {}) }) })
|
|
53
|
+
if (mounted.current && ticket === sequence.current) { setView(next); setError(undefined) }
|
|
54
|
+
} catch (cause) {
|
|
55
|
+
if (mounted.current && ticket === sequence.current) setError(cause instanceof Error ? cause.message : String(cause))
|
|
56
|
+
} finally {
|
|
57
|
+
mutation.current = false
|
|
58
|
+
if (mounted.current) setSubmitting(false)
|
|
59
|
+
}
|
|
60
|
+
}, [])
|
|
61
|
+
return { view, error, busy, prepare, refresh }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type EnvironmentController = ReturnType<typeof useKnowledgeEnvironment>
|
|
65
|
+
|
|
66
|
+
function ModelSelect({ id, label, value, options, currentModel, disabled, onChange }: {
|
|
67
|
+
id: string
|
|
68
|
+
label: string
|
|
69
|
+
value: string
|
|
70
|
+
options: ModelOptionView[]
|
|
71
|
+
currentModel: EnvironmentCurrentModel
|
|
72
|
+
disabled: boolean
|
|
73
|
+
onChange: (value: string) => void
|
|
74
|
+
}): ReactNode {
|
|
75
|
+
const chosen = options.find(option => option.id === value)
|
|
76
|
+
return <div className="grid min-w-0 gap-1.5">
|
|
77
|
+
<label htmlFor={id} className="text-xs font-medium text-tita-ink">{label}</label>
|
|
78
|
+
<Select value={value} onValueChange={onChange} disabled={disabled}>
|
|
79
|
+
<SelectTrigger id={id} className="w-full"><SelectValue>{chosen?.label ?? '请选择模型'}</SelectValue></SelectTrigger>
|
|
80
|
+
<SelectContent position="popper" align="start" className="max-h-64">
|
|
81
|
+
<SelectGroup>
|
|
82
|
+
{!currentModel.id && <>
|
|
83
|
+
<SelectLabel>当前运行</SelectLabel>
|
|
84
|
+
<SelectItem value={`${id}-current`} disabled className="h-auto items-start py-1.5">
|
|
85
|
+
{currentModel.state === 'active' ? `当前使用:${currentModel.label}` : '当前未启用'}
|
|
86
|
+
</SelectItem>
|
|
87
|
+
</>}
|
|
88
|
+
<SelectLabel>模型选项 · 按资源占用从低到高</SelectLabel>
|
|
89
|
+
{options.map(option => <SelectItem key={option.id} value={option.id} className="h-auto items-start py-2">
|
|
90
|
+
<span className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
91
|
+
<span className="flex min-w-0 items-center gap-2">
|
|
92
|
+
<span className="min-w-0 flex-1 truncate font-medium">{option.label}</span>
|
|
93
|
+
{/* 下载状态:不知道就不标(服务端没给资源目录时 `installed` 是 undefined)。 */}
|
|
94
|
+
{option.installed === true && <span className="shrink-0 rounded-md border border-tita-tone-green-line bg-tita-tone-green-tint px-1.5 py-0.5 text-[10px] font-medium leading-none text-tita-tone-green">已下载</span>}
|
|
95
|
+
{option.installed === false && <span className="shrink-0 rounded-md border border-tita-line bg-tita-surface-muted px-1.5 py-0.5 text-[10px] font-medium leading-none text-tita-ink-muted">需下载</span>}
|
|
96
|
+
{option.id === currentModel.id && <span className="shrink-0 rounded-md border border-tita-line bg-tita-surface-muted px-1.5 py-0.5 text-[10px] font-medium leading-none text-tita-ink">当前使用</span>}
|
|
97
|
+
</span>
|
|
98
|
+
<span className="line-clamp-2 text-[11px] leading-snug text-tita-ink-muted">
|
|
99
|
+
{option.download}{option.dimension ? ` · ${option.dimension} 维` : ''} · {option.description}
|
|
100
|
+
</span>
|
|
101
|
+
</span>
|
|
102
|
+
</SelectItem>)}
|
|
103
|
+
</SelectGroup>
|
|
104
|
+
</SelectContent>
|
|
105
|
+
</Select>
|
|
106
|
+
{chosen?.modelCardUrl && <a href={chosen.modelCardUrl} target="_blank" rel="noreferrer" className="w-fit text-xs text-tita-ink underline underline-offset-2">查看模型卡与许可</a>}
|
|
107
|
+
</div>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 这次点「安装」会下多少。
|
|
112
|
+
*
|
|
113
|
+
* 模型列表里每个选项自己标了「已下载 / 需下载」,但人真正要判断的是**这一次的总量**:
|
|
114
|
+
* 两个模型都可能已下载(那就只是补依赖 + 自检),也可能只差一个。所以把所选的两个加起来,
|
|
115
|
+
* 已下载的不重复计 —— 已下载的模型不会重新下载(HF 缓存 + 目标目录都在)。
|
|
116
|
+
*/
|
|
117
|
+
function DownloadSummary({ embedding, rerank, chosen }: { embedding: ModelOptionView[]; rerank: ModelOptionView[]; chosen: ModelSelection }): ReactNode {
|
|
118
|
+
const pick = (options: ModelOptionView[], id: string): ModelOptionView | undefined => options.find(option => option.id === id)
|
|
119
|
+
const pending = [pick(embedding, chosen.embedding), pick(rerank, chosen.rerank)]
|
|
120
|
+
.filter((option): option is ModelOptionView => option !== undefined && option.installed === false)
|
|
121
|
+
if (pending.length === 0) {
|
|
122
|
+
return <p className="m-0 text-xs leading-relaxed text-tita-ink-muted" role="status">
|
|
123
|
+
{pick(embedding, chosen.embedding)?.installed === true && pick(rerank, chosen.rerank)?.installed === true
|
|
124
|
+
? '所选模型都已下载,安装只需补齐推理依赖并重新自检。'
|
|
125
|
+
: '无法读取模型下载状态,安装会按需要补齐。'}
|
|
126
|
+
</p>
|
|
127
|
+
}
|
|
128
|
+
const bytes = pending.reduce((sum, option) => sum + (downloadBytes(option.download) ?? 0), 0)
|
|
129
|
+
// 两个以上才报合计:一个模型时合计与它自己那句是同一个数,纯重复。
|
|
130
|
+
const total = pending.length > 1 && bytes > 0 ? `,合计${formatBytes(bytes)}` : ''
|
|
131
|
+
return <p className="m-0 text-xs leading-relaxed text-tita-ink" role="status">
|
|
132
|
+
本次需下载{pending.map(option => `${option.label}(${option.download})`).join('、')}{total};已下载的不会重下。
|
|
133
|
+
</p>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function EnvironmentNotice({ controller, onOpen }: { controller: EnvironmentController; onOpen: () => void }): ReactNode {
|
|
137
|
+
const { view, error, busy } = controller
|
|
138
|
+
if (!error && (!view || view.report.state === 'ready')) return null
|
|
139
|
+
const items = view?.report.items ?? []
|
|
140
|
+
const failed = items.some(item => item.state === 'failed')
|
|
141
|
+
const missing = items.some(item => item.state === 'missing')
|
|
142
|
+
const previouslyChecked = Boolean(view?.report.checkedAt)
|
|
143
|
+
const message = error ? '环境状态读取失败'
|
|
144
|
+
: busy ? view?.job?.stage ?? '正在检查运行环境'
|
|
145
|
+
: failed ? '模型推理自检未通过,请查看原因并修复'
|
|
146
|
+
: missing ? '请准备或启用向量与重排模型,再运行自检'
|
|
147
|
+
: previouslyChecked ? '模型配置或资源已变化,请重新自检' : '首次使用前,请准备并自检向量与重排模型'
|
|
148
|
+
return <div className="mx-3 mt-2 flex shrink-0 items-center gap-2 border-b border-tita-line pb-2 text-xs text-tita-ink" role="status">
|
|
149
|
+
{busy ? <LoaderCircle size={14} className="tita-spin shrink-0" /> : <AlertCircle size={14} className="shrink-0 text-tita-warning" />}
|
|
150
|
+
<span className="min-w-0 flex-1">{message}</span>
|
|
151
|
+
<Button variant="outline" size="sm" onClick={onOpen}>环境准备</Button>
|
|
152
|
+
</div>
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function EnvironmentSetup({ controller }: { controller: EnvironmentController }): ReactNode {
|
|
156
|
+
const { view, error, busy, prepare, refresh } = controller
|
|
157
|
+
const [details, setDetails] = useState(false)
|
|
158
|
+
const [selection, setSelection] = useState<ModelSelection>()
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if (view) setSelection(view.selection)
|
|
161
|
+
}, [view?.selection.embedding, view?.selection.rerank])
|
|
162
|
+
const ready = view?.report.state === 'ready'
|
|
163
|
+
const job = view?.job
|
|
164
|
+
const running = job?.state === 'running'
|
|
165
|
+
const failure = job?.state === 'failed' ? job.error : undefined
|
|
166
|
+
const chosen = selection ?? view?.selection
|
|
167
|
+
/** 已下载、但当前选择没用到的那些:只报出来,不替人删。 */
|
|
168
|
+
const unusedModels = view ? [
|
|
169
|
+
...view.models.embedding.filter(option => option.installed === true && option.id !== view.selection.embedding),
|
|
170
|
+
...view.models.rerank.filter(option => option.installed === true && option.id !== view.selection.rerank),
|
|
171
|
+
] : []
|
|
172
|
+
const selectionChanged = Boolean(chosen && view && (chosen.embedding !== view.selection.embedding || chosen.rerank !== view.selection.rerank))
|
|
173
|
+
const checks = view?.report.items ?? []
|
|
174
|
+
const issues = checks.filter(item => item.state !== 'ready')
|
|
175
|
+
const checkItems = (items: typeof checks): ReactNode => <ul className="m-0 grid list-none gap-3 p-0" aria-label="运行环境检查项">
|
|
176
|
+
{items.map(item => <li key={item.id} className="flex min-w-0 items-start gap-2">
|
|
177
|
+
{item.state === 'ready' ? <Check size={14} className="mt-0.5 shrink-0 text-tita-success" /> : item.state === 'checking'
|
|
178
|
+
? <LoaderCircle size={14} className="tita-spin mt-0.5 shrink-0" /> : <AlertCircle size={14} className="mt-0.5 shrink-0 text-tita-warning" />}
|
|
179
|
+
<div className="min-w-0 flex-1 text-xs leading-relaxed">
|
|
180
|
+
<span className="font-medium text-tita-ink">{item.label}</span>
|
|
181
|
+
<p className="m-0 break-words text-tita-ink-muted">{item.message}</p>
|
|
182
|
+
{item.recovery && <p className="m-0 break-words text-tita-ink">{item.recovery}</p>}
|
|
183
|
+
</div>
|
|
184
|
+
</li>)}
|
|
185
|
+
</ul>
|
|
186
|
+
|
|
187
|
+
return <section id="tita-environment" tabIndex={-1} aria-labelledby="tita-environment-title" className="tita-settingsSection">
|
|
188
|
+
<div className="tita-settingsSectionHeader">
|
|
189
|
+
<h3 id="tita-environment-title">本地运行环境</h3>
|
|
190
|
+
<span className={cn('shrink-0 text-xs', ready && !error ? 'text-tita-success' : 'text-tita-ink-muted')} role="status" aria-live="polite">
|
|
191
|
+
{error ? '读取失败' : busy ? '进行中' : ready ? '已就绪' : view ? '待准备' : '读取中'}
|
|
192
|
+
</span>
|
|
193
|
+
</div>
|
|
194
|
+
<p className="mb-4 mt-0 text-xs leading-relaxed text-tita-ink-muted">选择向量与重排模型,安装后自动自检并启用。首次安装需要联网下载模型和推理依赖。</p>
|
|
195
|
+
{view?.capabilities && <ul className="mb-4 grid list-none gap-1 p-0 text-xs" aria-label="功能可用状态">
|
|
196
|
+
{view.capabilities.map(capability => <li key={capability.id} className="flex flex-wrap gap-x-2 gap-y-1">
|
|
197
|
+
<span className={capability.ready ? 'text-tita-success' : 'text-tita-warning'}>{capability.label} · {capability.ready ? '可用' : '待准备'}</span>
|
|
198
|
+
<span className="text-tita-ink-muted">{capability.message}</span>
|
|
199
|
+
</li>)}
|
|
200
|
+
</ul>}
|
|
201
|
+
{!ready && issues.length > 0 && <div className="mb-4">{checkItems(issues)}</div>}
|
|
202
|
+
{view && chosen && <div className="grid gap-4" aria-label="模型选择">
|
|
203
|
+
<ModelSelect id="tita-embedding-model" label="向量模型" value={chosen.embedding} currentModel={view.current.embedding} options={view.models.embedding} disabled={busy}
|
|
204
|
+
onChange={value => setSelection(current => ({ ...(current ?? view.selection), embedding: value as ModelSelection['embedding'] }))} />
|
|
205
|
+
<ModelSelect id="tita-rerank-model" label="重排模型" value={chosen.rerank} currentModel={view.current.rerank} options={view.models.rerank} disabled={busy}
|
|
206
|
+
onChange={value => setSelection(current => ({ ...(current ?? view.selection), rerank: value as ModelSelection['rerank'] }))} />
|
|
207
|
+
<DownloadSummary embedding={view.models.embedding} rerank={view.models.rerank} chosen={chosen} />
|
|
208
|
+
{(selectionChanged || Boolean(view && (!view.current.embedding.id || !view.current.rerank.id))) && <p className="m-0 text-xs leading-relaxed text-tita-warning" role="status">
|
|
209
|
+
安装将启用所选本地模型,并替换高级模型设置中的自定义路径。自检失败会恢复原设置。更改向量模型后,请构建检索索引。
|
|
210
|
+
</p>}
|
|
211
|
+
</div>}
|
|
212
|
+
{!view && !error && <p className="text-xs text-tita-ink-muted" role="status">正在读取环境状态…</p>}
|
|
213
|
+
{running && <p className="my-3 text-xs text-tita-ink" role="status" aria-live="polite">{job.stage}。你可以离开此面板,任务会继续。</p>}
|
|
214
|
+
{error && <div className="my-3 flex flex-wrap items-start gap-2 text-xs leading-relaxed text-tita-danger" role="alert">
|
|
215
|
+
<span className="min-w-0 flex-1 break-words">{error}</span>
|
|
216
|
+
<Button variant="outline" size="sm" onClick={() => { void refresh() }}>重新读取</Button>
|
|
217
|
+
</div>}
|
|
218
|
+
{failure && <p className="my-3 break-words text-xs text-tita-danger" role="alert">{failure}</p>}
|
|
219
|
+
{job?.state === 'cancelled' && <p className="my-3 text-xs text-tita-ink-muted" role="status">{job.error}</p>}
|
|
220
|
+
{view && <div className="mt-4 flex flex-wrap gap-2">
|
|
221
|
+
<Button size="sm" variant={ready ? 'outline' : 'default'} disabled={busy || Boolean(error)} onClick={() => { void prepare('install', chosen) }}>
|
|
222
|
+
<Download size={13} />{selectionChanged ? '安装所选模型' : ready ? '修复当前环境' : job?.state === 'failed' || job?.state === 'cancelled' ? '重试准备' : '安装并启用'}
|
|
223
|
+
</Button>
|
|
224
|
+
<Button variant="outline" size="sm" disabled={busy || selectionChanged} onClick={() => { void prepare('check') }}><RefreshCw size={13} />重新自检</Button>
|
|
225
|
+
{running && <Button variant="ghost" size="sm" onClick={() => { void prepare('cancel') }}>停止</Button>}
|
|
226
|
+
</div>}
|
|
227
|
+
{ready && <p className="mb-0 mt-3 text-xs text-tita-ink-muted">向量模型变更后需构建检索索引,文档无需重新抽取。</p>}
|
|
228
|
+
{(view || job) && <>
|
|
229
|
+
<Button variant="ghost" size="sm" className="-ml-2 mt-3" aria-expanded={details} aria-controls="tita-environment-details" onClick={() => setDetails(value => !value)}>
|
|
230
|
+
<ChevronDown size={13} className={details ? 'rotate-180' : ''} />检查详情与日志
|
|
231
|
+
</Button>
|
|
232
|
+
{details && <div id="tita-environment-details" className="mt-3 grid gap-3 text-xs leading-relaxed text-tita-ink-muted">
|
|
233
|
+
{checkItems(checks)}
|
|
234
|
+
{view?.report.checkedAt && <p className="m-0">最近自检:{new Date(view.report.checkedAt).toLocaleString()}</p>}
|
|
235
|
+
{unusedModels.length > 0 && <p className="m-0">
|
|
236
|
+
已下载但未启用:{unusedModels.map(option => `${option.label}(${option.download})`).join('、')}。它们留在资源目录里,不会被重新下载。
|
|
237
|
+
</p>}
|
|
238
|
+
{checks.map(item => item.path && <p key={item.id} className="m-0 break-all">{item.label}:{item.path}</p>)}
|
|
239
|
+
{job?.logs.length ? <pre className="m-0 max-h-40 overflow-auto whitespace-pre-wrap break-all rounded-tita-control bg-tita-surface-muted p-2 font-mono">{job.logs.join('\n')}</pre> : null}
|
|
240
|
+
</div>}
|
|
241
|
+
</>}
|
|
242
|
+
</section>
|
|
243
|
+
}
|
|
@@ -33,6 +33,10 @@ import { ExternalLink } from '@tita-agent/ui/icons'
|
|
|
33
33
|
import { layoutGraph, type PlacedGraph, type PlacedNode } from './graph/layout.ts'
|
|
34
34
|
import { cardKey, expansionGraphData, radiusOf, type ExpansionHit, type ExpansionNeighbor } from './graph/expansion.ts'
|
|
35
35
|
import { edgeStyleOf } from './graph/edges.ts'
|
|
36
|
+
import {
|
|
37
|
+
HIT_FILL as PALETTE_HIT_FILL, LABEL_FAINT as PALETTE_LABEL_FAINT, LABEL_INK as PALETTE_LABEL_INK,
|
|
38
|
+
NEIGHBOR_FILL as PALETTE_NEIGHBOR_FILL, OUTLINE_MUTED as PALETTE_OUTLINE_MUTED,
|
|
39
|
+
} from './graph/palette.ts'
|
|
36
40
|
import { styles } from './styles.ts'
|
|
37
41
|
|
|
38
42
|
export type { ExpansionHit, ExpansionNeighbor } from './graph/expansion.ts'
|
|
@@ -62,14 +66,16 @@ const EXPANSION_METRICS = { nodeW: 104, nodeH: 26, linkDistance: 72, stage: 300,
|
|
|
62
66
|
/*
|
|
63
67
|
* 画布侧的颜色都是**字面量**:canvas 渲染器不认 CSS 变量,写 `var(--tita-primary)`
|
|
64
68
|
* 会被解析成全透明黑(`parseColor` 的兜底)。图例上的色块必须与画布上的圆点同色,
|
|
65
|
-
* 所以它在 CSS
|
|
69
|
+
* 所以它在 CSS 里写了一份,并在注释里点名这里 —— 画布这一侧的值全部来自
|
|
70
|
+
* `graph/palette.ts`(三处各写一份正是它们漂开的真正原因)。
|
|
66
71
|
*/
|
|
67
|
-
const HIT_FILL =
|
|
68
|
-
const NEIGHBOR_FILL =
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const
|
|
72
|
+
const HIT_FILL = PALETTE_HIT_FILL
|
|
73
|
+
const NEIGHBOR_FILL = PALETTE_NEIGHBOR_FILL
|
|
74
|
+
/** 命中点的描边与填充同色:它是一个实心点,靠邻居的「空心」来区分两者。 */
|
|
75
|
+
const OUTLINE = PALETTE_HIT_FILL
|
|
76
|
+
const OUTLINE_MUTED = PALETTE_OUTLINE_MUTED
|
|
77
|
+
const LABEL_INK = PALETTE_LABEL_INK
|
|
78
|
+
const LABEL_FAINT = PALETTE_LABEL_FAINT
|
|
73
79
|
/** 标签用的字面量字族:同上,canvas 读不到 `--font-tita`。 */
|
|
74
80
|
const LABEL_FONT = '-apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif'
|
|
75
81
|
|