@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,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// `kvox-eval kg` — score knowledge-graph extraction against the golden set
|
|
4
|
+
// (issue #362; the package command since #580)
|
|
5
|
+
// =============================================================================
|
|
6
|
+
//
|
|
7
|
+
// kvox-eval kg --predictions gold
|
|
8
|
+
// kvox-eval kg --predictions <dir> [--only m01,m07] [--tag promotion]
|
|
9
|
+
// kvox-eval kg --runner extract --provider openai --model <id> [--out <dir>]
|
|
10
|
+
// kvox-eval kg --runner extract --provider openai-compatible --base-url <url> --model <id>
|
|
11
|
+
// kvox-eval kg --real-dir <dir outside the repo> --predictions <dir>
|
|
12
|
+
//
|
|
13
|
+
// Flags: --json <file> also writes the report as JSON; --enforce exits 1 when a
|
|
14
|
+
// §6 target (docs/specs/ontology.md) fails — for local use, CI reports only.
|
|
15
|
+
// `--run` is accepted for `--runner` (the web app's `npm run kg:eval` spelling).
|
|
16
|
+
//
|
|
17
|
+
// Exit codes: 0 ok · 1 --enforce and a target failed · 2 usage/runner/load
|
|
18
|
+
// error (a refused provider and a failed live call included) · 3 a real-data
|
|
19
|
+
// path inside the repository (refused).
|
|
20
|
+
//
|
|
21
|
+
// The API key for a live runner comes from KVOX_EVAL_OPENAI_API_KEY only
|
|
22
|
+
// (KG_EVAL_OPENAI_API_KEY and ASK_EVAL_OPENAI_API_KEY for one more release),
|
|
23
|
+
// never a flag, and is never printed or written anywhere. A failed live call
|
|
24
|
+
// is reported by its error class, code and HTTP status only.
|
|
25
|
+
//
|
|
26
|
+
// `runKgCommand` takes its output streams and environment as arguments, so a
|
|
27
|
+
// test (and the web app's thin `scripts/kg-eval.ts` wrapper) drives it in
|
|
28
|
+
// process.
|
|
29
|
+
// =============================================================================
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.KG_COMMAND_USAGE = exports.KG_EVAL_EXIT = void 0;
|
|
32
|
+
exports.runKgCommand = runKgCommand;
|
|
33
|
+
const fs_1 = require("fs");
|
|
34
|
+
const os_1 = require("os");
|
|
35
|
+
const path_1 = require("path");
|
|
36
|
+
const util_1 = require("util");
|
|
37
|
+
const ports_1 = require("@marinoscar/kvox-api/ports");
|
|
38
|
+
const index_js_1 = require("../fixtures/index.js");
|
|
39
|
+
const index_js_2 = require("../kg/index.js");
|
|
40
|
+
const index_js_3 = require("../kg/index.js");
|
|
41
|
+
const index_js_4 = require("../kg/index.js");
|
|
42
|
+
const index_js_5 = require("../live/index.js");
|
|
43
|
+
const index_js_6 = require("../live/index.js");
|
|
44
|
+
const index_js_7 = require("../real-data/index.js");
|
|
45
|
+
/**
|
|
46
|
+
* The exit codes of `kvox-eval kg` (and of the web app's `npm run kg:eval`).
|
|
47
|
+
*
|
|
48
|
+
* @stability experimental
|
|
49
|
+
*/
|
|
50
|
+
exports.KG_EVAL_EXIT = Object.freeze({ ok: 0, targetsFailed: 1, usage: 2, pathRefused: 3 });
|
|
51
|
+
/**
|
|
52
|
+
* The usage text of `kvox-eval kg`.
|
|
53
|
+
*
|
|
54
|
+
* @stability experimental
|
|
55
|
+
*/
|
|
56
|
+
exports.KG_COMMAND_USAGE = `usage: kvox-eval kg (--predictions <dir|gold> | --runner extract|extract-resolve --model <id>)
|
|
57
|
+
[--provider openai|openai-compatible|copilot] [--base-url <url>] [--out <dir>]
|
|
58
|
+
[--only m01,m07] [--tag <tag>] [--json <file>] [--enforce] [--real-dir <dir>]
|
|
59
|
+
reads a live runner's API key from ${index_js_5.KVOX_EVAL_API_KEY_ENV} (never a flag)`;
|
|
60
|
+
/** A command line that cannot run; printed with the usage text. */
|
|
61
|
+
class UsageError extends Error {
|
|
62
|
+
}
|
|
63
|
+
/** A live call that failed; printed by class, code and status only. */
|
|
64
|
+
class LiveCallError extends Error {
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Runs `kvox-eval kg` with the given arguments (everything after `kg`).
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* const code = await runKgCommand(['--predictions', 'gold'], { out: console.log, err: console.error, env: process.env });
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @param argv - the arguments.
|
|
75
|
+
* @param io - output streams and environment.
|
|
76
|
+
* @param options - the host's name, usage text, scratch directory and adapters.
|
|
77
|
+
* @returns the exit code ({@link KG_EVAL_EXIT}).
|
|
78
|
+
* @stability experimental
|
|
79
|
+
*/
|
|
80
|
+
async function runKgCommand(argv, io, options = {}) {
|
|
81
|
+
const name = options.name ?? 'kvox-eval kg';
|
|
82
|
+
const usage = options.usage ?? exports.KG_COMMAND_USAGE;
|
|
83
|
+
try {
|
|
84
|
+
return await run(argv, io, options, name, usage);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (err instanceof index_js_7.RealDataPathError) {
|
|
88
|
+
io.err(`${name}: ${err.message}`);
|
|
89
|
+
return exports.KG_EVAL_EXIT.pathRefused;
|
|
90
|
+
}
|
|
91
|
+
if (err instanceof UsageError || err instanceof index_js_3.KgEvalUsageError) {
|
|
92
|
+
io.err(`${name}: ${err.message}`);
|
|
93
|
+
io.err(usage);
|
|
94
|
+
return exports.KG_EVAL_EXIT.usage;
|
|
95
|
+
}
|
|
96
|
+
if (err instanceof index_js_1.KgEvalLoadError || err instanceof index_js_6.LiveProviderError || err instanceof LiveCallError) {
|
|
97
|
+
io.err(`${name}: ${err.message}`);
|
|
98
|
+
return exports.KG_EVAL_EXIT.usage;
|
|
99
|
+
}
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function run(argv, io, options, name, usage) {
|
|
104
|
+
let values;
|
|
105
|
+
try {
|
|
106
|
+
({ values } = (0, util_1.parseArgs)({
|
|
107
|
+
args: argv,
|
|
108
|
+
strict: true,
|
|
109
|
+
allowPositionals: false,
|
|
110
|
+
options: {
|
|
111
|
+
predictions: { type: 'string' },
|
|
112
|
+
runner: { type: 'string' },
|
|
113
|
+
run: { type: 'string' },
|
|
114
|
+
provider: { type: 'string' },
|
|
115
|
+
model: { type: 'string' },
|
|
116
|
+
'base-url': { type: 'string' },
|
|
117
|
+
out: { type: 'string' },
|
|
118
|
+
only: { type: 'string' },
|
|
119
|
+
tag: { type: 'string' },
|
|
120
|
+
json: { type: 'string' },
|
|
121
|
+
enforce: { type: 'boolean' },
|
|
122
|
+
'real-dir': { type: 'string' },
|
|
123
|
+
help: { type: 'boolean' },
|
|
124
|
+
},
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
throw new UsageError(err.message);
|
|
129
|
+
}
|
|
130
|
+
const str = (k) => (typeof values[k] === 'string' ? values[k] : undefined);
|
|
131
|
+
if (values.help) {
|
|
132
|
+
io.out(usage);
|
|
133
|
+
return exports.KG_EVAL_EXIT.ok;
|
|
134
|
+
}
|
|
135
|
+
// Real-data mode: the path guard runs before anything is read or written.
|
|
136
|
+
const realDirArg = str('real-dir') ?? (io.env.KG_EVAL_REAL_DIR || undefined);
|
|
137
|
+
const realDir = realDirArg ? (0, index_js_7.assertOutsideRepo)(realDirArg) : null;
|
|
138
|
+
if (str('runner') !== undefined && str('run') !== undefined)
|
|
139
|
+
throw new UsageError('pass --runner or --run, not both');
|
|
140
|
+
const runnerFlag = str('runner') !== undefined ? '--runner' : '--run';
|
|
141
|
+
const runnerName = str('runner') ?? str('run');
|
|
142
|
+
const predictionsArg = str('predictions');
|
|
143
|
+
if ((predictionsArg === undefined) === (runnerName === undefined)) {
|
|
144
|
+
throw new UsageError(`pass exactly one of --predictions <dir|gold> or ${runnerFlag} <runner>`);
|
|
145
|
+
}
|
|
146
|
+
// An unregistered runner is reported before anything is loaded or written.
|
|
147
|
+
const live = runnerName !== undefined ? (0, index_js_4.findKgEvalRunner)(runnerName) : null;
|
|
148
|
+
if (runnerName !== undefined && live === null) {
|
|
149
|
+
io.err(`${name}: no runner '${runnerName}' registered (known: ${Object.keys(index_js_4.KG_EVAL_RUNNERS).join(', ')})`);
|
|
150
|
+
return exports.KG_EVAL_EXIT.usage;
|
|
151
|
+
}
|
|
152
|
+
// The output guard runs before anything is loaded: a run over real data may
|
|
153
|
+
// never write inside the repository, not even into the git-ignored scratch dir.
|
|
154
|
+
let outDir = null;
|
|
155
|
+
if (live !== null) {
|
|
156
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
157
|
+
const synthetic = options.syntheticRunsDir ?? null;
|
|
158
|
+
const outArg = str('out') ??
|
|
159
|
+
(realDir ? (0, path_1.join)(realDir, 'runs', stamp) : synthetic ? (0, path_1.join)(synthetic, 'runs', stamp) : (0, path_1.join)((0, os_1.tmpdir)(), 'kvox-eval', 'runs', stamp));
|
|
160
|
+
outDir = (0, index_js_7.assertOutsideRepo)(outArg, { allowInside: realDir === null ? synthetic : null });
|
|
161
|
+
}
|
|
162
|
+
const only = str('only')
|
|
163
|
+
?.split(',')
|
|
164
|
+
.map((s) => s.trim())
|
|
165
|
+
.filter(Boolean);
|
|
166
|
+
const selection = {
|
|
167
|
+
...(only ? { fixtures: only } : {}),
|
|
168
|
+
...(str('tag') !== undefined ? { tag: str('tag') } : {}),
|
|
169
|
+
...(realDir ? { fixturesDir: realDir } : {}),
|
|
170
|
+
};
|
|
171
|
+
let report;
|
|
172
|
+
if (live !== null) {
|
|
173
|
+
// The provider is refused (copilot, an unknown id) before the key is looked for.
|
|
174
|
+
const provider = str('provider') ?? 'openai';
|
|
175
|
+
(0, index_js_6.assertLiveProvider)(provider);
|
|
176
|
+
const model = str('model');
|
|
177
|
+
if (!model)
|
|
178
|
+
throw new UsageError(`${runnerFlag} requires --model <id>`);
|
|
179
|
+
const key = (0, index_js_5.readEvalApiKey)(io.env, io.err);
|
|
180
|
+
if (key === null && provider === 'openai') {
|
|
181
|
+
throw new UsageError(`${runnerFlag} reads its API key from ${index_js_5.KVOX_EVAL_API_KEY_ENV}; it is not set`);
|
|
182
|
+
}
|
|
183
|
+
const baseUrl = str('base-url');
|
|
184
|
+
const { ai, failures } = (0, index_js_6.createLiveKvoxAi)({
|
|
185
|
+
provider,
|
|
186
|
+
model,
|
|
187
|
+
apiKey: key?.apiKey ?? null,
|
|
188
|
+
...(baseUrl !== undefined ? { baseUrl } : {}),
|
|
189
|
+
...(options.adapters !== undefined ? { adapters: options.adapters } : {}),
|
|
190
|
+
});
|
|
191
|
+
const dir = outDir;
|
|
192
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
193
|
+
try {
|
|
194
|
+
report = await (0, index_js_3.runKgEval)({
|
|
195
|
+
runner: live.name,
|
|
196
|
+
ai,
|
|
197
|
+
model,
|
|
198
|
+
provider,
|
|
199
|
+
...selection,
|
|
200
|
+
onPrediction: (fixtureId, pred) => (0, fs_1.writeFileSync)((0, path_1.join)(dir, `${fixtureId}.json`), `${JSON.stringify(pred, null, 2)}\n`),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
if (err instanceof ports_1.KvoxAiError)
|
|
205
|
+
throw new LiveCallError(describeLiveFailure(err, failures));
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
io.err(`${name}: predictions written to ${dir}`);
|
|
209
|
+
}
|
|
210
|
+
else if (predictionsArg === 'gold') {
|
|
211
|
+
report = await (0, index_js_3.runKgEval)({ runner: 'gold', ...selection });
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
report = await (0, index_js_3.runKgEval)({
|
|
215
|
+
predictionsDir: (0, path_1.resolve)(predictionsArg),
|
|
216
|
+
...selection,
|
|
217
|
+
onMissingPrediction: (fixtureId, dir) => io.err(`${name}: no prediction for ${fixtureId} in ${dir} (scored as empty)`),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
io.out((0, index_js_2.formatReport)(report));
|
|
221
|
+
const jsonPath = str('json');
|
|
222
|
+
if (jsonPath) {
|
|
223
|
+
const abs = (0, path_1.resolve)(jsonPath);
|
|
224
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(abs), { recursive: true });
|
|
225
|
+
(0, fs_1.writeFileSync)(abs, `${JSON.stringify(report, null, 2)}\n`);
|
|
226
|
+
}
|
|
227
|
+
if (values.enforce && !report.targetsMet) {
|
|
228
|
+
io.err(`${name}: one or more §6 targets failed (--enforce)`);
|
|
229
|
+
return exports.KG_EVAL_EXIT.targetsFailed;
|
|
230
|
+
}
|
|
231
|
+
return exports.KG_EVAL_EXIT.ok;
|
|
232
|
+
}
|
|
233
|
+
/** `the live call failed (auth; AI_KEY_INVALID, HTTP 400)`: class, code, status. Never a message body. */
|
|
234
|
+
function describeLiveFailure(err, failures) {
|
|
235
|
+
const last = failures[failures.length - 1];
|
|
236
|
+
const detail = last ? `; ${last.code}${last.status !== null ? `, HTTP ${last.status}` : ''}` : '';
|
|
237
|
+
return `the live call failed (${err.errorClass}${detail})`;
|
|
238
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type EvalCommandIo, type KgCommandOptions } from './kg-command.js';
|
|
3
|
+
/**
|
|
4
|
+
* The usage text of `kvox-eval`.
|
|
5
|
+
*
|
|
6
|
+
* @stability experimental
|
|
7
|
+
*/
|
|
8
|
+
export declare const KVOX_EVAL_USAGE = "usage: kvox-eval kg [flags] score knowledge-graph extraction against the golden set\n kvox-eval ask [flags] run the Ask evaluation headless (in-memory database, live model)\n kvox-eval ask --replay the Ask harness's scripted self-test (no model, no key)\n kvox-eval kg --help the kg flags\n kvox-eval ask --help the ask flags";
|
|
9
|
+
/**
|
|
10
|
+
* Runs `kvox-eval` with the given arguments (everything after the command name).
|
|
11
|
+
*
|
|
12
|
+
* @param argv - the arguments, the subcommand first.
|
|
13
|
+
* @param io - output streams and environment.
|
|
14
|
+
* @param options - passed to the kg command (the ask command takes its defaults).
|
|
15
|
+
* @returns the exit code.
|
|
16
|
+
* @stability experimental
|
|
17
|
+
*/
|
|
18
|
+
export declare function main(argv: string[], io?: EvalCommandIo, options?: KgCommandOptions): Promise<number>;
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// The `kvox-eval` command (issue #580)
|
|
5
|
+
// =============================================================================
|
|
6
|
+
//
|
|
7
|
+
// kvox-eval kg ... score knowledge-graph extraction (see kg-command.ts)
|
|
8
|
+
// kvox-eval ask ... the Ask evaluation, headless (see ask-command.ts): an
|
|
9
|
+
// in-memory PostgreSQL, the golden graph, the real
|
|
10
|
+
// `ask.respond` handler; `--replay` needs no model or key
|
|
11
|
+
// =============================================================================
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.KVOX_EVAL_USAGE = void 0;
|
|
14
|
+
exports.main = main;
|
|
15
|
+
const kg_command_js_1 = require("./kg-command.js");
|
|
16
|
+
/**
|
|
17
|
+
* The usage text of `kvox-eval`.
|
|
18
|
+
*
|
|
19
|
+
* @stability experimental
|
|
20
|
+
*/
|
|
21
|
+
exports.KVOX_EVAL_USAGE = `usage: kvox-eval kg [flags] score knowledge-graph extraction against the golden set
|
|
22
|
+
kvox-eval ask [flags] run the Ask evaluation headless (in-memory database, live model)
|
|
23
|
+
kvox-eval ask --replay the Ask harness's scripted self-test (no model, no key)
|
|
24
|
+
kvox-eval kg --help the kg flags
|
|
25
|
+
kvox-eval ask --help the ask flags`;
|
|
26
|
+
/**
|
|
27
|
+
* Runs `kvox-eval` with the given arguments (everything after the command name).
|
|
28
|
+
*
|
|
29
|
+
* @param argv - the arguments, the subcommand first.
|
|
30
|
+
* @param io - output streams and environment.
|
|
31
|
+
* @param options - passed to the kg command (the ask command takes its defaults).
|
|
32
|
+
* @returns the exit code.
|
|
33
|
+
* @stability experimental
|
|
34
|
+
*/
|
|
35
|
+
async function main(argv, io = defaultIo(), options = {}) {
|
|
36
|
+
const [command, ...rest] = argv;
|
|
37
|
+
if (command === 'kg')
|
|
38
|
+
return (0, kg_command_js_1.runKgCommand)(rest, io, options);
|
|
39
|
+
if (command === 'ask') {
|
|
40
|
+
// Loaded only here: the ask command brings Nest, the domain slices, PGlite and
|
|
41
|
+
// the generated Prisma client, which `kvox-eval kg` and `--help` never need.
|
|
42
|
+
const { runAskCommand } = require('../ask-run/index.js');
|
|
43
|
+
return runAskCommand(rest, io);
|
|
44
|
+
}
|
|
45
|
+
if (command === '--help' || command === '-h' || command === 'help') {
|
|
46
|
+
io.out(exports.KVOX_EVAL_USAGE);
|
|
47
|
+
return kg_command_js_1.KG_EVAL_EXIT.ok;
|
|
48
|
+
}
|
|
49
|
+
io.err(command === undefined ? 'kvox-eval: no command given' : `kvox-eval: unknown command '${command}'`);
|
|
50
|
+
io.err(exports.KVOX_EVAL_USAGE);
|
|
51
|
+
return kg_command_js_1.KG_EVAL_EXIT.usage;
|
|
52
|
+
}
|
|
53
|
+
function defaultIo() {
|
|
54
|
+
return {
|
|
55
|
+
out: (s) => process.stdout.write(`${s}\n`),
|
|
56
|
+
err: (s) => process.stderr.write(`${s}\n`),
|
|
57
|
+
env: process.env,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (require.main === module) {
|
|
61
|
+
main(process.argv.slice(2)).then((code) => {
|
|
62
|
+
process.exitCode = code;
|
|
63
|
+
}, (err) => {
|
|
64
|
+
// A KvoxAiError never reaches here (the kg command reports it by class);
|
|
65
|
+
// anything else is a bug, and its stack is the useful part.
|
|
66
|
+
process.stderr.write(`kvox-eval: ${err.stack ?? String(err)}\n`);
|
|
67
|
+
process.exitCode = kg_command_js_1.KG_EVAL_EXIT.usage;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DomainKey } from '@marinoscar/kvox-contract/ontology';
|
|
2
|
+
import type { GoldenFixture } from './fixture-schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* The tag that marks a fixture as written for a user with `personal` enabled.
|
|
5
|
+
*
|
|
6
|
+
* @stability experimental
|
|
7
|
+
*/
|
|
8
|
+
export declare const PERSONAL_FIXTURE_TAG = "personal";
|
|
9
|
+
/**
|
|
10
|
+
* The ontology domains a fixture is extracted and validated against.
|
|
11
|
+
*
|
|
12
|
+
* @param fixture - the fixture (its tags).
|
|
13
|
+
* @returns `core ∪ work`, plus `personal` for a fixture tagged {@link PERSONAL_FIXTURE_TAG}.
|
|
14
|
+
* @stability experimental
|
|
15
|
+
*/
|
|
16
|
+
export declare function fixtureDomains(fixture: Pick<GoldenFixture, 'tags'>): DomainKey[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Which ontology domains a golden fixture is extracted and validated against
|
|
4
|
+
// (issue #383). PURE.
|
|
5
|
+
// =============================================================================
|
|
6
|
+
//
|
|
7
|
+
// Every fixture is `core ∪ work` — the default a user who never touched the
|
|
8
|
+
// setting has. A fixture tagged `personal` is the story of a user who turned
|
|
9
|
+
// the `personal` domain on (docs/specs/ontology.md §17.2, §16 P6), so it is
|
|
10
|
+
// read against `core ∪ work ∪ personal`: its labels may use Interest, Trip,
|
|
11
|
+
// Milestone and the personal relations, and an extraction run over it is
|
|
12
|
+
// offered them. Keeping the default fixtures on `core ∪ work` is what proves a
|
|
13
|
+
// user who never enables `personal` sees no personal type anywhere.
|
|
14
|
+
// =============================================================================
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.PERSONAL_FIXTURE_TAG = void 0;
|
|
17
|
+
exports.fixtureDomains = fixtureDomains;
|
|
18
|
+
/**
|
|
19
|
+
* The tag that marks a fixture as written for a user with `personal` enabled.
|
|
20
|
+
*
|
|
21
|
+
* @stability experimental
|
|
22
|
+
*/
|
|
23
|
+
exports.PERSONAL_FIXTURE_TAG = 'personal';
|
|
24
|
+
/**
|
|
25
|
+
* The ontology domains a fixture is extracted and validated against.
|
|
26
|
+
*
|
|
27
|
+
* @param fixture - the fixture (its tags).
|
|
28
|
+
* @returns `core ∪ work`, plus `personal` for a fixture tagged {@link PERSONAL_FIXTURE_TAG}.
|
|
29
|
+
* @stability experimental
|
|
30
|
+
*/
|
|
31
|
+
function fixtureDomains(fixture) {
|
|
32
|
+
return fixture.tags.includes(exports.PERSONAL_FIXTURE_TAG) ? ['core', 'work', 'personal'] : ['core', 'work'];
|
|
33
|
+
}
|