🎉 Initial Commit
Some checks failed
release-nightly / build-docker (push) Has been cancelled

This commit is contained in:
2025-01-30 01:19:14 +08:00
commit 771227a9ed
27 changed files with 2152 additions and 0 deletions

24
pkg/internal/cache/store.go vendored Normal file
View File

@ -0,0 +1,24 @@
package cache
import (
"github.com/dgraph-io/ristretto"
"github.com/eko/gocache/lib/v4/store"
ristrettoCache "github.com/eko/gocache/store/ristretto/v4"
)
var S store.StoreInterface
func NewStore() error {
ristretto, err := ristretto.NewCache(&ristretto.Config{
NumCounters: 1000,
MaxCost: 100,
BufferItems: 64,
})
if err != nil {
return err
}
S = ristrettoCache.NewRistretto(ristretto)
return nil
}

View File

@ -0,0 +1,17 @@
package database
import (
"gorm.io/gorm"
)
var AutoMaintainRange = []any{}
func RunMigration(source *gorm.DB) error {
if err := source.AutoMigrate(
AutoMaintainRange...,
); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,27 @@
package database
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
"git.solsynth.dev/hypernet/insight/pkg/internal/gap"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"github.com/spf13/viper"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var C *gorm.DB
func NewGorm() error {
var err error
dsn, err := cruda.NewCrudaConn(gap.Nx).AllocDatabase("insight")
C, err = gorm.Open(postgres.Open(dsn), &gorm.Config{Logger: logger.New(&log.Logger, logger.Config{
Colorful: true,
IgnoreRecordNotFoundError: true,
LogLevel: lo.Ternary(viper.GetBool("debug.database"), logger.Info, logger.Silent),
})})
return err
}

View File

@ -0,0 +1,44 @@
package gap
import (
"fmt"
"strings"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"github.com/spf13/viper"
)
var Nx *nex.Conn
func InitializeToNexus() error {
grpcBind := strings.SplitN(viper.GetString("grpc_bind"), ":", 2)
httpBind := strings.SplitN(viper.GetString("bind"), ":", 2)
outboundIp, _ := nex.GetOutboundIP()
grpcOutbound := fmt.Sprintf("%s:%s", outboundIp, grpcBind[1])
httpOutbound := fmt.Sprintf("%s:%s", outboundIp, httpBind[1])
var err error
Nx, err = nex.NewNexusConn(viper.GetString("nexus_addr"), &proto.ServiceInfo{
Id: viper.GetString("id"),
Type: "wa",
Label: "Insight",
GrpcAddr: grpcOutbound,
HttpAddr: lo.ToPtr("http://" + httpOutbound + "/api"),
})
if err == nil {
go func() {
err := Nx.RunRegistering()
if err != nil {
log.Error().Err(err).Msg("An error occurred while registering service...")
}
}()
}
return err
}

View File

@ -0,0 +1,26 @@
package grpc
import (
"context"
health "google.golang.org/grpc/health/grpc_health_v1"
"time"
)
func (v *Server) Check(ctx context.Context, request *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
return &health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}, nil
}
func (v *Server) Watch(request *health.HealthCheckRequest, server health.Health_WatchServer) error {
for {
if server.Send(&health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}) != nil {
break
}
time.Sleep(1000 * time.Millisecond)
}
return nil
}

View File

@ -0,0 +1,25 @@
package grpc
import (
"context"
"fmt"
"git.solsynth.dev/hypernet/insight/pkg/internal/services"
"git.solsynth.dev/hypernet/insight/pkg/proto"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
func (v *Server) GenerateInsight(ctx context.Context, request *proto.InsightRequest) (*proto.InsightResponse, error) {
input := request.GetSource()
if err := services.PlaceOrder(uint(request.GetUserId()), len(input)); err != nil {
return nil, status.Errorf(codes.ResourceExhausted, fmt.Sprintf("failed to place order: %v", err))
}
out, err := services.GenerateInsights(input)
if err != nil {
_ = services.MakeRefund(uint(request.GetUserId()), len(input))
return nil, status.Errorf(codes.Internal, fmt.Sprintf("failed to generate insight: %v", err))
}
return &proto.InsightResponse{Response: out}, nil
}

View File

@ -0,0 +1,43 @@
package grpc
import (
"net"
iproto "git.solsynth.dev/hypernet/insight/pkg/proto"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/spf13/viper"
"google.golang.org/grpc"
health "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"
)
type Server struct {
proto.UnimplementedDirectoryServiceServer
iproto.UnimplementedInsightServiceServer
health.UnimplementedHealthServer
srv *grpc.Server
}
func NewGrpc() *Server {
server := &Server{
srv: grpc.NewServer(),
}
proto.RegisterDirectoryServiceServer(server.srv, server)
iproto.RegisterInsightServiceServer(server.srv, server)
health.RegisterHealthServer(server.srv, server)
reflection.Register(server.srv)
return server
}
func (v *Server) Listen() error {
listener, err := net.Listen("tcp", viper.GetString("grpc_bind"))
if err != nil {
return err
}
return v.srv.Serve(listener)
}

View File

@ -0,0 +1,42 @@
package grpc
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"strconv"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"git.solsynth.dev/hypernet/insight/pkg/internal/database"
)
func (v *Server) BroadcastEvent(ctx context.Context, in *proto.EventInfo) (*proto.EventResponse, error) {
switch in.GetEvent() {
case "deletion":
data := nex.DecodeMap(in.GetData())
resType, ok := data["type"].(string)
if !ok {
break
}
switch resType {
case "account":
id, ok := data["id"].(string)
if !ok {
break
}
numericId, err := strconv.Atoi(id)
if err != nil {
break
}
tx := database.C.Begin()
for _, model := range database.AutoMaintainRange {
switch model.(type) {
default:
tx.Delete(model, "account_id = ?", numericId)
}
}
tx.Commit()
}
}
return &proto.EventResponse{}, nil
}

5
pkg/internal/meta.go Normal file
View File

@ -0,0 +1,5 @@
package pkg
const (
AppVersion = "1.0.0"
)

View File

@ -0,0 +1,19 @@
package api
import (
"git.solsynth.dev/hypernet/insight/pkg/internal/services"
"github.com/gofiber/fiber/v2"
)
func MapAPIs(app *fiber.App, baseURL string) {
api := app.Group(baseURL).Name("API")
{
api.Get("/status", func(c *fiber.Ctx) error {
err := services.PingOllama()
if err != nil {
return fiber.NewError(fiber.StatusServiceUnavailable, err.Error())
}
return c.SendStatus(fiber.StatusOK)
})
}
}

View File

@ -0,0 +1,18 @@
package exts
import (
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
)
var validation = validator.New(validator.WithRequiredStructEnabled())
func BindAndValidate(c *fiber.Ctx, out any) error {
if err := c.BodyParser(out); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if err := validation.Struct(out); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
return nil
}

View File

@ -0,0 +1,71 @@
package server
import (
"strings"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"git.solsynth.dev/hypernet/insight/pkg/internal/server/api"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/logger"
jsoniter "github.com/json-iterator/go"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
var IReader *sec.InternalTokenReader
type App struct {
app *fiber.App
}
func NewServer() *App {
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
EnableIPValidation: true,
ServerHeader: "Hypernet.Insight",
AppName: "Hypernet.Insight",
ProxyHeader: fiber.HeaderXForwardedFor,
JSONEncoder: jsoniter.ConfigCompatibleWithStandardLibrary.Marshal,
JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal,
BodyLimit: 512 * 1024 * 1024 * 1024, // 512 TiB
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
})
app.Use(idempotency.New())
app.Use(cors.New(cors.Config{
AllowCredentials: true,
AllowMethods: strings.Join([]string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodOptions,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
}, ","),
AllowOriginsFunc: func(origin string) bool {
return true
},
}))
app.Use(logger.New(logger.Config{
Format: "${status} | ${latency} | ${method} ${path}\n",
Output: log.Logger,
}))
app.Use(sec.ContextMiddleware(IReader))
api.MapAPIs(app, "/api")
return &App{app}
}
func (v *App) Listen() {
if err := v.app.Listen(viper.GetString("bind")); err != nil {
log.Fatal().Err(err).Msg("An error occurred when starting server...")
}
}

View File

@ -0,0 +1,24 @@
package services
import (
database2 "git.solsynth.dev/hypernet/insight/pkg/internal/database"
"time"
"github.com/rs/zerolog/log"
)
func DoAutoDatabaseCleanup() {
deadline := time.Now().Add(60 * time.Minute)
log.Debug().Time("deadline", deadline).Msg("Now cleaning up entire database...")
var count int64
for _, model := range database2.AutoMaintainRange {
tx := database2.C.Unscoped().Delete(model, "deleted_at >= ?", deadline)
if tx.Error != nil {
log.Error().Err(tx.Error).Msg("An error occurred when running auth context cleanup...")
}
count += tx.RowsAffected
}
log.Debug().Int64("affected", count).Msg("Clean up entire database accomplished.")
}

View File

@ -0,0 +1,59 @@
package services
import (
"context"
"fmt"
"net/http"
"time"
"github.com/spf13/viper"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/ollama"
"github.com/tmc/langchaingo/prompts"
)
func PingOllama() error {
host := viper.GetString("ollama.url")
resp, err := http.Get(host + "/api/version")
if err != nil {
return fmt.Errorf("failed to ping ollama: %v", err)
}
if resp.StatusCode != 200 {
return fmt.Errorf("ollama returned status code %d", resp.StatusCode)
}
return nil
}
var LargeModel *ollama.LLM
func ConnectOllama() error {
model := viper.GetString("ollama.model")
llm, err := ollama.New(ollama.WithModel(model))
if err != nil {
return err
}
LargeModel = llm
return nil
}
func GenerateInsights(source string) (string, error) {
prompt := prompts.NewPromptTemplate(
"Summerize this post on Solar Network below: {{.content}}",
[]string{"content"},
)
inPrompt, err := prompt.Format(map[string]any{
"content": source,
})
if err != nil {
return "", fmt.Errorf("failed to format prompt: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel()
completion, err := LargeModel.Call(ctx, inPrompt,
llms.WithTemperature(0.8),
)
return completion, err
}

View File

@ -0,0 +1,69 @@
package services
import (
"context"
"fmt"
"time"
"git.solsynth.dev/hypernet/insight/pkg/internal/gap"
wproto "git.solsynth.dev/hypernet/wallet/pkg/proto"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
)
// PlaceOrder create a transaction if needed for user
// Pricing is 128 words input cost 10 source points, round up.
func PlaceOrder(user uint, inputLength int) error {
amount := float64(inputLength+128-1) / 128
conn, err := gap.Nx.GetClientGrpcConn("wa")
if err != nil {
return fmt.Errorf("unable to connect wallet: %v", err)
}
wc := wproto.NewPaymentServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
resp, err := wc.MakeTransactionWithAccount(ctx, &wproto.MakeTransactionWithAccountRequest{
PayerAccountId: lo.ToPtr(uint64(user)),
Amount: amount,
Remark: "Insight Thinking Fee",
})
if err != nil {
return err
}
log.Info().
Uint64("transaction", resp.Id).Float64("amount", amount).
Msg("Order placed for charge insight thinking fee...")
return nil
}
// MakeRefund to user who got error in generating insight
func MakeRefund(user uint, inputLength int) error {
amount := float64(inputLength+128-1) / 128
conn, err := gap.Nx.GetClientGrpcConn("wa")
if err != nil {
return fmt.Errorf("unable to connect wallet: %v", err)
}
wc := wproto.NewPaymentServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
resp, err := wc.MakeTransactionWithAccount(ctx, &wproto.MakeTransactionWithAccountRequest{
PayeeAccountId: lo.ToPtr(uint64(user)),
Amount: amount,
Remark: "Insight Thinking Failed - Refund",
})
if err != nil {
return err
}
log.Info().
Uint64("transaction", resp.Id).Float64("amount", amount).
Msg("Refund placed for insight thinking fee...")
return nil
}

97
pkg/main.go Normal file
View File

@ -0,0 +1,97 @@
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
pkg "git.solsynth.dev/hypernet/insight/pkg/internal"
"git.solsynth.dev/hypernet/insight/pkg/internal/gap"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/fatih/color"
"git.solsynth.dev/hypernet/insight/pkg/internal/cache"
"git.solsynth.dev/hypernet/insight/pkg/internal/database"
"git.solsynth.dev/hypernet/insight/pkg/internal/grpc"
"git.solsynth.dev/hypernet/insight/pkg/internal/server"
"git.solsynth.dev/hypernet/insight/pkg/internal/services"
"github.com/robfig/cron/v3"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
func init() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
}
func main() {
// Booting screen
fmt.Println(color.YellowString(" ___ _ _ _\n|_ _|_ __ ___(_) __ _| |__ | |_\n | || '_ \\/ __| |/ _` | '_ \\| __|\n | || | | \\__ \\ | (_| | | | | |_\n|___|_| |_|___/_|\\__, |_| |_|\\__|\n |___/"))
fmt.Printf("%s v%s\n", color.New(color.FgHiYellow).Add(color.Bold).Sprintf("Hypernet.Insight"), pkg.AppVersion)
fmt.Printf("The A-word in Hypernet.\n")
color.HiBlack("=====================================================\n")
// Configure settings
viper.AddConfigPath(".")
viper.AddConfigPath("..")
viper.SetConfigName("settings")
viper.SetConfigType("toml")
// Load settings
if err := viper.ReadInConfig(); err != nil {
log.Panic().Err(err).Msg("An error occurred when loading settings.")
}
// Connect to nexus
if err := gap.InitializeToNexus(); err != nil {
log.Error().Err(err).Msg("An error occurred when registering service to nexus...")
}
// Load keypair
if reader, err := sec.NewInternalTokenReader(viper.GetString("security.internal_public_key")); err != nil {
log.Error().Err(err).Msg("An error occurred when reading internal public key for jwt. Authentication related features will be disabled.")
} else {
server.IReader = reader
log.Info().Msg("Internal jwt public key loaded.")
}
// Connect to database
if err := database.NewGorm(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when connect to database.")
} else if err := database.RunMigration(database.C); err != nil {
log.Fatal().Err(err).Msg("An error occurred when running database auto migration.")
}
// Connect to ollama
if err := services.ConnectOllama(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when connecting to ollama.")
}
// Initialize cache
if err := cache.NewStore(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when initializing cache.")
}
// Configure timed tasks
quartz := cron.New(cron.WithLogger(cron.VerbosePrintfLogger(&log.Logger)))
quartz.AddFunc("@every 60m", services.DoAutoDatabaseCleanup)
quartz.Start()
// Server
go server.NewServer().Listen()
// Grpc Server
go grpc.NewGrpc().Listen()
// Messages
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
quartz.Stop()
}

192
pkg/proto/insight.pb.go Normal file
View File

@ -0,0 +1,192 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.3
// source: insight.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type InsightRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"`
UserId uint64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
}
func (x *InsightRequest) Reset() {
*x = InsightRequest{}
mi := &file_insight_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *InsightRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InsightRequest) ProtoMessage() {}
func (x *InsightRequest) ProtoReflect() protoreflect.Message {
mi := &file_insight_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InsightRequest.ProtoReflect.Descriptor instead.
func (*InsightRequest) Descriptor() ([]byte, []int) {
return file_insight_proto_rawDescGZIP(), []int{0}
}
func (x *InsightRequest) GetSource() string {
if x != nil {
return x.Source
}
return ""
}
func (x *InsightRequest) GetUserId() uint64 {
if x != nil {
return x.UserId
}
return 0
}
type InsightResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
}
func (x *InsightResponse) Reset() {
*x = InsightResponse{}
mi := &file_insight_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *InsightResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InsightResponse) ProtoMessage() {}
func (x *InsightResponse) ProtoReflect() protoreflect.Message {
mi := &file_insight_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InsightResponse.ProtoReflect.Descriptor instead.
func (*InsightResponse) Descriptor() ([]byte, []int) {
return file_insight_proto_rawDescGZIP(), []int{1}
}
func (x *InsightResponse) GetResponse() string {
if x != nil {
return x.Response
}
return ""
}
var File_insight_proto protoreflect.FileDescriptor
var file_insight_proto_rawDesc = []byte{
0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x0f, 0x49, 0x6e, 0x73,
0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x54, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x69,
0x67, 0x68, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65,
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x12, 0x15, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73,
0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x09,
0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_insight_proto_rawDescOnce sync.Once
file_insight_proto_rawDescData = file_insight_proto_rawDesc
)
func file_insight_proto_rawDescGZIP() []byte {
file_insight_proto_rawDescOnce.Do(func() {
file_insight_proto_rawDescData = protoimpl.X.CompressGZIP(file_insight_proto_rawDescData)
})
return file_insight_proto_rawDescData
}
var file_insight_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_insight_proto_goTypes = []any{
(*InsightRequest)(nil), // 0: proto.InsightRequest
(*InsightResponse)(nil), // 1: proto.InsightResponse
}
var file_insight_proto_depIdxs = []int32{
0, // 0: proto.InsightService.GenerateInsight:input_type -> proto.InsightRequest
1, // 1: proto.InsightService.GenerateInsight:output_type -> proto.InsightResponse
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_insight_proto_init() }
func file_insight_proto_init() {
if File_insight_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_insight_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_insight_proto_goTypes,
DependencyIndexes: file_insight_proto_depIdxs,
MessageInfos: file_insight_proto_msgTypes,
}.Build()
File_insight_proto = out.File
file_insight_proto_rawDesc = nil
file_insight_proto_goTypes = nil
file_insight_proto_depIdxs = nil
}

18
pkg/proto/insight.proto Normal file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
option go_package = ".;proto";
package proto;
service InsightService {
rpc GenerateInsight(InsightRequest) returns (InsightResponse) {}
}
message InsightRequest {
string source = 1;
uint64 user_id = 2;
}
message InsightResponse {
string response = 1;
}

View File

@ -0,0 +1,121 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.3
// source: insight.proto
package proto
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
InsightService_GenerateInsight_FullMethodName = "/proto.InsightService/GenerateInsight"
)
// InsightServiceClient is the client API for InsightService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type InsightServiceClient interface {
GenerateInsight(ctx context.Context, in *InsightRequest, opts ...grpc.CallOption) (*InsightResponse, error)
}
type insightServiceClient struct {
cc grpc.ClientConnInterface
}
func NewInsightServiceClient(cc grpc.ClientConnInterface) InsightServiceClient {
return &insightServiceClient{cc}
}
func (c *insightServiceClient) GenerateInsight(ctx context.Context, in *InsightRequest, opts ...grpc.CallOption) (*InsightResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(InsightResponse)
err := c.cc.Invoke(ctx, InsightService_GenerateInsight_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// InsightServiceServer is the server API for InsightService service.
// All implementations must embed UnimplementedInsightServiceServer
// for forward compatibility.
type InsightServiceServer interface {
GenerateInsight(context.Context, *InsightRequest) (*InsightResponse, error)
mustEmbedUnimplementedInsightServiceServer()
}
// UnimplementedInsightServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedInsightServiceServer struct{}
func (UnimplementedInsightServiceServer) GenerateInsight(context.Context, *InsightRequest) (*InsightResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GenerateInsight not implemented")
}
func (UnimplementedInsightServiceServer) mustEmbedUnimplementedInsightServiceServer() {}
func (UnimplementedInsightServiceServer) testEmbeddedByValue() {}
// UnsafeInsightServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to InsightServiceServer will
// result in compilation errors.
type UnsafeInsightServiceServer interface {
mustEmbedUnimplementedInsightServiceServer()
}
func RegisterInsightServiceServer(s grpc.ServiceRegistrar, srv InsightServiceServer) {
// If the following call pancis, it indicates UnimplementedInsightServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&InsightService_ServiceDesc, srv)
}
func _InsightService_GenerateInsight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InsightRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InsightServiceServer).GenerateInsight(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: InsightService_GenerateInsight_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InsightServiceServer).GenerateInsight(ctx, req.(*InsightRequest))
}
return interceptor(ctx, in, info, handler)
}
// InsightService_ServiceDesc is the grpc.ServiceDesc for InsightService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var InsightService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.InsightService",
HandlerType: (*InsightServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GenerateInsight",
Handler: _InsightService_GenerateInsight_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "insight.proto",
}