mirror of https://github.com/harness/drone.git
feat: [ML-334]: Extract interface for Intelligence service (#3066)
* Fix copyright header * Fix lint issues wrt copyright & comment structure * feat: [ML-334]: Extract interfae for Intelligence servicepull/3597/head
parent
b4baf364a9
commit
a89041e57e
|
@ -24,19 +24,19 @@ import (
|
|||
)
|
||||
|
||||
type Controller struct {
|
||||
authorizer authz.Authorizer
|
||||
intelligenceService *aiagent.HarnessIntelligence
|
||||
repoStore store.RepoStore
|
||||
pipelineStore store.PipelineStore
|
||||
executionStore store.ExecutionStore
|
||||
git git.Interface
|
||||
urlProvider url.Provider
|
||||
slackbot *messaging.Slack
|
||||
authorizer authz.Authorizer
|
||||
intelligence aiagent.Intelligence
|
||||
repoStore store.RepoStore
|
||||
pipelineStore store.PipelineStore
|
||||
executionStore store.ExecutionStore
|
||||
git git.Interface
|
||||
urlProvider url.Provider
|
||||
slackbot *messaging.Slack
|
||||
}
|
||||
|
||||
func NewController(
|
||||
authorizer authz.Authorizer,
|
||||
pipeline *aiagent.HarnessIntelligence,
|
||||
intelligence aiagent.Intelligence,
|
||||
repoStore store.RepoStore,
|
||||
pipelineStore store.PipelineStore,
|
||||
executionStore store.ExecutionStore,
|
||||
|
@ -45,13 +45,13 @@ func NewController(
|
|||
slackbot *messaging.Slack,
|
||||
) *Controller {
|
||||
return &Controller{
|
||||
authorizer: authorizer,
|
||||
intelligenceService: pipeline,
|
||||
repoStore: repoStore,
|
||||
pipelineStore: pipelineStore,
|
||||
executionStore: executionStore,
|
||||
git: git,
|
||||
urlProvider: urlProvider,
|
||||
slackbot: slackbot,
|
||||
authorizer: authorizer,
|
||||
intelligence: intelligence,
|
||||
repoStore: repoStore,
|
||||
pipelineStore: pipelineStore,
|
||||
executionStore: executionStore,
|
||||
git: git,
|
||||
urlProvider: urlProvider,
|
||||
slackbot: slackbot,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,45 +18,26 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
aitypes "github.com/harness/gitness/types/aigenerate"
|
||||
)
|
||||
|
||||
type GeneratePipelineInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
}
|
||||
|
||||
type PipelineData struct {
|
||||
YamlPipeline string `json:"yaml_pipeline"`
|
||||
}
|
||||
|
||||
type GeneratePipelineOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineData `json:"data"`
|
||||
}
|
||||
|
||||
func (c *Controller) GeneratePipeline(
|
||||
ctx context.Context,
|
||||
in *GeneratePipelineInput,
|
||||
) (*GeneratePipelineOutput, error) {
|
||||
generateRequest := &types.PipelineGenerateRequest{
|
||||
in *controllertypes.GeneratePipelineInput,
|
||||
) (*controllertypes.GeneratePipelineOutput, error) {
|
||||
generateRequest := &aitypes.PipelineGenerateRequest{
|
||||
Prompt: in.Prompt,
|
||||
RepoRef: in.RepoRef,
|
||||
}
|
||||
|
||||
// do permission check on repo here?
|
||||
repo, err := c.repoStore.FindByRef(ctx, in.RepoRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find repo by ref: %w", err)
|
||||
}
|
||||
|
||||
output, err := c.intelligenceService.Generate(ctx, generateRequest, repo)
|
||||
output, err := c.intelligence.GeneratePipeline(ctx, generateRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate pipeline: %w", err)
|
||||
}
|
||||
return &GeneratePipelineOutput{
|
||||
return &controllertypes.GeneratePipelineOutput{
|
||||
Status: "SUCCESS",
|
||||
Data: PipelineData{
|
||||
Data: controllertypes.PipelineData{
|
||||
YamlPipeline: output.YAML,
|
||||
},
|
||||
}, nil
|
||||
|
|
|
@ -18,39 +18,26 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
aitypes "github.com/harness/gitness/types/aigenerate"
|
||||
)
|
||||
|
||||
type GeneratePipelineStepInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
}
|
||||
|
||||
type PipelineStepData struct {
|
||||
StepYaml string `json:"yaml_step"`
|
||||
}
|
||||
|
||||
type GeneratePipelineStepOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineStepData `json:"data"`
|
||||
}
|
||||
|
||||
func (c *Controller) GeneratePipelineStep(
|
||||
ctx context.Context,
|
||||
in *GeneratePipelineInput,
|
||||
) (*GeneratePipelineStepOutput, error) {
|
||||
generateRequest := &types.PipelineStepGenerateRequest{
|
||||
in *controllertypes.GeneratePipelineInput,
|
||||
) (*controllertypes.GeneratePipelineStepOutput, error) {
|
||||
generateRequest := &aitypes.PipelineStepGenerateRequest{
|
||||
Prompt: in.Prompt,
|
||||
RepoRef: in.RepoRef,
|
||||
}
|
||||
|
||||
output, err := c.intelligenceService.GenerateStep(ctx, generateRequest)
|
||||
output, err := c.intelligence.GeneratePipelineStep(ctx, generateRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate pipeline: %w", err)
|
||||
}
|
||||
return &GeneratePipelineStepOutput{
|
||||
return &controllertypes.GeneratePipelineStepOutput{
|
||||
Status: "SUCCESS",
|
||||
Data: PipelineStepData{
|
||||
Data: controllertypes.PipelineStepData{
|
||||
StepYaml: output.YAML,
|
||||
},
|
||||
}, nil
|
||||
|
|
|
@ -16,28 +16,13 @@ package aiagent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
)
|
||||
|
||||
type SuggestPipelineInput struct {
|
||||
RepoRef string `json:"repo_ref"`
|
||||
Pipeline string `json:"pipeline"`
|
||||
}
|
||||
|
||||
func (c *Controller) SuggestPipeline(
|
||||
ctx context.Context,
|
||||
in *SuggestPipelineInput,
|
||||
) (*types.PipelineSuggestionsResponse, error) {
|
||||
suggestionRequest := &types.PipelineSuggestionsRequest{
|
||||
RepoRef: in.RepoRef,
|
||||
Pipeline: in.Pipeline,
|
||||
}
|
||||
|
||||
output, err := c.intelligenceService.Suggest(ctx, suggestionRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("suggest pipeline: %w", err)
|
||||
}
|
||||
return output, nil
|
||||
_ context.Context,
|
||||
_ *controllertypes.SuggestPipelineInput,
|
||||
) (*controllertypes.SuggestPipelineOutput, error) {
|
||||
return &controllertypes.SuggestPipelineOutput{}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Suggestion struct {
|
||||
ID string
|
||||
Prompt string
|
||||
UserSuggestion string
|
||||
Suggestion string
|
||||
}
|
||||
|
||||
// Additional common structs can be defined here as needed.
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type GeneratePipelineInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
}
|
||||
|
||||
type PipelineData struct {
|
||||
YamlPipeline string `json:"yaml_pipeline"`
|
||||
}
|
||||
|
||||
type GeneratePipelineOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineData `json:"data"`
|
||||
}
|
||||
|
||||
type SuggestPipelineInput struct {
|
||||
RepoRef string `json:"repo_ref"`
|
||||
Pipeline string `json:"pipeline"`
|
||||
}
|
||||
|
||||
type SuggestPipelineOutput struct {
|
||||
Suggestions []Suggestion
|
||||
}
|
||||
|
||||
type UpdatePipelineOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineData `json:"data"`
|
||||
}
|
||||
|
||||
type UpdatePipelineInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
Pipeline string `json:"pipeline"`
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type GeneratePipelineStageInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
}
|
||||
|
||||
type PipelineStageData struct {
|
||||
StageYaml string `json:"yaml_step"`
|
||||
}
|
||||
|
||||
type GeneratePipelineStageOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineStageData `json:"data"`
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type GeneratePipelineStepInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
}
|
||||
|
||||
type PipelineStepData struct {
|
||||
StepYaml string `json:"yaml_step"`
|
||||
}
|
||||
|
||||
type GeneratePipelineStepOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineStepData `json:"data"`
|
||||
}
|
|
@ -16,46 +16,13 @@ package aiagent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
)
|
||||
|
||||
type UpdatePipelineOutput struct {
|
||||
Status string `json:"status"`
|
||||
Data PipelineData `json:"data"`
|
||||
}
|
||||
|
||||
type UpdatePipelineInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
RepoRef string `json:"repo_ref"`
|
||||
Pipeline string `json:"pipeline"`
|
||||
}
|
||||
|
||||
func (c *Controller) UpdatePipeline(
|
||||
ctx context.Context,
|
||||
in *UpdatePipelineInput,
|
||||
) (*UpdatePipelineOutput, error) {
|
||||
generateRequest := &types.PipelineUpdateRequest{
|
||||
Prompt: in.Prompt,
|
||||
RepoRef: in.RepoRef,
|
||||
Pipeline: in.Pipeline,
|
||||
}
|
||||
|
||||
// do permission check on repo here?
|
||||
repo, err := c.repoStore.FindByRef(ctx, in.RepoRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find repo by ref: %w", err)
|
||||
}
|
||||
|
||||
output, err := c.intelligenceService.Update(ctx, generateRequest, repo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("update pipeline: %w", err)
|
||||
}
|
||||
return &UpdatePipelineOutput{
|
||||
Status: "SUCCESS",
|
||||
Data: PipelineData{
|
||||
YamlPipeline: output.YAML,
|
||||
},
|
||||
}, nil
|
||||
_ context.Context,
|
||||
_ *controllertypes.UpdatePipelineInput,
|
||||
) (*controllertypes.UpdatePipelineOutput, error) {
|
||||
return &controllertypes.UpdatePipelineOutput{}, nil
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ var WireSet = wire.NewSet(
|
|||
|
||||
func ProvideController(
|
||||
authorizer authz.Authorizer,
|
||||
aiagentPipeline *aiagent.HarnessIntelligence,
|
||||
intelligence aiagent.Intelligence,
|
||||
repoStore store.RepoStore,
|
||||
pipelineStore store.PipelineStore,
|
||||
executionStore store.ExecutionStore,
|
||||
|
@ -42,7 +42,7 @@ func ProvideController(
|
|||
) *Controller {
|
||||
return NewController(
|
||||
authorizer,
|
||||
aiagentPipeline,
|
||||
intelligence,
|
||||
repoStore,
|
||||
pipelineStore,
|
||||
executionStore,
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/harness/gitness/app/api/controller/aiagent"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
"github.com/harness/gitness/app/api/render"
|
||||
)
|
||||
|
||||
|
@ -26,7 +27,7 @@ func HandleGeneratePipeline(aiagentCtrl *aiagent.Controller) http.HandlerFunc {
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
in := new(aiagent.GeneratePipelineInput)
|
||||
in := new(controllertypes.GeneratePipelineInput)
|
||||
err := json.NewDecoder(r.Body).Decode(in)
|
||||
if err != nil {
|
||||
render.BadRequestf(ctx, w, "Invalid Request Body: %s.", err)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/harness/gitness/app/api/controller/aiagent"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
"github.com/harness/gitness/app/api/render"
|
||||
)
|
||||
|
||||
|
@ -26,7 +27,7 @@ func HandleGeneratePipelineStep(aiagentCtrl *aiagent.Controller) http.HandlerFun
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
in := new(aiagent.GeneratePipelineInput)
|
||||
in := new(controllertypes.GeneratePipelineInput)
|
||||
err := json.NewDecoder(r.Body).Decode(in)
|
||||
if err != nil {
|
||||
render.BadRequestf(ctx, w, "Invalid Request Body: %s.", err)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/harness/gitness/app/api/controller/aiagent"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
"github.com/harness/gitness/app/api/render"
|
||||
)
|
||||
|
||||
|
@ -26,7 +27,7 @@ func HandleSuggestPipelines(aiagentCtrl *aiagent.Controller) http.HandlerFunc {
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
in := new(aiagent.SuggestPipelineInput)
|
||||
in := new(controllertypes.SuggestPipelineInput)
|
||||
err := json.NewDecoder(r.Body).Decode(in)
|
||||
if err != nil {
|
||||
render.BadRequestf(ctx, w, "Invalid Request Body: %s.", err)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/harness/gitness/app/api/controller/aiagent"
|
||||
controllertypes "github.com/harness/gitness/app/api/controller/aiagent/types"
|
||||
"github.com/harness/gitness/app/api/render"
|
||||
)
|
||||
|
||||
|
@ -27,7 +28,7 @@ func HandleUpdatePipeline(aiagentCtrl *aiagent.Controller) http.HandlerFunc {
|
|||
ctx := r.Context()
|
||||
|
||||
// TODO Question: how come we decode body here vs putting that logic in the request package?
|
||||
in := new(aiagent.UpdatePipelineInput)
|
||||
in := new(controllertypes.UpdatePipelineInput)
|
||||
err := json.NewDecoder(r.Body).Decode(in)
|
||||
if err != nil {
|
||||
render.BadRequestf(ctx, w, "Invalid Request Body: %s.", err)
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package aiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
capabilitiesctrl "github.com/harness/gitness/app/api/controller/capabilities"
|
||||
"github.com/harness/gitness/app/auth/authz"
|
||||
"github.com/harness/gitness/app/services/capabilities"
|
||||
"github.com/harness/gitness/genai"
|
||||
"github.com/harness/gitness/types"
|
||||
capabilitytypes "github.com/harness/gitness/types/capabilities"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type HarnessIntelligence struct {
|
||||
authorizer authz.Authorizer
|
||||
cr *capabilities.Registry
|
||||
cc *capabilitiesctrl.Controller
|
||||
}
|
||||
|
||||
type Pipeline interface {
|
||||
Generate(ctx context.Context, req *types.PipelineGenerateRequest) (*types.PipelineGenerateResponse, error)
|
||||
}
|
||||
|
||||
func capabilityResponseToChatContext(
|
||||
ranCapabilities *capabilitiesctrl.CapabilityRunResponse) []capabilitytypes.AIContext {
|
||||
var aiContexts []capabilitytypes.AIContext
|
||||
for _, value := range ranCapabilities.CapabilitiesRan {
|
||||
aiContext := capabilitytypes.AIContext{
|
||||
Type: capabilitytypes.AIContextPayloadType("other"),
|
||||
Payload: value.Result,
|
||||
Name: string(value.Type),
|
||||
}
|
||||
aiContexts = append(aiContexts, aiContext)
|
||||
}
|
||||
return aiContexts
|
||||
}
|
||||
|
||||
func (s *HarnessIntelligence) Generate(
|
||||
ctx context.Context,
|
||||
req *types.PipelineGenerateRequest,
|
||||
repo *types.Repository) (*types.PipelineGenerateResponse, error) {
|
||||
if req.RepoRef == "" {
|
||||
return nil, fmt.Errorf("no repo ref specified")
|
||||
}
|
||||
|
||||
conversationID := uuid.New()
|
||||
chatRequest := &genai.ChatRequest{
|
||||
Prompt: req.Prompt,
|
||||
ConversationID: conversationID.String(),
|
||||
ConversationRaw: "",
|
||||
Context: genai.GenerateAIContext(
|
||||
genai.RepoRef{
|
||||
Ref: repo.Path,
|
||||
},
|
||||
),
|
||||
Capabilities: s.cr.Capabilities(),
|
||||
}
|
||||
|
||||
resp, err := s.CapabilitiesLoop(ctx, chatRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yaml string
|
||||
for _, value := range resp.Context {
|
||||
out, ok := value.Payload.(*capabilities.DisplayYamlOutput)
|
||||
if ok {
|
||||
yaml = out.Yaml
|
||||
}
|
||||
}
|
||||
return &types.PipelineGenerateResponse{
|
||||
YAML: yaml,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *HarnessIntelligence) GenerateStep(
|
||||
ctx context.Context,
|
||||
req *types.PipelineStepGenerateRequest) (*types.PipelineStepGenerateResponse, error) {
|
||||
conversationID := uuid.New()
|
||||
chatRequest := &genai.ChatRequest{
|
||||
Prompt: req.Prompt,
|
||||
ConversationID: conversationID.String(),
|
||||
ConversationRaw: "",
|
||||
Context: genai.GenerateAIContext(),
|
||||
Capabilities: s.cr.Capabilities(),
|
||||
}
|
||||
|
||||
resp, err := s.CapabilitiesLoop(ctx, chatRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yaml string
|
||||
for _, value := range resp.Context {
|
||||
out, ok := value.Payload.(*capabilities.DisplayYamlOutput)
|
||||
if ok {
|
||||
yaml = out.Yaml
|
||||
}
|
||||
}
|
||||
return &types.PipelineStepGenerateResponse{
|
||||
YAML: yaml,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TODO fix naming
|
||||
type PipelineYaml struct {
|
||||
Yaml string `yaml:"yaml"`
|
||||
}
|
||||
|
||||
// CapabilitiesLoop TODO: this should be replaced with an async model for Harness Enterprise, but remain for Harness.
|
||||
func (s *HarnessIntelligence) CapabilitiesLoop(
|
||||
ctx context.Context, req *genai.ChatRequest) (*genai.ChatRequest, error) {
|
||||
returnToUser := false
|
||||
for !returnToUser {
|
||||
capToRun, err := genai.CallAIFoundation(ctx, s.cr, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to call local chat: %w", err)
|
||||
}
|
||||
|
||||
resp, err := s.cc.RunCapabilities(ctx, capToRun)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to run capabilities: %w", err)
|
||||
}
|
||||
|
||||
prevChatRequest := req
|
||||
req = &genai.ChatRequest{
|
||||
Prompt: "",
|
||||
ConversationID: prevChatRequest.ConversationID,
|
||||
ConversationRaw: capToRun.ConversationRaw,
|
||||
Context: capabilityResponseToChatContext(resp),
|
||||
Capabilities: s.cr.Capabilities(),
|
||||
}
|
||||
|
||||
for _, value := range resp.CapabilitiesRan {
|
||||
if value.ReturnToUser {
|
||||
returnToUser = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (s *HarnessIntelligence) Update(
|
||||
ctx context.Context,
|
||||
req *types.PipelineUpdateRequest, repo *types.Repository) (*types.PipelineUpdateResponse, error) {
|
||||
if req.RepoRef == "" {
|
||||
return nil, fmt.Errorf("no repo ref specified")
|
||||
}
|
||||
|
||||
conversationID := uuid.New()
|
||||
chatRequest := &genai.ChatRequest{
|
||||
Prompt: req.Prompt,
|
||||
ConversationID: conversationID.String(),
|
||||
ConversationRaw: "",
|
||||
Context: genai.GenerateAIContext(
|
||||
genai.RepoRef{
|
||||
Ref: repo.Path,
|
||||
},
|
||||
genai.PipelineContext{
|
||||
Yaml: req.Pipeline,
|
||||
},
|
||||
),
|
||||
Capabilities: s.cr.Capabilities(),
|
||||
}
|
||||
|
||||
resp, err := s.CapabilitiesLoop(ctx, chatRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yaml string
|
||||
for _, value := range resp.Context {
|
||||
out, ok := value.Payload.(*capabilities.DisplayYamlOutput)
|
||||
if ok {
|
||||
yaml = out.Yaml
|
||||
}
|
||||
}
|
||||
|
||||
updateResponse := &types.PipelineUpdateResponse{
|
||||
YAML: yaml,
|
||||
}
|
||||
return updateResponse, nil
|
||||
}
|
||||
|
||||
func (s *HarnessIntelligence) Suggest(
|
||||
_ context.Context,
|
||||
_ *types.PipelineSuggestionsRequest) (*types.PipelineSuggestionsResponse, error) {
|
||||
return &types.PipelineSuggestionsResponse{
|
||||
Suggestions: []types.Suggestion{},
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package aiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
capabilitiesctrl "github.com/harness/gitness/app/api/controller/capabilities"
|
||||
"github.com/harness/gitness/app/auth/authz"
|
||||
"github.com/harness/gitness/app/services/capabilities"
|
||||
aitypes "github.com/harness/gitness/types/aigenerate"
|
||||
)
|
||||
|
||||
var _ Intelligence = GitnessIntelligence{}
|
||||
|
||||
// This interface serves are the single interface to provide AI use cases.
|
||||
type Intelligence interface {
|
||||
GeneratePipeline(
|
||||
ctx context.Context,
|
||||
req *aitypes.PipelineGenerateRequest) (*aitypes.PipelineGenerateResponse, error)
|
||||
GeneratePipelineStage(
|
||||
ctx context.Context,
|
||||
req *aitypes.PipelineStageGenerateRequest) (*aitypes.PipelineStageGenerateResponse, error)
|
||||
GeneratePipelineStep(
|
||||
ctx context.Context,
|
||||
req *aitypes.PipelineStepGenerateRequest) (*aitypes.PipelineStepGenerateResponse, error)
|
||||
}
|
||||
|
||||
type GitnessIntelligence struct {
|
||||
authorizer authz.Authorizer
|
||||
cr *capabilities.Registry
|
||||
cc *capabilitiesctrl.Controller
|
||||
}
|
||||
|
||||
// GeneratePipeline implements Intelligence.
|
||||
func (h GitnessIntelligence) GeneratePipeline(
|
||||
_ context.Context,
|
||||
_ *aitypes.PipelineGenerateRequest) (*aitypes.PipelineGenerateResponse, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// GeneratePipelineStage implements Intelligence.
|
||||
func (h GitnessIntelligence) GeneratePipelineStage(
|
||||
_ context.Context,
|
||||
_ *aitypes.PipelineStageGenerateRequest) (*aitypes.PipelineStageGenerateResponse, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// GeneratePipelineStep implements Intelligence.
|
||||
func (h GitnessIntelligence) GeneratePipelineStep(
|
||||
_ context.Context,
|
||||
_ *aitypes.PipelineStepGenerateRequest) (*aitypes.PipelineStepGenerateResponse, error) {
|
||||
panic("unimplemented")
|
||||
}
|
|
@ -30,8 +30,8 @@ func ProvideAiAgent(
|
|||
authorizer authz.Authorizer,
|
||||
cr *capabilities.Registry,
|
||||
cc *capabilitiesctrl.Controller,
|
||||
) (*HarnessIntelligence, error) {
|
||||
return &HarnessIntelligence{
|
||||
) (*GitnessIntelligence, error) {
|
||||
return &GitnessIntelligence{
|
||||
authorizer,
|
||||
cr,
|
||||
cc,
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Suggestion struct {
|
||||
ID string
|
||||
Prompt string
|
||||
UserSuggestion string
|
||||
Suggestion string
|
||||
}
|
||||
|
||||
// Additional common structs can be defined here as needed.
|
|
@ -14,46 +14,30 @@
|
|||
|
||||
package types
|
||||
|
||||
type PipelineSuggestionsRequest struct {
|
||||
RepoRef string
|
||||
Pipeline string
|
||||
}
|
||||
|
||||
type PipelineGenerateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
}
|
||||
|
||||
type PipelineUpdateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
Pipeline string
|
||||
}
|
||||
|
||||
type PipelineStepGenerateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
}
|
||||
|
||||
type PipelineGenerateResponse struct {
|
||||
YAML string
|
||||
}
|
||||
|
||||
type PipelineUpdateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
Pipeline string
|
||||
}
|
||||
|
||||
type PipelineUpdateResponse struct {
|
||||
YAML string
|
||||
}
|
||||
|
||||
type Suggestion struct {
|
||||
ID string
|
||||
Prompt string
|
||||
UserSuggestion string
|
||||
Suggestion string
|
||||
type PipelineSuggestionsRequest struct {
|
||||
RepoRef string
|
||||
Pipeline string
|
||||
}
|
||||
|
||||
type PipelineSuggestionsResponse struct {
|
||||
Suggestions []Suggestion
|
||||
}
|
||||
|
||||
type PipelineStepGenerateResponse struct {
|
||||
YAML string
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type PipelineStageGenerateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
}
|
||||
|
||||
type PipelineStageGenerateResponse struct {
|
||||
YAML string
|
||||
}
|
||||
|
||||
type PipelineStageUpdateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
Stage string
|
||||
}
|
||||
|
||||
type PipelineStageUpdateResponse struct {
|
||||
YAML string
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type PipelineStepGenerateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
}
|
||||
|
||||
type PipelineStepGenerateResponse struct {
|
||||
YAML string
|
||||
}
|
||||
|
||||
type PipelineStepUpdateRequest struct {
|
||||
Prompt string
|
||||
RepoRef string
|
||||
Step string
|
||||
}
|
||||
|
||||
type PipelineStepUpdateResponse struct {
|
||||
YAML string
|
||||
}
|
Loading…
Reference in New Issue