mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-08-24 03:56:32 +00:00
feat(settings): add version and isDevelopMode fields to Settings model and GraphQL schema
- Introduced new fields `version` and `isDevelopMode` in the Settings model to provide application versioning and development mode status. - Updated GraphQL schema and resolvers to support the new fields, ensuring they are accessible via the Settings query. - Enhanced Swagger documentation to reflect the changes in the Settings API endpoint. - Added necessary validation and response handling for the new fields in the Settings service.
This commit is contained in:
@@ -536,6 +536,8 @@ type ComplexityRoot struct {
|
||||
AssistantUseAgents func(childComplexity int) int
|
||||
Debug func(childComplexity int) int
|
||||
DockerInside func(childComplexity int) int
|
||||
IsDevelopMode func(childComplexity int) int
|
||||
Version func(childComplexity int) int
|
||||
}
|
||||
|
||||
Subscription struct {
|
||||
@@ -3540,6 +3542,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Settings.DockerInside(childComplexity), true
|
||||
|
||||
case "Settings.isDevelopMode":
|
||||
if e.complexity.Settings.IsDevelopMode == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Settings.IsDevelopMode(childComplexity), true
|
||||
|
||||
case "Settings.version":
|
||||
if e.complexity.Settings.Version == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Settings.Version(childComplexity), true
|
||||
|
||||
case "Subscription.apiTokenCreated":
|
||||
if e.complexity.Subscription.APITokenCreated == nil {
|
||||
break
|
||||
@@ -23912,8 +23928,12 @@ func (ec *executionContext) fieldContext_Query_settings(_ context.Context, field
|
||||
return ec.fieldContext_Settings_debug(ctx, field)
|
||||
case "askUser":
|
||||
return ec.fieldContext_Settings_askUser(ctx, field)
|
||||
case "version":
|
||||
return ec.fieldContext_Settings_version(ctx, field)
|
||||
case "dockerInside":
|
||||
return ec.fieldContext_Settings_dockerInside(ctx, field)
|
||||
case "isDevelopMode":
|
||||
return ec.fieldContext_Settings_isDevelopMode(ctx, field)
|
||||
case "assistantUseAgents":
|
||||
return ec.fieldContext_Settings_assistantUseAgents(ctx, field)
|
||||
}
|
||||
@@ -25680,6 +25700,50 @@ func (ec *executionContext) fieldContext_Settings_askUser(_ context.Context, fie
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Settings_version(ctx context.Context, field graphql.CollectedField, obj *model.Settings) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Settings_version(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Version, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Settings_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Settings",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Settings_dockerInside(ctx context.Context, field graphql.CollectedField, obj *model.Settings) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Settings_dockerInside(ctx, field)
|
||||
if err != nil {
|
||||
@@ -25724,6 +25788,50 @@ func (ec *executionContext) fieldContext_Settings_dockerInside(_ context.Context
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Settings_isDevelopMode(ctx context.Context, field graphql.CollectedField, obj *model.Settings) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Settings_isDevelopMode(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.IsDevelopMode, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(bool)
|
||||
fc.Result = res
|
||||
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Settings_isDevelopMode(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Settings",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Boolean does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Settings_assistantUseAgents(ctx context.Context, field graphql.CollectedField, obj *model.Settings) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Settings_assistantUseAgents(ctx, field)
|
||||
if err != nil {
|
||||
@@ -39224,11 +39332,21 @@ func (ec *executionContext) _Settings(ctx context.Context, sel ast.SelectionSet,
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "version":
|
||||
out.Values[i] = ec._Settings_version(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "dockerInside":
|
||||
out.Values[i] = ec._Settings_dockerInside(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "isDevelopMode":
|
||||
out.Values[i] = ec._Settings_isDevelopMode(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "assistantUseAgents":
|
||||
out.Values[i] = ec._Settings_assistantUseAgents(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
|
||||
@@ -448,10 +448,12 @@ type SearchLog struct {
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
Debug bool `json:"debug"`
|
||||
AskUser bool `json:"askUser"`
|
||||
DockerInside bool `json:"dockerInside"`
|
||||
AssistantUseAgents bool `json:"assistantUseAgents"`
|
||||
Debug bool `json:"debug"`
|
||||
AskUser bool `json:"askUser"`
|
||||
Version string `json:"version"`
|
||||
DockerInside bool `json:"dockerInside"`
|
||||
IsDevelopMode bool `json:"isDevelopMode"`
|
||||
AssistantUseAgents bool `json:"assistantUseAgents"`
|
||||
}
|
||||
|
||||
type Subscription struct {
|
||||
|
||||
@@ -158,7 +158,9 @@ enum VectorStoreAction {
|
||||
type Settings {
|
||||
debug: Boolean!
|
||||
askUser: Boolean!
|
||||
version: String!
|
||||
dockerInside: Boolean!
|
||||
isDevelopMode: Boolean!
|
||||
assistantUseAgents: Boolean!
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"pentagi/pkg/server/auth"
|
||||
"pentagi/pkg/templates"
|
||||
"pentagi/pkg/templates/validator"
|
||||
"pentagi/pkg/version"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -1960,7 +1961,9 @@ func (r *queryResolver) Settings(ctx context.Context) (*model.Settings, error) {
|
||||
settings := &model.Settings{
|
||||
Debug: r.Config.Debug,
|
||||
AskUser: r.Config.AskUser,
|
||||
Version: version.GetBinaryVersion(),
|
||||
DockerInside: r.Config.DockerInside,
|
||||
IsDevelopMode: version.IsDevelopMode(),
|
||||
AssistantUseAgents: r.Config.AssistantUseAgents,
|
||||
}
|
||||
|
||||
|
||||
@@ -5155,7 +5155,10 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/models.ProviderInfo"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.ProviderInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6095,6 +6098,48 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/settings/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Settings"
|
||||
],
|
||||
"summary": "Retrieve settings",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "settings received successful",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SuccessResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/models.Settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "getting settings not permitted",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/termlogs/": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -8469,6 +8514,53 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"agent_types",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"agent_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "gpt-4o"
|
||||
},
|
||||
"price_info": {
|
||||
"$ref": "#/definitions/models.ModelPriceInfo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelPriceInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cache_read": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 0.1
|
||||
},
|
||||
"cache_write": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 0.3
|
||||
},
|
||||
"input": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 1.1
|
||||
},
|
||||
"output": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelUsageStats": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -8744,10 +8836,22 @@ const docTemplate = `{
|
||||
"models.ProviderInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"default_model",
|
||||
"models",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"default_model": {
|
||||
"type": "string",
|
||||
"example": "gpt-4o"
|
||||
},
|
||||
"models": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.ModelInfo"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "my openai provider"
|
||||
@@ -8956,6 +9060,35 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Settings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ask_user": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"assistant_use_agents": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"debug": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"docker_inside": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"is_develop_mode": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"example": "v1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Subtask": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -5147,7 +5147,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/models.ProviderInfo"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.ProviderInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6087,6 +6090,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/settings/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Settings"
|
||||
],
|
||||
"summary": "Retrieve settings",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "settings received successful",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SuccessResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/models.Settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "getting settings not permitted",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/termlogs/": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -8461,6 +8506,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"agent_types",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"agent_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "gpt-4o"
|
||||
},
|
||||
"price_info": {
|
||||
"$ref": "#/definitions/models.ModelPriceInfo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelPriceInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cache_read": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 0.1
|
||||
},
|
||||
"cache_write": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 0.3
|
||||
},
|
||||
"input": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 1.1
|
||||
},
|
||||
"output": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"example": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ModelUsageStats": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -8736,10 +8828,22 @@
|
||||
"models.ProviderInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"default_model",
|
||||
"models",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"default_model": {
|
||||
"type": "string",
|
||||
"example": "gpt-4o"
|
||||
},
|
||||
"models": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.ModelInfo"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "my openai provider"
|
||||
@@ -8948,6 +9052,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Settings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ask_user": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"assistant_use_agents": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"debug": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"docker_inside": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"is_develop_mode": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"example": "v1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Subtask": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -917,6 +917,40 @@ definitions:
|
||||
required:
|
||||
- path
|
||||
type: object
|
||||
models.ModelInfo:
|
||||
properties:
|
||||
agent_types:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
example: gpt-4o
|
||||
type: string
|
||||
price_info:
|
||||
$ref: '#/definitions/models.ModelPriceInfo'
|
||||
required:
|
||||
- agent_types
|
||||
- name
|
||||
type: object
|
||||
models.ModelPriceInfo:
|
||||
properties:
|
||||
cache_read:
|
||||
example: 0.1
|
||||
minimum: 0
|
||||
type: number
|
||||
cache_write:
|
||||
example: 0.3
|
||||
minimum: 0
|
||||
type: number
|
||||
input:
|
||||
example: 1.1
|
||||
minimum: 0
|
||||
type: number
|
||||
output:
|
||||
example: 3
|
||||
minimum: 0
|
||||
type: number
|
||||
type: object
|
||||
models.ModelUsageStats:
|
||||
properties:
|
||||
model:
|
||||
@@ -1115,6 +1149,13 @@ definitions:
|
||||
type: object
|
||||
models.ProviderInfo:
|
||||
properties:
|
||||
default_model:
|
||||
example: gpt-4o
|
||||
type: string
|
||||
models:
|
||||
items:
|
||||
$ref: '#/definitions/models.ModelInfo'
|
||||
type: array
|
||||
name:
|
||||
example: my openai provider
|
||||
type: string
|
||||
@@ -1122,6 +1163,8 @@ definitions:
|
||||
example: openai
|
||||
type: string
|
||||
required:
|
||||
- default_model
|
||||
- models
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
@@ -1265,6 +1308,27 @@ definitions:
|
||||
- initiator
|
||||
- query
|
||||
type: object
|
||||
models.Settings:
|
||||
properties:
|
||||
ask_user:
|
||||
example: false
|
||||
type: boolean
|
||||
assistant_use_agents:
|
||||
example: false
|
||||
type: boolean
|
||||
debug:
|
||||
example: false
|
||||
type: boolean
|
||||
docker_inside:
|
||||
example: false
|
||||
type: boolean
|
||||
is_develop_mode:
|
||||
example: false
|
||||
type: boolean
|
||||
version:
|
||||
example: v1.0.0
|
||||
type: string
|
||||
type: object
|
||||
models.Subtask:
|
||||
properties:
|
||||
context:
|
||||
@@ -5330,7 +5394,9 @@ paths:
|
||||
- $ref: '#/definitions/SuccessResponse'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/models.ProviderInfo'
|
||||
items:
|
||||
$ref: '#/definitions/models.ProviderInfo'
|
||||
type: array
|
||||
type: object
|
||||
"403":
|
||||
description: getting providers not permitted
|
||||
@@ -5946,6 +6012,29 @@ paths:
|
||||
summary: Retrieve searchlogs list
|
||||
tags:
|
||||
- Searchlogs
|
||||
/settings/:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: settings received successful
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/SuccessResponse'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/models.Settings'
|
||||
type: object
|
||||
"403":
|
||||
description: getting settings not permitted
|
||||
schema:
|
||||
$ref: '#/definitions/ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Retrieve settings
|
||||
tags:
|
||||
- Settings
|
||||
/termlogs/:
|
||||
get:
|
||||
parameters:
|
||||
|
||||
@@ -96,11 +96,35 @@ func (pp PatchProvider) Valid() error {
|
||||
return validate.Struct(pp)
|
||||
}
|
||||
|
||||
// ModelPriceInfo is model to contain price information for a model
|
||||
// nolint:lll
|
||||
type ModelPriceInfo struct {
|
||||
Input float64 `form:"input" json:"input" validate:"omitempty,numeric,min=0" example:"1.1"`
|
||||
Output float64 `form:"output" json:"output" validate:"omitempty,numeric,min=0" example:"3.0"`
|
||||
CacheRead float64 `form:"cache_read" json:"cache_read" validate:"omitempty,numeric,min=0" example:"0.1"`
|
||||
CacheWrite float64 `form:"cache_write" json:"cache_write" validate:"omitempty,numeric,min=0" example:"0.3"`
|
||||
}
|
||||
|
||||
// Valid is function to control input/output data
|
||||
func (mpi ModelPriceInfo) Valid() error {
|
||||
return validate.Struct(mpi)
|
||||
}
|
||||
|
||||
// ModelInfo is model to contain model short information for display
|
||||
// nolint:lll
|
||||
type ModelInfo struct {
|
||||
Name string `form:"name" json:"name" validate:"required" example:"gpt-4o"`
|
||||
AgentTypes []string `form:"agent_types" json:"agent_types" validate:"required"`
|
||||
PriceInfo *ModelPriceInfo `form:"price_info" json:"price_info" validate:"omitempty,valid"`
|
||||
}
|
||||
|
||||
// ProviderInfo is model to contain provider short information for display
|
||||
// nolint:lll
|
||||
type ProviderInfo struct {
|
||||
Name string `form:"name" json:"name" validate:"required" example:"my openai provider"`
|
||||
Type ProviderType `form:"type" json:"type" validate:"valid,required" example:"openai"`
|
||||
Name string `form:"name" json:"name" validate:"required" example:"my openai provider"`
|
||||
Type ProviderType `form:"type" json:"type" validate:"valid,required" example:"openai"`
|
||||
DefaultModel string `form:"default_model" json:"default_model" validate:"required" example:"gpt-4o"`
|
||||
Models []ModelInfo `form:"models" json:"models" validate:"required"`
|
||||
}
|
||||
|
||||
// Valid is function to control input/output data
|
||||
|
||||
@@ -141,21 +141,43 @@ func TestPatchProviderValid(t *testing.T) {
|
||||
func TestProviderInfoValid(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validInfo := ProviderInfo{
|
||||
Name: "my-provider",
|
||||
Type: ProviderType("openai"),
|
||||
DefaultModel: "gpt-4o",
|
||||
Models: []ModelInfo{{Name: "gpt-4o", AgentTypes: []string{"primary_agent"}}},
|
||||
}
|
||||
|
||||
t.Run("valid provider info", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
pi := ProviderInfo{Name: "my-provider", Type: ProviderType("openai")}
|
||||
assert.NoError(t, pi.Valid())
|
||||
assert.NoError(t, validInfo.Valid())
|
||||
})
|
||||
|
||||
t.Run("missing name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
pi := ProviderInfo{Name: "", Type: ProviderType("openai")}
|
||||
pi := validInfo
|
||||
pi.Name = ""
|
||||
assert.Error(t, pi.Valid())
|
||||
})
|
||||
|
||||
t.Run("invalid type", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
pi := ProviderInfo{Name: "my-provider", Type: ProviderType("invalid")}
|
||||
pi := validInfo
|
||||
pi.Type = ProviderType("invalid")
|
||||
assert.Error(t, pi.Valid())
|
||||
})
|
||||
|
||||
t.Run("missing default model", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
pi := validInfo
|
||||
pi.DefaultModel = ""
|
||||
assert.Error(t, pi.Valid())
|
||||
})
|
||||
|
||||
t.Run("missing models", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
pi := validInfo
|
||||
pi.Models = nil
|
||||
assert.Error(t, pi.Valid())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package models
|
||||
|
||||
// Settings is model to contain application settings information
|
||||
// nolint:lll
|
||||
type Settings struct {
|
||||
Debug bool `json:"debug" example:"false"`
|
||||
AskUser bool `json:"ask_user" example:"false"`
|
||||
Version string `json:"version" example:"v1.0.0"`
|
||||
DockerInside bool `json:"docker_inside" example:"false"`
|
||||
IsDevelopMode bool `json:"is_develop_mode" example:"false"`
|
||||
AssistantUseAgents bool `json:"assistant_use_agents" example:"false"`
|
||||
}
|
||||
|
||||
// Valid is function to control input/output data
|
||||
func (s Settings) Valid() error {
|
||||
return validate.Struct(s)
|
||||
}
|
||||
@@ -155,6 +155,7 @@ func NewRouter(
|
||||
userService := services.NewUserService(orm, userCache)
|
||||
roleService := services.NewRoleService(orm)
|
||||
providerService := services.NewProviderService(providers)
|
||||
settingsService := services.NewSettingsService(cfg)
|
||||
flowService := services.NewFlowService(orm, providers, controller, subscriptions)
|
||||
flowFileService := services.NewFlowFileService(orm, cfg.DataDir, dockerClient, subscriptions)
|
||||
resourceService := services.NewResourceService(orm, cfg.DataDir, subscriptions)
|
||||
@@ -252,6 +253,7 @@ func NewRouter(
|
||||
|
||||
setKnowledgeGroup(privateGroup, knowledgeService)
|
||||
setProvidersGroup(privateGroup, providerService)
|
||||
setSettingsGroup(privateGroup, settingsService)
|
||||
setFlowsGroup(privateGroup, flowService)
|
||||
setFlowFilesGroup(privateGroup, flowFileService)
|
||||
setResourcesGroup(privateGroup, resourceService)
|
||||
@@ -358,6 +360,13 @@ func setProvidersGroup(parent *gin.RouterGroup, svc *services.ProviderService) {
|
||||
}
|
||||
}
|
||||
|
||||
func setSettingsGroup(parent *gin.RouterGroup, svc *services.SettingsService) {
|
||||
settingsGroup := parent.Group("/settings")
|
||||
{
|
||||
settingsGroup.GET("/", svc.GetSettings)
|
||||
}
|
||||
}
|
||||
|
||||
func setGraphqlGroup(parent *gin.RouterGroup, svc *services.GraphqlService) {
|
||||
graphqlGroup := parent.Group("/")
|
||||
{
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"slices"
|
||||
|
||||
"pentagi/pkg/providers"
|
||||
"pentagi/pkg/providers/pconfig"
|
||||
"pentagi/pkg/providers/provider"
|
||||
"pentagi/pkg/server/logger"
|
||||
"pentagi/pkg/server/models"
|
||||
"pentagi/pkg/server/response"
|
||||
@@ -27,7 +29,7 @@ func NewProviderService(providers providers.ProviderController) *ProviderService
|
||||
// @Tags Providers
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} response.successResp{data=models.ProviderInfo} "providers list received successful"
|
||||
// @Success 200 {object} response.successResp{data=[]models.ProviderInfo} "providers list received successful"
|
||||
// @Failure 403 {object} response.errorResp "getting providers not permitted"
|
||||
// @Router /providers/ [get]
|
||||
func (s *ProviderService) GetProviders(c *gin.Context) {
|
||||
@@ -47,11 +49,75 @@ func (s *ProviderService) GetProviders(c *gin.Context) {
|
||||
|
||||
providerInfos := make([]models.ProviderInfo, len(providers))
|
||||
for i, name := range providers.ListNames() {
|
||||
prv := providers[name]
|
||||
providerInfos[i] = models.ProviderInfo{
|
||||
Name: name.String(),
|
||||
Type: models.ProviderType(providers[name].Type()),
|
||||
Name: name.String(),
|
||||
Type: models.ProviderType(prv.Type()),
|
||||
DefaultModel: prv.Model(pconfig.OptionsTypePrimaryAgent),
|
||||
Models: buildModelInfos(prv),
|
||||
}
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusOK, providerInfos)
|
||||
}
|
||||
|
||||
func buildModelInfos(prv provider.Provider) []models.ModelInfo {
|
||||
modelsConfig := prv.GetModels()
|
||||
|
||||
// Build lookup: model name -> price from ModelsConfig (models.yml)
|
||||
modelConfigPrice := make(map[string]*pconfig.PriceInfo, len(modelsConfig))
|
||||
for _, mc := range modelsConfig {
|
||||
if mc.Price != nil {
|
||||
modelConfigPrice[mc.Name] = mc.Price
|
||||
}
|
||||
}
|
||||
|
||||
// Collect unique models actually in use across all agent types.
|
||||
// For price priority: AgentConfig.Price > ModelsConfig price.
|
||||
type entry struct {
|
||||
price *pconfig.PriceInfo
|
||||
agentTypes []string
|
||||
}
|
||||
seen := make(map[string]*entry)
|
||||
order := make([]string, 0)
|
||||
|
||||
for _, optType := range pconfig.AllAgentTypes {
|
||||
modelName := prv.Model(optType)
|
||||
if modelName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
e, exists := seen[modelName]
|
||||
if !exists {
|
||||
price := prv.GetPriceInfo(optType)
|
||||
if price == nil {
|
||||
price = modelConfigPrice[modelName]
|
||||
}
|
||||
e = &entry{price: price}
|
||||
seen[modelName] = e
|
||||
order = append(order, modelName)
|
||||
}
|
||||
|
||||
e.agentTypes = append(e.agentTypes, string(optType))
|
||||
}
|
||||
|
||||
modelInfos := make([]models.ModelInfo, 0, len(order))
|
||||
for _, name := range order {
|
||||
e := seen[name]
|
||||
mi := models.ModelInfo{
|
||||
Name: name,
|
||||
AgentTypes: e.agentTypes,
|
||||
}
|
||||
if e.price != nil {
|
||||
mi.PriceInfo = &models.ModelPriceInfo{
|
||||
Input: e.price.Input,
|
||||
Output: e.price.Output,
|
||||
CacheRead: e.price.CacheRead,
|
||||
CacheWrite: e.price.CacheWrite,
|
||||
}
|
||||
}
|
||||
modelInfos = append(modelInfos, mi)
|
||||
}
|
||||
|
||||
return modelInfos
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
"pentagi/pkg/config"
|
||||
"pentagi/pkg/server/logger"
|
||||
"pentagi/pkg/server/models"
|
||||
"pentagi/pkg/server/response"
|
||||
"pentagi/pkg/version"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type SettingsService struct {
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
func NewSettingsService(cfg *config.Config) *SettingsService {
|
||||
return &SettingsService{cfg: cfg}
|
||||
}
|
||||
|
||||
// GetSettings is a function to return settings
|
||||
// @Summary Retrieve settings
|
||||
// @Tags Settings
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} response.successResp{data=models.Settings} "settings received successful"
|
||||
// @Failure 403 {object} response.errorResp "getting settings not permitted"
|
||||
// @Router /settings/ [get]
|
||||
func (s *SettingsService) GetSettings(c *gin.Context) {
|
||||
privs := c.GetStringSlice("prm")
|
||||
if !slices.Contains(privs, "settings.view") {
|
||||
logger.FromContext(c).Errorf("error filtering user role permissions: permission not found")
|
||||
response.Error(c, response.ErrNotPermitted, nil)
|
||||
return
|
||||
}
|
||||
|
||||
settings := models.Settings{
|
||||
Debug: s.cfg.Debug,
|
||||
AskUser: s.cfg.AskUser,
|
||||
Version: version.GetBinaryVersion(),
|
||||
DockerInside: s.cfg.DockerInside,
|
||||
IsDevelopMode: version.IsDevelopMode(),
|
||||
AssistantUseAgents: s.cfg.AssistantUseAgents,
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusOK, settings)
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
fragment settingsFragment on Settings {
|
||||
debug
|
||||
askUser
|
||||
version
|
||||
dockerInside
|
||||
isDevelopMode
|
||||
assistantUseAgents
|
||||
}
|
||||
|
||||
|
||||
@@ -990,6 +990,8 @@ export type Settings = {
|
||||
assistantUseAgents: Scalars['Boolean']['output'];
|
||||
debug: Scalars['Boolean']['output'];
|
||||
dockerInside: Scalars['Boolean']['output'];
|
||||
isDevelopMode: Scalars['Boolean']['output'];
|
||||
version: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export enum StatusType {
|
||||
@@ -1292,7 +1294,9 @@ export type VectorStoreLog = {
|
||||
export type SettingsFragmentFragment = {
|
||||
debug: boolean;
|
||||
askUser: boolean;
|
||||
version: string;
|
||||
dockerInside: boolean;
|
||||
isDevelopMode: boolean;
|
||||
assistantUseAgents: boolean;
|
||||
};
|
||||
|
||||
@@ -2371,7 +2375,9 @@ export const SettingsFragmentFragmentDoc = gql`
|
||||
fragment settingsFragment on Settings {
|
||||
debug
|
||||
askUser
|
||||
version
|
||||
dockerInside
|
||||
isDevelopMode
|
||||
assistantUseAgents
|
||||
}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user