diff --git a/.gitignore b/.gitignore
index 73484b0..4ab4db1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ front/next-env.d.ts
# Golang
output
+.idea
diff --git a/README.md b/README.md
index 1c97ef3..4cd6ebb 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Observātiō
+# Observātiō - Smart ClusterAPI Troubleshoot Platform
[](https://github.com/knabben/observatio/actions/workflows/build.yml)
@@ -13,7 +13,11 @@ the project enables users to swiftly identify and address issues, improving oper
This solution empowers organizations to maintain optimal cluster functionality, streamline troubleshooting efforts,
and ensure robust management of their cloud-native environments.
-## Development
+
+
+
+
+## Production
### Prerequisites
@@ -21,6 +25,19 @@ and ensure robust management of their cloud-native environments.
- Node.js and pnpm
- Linux and Make
+### Build and run
+
+Ensure your management cluster is accessible via `${HOME}/.kube/config` compile the bundled frontend in the go binary
+and run the server.
+
+```bash
+make build && ./output/observatio serve
+```
+
+Both API and frontend are accessible via port TCP 8080.
+
+## Development
+
### Backend Setup
1. Install backend dependencies:
diff --git a/front/app/ui/dashboard/components/clusters/infra/infra-details.tsx b/front/app/ui/dashboard/components/clusters/infra/infra-details.tsx
index 2e5ec7c..e957305 100644
--- a/front/app/ui/dashboard/components/clusters/infra/infra-details.tsx
+++ b/front/app/ui/dashboard/components/clusters/infra/infra-details.tsx
@@ -22,7 +22,12 @@ export default function ClusterInfraDetails({
},
{
label: "AI Troubleshooting",
- content: (cluster: ClusterInfraType) =>
+ content: (cluster: ClusterInfraType) =>
}];
const headerRender = (cluster: ClusterInfraType) => (
diff --git a/front/app/ui/dashboard/components/mds/details.tsx b/front/app/ui/dashboard/components/mds/details.tsx
index 1a8b058..01b76fa 100644
--- a/front/app/ui/dashboard/components/mds/details.tsx
+++ b/front/app/ui/dashboard/components/mds/details.tsx
@@ -19,7 +19,11 @@ export default function MachineDeploymentDetails({
},
{
label: "AI Troubleshooting",
- content: (md: MachineDeploymentType) =>
+ content: (md: MachineDeploymentType) =>
}
];
const headerRender = (md: MachineDeploymentType) => (
diff --git a/front/public/screen.png b/front/public/screen.png
new file mode 100755
index 0000000..c351c27
Binary files /dev/null and b/front/public/screen.png differ
diff --git a/webserver/internal/infra/llm/messages.go b/webserver/internal/infra/llm/messages.go
index ff113f7..5e160c3 100644
--- a/webserver/internal/infra/llm/messages.go
+++ b/webserver/internal/infra/llm/messages.go
@@ -7,9 +7,17 @@ import (
)
var (
- TASK_SYSTEM = `You will serve as a Kubernetes administrator managing a on-premises datacenter on VMware vCenter.`
- TASK_CONTEXT = `Your task is to assist operators in troubleshooting issues within the cluster.
-Provide a detailed explanation of the issue. New inputs are provided and you must respond accordingly the context`
+ TASK_SYSTEM = `You will serve as a Cluster API advisor helping troubleshoot on-premises Kubernetes on VMware vCenter infrastructure.`
+ TASK_CONTEXT = `You are Observatio AI, an advanced Kubernetes cluster troubleshooting assistant specialized in ClusterAPI (CAPI) environments.
+You are part of a sophisticated monitoring platform that revolutionizes Kubernetes cluster assessment through data aggregation, MCP server integration, and AI-powered remediation.
+Provide expert-level Kubernetes troubleshooting, root cause analysis, and automated remediation for DevOps teams managing distributed CAPI clusters.
+You excel at translating complex cluster issues into actionable solutions. Your task is to assist operators in troubleshooting issues within the cluster.
+
+When you receive a customer question, you must respond with a detailed DESCRIPTION of the issue, under tag, ALWAYS.
+If you have suggestions for fixing the issue or improvements, you can also include them under tag.
+
+You only run available tools when request to increase the context of the issue.
+`
)
// MessageTemplate defines the structure for formatting error messages
diff --git a/webserver/internal/infra/llm/observation.go b/webserver/internal/infra/llm/observation.go
index eea3421..3c75a47 100644
--- a/webserver/internal/infra/llm/observation.go
+++ b/webserver/internal/infra/llm/observation.go
@@ -40,10 +40,15 @@ func NewObservationService() (*ObservationService, error) {
return service, nil
}
+// ChatWithAgent facilitates a conversation between a user and an AI agent by managing message history and API interactions.
func (s *ObservationService) ChatWithAgent(ctx context.Context, message *ChatMessage) (*ChatMessage, error) {
logger := log.FromContext(ctx)
- s.conversationManager.AddUserMessage(formatMessage(message.Content))
+ userMessage := message.Content
+ if s.conversationManager.GetHistoryLength() == 0 {
+ userMessage = formatMessage(userMessage)
+ }
+ s.conversationManager.AddUserMessage(userMessage)
var historyLength = s.conversationManager.GetHistoryLength()
if historyLength > 0 {
@@ -60,14 +65,17 @@ func (s *ObservationService) ChatWithAgent(ctx context.Context, message *ChatMes
return nil, fmt.Errorf("claude API response format error: %v", err)
}
- if len(response.Content) > 0 {
- logger.Info("Parsed response from Claude", "response", parsedResponse)
- s.conversationManager.AddAssistantMessage(parsedResponse)
- s.conversationManager.TrimHistory()
+ if len(response.Content) == 0 {
+ return ToMessageParam("Bot error, try again."), nil
}
+
+ logger.Info("Parsed response from Claude", "response", parsedResponse)
+ s.conversationManager.AddAssistantMessage(parsedResponse)
+ s.conversationManager.TrimHistory()
return ToMessageParam(parsedResponse), nil
}
+// requestAgent sends a request to the Anthropic API with specified messages and returns the API response or an error.
func (s *ObservationService) requestAgent(ctx context.Context, messages []anthropic.MessageParam) (*anthropic.Message, error) {
request := anthropic.MessageNewParams{
Model: anthropic.ModelClaude3_7SonnetLatest,
@@ -82,6 +90,8 @@ func (s *ObservationService) requestAgent(ctx context.Context, messages []anthro
return s.anthropicClient.Messages.New(ctx, request)
}
+// responseAgent processes the response content from the Anthropic API and constructs a formatted string combining text and tool outputs.
+// It handles text blocks and tool-use blocks, extracting detailed outputs as necessary. Returns the formatted response or an error.
func (s *ObservationService) responseAgent(response *anthropic.Message) (string, error) {
var (
responseText string
@@ -108,13 +118,18 @@ func (s *ObservationService) responseAgent(response *anthropic.Message) (string,
if err != nil {
return "", err
}
+ responseText += fmt.Sprintf("\n\nkubectl %s\n", input.Command)
toolResults = append(toolResults, toolResponse.(string))
}
}
}
if len(toolResults) > 0 {
- responseText += "\n\nTool Results:\n" + fmt.Sprintf("%v", toolResults)
+ responseText += "\n"
+ for _, toolResult := range toolResults {
+ responseText += fmt.Sprintf("%s
", toolResult)
+ }
+ responseText += ""
}
return responseText, nil
diff --git a/webserver/internal/web/handlers/system/ws_client.go b/webserver/internal/web/handlers/system/ws_client.go
index 66fd004..96a732a 100644
--- a/webserver/internal/web/handlers/system/ws_client.go
+++ b/webserver/internal/web/handlers/system/ws_client.go
@@ -72,7 +72,7 @@ func (c *WSClient) reader() {
// Start to chat with the bot agent, sending the first message.
response, err := (*c.service).ChatWithAgent(ctx, message)
if err != nil {
- logger.Error(err, "error writing close message")
+ logger.Error(err, "error writing response message to client")
return
}