@vfarcic/dot-ai 0.109.0 → 0.111.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/dist/core/ai-provider.interface.d.ts +11 -16
- package/dist/core/ai-provider.interface.d.ts.map +1 -1
- package/dist/core/kubectl-tools.d.ts +66 -0
- package/dist/core/kubectl-tools.d.ts.map +1 -0
- package/dist/core/kubectl-tools.js +473 -0
- package/dist/core/kubernetes-utils.d.ts +1 -0
- package/dist/core/kubernetes-utils.d.ts.map +1 -1
- package/dist/core/kubernetes-utils.js +30 -0
- package/dist/core/providers/anthropic-provider.d.ts +5 -4
- package/dist/core/providers/anthropic-provider.d.ts.map +1 -1
- package/dist/core/providers/anthropic-provider.js +152 -109
- package/dist/core/providers/provider-debug-utils.d.ts +47 -4
- package/dist/core/providers/provider-debug-utils.d.ts.map +1 -1
- package/dist/core/providers/provider-debug-utils.js +67 -7
- package/dist/core/providers/vercel-provider.d.ts +11 -21
- package/dist/core/providers/vercel-provider.d.ts.map +1 -1
- package/dist/core/providers/vercel-provider.js +285 -25
- package/dist/tools/remediate.d.ts +0 -40
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +133 -493
- package/package.json +1 -1
- package/prompts/remediate-system.md +166 -0
- package/scripts/crossplane.nu +29 -57
- package/prompts/remediate-final-analysis.md +0 -243
- package/prompts/remediate-investigation.md +0 -194
|
@@ -18,6 +18,8 @@ export interface AIResponse {
|
|
|
18
18
|
usage: {
|
|
19
19
|
input_tokens: number;
|
|
20
20
|
output_tokens: number;
|
|
21
|
+
cache_creation_input_tokens?: number;
|
|
22
|
+
cache_read_input_tokens?: number;
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
@@ -122,11 +124,19 @@ export interface AgenticResult {
|
|
|
122
124
|
input: any;
|
|
123
125
|
output: any;
|
|
124
126
|
}>;
|
|
125
|
-
/** Token usage statistics */
|
|
127
|
+
/** Token usage statistics including cache metrics */
|
|
126
128
|
totalTokens: {
|
|
127
129
|
input: number;
|
|
128
130
|
output: number;
|
|
131
|
+
cacheCreation?: number;
|
|
132
|
+
cacheRead?: number;
|
|
129
133
|
};
|
|
134
|
+
/** Execution status (PRD #143 Decision 5) */
|
|
135
|
+
status?: 'success' | 'failed' | 'timeout' | 'parse_error';
|
|
136
|
+
/** Reason for loop completion (PRD #143 Decision 5) */
|
|
137
|
+
completionReason?: 'investigation_complete' | 'max_iterations' | 'parse_failure' | 'model_stopped' | 'error';
|
|
138
|
+
/** Specific model version used (PRD #143 Decision 5) */
|
|
139
|
+
modelVersion?: string;
|
|
130
140
|
}
|
|
131
141
|
/**
|
|
132
142
|
* AI Provider Interface
|
|
@@ -189,20 +199,5 @@ export interface AIProvider {
|
|
|
189
199
|
* @returns Agentic result with final message, iterations, tool calls, and token usage
|
|
190
200
|
*/
|
|
191
201
|
toolLoop(config: ToolLoopConfig): Promise<AgenticResult>;
|
|
192
|
-
/**
|
|
193
|
-
* Single-shot message with tool calling enabled (NEW - PRD #136)
|
|
194
|
-
*
|
|
195
|
-
* AI can call tools, but only processes one round.
|
|
196
|
-
* Useful for simple tool use cases that don't require iteration.
|
|
197
|
-
*
|
|
198
|
-
* @param message The message/prompt to send
|
|
199
|
-
* @param tools Available tools for this request
|
|
200
|
-
* @param toolExecutor Function to execute tool calls
|
|
201
|
-
* @param operation Optional operation identifier for debugging
|
|
202
|
-
* @returns AI response with content, usage, and any tool calls made
|
|
203
|
-
*/
|
|
204
|
-
sendMessageWithTools(message: string, tools: AITool[], toolExecutor: ToolExecutor, operation?: string): Promise<AIResponse & {
|
|
205
|
-
toolCalls?: any[];
|
|
206
|
-
}>;
|
|
207
202
|
}
|
|
208
203
|
//# sourceMappingURL=ai-provider.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-provider.interface.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-provider.interface.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubectl Tools for AI-Powered Investigation
|
|
3
|
+
*
|
|
4
|
+
* Shared tool definitions and executor for kubectl operations.
|
|
5
|
+
* Used by remediation, diagnostics, and other investigation workflows.
|
|
6
|
+
*
|
|
7
|
+
* PRD #143: Tool-Based Remediation with Observability Data Sources
|
|
8
|
+
*/
|
|
9
|
+
import { AITool } from './ai-provider.interface';
|
|
10
|
+
/**
|
|
11
|
+
* Tool: kubectl_api_resources
|
|
12
|
+
* Get list of all available Kubernetes API resources in the cluster
|
|
13
|
+
*/
|
|
14
|
+
export declare const KUBECTL_API_RESOURCES_TOOL: AITool;
|
|
15
|
+
/**
|
|
16
|
+
* Tool: kubectl_get
|
|
17
|
+
* Get Kubernetes resources with their current state
|
|
18
|
+
*/
|
|
19
|
+
export declare const KUBECTL_GET_TOOL: AITool;
|
|
20
|
+
/**
|
|
21
|
+
* Tool: kubectl_describe
|
|
22
|
+
* Get detailed information about Kubernetes resources
|
|
23
|
+
*/
|
|
24
|
+
export declare const KUBECTL_DESCRIBE_TOOL: AITool;
|
|
25
|
+
/**
|
|
26
|
+
* Tool: kubectl_logs
|
|
27
|
+
* Get container logs from pods
|
|
28
|
+
*/
|
|
29
|
+
export declare const KUBECTL_LOGS_TOOL: AITool;
|
|
30
|
+
/**
|
|
31
|
+
* Tool: kubectl_events
|
|
32
|
+
* Get Kubernetes events for troubleshooting
|
|
33
|
+
*/
|
|
34
|
+
export declare const KUBECTL_EVENTS_TOOL: AITool;
|
|
35
|
+
/**
|
|
36
|
+
* Tool: kubectl_patch_dryrun
|
|
37
|
+
* Validate patch commands with dry-run before execution
|
|
38
|
+
*/
|
|
39
|
+
export declare const KUBECTL_PATCH_DRYRUN_TOOL: AITool;
|
|
40
|
+
/**
|
|
41
|
+
* Tool: kubectl_apply_dryrun
|
|
42
|
+
* Validate apply commands with dry-run before execution
|
|
43
|
+
*/
|
|
44
|
+
export declare const KUBECTL_APPLY_DRYRUN_TOOL: AITool;
|
|
45
|
+
/**
|
|
46
|
+
* Tool: kubectl_delete_dryrun
|
|
47
|
+
* Validate delete commands with dry-run before execution
|
|
48
|
+
*/
|
|
49
|
+
export declare const KUBECTL_DELETE_DRYRUN_TOOL: AITool;
|
|
50
|
+
/**
|
|
51
|
+
* Tool: kubectl_get_crd_schema
|
|
52
|
+
* Get the OpenAPI v3 schema for a Custom Resource Definition
|
|
53
|
+
*/
|
|
54
|
+
export declare const KUBECTL_GET_CRD_SCHEMA_TOOL: AITool;
|
|
55
|
+
/**
|
|
56
|
+
* Tool executor for kubectl-based tools
|
|
57
|
+
* Handles execution and error handling for all kubectl tool calls
|
|
58
|
+
*/
|
|
59
|
+
export declare function executeKubectlTools(toolName: string, input: any): Promise<any>;
|
|
60
|
+
/**
|
|
61
|
+
* All kubectl investigation tools (read-only operations + dry-run validation)
|
|
62
|
+
* Used during investigation phase for gathering cluster state information and validating solutions
|
|
63
|
+
* Convenient array for passing to toolLoop()
|
|
64
|
+
*/
|
|
65
|
+
export declare const KUBECTL_INVESTIGATION_TOOLS: AITool[];
|
|
66
|
+
//# sourceMappingURL=kubectl-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kubectl-tools.d.ts","sourceRoot":"","sources":["../../src/core/kubectl-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAQxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAsB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAiBnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAsB/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAkBjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAyBvC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAiBvC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAiBxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAazC,CAAC;AAEF;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAsRpF;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,EAU/C,CAAC"}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Kubectl Tools for AI-Powered Investigation
|
|
4
|
+
*
|
|
5
|
+
* Shared tool definitions and executor for kubectl operations.
|
|
6
|
+
* Used by remediation, diagnostics, and other investigation workflows.
|
|
7
|
+
*
|
|
8
|
+
* PRD #143: Tool-Based Remediation with Observability Data Sources
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.KUBECTL_INVESTIGATION_TOOLS = exports.KUBECTL_GET_CRD_SCHEMA_TOOL = exports.KUBECTL_DELETE_DRYRUN_TOOL = exports.KUBECTL_APPLY_DRYRUN_TOOL = exports.KUBECTL_PATCH_DRYRUN_TOOL = exports.KUBECTL_EVENTS_TOOL = exports.KUBECTL_LOGS_TOOL = exports.KUBECTL_DESCRIBE_TOOL = exports.KUBECTL_GET_TOOL = exports.KUBECTL_API_RESOURCES_TOOL = void 0;
|
|
12
|
+
exports.executeKubectlTools = executeKubectlTools;
|
|
13
|
+
const kubernetes_utils_1 = require("./kubernetes-utils");
|
|
14
|
+
/**
|
|
15
|
+
* Tool: kubectl_api_resources
|
|
16
|
+
* Get list of all available Kubernetes API resources in the cluster
|
|
17
|
+
*/
|
|
18
|
+
exports.KUBECTL_API_RESOURCES_TOOL = {
|
|
19
|
+
name: 'kubectl_api_resources',
|
|
20
|
+
description: 'Get list of all available Kubernetes API resources in the cluster (resource types, API groups, namespaced vs cluster-scoped). Use this to discover what resources are available before querying specific resources. Essential for understanding what can be investigated in this cluster.',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {},
|
|
24
|
+
required: []
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Tool: kubectl_get
|
|
29
|
+
* Get Kubernetes resources with their current state
|
|
30
|
+
*/
|
|
31
|
+
exports.KUBECTL_GET_TOOL = {
|
|
32
|
+
name: 'kubectl_get',
|
|
33
|
+
description: 'Get Kubernetes resources and their current state in TABLE FORMAT (most efficient). Returns compact table with NAME, STATUS, READY, AGE columns. Use this to list resources and check basic status. For detailed information, use kubectl_describe instead. IMPORTANT: Always returns table format - output format flags like -o=yaml or -o=json are automatically stripped.',
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
resource: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Resource type to get (e.g., "pods", "deployments", "services", "pod/my-pod", "clusters.postgresql.cnpg.io"). Can be plural (pods) or singular with name (pod/name). Can include API group for custom resources.'
|
|
40
|
+
},
|
|
41
|
+
namespace: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: 'Kubernetes namespace to query. Omit for cluster-scoped resources or to query all namespaces.'
|
|
44
|
+
},
|
|
45
|
+
args: {
|
|
46
|
+
type: 'array',
|
|
47
|
+
items: { type: 'string' },
|
|
48
|
+
description: 'Filtering arguments only (e.g., ["--selector=app=myapp"], ["--field-selector=status.phase=Running"], ["--all-namespaces"], ["--show-labels"]). Output format flags (-o=yaml, -o=json, etc.) are NOT allowed and will be automatically stripped.'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
required: ['resource']
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Tool: kubectl_describe
|
|
56
|
+
* Get detailed information about Kubernetes resources
|
|
57
|
+
*/
|
|
58
|
+
exports.KUBECTL_DESCRIBE_TOOL = {
|
|
59
|
+
name: 'kubectl_describe',
|
|
60
|
+
description: 'Get detailed information about specific Kubernetes resources including configuration, status, events, and relationships. Use this when you need comprehensive details about a specific resource, especially to understand configuration issues or see recent events related to that resource.',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
resource: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'Resource to describe (e.g., "pod/my-pod", "deployment/my-app", "cluster/postgres-db"). Should include the resource name.'
|
|
67
|
+
},
|
|
68
|
+
namespace: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Kubernetes namespace. Required for namespaced resources.'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
required: ['resource']
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Tool: kubectl_logs
|
|
78
|
+
* Get container logs from pods
|
|
79
|
+
*/
|
|
80
|
+
exports.KUBECTL_LOGS_TOOL = {
|
|
81
|
+
name: 'kubectl_logs',
|
|
82
|
+
description: 'Get container logs from pods. Essential for debugging application crashes, errors, and understanding runtime behavior. Use --previous flag to get logs from crashed/restarted containers.',
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
resource: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
description: 'Pod name to get logs from (e.g., "my-pod" or "pod/my-pod").'
|
|
89
|
+
},
|
|
90
|
+
namespace: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
description: 'Kubernetes namespace where the pod is running.'
|
|
93
|
+
},
|
|
94
|
+
args: {
|
|
95
|
+
type: 'array',
|
|
96
|
+
items: { type: 'string' },
|
|
97
|
+
description: 'Additional log arguments (e.g., ["--previous"] for crashed container logs, ["--tail=50"] to limit output, ["--since=5m"] for recent logs, ["-c", "container-name"] for specific container).'
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
required: ['resource', 'namespace']
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Tool: kubectl_events
|
|
105
|
+
* Get Kubernetes events for troubleshooting
|
|
106
|
+
*/
|
|
107
|
+
exports.KUBECTL_EVENTS_TOOL = {
|
|
108
|
+
name: 'kubectl_events',
|
|
109
|
+
description: 'Get Kubernetes events which record important state changes, errors, warnings, and informational messages from the cluster. Essential for understanding scheduling issues, resource problems, configuration errors, and system-level events affecting resources.',
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
namespace: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Kubernetes namespace to get events from. Omit for cluster-wide events.'
|
|
116
|
+
},
|
|
117
|
+
args: {
|
|
118
|
+
type: 'array',
|
|
119
|
+
items: { type: 'string' },
|
|
120
|
+
description: 'Additional event arguments (e.g., ["--sort-by=.lastTimestamp"] to sort by time, ["--field-selector=involvedObject.name=my-pod"] to filter by resource, ["--since=10m"] for recent events).'
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
required: []
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Tool: kubectl_patch_dryrun
|
|
128
|
+
* Validate patch commands with dry-run before execution
|
|
129
|
+
*/
|
|
130
|
+
exports.KUBECTL_PATCH_DRYRUN_TOOL = {
|
|
131
|
+
name: 'kubectl_patch_dryrun',
|
|
132
|
+
description: 'Validate that a kubectl patch command will be accepted by the cluster without actually applying it. Use this to test your proposed remediation patches before completing investigation. Essential for confirming command syntax and cluster acceptance.',
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
resource: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'Resource to patch (e.g., "deployment/my-app", "cluster/postgres-db"). Must include resource type and name.'
|
|
139
|
+
},
|
|
140
|
+
namespace: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
description: 'Kubernetes namespace. Required for namespaced resources.'
|
|
143
|
+
},
|
|
144
|
+
patch: {
|
|
145
|
+
type: 'string',
|
|
146
|
+
description: 'The patch content in JSON format (e.g., \'{"spec":{"replicas":3}}\')'
|
|
147
|
+
},
|
|
148
|
+
patchType: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
description: 'Type of patch: "strategic" (default), "merge", or "json". Use "json" for JSON Patch operations.'
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
required: ['resource', 'patch']
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Tool: kubectl_apply_dryrun
|
|
158
|
+
* Validate apply commands with dry-run before execution
|
|
159
|
+
*/
|
|
160
|
+
exports.KUBECTL_APPLY_DRYRUN_TOOL = {
|
|
161
|
+
name: 'kubectl_apply_dryrun',
|
|
162
|
+
description: 'Validate that a kubectl apply command will be accepted by the cluster without actually applying it. Use this to test applying YAML manifests or configuration changes before completing investigation.',
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: 'object',
|
|
165
|
+
properties: {
|
|
166
|
+
manifest: {
|
|
167
|
+
type: 'string',
|
|
168
|
+
description: 'The YAML manifest content to apply'
|
|
169
|
+
},
|
|
170
|
+
namespace: {
|
|
171
|
+
type: 'string',
|
|
172
|
+
description: 'Kubernetes namespace for the resource. Omit for cluster-scoped resources or if namespace is specified in manifest.'
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
required: ['manifest']
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Tool: kubectl_delete_dryrun
|
|
180
|
+
* Validate delete commands with dry-run before execution
|
|
181
|
+
*/
|
|
182
|
+
exports.KUBECTL_DELETE_DRYRUN_TOOL = {
|
|
183
|
+
name: 'kubectl_delete_dryrun',
|
|
184
|
+
description: 'Validate that a kubectl delete command will be accepted by the cluster without actually deleting resources. Use this to test resource deletion before completing investigation.',
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: 'object',
|
|
187
|
+
properties: {
|
|
188
|
+
resource: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
description: 'Resource to delete (e.g., "pod/my-pod", "deployment/my-app", "configmap/my-config")'
|
|
191
|
+
},
|
|
192
|
+
namespace: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
description: 'Kubernetes namespace. Required for namespaced resources.'
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
required: ['resource']
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Tool: kubectl_get_crd_schema
|
|
202
|
+
* Get the OpenAPI v3 schema for a Custom Resource Definition
|
|
203
|
+
*/
|
|
204
|
+
exports.KUBECTL_GET_CRD_SCHEMA_TOOL = {
|
|
205
|
+
name: 'kubectl_get_crd_schema',
|
|
206
|
+
description: 'Get the OpenAPI v3 schema for a Custom Resource Definition (CRD). Use this to understand the structure, required fields, validation rules, and available properties when crafting patches or configurations for custom resources like CNPG clusters, Crossplane resources, ArgoCD applications, etc.',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
crdName: {
|
|
211
|
+
type: 'string',
|
|
212
|
+
description: 'Full CRD name including API group (e.g., "clusters.postgresql.cnpg.io", "compositions.apiextensions.crossplane.io", "applications.argoproj.io"). Use kubectl_api_resources to discover available CRDs.'
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
required: ['crdName']
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Tool executor for kubectl-based tools
|
|
220
|
+
* Handles execution and error handling for all kubectl tool calls
|
|
221
|
+
*/
|
|
222
|
+
async function executeKubectlTools(toolName, input) {
|
|
223
|
+
try {
|
|
224
|
+
switch (toolName) {
|
|
225
|
+
case 'kubectl_api_resources': {
|
|
226
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(['api-resources']);
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
data: output,
|
|
230
|
+
message: 'Successfully retrieved cluster API resources'
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
case 'kubectl_get': {
|
|
234
|
+
const { resource, namespace, args = [] } = input;
|
|
235
|
+
if (!resource) {
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
error: 'Missing required parameter: resource',
|
|
239
|
+
message: 'kubectl_get requires a resource parameter'
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// Build kubectl command
|
|
243
|
+
const cmdArgs = ['get', resource];
|
|
244
|
+
// Add namespace if provided
|
|
245
|
+
if (namespace) {
|
|
246
|
+
cmdArgs.push('-n', namespace);
|
|
247
|
+
}
|
|
248
|
+
// Strip output format args - we always return table format for efficiency
|
|
249
|
+
// Allow filtering args like --selector, --field-selector, --all-namespaces, --show-labels
|
|
250
|
+
if (args && Array.isArray(args)) {
|
|
251
|
+
const filteredArgs = args.filter(arg => {
|
|
252
|
+
const argLower = arg.toLowerCase();
|
|
253
|
+
// Block any output format flags
|
|
254
|
+
return !argLower.startsWith('-o=') &&
|
|
255
|
+
!argLower.startsWith('-o') &&
|
|
256
|
+
!argLower.startsWith('--output') &&
|
|
257
|
+
!argLower.includes('=json') &&
|
|
258
|
+
!argLower.includes('=yaml');
|
|
259
|
+
});
|
|
260
|
+
cmdArgs.push(...filteredArgs);
|
|
261
|
+
}
|
|
262
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
263
|
+
return {
|
|
264
|
+
success: true,
|
|
265
|
+
data: output,
|
|
266
|
+
message: `Successfully retrieved ${resource}${namespace ? ` in namespace ${namespace}` : ''}`
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
case 'kubectl_describe': {
|
|
270
|
+
const { resource, namespace } = input;
|
|
271
|
+
if (!resource) {
|
|
272
|
+
return {
|
|
273
|
+
success: false,
|
|
274
|
+
error: 'Missing required parameter: resource',
|
|
275
|
+
message: 'kubectl_describe requires a resource parameter'
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// Build kubectl command
|
|
279
|
+
const cmdArgs = ['describe', resource];
|
|
280
|
+
// Add namespace if provided
|
|
281
|
+
if (namespace) {
|
|
282
|
+
cmdArgs.push('-n', namespace);
|
|
283
|
+
}
|
|
284
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
285
|
+
return {
|
|
286
|
+
success: true,
|
|
287
|
+
data: output,
|
|
288
|
+
message: `Successfully described ${resource}${namespace ? ` in namespace ${namespace}` : ''}`
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
case 'kubectl_logs': {
|
|
292
|
+
const { resource, namespace, args = [] } = input;
|
|
293
|
+
if (!resource) {
|
|
294
|
+
return {
|
|
295
|
+
success: false,
|
|
296
|
+
error: 'Missing required parameter: resource',
|
|
297
|
+
message: 'kubectl_logs requires a resource parameter'
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
if (!namespace) {
|
|
301
|
+
return {
|
|
302
|
+
success: false,
|
|
303
|
+
error: 'Missing required parameter: namespace',
|
|
304
|
+
message: 'kubectl_logs requires a namespace parameter'
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// Build kubectl command
|
|
308
|
+
const cmdArgs = ['logs', resource, '-n', namespace];
|
|
309
|
+
// Add additional arguments
|
|
310
|
+
if (args && Array.isArray(args)) {
|
|
311
|
+
cmdArgs.push(...args);
|
|
312
|
+
}
|
|
313
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
314
|
+
return {
|
|
315
|
+
success: true,
|
|
316
|
+
data: output,
|
|
317
|
+
message: `Successfully retrieved logs for ${resource} in namespace ${namespace}`
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
case 'kubectl_events': {
|
|
321
|
+
const { namespace, args = [] } = input;
|
|
322
|
+
// Build kubectl command
|
|
323
|
+
const cmdArgs = ['get', 'events'];
|
|
324
|
+
// Add namespace if provided
|
|
325
|
+
if (namespace) {
|
|
326
|
+
cmdArgs.push('-n', namespace);
|
|
327
|
+
}
|
|
328
|
+
// Add additional arguments
|
|
329
|
+
if (args && Array.isArray(args)) {
|
|
330
|
+
cmdArgs.push(...args);
|
|
331
|
+
}
|
|
332
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
333
|
+
return {
|
|
334
|
+
success: true,
|
|
335
|
+
data: output,
|
|
336
|
+
message: `Successfully retrieved events${namespace ? ` in namespace ${namespace}` : ' (cluster-wide)'}`
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
case 'kubectl_patch_dryrun': {
|
|
340
|
+
const { resource, namespace, patch, patchType = 'strategic' } = input;
|
|
341
|
+
if (!resource) {
|
|
342
|
+
return {
|
|
343
|
+
success: false,
|
|
344
|
+
error: 'Missing required parameter: resource',
|
|
345
|
+
message: 'kubectl_patch_dryrun requires a resource parameter'
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (!patch) {
|
|
349
|
+
return {
|
|
350
|
+
success: false,
|
|
351
|
+
error: 'Missing required parameter: patch',
|
|
352
|
+
message: 'kubectl_patch_dryrun requires a patch parameter'
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
// Build kubectl command
|
|
356
|
+
const cmdArgs = ['patch', resource, '--dry-run=server'];
|
|
357
|
+
// Add namespace if provided
|
|
358
|
+
if (namespace) {
|
|
359
|
+
cmdArgs.push('-n', namespace);
|
|
360
|
+
}
|
|
361
|
+
// Add patch type
|
|
362
|
+
if (patchType === 'json') {
|
|
363
|
+
cmdArgs.push('--type=json');
|
|
364
|
+
}
|
|
365
|
+
else if (patchType === 'merge') {
|
|
366
|
+
cmdArgs.push('--type=merge');
|
|
367
|
+
}
|
|
368
|
+
// strategic is default, no flag needed
|
|
369
|
+
// Add patch content
|
|
370
|
+
cmdArgs.push('-p', patch);
|
|
371
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
372
|
+
return {
|
|
373
|
+
success: true,
|
|
374
|
+
data: output,
|
|
375
|
+
message: `Dry-run validation successful for patch on ${resource}${namespace ? ` in namespace ${namespace}` : ''}`
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
case 'kubectl_apply_dryrun': {
|
|
379
|
+
const { manifest, namespace } = input;
|
|
380
|
+
if (!manifest) {
|
|
381
|
+
return {
|
|
382
|
+
success: false,
|
|
383
|
+
error: 'Missing required parameter: manifest',
|
|
384
|
+
message: 'kubectl_apply_dryrun requires a manifest parameter'
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
// Build kubectl command
|
|
388
|
+
const cmdArgs = ['apply', '--dry-run=server', '-f', '-'];
|
|
389
|
+
// Add namespace if provided
|
|
390
|
+
if (namespace) {
|
|
391
|
+
cmdArgs.push('-n', namespace);
|
|
392
|
+
}
|
|
393
|
+
// Execute with manifest as stdin
|
|
394
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs, { stdin: manifest });
|
|
395
|
+
return {
|
|
396
|
+
success: true,
|
|
397
|
+
data: output,
|
|
398
|
+
message: `Dry-run validation successful for apply${namespace ? ` in namespace ${namespace}` : ''}`
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
case 'kubectl_delete_dryrun': {
|
|
402
|
+
const { resource, namespace } = input;
|
|
403
|
+
if (!resource) {
|
|
404
|
+
return {
|
|
405
|
+
success: false,
|
|
406
|
+
error: 'Missing required parameter: resource',
|
|
407
|
+
message: 'kubectl_delete_dryrun requires a resource parameter'
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
// Build kubectl command
|
|
411
|
+
const cmdArgs = ['delete', resource, '--dry-run=server'];
|
|
412
|
+
// Add namespace if provided
|
|
413
|
+
if (namespace) {
|
|
414
|
+
cmdArgs.push('-n', namespace);
|
|
415
|
+
}
|
|
416
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
417
|
+
return {
|
|
418
|
+
success: true,
|
|
419
|
+
data: output,
|
|
420
|
+
message: `Dry-run validation successful for delete on ${resource}${namespace ? ` in namespace ${namespace}` : ''}`
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
case 'kubectl_get_crd_schema': {
|
|
424
|
+
const { crdName } = input;
|
|
425
|
+
if (!crdName) {
|
|
426
|
+
return {
|
|
427
|
+
success: false,
|
|
428
|
+
error: 'Missing required parameter: crdName',
|
|
429
|
+
message: 'kubectl_get_crd_schema requires a crdName parameter (e.g., "clusters.postgresql.cnpg.io")'
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
// Get CRD definition in JSON format - AI can parse what it needs
|
|
433
|
+
const cmdArgs = ['get', 'crd', crdName, '-o', 'json'];
|
|
434
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(cmdArgs);
|
|
435
|
+
return {
|
|
436
|
+
success: true,
|
|
437
|
+
data: output,
|
|
438
|
+
message: `Successfully retrieved CRD schema for ${crdName}`
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
default:
|
|
442
|
+
return {
|
|
443
|
+
success: false,
|
|
444
|
+
error: `Unknown kubectl tool: ${toolName}`,
|
|
445
|
+
message: `Tool '${toolName}' is not implemented`
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
451
|
+
return {
|
|
452
|
+
success: false,
|
|
453
|
+
error: errorMessage,
|
|
454
|
+
message: `Failed to execute ${toolName}: ${errorMessage}`
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* All kubectl investigation tools (read-only operations + dry-run validation)
|
|
460
|
+
* Used during investigation phase for gathering cluster state information and validating solutions
|
|
461
|
+
* Convenient array for passing to toolLoop()
|
|
462
|
+
*/
|
|
463
|
+
exports.KUBECTL_INVESTIGATION_TOOLS = [
|
|
464
|
+
exports.KUBECTL_API_RESOURCES_TOOL,
|
|
465
|
+
exports.KUBECTL_GET_TOOL,
|
|
466
|
+
exports.KUBECTL_DESCRIBE_TOOL,
|
|
467
|
+
exports.KUBECTL_LOGS_TOOL,
|
|
468
|
+
exports.KUBECTL_EVENTS_TOOL,
|
|
469
|
+
exports.KUBECTL_PATCH_DRYRUN_TOOL,
|
|
470
|
+
exports.KUBECTL_APPLY_DRYRUN_TOOL,
|
|
471
|
+
exports.KUBECTL_DELETE_DRYRUN_TOOL,
|
|
472
|
+
exports.KUBECTL_GET_CRD_SCHEMA_TOOL
|
|
473
|
+
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kubernetes-utils.d.ts","sourceRoot":"","sources":["../../src/core/kubernetes-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"kubernetes-utils.d.ts","sourceRoot":"","sources":["../../src/core/kubernetes-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAuD5F;AAsBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,CAmBlF;AAGD,qBAAa,eAAe;IAC1B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;IA0D7E,OAAO,CAAC,MAAM,CAAC,cAAc;IAa7B,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAYpC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAInC,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAIrC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAMhC,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAI1C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAYlC,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAgBzC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAYxC,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAQ1C,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAYrC,OAAO,CAAC,MAAM,CAAC,gCAAgC;CAGhD"}
|
|
@@ -18,6 +18,36 @@ async function executeKubectl(args, config) {
|
|
|
18
18
|
const command = buildKubectlCommand(args, config);
|
|
19
19
|
const timeout = config?.timeout || 30000;
|
|
20
20
|
try {
|
|
21
|
+
// If stdin is provided, use spawn for proper stdin piping
|
|
22
|
+
if (config?.stdin) {
|
|
23
|
+
const { spawn } = require('child_process');
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
let stdout = '';
|
|
26
|
+
let stderr = '';
|
|
27
|
+
const proc = spawn('sh', ['-c', command], {
|
|
28
|
+
timeout,
|
|
29
|
+
maxBuffer: 100 * 1024 * 1024
|
|
30
|
+
});
|
|
31
|
+
proc.stdout.on('data', (data) => { stdout += data.toString(); });
|
|
32
|
+
proc.stderr.on('data', (data) => { stderr += data.toString(); });
|
|
33
|
+
proc.on('error', (error) => reject(error));
|
|
34
|
+
proc.on('close', (code) => {
|
|
35
|
+
if (code !== 0) {
|
|
36
|
+
reject(new Error(`kubectl command failed: ${stderr || stdout}`));
|
|
37
|
+
}
|
|
38
|
+
else if (stderr && !stderr.includes('Warning')) {
|
|
39
|
+
reject(new Error(`kubectl command failed: ${stderr}`));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
resolve(stdout.trim());
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Write stdin and close
|
|
46
|
+
proc.stdin.write(config.stdin);
|
|
47
|
+
proc.stdin.end();
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// No stdin - use regular execAsync
|
|
21
51
|
const { stdout, stderr } = await execAsync(command, {
|
|
22
52
|
timeout,
|
|
23
53
|
maxBuffer: 100 * 1024 * 1024 // 100MB buffer for large clusters with 1000+ CRDs
|