Skip to content

Commit e450960

Browse files
archit-harnessHarness
authored andcommitted
[feat]: [DBOPS-1395]: Add support for dbops changeset agent (#103)
* [feat]: [DBOPS-1395]: Add support for dbops changeset agent * Merge branch 'master' into DBOPS-1395 # Conflicts: # cmd/harness-mcp-server/main.go # pkg/modules/unlicensed.go * [feat]: [DBOPS-1395]: Add support for dbops changeset agent
1 parent 6fd07c4 commit e450960

File tree

8 files changed

+424
-211
lines changed

8 files changed

+424
-211
lines changed

client/dto/genai.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,74 @@ const (
5252
CallerUnifiedAgent Caller = "unified_agent"
5353
)
5454

55-
type ServiceChatParameters struct {
55+
// GenAIRequest defines the interface for all GenAI request types
56+
type GenAIRequest interface {
57+
GetBaseParameters() *BaseRequestParameters
58+
IsStreaming() bool
59+
}
60+
61+
// BaseRequestParameters defines common fields for all GenAI request types
62+
type BaseRequestParameters struct {
5663
Prompt string `json:"prompt"`
5764
Provider string `json:"provider,omitempty"`
5865
ModelName string `json:"model_name,omitempty"`
5966
ConversationID string `json:"conversation_id"`
6067
InteractionID string `json:"interaction_id,omitempty"`
61-
Capabilities []Capability `json:"capabilities"`
68+
Capabilities []Capability `json:"capabilities,omitempty"`
6269
ConversationRaw []any `json:"conversation_raw,omitempty"`
6370
Context []ContextItem `json:"context,omitempty"`
64-
Action RequestAction `json:"action,omitempty"`
6571
HarnessContext *HarnessContext `json:"harness_context,omitempty"`
6672
Stream bool `json:"stream,omitempty"`
6773
Caller Caller `json:"caller,omitempty"`
6874
}
6975

76+
// GetBaseParameters returns the base parameters
77+
func (b *BaseRequestParameters) GetBaseParameters() *BaseRequestParameters {
78+
return b
79+
}
80+
81+
// IsStreaming returns whether the request is streaming
82+
func (b *BaseRequestParameters) IsStreaming() bool {
83+
return b.Stream
84+
}
85+
86+
// ServiceChatParameters extends BaseRequestParameters for AI DevOps agent requests
87+
type ServiceChatParameters struct {
88+
BaseRequestParameters
89+
Action RequestAction `json:"action,omitempty"`
90+
}
91+
92+
// GetBaseParameters returns the base parameters
93+
func (s *ServiceChatParameters) GetBaseParameters() *BaseRequestParameters {
94+
return &s.BaseRequestParameters
95+
}
96+
97+
// IsStreaming returns whether the request is streaming
98+
func (s *ServiceChatParameters) IsStreaming() bool {
99+
return s.BaseRequestParameters.Stream
100+
}
101+
102+
// DatabaseType defines the supported database types
103+
type DatabaseType string
104+
105+
// DBChangesetParameters extends BaseRequestParameters for database changeset generation
106+
type DBChangesetParameters struct {
107+
BaseRequestParameters
108+
DatabaseType DatabaseType `json:"database_type"`
109+
OldChangeset string `json:"oldchangeset,omitempty"`
110+
ErrorContext string `json:"error_context,omitempty"`
111+
}
112+
113+
// GetBaseParameters returns the base parameters
114+
func (d *DBChangesetParameters) GetBaseParameters() *BaseRequestParameters {
115+
return &d.BaseRequestParameters
116+
}
117+
118+
// IsStreaming returns whether the request is streaming
119+
func (d *DBChangesetParameters) IsStreaming() bool {
120+
return d.BaseRequestParameters.Stream
121+
}
122+
70123
type CapabilityToRun struct {
71124
CallID string `json:"call_id"`
72125
Type string `json:"type"`

client/genai.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ import (
1515

1616
const (
1717
aiDevopsChatPath = "chat/platform"
18+
dbChangesetPath = "chat/db-changeset"
1819
)
1920

2021
type GenaiService struct {
2122
Client *Client
2223
}
2324

24-
// SendAIDevOpsChat sends a request to the AI DevOps service and returns the response.
25-
// If request.Stream is true and onProgress is provided, it will handle streaming responses.
26-
// For non-streaming requests or when onProgress is nil, it will use the standard request flow.
27-
func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, request *dto.ServiceChatParameters, onProgress ...func(progressUpdate dto.ProgressUpdate) error) (*dto.ServiceChatResponse, error) {
25+
// sendGenAIRequest is a generic method to send requests to GenAI services
26+
func (g *GenaiService) sendGenAIRequest(ctx context.Context, path string, scope dto.Scope, request dto.GenAIRequest,
27+
onProgress ...func(progressUpdate dto.ProgressUpdate) error) (*dto.ServiceChatResponse, error) {
2828
if g == nil || g.Client == nil {
2929
return nil, fmt.Errorf("genai service or client is nil")
3030
}
@@ -56,11 +56,13 @@ func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, re
5656
params["projectIdentifier"] = scope.ProjectID
5757
}
5858

59+
// Determine if streaming is required
60+
shouldStream := request.IsStreaming() && progressCB != nil
61+
5962
// Handle non-streaming case with early return
60-
isStreaming := request.Stream && progressCB != nil
61-
if !isStreaming {
63+
if !shouldStream {
6264
var response dto.ServiceChatResponse
63-
err := g.Client.Post(ctx, aiDevopsChatPath, params, request, &response)
65+
err := g.Client.Post(ctx, path, params, request, &response)
6466
if err != nil {
6567
return nil, fmt.Errorf("failed to send request to genai service: %w", err)
6668
}
@@ -69,7 +71,7 @@ func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, re
6971
}
7072

7173
// Execute the streaming request
72-
resp, err := g.Client.PostStream(ctx, aiDevopsChatPath, params, request)
74+
resp, err := g.Client.PostStream(ctx, path, params, request)
7375
if err != nil {
7476
slog.Warn("Failed to execute streaming request", "error", err.Error())
7577
return nil, fmt.Errorf("failed to execute streaming request: %w", err)
@@ -84,7 +86,7 @@ func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, re
8486

8587
// Initialize the response with conversation ID from request
8688
finalResponse := &dto.ServiceChatResponse{
87-
ConversationID: request.ConversationID,
89+
ConversationID: request.GetBaseParameters().ConversationID,
8890
}
8991

9092
// Process the streaming response
@@ -97,6 +99,19 @@ func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, re
9799
return finalResponse, nil
98100
}
99101

102+
// SendAIDevOpsChat sends a request to the AI DevOps service and returns the response.
103+
// If request.Stream is true and onProgress is provided, it will handle streaming responses.
104+
// For non-streaming requests or when onProgress is nil, it will use the standard request flow.
105+
func (g *GenaiService) SendAIDevOpsChat(ctx context.Context, scope dto.Scope, request *dto.ServiceChatParameters, onProgress ...func(progressUpdate dto.ProgressUpdate) error) (*dto.ServiceChatResponse, error) {
106+
return g.sendGenAIRequest(ctx, aiDevopsChatPath, scope, request, onProgress...)
107+
}
108+
109+
// SendDBChangeset sends a request to generate database changesets and returns the response.
110+
// If request.Stream is true and onProgress is provided, it will handle streaming responses.
111+
func (g *GenaiService) SendDBChangeset(ctx context.Context, scope dto.Scope, request *dto.DBChangesetParameters, onProgress ...func(progressUpdate dto.ProgressUpdate) error) (*dto.ServiceChatResponse, error) {
112+
return g.sendGenAIRequest(ctx, dbChangesetPath, scope, request, onProgress...)
113+
}
114+
100115
// processStreamingResponse handles Server-Sent Events (SSE) streaming responses
101116
// and accumulates complete events before forwarding them with appropriate event types
102117
func (g *GenaiService) processStreamingResponse(body io.ReadCloser, finalResponse *dto.ServiceChatResponse, onProgress func(dto.ProgressUpdate) error) error {

pkg/harness/tools/dbops.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
78
"github.com/harness/harness-mcp/client/dbops"
89
"github.com/harness/harness-mcp/cmd/harness-mcp-server/config"
910
"github.com/mark3labs/mcp-go/mcp"

0 commit comments

Comments
 (0)