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
package/lib/types/wiki-trial.js
CHANGED
|
@@ -1,53 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* ## 五层
|
|
5
|
-
*
|
|
6
|
-
* ```
|
|
7
|
-
* Document ──▶ Knowledge ──▶ Canonical Knowledge ──▶ Wiki Card ──▶ 索引
|
|
8
|
-
* ```
|
|
9
|
-
*
|
|
10
|
-
* - **Knowledge** 是知识:一条可独立检索、验证或执行的最小知识单元。
|
|
11
|
-
* **只有 `text` 是内容**;`object` / `action` / `scene` / `sources` 都是索引与出处。
|
|
12
|
-
* 把索引当知识,是这套模型最常见的误解。
|
|
13
|
-
* - **Coordinate** 是 `(object, action, scene)` 这个位置。它是**复合键,不是实体** ——
|
|
14
|
-
* 所以没有 Coordinate 表,也没有"坐标实体"这一层。一条 Knowledge 只有一个坐标,
|
|
15
|
-
* 那是它的「家」。别的卡可以引用它,那是卡的事,不是坐标的事。
|
|
16
|
-
* - **Wiki Card** 是交付视图:一个坐标 + 至少一条 Knowledge 就物化成一张。
|
|
17
|
-
* 标题是**坐标的自然语言投影**,由系统推导 —— 坐标是判重键,模型不参与命名。
|
|
18
|
-
* - **索引**有三个:轴 / Knowledge / Wiki Card。前两个装内容,第三个装任务。
|
|
19
|
-
*
|
|
20
|
-
* ## 四个阶段,七个动作
|
|
21
|
-
*
|
|
22
|
-
* | 阶段 | 动作 |
|
|
23
|
-
* |---|---|
|
|
24
|
-
* | ① Extract | 1 Semantic Extraction |
|
|
25
|
-
* | ② Resolve | 2 Entity Resolution · 3 Knowledge Resolution · 4 Coordinate Assignment |
|
|
26
|
-
* | ③ Materialize | 5 Card Materialization · 6 Card Organization |
|
|
27
|
-
* | ④ Index | 7 Build Index |
|
|
28
|
-
*
|
|
29
|
-
* 顺序里有一条硬规矩:**先把"知识是什么"搞清楚,再决定"这些知识怎么组织成 Wiki Card"。**
|
|
30
|
-
* Wiki Card 是组织结果,不是知识合并结果。
|
|
31
|
-
*
|
|
32
|
-
* ## 只调一次
|
|
33
|
-
*
|
|
34
|
-
* 七步是给人 review 的,不是给模型分的工。一次调用输入全文,输出一个 JSON:
|
|
35
|
-
* `subject` / `knowledge` / `objects` / `actions` / `scenes` / `dropped`。
|
|
36
|
-
* 分块只在文档塞不进上下文时才做。
|
|
37
|
-
*
|
|
38
|
-
* ## 对象 × 动作矩阵
|
|
39
|
-
*
|
|
40
|
-
* 矩阵**不让模型再填一遍**。它是 Knowledge 坐标的二维排布,本地算出来的:行是对象,列是动作,
|
|
41
|
-
* 多一行「无对象」收只有动作的知识,多一列「无动作」收只有对象的知识。
|
|
42
|
-
*
|
|
43
|
-
* **坐标是三维的,矩阵是它的二维投影。** 场景落在格子**内部**,不进坐标轴 ——
|
|
44
|
-
* 一格里有几个场景,就有几张卡。
|
|
45
|
-
*
|
|
46
|
-
* ## 只读
|
|
47
|
-
*
|
|
48
|
-
* 它不写 SourceRaw、不建卡、不进索引。给一段正文,返回四个阶段的判定结果与矩阵。
|
|
49
|
-
*/
|
|
50
|
-
import { AXIS_CONTRACT_LINES } from './axis-contract.js';
|
|
1
|
+
import { normalizeKnowledgeExtraction } from './knowledge-contract.js';
|
|
2
|
+
import { buildTrialSystem } from './extract-contract.js';
|
|
3
|
+
import { decodeExtractionTable } from './extract-table.js';
|
|
51
4
|
/**
|
|
52
5
|
* 抽取契约(0063 §5.6)。**这是契约,不是要抄进代码的字符串。**
|
|
53
6
|
*
|
|
@@ -58,101 +11,8 @@ import { AXIS_CONTRACT_LINES } from './axis-contract.js';
|
|
|
58
11
|
* 2. 三个分量**可以全空** —— §九 明写"允许 Knowledge 没有领域坐标"。
|
|
59
12
|
* 文档 §5.6 里"每条至少挂一个 object 或一个 action"与它冲突。
|
|
60
13
|
*/
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
*
|
|
64
|
-
* §5.3.2 说「`section` 的合法取值来自类型定义」—— 那就应当**下发**给它,帮助模型
|
|
65
|
-
* 使用一致的小节名。不下发的话,那句「合法取值来自类型定义」只是一句写在文档里的愿望。
|
|
66
|
-
*/
|
|
67
|
-
function sectionRule(sections) {
|
|
68
|
-
const legal = (sections ?? []).map(section => section.trim()).filter(Boolean);
|
|
69
|
-
if (legal.length === 0) {
|
|
70
|
-
return ['- section 是这条知识在卡片里的位置。拿不准就填「字段」。'];
|
|
71
|
-
}
|
|
72
|
-
return [
|
|
73
|
-
`- section 只能填这几个之一:${legal.join(' / ')},或者「字段」。`,
|
|
74
|
-
'- 拿不准就填「字段」。**不要自创小节名** —— 卡片是按骨架校验的,编出来的名字对不上。',
|
|
75
|
-
];
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 抽取契约的 system 段。**骨架的小节随知识库变化,所以它是拼出来的,不是常量。**
|
|
79
|
-
*
|
|
80
|
-
* 编译链路用 `buildTrialSystem(profileSections)`;试跑面板用默认实例(不下发小节清单),
|
|
81
|
-
* 因为那一层没有「本库骨架」这个概念。
|
|
82
|
-
*/
|
|
83
|
-
export function buildTrialSystem(sections) {
|
|
84
|
-
return trialSystemBody(sectionRule(sections));
|
|
85
|
-
}
|
|
86
|
-
const trialSystemBody = (positionRule) => [
|
|
87
|
-
'你在把一份业务文档拆成知识库要用的内容。知识以 Knowledge 为单位:',
|
|
88
|
-
'一条可独立检索、验证或执行的最小知识单元。',
|
|
89
|
-
'',
|
|
90
|
-
'只回一个 JSON 对象,不要散文,不要代码围栏。',
|
|
91
|
-
'',
|
|
92
|
-
'输出形状:',
|
|
93
|
-
'{',
|
|
94
|
-
' "subject": "这份文档讲的业务主体",',
|
|
95
|
-
' "knowledge": [',
|
|
96
|
-
' { "id": "k1",',
|
|
97
|
-
' "text": "一条可独立检索、验证或执行的最小知识单元",',
|
|
98
|
-
' "object": "对象名或 null", "action": "动作名或 null", "scene": "场景名或 null",',
|
|
99
|
-
' "section": "步骤", "order": 1,',
|
|
100
|
-
' "sources": [ { "quote": "原文里原样复制的一段", "heading_path": ["一级", "二级"] } ] }',
|
|
101
|
-
' ],',
|
|
102
|
-
' "objects": [ { "mention": "原文中的对象叫法", "definition": "一句话说清它指什么、边界在哪", "evidence": "支持它的原文短引文", "existing": "已有对象的名字(没有就省略这个键)" } ],',
|
|
103
|
-
' "actions": [ { "mention": "原文中的动作叫法", "definition": "同上", "evidence": "支持它的原文短引文", "existing": "…" } ],',
|
|
104
|
-
' "scenes": [ { "mention": "原文中的场景叫法", "definition": "同上", "evidence": "支持它的原文短引文", "existing": "…" } ],',
|
|
105
|
-
' "dropped": [ { "quote": "原文片段", "why": "为什么丢掉" } ]',
|
|
106
|
-
'}',
|
|
107
|
-
'',
|
|
108
|
-
'# 知识:一条只讲一个单元',
|
|
109
|
-
'- text 是一条能脱离上下文独立阅读的最小知识单元。事实要能判断真假,操作步骤要能被执行。',
|
|
110
|
-
'- 一段原文里有几个独立单元就写几条。不要压成一条,也不要拆碎。',
|
|
111
|
-
' 不该拆:「SPM 由 spm_b、spm_c、spm_d 三部分构成」是一个完整事实。',
|
|
112
|
-
' 该拆:「spm_c 是楼层 ID」「楼层拖拽后 ID 会变化」「取数不能写死楼层 ID」是三条。',
|
|
113
|
-
'- 不许推理出原文没有的事实。只做压缩、归一化、结构化。不许编原文没有的步骤。',
|
|
114
|
-
'- 不要写「该字段」「上述」这种指代 —— 读者看不到上下文。',
|
|
115
|
-
'',
|
|
116
|
-
...AXIS_CONTRACT_LINES,
|
|
117
|
-
'',
|
|
118
|
-
'- 一条 Knowledge 只挂一个 object、一个 action、一个 scene。那是它的家。',
|
|
119
|
-
' 别的卡片可以引用它 —— 那是卡片的事,不是坐标的事,不要为它多挂几个坐标。',
|
|
120
|
-
'- 三个都留 null 是允许的。它不进矩阵、不成卡,但仍然可被全库命中。',
|
|
121
|
-
' 不要为了让它成卡而编一个坐标。',
|
|
122
|
-
'- 不要造"动作实例"。「通天塔spm取数」不是动作,它是坐标(通天塔 × 取数 × SPM)推出来的卡名。',
|
|
123
|
-
'',
|
|
124
|
-
'# 坐标:定义与证据',
|
|
125
|
-
'- 每个 object / action / scene 都写 `definition`:一句话说清**它指什么、边界在哪**。',
|
|
126
|
-
' 它是下一次抽取的参考 —— 名字只能让人认出写法相同的东西,定义才能认出「换了说法但同一个」。',
|
|
127
|
-
' 写「通天塔坑位click:通天塔投放位上的一次点击上报」这种能判断的句子,不要写「一个对象」这种空话。',
|
|
128
|
-
'- 每个 object / action / scene 都写 `evidence`:从原文复制支持该坐标及其定义的最短片段。没有证据就不要抽这个坐标。',
|
|
129
|
-
'- `definition` 只能总结原文和已有坐标定义能支持的范围,不要补造原文没有的属性、状态或因果。',
|
|
130
|
-
'',
|
|
131
|
-
'# 坐标:先看用户消息里的「已有坐标」',
|
|
132
|
-
'- 你讲的东西如果就是清单里的某一个(哪怕原文用的是另一个说法),就写**它的名字**,',
|
|
133
|
-
' 并把 `existing` 写成那个名字。别造一个近似的名字 —— 那会让库里长出两个只在写法上不同的实体。',
|
|
134
|
-
'- 清单里没有的才写新名字(`existing` 留空)。拿不准就写新名字:解析那一步会兜底。',
|
|
135
|
-
'- 清单是**参考**,不是限制:库里没有的东西照样可以抽出来。',
|
|
136
|
-
'',
|
|
137
|
-
'# 来源:原样,别改写',
|
|
138
|
-
'- quote 必须一个字都不改,从原文原样复制。',
|
|
139
|
-
'- 挑最短的必要片段,不要整段照抄。',
|
|
140
|
-
'- 一段原文支撑多条知识时,每条都要各自写上它的 quote。',
|
|
141
|
-
'- heading_path 是从外到内的标题路径,只作定位线索。',
|
|
142
|
-
'',
|
|
143
|
-
'# 位置:这条知识在卡里排哪',
|
|
144
|
-
...positionRule,
|
|
145
|
-
'- order 是同一小节内的第几位,从 1 开始。',
|
|
146
|
-
'- 不要写卡片正文,也不要写导语、备注、警告。你只给"哪条知识放在哪个小节、排第几"。',
|
|
147
|
-
'',
|
|
148
|
-
'# 别把排版当结构',
|
|
149
|
-
'- 原文里的小节标题只是作者写给"人顺着读"的排版,不是知识边界。',
|
|
150
|
-
'- 一个标题里可以装几件事,一件事也可以跨几个标题。不要按标题切。',
|
|
151
|
-
'',
|
|
152
|
-
'- 不含知识的片段放 dropped,写清 why。不许悄悄丢。',
|
|
153
|
-
'',
|
|
154
|
-
'每条 quote 必须从原文原样复制,一个字都不要改。没有 quote 的判断一律不要。',
|
|
155
|
-
].join('\n');
|
|
14
|
+
/** 抽取契约的 system 段搬到了 `extract-contract.ts`(说明页要显示它,而这里进不了浏览器)。 */
|
|
15
|
+
export { buildTrialSystem } from './extract-contract.js';
|
|
156
16
|
/** 默认的 system 段(不下发骨架小节)。试跑面板用它。 */
|
|
157
17
|
export const TRIAL_SYSTEM = buildTrialSystem();
|
|
158
18
|
/** 组装提示词。全文进去 —— 标题本来就在正文里,不必再列一遍。 */
|
|
@@ -172,7 +32,7 @@ export function buildTrialPrompt(input) {
|
|
|
172
32
|
const note = (input.note ?? '').trim();
|
|
173
33
|
if (note !== '')
|
|
174
34
|
sections.push('# 本库的坐标约定(人写的,优先听它)', note, '');
|
|
175
|
-
sections.push('# 输出',
|
|
35
|
+
sections.push('# 输出', `按 system 中的版本协议返回${input.outputFormat === 'json' ? ' JSON 对象' : ' TOON 表格'},不要混用格式。`);
|
|
176
36
|
return sections.join('\n');
|
|
177
37
|
}
|
|
178
38
|
const AXIS_BLOCK_TITLE = { object: '对象', action: '动作', scene: '场景' };
|
|
@@ -235,6 +95,11 @@ function renderAxisBlock(block) {
|
|
|
235
95
|
/** 从可能带 ``` 围栏的文本里取出 JSON。与 `extract-model.ts` 同构。 */
|
|
236
96
|
function parseJsonObject(raw) {
|
|
237
97
|
const trimmed = raw.trim();
|
|
98
|
+
// Parse the transport first: code fences inside JSON string values are source data.
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(trimmed);
|
|
101
|
+
}
|
|
102
|
+
catch { /* tolerate an outer Markdown wrapper */ }
|
|
238
103
|
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
239
104
|
const body = (fenced ? fenced[1] : trimmed).trim();
|
|
240
105
|
try {
|
|
@@ -269,7 +134,7 @@ function plainRecord(value) {
|
|
|
269
134
|
* 被误报为「清单外」并置空,最终整批 Knowledge 都变成「无坐标」。先把它们补回
|
|
270
135
|
* 抽取清单,再走同一套 Entity Resolution,既不猜坐标,也不绕过注册表。
|
|
271
136
|
*/
|
|
272
|
-
function
|
|
137
|
+
function axisMentionsFromItems(raw) {
|
|
273
138
|
const out = { object: [], action: [], scene: [] };
|
|
274
139
|
if (!Array.isArray(raw))
|
|
275
140
|
return out;
|
|
@@ -292,6 +157,12 @@ function axisMentionsFromKnowledge(raw) {
|
|
|
292
157
|
}
|
|
293
158
|
return out;
|
|
294
159
|
}
|
|
160
|
+
function axisMentionsFromKnowledge(raw) {
|
|
161
|
+
return axisMentionsFromItems(raw);
|
|
162
|
+
}
|
|
163
|
+
function axisMentionsFromEvents(raw) {
|
|
164
|
+
return axisMentionsFromItems(raw);
|
|
165
|
+
}
|
|
295
166
|
/** 顶层轴清单优先,Knowledge 坐标只补缺项;readAxes 会按归一化名称去重。 */
|
|
296
167
|
function mergeAxisMentions(raw, supplements) {
|
|
297
168
|
return [...(Array.isArray(raw) ? raw : []), ...supplements];
|
|
@@ -581,6 +452,9 @@ function readKnowledge(raw, options) {
|
|
|
581
452
|
const order = typeof rawOrder === 'number' && Number.isFinite(rawOrder) ? Math.trunc(rawOrder) : 1;
|
|
582
453
|
knowledge.push({
|
|
583
454
|
id,
|
|
455
|
+
kind: record.kind === 'procedure' ? 'procedure' : 'fact',
|
|
456
|
+
...(record.scope_identity === true ? { scopeIdentity: true } : {}),
|
|
457
|
+
...(record.data && typeof record.data === 'object' ? { data: record.data } : {}),
|
|
584
458
|
text,
|
|
585
459
|
object,
|
|
586
460
|
action,
|
|
@@ -593,6 +467,141 @@ function readKnowledge(raw, options) {
|
|
|
593
467
|
}
|
|
594
468
|
return { knowledge, problems };
|
|
595
469
|
}
|
|
470
|
+
function readTrialSources(raw, options) {
|
|
471
|
+
if (!Array.isArray(raw))
|
|
472
|
+
return [];
|
|
473
|
+
const sources = [];
|
|
474
|
+
for (const item of raw) {
|
|
475
|
+
if (item === null || typeof item !== 'object')
|
|
476
|
+
continue;
|
|
477
|
+
const source = item;
|
|
478
|
+
const quote = str(source.quote);
|
|
479
|
+
if (!quote)
|
|
480
|
+
continue;
|
|
481
|
+
const located = locateQuote(options.text, quote);
|
|
482
|
+
sources.push({
|
|
483
|
+
documentId: options.documentId,
|
|
484
|
+
quote,
|
|
485
|
+
...(located.locator ? { locator: located.locator } : {}),
|
|
486
|
+
headingPath: strList(source.heading_path),
|
|
487
|
+
found: located.found,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
return sources;
|
|
491
|
+
}
|
|
492
|
+
/** 读取一次具体事件;缺失字段保留为空,不用模型补猜。 */
|
|
493
|
+
function readEvents(raw, options) {
|
|
494
|
+
if (!Array.isArray(raw))
|
|
495
|
+
return { events: [], problems: [] };
|
|
496
|
+
const objectMap = new Map(options.objects.flatMap(axis => [axis.name, ...axis.aliases].map(name => [normalizeAxisName(name), axis.name])));
|
|
497
|
+
const actionMap = new Map(options.actions.flatMap(axis => [axis.name, ...axis.aliases].map(name => [normalizeAxisName(name), axis.name])));
|
|
498
|
+
const sceneMap = new Map(options.scenes.flatMap(axis => [axis.name, ...axis.aliases].map(name => [normalizeAxisName(name), axis.name])));
|
|
499
|
+
const events = [];
|
|
500
|
+
const problems = [];
|
|
501
|
+
const ids = new Set();
|
|
502
|
+
for (const entry of raw) {
|
|
503
|
+
if (entry === null || typeof entry !== 'object')
|
|
504
|
+
continue;
|
|
505
|
+
const record = entry;
|
|
506
|
+
const id = str(record.id) || `e${events.length + 1}`;
|
|
507
|
+
if (ids.has(id)) {
|
|
508
|
+
problems.push(`Event id「${id}」重复,后续条目已跳过`);
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
ids.add(id);
|
|
512
|
+
const title = str(record.title);
|
|
513
|
+
const summary = str(record.summary) || title;
|
|
514
|
+
if (!title && !summary) {
|
|
515
|
+
problems.push(`Event「${id}」没有标题或摘要,已跳过`);
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
const coordinate = plainRecord(record.coordinate);
|
|
519
|
+
const resolve = (value, map, axis) => {
|
|
520
|
+
const mention = str(value);
|
|
521
|
+
if (!mention)
|
|
522
|
+
return null;
|
|
523
|
+
const canonical = map.get(normalizeAxisName(mention));
|
|
524
|
+
if (canonical)
|
|
525
|
+
return canonical;
|
|
526
|
+
problems.push(`Event「${id}」的${axis}「${mention}」没有进入轴清单,已置空`);
|
|
527
|
+
return null;
|
|
528
|
+
};
|
|
529
|
+
const object = resolve(coordinate.object_mention ?? coordinate.object, objectMap, '对象');
|
|
530
|
+
const action = resolve(coordinate.action_mention ?? coordinate.action, actionMap, '动作');
|
|
531
|
+
const scene = resolve(coordinate.scene_mention ?? coordinate.scene, sceneMap, '场景');
|
|
532
|
+
const timeline = [];
|
|
533
|
+
if (Array.isArray(record.timeline)) {
|
|
534
|
+
for (const [index, rawStep] of record.timeline.entries()) {
|
|
535
|
+
if (rawStep === null || typeof rawStep !== 'object')
|
|
536
|
+
continue;
|
|
537
|
+
const step = rawStep;
|
|
538
|
+
const description = str(step.description);
|
|
539
|
+
if (!description)
|
|
540
|
+
continue;
|
|
541
|
+
const candidateType = str(step.type);
|
|
542
|
+
const type = ['observation', 'check', 'action', 'result', 'conclusion'].includes(candidateType)
|
|
543
|
+
? candidateType
|
|
544
|
+
: 'observation';
|
|
545
|
+
const sources = readTrialSources(step.sources, options);
|
|
546
|
+
if (!sources.some(source => source.found))
|
|
547
|
+
problems.push(`Event「${id}」时间线第 ${index + 1} 项没有可核验的原文引文`);
|
|
548
|
+
timeline.push({
|
|
549
|
+
id: str(step.id) || `${id}.t${index + 1}`,
|
|
550
|
+
type,
|
|
551
|
+
description,
|
|
552
|
+
result: str(step.result) || null,
|
|
553
|
+
at: str(step.at) || null,
|
|
554
|
+
sources,
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
const sources = readTrialSources(record.sources, options);
|
|
559
|
+
const evidence = [...sources, ...timeline.flatMap(step => step.sources)];
|
|
560
|
+
if (!evidence.some(source => source.found)) {
|
|
561
|
+
problems.push(`Event「${id}」没有可核验的原文引文,已留在抽取轨迹但不进入 Event 真源`);
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
const rawRootCause = record.root_cause;
|
|
565
|
+
const root = typeof rawRootCause === 'string' ? { text: rawRootCause, status: 'suspected' } : plainRecord(rawRootCause);
|
|
566
|
+
const rootCause = str(root.text) || null;
|
|
567
|
+
const rootStatus = str(root.status);
|
|
568
|
+
const rootCauseStatus = rootCause && (rootStatus === 'confirmed' || rootStatus === 'suspected')
|
|
569
|
+
? rootStatus
|
|
570
|
+
: null;
|
|
571
|
+
const missing = strList(record.missing);
|
|
572
|
+
const addMissing = (label, missingValue) => {
|
|
573
|
+
if (!str(missingValue) && !missing.includes(label))
|
|
574
|
+
missing.push(label);
|
|
575
|
+
};
|
|
576
|
+
const occurredAt = str(record.occurred_at) || null;
|
|
577
|
+
const symptom = str(record.symptom) || null;
|
|
578
|
+
const outcome = str(record.outcome) || null;
|
|
579
|
+
addMissing('发生时间', occurredAt);
|
|
580
|
+
addMissing('问题现象', symptom);
|
|
581
|
+
addMissing('根因', rootCause);
|
|
582
|
+
addMissing('处理结果', outcome);
|
|
583
|
+
addMissing('问题坐标', object || action || scene);
|
|
584
|
+
events.push({
|
|
585
|
+
id,
|
|
586
|
+
externalId: str(record.external_id) || null,
|
|
587
|
+
title: title || summary,
|
|
588
|
+
summary,
|
|
589
|
+
object,
|
|
590
|
+
action,
|
|
591
|
+
scene,
|
|
592
|
+
occurredAt,
|
|
593
|
+
symptom,
|
|
594
|
+
timeline,
|
|
595
|
+
rootCause,
|
|
596
|
+
rootCauseStatus,
|
|
597
|
+
outcome,
|
|
598
|
+
missing,
|
|
599
|
+
sources,
|
|
600
|
+
noCoordinate: !object && !action && !scene,
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
return { events, problems };
|
|
604
|
+
}
|
|
596
605
|
// ------------------------------------------------------------ 本地推导
|
|
597
606
|
/**
|
|
598
607
|
* 物化 Wiki Card(第 5 步)。**系统做,确定性。**
|
|
@@ -606,27 +615,40 @@ function readKnowledge(raw, options) {
|
|
|
606
615
|
* **没有"要不要建卡"这个问题。** 一个坐标 + 至少一条知识,就天然要建。
|
|
607
616
|
* 三个分量全空的知识不成卡 —— 它没有坐标。
|
|
608
617
|
*/
|
|
609
|
-
export function materialize(knowledge) {
|
|
618
|
+
export function materialize(knowledge, events = []) {
|
|
610
619
|
const groups = new Map();
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
continue;
|
|
614
|
-
const key = `${item.object ?? ''}\u0001${item.action ?? ''}\u0001${item.scene ?? ''}`;
|
|
620
|
+
const groupOf = (object, action, scene) => {
|
|
621
|
+
const key = `${object ?? ''}\u0001${action ?? ''}\u0001${scene ?? ''}`;
|
|
615
622
|
let card = groups.get(key);
|
|
616
623
|
if (!card) {
|
|
617
624
|
card = {
|
|
618
|
-
object
|
|
619
|
-
action
|
|
620
|
-
scene
|
|
621
|
-
name: cardNameFor(
|
|
625
|
+
object,
|
|
626
|
+
action,
|
|
627
|
+
scene,
|
|
628
|
+
name: cardNameFor(object, action, scene),
|
|
622
629
|
placements: [],
|
|
630
|
+
events: [],
|
|
623
631
|
};
|
|
624
632
|
groups.set(key, card);
|
|
625
633
|
}
|
|
634
|
+
return card;
|
|
635
|
+
};
|
|
636
|
+
for (const item of knowledge) {
|
|
637
|
+
if (item.noCoordinate)
|
|
638
|
+
continue;
|
|
639
|
+
const card = groupOf(item.object, item.action, item.scene);
|
|
626
640
|
card.placements.push({ item: item.id, section: item.section, order: item.order });
|
|
627
641
|
}
|
|
642
|
+
for (const event of events) {
|
|
643
|
+
if (event.noCoordinate)
|
|
644
|
+
continue;
|
|
645
|
+
const key = `${event.object ?? ''}\u0001${event.action ?? ''}\u0001${event.scene ?? ''}`;
|
|
646
|
+
// A WikiCard is created by Knowledge. Event only adds a reference to an existing knowledge group.
|
|
647
|
+
groups.get(key)?.events.push(event.id);
|
|
648
|
+
}
|
|
628
649
|
for (const card of groups.values()) {
|
|
629
650
|
card.placements.sort((left, right) => left.section.localeCompare(right.section) || left.order - right.order || left.item.localeCompare(right.item));
|
|
651
|
+
card.events.sort((left, right) => left.localeCompare(right));
|
|
630
652
|
}
|
|
631
653
|
return [...groups.values()];
|
|
632
654
|
}
|
|
@@ -644,7 +666,7 @@ export function materialize(knowledge) {
|
|
|
644
666
|
*
|
|
645
667
|
* 组是**最小的可点单位**:点一个数字要看到的就是那一组的知识。
|
|
646
668
|
*/
|
|
647
|
-
export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
669
|
+
export function buildMatrix(objects, actions, knowledge, wikiCards, events = []) {
|
|
648
670
|
/** 一组一组的桶。键是 `object\u0001action\u0001scene`。 */
|
|
649
671
|
const buckets = new Map();
|
|
650
672
|
const bucketOf = (object, action, scene) => {
|
|
@@ -652,7 +674,7 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
652
674
|
const hit = buckets.get(key);
|
|
653
675
|
if (hit)
|
|
654
676
|
return hit;
|
|
655
|
-
const created = { object, action, scene, knowledge: 0, items: [] };
|
|
677
|
+
const created = { object, action, scene, knowledge: 0, events: 0, items: [], eventItems: [] };
|
|
656
678
|
buckets.set(key, created);
|
|
657
679
|
return created;
|
|
658
680
|
};
|
|
@@ -663,6 +685,13 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
663
685
|
bucket.knowledge += 1;
|
|
664
686
|
bucket.items.push(item.id);
|
|
665
687
|
}
|
|
688
|
+
for (const event of events) {
|
|
689
|
+
if (event.noCoordinate)
|
|
690
|
+
continue;
|
|
691
|
+
const bucket = bucketOf(event.object, event.action, event.scene ?? '');
|
|
692
|
+
bucket.events += 1;
|
|
693
|
+
bucket.eventItems.push(event.id);
|
|
694
|
+
}
|
|
666
695
|
// 卡名叠进它自己那一组。一个 `(object, action, scene)` 至多一张卡,所以是赋值不是追加。
|
|
667
696
|
const cardOf = new Map();
|
|
668
697
|
for (const card of wikiCards) {
|
|
@@ -676,8 +705,10 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
676
705
|
out.push({
|
|
677
706
|
scene: bucket.scene,
|
|
678
707
|
knowledge: bucket.knowledge,
|
|
708
|
+
events: bucket.events,
|
|
679
709
|
card: cardOf.get(`${object ?? '\u0000'}\u0001${action ?? '\u0000'}\u0001${bucket.scene}`) ?? '',
|
|
680
710
|
items: bucket.items,
|
|
711
|
+
eventItems: bucket.eventItems,
|
|
681
712
|
});
|
|
682
713
|
}
|
|
683
714
|
// 场景名的阅读顺序:先空场景(它是「没有细分」的那一组),再按名字。
|
|
@@ -689,7 +720,7 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
689
720
|
const groups = groupsFor(object, action);
|
|
690
721
|
if (groups.length === 0)
|
|
691
722
|
continue;
|
|
692
|
-
cells.push({ object, action, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0) });
|
|
723
|
+
cells.push({ object, action, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0), events: groups.reduce((sum, group) => sum + group.events, 0) });
|
|
693
724
|
}
|
|
694
725
|
}
|
|
695
726
|
// 行头:这一行里「有对象、没动作」的那些知识。列头同理。
|
|
@@ -697,13 +728,13 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
697
728
|
for (const object of objects) {
|
|
698
729
|
const groups = groupsFor(object, null);
|
|
699
730
|
if (groups.length > 0)
|
|
700
|
-
noAction.push({ name: object, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0) });
|
|
731
|
+
noAction.push({ name: object, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0), events: groups.reduce((sum, group) => sum + group.events, 0) });
|
|
701
732
|
}
|
|
702
733
|
const noObject = [];
|
|
703
734
|
for (const action of actions) {
|
|
704
735
|
const groups = groupsFor(null, action);
|
|
705
736
|
if (groups.length > 0)
|
|
706
|
-
noObject.push({ name: action, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0) });
|
|
737
|
+
noObject.push({ name: action, groups, knowledge: groups.reduce((sum, group) => sum + group.knowledge, 0), events: groups.reduce((sum, group) => sum + group.events, 0) });
|
|
707
738
|
}
|
|
708
739
|
return {
|
|
709
740
|
objects,
|
|
@@ -712,6 +743,7 @@ export function buildMatrix(objects, actions, knowledge, wikiCards) {
|
|
|
712
743
|
noAction,
|
|
713
744
|
noObject,
|
|
714
745
|
noCoordinate: knowledge.filter(item => item.noCoordinate).length,
|
|
746
|
+
noCoordinateEvents: events.filter(item => item.noCoordinate).length,
|
|
715
747
|
withKnowledge: cells.filter(cell => cell.knowledge > 0).length,
|
|
716
748
|
filled: cells.length,
|
|
717
749
|
slots: objects.length * actions.length,
|
|
@@ -761,10 +793,10 @@ function findTwins(knowledge) {
|
|
|
761
793
|
* 每一步给两样:`rows`(按什么判、缺什么)和 `items`(**逐条判出的实际值**)。
|
|
762
794
|
* 试跑面板是给人逐步 review 的,只有统计没有值就没法 review。
|
|
763
795
|
*
|
|
764
|
-
* 第 2、3
|
|
796
|
+
* 第 2、3 步里如实写明能力边界:轴归一需要库内注册表,候选歧义可在编译时补判;知识同义与冲突仍不做模型裁决。
|
|
765
797
|
*/
|
|
766
798
|
export function buildReport(input) {
|
|
767
|
-
const { objects, actions, scenes, knowledge, wikiCards, matrix, dropped } = input;
|
|
799
|
+
const { objects, actions, scenes, knowledge, events, wikiCards, matrix, dropped } = input;
|
|
768
800
|
const headings = scanHeadings(input.text);
|
|
769
801
|
const axes = [...objects, ...actions, ...scenes];
|
|
770
802
|
const aliased = axes.filter(axis => axis.aliases.length > 0);
|
|
@@ -781,8 +813,15 @@ export function buildReport(input) {
|
|
|
781
813
|
invented.push({ id: item.id, quote: source.quote });
|
|
782
814
|
}
|
|
783
815
|
}
|
|
816
|
+
for (const event of events) {
|
|
817
|
+
for (const source of [...event.sources, ...event.timeline.flatMap(step => step.sources)]) {
|
|
818
|
+
if (!source.found)
|
|
819
|
+
invented.push({ id: event.id, quote: source.quote });
|
|
820
|
+
}
|
|
821
|
+
}
|
|
784
822
|
const noSource = knowledge.filter(item => item.sources.length === 0);
|
|
785
823
|
const noCoordinate = knowledge.filter(item => item.noCoordinate);
|
|
824
|
+
const noCoordinateEvents = events.filter(item => item.noCoordinate);
|
|
786
825
|
const twins = findTwins(knowledge);
|
|
787
826
|
const collisions = findCollisions(wikiCards);
|
|
788
827
|
const sections = new Set(knowledge.flatMap(item => item.section));
|
|
@@ -790,25 +829,28 @@ export function buildReport(input) {
|
|
|
790
829
|
const steps = [
|
|
791
830
|
{
|
|
792
831
|
id: 'extract', order: 1, name: '语义抽取', phase: '① Extract · 抽取', actor: '模型',
|
|
793
|
-
needsHuman: noCoordinate.length > 0 || noSource.length > 0 || knowledge.length === 0,
|
|
794
|
-
summary: `${knowledge.length}
|
|
832
|
+
needsHuman: noCoordinate.length > 0 || noSource.length > 0 || knowledge.length === 0 || events.some(event => event.missing.length > 0),
|
|
833
|
+
summary: `${knowledge.length} 条 Knowledge · ${events.length} 个 Event · ${objects.length} 对象 · ${actions.length} 动作 · ${scenes.length} 场景 · 一次调用`,
|
|
795
834
|
rows: [
|
|
796
835
|
{ label: '输入', value: `${input.text.split(/\r?\n/).length} 行 / ${countChars(input.text)} 字 / ${headings.length} 个标题,全文进去,不切块` },
|
|
797
|
-
{ label: '一次调用出全部', value: '
|
|
836
|
+
{ label: '一次调用出全部', value: '同一份 Document 并行抽取 Knowledge 与 Event,再提取 Object / Action / Scene mentions' },
|
|
798
837
|
{ label: '这一步不解决', value: '这是不是已有知识(第 3 步)· 这些名字是不是已有实体(第 2 步)· 应该生成哪张卡(第 5 步)' },
|
|
799
838
|
{ label: '五条规则', value: '一条只讲一个单元 · 不推理出原文没有的事实 · 不写「该字段」这种指代 · 坐标各一个 · quote 原样复制' },
|
|
800
|
-
{ label: '没有出处', value: noSource.length > 0 ? `${noSource.length}
|
|
839
|
+
{ label: '没有出处', value: noSource.length > 0 ? `${noSource.length} 条 Knowledge 一个 quote 都没给` : 'Knowledge / Event 都有可核验出处' },
|
|
840
|
+
],
|
|
841
|
+
items: [
|
|
842
|
+
...knowledge.map(item => makeItem(item.id, shortQuote(item.text), `${coordLabel(item.object, item.action, item.scene)} · ${item.sources.length} 条出处`, item.noCoordinate || item.sources.length === 0 ? 'warn' : undefined)),
|
|
843
|
+
...events.map(event => makeItem(`Event ${event.id}`, event.title, `${coordLabel(event.object, event.action, event.scene)} · ${event.timeline.length} 个时间线节点 · ${event.missing.length} 项待补`, event.noCoordinate || event.missing.length > 0 ? 'warn' : undefined)),
|
|
801
844
|
],
|
|
802
|
-
items: knowledge.map(item => makeItem(item.id, shortQuote(item.text), `${coordLabel(item.object, item.action, item.scene)} · ${item.sources.length} 条出处`, item.noCoordinate || item.sources.length === 0 ? 'warn' : undefined)),
|
|
803
845
|
},
|
|
804
846
|
{
|
|
805
847
|
id: 'entity', order: 2, name: '轴实体归一', phase: '② Resolve · 归一', actor: '系统',
|
|
806
848
|
needsHuman: aliased.length > 0 || ambiguous.length > 0 || created.length > 0,
|
|
807
849
|
summary: `${axes.length} 个轴实体 · 命中 ${matched.length} · 新建候选 ${created.length} · 不唯一 ${ambiguous.length}`,
|
|
808
850
|
rows: [
|
|
809
|
-
{ label: '顺序', value: '
|
|
851
|
+
{ label: '顺序', value: '注册表直接命中 → 对有候选的歧义坐标合并一次模型补判 → 未命中时新建候选' },
|
|
810
852
|
{ label: '三个轴同一套', value: 'Object / Action / Scene 走同一套流程,没有哪个更特殊' },
|
|
811
|
-
{ label: '不唯一就不猜', value: '
|
|
853
|
+
{ label: '不唯一就不猜', value: '模型只在给定候选中选择;证据不足时保留歧义。猜错等于把知识挂到错误的对象上,而那个错误会一路传到卡名' },
|
|
812
854
|
{ label: '不机械拼前缀', value: '只有原文、章节、SourceRaw 元数据提供了作用域证据,才生成全限定名 —— 「通天塔」+ 每个对象会把「楼层」错加成「通天塔楼层」。人写的指导随已有坐标一起下发,由模型据此判断' },
|
|
813
855
|
/*
|
|
814
856
|
* 「这一次发了多少参考」必须露出来(0068)。模型看不到某条坐标时会以为库里没有它,
|
|
@@ -817,8 +859,10 @@ export function buildReport(input) {
|
|
|
817
859
|
{ label: '已有坐标', value: input.axesContext === undefined
|
|
818
860
|
? '这一次没有下发(没接注册表,或者库里还没有实体)—— 模型只能自己造名字'
|
|
819
861
|
: `下发 ${input.axesContext.injected} / 共 ${input.axesContext.totals} 条${input.axesContext.truncated > 0 ? ` · 未下发 ${input.axesContext.truncated} 条` : ''}${input.axesContext.selection === 'relevant' ? ' · 当前文档相关候选' : input.axesContext.selection === 'full' ? ' · 全集' : ''},含名字、别名、定义与人写的指导` },
|
|
820
|
-
{ label: '
|
|
821
|
-
|
|
862
|
+
{ label: '模型补判', value: input.model.axisResolution
|
|
863
|
+
? '本次对无法直接命中的坐标发出了一次合并请求;模型只能返回候选 ID,代码会验(查得到 / 同类 / 没被并)'
|
|
864
|
+
: '本次坐标都可直接解析,或没有可比较的候选,因此没有额外模型请求' },
|
|
865
|
+
{ label: '新建的是候选', value: '模型确认没有匹配项后才建 status=candidate;证据不足时保留歧义,等人确认' },
|
|
822
866
|
{ label: '三类绝不进别名', value: '上位概念(「通天塔spm取数」不能含「通天塔」)· 组成部分(不能含「spm取数」)· 相关但不同(不能含「通天塔埋点」)' },
|
|
823
867
|
{ label: '注册表', value: axes.some(axis => axis.outcome === 'no-registry')
|
|
824
868
|
? '这次没有查到库内注册表(这个部署上没有,或调用方没给)。所以只判得动文档内的写法变体'
|
|
@@ -861,17 +905,17 @@ export function buildReport(input) {
|
|
|
861
905
|
},
|
|
862
906
|
{
|
|
863
907
|
id: 'materialize', order: 5, name: '按坐标成卡', phase: '③ Materialize · 物化', actor: '系统',
|
|
864
|
-
needsHuman: collisions.length > 0 || noCoordinate.length > 0,
|
|
865
|
-
summary: `${wikiCards.length} 张 Wiki Card · ${placements}
|
|
908
|
+
needsHuman: collisions.length > 0 || noCoordinate.length > 0 || events.some(event => event.noCoordinate),
|
|
909
|
+
summary: `${wikiCards.length} 张 Wiki Card · ${placements} 条 Knowledge · ${events.filter(event => !event.noCoordinate).length} 个 Event`,
|
|
866
910
|
rows: [
|
|
867
911
|
{ label: '三步', value: '按 (object, action, scene) 分组 → 每组物化成一张 Wiki Card → 生成自然语言标题' },
|
|
868
912
|
{ label: '标题组织', value: '完整坐标写成「对象在场景下的动作」;缺少分量时退化为通顺的短标题;旧拼接标题保留为 alias' },
|
|
869
913
|
{ label: '为什么不让模型做', value: '坐标是卡片主键 · 标题是确定的展示投影 · 模型判会漂移(同一坐标每次给不同标题会污染召回)' },
|
|
870
|
-
{ label: '
|
|
871
|
-
{ label: '不成卡的那些', value: noCoordinate.length > 0 ? `${noCoordinate.length}
|
|
914
|
+
{ label: '卡片由 Knowledge 生成', value: '坐标下至少有一条 Knowledge 才物化 WikiCard;同坐标 Event 只建立引用,不单独建卡' },
|
|
915
|
+
{ label: '不成卡的那些', value: noCoordinate.length + events.filter(event => event.noCoordinate).length > 0 ? `${noCoordinate.length} 条 Knowledge、${events.filter(event => event.noCoordinate).length} 个 Event 缺少坐标,不归入坐标卡` : '无' },
|
|
872
916
|
],
|
|
873
917
|
items: wikiCards.length > 0
|
|
874
|
-
? wikiCards.map(card => makeItem(coordLabel(card.object, card.action, card.scene), card.name, `${card.placements.length}
|
|
918
|
+
? wikiCards.map(card => makeItem(coordLabel(card.object, card.action, card.scene), card.name, `${card.placements.length} 条 Knowledge · ${card.events.length} 个 Event`))
|
|
875
919
|
: [makeItem('—', '没有成卡', '知识一条都没有坐标,或者模型没给出知识', 'warn')],
|
|
876
920
|
},
|
|
877
921
|
{
|
|
@@ -907,7 +951,7 @@ export function buildReport(input) {
|
|
|
907
951
|
],
|
|
908
952
|
items: [
|
|
909
953
|
makeItem('召回单元', `${sections.size} 个 section`, '卡片按 ## 小节切成一节一条'),
|
|
910
|
-
makeItem('Knowledge', `${knowledge.length}
|
|
954
|
+
makeItem('Knowledge / Event', `${knowledge.length} / ${events.length}`, '两类并列真源;Knowledge 生成 WikiCard,Event 通过引用关联'),
|
|
911
955
|
makeItem('轴注册表', `${axes.length} 条`, 'canonical name + aliases —— 不是索引'),
|
|
912
956
|
],
|
|
913
957
|
},
|
|
@@ -950,6 +994,8 @@ export function buildReport(input) {
|
|
|
950
994
|
}
|
|
951
995
|
for (const item of noCoordinate)
|
|
952
996
|
exceptions.push({ step: '无坐标', message: `「${shortQuote(item.text)}」三个坐标分量都空。它不进矩阵、不成卡,但仍可被全库命中 —— 要人决定补坐标还是单独归档` });
|
|
997
|
+
for (const event of noCoordinateEvents)
|
|
998
|
+
exceptions.push({ step: 'Event 无坐标', message: `Event「${shortQuote(event.title)}」没有坐标,因此没有归入 Wiki Card;Event 本身和出处仍保留` });
|
|
953
999
|
for (const twin of twins)
|
|
954
1000
|
exceptions.push({ step: '同义候选', message: `${twin.ids.join(' / ')} 文本归一化后相同,要人确认是不是同一条知识` });
|
|
955
1001
|
for (const collision of collisions) {
|
|
@@ -968,6 +1014,7 @@ export function buildReport(input) {
|
|
|
968
1014
|
actions,
|
|
969
1015
|
scenes,
|
|
970
1016
|
knowledge,
|
|
1017
|
+
events,
|
|
971
1018
|
wikiCards,
|
|
972
1019
|
matrix,
|
|
973
1020
|
checks,
|
|
@@ -985,10 +1032,11 @@ function emptyReport(input) {
|
|
|
985
1032
|
const actions = [];
|
|
986
1033
|
const scenes = [];
|
|
987
1034
|
const knowledge = [];
|
|
1035
|
+
const events = [];
|
|
988
1036
|
const wikiCards = [];
|
|
989
1037
|
return buildReport({
|
|
990
1038
|
title: input.title, text: input.text, subject: input.subject,
|
|
991
|
-
objects, actions, scenes, knowledge, wikiCards, dropped: [],
|
|
1039
|
+
objects, actions, scenes, knowledge, events, wikiCards, dropped: [],
|
|
992
1040
|
matrix: buildMatrix([], [], [], []),
|
|
993
1041
|
problems: [],
|
|
994
1042
|
model: input.model, promptUser: input.promptUser,
|
|
@@ -1007,8 +1055,10 @@ export async function runWikiTrial(input) {
|
|
|
1007
1055
|
const subject = (input.subject ?? '').trim();
|
|
1008
1056
|
const docId = (input.docId ?? '').trim();
|
|
1009
1057
|
// 提示词先组装好再走分支:模型不可用时它照样要回给界面 —— 用户要看的正是"本来会发出去什么"。
|
|
1010
|
-
const promptUser = buildTrialPrompt({ title: input.title, text: input.text, ...(input.axes === undefined ? {} : { axes: input.axes }), ...(input.note ? { note: input.note } : {}) });
|
|
1011
|
-
const system = buildTrialSystem(input.sections);
|
|
1058
|
+
const promptUser = buildTrialPrompt({ title: input.title, text: input.text, ...(input.axes === undefined ? {} : { axes: input.axes }), ...(input.note ? { note: input.note } : {}), outputFormat: input.outputFormat });
|
|
1059
|
+
const system = buildTrialSystem(input.sections, input.outputFormat);
|
|
1060
|
+
const sessionId = input.sessionId ?? 'knowledge:trial';
|
|
1061
|
+
const request = { ...input.modelRequest, sessionId };
|
|
1012
1062
|
const axesContext = input.axes === undefined ? undefined : {
|
|
1013
1063
|
injected: ['object', 'action', 'scene'].reduce((sum, kind) => sum + (input.axes.entries[kind]?.length ?? 0), 0),
|
|
1014
1064
|
totals: ['object', 'action', 'scene'].reduce((sum, kind) => sum + (input.axes.totals[kind] ?? 0), 0),
|
|
@@ -1019,21 +1069,44 @@ export async function runWikiTrial(input) {
|
|
|
1019
1069
|
return emptyReport({
|
|
1020
1070
|
title: input.title, text: input.text, subject: subject || input.title, promptUser, system,
|
|
1021
1071
|
axesContext,
|
|
1022
|
-
model: { ok: false, why: input.callWhy ?? '模型不可用' },
|
|
1072
|
+
model: { ok: false, why: input.callWhy ?? '模型不可用', request },
|
|
1023
1073
|
});
|
|
1024
1074
|
}
|
|
1025
1075
|
let raw = '';
|
|
1076
|
+
let usage;
|
|
1026
1077
|
try {
|
|
1027
|
-
raw = await input.call({ system, prompt: promptUser, sessionId:
|
|
1078
|
+
raw = await input.call({ system, prompt: promptUser, sessionId, onUsage: value => { usage = value; }, onDelta: text => { raw += text; input.onDelta?.(text); } });
|
|
1028
1079
|
}
|
|
1029
1080
|
catch (cause) {
|
|
1030
1081
|
return emptyReport({
|
|
1031
1082
|
title: input.title, text: input.text, subject: subject || input.title, promptUser, system,
|
|
1032
1083
|
axesContext,
|
|
1033
|
-
model: {
|
|
1084
|
+
model: {
|
|
1085
|
+
ok: false,
|
|
1086
|
+
why: `调用模型失败:${cause instanceof Error ? cause.message : String(cause)}`,
|
|
1087
|
+
request,
|
|
1088
|
+
...(raw ? { response: raw } : {}),
|
|
1089
|
+
...(usage ? { usage } : {}),
|
|
1090
|
+
},
|
|
1034
1091
|
});
|
|
1035
1092
|
}
|
|
1036
|
-
|
|
1093
|
+
let parsed;
|
|
1094
|
+
let outputFormat = 'json';
|
|
1095
|
+
let parseError = '';
|
|
1096
|
+
const body = raw.trim().replace(/^```(?:toon|text)?\s*\n/, '').replace(/\n```\s*$/, '');
|
|
1097
|
+
try {
|
|
1098
|
+
if (/^format:\s*knowledge-table-v[12]\s*$/m.test(body)) {
|
|
1099
|
+
parsed = decodeExtractionTable(body);
|
|
1100
|
+
outputFormat = 'table';
|
|
1101
|
+
}
|
|
1102
|
+
else
|
|
1103
|
+
parsed = parseJsonObject(raw);
|
|
1104
|
+
if (parsed)
|
|
1105
|
+
parsed = normalizeKnowledgeExtraction(parsed);
|
|
1106
|
+
}
|
|
1107
|
+
catch (cause) {
|
|
1108
|
+
parseError = cause instanceof Error ? cause.message : String(cause);
|
|
1109
|
+
}
|
|
1037
1110
|
const record = parsed !== null && typeof parsed === 'object' ? parsed : undefined;
|
|
1038
1111
|
if (!record) {
|
|
1039
1112
|
return emptyReport({
|
|
@@ -1041,7 +1114,10 @@ export async function runWikiTrial(input) {
|
|
|
1041
1114
|
axesContext,
|
|
1042
1115
|
model: {
|
|
1043
1116
|
ok: false,
|
|
1044
|
-
why: '
|
|
1117
|
+
why: parseError || '模型返回不是有效的抽取表格或兼容 JSON',
|
|
1118
|
+
request,
|
|
1119
|
+
response: raw,
|
|
1120
|
+
...(usage ? { usage } : {}),
|
|
1045
1121
|
// 把模型实际说的那一段带上:只报「不是 JSON」的话,人不知道该去改什么。
|
|
1046
1122
|
...(raw.trim() ? { raw: raw.trim().replace(/\s+/g, ' ').slice(0, 160) } : {}),
|
|
1047
1123
|
},
|
|
@@ -1054,9 +1130,10 @@ export async function runWikiTrial(input) {
|
|
|
1054
1130
|
*/
|
|
1055
1131
|
const mentions = plainRecord(record.axis_mentions);
|
|
1056
1132
|
const knowledgeAxes = axisMentionsFromKnowledge(record.knowledge);
|
|
1057
|
-
const
|
|
1058
|
-
const
|
|
1059
|
-
const
|
|
1133
|
+
const eventAxes = axisMentionsFromEvents(record.events);
|
|
1134
|
+
const objectRead = readAxes(mergeAxisMentions(mentions.objects ?? record.objects, [...knowledgeAxes.object, ...eventAxes.object]), 'object');
|
|
1135
|
+
const actionRead = readAxes(mergeAxisMentions(mentions.actions ?? record.actions, [...knowledgeAxes.action, ...eventAxes.action]), 'action');
|
|
1136
|
+
const sceneRead = readAxes(mergeAxisMentions(mentions.scenes ?? record.scenes, [...knowledgeAxes.scene, ...eventAxes.scene]), 'scene');
|
|
1060
1137
|
/**
|
|
1061
1138
|
* Resolve 第 2 步:把 mention 交给**轴注册表**。
|
|
1062
1139
|
*
|
|
@@ -1067,18 +1144,40 @@ export async function runWikiTrial(input) {
|
|
|
1067
1144
|
* (`坑位click` → `通天塔坑位click`),而 Knowledge 的坐标写的是 mention。
|
|
1068
1145
|
* 顺序反了,那条知识就会因为「坐标不在清单里」被当成编造的坐标丢掉。
|
|
1069
1146
|
*/
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1147
|
+
let objects;
|
|
1148
|
+
let actions;
|
|
1149
|
+
let scenes;
|
|
1150
|
+
let axisResolution;
|
|
1151
|
+
if (input.resolveAxisSet) {
|
|
1152
|
+
const resolved = await input.resolveAxisSet({
|
|
1153
|
+
objects: objectRead.axes,
|
|
1154
|
+
actions: actionRead.axes,
|
|
1155
|
+
scenes: sceneRead.axes,
|
|
1156
|
+
});
|
|
1157
|
+
objects = resolved.objects;
|
|
1158
|
+
actions = resolved.actions;
|
|
1159
|
+
scenes = resolved.scenes;
|
|
1160
|
+
axisResolution = resolved.trace;
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
objects = await resolveAxes('object', objectRead.axes, input.resolveAxis);
|
|
1164
|
+
actions = await resolveAxes('action', actionRead.axes, input.resolveAxis);
|
|
1165
|
+
scenes = await resolveAxes('scene', sceneRead.axes, input.resolveAxis);
|
|
1166
|
+
}
|
|
1073
1167
|
const knowledgeRead = readKnowledge(record.knowledge, {
|
|
1074
1168
|
text: input.text,
|
|
1075
1169
|
// 有真文档就用它的 id:来源要指得回那份文档,而不是一个标题字符串。
|
|
1076
1170
|
documentId: docId || input.title,
|
|
1077
1171
|
objects, actions, scenes,
|
|
1078
1172
|
});
|
|
1173
|
+
const eventRead = readEvents(record.events, {
|
|
1174
|
+
text: input.text,
|
|
1175
|
+
documentId: docId || input.title,
|
|
1176
|
+
objects, actions, scenes,
|
|
1177
|
+
});
|
|
1079
1178
|
// `dropped` 在新契约里收在 `audit` 下 —— 它是审计,不是知识模型的一部分(§5.5)。
|
|
1080
1179
|
const dropped = readDropped(plainRecord(record.audit).dropped ?? record.dropped);
|
|
1081
|
-
const wikiCards = materialize(knowledgeRead.knowledge);
|
|
1180
|
+
const wikiCards = materialize(knowledgeRead.knowledge, eventRead.events);
|
|
1082
1181
|
const modelSubject = str(record.subject) || subject || input.title;
|
|
1083
1182
|
return buildReport({
|
|
1084
1183
|
title: input.title, text: input.text, subject: modelSubject,
|
|
@@ -1086,13 +1185,25 @@ export async function runWikiTrial(input) {
|
|
|
1086
1185
|
actions,
|
|
1087
1186
|
scenes,
|
|
1088
1187
|
knowledge: knowledgeRead.knowledge,
|
|
1188
|
+
events: eventRead.events,
|
|
1089
1189
|
wikiCards,
|
|
1090
|
-
matrix: buildMatrix(objects.map(axis => axis.name), actions.map(axis => axis.name), knowledgeRead.knowledge, wikiCards),
|
|
1091
|
-
problems: [...objectRead.problems, ...actionRead.problems, ...sceneRead.problems, ...knowledgeRead.problems],
|
|
1190
|
+
matrix: buildMatrix(objects.map(axis => axis.name), actions.map(axis => axis.name), knowledgeRead.knowledge, wikiCards, eventRead.events),
|
|
1191
|
+
problems: [...objectRead.problems, ...actionRead.problems, ...sceneRead.problems, ...knowledgeRead.problems, ...eventRead.problems],
|
|
1092
1192
|
dropped,
|
|
1093
|
-
model:
|
|
1094
|
-
|
|
1095
|
-
:
|
|
1193
|
+
model: {
|
|
1194
|
+
ok: knowledgeRead.knowledge.length > 0 || eventRead.events.length > 0,
|
|
1195
|
+
parsed: Array.isArray(record.knowledge) && Array.isArray(record.events ?? [])
|
|
1196
|
+
&& knowledgeRead.knowledge.length === record.knowledge.length
|
|
1197
|
+
&& eventRead.events.length === (Array.isArray(record.events) ? record.events.length : 0)
|
|
1198
|
+
&& knowledgeRead.knowledge.every(item => item.sources.length > 0 && item.sources.every(source => source.found))
|
|
1199
|
+
&& eventRead.events.every(item => [...item.sources, ...item.timeline.flatMap(step => step.sources)].every(source => source.found)),
|
|
1200
|
+
outputFormat,
|
|
1201
|
+
...(!(knowledgeRead.knowledge.length > 0 || eventRead.events.length > 0) ? { why: '模型没有给出 Knowledge 或 Event' } : {}),
|
|
1202
|
+
request,
|
|
1203
|
+
response: raw,
|
|
1204
|
+
...(usage ? { usage } : {}),
|
|
1205
|
+
...(axisResolution ? { axisResolution } : {}),
|
|
1206
|
+
},
|
|
1096
1207
|
promptUser, system,
|
|
1097
1208
|
...(axesContext === undefined ? {} : { axesContext }),
|
|
1098
1209
|
});
|
|
@@ -1132,34 +1243,36 @@ async function resolveAxes(kind, axes, resolveAxis) {
|
|
|
1132
1243
|
// `null` = 这个部署上没有注册表。那不是「没命中」,是「这一次没查过」。
|
|
1133
1244
|
if (resolution === null)
|
|
1134
1245
|
return axes;
|
|
1135
|
-
|
|
1136
|
-
const entity = resolution.entity;
|
|
1137
|
-
out.push({
|
|
1138
|
-
name: entity.name,
|
|
1139
|
-
id: entity.id,
|
|
1140
|
-
// 原来的 mention 进别名:它可能只是这个实体的一种写法。
|
|
1141
|
-
aliases: [...new Set([...axis.aliases, ...(entity.name === axis.name ? [] : [axis.name])])],
|
|
1142
|
-
outcome: resolution.outcome === 'created' ? 'new' : 'matched',
|
|
1143
|
-
how: describeHit(resolution),
|
|
1144
|
-
// 报告里显示的是**库里那份**(模型这次给的可能没被采纳 —— 人写的定义不许覆盖)。
|
|
1145
|
-
...(entity.description ? { definition: entity.description } : axis.definition ? { definition: axis.definition } : {}),
|
|
1146
|
-
...(axis.evidence ? { evidence: axis.evidence } : {}),
|
|
1147
|
-
});
|
|
1148
|
-
continue;
|
|
1149
|
-
}
|
|
1150
|
-
if (resolution.outcome === 'ambiguous') {
|
|
1151
|
-
const names = (resolution.candidates ?? []).map(candidate => candidate.name);
|
|
1152
|
-
out.push({
|
|
1153
|
-
...axis,
|
|
1154
|
-
outcome: 'ambiguous',
|
|
1155
|
-
how: names.length > 0 ? `不唯一,候选:${names.join('、')}` : '不唯一,但注册表里没有候选',
|
|
1156
|
-
});
|
|
1157
|
-
continue;
|
|
1158
|
-
}
|
|
1159
|
-
out.push({ ...axis, outcome: 'no-registry', how: '只做了文档内的机械归一' });
|
|
1246
|
+
out.push(applyTrialAxisResolution(axis, resolution));
|
|
1160
1247
|
}
|
|
1161
1248
|
return out;
|
|
1162
1249
|
}
|
|
1250
|
+
/** 将注册表结论变成报告里的坐标。供批量补判复用同一套字段处理。 */
|
|
1251
|
+
export function applyTrialAxisResolution(axis, resolution) {
|
|
1252
|
+
if (resolution === null)
|
|
1253
|
+
return { ...axis, outcome: 'no-registry', how: '只做了文档内的机械归一' };
|
|
1254
|
+
if ((resolution.outcome === 'matched' || resolution.outcome === 'created') && resolution.entity) {
|
|
1255
|
+
const entity = resolution.entity;
|
|
1256
|
+
return {
|
|
1257
|
+
name: entity.name,
|
|
1258
|
+
id: entity.id,
|
|
1259
|
+
aliases: [...new Set([...axis.aliases, ...(entity.name === axis.name ? [] : [axis.name])])],
|
|
1260
|
+
outcome: resolution.outcome === 'created' ? 'new' : 'matched',
|
|
1261
|
+
how: describeHit(resolution),
|
|
1262
|
+
...(entity.description ? { definition: entity.description } : axis.definition ? { definition: axis.definition } : {}),
|
|
1263
|
+
...(axis.evidence ? { evidence: axis.evidence } : {}),
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
if (resolution.outcome === 'ambiguous') {
|
|
1267
|
+
const names = (resolution.candidates ?? []).map(candidate => candidate.name);
|
|
1268
|
+
return {
|
|
1269
|
+
...axis,
|
|
1270
|
+
outcome: 'ambiguous',
|
|
1271
|
+
how: names.length > 0 ? `不唯一,候选:${names.join('、')}` : '不唯一,但注册表里没有候选',
|
|
1272
|
+
};
|
|
1273
|
+
}
|
|
1274
|
+
return { ...axis, outcome: 'ambiguous', how: '坐标为空,无法解析' };
|
|
1275
|
+
}
|
|
1163
1276
|
/** 读 `dropped`。它是**审计轨迹**(§5.5),不进知识模型。 */
|
|
1164
1277
|
function readDropped(raw) {
|
|
1165
1278
|
if (!Array.isArray(raw))
|
|
@@ -1181,7 +1294,7 @@ export function trialSummary(report) {
|
|
|
1181
1294
|
const pieces = [
|
|
1182
1295
|
`${report.lines} 行`, `${report.chars} 字`,
|
|
1183
1296
|
`${report.objects.length} 对象`, `${report.actions.length} 动作`, `${report.scenes.length} 场景`,
|
|
1184
|
-
`${report.knowledge.length}
|
|
1297
|
+
`${report.knowledge.length} Knowledge`, `${report.events.length} Event`, `${report.wikiCards.length} Wiki Card`,
|
|
1185
1298
|
];
|
|
1186
1299
|
const dropped = report.audit.dropped.length;
|
|
1187
1300
|
if (dropped > 0)
|