@marinoscar/kvox-eval 0.0.0-bootstrap → 0.1.0-next.0
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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/ask/index.d.ts +6 -0
- package/dist/ask/index.js +28 -0
- package/dist/ask/question-schema.d.ts +121 -0
- package/dist/ask/question-schema.js +167 -0
- package/dist/ask/report.d.ts +88 -0
- package/dist/ask/report.js +170 -0
- package/dist/ask/scorer.d.ts +104 -0
- package/dist/ask/scorer.js +164 -0
- package/dist/ask-run/ask-command.d.ts +62 -0
- package/dist/ask-run/ask-command.js +254 -0
- package/dist/ask-run/host/app.d.ts +65 -0
- package/dist/ask-run/host/app.js +146 -0
- package/dist/ask-run/host/db.d.ts +38 -0
- package/dist/ask-run/host/db.js +126 -0
- package/dist/ask-run/host/ports.d.ts +35 -0
- package/dist/ask-run/host/ports.js +113 -0
- package/dist/ask-run/index.d.ts +13 -0
- package/dist/ask-run/index.js +35 -0
- package/dist/ask-run/replay.d.ts +128 -0
- package/dist/ask-run/replay.js +212 -0
- package/dist/ask-run/run-ask-eval.d.ts +125 -0
- package/dist/ask-run/run-ask-eval.js +193 -0
- package/dist/ask-run/seed-golden-graph.d.ts +64 -0
- package/dist/ask-run/seed-golden-graph.js +495 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +12 -0
- package/dist/cli/kg-command.d.ts +66 -0
- package/dist/cli/kg-command.js +238 -0
- package/dist/cli/main.d.ts +18 -0
- package/dist/cli/main.js +69 -0
- package/dist/fixtures/domains.d.ts +16 -0
- package/dist/fixtures/domains.js +33 -0
- package/dist/fixtures/fixture-schema.d.ts +323 -0
- package/dist/fixtures/fixture-schema.js +199 -0
- package/dist/fixtures/index.d.ts +16 -0
- package/dist/fixtures/index.js +40 -0
- package/dist/fixtures/load.d.ts +73 -0
- package/dist/fixtures/load.js +137 -0
- package/dist/fixtures/questions.d.ts +15 -0
- package/dist/fixtures/questions.js +26 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +36 -0
- package/dist/kg/gold-runner.d.ts +13 -0
- package/dist/kg/gold-runner.js +57 -0
- package/dist/kg/index.d.ts +17 -0
- package/dist/kg/index.js +65 -0
- package/dist/kg/internals.d.ts +7 -0
- package/dist/kg/internals.js +17 -0
- package/dist/kg/prediction-schema.d.ts +245 -0
- package/dist/kg/prediction-schema.js +102 -0
- package/dist/kg/predictions.d.ts +11 -0
- package/dist/kg/predictions.js +49 -0
- package/dist/kg/report.d.ts +84 -0
- package/dist/kg/report.js +125 -0
- package/dist/kg/run-kg-eval.d.ts +77 -0
- package/dist/kg/run-kg-eval.js +137 -0
- package/dist/kg/runner.d.ts +72 -0
- package/dist/kg/runner.js +51 -0
- package/dist/kg/runners/extract-resolve-runner.d.ts +40 -0
- package/dist/kg/runners/extract-resolve-runner.js +199 -0
- package/dist/kg/runners/extract-runner.d.ts +65 -0
- package/dist/kg/runners/extract-runner.js +243 -0
- package/dist/kg/scorer.d.ts +226 -0
- package/dist/kg/scorer.js +463 -0
- package/dist/kg/targets.d.ts +17 -0
- package/dist/kg/targets.js +16 -0
- package/dist/kg/text.d.ts +45 -0
- package/dist/kg/text.js +100 -0
- package/dist/live/adapters.d.ts +16 -0
- package/dist/live/adapters.js +58 -0
- package/dist/live/env.d.ts +39 -0
- package/dist/live/env.js +56 -0
- package/dist/live/index.d.ts +6 -0
- package/dist/live/index.js +16 -0
- package/dist/live/live-ai.d.ts +104 -0
- package/dist/live/live-ai.js +157 -0
- package/dist/parity/constants.d.ts +79 -0
- package/dist/parity/constants.js +104 -0
- package/dist/parity/index.d.ts +20 -0
- package/dist/parity/index.js +38 -0
- package/dist/parity/internals.d.ts +8 -0
- package/dist/parity/internals.js +16 -0
- package/dist/parity/scenario.d.ts +45 -0
- package/dist/parity/scenario.js +245 -0
- package/dist/parity/script.d.ts +44 -0
- package/dist/parity/script.js +136 -0
- package/dist/parity/snapshot.d.ts +43 -0
- package/dist/parity/snapshot.js +71 -0
- package/dist/real-data/index.d.ts +2 -0
- package/dist/real-data/index.js +12 -0
- package/dist/real-data/real-data.d.ts +76 -0
- package/dist/real-data/real-data.js +156 -0
- package/fixtures/kg-golden/README.md +136 -0
- package/fixtures/kg-golden/ask-questions.json +458 -0
- package/fixtures/kg-golden/meetings/m01-northwind-pilot-kickoff.json +792 -0
- package/fixtures/kg-golden/meetings/m02-halden-migration-planning.json +814 -0
- package/fixtures/kg-golden/meetings/m03-larkspur-weekly-sync.json +601 -0
- package/fixtures/kg-golden/meetings/m04-corvid-intake-discovery.json +690 -0
- package/fixtures/kg-golden/meetings/m05-hosting-vendor-selection.json +631 -0
- package/fixtures/kg-golden/meetings/m06-northwind-floor-data-review.json +649 -0
- package/fixtures/kg-golden/meetings/m07-gullwing-intro-notes.json +428 -0
- package/fixtures/kg-golden/meetings/m08-halden-migration-checkpoint.json +672 -0
- package/fixtures/kg-golden/meetings/m09-northwind-platform-org-update.json +711 -0
- package/fixtures/kg-golden/meetings/m10-corvid-prototype-review.json +623 -0
- package/fixtures/kg-golden/meetings/m11-solvane-grid-dashboard-scoping.json +689 -0
- package/fixtures/kg-golden/meetings/m12-northwind-pilot-replan.json +681 -0
- package/fixtures/kg-golden/meetings/m13-halden-cutover-go-no-go.json +721 -0
- package/fixtures/kg-golden/meetings/m14-gullwing-discovery-readout.json +719 -0
- package/fixtures/kg-golden/meetings/m15-halden-handover-ravi-leaving.json +716 -0
- package/fixtures/kg-golden/meetings/m16-varden-claims-portal-intro.json +704 -0
- package/fixtures/kg-golden/meetings/m17-corvid-usability-debrief.json +572 -0
- package/fixtures/kg-golden/meetings/m18-hosting-decision-revisited.json +655 -0
- package/fixtures/kg-golden/meetings/m19-solvane-integration-kickoff.json +726 -0
- package/fixtures/kg-golden/meetings/m20-northwind-go-live-retro.json +673 -0
- package/fixtures/kg-golden/meetings/m21-quarterly-account-review.json +449 -0
- package/fixtures/kg-golden/meetings/m22-halden-intro-call-2020.json +558 -0
- package/fixtures/kg-golden/meetings/m23-gullwing-model-review.json +702 -0
- package/fixtures/kg-golden/meetings/m24-varden-discovery-midpoint.json +643 -0
- package/fixtures/kg-golden/meetings/m25-corvid-rollout-planning.json +642 -0
- package/fixtures/kg-golden/meetings/m26-larkspur-engineering-prep.json +695 -0
- package/fixtures/kg-golden/meetings/m27-solvane-phase-one-demo.json +649 -0
- package/fixtures/kg-golden/meetings/m28-northwind-building-5-scoping.json +715 -0
- package/fixtures/kg-golden/meetings/m29-halden-southern-cutover-review.json +752 -0
- package/fixtures/kg-golden/meetings/m30-varden-portal-build-kickoff.json +697 -0
- package/fixtures/kg-golden/meetings/m31-gullwing-rollout-renewal.json +681 -0
- package/fixtures/kg-golden/meetings/m32-brambleway-weekly-sync.json +472 -0
- package/fixtures/kg-golden/meetings/m33-nina-oliver-one-on-one.json +342 -0
- package/fixtures/kg-golden/meetings/m34-coffee-with-dana.json +249 -0
- package/fixtures/kg-golden/meetings/m35-brambleway-june-sync.json +553 -0
- package/fixtures/kg-golden/meetings/m36-copenhagen-conference-planning.json +296 -0
- package/host/generated/client.d.ts +1 -0
- package/host/generated/client.js +5 -0
- package/host/generated/default.d.ts +1 -0
- package/host/generated/default.js +5 -0
- package/host/generated/edge.d.ts +1 -0
- package/host/generated/edge.js +1658 -0
- package/host/generated/index-browser.js +1684 -0
- package/host/generated/index.d.ts +192335 -0
- package/host/generated/index.js +1658 -0
- package/host/generated/package.json +139 -0
- package/host/generated/query_compiler_fast_bg.js +2 -0
- package/host/generated/query_compiler_fast_bg.wasm +0 -0
- package/host/generated/query_compiler_fast_bg.wasm-base64.js +2 -0
- package/host/generated/runtime/client.d.ts +3433 -0
- package/host/generated/runtime/client.js +110 -0
- package/host/generated/runtime/index-browser.d.ts +90 -0
- package/host/generated/runtime/index-browser.js +6 -0
- package/host/generated/runtime/wasm-compiler-edge.js +100 -0
- package/host/generated/schema.prisma +6312 -0
- package/host/generated/wasm-edge-light-loader.mjs +5 -0
- package/host/generated/wasm-worker-loader.mjs +5 -0
- package/host/prisma/fragments/kvox.ask.prisma +126 -0
- package/host/prisma/fragments/kvox.graph.prisma +1073 -0
- package/host/prisma/fragments/kvox.notes.prisma +787 -0
- package/host/prisma/fragments/kvox.search.prisma +211 -0
- package/host/prisma/fragments/kvox.transcripts.prisma +790 -0
- package/host/prisma/kvox.lock +101 -0
- package/host/prisma/migrations/20240101000000_initial/migration.sql +297 -0
- package/host/prisma/migrations/20240101000001_add_personal_access_tokens/migration.sql +31 -0
- package/host/prisma/migrations/20240101000002_add_credentials/migration.sql +20 -0
- package/host/prisma/migrations/20240101000003_add_notification_deliveries/migration.sql +27 -0
- package/host/prisma/migrations/20240101000004_drop_stale_uuid_defaults/migration.sql +35 -0
- package/host/prisma/migrations/20240101000005_add_notifications/migration.sql +22 -0
- package/host/prisma/migrations/20240101000006_add_push_subscriptions/migration.sql +25 -0
- package/host/prisma/migrations/20240101000007_add_jobs/migration.sql +110 -0
- package/host/prisma/migrations/20240101000008_add_worker_nodes/migration.sql +90 -0
- package/host/prisma/migrations/20240101000009_add_database_backup_runs/migration.sql +104 -0
- package/host/prisma/migrations/20240101000010_add_notification_broadcasts/migration.sql +57 -0
- package/host/prisma/migrations/20240101000011_add_backup_run_job_link/migration.sql +87 -0
- package/host/prisma/migrations/20240101000012_add_job_node_secrets/migration.sql +61 -0
- package/host/prisma/migrations/20240101000013_add_backup_run_pg_dump_version/migration.sql +26 -0
- package/host/prisma/migrations/20240101000014_add_job_claim_token/migration.sql +92 -0
- package/host/prisma/migrations/20240101000015_add_ai_platform/migration.sql +108 -0
- package/host/prisma/migrations/20240101000016_revoke_viewer_ai_use/migration.sql +32 -0
- package/host/prisma/migrations/20240101000017_add_user_credentials/migration.sql +29 -0
- package/host/prisma/migrations/20240101000018_add_device_session_credential_link/migration.sql +52 -0
- package/host/prisma/migrations/20240101000019_add_worker_node_vitals/migration.sql +3 -0
- package/host/prisma/migrations/20240101000020_add_job_trace_context/migration.sql +6 -0
- package/host/prisma/migrations/20240101000021_add_retention_created_at_indexes/migration.sql +13 -0
- package/host/prisma/migrations/20240101000022_add_organizations/migration.sql +142 -0
- package/host/prisma/migrations/20240101000023_split_system_org_roles/migration.sql +131 -0
- package/host/prisma/migrations/20240101000024_org_scoped_rls/migration.sql +215 -0
- package/host/prisma/migrations/20240101000025_add_groups/migration.sql +165 -0
- package/host/prisma/migrations/20240101000026_add_grants/migration.sql +117 -0
- package/host/prisma/migrations/20240101000027_add_org_settings/migration.sql +49 -0
- package/host/prisma/migrations/20240101000028_add_org_credentials/migration.sql +54 -0
- package/host/prisma/migrations/20240101000029_add_jobs_org_id/migration.sql +18 -0
- package/host/prisma/migrations/20240101000030_add_jobs_org_id_status_index/migration.sql +6 -0
- package/host/prisma/migrations/20240101000031_add_broadcast_target_org/migration.sql +21 -0
- package/host/prisma/migrations/20240101000032_add_android_app/migration.sql +60 -0
- package/host/prisma/migrations/20240101000033_open_job_reason/migration.sql +16 -0
- package/host/prisma/migrations/20240101000034_ai_usage_feature/migration.sql +37 -0
- package/host/prisma/migrations/20240101000035_add_app_metadata/migration.sql +49 -0
- package/host/prisma/migrations/20240101000036_open_sharing_vocabularies/migration.sql +97 -0
- package/host/prisma/migrations/20260914130000_kvox_add_transcripts/migration.sql +322 -0
- package/host/prisma/migrations/20260914140000_kvox_add_notes/migration.sql +311 -0
- package/host/prisma/migrations/20260915120000_kvox_add_search_vectors/migration.sql +150 -0
- package/host/prisma/migrations/20260915130000_kvox_add_search_embeddings/migration.sql +362 -0
- package/host/prisma/migrations/20260915210000_kvox_add_note_title_source/migration.sql +30 -0
- package/host/prisma/migrations/20260923120000_kvox_add_note_generation_context_snapshot/migration.sql +24 -0
- package/host/prisma/migrations/20260923130000_kvox_add_user_hidden_note_templates/migration.sql +35 -0
- package/host/prisma/migrations/20260923140000_kvox_add_transcript_speaker_identities/migration.sql +6 -0
- package/host/prisma/migrations/20260923150000_kvox_transcript_name_checks/migration.sql +95 -0
- package/host/prisma/migrations/20260923160000_kvox_add_note_body_format/migration.sql +27 -0
- package/host/prisma/migrations/20260923170000_kvox_add_note_version_body_format/migration.sql +23 -0
- package/host/prisma/migrations/20260926012548_kvox_add_knowledge_graph/migration.sql +680 -0
- package/host/prisma/migrations/20260926030000_kvox_fix_kg_relations_valid_precision_chk/migration.sql +29 -0
- package/host/prisma/migrations/20260926030100_kvox_add_transcript_recorded_at/migration.sql +9 -0
- package/host/prisma/migrations/20260926030200_kvox_kg_evidence_invariant/migration.sql +60 -0
- package/host/prisma/migrations/20260926040000_kvox_add_kg_graph_layouts/migration.sql +30 -0
- package/host/prisma/migrations/20260926050000_kvox_add_ask_conversations/migration.sql +99 -0
- package/host/prisma/migrations/20260926231512_kvox_add_kg_exports/migration.sql +52 -0
- package/host/prisma/migrations/20261016120000_kvox_transcripts_org_id/migration.sql +49 -0
- package/host/prisma/platform.lock +319 -0
- package/host/prisma/schema/app.kvox.ask.prisma +110 -0
- package/host/prisma/schema/app.kvox.graph.prisma +1030 -0
- package/host/prisma/schema/app.kvox.notes.prisma +746 -0
- package/host/prisma/schema/app.kvox.search.prisma +208 -0
- package/host/prisma/schema/app.kvox.transcripts.prisma +726 -0
- package/host/prisma/schema/platform.ai.prisma +419 -0
- package/host/prisma/schema/platform.android-app.prisma +46 -0
- package/host/prisma/schema/platform.base.prisma +15 -0
- package/host/prisma/schema/platform.credentials.prisma +156 -0
- package/host/prisma/schema/platform.db-backup.prisma +359 -0
- package/host/prisma/schema/platform.identity.prisma +638 -0
- package/host/prisma/schema/platform.jobs.prisma +824 -0
- package/host/prisma/schema/platform.notifications.prisma +641 -0
- package/host/prisma/schema/platform.settings.prisma +53 -0
- package/host/prisma/schema/platform.sharing.prisma +208 -0
- package/host/prisma/schema/platform.storage.prisma +118 -0
- package/package.json +112 -1
- package/parity/requests.ask.json +2681 -0
- package/parity/requests.m01.json +1554 -0
- package/parity/requests.m02.json +1554 -0
- package/parity/requests.m03.json +1554 -0
- package/parity/requests.m04.json +1554 -0
- package/parity/requests.m05.json +1554 -0
- package/parity/requests.m06.json +1554 -0
- package/parity/requests.m07.json +1554 -0
- package/parity/requests.m08.json +1554 -0
- package/parity/requests.m09.json +1554 -0
- package/parity/requests.m10.json +1554 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// The `extract` kg:eval runner (#363; docs/specs/ontology.md §6)
|
|
4
|
+
// =============================================================================
|
|
5
|
+
//
|
|
6
|
+
// Runs `kg.extract`'s own pure pipeline against one golden fixture, with NO
|
|
7
|
+
// database: fixture → `ExtractionInput` → `buildExtractionContext` →
|
|
8
|
+
// `assembleExtractionPrompt` + `buildExtractionOutputSchema` → ONE
|
|
9
|
+
// `KvoxAiPort.generateStructured` call (`createKvoxAi` over the provider
|
|
10
|
+
// adapters for a live run, a fake in a test) → `validateExtraction` → the deterministic Meeting
|
|
11
|
+
// and ATTENDED rows → `applyPrecheck` (default preferences) → a prediction.
|
|
12
|
+
//
|
|
13
|
+
// It is the production code path minus the loader and the writer, so a score
|
|
14
|
+
// measures the prompt, the schema and the validator the product ships.
|
|
15
|
+
//
|
|
16
|
+
// A fixture's speaker is treated as IDENTIFIED_AS the known Person whose label
|
|
17
|
+
// or alias is its display name — what #356's speaker naming produces — so the
|
|
18
|
+
// known-entity priority and the ATTENDED rows behave as they would in the app.
|
|
19
|
+
// The golden set labels its own Meeting entity (key `meeting`); the runner
|
|
20
|
+
// emits the deterministic Meeting row under the same ref.
|
|
21
|
+
//
|
|
22
|
+
// ⚠ The runner never sees a key: the port it is handed owns it (#580). A
|
|
23
|
+
// prediction carries `model` alone.
|
|
24
|
+
// =============================================================================
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.EVAL_USER_ID = exports.EVAL_CONTEXT_WINDOW_TOKENS = exports.EVAL_TIMEOUT_MS = exports.EVAL_MAX_OUTPUT_TOKENS = void 0;
|
|
27
|
+
exports.fixtureToInput = fixtureToInput;
|
|
28
|
+
exports.rowsToPrediction = rowsToPrediction;
|
|
29
|
+
exports.runExtraction = runExtraction;
|
|
30
|
+
exports.precheckToPrediction = precheckToPrediction;
|
|
31
|
+
exports.createExtractRunner = createExtractRunner;
|
|
32
|
+
const ontology_1 = require("@marinoscar/kvox-contract/ontology");
|
|
33
|
+
const zod_1 = require("zod");
|
|
34
|
+
const internals_js_1 = require("../internals.js");
|
|
35
|
+
const graph_extraction_1 = require("@marinoscar/kvox-api/graph-extraction");
|
|
36
|
+
const graph_1 = require("@marinoscar/kvox-api/graph");
|
|
37
|
+
const index_js_1 = require("../../fixtures/index.js");
|
|
38
|
+
/**
|
|
39
|
+
* The completion ceiling an eval run uses (a production run takes it from policy).
|
|
40
|
+
*
|
|
41
|
+
* @stability experimental
|
|
42
|
+
*/
|
|
43
|
+
exports.EVAL_MAX_OUTPUT_TOKENS = 16_000;
|
|
44
|
+
/**
|
|
45
|
+
* How long one structured call may take before the run gives up on it.
|
|
46
|
+
*
|
|
47
|
+
* @stability experimental
|
|
48
|
+
*/
|
|
49
|
+
exports.EVAL_TIMEOUT_MS = 180_000;
|
|
50
|
+
/**
|
|
51
|
+
* The context window an eval target reports (the port's target carries one; a direct runtime never reads it).
|
|
52
|
+
*
|
|
53
|
+
* @stability experimental
|
|
54
|
+
*/
|
|
55
|
+
exports.EVAL_CONTEXT_WINDOW_TOKENS = 128_000;
|
|
56
|
+
/**
|
|
57
|
+
* The user id an eval call carries (there is no signed-in user).
|
|
58
|
+
*
|
|
59
|
+
* @stability experimental
|
|
60
|
+
*/
|
|
61
|
+
exports.EVAL_USER_ID = 'kg-eval';
|
|
62
|
+
/**
|
|
63
|
+
* The one fixture → input mapping. Pure.
|
|
64
|
+
*
|
|
65
|
+
* @stability experimental
|
|
66
|
+
*/
|
|
67
|
+
function fixtureToInput(fixture) {
|
|
68
|
+
const recordedAt = new Date(fixture.recordedAt);
|
|
69
|
+
const known = fixture.knownEntities.map((k) => ({
|
|
70
|
+
id: k.id,
|
|
71
|
+
type: k.type,
|
|
72
|
+
label: k.label,
|
|
73
|
+
aliases: [...k.aliases],
|
|
74
|
+
reviewStatus: 'accepted',
|
|
75
|
+
mergedIntoId: null,
|
|
76
|
+
orgLabel: null,
|
|
77
|
+
}));
|
|
78
|
+
const personFor = (name) => {
|
|
79
|
+
if (!name)
|
|
80
|
+
return null;
|
|
81
|
+
const n = (0, internals_js_1.normalizeForMatch)(name);
|
|
82
|
+
const hit = known.find((k) => k.type === 'Person' && [k.label, ...k.aliases].some((a) => (0, internals_js_1.normalizeForMatch)(a) === n));
|
|
83
|
+
return hit?.id ?? null;
|
|
84
|
+
};
|
|
85
|
+
const speakers = fixture.hasTranscript
|
|
86
|
+
? fixture.speakers.map((s) => ({ id: s.id, label: s.label, displayName: s.displayName, personEntityId: personFor(s.displayName) }))
|
|
87
|
+
: [];
|
|
88
|
+
const linked = new Set(speakers.map((s) => s.personEntityId).filter((id) => id !== null));
|
|
89
|
+
return {
|
|
90
|
+
note: {
|
|
91
|
+
id: `${fixture.id}-note`,
|
|
92
|
+
title: fixture.title,
|
|
93
|
+
bodyAtVersion: fixture.note.body,
|
|
94
|
+
version: fixture.note.version,
|
|
95
|
+
contextText: fixture.contextText,
|
|
96
|
+
createdAt: recordedAt,
|
|
97
|
+
},
|
|
98
|
+
transcript: fixture.hasTranscript
|
|
99
|
+
? { id: `${fixture.id}-transcript`, title: fixture.title, recordedAt, createdAt: recordedAt }
|
|
100
|
+
: null,
|
|
101
|
+
segments: fixture.hasTranscript
|
|
102
|
+
? fixture.segments.map((s) => ({ id: s.id, rev: s.rev, startMs: s.startMs, endMs: s.endMs, speakerId: s.speakerId, text: s.text }))
|
|
103
|
+
: [],
|
|
104
|
+
speakers,
|
|
105
|
+
effectiveSchema: (0, ontology_1.computeEffectiveSchema)({ enabledDomains: (0, index_js_1.fixtureDomains)(fixture), userAttributes: [] }),
|
|
106
|
+
guidance: null,
|
|
107
|
+
knownEntityCandidates: {
|
|
108
|
+
pinned: [],
|
|
109
|
+
speakerPersons: known.filter((k) => linked.has(k.id)),
|
|
110
|
+
organizations: [],
|
|
111
|
+
contextPool: known,
|
|
112
|
+
recentlyMentioned: known,
|
|
113
|
+
},
|
|
114
|
+
existingMeeting: null,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const endpoint = (ref) => (ref === null ? null : 'entityId' in ref ? ref.entityId : ref.ref);
|
|
118
|
+
const evidenceOf = (row) => row.evidence.map((e) => e.source === 'segment'
|
|
119
|
+
? { source: 'segment', segmentId: e.segmentId, quote: e.quote }
|
|
120
|
+
: { source: 'note', segmentId: null, quote: e.quote });
|
|
121
|
+
/**
|
|
122
|
+
* Proposal rows (with their pre-check decisions) → a kg:eval prediction. Pure.
|
|
123
|
+
*
|
|
124
|
+
* @stability experimental
|
|
125
|
+
*/
|
|
126
|
+
function rowsToPrediction(fixtureId, model, rows, decisions, stats) {
|
|
127
|
+
const prediction = { fixtureId, model, entities: [], relations: [], items: [], stats };
|
|
128
|
+
rows.forEach((row, i) => {
|
|
129
|
+
const prechecked = decisions[i] === 'accept';
|
|
130
|
+
if (row.kind === 'entity') {
|
|
131
|
+
const linked = row.resolution?.ref ?? null;
|
|
132
|
+
prediction.entities.push({
|
|
133
|
+
ref: row.payload.ref,
|
|
134
|
+
type: row.payload.type,
|
|
135
|
+
label: row.payload.label,
|
|
136
|
+
aliases: [...row.payload.aliases],
|
|
137
|
+
resolution: linked
|
|
138
|
+
? { outcome: 'linked', entityId: linked, score: row.resolution?.score ?? null, prechecked }
|
|
139
|
+
: { outcome: 'new', entityId: null, score: null, prechecked },
|
|
140
|
+
evidence: evidenceOf(row),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (row.kind === 'relation') {
|
|
144
|
+
prediction.relations.push({
|
|
145
|
+
type: row.payload.type,
|
|
146
|
+
from: endpoint(row.payload.from),
|
|
147
|
+
to: endpoint(row.payload.to),
|
|
148
|
+
validFrom: row.payload.validFrom,
|
|
149
|
+
validTo: row.payload.validTo,
|
|
150
|
+
precision: row.payload.precision,
|
|
151
|
+
evidence: evidenceOf(row),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
prediction.items.push({
|
|
156
|
+
kind: row.payload.kind,
|
|
157
|
+
subject: endpoint(row.payload.subject) ?? '',
|
|
158
|
+
owner: endpoint(row.payload.owner),
|
|
159
|
+
counterparty: endpoint(row.payload.counterparty),
|
|
160
|
+
title: row.payload.title,
|
|
161
|
+
statement: row.payload.statement,
|
|
162
|
+
occurredAt: row.payload.occurredAt,
|
|
163
|
+
dueAt: row.payload.dueAt,
|
|
164
|
+
sensitivity: row.payload.sensitivity,
|
|
165
|
+
evidence: evidenceOf(row),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return prediction;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The shared half of every runner: one `generateStructured` call and the
|
|
173
|
+
* validator, returning the proposal rows before any pre-check. `null` when the
|
|
174
|
+
* model's answer fails validation (`invalidOutput`). #364's `extract+resolve`
|
|
175
|
+
* runner resolves these rows before the pre-check runs.
|
|
176
|
+
*
|
|
177
|
+
* @stability experimental
|
|
178
|
+
*/
|
|
179
|
+
async function runExtraction(ai, fixture, opts) {
|
|
180
|
+
const ctx = (0, internals_js_1.buildExtractionContext)(fixtureToInput(fixture));
|
|
181
|
+
// The row caps a production run at this ceiling would send (#435).
|
|
182
|
+
const caps = (0, internals_js_1.extractionRowCaps)(exports.EVAL_MAX_OUTPUT_TOKENS, 'none');
|
|
183
|
+
const prompt = (0, internals_js_1.assembleExtractionPrompt)(ctx, caps);
|
|
184
|
+
const schema = (0, internals_js_1.buildExtractionOutputSchema)(ctx, caps);
|
|
185
|
+
// `schema` is the pass-through validator: `validateExtraction` below is the
|
|
186
|
+
// product's own validation, exactly as in the `kg.extract` handler.
|
|
187
|
+
const result = await ai.generateStructured({ userId: exports.EVAL_USER_ID, orgId: null, feature: 'graph.extract', signal: AbortSignal.timeout(exports.EVAL_TIMEOUT_MS) }, {
|
|
188
|
+
target: {
|
|
189
|
+
provider: opts.provider ?? 'openai',
|
|
190
|
+
model: opts.model,
|
|
191
|
+
contextWindowTokens: exports.EVAL_CONTEXT_WINDOW_TOKENS,
|
|
192
|
+
maxOutputTokens: exports.EVAL_MAX_OUTPUT_TOKENS,
|
|
193
|
+
source: 'requested',
|
|
194
|
+
},
|
|
195
|
+
system: prompt.systemPrompt,
|
|
196
|
+
user: prompt.userContent,
|
|
197
|
+
schemaName: internals_js_1.EXTRACTION_SCHEMA_NAME,
|
|
198
|
+
schema: zod_1.z.unknown(),
|
|
199
|
+
jsonSchema: schema,
|
|
200
|
+
maxOutputTokens: exports.EVAL_MAX_OUTPUT_TOKENS,
|
|
201
|
+
});
|
|
202
|
+
const validated = (0, internals_js_1.validateExtraction)(result.value, ctx);
|
|
203
|
+
if (!validated.ok)
|
|
204
|
+
return null;
|
|
205
|
+
const final = (0, internals_js_1.addDeterministicRows)(ctx, validated);
|
|
206
|
+
return { rows: final.rows, stats: { ...final.stats.dropped, quoteNotLocated: final.stats.quoteNotLocated } };
|
|
207
|
+
}
|
|
208
|
+
const ALL_DOMAINS_REVIEW_ONLY = (0, graph_extraction_1.reviewOnlyTypes)((0, ontology_1.computeEffectiveSchema)({ enabledDomains: ['core', 'work', 'personal'], userAttributes: [] }));
|
|
209
|
+
/**
|
|
210
|
+
* Pre-check the rows with default preferences and turn them into a prediction.
|
|
211
|
+
*
|
|
212
|
+
* @stability experimental
|
|
213
|
+
*/
|
|
214
|
+
function precheckToPrediction(fixtureId, model, rows, stats) {
|
|
215
|
+
const precheck = rows.map((row) => ({
|
|
216
|
+
kind: row.kind,
|
|
217
|
+
payload: row.payload,
|
|
218
|
+
resolution: row.resolution,
|
|
219
|
+
flags: row.flags,
|
|
220
|
+
decision: 'pending',
|
|
221
|
+
}));
|
|
222
|
+
// Every domain's review-only types: a type a fixture's domains do not
|
|
223
|
+
// include can never have been proposed, so listing it changes nothing.
|
|
224
|
+
(0, graph_extraction_1.applyPrecheck)(precheck, graph_1.GRAPH_PREFERENCE_DEFAULTS, { reviewOnlyTypes: ALL_DOMAINS_REVIEW_ONLY });
|
|
225
|
+
return rowsToPrediction(fixtureId, model, rows, precheck.map((p) => p.decision), stats);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The `extract` runner over `deps.ai`.
|
|
229
|
+
*
|
|
230
|
+
* @stability experimental
|
|
231
|
+
*/
|
|
232
|
+
function createExtractRunner(deps) {
|
|
233
|
+
return {
|
|
234
|
+
name: 'extract',
|
|
235
|
+
async run(fixture, opts) {
|
|
236
|
+
const extracted = await runExtraction(deps.ai, fixture, opts);
|
|
237
|
+
if (!extracted) {
|
|
238
|
+
return { fixtureId: fixture.id, model: opts.model, entities: [], relations: [], items: [], stats: { invalidOutput: 1 } };
|
|
239
|
+
}
|
|
240
|
+
return precheckToPrediction(fixture.id, opts.model, extracted.rows, extracted.stats);
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { GoldenFixture, ItemLabelKind, ValidPrecisionLabel } from '../fixtures/index.js';
|
|
2
|
+
import type { KgEvalPrediction } from './prediction-schema.js';
|
|
3
|
+
export { normalizeName } from './text.js';
|
|
4
|
+
/**
|
|
5
|
+
* The token-set Jaccard a predicted label needs against a gold name to be a match candidate.
|
|
6
|
+
*
|
|
7
|
+
* @stability experimental
|
|
8
|
+
*/
|
|
9
|
+
export declare const ENTITY_MATCH_JACCARD = 0.8;
|
|
10
|
+
/**
|
|
11
|
+
* The token-set F1 a predicted item statement needs against the gold statement.
|
|
12
|
+
*
|
|
13
|
+
* @stability experimental
|
|
14
|
+
*/
|
|
15
|
+
export declare const ITEM_STATEMENT_F1 = 0.5;
|
|
16
|
+
/**
|
|
17
|
+
* Report rows, fixed order. Relation rows (`relation:<TYPE>`) follow, sorted.
|
|
18
|
+
*
|
|
19
|
+
* @stability experimental
|
|
20
|
+
*/
|
|
21
|
+
export declare const ENTITY_REPORT_TYPES: readonly ["Person", "Organization", "Project", "Meeting", "Interest", "Trip", "Milestone"];
|
|
22
|
+
/**
|
|
23
|
+
* The report row of each item kind.
|
|
24
|
+
*
|
|
25
|
+
* @stability experimental
|
|
26
|
+
*/
|
|
27
|
+
export declare const ITEM_REPORT_TYPES: Record<ItemLabelKind, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Every fixed report row: the entity types, then the item kinds.
|
|
30
|
+
*
|
|
31
|
+
* @stability experimental
|
|
32
|
+
*/
|
|
33
|
+
export declare const BASE_REPORT_TYPES: string[];
|
|
34
|
+
/**
|
|
35
|
+
* True positives, false positives and false negatives of one report row.
|
|
36
|
+
*
|
|
37
|
+
* @stability experimental
|
|
38
|
+
*/
|
|
39
|
+
export interface Counts {
|
|
40
|
+
tp: number;
|
|
41
|
+
fp: number;
|
|
42
|
+
fn: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One fixture's score: counts per type, entity coverage, auto-link precision, evidence
|
|
46
|
+
* validity, temporal accuracy and the prediction's dropped counts.
|
|
47
|
+
*
|
|
48
|
+
* @stability experimental
|
|
49
|
+
*/
|
|
50
|
+
export interface FixtureScore {
|
|
51
|
+
fixtureId: string;
|
|
52
|
+
types: Record<string, Counts>;
|
|
53
|
+
coverage: {
|
|
54
|
+
matched: number;
|
|
55
|
+
total: number;
|
|
56
|
+
};
|
|
57
|
+
/** `anyResolution`: at least one prediction carried a resolution at all. */
|
|
58
|
+
autoLink: {
|
|
59
|
+
correct: number;
|
|
60
|
+
total: number;
|
|
61
|
+
anyResolution: boolean;
|
|
62
|
+
};
|
|
63
|
+
evidence: {
|
|
64
|
+
valid: number;
|
|
65
|
+
total: number;
|
|
66
|
+
};
|
|
67
|
+
temporal: {
|
|
68
|
+
accurate: number;
|
|
69
|
+
total: number;
|
|
70
|
+
};
|
|
71
|
+
stats: Record<string, number>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A run's score: the fixtures' scores summed, plus each fixture's own.
|
|
75
|
+
*
|
|
76
|
+
* @stability experimental
|
|
77
|
+
*/
|
|
78
|
+
export interface RunScore {
|
|
79
|
+
fixtures: number;
|
|
80
|
+
types: Record<string, Counts>;
|
|
81
|
+
coverage: {
|
|
82
|
+
matched: number;
|
|
83
|
+
total: number;
|
|
84
|
+
};
|
|
85
|
+
autoLink: {
|
|
86
|
+
correct: number;
|
|
87
|
+
total: number;
|
|
88
|
+
anyResolution: boolean;
|
|
89
|
+
};
|
|
90
|
+
evidence: {
|
|
91
|
+
valid: number;
|
|
92
|
+
total: number;
|
|
93
|
+
};
|
|
94
|
+
temporal: {
|
|
95
|
+
accurate: number;
|
|
96
|
+
total: number;
|
|
97
|
+
};
|
|
98
|
+
stats: Record<string, number>;
|
|
99
|
+
perFixture: FixtureScore[];
|
|
100
|
+
}
|
|
101
|
+
interface Named {
|
|
102
|
+
type: string;
|
|
103
|
+
names: Set<string>;
|
|
104
|
+
tokenSets: Set<string>[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Similarity of one predicted label to one gold name set; 0 when not a candidate.
|
|
108
|
+
*
|
|
109
|
+
* @stability experimental
|
|
110
|
+
*/
|
|
111
|
+
export declare function nameSimilarity(predLabel: string, gold: Pick<Named, 'names' | 'tokenSets'>): number;
|
|
112
|
+
/**
|
|
113
|
+
* The one-to-one assignment of predicted to gold entities (greedy by descending similarity).
|
|
114
|
+
*
|
|
115
|
+
* @param gold - the gold entities (label and aliases).
|
|
116
|
+
* @param preds - the predicted entities.
|
|
117
|
+
* @param opts - `typed`: candidates must share a type (entity coverage drops the check).
|
|
118
|
+
* @returns predicted index to gold index.
|
|
119
|
+
*
|
|
120
|
+
* @stability experimental
|
|
121
|
+
*/
|
|
122
|
+
export declare function matchEntities(gold: ReadonlyArray<{
|
|
123
|
+
type: string;
|
|
124
|
+
label: string;
|
|
125
|
+
aliases: readonly string[];
|
|
126
|
+
}>, preds: ReadonlyArray<{
|
|
127
|
+
type: string;
|
|
128
|
+
label: string;
|
|
129
|
+
}>, opts: {
|
|
130
|
+
typed: boolean;
|
|
131
|
+
}): Map<number, number>;
|
|
132
|
+
/**
|
|
133
|
+
* Whether two temporal ranges are equal at the gold precision (`unknown` matches only `unknown`).
|
|
134
|
+
*
|
|
135
|
+
* @param gold - the gold bounds and precision.
|
|
136
|
+
* @param pred - the predicted bounds and precision.
|
|
137
|
+
* @returns `true` when equal.
|
|
138
|
+
*
|
|
139
|
+
* @stability experimental
|
|
140
|
+
*/
|
|
141
|
+
export declare function temporalEqual(gold: {
|
|
142
|
+
validFrom: string | null;
|
|
143
|
+
validTo: string | null;
|
|
144
|
+
precision: ValidPrecisionLabel;
|
|
145
|
+
}, pred: {
|
|
146
|
+
validFrom: string | null;
|
|
147
|
+
validTo: string | null;
|
|
148
|
+
precision: ValidPrecisionLabel;
|
|
149
|
+
}): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Scores one fixture's prediction. Pure and deterministic.
|
|
152
|
+
*
|
|
153
|
+
* @param fixture - the fixture and its labels.
|
|
154
|
+
* @param prediction - what a run predicted for it.
|
|
155
|
+
* @returns the fixture's score.
|
|
156
|
+
*
|
|
157
|
+
* @stability experimental
|
|
158
|
+
*/
|
|
159
|
+
export declare function scoreFixture(fixture: GoldenFixture, prediction: KgEvalPrediction): FixtureScore;
|
|
160
|
+
/**
|
|
161
|
+
* Scores every fixture of a run (a fixture with no prediction scores as empty).
|
|
162
|
+
*
|
|
163
|
+
* @param fixtures - the fixtures.
|
|
164
|
+
* @param predictions - the predictions by fixture id.
|
|
165
|
+
* @returns the run's score.
|
|
166
|
+
*
|
|
167
|
+
* @stability experimental
|
|
168
|
+
*/
|
|
169
|
+
export declare function scoreRun(fixtures: readonly GoldenFixture[], predictions: ReadonlyMap<string, KgEvalPrediction>): RunScore;
|
|
170
|
+
/**
|
|
171
|
+
* `num / den`, or `null` (printed `n/a`) when `den` is 0.
|
|
172
|
+
*
|
|
173
|
+
* @stability experimental
|
|
174
|
+
*/
|
|
175
|
+
export declare const ratio: (num: number, den: number) => number | null;
|
|
176
|
+
/**
|
|
177
|
+
* Precision of one row, or `null` with nothing predicted.
|
|
178
|
+
*
|
|
179
|
+
* @param c - the row's counts.
|
|
180
|
+
* @returns the ratio or `null`.
|
|
181
|
+
*
|
|
182
|
+
* @stability experimental
|
|
183
|
+
*/
|
|
184
|
+
export declare function precisionOf(c: Counts): number | null;
|
|
185
|
+
/**
|
|
186
|
+
* Recall of one row, or `null` with nothing labelled.
|
|
187
|
+
*
|
|
188
|
+
* @param c - the row's counts.
|
|
189
|
+
* @returns the ratio or `null`.
|
|
190
|
+
*
|
|
191
|
+
* @stability experimental
|
|
192
|
+
*/
|
|
193
|
+
export declare function recallOf(c: Counts): number | null;
|
|
194
|
+
/**
|
|
195
|
+
* F1 of one row, or `null` when precision or recall is.
|
|
196
|
+
*
|
|
197
|
+
* @param c - the row's counts.
|
|
198
|
+
* @returns the ratio or `null`.
|
|
199
|
+
*
|
|
200
|
+
* @stability experimental
|
|
201
|
+
*/
|
|
202
|
+
export declare function f1Of(c: Counts): number | null;
|
|
203
|
+
/**
|
|
204
|
+
* Gold entities matched by any prediction, type ignored, over all gold entities (the §6 entity-coverage target).
|
|
205
|
+
*
|
|
206
|
+
* @param run - the run's coverage counts.
|
|
207
|
+
* @returns the ratio or `null`.
|
|
208
|
+
*
|
|
209
|
+
* @stability experimental
|
|
210
|
+
*/
|
|
211
|
+
export declare function entityCoverage(run: Pick<RunScore, 'coverage'>): number | null;
|
|
212
|
+
/**
|
|
213
|
+
* Recall of the Commitment row (the §6 commitment-recall target).
|
|
214
|
+
*
|
|
215
|
+
* @param run - the run's per-type counts.
|
|
216
|
+
* @returns the ratio or `null`.
|
|
217
|
+
*
|
|
218
|
+
* @stability experimental
|
|
219
|
+
*/
|
|
220
|
+
export declare function commitmentRecall(run: Pick<RunScore, 'types'>): number | null;
|
|
221
|
+
/**
|
|
222
|
+
* `null` (printed `n/a`) when no prediction carries a resolution, or none was a prechecked link.
|
|
223
|
+
*
|
|
224
|
+
* @stability experimental
|
|
225
|
+
*/
|
|
226
|
+
export declare function autoLinkPrecision(run: Pick<RunScore, 'autoLink'>): number | null;
|