Skip to content

Commit

Permalink
add copilot web
Browse files Browse the repository at this point in the history
  • Loading branch information
shaowenchen committed Sep 18, 2024
1 parent 6572380 commit 622769f
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Dockerfile-Server
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ FROM hubimage/runtime-ubuntu:22.04
COPY --from=builder /builder/bin/ops-server .
COPY --from=builder /builder/default.toml .
COPY --from=builder-web /builder/web/dist ./web/dist
ENTRYPOINT ["./ops-server", "-c", "./default.toml"]
CMD ["./ops-server", "-c", "./default.toml"]
Expose 80
6 changes: 6 additions & 0 deletions default.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[server]
runmode="release"
token="P@88w0rd"
[copilot]
endpoint="https://api.openai.com/v1"
key=""
model="gpt-3.5-turbo-16k"
opsserver="http://myops-server.ops-system.svc"
opstoken="P@88w0rd"
59 changes: 59 additions & 0 deletions pkg/server/api-copilot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package server

import (
"fmt"
"github.com/gin-gonic/gin"
opscopilot "github.com/shaowenchen/ops/pkg/copilot"
opslog "github.com/shaowenchen/ops/pkg/log"
)

var logger *opslog.Logger
var pipelinerunsManager *opscopilot.PipelineRunsManager

func Init() {
logger = opslog.NewLogger().SetVerbose("debug").SetStd().SetFile().SetFlag().Build()
pipelinerunsManager, _ = opscopilot.NewPipelineRunsManager(GlobalConfig.Copilot.OpsServer, GlobalConfig.Copilot.OpsToken, "ops-system")
}

func PostCopilot(c *gin.Context) {
type Params struct {
Input string `json:"input"`
}
var req = Params{}
err := c.ShouldBindJSON(&req)
if err != nil {
showError(c, "get body error "+err.Error())
return
}
if req.Input == "" {
showError(c, "input is required")
return
}
input := req.Input
// build chat
chatHistory := opscopilot.RoleContentList{}
chat, err := opscopilot.BuildOpenAIChat(GlobalConfig.Copilot.Endpoint, GlobalConfig.Copilot.Key, GlobalConfig.Copilot.Model, &chatHistory, "", "copilot", 0.1)
if err != nil {
logger.Error.Printf("build chat error: %v\n", err)
showError(c, err.Error())
return
}
prHistory := opscopilot.RoleContentList{}
pr, exitCode, err := opscopilot.RunPipeline(logger, chat, &prHistory, pipelinerunsManager, input, nil)

var output string
if exitCode == opscopilot.ExitCodeIntentionEmpty {
output = "I can not understand your input:" + input + ", please help me to solve it, use following intention:\n " + pipelinerunsManager.GetForIntent()
} else if exitCode == opscopilot.ExitCodeParametersNotFound {
output = "I can not get the parameters, please help me to solve it:\n " + pipelinerunsManager.GetForVariables(pr)
} else {
output = fmt.Sprintf("%s", pipelinerunsManager.PrintMarkdownPipelineRuns(pr))
}
if output == "" {
output = "It's bug, please contact chenshaowen to fix it"
}
if err != nil {
output = err.Error()
}
showData(c, output)
}
5 changes: 4 additions & 1 deletion pkg/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package server

import (
"fmt"
"github.com/spf13/viper"
"os"
"path/filepath"
"strings"

"github.com/shaowenchen/ops/pkg/option"
"github.com/spf13/viper"
)

var GlobalConfig = &ConfigOptions{}

type ConfigOptions struct {
Server ServerOptions
Copilot option.CopilotOption
}

type ServerOptions struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func SetupRouter(r *gin.Engine) {
v1Pipelineruns.POST("", CreatePipelineRun)
v1Pipelineruns.GET("/:pipelinerun", GetPipelineRun)
}
v1Copilot := r.Group("/api/v1/copilot").Use(AuthMiddleware())
{
v1Copilot.POST("", PostCopilot)
}
}

func SetHealthzRouter(r *gin.Engine) {
Expand Down
3 changes: 3 additions & 0 deletions web/src/components/Nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<li class="nav-item">
<router-link to="/" class="nav-link">Home</router-link>
</li>
<li class="nav-item">
<router-link to="/copilot" class="nav-link">Copilot</router-link>
</li>
<li class="nav-item">
<router-link to="/hosts" class="nav-link">Hosts</router-link>
</li>
Expand Down
3 changes: 2 additions & 1 deletion web/src/router/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createRouter, createWebHistory } from "vue-router";

import { Home, Hosts, Clusters, Tasks, TaskRuns, Pipelines, PipelineRuns, Login} from "@/views";
import { Home, Hosts, Clusters, Tasks, TaskRuns, Pipelines, PipelineRuns, Login, Copilot} from "@/views";

export const router = createRouter({
history: createWebHistory(),
Expand All @@ -14,6 +14,7 @@ export const router = createRouter({
{ path: "/pipelines", component: Pipelines, name: "pipelines" },
{ path: "/pipelineruns", component: PipelineRuns, name: "pipelineruns" },
{ path: "/login", component: Login, name: "login" },
{ path: "/copilot", component: Copilot, name: "copilot" },
],
});

Expand Down
17 changes: 17 additions & 0 deletions web/src/stores/copilot.store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineStore } from "pinia";
import { fetchWrapper } from "@/helpers";

export const useCopilotStore = defineStore({
id: "copilot",
state: () => ({
alert: null,
}),
actions: {
async post(input) {
const res = await fetchWrapper.post(`/api/v1/copilot/`, {
input: input,
});
return res.data;
},
},
});
1 change: 1 addition & 0 deletions web/src/stores/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './taskruns.store';
export * from './pipelines.store';
export * from './pipelineruns.store';
export * from './login.store'
export * from './copilot.store'
115 changes: 115 additions & 0 deletions web/src/views/Copilot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<script setup>
import { ref } from "vue";
import { useCopilotStore } from "@/stores";
var messageList = ref([]);
var currentMessage = ref("");
function sendMessage() {
if (currentMessage.value.trim() === "") return;
messageList.value.push({
sender: "user",
content: currentMessage.value,
timestamp: new Date().toLocaleTimeString(),
});
res = useCopilotStore().post(currentMessage.value);
messageList.value.push({
sender: "bot",
content: res,
timestamp: new Date().toLocaleTimeString(),
});
currentMessage.value = "";
}
</script>

<template>
<div class="chat-container">
<div class="chat-box">
<div v-for="(message, index) in messageList" :key="index" class="message">
<div
:class="message.sender === 'user' ? 'user-message' : 'bot-message'"
>
<p>{{ message.content }}</p>
<span class="timestamp">{{ message.timestamp }}</span>
</div>
</div>
</div>
<el-input
v-model="currentMessage"
placeholder="输入消息..."
class="input-box"
@keyup.enter="sendMessage"
/>
<el-button type="primary" @click="sendMessage">发送</el-button>
</div>
</template>

<style scoped>
.chat-container {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 400px;
width: 100%;
max-width: 600px;
margin: 0 auto;
border: 1px solid #ccc;
padding: 10px;
border-radius: 10px;
background-color: #f9f9f9;
}
.chat-box {
flex-grow: 1;
overflow-y: auto;
margin-bottom: 10px;
padding-right: 10px;
}
.message {
margin: 10px 0;
}
.user-message {
text-align: right;
}
.bot-message {
text-align: left;
}
.user-message p,
.bot-message p {
display: inline-block;
padding: 10px;
border-radius: 10px;
max-width: 70%;
}
.user-message p {
background-color: #007bff;
color: white;
}
.bot-message p {
background-color: #f1f1f1;
color: black;
}
.timestamp {
display: block;
font-size: 0.8em;
margin-top: 5px;
color: gray;
}
.input-box {
width: calc(100% - 100px);
}
.el-button {
margin-left: 10px;
}
</style>
1 change: 1 addition & 0 deletions web/src/views/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export { default as TaskRuns } from './TaskRuns.vue';
export { default as Pipelines } from './Pipelines.vue';
export { default as PipelineRuns } from './PipelineRuns.vue';
export { default as Login } from './Login.vue';
export { default as Copilot } from './Copilot.vue'

0 comments on commit 622769f

Please sign in to comment.