@kinetica/admin-agent 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.
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: Kinetica CREATE INDEX / DROP INDEX Syntax
3
+ category: sql-syntax
4
+ keywords: [create-index, drop-index, index, ki_indexes, if-not-exists, explain, query-optimization]
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ Kinetica's `CREATE INDEX` syntax differs from standard SQL in two
10
+ places worth flagging up front:
11
+
12
+ 1. The index name is **required** and goes **before** `ON` — there is
13
+ no "unnamed index" form.
14
+ 2. Kinetica does NOT support `IF NOT EXISTS` — you must check
15
+ `ki_catalog.ki_indexes` before creating an index to avoid a
16
+ duplicate-name error.
17
+
18
+ ## Syntax
19
+
20
+ ```sql
21
+ -- Single column:
22
+ CREATE INDEX index_name ON [schema.]table_name (column_name)
23
+
24
+ -- Multiple columns (composite index):
25
+ CREATE INDEX index_name ON [schema.]table_name (col1, col2)
26
+
27
+ -- Drop an index:
28
+ DROP INDEX index_name ON [schema.]table_name
29
+ ```
30
+
31
+ ## Key Rules
32
+
33
+ - **Index name is REQUIRED and goes BEFORE `ON`:**
34
+ - Correct: `CREATE INDEX idx_user_email ON users (email)`
35
+ - WRONG: `CREATE INDEX ON users (email)` — syntax error
36
+ - **No `IF NOT EXISTS`:** Kinetica rejects this clause. Before
37
+ creating an index, query `ki_catalog.ki_indexes` to see whether
38
+ an index already covers the column(s). Skipping this check and
39
+ retrying on failure is wasted work and pollutes audit logs.
40
+ - **Verify with `kinetica_explain_query`:** run
41
+ `kinetica_explain_query` on the target query both BEFORE and AFTER
42
+ index creation. The plan should show the new index being used;
43
+ if it isn't, either the query doesn't benefit from the index or
44
+ the statistics haven't caught up — there is no
45
+ `ANALYZE TABLE` to force stats refresh (see
46
+ `version-quirks-7.2.md`).
47
+ - **Naming convention:** prefer `idx_<table>_<column>` or
48
+ `idx_<table>_<cols>_<purpose>` so index names stay discoverable in
49
+ `ki_catalog.ki_indexes`.
@@ -0,0 +1,106 @@
1
+ ---
2
+ title: ki_tiered_objects Reference
3
+ category: storage
4
+ keywords: [tiered, tier, storage, RAM, PERSIST, DISK, VRAM, eviction, memory pressure]
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ `ki_catalog.ki_tiered_objects` tracks per-chunk tier placement for every data object across all ranks. Each row represents one chunk of data (a column segment, index fragment, etc.) and where it currently lives in the storage hierarchy.
10
+
11
+ **Two ways to check tier placement:**
12
+
13
+ - **`kinetica_resource_objects`** (REST tool) — pre-aggregated per-table view via `/show/resource/objects`. Accepts `table_names` filter. Best for checking a specific table's tier distribution.
14
+ - **`ki_catalog.ki_tiered_objects`** (SQL) — per-chunk granularity. Best for aggregate analysis across all objects, eviction diagnostics, and memory pressure investigation.
15
+
16
+ ## The `id` Column — NOT a Numeric OID
17
+
18
+ **CRITICAL:** `id` is a `char256` string identifier, NOT a numeric OID. Do NOT join with `ki_objects.oid`.
19
+
20
+ Format: `@<table_name>@<internal_id>[<type>][<chunk>]`
21
+ Example: `@nyctaxi@365[col][0]`
22
+
23
+ To filter for a specific table in SQL:
24
+
25
+ ```sql
26
+ WHERE id LIKE '%table_name%'
27
+ ```
28
+
29
+ For structured per-table tier data, prefer `kinetica_resource_objects` with `table_names` filter instead of SQL joins.
30
+
31
+ ## Column Reference
32
+
33
+ | Column | Type | Meaning | Diagnostic Use |
34
+ | ---------------------- | ------- | ------------------------------------------------ | ---------------------------------------------- |
35
+ | `size` | long | Bytes occupied in current tier | Identify large objects consuming tier capacity |
36
+ | `id` | char256 | String object identifier (see above) | Filter by table name via LIKE |
37
+ | `priority` | int | Eviction priority (1=system, 5=user, 9=temp) | Higher priority = evicted last |
38
+ | `tier` | char32 | Current storage tier (RAM, PERSIST, DISK0, VRAM) | Identify what's where |
39
+ | `evictable` | boolean | Tier manager can evict to lower tier | Find non-evictable objects blocking space |
40
+ | `locked` | boolean | Pinned in current tier | Locked objects cannot be evicted |
41
+ | `pin_count` | int | Active reference count | High pin_count = actively used |
42
+ | `ram_evictions` | int | Times evicted from RAM | High count = memory pressure thrashing |
43
+ | `persist_evictions` | int | Times evicted from PERSIST | High count = persist tier pressure |
44
+ | `owner_resource_group` | char128 | Resource group that owns allocation | Tie back to resource group limits |
45
+ | `source_rank` | int | Which rank holds this chunk | Per-rank tier analysis |
46
+ | `outer_object` | char256 | Parent object name (nullable) | Object hierarchy |
47
+
48
+ ## Tier Hierarchy
49
+
50
+ Data flows down when evicted under memory pressure:
51
+
52
+ ```
53
+ VRAM (GPU memory) → RAM (main memory) → PERSIST (permanent storage) → DISK0 (swap cache)
54
+ ```
55
+
56
+ **Priority values determine eviction order** within a tier:
57
+
58
+ - **1** — system tables (`ki_catalog.*`), evicted last
59
+ - **5** — user tables, standard eviction behavior
60
+ - **9** — temporary/ephemeral, evicted first
61
+
62
+ **Eviction semantics:**
63
+
64
+ - `evictable=true` — tier manager can move to a lower tier under pressure
65
+ - `locked=true` — pinned in current tier, will NOT be evicted regardless of pressure
66
+ - When both are false, the object is at rest but not pinned
67
+
68
+ ## Common Diagnostic Queries
69
+
70
+ ```sql
71
+ -- Objects NOT in RAM (potential memory pressure — data has been evicted)
72
+ SELECT id, tier, size, source_rank, owner_resource_group
73
+ FROM ki_catalog.ki_tiered_objects
74
+ WHERE tier != 'VRAM' AND tier != 'RAM'
75
+ ORDER BY size DESC
76
+ LIMIT 20;
77
+
78
+ -- Per-table tier distribution (replace <table_name>)
79
+ SELECT tier, COUNT(*) AS chunks, SUM(size) AS total_bytes
80
+ FROM ki_catalog.ki_tiered_objects
81
+ WHERE id LIKE '%<table_name>%'
82
+ GROUP BY tier;
83
+
84
+ -- Locked objects preventing eviction
85
+ SELECT id, tier, size, source_rank, owner_resource_group
86
+ FROM ki_catalog.ki_tiered_objects
87
+ WHERE locked = 1
88
+ ORDER BY size DESC
89
+ LIMIT 20;
90
+
91
+ -- Objects with high eviction churn (memory pressure indicator)
92
+ SELECT id, tier, size, ram_evictions, persist_evictions, source_rank
93
+ FROM ki_catalog.ki_tiered_objects
94
+ WHERE ram_evictions > 0 OR persist_evictions > 0
95
+ ORDER BY ram_evictions + persist_evictions DESC
96
+ LIMIT 20;
97
+ ```
98
+
99
+ ## Key Gotchas
100
+
101
+ - **Rank 0 has no tiered objects** — it is the head/coordinator node with metadata only. All tiered objects are on worker ranks (1+).
102
+ - **VRAM tier only exists when GPUs are present** — on CPU-only clusters, the highest tier is RAM.
103
+ - **`outer_object` is nullable** — not all objects have a parent; NULL means top-level object.
104
+ - **`source_rank` is dict-encoded** — efficient for filtering/grouping, but values are integers representing rank numbers.
105
+ - **Empty results are normal for small datasets** — if all data fits in RAM, there may be no objects on lower tiers.
106
+ - **`size` is per-chunk, not per-table** — to get total table size in a tier, SUM(size) with a LIKE filter on the table name.
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: Kinetica 7.2.x Version Quirks
3
+ category: version-compat
4
+ keywords:
5
+ [
6
+ 7.2,
7
+ version,
8
+ quirks,
9
+ limitations,
10
+ analyze-table,
11
+ verifydb,
12
+ shard-key,
13
+ ki_tables,
14
+ ki_version,
15
+ rebalance,
16
+ ]
17
+ ---
18
+
19
+ ## Overview
20
+
21
+ Known limitations and non-obvious behaviors of Kinetica 7.2.x that affect
22
+ diagnostic SQL generation, mutation planning, and result interpretation.
23
+ If the agent is about to suggest any of the patterns below, these notes
24
+ override the "obvious" choice.
25
+
26
+ ## Commands NOT Supported
27
+
28
+ - **`ANALYZE TABLE`** — returns a syntax error. Kinetica does not maintain
29
+ cost-based optimizer statistics the way PostgreSQL or Oracle do; query
30
+ planning uses shard/column metadata already tracked by the storage
31
+ layer. Do NOT suggest `ANALYZE TABLE` as remediation for query
32
+ performance problems, and do NOT propose it via
33
+ `kinetica_execute_mutation_sql` — there is no equivalent "refresh table
34
+ stats" command to substitute.
35
+ - **`ALTER TABLE ... SET SHARD KEY`** on existing columns — shard keys are
36
+ immutable once designated at table creation. To change a shard key, the
37
+ table must be dropped and recreated.
38
+
39
+ ## Missing System Tables in 7.2.x
40
+
41
+ Querying either of these returns an `"Object not found"` error. Do NOT
42
+ attempt them — use the replacement instead:
43
+
44
+ - `ki_catalog.ki_tables` — does NOT exist. Use
45
+ `ki_catalog.ki_objects WHERE obj_kind = 'R'` to list tables (see
46
+ `knowledge/references/` for the full `obj_kind` enum).
47
+ - `ki_catalog.ki_version` — does NOT exist. Get the version from
48
+ `kinetica_health_check` or `kinetica_get_system_properties`
49
+ (`version.*` keys). The version is also surfaced as `version` in the
50
+ session context at startup, so you usually don't need to query at
51
+ all.
52
+
53
+ ## `ki_catalog.ki_columns` — Correct Column Names
54
+
55
+ The schema uses these names (not the "obvious" SQL-standard names):
56
+
57
+ | Do NOT use | Correct 7.2.x name |
58
+ | ------------------ | -------------------------------------------------------------------- |
59
+ | `data_type` | `column_type_oid` (long; join to `ki_datatypes.oid` for type name) |
60
+ | `dict_encoding` | `is_dict_encoded` (int flag, 0 or 1) |
61
+ | `compression_type` | `bytes_on_disk_compressed` / `bytes_on_disk_uncompressed` (two cols) |
62
+
63
+ ## Response Sentinel Values
64
+
65
+ - **`/admin/verifydb`** returns `orphaned_tables_total_size: -1` on
66
+ healthy systems — `-1` means "check was not run", NOT "something is
67
+ wrong". Do NOT flag `-1` as a problem in diagnostic reports. A real
68
+ orphan count is a non-negative integer.
69
+
70
+ ## Endpoint Preconditions
71
+
72
+ - **`/admin/rebalance`** requires 2+ worker ranks. Single-worker clusters
73
+ return `"Database must be offline"` — this is expected behavior, not a
74
+ bug, and means rebalance is simply not applicable. Do not suggest
75
+ rebalance on clusters with only rank 0 + one worker.
76
+ - **`/show/table`** accepts only two-part names (`<schema>.<table>`).
77
+ Three-part names like `ki_home.ki_catalog.ki_objects` return a 400
78
+ error. Use `ki_catalog.ki_objects` (two parts).
79
+ - **`/show/table`** with empty `table_name` returns schema-level
80
+ collections with an empty `sizes` array — NOT a list of tables with
81
+ sizes. For a real table listing with sizes, query
82
+ `ki_catalog.ki_objects` via SQL instead.
83
+ - **`/admin/show/logs`** is not implemented on 7.2.x — returns 404
84
+ "Unknown URI". The `kinetica_get_logs` tool falls back to SQL against
85
+ `ki_catalog.ki_log`.
86
+
87
+ ## Default Resource Groups
88
+
89
+ Every 7.2.x install ships with two groups that should not be flagged as
90
+ anomalies:
91
+
92
+ - `kinetica_system_resource_group` — priority 100 (system reserved)
93
+ - `kinetica_default_resource_group` — priority 50 (default user group)
94
+
95
+ `/show/resourcegroups` includes a `max_tier_priority` field per group.
96
+ User-created groups sit between these defaults.
@@ -0,0 +1,57 @@
1
+ # Kinetica Diagnostic Report
2
+
3
+ | Field | Value |
4
+ | --------------------------------- | ----------------------- |
5
+ | **Investigation Date/Time (UTC)** | YYYY-MM-DD HH:MM:SS UTC |
6
+ | **Kinetica Version** | X.Y.Z.W |
7
+ | **Investigation Duration** | N minutes |
8
+ | **Tool Calls** | N |
9
+ | **Rounds** | N |
10
+
11
+ ---
12
+
13
+ ## Summary
14
+
15
+ [1-3 sentence executive summary. State whether the issue was identified and what it is.]
16
+
17
+ ---
18
+
19
+ ## Remediation
20
+
21
+ [Numbered list of specific, actionable remediation steps tied to the identified root cause. Include both immediate manual actions and agent-assisted mutation steps.]
22
+
23
+ ---
24
+
25
+ ## Root Cause Analysis
26
+
27
+ [Named root cause with supporting evidence. Commit to the most likely cause. If multiple hypotheses, rank by likelihood. No generic hedging.]
28
+
29
+ ---
30
+
31
+ ## Evidence Collected
32
+
33
+ [Key findings only — NOT raw tool response dumps. Extract the relevant data points that support your conclusion. Reference which tool provided each finding.]
34
+
35
+ ---
36
+
37
+ ## Evidence Gaps
38
+
39
+ [Any tool calls that failed or returned incomplete data. Include HTTP status codes where available, e.g., "Cluster status: unavailable (HTTP 503)". Write "None" if all tools responded successfully.]
40
+
41
+ ---
42
+
43
+ ## Mutations Applied
44
+
45
+ | Timestamp | Tool | Parameters | Before | After | Approval | Verified |
46
+ | --------- | --------- | ----------- | ------ | ----- | --------------- | -------------------- |
47
+ | HH:MM:SS | tool_name | param=value | old | new | APPROVED/DENIED | confirmed/failed/N/A |
48
+
49
+ Write "None" if no mutations were proposed during this investigation.
50
+
51
+ ---
52
+
53
+ ## Post-Remediation Verification
54
+
55
+ [Summary of Round 5 re-check results. What was confirmed changed. What still shows warning.
56
+ Include specific metric comparisons: "GPU memory reduced from 95% to 78%".
57
+ Write "Not applicable -- no mutations applied" if no mutations were approved.]
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@kinetica/admin-agent",
3
+ "version": "0.1.0",
4
+ "description": "Autonomous diagnostic agent for Kinetica databases",
5
+ "license": "Apache-2.0",
6
+ "author": "Kinetica",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/kineticadb/admin-agent.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/kineticadb/admin-agent/issues"
13
+ },
14
+ "homepage": "https://github.com/kineticadb/admin-agent#readme",
15
+ "keywords": [
16
+ "kinetica",
17
+ "database",
18
+ "diagnostics",
19
+ "agent",
20
+ "dba",
21
+ "ai-agent",
22
+ "claude"
23
+ ],
24
+ "engines": {
25
+ "node": ">=20.20"
26
+ },
27
+ "files": [
28
+ "dist/",
29
+ "knowledge/",
30
+ "LICENSE",
31
+ "NOTICE",
32
+ "README.md"
33
+ ],
34
+ "bin": {
35
+ "admin-agent": "./dist/admin-agent.js"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "postbuild": "chmod +x dist/admin-agent.js",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "test:coverage": "vitest run --coverage",
47
+ "lint": "eslint src",
48
+ "lint:fix": "eslint src --fix",
49
+ "format": "prettier --write .",
50
+ "format:check": "prettier --check .",
51
+ "dev": "tsx src/cli/index.ts",
52
+ "eval": "tsx src/evals/report-format.eval.ts",
53
+ "eval:report-format": "tsx src/evals/report-format.eval.ts",
54
+ "prepublishOnly": "npm run typecheck && npm test && npm run build"
55
+ },
56
+ "dependencies": {
57
+ "@anthropic-ai/claude-agent-sdk": "~0.2.80",
58
+ "@inquirer/prompts": "^8.3.0",
59
+ "picocolors": "^1.1.1",
60
+ "zod": "^4.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@eslint/js": "^10.0.1",
64
+ "@types/node": "^25.3.3",
65
+ "@vitest/coverage-v8": "^4.0.18",
66
+ "eslint": "^10.2.1",
67
+ "eslint-config-prettier": "^10.1.8",
68
+ "globals": "^17.5.0",
69
+ "prettier": "^3.8.3",
70
+ "tsup": "^8.0.0",
71
+ "tsx": "^4.21.0",
72
+ "typescript": "^5.0.0",
73
+ "typescript-eslint": "^8.59.0",
74
+ "vitest": "^4.0.18"
75
+ }
76
+ }