Agent par défaut
This commit is contained in:
1 parent
cf10b9073b
commit
f74e4d1043
24 files changed
+385
-37
No files matched your search
@@ -63,7 +63,7 @@ create table user_addresses (
|
||||
create table teams (
|
||||
id text not null primary key,
|
||||
label text not null,
|
||||
default_model_id text,
|
||||
default_agent_id text,
|
||||
_date_created numeric not null default current_timestamp,
|
||||
_date_updated numeric ,
|
||||
_version text not null
|
||||
|
||||
@@ -68,7 +68,7 @@ func (ur *TursoUserRepository) DeleteUser(id string) error {
|
||||
}
|
||||
|
||||
func (ur *TursoUserRepository) FindTeam(userid string, teamid string) (*domain.Team, error) {
|
||||
return ur.TeamTable.SelectOne("id=$1 and user_id=$2", teamid, userid)
|
||||
return ur.TeamTable.SelectOne("id=$1 and id in (select team_id from user_teams where user_id=$2)", teamid, userid)
|
||||
}
|
||||
|
||||
func (ur *TursoUserRepository) ListTeams(userid string) ([]*domain.Team, error) {
|
||||
|
||||
@@ -74,3 +74,48 @@ func (e *AnyLLMEngine) ListModelsFromProvider(ctx context.Context, provider *dom
|
||||
}
|
||||
return models, nil
|
||||
}
|
||||
|
||||
func (e *AnyLLMEngine) Stream(
|
||||
ctx context.Context,
|
||||
provider *domain.Provider,
|
||||
modelID string,
|
||||
params *domain.StreamParams,
|
||||
messages []*domain.Message,
|
||||
) error {
|
||||
|
||||
p, err := providerFactory(provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
anyllmMessages := make([]anyllm.Message, 0)
|
||||
for _, m := range messages {
|
||||
anyllmMessages = append(anyllmMessages, anyllm.Message{
|
||||
Role: m.Role,
|
||||
Content: m.Content,
|
||||
})
|
||||
}
|
||||
|
||||
chunkChan, errChan := p.CompletionStream(ctx, anyllm.CompletionParams{
|
||||
Model: modelID,
|
||||
Messages: anyllmMessages,
|
||||
Stream: true,
|
||||
})
|
||||
|
||||
for chunk := range chunkChan {
|
||||
if len(chunk.Choices) > 0 {
|
||||
content := chunk.Choices[0].Delta.Content
|
||||
if params.OnChunk != nil {
|
||||
params.OnChunk(&domain.Chunk{
|
||||
Content: content,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := <-errChan; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -13,6 +13,7 @@ const (
|
||||
DEFAULT_DB_URL = "lassistanoque.db"
|
||||
DEFAULT_HTTP_PORT = 3000
|
||||
DEFAULT_STORAGE_TYPE = "database"
|
||||
DEFAULT_SERVER_ID = "default"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@@ -27,6 +28,7 @@ type Config struct {
|
||||
StorageS3AccessKeyID string // S3
|
||||
StorageS3AccessKeySecret string // S3
|
||||
StorageS3UseSSL string // S3
|
||||
ServerID string
|
||||
}
|
||||
|
||||
var config *Config
|
||||
@@ -56,6 +58,10 @@ func GetConfig() *Config {
|
||||
if storageType == "" {
|
||||
storageType = DEFAULT_STORAGE_TYPE
|
||||
}
|
||||
serverID := os.Getenv("LASSISTANOQUE_SERVER_ID")
|
||||
if serverID == "" {
|
||||
serverID = DEFAULT_SERVER_ID
|
||||
}
|
||||
|
||||
config = &Config{
|
||||
DatabaseType: databaseType,
|
||||
@@ -63,6 +69,7 @@ func GetConfig() *Config {
|
||||
HttpPort: httpPort,
|
||||
JWTSecret: jwtsecret,
|
||||
StorageType: storageType,
|
||||
ServerID: serverID,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,48 @@ type LLMModel struct {
|
||||
Detail *LLMModelDetail `json:"detail"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Role string
|
||||
Content string
|
||||
ToolCalls []ToolCall
|
||||
ToolCallID string
|
||||
|
||||
//Reasoning *Reasoning
|
||||
}
|
||||
|
||||
type Tool struct {
|
||||
}
|
||||
|
||||
type ToolCall struct {
|
||||
}
|
||||
|
||||
type Chunk struct {
|
||||
Content string
|
||||
}
|
||||
|
||||
type StreamParams struct {
|
||||
Tools []*Tool
|
||||
OnChunk func(chunk *Chunk)
|
||||
OnDebug func()
|
||||
}
|
||||
|
||||
type Role string
|
||||
|
||||
const (
|
||||
RoleSystem Role = "system"
|
||||
RoleUser Role = "user"
|
||||
RoleAssistant Role = "assistant"
|
||||
RoleTool Role = "tool"
|
||||
)
|
||||
|
||||
type LLMEngine interface {
|
||||
ListProviderTypes() []Item
|
||||
ListModelsFromProvider(ctx context.Context, provider *Provider) ([]string, error)
|
||||
Stream(
|
||||
ctx context.Context,
|
||||
provider *Provider,
|
||||
modelID string,
|
||||
params *StreamParams,
|
||||
messages []*Message,
|
||||
) error
|
||||
}
|
||||
@@ -23,7 +23,7 @@ type User struct {
|
||||
type Team struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
Label string `db:"label" json:"label"`
|
||||
DefaultModelID *string `db:"default_model_id" json:"defaultModelId"`
|
||||
DefaultAgentID *string `db:"default_agent_id" json:"defaultAgentId"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_dateCreated"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_dateUpdated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
|
||||
@@ -7,11 +7,19 @@ import (
|
||||
"trankilou.fr/lassistanoque/backend/internal/domain"
|
||||
"trankilou.fr/lassistanoque/backend/internal/service/agent"
|
||||
"trankilou.fr/lassistanoque/backend/internal/service/auth"
|
||||
"trankilou.fr/lassistanoque/backend/internal/service/user"
|
||||
)
|
||||
|
||||
func NewAgentGroup(prefix string, e *echo.Group, service *agent.Service, middlewares ...echo.MiddlewareFunc) *echo.Group {
|
||||
func NewAgentGroup(
|
||||
prefix string,
|
||||
e *echo.Group,
|
||||
agentService *agent.Service,
|
||||
userService *user.Service,
|
||||
middlewares ...echo.MiddlewareFunc) *echo.Group {
|
||||
|
||||
agentHandler := &AgentHandler{
|
||||
agentService: service,
|
||||
agentService: agentService,
|
||||
userService: userService,
|
||||
}
|
||||
agent := e.Group(prefix, middlewares...)
|
||||
|
||||
@@ -26,6 +34,7 @@ func NewAgentGroup(prefix string, e *echo.Group, service *agent.Service, middlew
|
||||
|
||||
type AgentHandler struct {
|
||||
agentService *agent.Service
|
||||
userService *user.Service
|
||||
}
|
||||
|
||||
func (h *AgentHandler) ListAgents(c *echo.Context) error {
|
||||
@@ -98,3 +107,11 @@ func (h *AgentHandler) DeleteAgent(c *echo.Context) error {
|
||||
}
|
||||
return c.JSON(http.StatusOK, agentID)
|
||||
}
|
||||
|
||||
type DefaulAgentRequest struct {
|
||||
AgentID string `json:"AgentId"`
|
||||
}
|
||||
type DefaulAgentResponse struct {
|
||||
NewDefaultAgentID *string `json:"newDefaultAgentId"`
|
||||
OldDefaultAgentID *string `json:"oldDefaultAgentId"`
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v5"
|
||||
"trankilou.fr/lassistanoque/backend/internal/domain"
|
||||
"trankilou.fr/lassistanoque/backend/internal/service/auth"
|
||||
"trankilou.fr/lassistanoque/backend/internal/service/user"
|
||||
)
|
||||
|
||||
func NewTeamGroup(prefix string, e *echo.Group, service *user.Service, middlewares ...echo.MiddlewareFunc) *echo.Group {
|
||||
teamHandler := &TeamHandler{
|
||||
userService: service,
|
||||
}
|
||||
h := e.Group(prefix, middlewares...)
|
||||
h.GET("/:team", teamHandler.Get)
|
||||
h.PUT("/:team", teamHandler.Update)
|
||||
return h
|
||||
}
|
||||
|
||||
type TeamHandler struct {
|
||||
userService *user.Service
|
||||
}
|
||||
|
||||
func (h TeamHandler) Get(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
teamID := c.Param("team")
|
||||
user, err := h.userService.GetTeam(userID, teamID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
|
||||
}
|
||||
return c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
func (h TeamHandler) Update(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
teamID := c.Param("team")
|
||||
|
||||
var updTeam domain.Team
|
||||
if err := c.Bind(&updTeam); err != nil {
|
||||
return c.String(http.StatusBadRequest, "bad request")
|
||||
}
|
||||
|
||||
if teamID != updTeam.ID {
|
||||
return c.String(http.StatusBadRequest, "bad request")
|
||||
}
|
||||
|
||||
user, err := h.userService.UpdateTeam(userID, &updTeam)
|
||||
if err != nil {
|
||||
return c.String(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, user)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
@@ -30,7 +31,7 @@ var indexhtml []byte
|
||||
var robotstxt []byte
|
||||
|
||||
type Router struct {
|
||||
echo *echo.Echo
|
||||
server *http.Server
|
||||
}
|
||||
|
||||
type Dependencies struct {
|
||||
@@ -44,6 +45,8 @@ type Dependencies struct {
|
||||
|
||||
func NewRouter(deps Dependencies) *Router {
|
||||
|
||||
cfg := config.GetConfig()
|
||||
|
||||
e := echo.New()
|
||||
e.Use(middleware.RequestLogger())
|
||||
e.Use(middleware.CORS("http://localhost:5173"))
|
||||
@@ -76,14 +79,23 @@ func NewRouter(deps Dependencies) *Router {
|
||||
_ = handlers.NewUserGroup("/user", api, deps.UserService, deps.TokenManager.TokenMiddleware)
|
||||
_ = handlers.NewMiscGroup("/misc", api, deps.TokenManager.TokenMiddleware)
|
||||
_ = handlers.NewModelGroup("/provider", api, deps.ProviderService, deps.TokenManager.TokenMiddleware)
|
||||
_ = handlers.NewAgentGroup("/agent", api, deps.AgentService, deps.TokenManager.TokenMiddleware)
|
||||
_ = handlers.NewAgentGroup("/agent", api, deps.AgentService, deps.UserService, deps.TokenManager.TokenMiddleware)
|
||||
_ = handlers.NewTeamGroup("/team", api, deps.UserService, deps.TokenManager.TokenMiddleware)
|
||||
|
||||
server := http.Server{
|
||||
Addr: fmt.Sprintf(":%d", cfg.HttpPort),
|
||||
Handler: e,
|
||||
}
|
||||
|
||||
return &Router{
|
||||
echo: e,
|
||||
&server,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) Start() error {
|
||||
cfg := config.GetConfig()
|
||||
return r.echo.Start(fmt.Sprintf(":%d", cfg.HttpPort))
|
||||
return r.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (r *Router) Stop(ctx context.Context) error {
|
||||
return r.server.Shutdown(ctx)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package llmserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"trankilou.fr/lassistanoque/backend/internal/utility"
|
||||
)
|
||||
|
||||
type Dependencies struct {
|
||||
}
|
||||
|
||||
type LLMServer struct {
|
||||
started bool
|
||||
mu sync.Mutex
|
||||
sessions map[string]*Session // running sessions
|
||||
newSessionChan chan string
|
||||
closeChan chan bool
|
||||
}
|
||||
|
||||
func NewLLMServer(deps Dependencies) *LLMServer {
|
||||
return &LLMServer{
|
||||
started: true,
|
||||
sessions: make(map[string]*Session),
|
||||
newSessionChan: make(chan string),
|
||||
closeChan: make(chan bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LLMServer) Start() error {
|
||||
|
||||
for {
|
||||
select {
|
||||
case _ = <-s.closeChan:
|
||||
fmt.Println("Closing LLM Server")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *LLMServer) Stop(ctx context.Context) error {
|
||||
s.closeChan <- true
|
||||
s.started = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LLMServer) StartSession() (*Session, error) {
|
||||
sid := utility.GenID()
|
||||
session := &Session{}
|
||||
|
||||
s.mu.Lock()
|
||||
s.sessions[sid] = session
|
||||
s.mu.Unlock()
|
||||
|
||||
return session, nil
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package llmserver
|
||||
|
||||
type Session struct {
|
||||
server string
|
||||
}
|
||||
@@ -105,3 +105,24 @@ func (s *Service) DeleteAddress(userId string, addressId string) error {
|
||||
}
|
||||
return s.repo.DeleteUserAddress(addressId)
|
||||
}
|
||||
|
||||
func (s *Service) GetTeam(userid, id string) (*domain.Team, error) {
|
||||
team, err := s.repo.FindTeam(userid, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return team, nil
|
||||
}
|
||||
|
||||
func (s *Service) UpdateTeam(userid string, team *domain.Team) (*domain.Team, error) {
|
||||
updTeam, err := s.repo.FindTeam(userid, team.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updTeam.Label = team.Label
|
||||
updTeam.DefaultAgentID = team.DefaultAgentID
|
||||
|
||||
return s.repo.UpdateTeam(userid, updTeam)
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user