postgresai 0.16.0 → 0.17.0-dev.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.
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
7
7
  grant pg_monitor to {{ROLE_IDENT}};
8
8
  grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
9
9
 
10
+ -- Required for cluster-wide pg_stat_statements collection.
11
+ -- pg_stat_statements is backed by shared memory and holds entries for every database
12
+ -- in the cluster, but a role without pg_read_all_stats sees other users' rows with
13
+ -- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
14
+ -- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
15
+ -- granting it explicitly documents the dependency and keeps the metric working if the
16
+ -- pg_monitor grant above is ever narrowed. Idempotent.
17
+ grant pg_read_all_stats to {{ROLE_IDENT}};
18
+
10
19
  -- Create postgres_ai schema for our objects
11
20
  -- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
12
21
  create schema if not exists postgres_ai;
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
7
7
  grant pg_monitor to {{ROLE_IDENT}};
8
8
  grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
9
9
 
10
+ -- Required for cluster-wide pg_stat_statements collection.
11
+ -- pg_stat_statements is backed by shared memory and holds entries for every database
12
+ -- in the cluster, but a role without pg_read_all_stats sees other users' rows with
13
+ -- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
14
+ -- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
15
+ -- granting it explicitly documents the dependency and keeps the metric working if the
16
+ -- pg_monitor grant above is ever narrowed. Idempotent.
17
+ grant pg_read_all_stats to {{ROLE_IDENT}};
18
+
10
19
  -- Create postgres_ai schema for our objects
11
20
  -- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
12
21
  create schema if not exists postgres_ai;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresai",
3
- "version": "0.16.0",
3
+ "version": "0.17.0-dev.0",
4
4
  "description": "postgres_ai CLI",
5
5
  "license": "Apache-2.0",
6
6
  "private": false,
@@ -49,19 +49,24 @@
49
49
  "release-notes": "bun run scripts/generate-release-notes.ts"
50
50
  },
51
51
  "dependencies": {
52
- "@modelcontextprotocol/sdk": "^1.20.2",
52
+ "@modelcontextprotocol/sdk": "^1.26.0",
53
53
  "commander": "^14.0.3",
54
- "js-yaml": "^4.1.0",
54
+ "js-yaml": "^4.3.1",
55
55
  "pg": "^8.16.3"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/bun": "^1.3.6",
59
59
  "@types/js-yaml": "^4.0.9",
60
60
  "@types/pg": "^8.15.6",
61
- "ajv": "^8.17.1",
61
+ "ajv": "8.18.0",
62
62
  "ajv-formats": "^3.0.1",
63
63
  "typescript": "^6.0.2"
64
64
  },
65
+ "overrides": {
66
+ "ajv": "8.18.0",
67
+ "fast-uri": "3.1.5",
68
+ "path-to-regexp": "8.4.0"
69
+ },
65
70
  "publishConfig": {
66
71
  "access": "public"
67
72
  }
@@ -58,16 +58,151 @@
58
58
  "type": "object",
59
59
  "additionalProperties": { "$ref": "#/$defs/setting" }
60
60
  },
61
+ "effectiveValue": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "required": ["raw", "effective", "unit", "inherited_from", "inheritance_chain"],
65
+ "properties": {
66
+ "raw": { "type": ["string", "null"] },
67
+ "effective": { "type": ["number", "null"] },
68
+ "unit": { "type": "string" },
69
+ "inherited_from": { "type": ["string", "null"] },
70
+ "inheritance_chain": { "type": "string" }
71
+ }
72
+ },
73
+ "effectiveValues": {
74
+ "type": "object",
75
+ "additionalProperties": false,
76
+ "required": ["cost_delay_ms", "cost_limit", "work_mem_kb"],
77
+ "properties": {
78
+ "autovacuum": { "type": ["boolean", "null"] },
79
+ "track_counts": { "type": ["boolean", "null"] },
80
+ "cost_delay_ms": { "$ref": "#/$defs/effectiveValue" },
81
+ "cost_limit": { "$ref": "#/$defs/effectiveValue" },
82
+ "work_mem_kb": { "$ref": "#/$defs/effectiveValue" },
83
+ "naptime_s": { "type": ["number", "null"] },
84
+ "scale_factor": { "type": ["number", "null"] },
85
+ "analyze_scale_factor": { "type": ["number", "null"] },
86
+ "vacuum_insert_threshold": { "type": ["number", "null"] },
87
+ "log_min_duration_ms": { "type": ["number", "null"] },
88
+ "max_workers": { "type": ["number", "null"] },
89
+ "page_cost_hit": { "type": "number" },
90
+ "page_cost_miss": { "type": "number" },
91
+ "page_cost_dirty": { "type": "number" }
92
+ }
93
+ },
94
+ "throughputBudget": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "required": [
98
+ "effective_cost_delay_ms",
99
+ "effective_cost_limit",
100
+ "page_cost_hit",
101
+ "page_cost_miss",
102
+ "page_cost_dirty",
103
+ "tokens_per_sec",
104
+ "read_hit_mbps",
105
+ "read_miss_mbps",
106
+ "dirty_write_mbps",
107
+ "throttling_disabled"
108
+ ],
109
+ "properties": {
110
+ "effective_cost_delay_ms": { "type": ["number", "null"] },
111
+ "effective_cost_limit": { "type": ["number", "null"] },
112
+ "page_cost_hit": { "type": "number" },
113
+ "page_cost_miss": { "type": "number" },
114
+ "page_cost_dirty": { "type": "number" },
115
+ "tokens_per_sec": { "type": ["number", "null"] },
116
+ "read_hit_mbps": { "type": ["number", "null"] },
117
+ "read_miss_mbps": { "type": ["number", "null"] },
118
+ "dirty_write_mbps": { "type": ["number", "null"] },
119
+ "throttling_disabled": { "type": "boolean" }
120
+ }
121
+ },
122
+ "largestTable": {
123
+ "type": "object",
124
+ "additionalProperties": false,
125
+ "required": [
126
+ "schema_name",
127
+ "table_name",
128
+ "relkind",
129
+ "relpages",
130
+ "total_relation_size_bytes",
131
+ "total_relation_size_pretty",
132
+ "has_av_override",
133
+ "reloptions",
134
+ "scale_factor_override"
135
+ ],
136
+ "properties": {
137
+ "schema_name": { "type": "string" },
138
+ "table_name": { "type": "string" },
139
+ "relkind": { "type": "string" },
140
+ "relpages": { "type": "number" },
141
+ "total_relation_size_bytes": { "type": "number" },
142
+ "total_relation_size_pretty": { "type": "string" },
143
+ "has_av_override": { "type": "boolean" },
144
+ "reloptions": { "type": "string" },
145
+ "scale_factor_override": { "type": ["number", "null"] }
146
+ }
147
+ },
148
+ "reloptionsOverview": {
149
+ "type": "object",
150
+ "additionalProperties": false,
151
+ "required": [
152
+ "relations_total",
153
+ "candidates_considered",
154
+ "tables_with_av_overrides",
155
+ "autovacuum_disabled_tables",
156
+ "cost_delay_zero_tables",
157
+ "cost_delay_zero_toast_only_tables"
158
+ ],
159
+ "properties": {
160
+ "relations_total": { "type": "number" },
161
+ "candidates_considered": { "type": "number" },
162
+ "tables_with_av_overrides": { "type": "number" },
163
+ "autovacuum_disabled_tables": { "type": "array", "items": { "type": "string" } },
164
+ "cost_delay_zero_tables": { "type": "array", "items": { "type": "string" } },
165
+ "cost_delay_zero_toast_only_tables": { "type": "array", "items": { "type": "string" } }
166
+ }
167
+ },
168
+ "firedRule": {
169
+ "type": "object",
170
+ "additionalProperties": false,
171
+ "required": ["id", "severity", "conclusion", "recommendation"],
172
+ "properties": {
173
+ "id": { "type": "string" },
174
+ "severity": { "enum": ["CRITICAL", "WARNING", "NOTICE", "INFO"] },
175
+ "conclusion": { "type": "string" },
176
+ "recommendation": { "type": "string" }
177
+ }
178
+ },
179
+ "settingsAnalysis": {
180
+ "type": "object",
181
+ "additionalProperties": false,
182
+ "required": ["severity", "rules_fired", "largest_tables", "reloptions_overview"],
183
+ "properties": {
184
+ "severity": { "enum": ["CRITICAL", "WARNING", "NOTICE", "INFO", null] },
185
+ "rules_fired": { "type": "array", "items": { "$ref": "#/$defs/firedRule" } },
186
+ "largest_tables": { "type": "array", "items": { "$ref": "#/$defs/largestTable" } },
187
+ "reloptions_overview": { "$ref": "#/$defs/reloptionsOverview" },
188
+ "database_size_bytes": { "type": "number" },
189
+ "database_size_pretty": { "type": "string" },
190
+ "thresholds": { "type": "object" }
191
+ }
192
+ },
61
193
  "nodeResult": {
62
194
  "type": "object",
63
195
  "additionalProperties": false,
64
196
  "required": ["data"],
65
197
  "properties": {
66
198
  "data": { "$ref": "#/$defs/data" },
67
- "postgres_version": { "$ref": "#/$defs/postgresVersion" }
199
+ "postgres_version": { "$ref": "#/$defs/postgresVersion" },
200
+ "effective_values": { "$ref": "#/$defs/effectiveValues" },
201
+ "throughput_budget": { "$ref": "#/$defs/throughputBudget" },
202
+ "conclusions": { "type": "array", "items": { "type": "string" } },
203
+ "recommendations": { "type": "array", "items": { "type": "string" } },
204
+ "settings_analysis": { "$ref": "#/$defs/settingsAnalysis" }
68
205
  }
69
206
  }
70
207
  }
71
208
  }
72
-
73
-
@@ -78,7 +78,124 @@
78
78
  "table_size_bytes": { "type": "number" },
79
79
  "table_size_pretty": { "type": "string" },
80
80
  "exceeds_dead_tuple_thresholds": { "type": "boolean" },
81
- "autovacuum_disabled_flagged": { "type": "boolean" }
81
+ "autovacuum_disabled_flagged": { "type": "boolean" },
82
+ "reltuples": { "type": "number" },
83
+ "relpages": { "type": "number" },
84
+ "n_mod_since_analyze": { "type": "number" },
85
+ "n_ins_since_vacuum": { "type": ["number", "null"] },
86
+ "last_autoanalyze": { "type": ["string", "null"] },
87
+ "last_autoanalyze_epoch": { "type": "number" },
88
+ "eff_vacuum_threshold": { "type": "number" },
89
+ "eff_vacuum_scale_factor": { "type": "number" },
90
+ "vacuum_settings_from_reloptions": { "type": "boolean" },
91
+ "eff_analyze_threshold": { "type": "number" },
92
+ "eff_analyze_scale_factor": { "type": "number" },
93
+ "eff_insert_threshold": { "type": ["number", "null"] },
94
+ "eff_insert_scale_factor": { "type": ["number", "null"] },
95
+ "insert_settings_from_reloptions": { "type": "boolean" },
96
+ "vacuum_trigger_point": { "type": "number" },
97
+ "analyze_trigger_point": { "type": "number" },
98
+ "insert_trigger_point": { "type": ["number", "null"] },
99
+ "over_trigger_ratio": { "type": "number" },
100
+ "over_vacuum_trigger": { "type": "boolean" },
101
+ "over_analyze_trigger": { "type": "boolean" },
102
+ "over_insert_trigger": { "type": "boolean" },
103
+ "toast_autovacuum_disabled": { "type": "boolean" },
104
+ "starving": { "type": "boolean" }
105
+ }
106
+ },
107
+ "triggerThresholds": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "required": ["top_k", "keepup_min_rows", "queue_saturation_multiplier", "starvation_hours"],
111
+ "properties": {
112
+ "top_k": { "type": "number" },
113
+ "keepup_min_rows": { "type": "number" },
114
+ "queue_saturation_multiplier": { "type": "number" },
115
+ "starvation_hours": { "type": "number" }
116
+ }
117
+ },
118
+ "blockedWorker": {
119
+ "type": "object",
120
+ "additionalProperties": false,
121
+ "required": ["worker_pid", "blocker_pid", "blocker_queryid", "wait_seconds"],
122
+ "properties": {
123
+ "worker_pid": { "type": "number" },
124
+ "blocker_pid": { "type": ["number", "null"] },
125
+ "blocker_queryid": { "type": ["string", "null"] },
126
+ "wait_seconds": { "type": "number" }
127
+ }
128
+ },
129
+ "vacuumProgressEntry": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "required": [
133
+ "schema_name",
134
+ "table_name",
135
+ "vacuum_mode",
136
+ "phase",
137
+ "phase_code",
138
+ "heap_blks_total",
139
+ "heap_blks_scanned",
140
+ "heap_blks_vacuumed",
141
+ "index_vacuum_count",
142
+ "is_anti_wraparound"
143
+ ],
144
+ "properties": {
145
+ "schema_name": { "type": "string" },
146
+ "table_name": { "type": "string" },
147
+ "vacuum_mode": { "type": "string" },
148
+ "phase": { "type": "string" },
149
+ "phase_code": { "type": ["number", "null"] },
150
+ "heap_blks_total": { "type": "number" },
151
+ "heap_blks_scanned": { "type": "number" },
152
+ "heap_blks_vacuumed": { "type": "number" },
153
+ "index_vacuum_count": { "type": "number" },
154
+ "is_anti_wraparound": { "type": "boolean" }
155
+ }
156
+ },
157
+ "autovacuumKeepup": {
158
+ "type": "object",
159
+ "additionalProperties": false,
160
+ "required": [
161
+ "relations_total",
162
+ "candidates_considered",
163
+ "queue_length",
164
+ "analyze_queue_length",
165
+ "insert_queue_length",
166
+ "total_dead_tuples_all",
167
+ "active_workers",
168
+ "max_workers",
169
+ "free_slots",
170
+ "anti_wraparound_workers",
171
+ "anti_wraparound_present",
172
+ "saturated",
173
+ "chronic_under_provisioning",
174
+ "starving_tables_count",
175
+ "blocked_workers",
176
+ "vacuum_progress",
177
+ "judgment",
178
+ "status"
179
+ ],
180
+ "properties": {
181
+ "relations_total": { "type": "number" },
182
+ "candidates_considered": { "type": "number" },
183
+ "queue_length": { "type": "number" },
184
+ "analyze_queue_length": { "type": "number" },
185
+ "insert_queue_length": { "type": ["number", "null"] },
186
+ "total_dead_tuples_all": { "type": "number" },
187
+ "active_workers": { "type": "number" },
188
+ "max_workers": { "type": ["number", "null"] },
189
+ "free_slots": { "type": ["number", "null"] },
190
+ "anti_wraparound_workers": { "type": "number" },
191
+ "anti_wraparound_present": { "type": "boolean" },
192
+ "saturated": { "type": "boolean" },
193
+ "chronic_under_provisioning": { "type": "boolean" },
194
+ "starving_tables_count": { "type": "number" },
195
+ "blocked_workers": { "type": "array", "items": { "$ref": "#/$defs/blockedWorker" } },
196
+ "vacuum_progress": { "type": "array", "items": { "$ref": "#/$defs/vacuumProgressEntry" } },
197
+ "judgment": { "type": "string" },
198
+ "status": { "type": "string", "enum": ["ok", "warning", "critical"] }
82
199
  }
83
200
  },
84
201
  "thresholds": {
@@ -115,6 +232,8 @@
115
232
  "autovacuum_disabled_flagged_count": { "type": "integer" },
116
233
  "total_dead_tuples": { "type": "number" },
117
234
  "thresholds": { "$ref": "#/$defs/thresholds" },
235
+ "trigger_thresholds": { "$ref": "#/$defs/triggerThresholds" },
236
+ "autovacuum_keepup": { "$ref": "#/$defs/autovacuumKeepup" },
118
237
  "conclusions": { "type": "array", "items": { "type": "string" } },
119
238
  "recommendations": { "type": "array", "items": { "type": "string" } },
120
239
  "database_size_bytes": { "type": "number" },
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
7
7
  grant pg_monitor to {{ROLE_IDENT}};
8
8
  grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
9
9
 
10
+ -- Required for cluster-wide pg_stat_statements collection.
11
+ -- pg_stat_statements is backed by shared memory and holds entries for every database
12
+ -- in the cluster, but a role without pg_read_all_stats sees other users' rows with
13
+ -- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
14
+ -- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
15
+ -- granting it explicitly documents the dependency and keeps the metric working if the
16
+ -- pg_monitor grant above is ever narrowed. Idempotent.
17
+ grant pg_read_all_stats to {{ROLE_IDENT}};
18
+
10
19
  -- Create postgres_ai schema for our objects
11
20
  -- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
12
21
  create schema if not exists postgres_ai;