taurusdb-core 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.
Files changed (170) hide show
  1. package/README.md +21 -0
  2. package/dist/auth/secret-resolver.d.ts +16 -0
  3. package/dist/auth/secret-resolver.js +64 -0
  4. package/dist/auth/sql-profile-loader/env-source.d.ts +3 -0
  5. package/dist/auth/sql-profile-loader/env-source.js +94 -0
  6. package/dist/auth/sql-profile-loader/file-source.d.ts +6 -0
  7. package/dist/auth/sql-profile-loader/file-source.js +40 -0
  8. package/dist/auth/sql-profile-loader/loader.d.ts +16 -0
  9. package/dist/auth/sql-profile-loader/loader.js +81 -0
  10. package/dist/auth/sql-profile-loader/parsing.d.ts +14 -0
  11. package/dist/auth/sql-profile-loader/parsing.js +216 -0
  12. package/dist/auth/sql-profile-loader/runtime-override.d.ts +14 -0
  13. package/dist/auth/sql-profile-loader/runtime-override.js +52 -0
  14. package/dist/auth/sql-profile-loader/types.d.ts +64 -0
  15. package/dist/auth/sql-profile-loader/types.js +1 -0
  16. package/dist/auth/sql-profile-loader.d.ts +4 -0
  17. package/dist/auth/sql-profile-loader.js +3 -0
  18. package/dist/capability/feature-matrix.d.ts +5 -0
  19. package/dist/capability/feature-matrix.js +237 -0
  20. package/dist/capability/probe.d.ts +19 -0
  21. package/dist/capability/probe.js +139 -0
  22. package/dist/capability/types.d.ts +49 -0
  23. package/dist/capability/types.js +16 -0
  24. package/dist/capability/version.d.ts +3 -0
  25. package/dist/capability/version.js +47 -0
  26. package/dist/cloud/auth.d.ts +26 -0
  27. package/dist/cloud/auth.js +198 -0
  28. package/dist/cloud/instances.d.ts +46 -0
  29. package/dist/cloud/instances.js +224 -0
  30. package/dist/config/env.d.ts +1 -0
  31. package/dist/config/env.js +194 -0
  32. package/dist/config/index.d.ts +6 -0
  33. package/dist/config/index.js +21 -0
  34. package/dist/config/redaction.d.ts +2 -0
  35. package/dist/config/redaction.js +19 -0
  36. package/dist/config/schema.d.ts +417 -0
  37. package/dist/config/schema.js +100 -0
  38. package/dist/context/datasource-resolver.d.ts +19 -0
  39. package/dist/context/datasource-resolver.js +71 -0
  40. package/dist/context/session-context.d.ts +26 -0
  41. package/dist/context/session-context.js +1 -0
  42. package/dist/diagnostics/metrics-source.d.ts +65 -0
  43. package/dist/diagnostics/metrics-source.js +280 -0
  44. package/dist/diagnostics/slow-sql-source/das-source.d.ts +43 -0
  45. package/dist/diagnostics/slow-sql-source/das-source.js +170 -0
  46. package/dist/diagnostics/slow-sql-source/factory.d.ts +5 -0
  47. package/dist/diagnostics/slow-sql-source/factory.js +87 -0
  48. package/dist/diagnostics/slow-sql-source/parsers.d.ts +7 -0
  49. package/dist/diagnostics/slow-sql-source/parsers.js +125 -0
  50. package/dist/diagnostics/slow-sql-source/taurus-api-source.d.ts +42 -0
  51. package/dist/diagnostics/slow-sql-source/taurus-api-source.js +149 -0
  52. package/dist/diagnostics/slow-sql-source/types.d.ts +40 -0
  53. package/dist/diagnostics/slow-sql-source/types.js +1 -0
  54. package/dist/diagnostics/slow-sql-source/utils.d.ts +20 -0
  55. package/dist/diagnostics/slow-sql-source/utils.js +170 -0
  56. package/dist/diagnostics/slow-sql-source.d.ts +4 -0
  57. package/dist/diagnostics/slow-sql-source.js +3 -0
  58. package/dist/diagnostics/types.d.ts +189 -0
  59. package/dist/diagnostics/types.js +39 -0
  60. package/dist/engine/data-access/locks.d.ts +8 -0
  61. package/dist/engine/data-access/locks.js +146 -0
  62. package/dist/engine/data-access/processlist.d.ts +4 -0
  63. package/dist/engine/data-access/processlist.js +56 -0
  64. package/dist/engine/data-access/statements.d.ts +10 -0
  65. package/dist/engine/data-access/statements.js +203 -0
  66. package/dist/engine/data-access/storage.d.ts +6 -0
  67. package/dist/engine/data-access/storage.js +96 -0
  68. package/dist/engine/data-access.d.ts +4 -0
  69. package/dist/engine/data-access.js +4 -0
  70. package/dist/engine/diagnostics.d.ts +7 -0
  71. package/dist/engine/diagnostics.js +7 -0
  72. package/dist/engine/helper-modules/diagnostics.d.ts +57 -0
  73. package/dist/engine/helper-modules/diagnostics.js +322 -0
  74. package/dist/engine/helper-modules/parsers.d.ts +13 -0
  75. package/dist/engine/helper-modules/parsers.js +283 -0
  76. package/dist/engine/helper-modules/sql.d.ts +12 -0
  77. package/dist/engine/helper-modules/sql.js +119 -0
  78. package/dist/engine/helper-modules/types.d.ts +103 -0
  79. package/dist/engine/helper-modules/types.js +1 -0
  80. package/dist/engine/helpers.d.ts +4 -0
  81. package/dist/engine/helpers.js +4 -0
  82. package/dist/engine/runtime.d.ts +20 -0
  83. package/dist/engine/runtime.js +385 -0
  84. package/dist/engine/types.d.ts +125 -0
  85. package/dist/engine/types.js +1 -0
  86. package/dist/engine/workflows/connection-spike.d.ts +4 -0
  87. package/dist/engine/workflows/connection-spike.js +316 -0
  88. package/dist/engine/workflows/db-hotspot.d.ts +4 -0
  89. package/dist/engine/workflows/db-hotspot.js +182 -0
  90. package/dist/engine/workflows/lock-contention-helpers/entities.d.ts +9 -0
  91. package/dist/engine/workflows/lock-contention-helpers/entities.js +58 -0
  92. package/dist/engine/workflows/lock-contention-helpers/no-match.d.ts +3 -0
  93. package/dist/engine/workflows/lock-contention-helpers/no-match.js +65 -0
  94. package/dist/engine/workflows/lock-contention-helpers/report.d.ts +21 -0
  95. package/dist/engine/workflows/lock-contention-helpers/report.js +104 -0
  96. package/dist/engine/workflows/lock-contention-helpers/root-cause.d.ts +4 -0
  97. package/dist/engine/workflows/lock-contention-helpers/root-cause.js +79 -0
  98. package/dist/engine/workflows/lock-contention-helpers/signals.d.ts +22 -0
  99. package/dist/engine/workflows/lock-contention-helpers/signals.js +34 -0
  100. package/dist/engine/workflows/lock-contention-helpers.d.ts +5 -0
  101. package/dist/engine/workflows/lock-contention-helpers.js +5 -0
  102. package/dist/engine/workflows/lock-contention.d.ts +4 -0
  103. package/dist/engine/workflows/lock-contention.js +67 -0
  104. package/dist/engine/workflows/service-latency.d.ts +4 -0
  105. package/dist/engine/workflows/service-latency.js +262 -0
  106. package/dist/engine/workflows/slow-query-helpers.d.ts +41 -0
  107. package/dist/engine/workflows/slow-query-helpers.js +253 -0
  108. package/dist/engine/workflows/slow-query.d.ts +4 -0
  109. package/dist/engine/workflows/slow-query.js +156 -0
  110. package/dist/engine/workflows/storage-pressure-helpers.d.ts +12 -0
  111. package/dist/engine/workflows/storage-pressure-helpers.js +281 -0
  112. package/dist/engine/workflows/storage-pressure.d.ts +4 -0
  113. package/dist/engine/workflows/storage-pressure.js +27 -0
  114. package/dist/engine/workflows/top-slow-sql.d.ts +4 -0
  115. package/dist/engine/workflows/top-slow-sql.js +222 -0
  116. package/dist/engine.d.ts +77 -0
  117. package/dist/engine.js +240 -0
  118. package/dist/executor/adapters/mysql.d.ts +2 -0
  119. package/dist/executor/adapters/mysql.js +114 -0
  120. package/dist/executor/connection-pool.d.ts +105 -0
  121. package/dist/executor/connection-pool.js +236 -0
  122. package/dist/executor/explain.d.ts +5 -0
  123. package/dist/executor/explain.js +119 -0
  124. package/dist/executor/query-tracker.d.ts +45 -0
  125. package/dist/executor/query-tracker.js +83 -0
  126. package/dist/executor/result-normalizer.d.ts +6 -0
  127. package/dist/executor/result-normalizer.js +47 -0
  128. package/dist/executor/sql-executor.d.ts +32 -0
  129. package/dist/executor/sql-executor.js +250 -0
  130. package/dist/executor/types.d.ts +70 -0
  131. package/dist/executor/types.js +1 -0
  132. package/dist/index.d.ts +40 -0
  133. package/dist/index.js +21 -0
  134. package/dist/safety/confirmation-store.d.ts +44 -0
  135. package/dist/safety/confirmation-store.js +130 -0
  136. package/dist/safety/guardrail.d.ts +39 -0
  137. package/dist/safety/guardrail.js +99 -0
  138. package/dist/safety/parser/adapter.d.ts +10 -0
  139. package/dist/safety/parser/adapter.js +72 -0
  140. package/dist/safety/parser/ast-utils.d.ts +10 -0
  141. package/dist/safety/parser/ast-utils.js +167 -0
  142. package/dist/safety/parser/features.d.ts +12 -0
  143. package/dist/safety/parser/features.js +113 -0
  144. package/dist/safety/parser/index.d.ts +2 -0
  145. package/dist/safety/parser/index.js +1 -0
  146. package/dist/safety/parser/types.d.ts +76 -0
  147. package/dist/safety/parser/types.js +1 -0
  148. package/dist/safety/redaction.d.ts +34 -0
  149. package/dist/safety/redaction.js +186 -0
  150. package/dist/safety/sql-classifier.d.ts +19 -0
  151. package/dist/safety/sql-classifier.js +43 -0
  152. package/dist/safety/sql-validator.d.ts +19 -0
  153. package/dist/safety/sql-validator.js +143 -0
  154. package/dist/schema/adapters/mysql.d.ts +16 -0
  155. package/dist/schema/adapters/mysql.js +287 -0
  156. package/dist/schema/introspector.d.ts +70 -0
  157. package/dist/schema/introspector.js +40 -0
  158. package/dist/taurus/flashback.d.ts +36 -0
  159. package/dist/taurus/flashback.js +149 -0
  160. package/dist/taurus/recycle-bin.d.ts +14 -0
  161. package/dist/taurus/recycle-bin.js +61 -0
  162. package/dist/utils/formatter.d.ts +70 -0
  163. package/dist/utils/formatter.js +60 -0
  164. package/dist/utils/hash.d.ts +2 -0
  165. package/dist/utils/hash.js +247 -0
  166. package/dist/utils/id.d.ts +2 -0
  167. package/dist/utils/id.js +11 -0
  168. package/dist/utils/logger.d.ts +9 -0
  169. package/dist/utils/logger.js +39 -0
  170. package/package.json +46 -0
@@ -0,0 +1,96 @@
1
+ import { clampInteger, escapeLikePrefix, parseStatementDigestRows, parseTableStorageRows, quoteLiteral, } from "../helpers.js";
2
+ export async function findStorageStatementDigests(engine, input, ctx) {
3
+ const maxRows = Math.min(clampInteger(input.maxCandidates, 5, 1, 10) * 2, 20);
4
+ const whereClauses = ["DIGEST_TEXT IS NOT NULL", "DIGEST_TEXT <> 'NULL'"];
5
+ const focusedTable = input.table?.includes(".")
6
+ ? input.table.split(".").slice(1).join(".")
7
+ : input.table;
8
+ if (ctx.database) {
9
+ whereClauses.push(`SCHEMA_NAME = ${quoteLiteral(ctx.database)}`);
10
+ }
11
+ if (focusedTable) {
12
+ const tableLike = quoteLiteral(`%${escapeLikePrefix(focusedTable)}%`);
13
+ whereClauses.push(`(DIGEST_TEXT LIKE ${tableLike} ESCAPE '\\\\' OR QUERY_SAMPLE_TEXT LIKE ${tableLike} ESCAPE '\\\\')`);
14
+ }
15
+ const sql = `
16
+ SELECT
17
+ SCHEMA_NAME AS schema_name,
18
+ DIGEST AS digest,
19
+ DIGEST_TEXT AS digest_text,
20
+ QUERY_SAMPLE_TEXT AS query_sample_text,
21
+ COUNT_STAR AS exec_count,
22
+ ROUND(AVG_TIMER_WAIT / 1000000000, 3) AS avg_latency_ms,
23
+ ROUND(SUM_TIMER_WAIT / 1000000000, 3) AS total_latency_ms,
24
+ ROUND(MAX_TIMER_WAIT / 1000000000, 3) AS max_latency_ms,
25
+ ROUND(SUM_LOCK_TIME / 1000000000 / NULLIF(COUNT_STAR, 0), 3) AS avg_lock_time_ms,
26
+ ROUND(SUM_ROWS_EXAMINED / NULLIF(COUNT_STAR, 0), 3) AS avg_rows_examined,
27
+ ROUND(SUM_SORT_ROWS / NULLIF(COUNT_STAR, 0), 3) AS avg_sort_rows,
28
+ ROUND(SUM_CREATED_TMP_TABLES / NULLIF(COUNT_STAR, 0), 3) AS avg_tmp_tables,
29
+ ROUND(SUM_CREATED_TMP_DISK_TABLES / NULLIF(COUNT_STAR, 0), 3) AS avg_tmp_disk_tables,
30
+ SUM_SELECT_SCAN AS select_scan_count,
31
+ SUM_NO_INDEX_USED AS no_index_used_count
32
+ FROM performance_schema.events_statements_summary_by_digest
33
+ WHERE ${whereClauses.join(" AND ")}
34
+ ORDER BY
35
+ SUM_CREATED_TMP_DISK_TABLES DESC,
36
+ SUM_ROWS_EXAMINED DESC,
37
+ SUM_SORT_ROWS DESC,
38
+ SUM_TIMER_WAIT DESC,
39
+ COUNT_STAR DESC
40
+ LIMIT ${maxRows}
41
+ `.trim();
42
+ const result = await engine.executor.executeReadonly(sql, ctx, {
43
+ maxRows,
44
+ maxColumns: 15,
45
+ maxFieldChars: 4096,
46
+ timeoutMs: ctx.limits.timeoutMs,
47
+ });
48
+ return parseStatementDigestRows(result);
49
+ }
50
+ export async function findTableStorageStats(engine, input, ctx) {
51
+ const maxRows = clampInteger(input.maxCandidates, 5, 1, 10);
52
+ const whereClauses = [
53
+ "TABLE_TYPE = 'BASE TABLE'",
54
+ "TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')",
55
+ ];
56
+ const focusedTable = input.table?.includes(".")
57
+ ? {
58
+ schema: input.table.split(".")[0],
59
+ table: input.table.split(".").slice(1).join("."),
60
+ }
61
+ : {
62
+ schema: ctx.database,
63
+ table: input.table,
64
+ };
65
+ if (focusedTable.schema) {
66
+ whereClauses.push(`TABLE_SCHEMA = ${quoteLiteral(focusedTable.schema)}`);
67
+ }
68
+ else if (ctx.database && input.scope !== "instance") {
69
+ whereClauses.push(`TABLE_SCHEMA = ${quoteLiteral(ctx.database)}`);
70
+ }
71
+ if (focusedTable.table) {
72
+ whereClauses.push(`TABLE_NAME = ${quoteLiteral(focusedTable.table)}`);
73
+ }
74
+ const sql = `
75
+ SELECT
76
+ TABLE_SCHEMA AS schema_name,
77
+ TABLE_NAME AS table_name,
78
+ ENGINE AS engine,
79
+ TABLE_ROWS AS row_count_estimate,
80
+ ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 3) AS total_mb,
81
+ ROUND(DATA_LENGTH / 1024 / 1024, 3) AS data_mb,
82
+ ROUND(INDEX_LENGTH / 1024 / 1024, 3) AS index_mb,
83
+ ROUND(DATA_FREE / 1024 / 1024, 3) AS data_free_mb
84
+ FROM information_schema.TABLES
85
+ WHERE ${whereClauses.join(" AND ")}
86
+ ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC, TABLE_ROWS DESC, TABLE_SCHEMA ASC, TABLE_NAME ASC
87
+ LIMIT ${maxRows}
88
+ `.trim();
89
+ const result = await engine.executor.executeReadonly(sql, ctx, {
90
+ maxRows,
91
+ maxColumns: 8,
92
+ maxFieldChars: 512,
93
+ timeoutMs: ctx.limits.timeoutMs,
94
+ });
95
+ return parseTableStorageRows(result);
96
+ }
@@ -0,0 +1,4 @@
1
+ export { showProcesslist } from "./data-access/processlist.js";
2
+ export { showLockWaits, findMetadataLockWaits, findLatestDeadlock } from "./data-access/locks.js";
3
+ export { findStatementDigestSample, findStatementDigestSampleForSql, findStatementDigestCandidatesForSqlHints, findTopStatementDigests, isPerformanceSchemaEnabled, findStatementWaitEvents, } from "./data-access/statements.js";
4
+ export { findStorageStatementDigests, findTableStorageStats } from "./data-access/storage.js";
@@ -0,0 +1,4 @@
1
+ export { showProcesslist } from "./data-access/processlist.js";
2
+ export { showLockWaits, findMetadataLockWaits, findLatestDeadlock } from "./data-access/locks.js";
3
+ export { findStatementDigestSample, findStatementDigestSampleForSql, findStatementDigestCandidatesForSqlHints, findTopStatementDigests, isPerformanceSchemaEnabled, findStatementWaitEvents, } from "./data-access/statements.js";
4
+ export { findStorageStatementDigests, findTableStorageStats } from "./data-access/storage.js";
@@ -0,0 +1,7 @@
1
+ export { diagnoseSlowQuery } from "./workflows/slow-query.js";
2
+ export { diagnoseServiceLatency } from "./workflows/service-latency.js";
3
+ export { diagnoseDbHotspot } from "./workflows/db-hotspot.js";
4
+ export { findTopSlowSql } from "./workflows/top-slow-sql.js";
5
+ export { diagnoseConnectionSpike } from "./workflows/connection-spike.js";
6
+ export { diagnoseLockContention } from "./workflows/lock-contention.js";
7
+ export { diagnoseStoragePressure } from "./workflows/storage-pressure.js";
@@ -0,0 +1,7 @@
1
+ export { diagnoseSlowQuery } from "./workflows/slow-query.js";
2
+ export { diagnoseServiceLatency } from "./workflows/service-latency.js";
3
+ export { diagnoseDbHotspot } from "./workflows/db-hotspot.js";
4
+ export { findTopSlowSql } from "./workflows/top-slow-sql.js";
5
+ export { diagnoseConnectionSpike } from "./workflows/connection-spike.js";
6
+ export { diagnoseLockContention } from "./workflows/lock-contention.js";
7
+ export { diagnoseStoragePressure } from "./workflows/storage-pressure.js";
@@ -0,0 +1,57 @@
1
+ import type { SessionContext } from "../../context/session-context.js";
2
+ import type { MetricAlias, MetricSummary, MetricsSource } from "../../diagnostics/metrics-source.js";
3
+ import type { DbHotspotItem, DiagnosticBaseInput, DiagnosticNextToolInput, DiagnosticRootCauseCandidate, DiagnosticSeverity, DiagnoseConnectionSpikeInput, DiagnoseLockContentionInput, ServiceLatencyCandidate, ServiceLatencySuspectedCategory } from "../../diagnostics/types.js";
4
+ import type { ExplainResult } from "../../executor/sql-executor.js";
5
+ export declare function countBy<T>(rows: T[], pick: (row: T) => string | undefined): Array<{
6
+ key: string;
7
+ count: number;
8
+ }>;
9
+ export declare function pickMetric(metrics: MetricSummary[], alias: MetricAlias): MetricSummary | undefined;
10
+ export declare function metricSummaryText(metric: MetricSummary): string;
11
+ export declare function roundMetric(value: number): number;
12
+ export interface SafeMetricsQueryResult {
13
+ metrics: MetricSummary[];
14
+ error?: string;
15
+ }
16
+ export declare function queryMetricsSafely(source: MetricsSource | undefined, aliases: MetricAlias[], input: DiagnosticBaseInput, ctx: SessionContext): Promise<MetricSummary[]>;
17
+ export declare function queryMetricsWithStatus(source: MetricsSource | undefined, aliases: MetricAlias[], input: DiagnosticBaseInput, ctx: SessionContext): Promise<SafeMetricsQueryResult>;
18
+ export declare function metricsSourceLimitation(source: MetricsSource | undefined): string[];
19
+ export declare function confidenceWeight(value: ServiceLatencyCandidate["confidence"]): number;
20
+ export declare function rootCauseBasePriority(code: string): number;
21
+ export declare function rootCauseConfidenceWeight(value: DiagnosticRootCauseCandidate["confidence"]): number;
22
+ export declare function rootCauseRankScore(candidate: DiagnosticRootCauseCandidate): number;
23
+ export declare function sortRootCauseCandidates(candidates: DiagnosticRootCauseCandidate[]): DiagnosticRootCauseCandidate[];
24
+ export declare function severityFromSlowQueryEvidence(riskSummary: ExplainResult["riskSummary"], candidates: DiagnosticRootCauseCandidate[]): DiagnosticSeverity;
25
+ export declare function serviceCategoryPriority(value: ServiceLatencySuspectedCategory): number;
26
+ export declare function hotspotTypePriority(value: DbHotspotItem["type"]): number;
27
+ export declare function buildSlowQueryNextToolInput(source: {
28
+ sqlHash?: string;
29
+ digestText?: string;
30
+ sampleSql?: string;
31
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput | undefined;
32
+ export declare function buildBaseNextToolInput(input: DiagnosticBaseInput): Record<string, unknown>;
33
+ export declare function buildDbHotspotNextToolInput(source: {
34
+ scope?: "sql" | "table" | "session";
35
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput;
36
+ export declare function buildFindTopSlowSqlNextToolInput(source: {
37
+ sortBy?: "avg_latency" | "total_latency" | "exec_count" | "lock_time";
38
+ topN?: number;
39
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput;
40
+ export declare function buildLockContentionNextToolInput(source: {
41
+ table?: string;
42
+ blockerSessionId?: string;
43
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput;
44
+ export declare function buildConnectionSpikeNextToolInput(source: {
45
+ user?: string;
46
+ clientHost?: string;
47
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput;
48
+ export declare function buildShowProcesslistNextToolInput(source: {
49
+ user?: string;
50
+ host?: string;
51
+ command?: string;
52
+ includeIdle?: boolean;
53
+ includeInfo?: boolean;
54
+ }, input: DiagnosticBaseInput, rationale: string): DiagnosticNextToolInput;
55
+ export declare function dedupeNextToolInputs(inputs: DiagnosticNextToolInput[]): DiagnosticNextToolInput[];
56
+ export declare function evidenceRowLimit(level: DiagnoseConnectionSpikeInput["evidenceLevel"]): number;
57
+ export declare function lockEvidenceRowLimit(level: DiagnoseLockContentionInput["evidenceLevel"]): number;
@@ -0,0 +1,322 @@
1
+ export function countBy(rows, pick) {
2
+ const counts = new Map();
3
+ for (const row of rows) {
4
+ const key = pick(row);
5
+ if (!key) {
6
+ continue;
7
+ }
8
+ counts.set(key, (counts.get(key) ?? 0) + 1);
9
+ }
10
+ return [...counts.entries()]
11
+ .map(([key, count]) => ({ key, count }))
12
+ .sort((left, right) => right.count - left.count || left.key.localeCompare(right.key));
13
+ }
14
+ export function pickMetric(metrics, alias) {
15
+ return metrics.find((metric) => metric.alias === alias);
16
+ }
17
+ export function metricSummaryText(metric) {
18
+ const parts = [
19
+ `metric=${metric.metricName}`,
20
+ `points=${metric.points.length}`,
21
+ metric.latest !== undefined
22
+ ? `latest=${roundMetric(metric.latest)}`
23
+ : undefined,
24
+ metric.max !== undefined ? `max=${roundMetric(metric.max)}` : undefined,
25
+ metric.avg !== undefined ? `avg=${roundMetric(metric.avg)}` : undefined,
26
+ ].filter((part) => part !== undefined);
27
+ return parts.join(", ");
28
+ }
29
+ export function roundMetric(value) {
30
+ return Math.round(value * 1000) / 1000;
31
+ }
32
+ export async function queryMetricsSafely(source, aliases, input, ctx) {
33
+ const result = await queryMetricsWithStatus(source, aliases, input, ctx);
34
+ return result.metrics;
35
+ }
36
+ export async function queryMetricsWithStatus(source, aliases, input, ctx) {
37
+ if (!source) {
38
+ return { metrics: [] };
39
+ }
40
+ try {
41
+ return {
42
+ metrics: await source.query({ aliases, timeRange: input.timeRange }, ctx),
43
+ };
44
+ }
45
+ catch (error) {
46
+ return {
47
+ metrics: [],
48
+ error: error instanceof Error && error.message.trim().length > 0
49
+ ? error.message
50
+ : "Metrics query failed.",
51
+ };
52
+ }
53
+ }
54
+ export function metricsSourceLimitation(source) {
55
+ return source
56
+ ? []
57
+ : ["No CES or control-plane metrics source is configured yet."];
58
+ }
59
+ export function confidenceWeight(value) {
60
+ switch (value) {
61
+ case "high":
62
+ return 3;
63
+ case "medium":
64
+ return 2;
65
+ default:
66
+ return 1;
67
+ }
68
+ }
69
+ export function rootCauseBasePriority(code) {
70
+ switch (code) {
71
+ case "slow_query_full_table_scan":
72
+ return 90;
73
+ case "slow_query_poor_index_usage":
74
+ return 60;
75
+ case "slow_query_runtime_scan_pressure":
76
+ return 70;
77
+ case "slow_query_tmp_disk_spill":
78
+ return 65;
79
+ case "slow_query_wait_event_lock_contention":
80
+ return 60;
81
+ case "slow_query_lock_wait_pressure":
82
+ return 55;
83
+ case "slow_query_filesort":
84
+ return 50;
85
+ case "slow_query_temp_structure":
86
+ return 45;
87
+ case "slow_query_wait_event_io_pressure":
88
+ return 40;
89
+ case "slow_query_wait_event_sync_contention":
90
+ return 35;
91
+ case "slow_query_taurus_feature_gap":
92
+ return 20;
93
+ case "slow_query_plan_collected":
94
+ return 10;
95
+ default:
96
+ return 0;
97
+ }
98
+ }
99
+ export function rootCauseConfidenceWeight(value) {
100
+ switch (value) {
101
+ case "high":
102
+ return 30;
103
+ case "medium":
104
+ return 15;
105
+ default:
106
+ return 0;
107
+ }
108
+ }
109
+ export function rootCauseRankScore(candidate) {
110
+ return (rootCauseBasePriority(candidate.code) +
111
+ rootCauseConfidenceWeight(candidate.confidence));
112
+ }
113
+ export function sortRootCauseCandidates(candidates) {
114
+ return [...candidates].sort((left, right) => rootCauseRankScore(right) - rootCauseRankScore(left) ||
115
+ rootCauseBasePriority(right.code) - rootCauseBasePriority(left.code) ||
116
+ rootCauseConfidenceWeight(right.confidence) -
117
+ rootCauseConfidenceWeight(left.confidence) ||
118
+ left.code.localeCompare(right.code));
119
+ }
120
+ export function severityFromSlowQueryEvidence(riskSummary, candidates) {
121
+ if (riskSummary.fullTableScanLikely ||
122
+ riskSummary.usesFilesort ||
123
+ riskSummary.usesTempStructure) {
124
+ return (riskSummary.estimatedRows ?? 0) >= 100_000 ? "high" : "warning";
125
+ }
126
+ if (candidates.some((candidate) => candidate.confidence === "high")) {
127
+ return "warning";
128
+ }
129
+ if (candidates.some((candidate) => candidate.confidence === "medium")) {
130
+ return "warning";
131
+ }
132
+ return "info";
133
+ }
134
+ export function serviceCategoryPriority(value) {
135
+ switch (value) {
136
+ case "lock_contention":
137
+ return 5;
138
+ case "connection_spike":
139
+ return 4;
140
+ case "slow_sql":
141
+ return 3;
142
+ case "resource_pressure":
143
+ return 2;
144
+ case "mixed":
145
+ default:
146
+ return 1;
147
+ }
148
+ }
149
+ export function hotspotTypePriority(value) {
150
+ switch (value) {
151
+ case "session":
152
+ return 3;
153
+ case "table":
154
+ return 2;
155
+ case "sql":
156
+ default:
157
+ return 1;
158
+ }
159
+ }
160
+ export function buildSlowQueryNextToolInput(source, input, rationale) {
161
+ const slowQueryInput = {};
162
+ if (input.datasource) {
163
+ slowQueryInput.datasource = input.datasource;
164
+ }
165
+ if (input.database) {
166
+ slowQueryInput.database = input.database;
167
+ }
168
+ if (input.timeRange) {
169
+ slowQueryInput.time_range = input.timeRange;
170
+ }
171
+ if (input.evidenceLevel) {
172
+ slowQueryInput.evidence_level = input.evidenceLevel;
173
+ }
174
+ if (input.includeRawEvidence !== undefined) {
175
+ slowQueryInput.include_raw_evidence = input.includeRawEvidence;
176
+ }
177
+ if (input.maxCandidates !== undefined) {
178
+ slowQueryInput.max_candidates = input.maxCandidates;
179
+ }
180
+ if (source.sampleSql) {
181
+ slowQueryInput.sql = source.sampleSql;
182
+ }
183
+ else if (source.digestText) {
184
+ slowQueryInput.digest_text = source.digestText;
185
+ }
186
+ else if (source.sqlHash) {
187
+ slowQueryInput.sql_hash = source.sqlHash;
188
+ }
189
+ else {
190
+ return undefined;
191
+ }
192
+ return {
193
+ tool: "diagnose_slow_query",
194
+ input: slowQueryInput,
195
+ rationale,
196
+ };
197
+ }
198
+ export function buildBaseNextToolInput(input) {
199
+ const nextInput = {};
200
+ if (input.datasource) {
201
+ nextInput.datasource = input.datasource;
202
+ }
203
+ if (input.database) {
204
+ nextInput.database = input.database;
205
+ }
206
+ if (input.timeRange) {
207
+ nextInput.time_range = input.timeRange;
208
+ }
209
+ if (input.evidenceLevel) {
210
+ nextInput.evidence_level = input.evidenceLevel;
211
+ }
212
+ if (input.includeRawEvidence !== undefined) {
213
+ nextInput.include_raw_evidence = input.includeRawEvidence;
214
+ }
215
+ if (input.maxCandidates !== undefined) {
216
+ nextInput.max_candidates = input.maxCandidates;
217
+ }
218
+ return nextInput;
219
+ }
220
+ export function buildDbHotspotNextToolInput(source, input, rationale) {
221
+ const nextInput = buildBaseNextToolInput(input);
222
+ if (source.scope) {
223
+ nextInput.scope = source.scope;
224
+ }
225
+ return {
226
+ tool: "diagnose_db_hotspot",
227
+ input: nextInput,
228
+ rationale,
229
+ };
230
+ }
231
+ export function buildFindTopSlowSqlNextToolInput(source, input, rationale) {
232
+ const nextInput = buildBaseNextToolInput(input);
233
+ if (source.sortBy) {
234
+ nextInput.sort_by = source.sortBy;
235
+ }
236
+ if (source.topN !== undefined) {
237
+ nextInput.top_n = source.topN;
238
+ }
239
+ return {
240
+ tool: "find_top_slow_sql",
241
+ input: nextInput,
242
+ rationale,
243
+ };
244
+ }
245
+ export function buildLockContentionNextToolInput(source, input, rationale) {
246
+ const nextInput = buildBaseNextToolInput(input);
247
+ if (source.table) {
248
+ nextInput.table = source.table;
249
+ }
250
+ if (source.blockerSessionId) {
251
+ nextInput.blocker_session_id = source.blockerSessionId;
252
+ }
253
+ return {
254
+ tool: "diagnose_lock_contention",
255
+ input: nextInput,
256
+ rationale,
257
+ };
258
+ }
259
+ export function buildConnectionSpikeNextToolInput(source, input, rationale) {
260
+ const nextInput = buildBaseNextToolInput(input);
261
+ if (source.user) {
262
+ nextInput.user = source.user;
263
+ }
264
+ if (source.clientHost) {
265
+ nextInput.client_host = source.clientHost;
266
+ }
267
+ nextInput.compare_baseline = false;
268
+ return {
269
+ tool: "diagnose_connection_spike",
270
+ input: nextInput,
271
+ rationale,
272
+ };
273
+ }
274
+ export function buildShowProcesslistNextToolInput(source, input, rationale) {
275
+ const nextInput = buildBaseNextToolInput(input);
276
+ if (source.user) {
277
+ nextInput.user = source.user;
278
+ }
279
+ if (source.host) {
280
+ nextInput.host = source.host;
281
+ }
282
+ if (source.command) {
283
+ nextInput.command = source.command;
284
+ }
285
+ nextInput.include_idle = source.includeIdle ?? true;
286
+ nextInput.include_info = source.includeInfo ?? true;
287
+ nextInput.max_rows = 20;
288
+ return {
289
+ tool: "show_processlist",
290
+ input: nextInput,
291
+ rationale,
292
+ };
293
+ }
294
+ export function dedupeNextToolInputs(inputs) {
295
+ return inputs.filter((item, index, allItems) => {
296
+ const key = `${item.tool}:${JSON.stringify(item.input)}`;
297
+ return (allItems.findIndex((candidate) => {
298
+ const candidateKey = `${candidate.tool}:${JSON.stringify(candidate.input)}`;
299
+ return candidateKey === key;
300
+ }) === index);
301
+ });
302
+ }
303
+ export function evidenceRowLimit(level) {
304
+ switch (level) {
305
+ case "full":
306
+ return 100;
307
+ case "standard":
308
+ return 50;
309
+ default:
310
+ return 20;
311
+ }
312
+ }
313
+ export function lockEvidenceRowLimit(level) {
314
+ switch (level) {
315
+ case "full":
316
+ return 100;
317
+ case "standard":
318
+ return 50;
319
+ default:
320
+ return 20;
321
+ }
322
+ }
@@ -0,0 +1,13 @@
1
+ import type { QueryResult } from "../../executor/sql-executor.js";
2
+ import type { DeadlockSummary, LockWaitRow, MetadataLockRow, ProcesslistRow, ReplicationStatusRow, StatementDigestRow, StatementWaitEventRow, TableStorageRow } from "./types.js";
3
+ export declare function parseProcesslistRows(result: QueryResult): ProcesslistRow[];
4
+ export declare function parseOptionalInteger(value: unknown): number | undefined;
5
+ export declare function parseLockWaitRows(result: QueryResult): LockWaitRow[];
6
+ export declare function isIdleTransactionBlocker(row: LockWaitRow): boolean;
7
+ export declare function parseOptionalNumber(value: unknown): number | undefined;
8
+ export declare function parseMetadataLockRows(result: QueryResult): MetadataLockRow[];
9
+ export declare function parseDeadlockSummary(result: QueryResult): DeadlockSummary | undefined;
10
+ export declare function parseStatementDigestRows(result: QueryResult): StatementDigestRow[];
11
+ export declare function parseStatementWaitEventRows(result: QueryResult): StatementWaitEventRow[];
12
+ export declare function parseTableStorageRows(result: QueryResult): TableStorageRow[];
13
+ export declare function parseReplicationStatusRows(result: QueryResult): ReplicationStatusRow[];