nilometer 0.0.0-stage → 0.1.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 +63 -0
- package/LICENSE +21 -0
- package/README.md +462 -2
- package/core/pricing/prices.json +348 -0
- package/core/schema/001_ingestion.sql +57 -0
- package/core/schema/002_line_count.sql +7 -0
- package/core/schema/003_derived.sql +70 -0
- package/core/schema/004_requests_dedup.sql +50 -0
- package/core/schema/005_repositories.sql +25 -0
- package/core/schema/006_status_readings.sql +33 -0
- package/core/schema/007_pricing.sql +95 -0
- package/core/schema/008_interruptions.sql +263 -0
- package/core/schema/009_headroom.sql +84 -0
- package/core/schema/010_attribution.sql +106 -0
- package/core/schema/011_projections.sql +83 -0
- package/core/schema/012_unsplit_cache_writes.sql +49 -0
- package/core/schema/013_repository_revalidation.sql +104 -0
- package/core/schema/014_observed_readings.sql +204 -0
- package/core/schema/015_response_observations.sql +127 -0
- package/core/schema/016_windows_repository_paths.sql +41 -0
- package/core/schema/017_unattributed_usage_once.sql +47 -0
- package/core/schema/018_request_time_index.sql +21 -0
- package/core/schema/019_dedup_earliest_of_equals.sql +61 -0
- package/core/schema/020_limit_quota_fields.sql +131 -0
- package/core/schema/021_plan_periods.sql +121 -0
- package/core/schema/022_attachment_walk.sql +223 -0
- package/core/schema/023_auto_continuations.sql +129 -0
- package/core/schema/024_counted_limit_groups.sql +29 -0
- package/core/schema/025_model_fallback.sql +77 -0
- package/core/schema/026_changed_readings.sql +106 -0
- package/core/schema/027_weekly_crossings.sql +32 -0
- package/core/schema/028_stale_readings.sql +196 -0
- package/core/schema/029_lockout_sessions.sql +68 -0
- package/core/schema/030_repository_aliases.sql +81 -0
- package/core/schema/031_cte_cursor_budget.sql +153 -0
- package/dist/cli/main.cli.js +39 -0
- package/dist/cli/program.js +801 -0
- package/dist/core/db/database.js +182 -0
- package/dist/core/db/fingerprint.js +71 -0
- package/dist/core/ingest/attribution.js +131 -0
- package/dist/core/ingest/classify.js +382 -0
- package/dist/core/ingest/command.js +95 -0
- package/dist/core/ingest/derive.js +212 -0
- package/dist/core/ingest/discover.js +126 -0
- package/dist/core/ingest/ingest.js +160 -0
- package/dist/core/ingest/reader.js +89 -0
- package/dist/core/ingest/reset-time.js +97 -0
- package/dist/core/ingest/results.js +201 -0
- package/dist/core/ingest/spool.js +165 -0
- package/dist/core/ingest/store.js +99 -0
- package/dist/core/install/install.js +185 -0
- package/dist/core/install/locations.js +89 -0
- package/dist/core/install/private-files.js +259 -0
- package/dist/core/install/record.js +103 -0
- package/dist/core/plans/plan-prices.js +128 -0
- package/dist/core/plans/repository-aliases.js +136 -0
- package/dist/core/pricing/prices.js +147 -0
- package/dist/core/settings/settings-file.js +215 -0
- package/dist/core/settings/statusline.js +240 -0
- package/dist/core/util/commands.js +91 -0
- package/dist/core/util/node-version.js +58 -0
- package/dist/core/util/open-page.js +69 -0
- package/dist/core/util/paths.js +36 -0
- package/dist/core/verify/compare.js +77 -0
- package/dist/core/verify/verify.js +220 -0
- package/dist/viewer/explain.js +574 -0
- package/dist/viewer/format.js +150 -0
- package/dist/viewer/html-charts.js +1292 -0
- package/dist/viewer/html-contract.js +2 -0
- package/dist/viewer/html-data.js +718 -0
- package/dist/viewer/html.js +1654 -0
- package/dist/viewer/queries.js +128 -0
- package/dist/viewer/render.js +602 -0
- package/dist/viewer/report.js +120 -0
- package/dist/viewer/save.js +110 -0
- package/docs/requirements.md +113 -0
- package/hooks/statusline.sh +104 -0
- package/package.json +61 -4
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Loading the report's rows from the metric views (docs/development.md P7.1).
|
|
3
|
+
*
|
|
4
|
+
* Observations and projections are read by separate functions from separate view lists, and come
|
|
5
|
+
* back as separate objects, so no rendering code can place a projection among observations
|
|
6
|
+
* (README principle 2). `tests/unit/viewer/queries.test.ts` checks that {@link OBSERVED_VIEWS}
|
|
7
|
+
* holds only `obs_` views and {@link PROJECTED_VIEWS} only `proj_` views. The SQL here only selects
|
|
8
|
+
* whole views: every computation stays in the views themselves.
|
|
9
|
+
*/
|
|
10
|
+
import { listAliases } from "../core/plans/repository-aliases.js";
|
|
11
|
+
/** The views {@link loadObserved} reads. Only `obs_` views belong here. */
|
|
12
|
+
export const OBSERVED_VIEWS = [
|
|
13
|
+
"obs_limit_hits",
|
|
14
|
+
"obs_mid_task_interruptions",
|
|
15
|
+
"obs_lockout_time",
|
|
16
|
+
"obs_lockout_intervals",
|
|
17
|
+
"obs_interruptions_by_plan",
|
|
18
|
+
"obs_sessions_not_resumed",
|
|
19
|
+
"obs_window_headroom",
|
|
20
|
+
"obs_window_peak",
|
|
21
|
+
"obs_weekly_crossings",
|
|
22
|
+
"obs_usage_by_model",
|
|
23
|
+
"obs_usage_by_repo",
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Metric views the report no longer shows, kept so `nilometer explain` can still list their
|
|
27
|
+
* events. Unattributed usage was zero in every one of Phase 8's 49 windows, since each fresh
|
|
28
|
+
* reading follows a request in its own session (D-044); D-079 took it off the screen, and the
|
|
29
|
+
* view stays to show that it is always zero.
|
|
30
|
+
*/
|
|
31
|
+
export const EXPLAIN_ONLY_VIEWS = ["obs_unattributed_usage"];
|
|
32
|
+
/** The views {@link loadProjected} reads. Only `proj_` views belong here. */
|
|
33
|
+
export const PROJECTED_VIEWS = ["proj_burn_rate", "proj_api_list_price"];
|
|
34
|
+
/**
|
|
35
|
+
* Reads every row of one observed view.
|
|
36
|
+
* @param db - Open, migrated database.
|
|
37
|
+
* @param view - A name from {@link OBSERVED_VIEWS}.
|
|
38
|
+
* @param order - ORDER BY clause.
|
|
39
|
+
* @returns The rows.
|
|
40
|
+
*/
|
|
41
|
+
function observed(db, view, order = "1") {
|
|
42
|
+
return db.prepare(`SELECT * FROM ${view} ORDER BY ${order}`).all();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reads every row of one projected view.
|
|
46
|
+
* @param db - Open, migrated database.
|
|
47
|
+
* @param view - A name from {@link PROJECTED_VIEWS}.
|
|
48
|
+
* @param order - ORDER BY clause.
|
|
49
|
+
* @returns The rows.
|
|
50
|
+
*/
|
|
51
|
+
function projected(db, view, order) {
|
|
52
|
+
return db.prepare(`SELECT * FROM ${view} ORDER BY ${order}`).all();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Loads every observed metric.
|
|
56
|
+
* @param db - Open, migrated database.
|
|
57
|
+
* @param reportedAt - The report's time: a window is open only until its reset, as of it (D-083).
|
|
58
|
+
* Omitted, open is as of the last status line reading, as the views define it.
|
|
59
|
+
* @returns The observed report.
|
|
60
|
+
*/
|
|
61
|
+
export function loadObserved(db, reportedAt) {
|
|
62
|
+
// The report's own time, in Unix seconds, for "open" (D-083); null keeps the view's rule.
|
|
63
|
+
const at = reportedAt === undefined ? null : reportedAt.getTime() / 1000;
|
|
64
|
+
return {
|
|
65
|
+
limitHits: observed(db, "obs_limit_hits")[0],
|
|
66
|
+
midTask: observed(db, "obs_mid_task_interruptions")[0],
|
|
67
|
+
lockout: observed(db, "obs_lockout_time")[0],
|
|
68
|
+
lockoutIntervals: observed(db, "obs_lockout_intervals", "interval_number"),
|
|
69
|
+
// Before the first plan, then plans in order, then hits with no time (D-075).
|
|
70
|
+
interruptionsByPlan: observed(db, "obs_interruptions_by_plan", "CASE period_kind WHEN 'none' THEN 0 WHEN 'plan' THEN 1 ELSE 2 END, from_month"),
|
|
71
|
+
notResumed: observed(db, "obs_sessions_not_resumed")[0],
|
|
72
|
+
// Headroom and peak describe the same window instances, so they're joined in SQL to sit side by side.
|
|
73
|
+
windows: db
|
|
74
|
+
.prepare(`SELECT h.*, p.peak_used_percentage,
|
|
75
|
+
-- Open only until its reset, as of the report's time (D-083).
|
|
76
|
+
(h.window_open = 1 AND (:at IS NULL OR unixepoch(h.reset_at_utc, 'subsec') > :at))
|
|
77
|
+
AS open_at_report
|
|
78
|
+
FROM obs_window_headroom h
|
|
79
|
+
JOIN obs_window_peak p ON p.window = h.window AND p.reset_at_utc = h.reset_at_utc
|
|
80
|
+
ORDER BY open_at_report DESC, h.reset_at_utc DESC, h.window`)
|
|
81
|
+
.all({ at }),
|
|
82
|
+
// Newest window first, as the windows table lists them; within one, the lower level first.
|
|
83
|
+
weeklyCrossings: observed(db, "obs_weekly_crossings", "reset_at_utc DESC, threshold"),
|
|
84
|
+
byModel: observed(db, "obs_usage_by_model", "output_tokens DESC, model"),
|
|
85
|
+
byRepo: observed(db, "obs_usage_by_repo", "output_tokens DESC, repository"),
|
|
86
|
+
repositoryAliases: listAliases(db),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Loads every projection.
|
|
91
|
+
* @param db - Open, migrated database.
|
|
92
|
+
* @param reportedAt - The report's time, as for {@link loadObserved}: burn rate projects windows open at it.
|
|
93
|
+
* @returns The projected report.
|
|
94
|
+
*/
|
|
95
|
+
export function loadProjected(db, reportedAt) {
|
|
96
|
+
// The report's own time, as loadObserved takes it (D-083).
|
|
97
|
+
const at = reportedAt === undefined ? null : reportedAt.getTime() / 1000;
|
|
98
|
+
return {
|
|
99
|
+
// A projection for a window that has already reset would project into the past (D-083).
|
|
100
|
+
burnRate: db
|
|
101
|
+
.prepare(`SELECT *,
|
|
102
|
+
(window_open = 1 AND (:at IS NULL OR unixepoch(reset_at_utc, 'subsec') > :at))
|
|
103
|
+
AS open_at_report
|
|
104
|
+
FROM proj_burn_rate
|
|
105
|
+
ORDER BY open_at_report DESC, reset_at_utc DESC, window`)
|
|
106
|
+
.all({ at }),
|
|
107
|
+
apiListPrice: projected(db, "proj_api_list_price", "month"),
|
|
108
|
+
// Grouped by reading date so each count stays beside its own date. The month view's
|
|
109
|
+
// verified_on is the latest date in the month, which isn't the date its count refers to once
|
|
110
|
+
// price rows were read on different days.
|
|
111
|
+
rateReadings: db
|
|
112
|
+
.prepare(`SELECT verified_on, COUNT(*) AS priced_before_verified_requests
|
|
113
|
+
FROM request_costs
|
|
114
|
+
WHERE timestamp_utc IS NOT NULL AND unpriced_reason IS NULL AND day_utc < verified_on
|
|
115
|
+
GROUP BY verified_on
|
|
116
|
+
ORDER BY verified_on`)
|
|
117
|
+
.all(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Reads when the last ingest finished.
|
|
122
|
+
* @param db - Open, migrated database.
|
|
123
|
+
* @returns ISO-8601 UTC, or null before any completed ingest.
|
|
124
|
+
*/
|
|
125
|
+
export function lastIngestAt(db) {
|
|
126
|
+
return db.prepare("SELECT MAX(finished_at) AS at FROM ingest_runs").get().at;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=queries.js.map
|