Skip to content

Commit

Permalink
Merge pull request #57 from mylxsw/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
mylxsw authored Apr 7, 2024
2 parents aead1b3 + 7b121f9 commit 5536da9
Show file tree
Hide file tree
Showing 85 changed files with 8,049 additions and 2,014 deletions.
17 changes: 8 additions & 9 deletions api/openai/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package openai
import (
"context"
"github.com/mylxsw/aidea-server/config"
"github.com/mylxsw/aidea-server/pkg/ai/chat"
"github.com/mylxsw/aidea-server/pkg/repo"
"github.com/mylxsw/aidea-server/pkg/service"
"github.com/mylxsw/glacier/infra"
"github.com/mylxsw/glacier/web"
"github.com/mylxsw/go-utils/array"
"net/http"
)

type CompatibleController struct {
conf *config.Config `autowire:"@"`
conf *config.Config `autowire:"@"`
svc *service.Service `autowire:"@"`
}

func NewOpenAICompatibleController(resolver infra.Resolver) web.Controller {
Expand All @@ -31,25 +33,23 @@ type Model struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
OwnedBy string `json:"owned_by"`
}

func (ctl *CompatibleController) Models(ctx context.Context, webCtx web.Context) web.Response {
models := array.Map(chat.Models(ctl.conf, false), func(item chat.Model, _ int) Model {
models := array.Map(ctl.svc.Chat.Models(ctx, false), func(item repo.Model, _ int) Model {
return Model{
ID: item.RealID(),
ID: item.ModelId,
Object: "model",
Created: 1626777600,
OwnedBy: item.Category,
}
})
return webCtx.JSON(web.M{"data": models, "object": "list"})
}

func (ctl *CompatibleController) Model(ctx context.Context, webCtx web.Context) web.Response {
modelID := webCtx.PathVar("model_id")
matched := array.Filter(chat.Models(ctl.conf, true), func(item chat.Model, _ int) bool {
return item.RealID() == modelID
matched := array.Filter(ctl.svc.Chat.Models(ctx, true), func(item repo.Model, _ int) bool {
return item.ModelId == modelID
})

if len(matched) == 0 {
Expand All @@ -60,6 +60,5 @@ func (ctl *CompatibleController) Model(ctx context.Context, webCtx web.Context)
ID: modelID,
Object: "model",
Created: 1626777600,
OwnedBy: matched[0].Category,
})
}
37 changes: 11 additions & 26 deletions coins-table.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# 注册账号赠币数量
signup_gift_coins: 1000
# 绑定手机赠币数量
Expand All @@ -10,36 +9,22 @@ invited_gift_coins: 100
# 被引荐人充值,引荐人获得的奖励比例
invite_payment_gift_rate: 0.05

# 每日免费模型额度配置
# 模型标识参考 internal/coins/price.go 中的 coinTables
# 字段说明:
# - model: 模型标识
# - name: 模型名称
# - free_count: 每日免费次数
# - info: 提示信息,可选
# - end_at: 活动结束时间,格式为 ISO 8601,如 2021-12-31T00:00:00Z
free_models:
- model: gpt-3.5-turbo
name: GPT 3.5 Turbo
free_count: 5
non_cn: true

- model: model_ernie_bot_turbo
name: 文心一言 Turbo
free_count: 5

- model: generalv2
name: 讯飞星火 v2
free_count: 5
# 优先显示美元价格
# 启用后,在充值页面将默认显示美元价格
prefer_usd: false
# 默认汇率(人民币-美元)
default_exchange_rate: 7.1

# 在线充值产品列表,这里为空时,将使用 internal/coins/ 中的 products 数据
# 字段说明:
# - id: 产品 ID,唯一标识,不能重复
# - name: 产品名称
# - quota: 购买后获得的智慧果数量
# - retail_price: 零售价,单位为分
# - retail_price_usd: 零售价,单位为美元(用于 Stripe 支付方式)
# - expire_policy: 有效期,可选值为 never, week, 2week, month, 3month, 6month, year
# - recommend: 是否推荐,推荐的产品会在充值页面显示 Best Deal 标识
# - methods: 支持的支付方式,可选值为 alipay, apple_pay, stripe,默认全部支持
products:
- id: cc.aicode.aidea.coins_600_2
name: 6元700个
Expand All @@ -59,10 +44,10 @@ products:
coin_tables:
# 图片生成价格:文生图、图生图、超分辨率、上色
image:
default: 20
dall-e-3: 100
dall-e-3-hd: 150
dall-e-2: 20
default: 20
dall-e-3: 100
dall-e-3-hd: 150
dall-e-2: 20
# 所有聊天模型都在这里配置,因为历史遗留原因,都归类到了 openai 下
openai:
# 百川大模型
Expand Down
36 changes: 25 additions & 11 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
######## 基本配置 ########

# 是否是生产环境
# 是否为生产环境,生产环境下只有正式的支付渠道可用,测试渠道将不会真实充值
production: true

# Web 服务监听地址
listen: 0.0.0.0:8080

Expand Down Expand Up @@ -60,6 +64,12 @@ enable-scheduler: true
# 支持的短信通道,支持 aliyun, tencent,配置多个则随机选择
sms-channels: [ "aliyun", "tencent" ]

# 是否提示用户绑定手机号
should-bind-phone: false

# Web 服务的基础 URL,例如 https://web.aicode.cc
base-url: ""

######## OpenAI 配置 ########

# 是否启用 OpenAI
Expand Down Expand Up @@ -212,8 +222,6 @@ moonshot-apikey: ""

# https://github.com/songquanpeng/one-api

# 支持的模型列表,当前支持:chatglm_turbo, chatglm_pro, chatglm_std, chatglm_lite, PaLM-2
oneapi-support-models: [ ]
enable-oneapi: false
oneapi-server: ""
oneapi-key: ""
Expand Down Expand Up @@ -436,14 +444,6 @@ default-txt2img-model: sb-stable-diffusion-xl-1024-v1-0
# 图生图图像识别处理模型,用于识别图像内容,生成图生图的提示语,目前支持 xfyun,留空则表示不启用
img2img-recognition-provider: ""

######## 虚拟模型配置 ########
enable-virtual-model: false
virtual-model-implementation: "openai"
virtual-model-nanxian-rel: "gpt-3.5-turbo"
virtual-model-nanxian-prompt: ""
virtual-model-beichou-rel: "gpt-4"
virtual-model-beichou-prompt: ""

######## 价格相关 ########
# 智慧果收费标准、充值、赠送相关配置
# 系统内置默认规则,在 internal/coins 中定义,不指定该选项使用默认配置
Expand All @@ -463,4 +463,18 @@ free-chat-model: gpt-3.5-turbo

######## 微信开放平台 ########
wechat-appid: ""
wechat-secret: ""
wechat-secret: ""

######## Stripe ########
# 是否启用 Stripe 支付
# https://stripe.com/docs/development/quickstart#api-keys
enable-stripe: false
stripe-publishable-key: ""
stripe-secret-key: ""
stripe-webhook-secret: ""

######## 默认首页模型 ########
# 首页默认展示的模型,取值为表 models.model_id 的值
default-home-models: ["gpt-3.5-turbo", "gpt-4"]
# IOS 系统默认首页模型,取值为表 models.model_id 的值,如果为空,则使用 default-home-models
default-home-models-ios: ["chat-3.5", "chat-4"]
58 changes: 32 additions & 26 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ type Config struct {
DebugWithSQL bool `json:"debug_with_sql" yaml:"debug_with_sql"`
// 是否启用 API Keys 功能
EnableAPIKeys bool `json:"enable_api_keys" yaml:"enable_api_keys"`
// 是否是生产环境
IsProduction bool `json:"is_production" yaml:"is_production"`

// 是否提示用户绑定手机
ShouldBindPhone bool `json:"should_bind_phone" yaml:"should_bind_phone"`

// BaseURL 服务的基础 URL
BaseURL string `json:"base_url" yaml:"base_url"`
Expand Down Expand Up @@ -264,10 +269,6 @@ type Config struct {
// 图生图图像识别处理模型,用于识别图像内容,生成图生图的提示语
ImageToImageRecognitionProvider string `json:"img2img-recognition-provider" yaml:"img2img-recognition-provider"`

// 虚拟模型
EnableVirtualModel bool `json:"enable_virtual_model" yaml:"enable_virtual_model"`
VirtualModel VirtualModel `json:"virtual_model" yaml:"virtual_model"`

// 字体文件路径
FontPath string `json:"font_path" yaml:"font_path"`
// 服务状态页面
Expand All @@ -285,6 +286,13 @@ type Config struct {
// 微信开放平台配置
WeChatAppID string `json:"wechat_appid" yaml:"wechat_appid"`
WeChatSecret string `json:"wechat_secret" yaml:"wechat_secret"`

// Stripe 支付
Stripe StripeConfig `json:"stripe" yaml:"stripe"`

// 首页默认常用模型
DefaultHomeModels []string `json:"default_home_models" yaml:"default_home_models"`
DefaultHomeModelsIOS []string `json:"default_home_models_ios" yaml:"default_home_models_ios"`
}

func (conf *Config) SupportProxy() bool {
Expand All @@ -310,14 +318,6 @@ func (conf *Config) RedisAddr() string {
return fmt.Sprintf("%s:%d", conf.RedisHost, conf.RedisPort)
}

type VirtualModel struct {
Implementation string `json:"implementation"`
NanxianRel string `json:"nanxian_rel"`
NanxianPrompt string `json:"nanxian_prompt"`
BeichouRel string `json:"beichou_rel"`
BeichouPrompt string `json:"beichou_prompt"`
}

func Register(ins *app.App) {
// 加载命令行选项
initCmdFlags(ins)
Expand Down Expand Up @@ -349,6 +349,15 @@ func Register(ins *app.App) {
coins.DebugPrintPriceInfo()
}

// 加载 Stripe 配置
stripe := StripeConfig{
Enabled: ctx.Bool("enable-stripe"),
PublishableKey: ctx.String("stripe-publishable-key"),
SecretKey: ctx.String("stripe-secret-key"),
WebhookSecret: ctx.String("stripe-webhook-secret"),
}
stripe.Init()

return &Config{
Listen: ctx.String("listen"),
DBURI: ctx.String("db-uri"),
Expand All @@ -359,8 +368,10 @@ func Register(ins *app.App) {
EnableWebsocket: ctx.Bool("enable-websocket"),
DebugWithSQL: ctx.Bool("debug-with-sql"),
UniversalLinkConfig: strings.TrimSpace(ctx.String("universal-link-config")),
ShouldBindPhone: ctx.Bool("should-bind-phone"),

BaseURL: strings.TrimSuffix(ctx.String("base-url"), "/"),
BaseURL: strings.TrimSuffix(ctx.String("base-url"), "/"),
IsProduction: ctx.Bool("production"),

EnableModelRateLimit: ctx.Bool("enable-model-rate-limit"),
EnableCustomHomeModels: ctx.Bool("enable-custom-home-models"),
Expand Down Expand Up @@ -442,10 +453,9 @@ func Register(ins *app.App) {
EnableMoonshot: ctx.Bool("enable-moonshot"),
MoonshotAPIKey: ctx.String("moonshot-apikey"),

OneAPISupportModels: ctx.StringSlice("oneapi-support-models"),
EnableOneAPI: ctx.Bool("enable-oneapi"),
OneAPIServer: ctx.String("oneapi-server"),
OneAPIKey: ctx.String("oneapi-key"),
EnableOneAPI: ctx.Bool("enable-oneapi"),
OneAPIServer: ctx.String("oneapi-server"),
OneAPIKey: ctx.String("oneapi-key"),

OpenRouterSupportModels: ctx.StringSlice("openrouter-support-models"),
EnableOpenRouter: ctx.Bool("enable-openrouter"),
Expand Down Expand Up @@ -555,15 +565,6 @@ func Register(ins *app.App) {

ImageToImageRecognitionProvider: ctx.String("img2img-recognition-provider"),

EnableVirtualModel: ctx.Bool("enable-virtual-model"),
VirtualModel: VirtualModel{
Implementation: ctx.String("virtual-model-implementation"),
NanxianRel: ctx.String("virtual-model-nanxian-rel"),
NanxianPrompt: strings.TrimSpace(ctx.String("virtual-model-nanxian-prompt")),
BeichouRel: ctx.String("virtual-model-beichou-rel"),
BeichouPrompt: strings.TrimSpace(ctx.String("virtual-model-beichou-prompt")),
},

FontPath: ctx.String("font-path"),
ServiceStatusPage: ctx.String("service-status-page"),

Expand All @@ -574,6 +575,11 @@ func Register(ins *app.App) {

WeChatAppID: ctx.String("wechat-appid"),
WeChatSecret: ctx.String("wechat-secret"),

Stripe: stripe,

DefaultHomeModels: ctx.StringSlice("default-home-models"),
DefaultHomeModelsIOS: ctx.StringSlice("default-home-models-ios"),
}
})
}
18 changes: 10 additions & 8 deletions config/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func initCmdFlags(ins *app.App) {
ins.AddDurationFlag("start-delay", 0, "服务启动延迟时间,用于在服务启动前做一些初始化工作,例如 Docker 环境下等待初始化数据库等")

ins.AddStringFlag("base-url", "", "Web 服务的基础 URL,例如 https://web.aicode.cc")
ins.AddBoolFlag("production", "是否为生产环境,生产环境下只有正式的支付渠道可用")
ins.AddStringFlag("socks5-proxy", "", "socks5 proxy")
ins.AddStringFlag("proxy-url", "", "HTTP 代理放置,支持 http、https、socks5,代理类型由 URL schema 决定,如果 scheme 为空,则默认为 http")
ins.AddStringFlag("db-uri", "root:12345@tcp(127.0.0.1:3306)/aiserver?charset=utf8mb4&parseTime=True&loc=Local", "database url")
Expand All @@ -25,6 +26,7 @@ func initCmdFlags(ins *app.App) {
ins.AddBoolFlag("enable-api-keys", "是否启用 API Keys 功能")
ins.AddBoolFlag("enable-model-rate-limit", "是否启用模型请求频率限制,当前限制只支持每分钟 5 次/用户")
ins.AddStringFlag("universal-link-config", "", "universal link 配置文件路径,留空则使用默认的 universal link,配置文件格式参考 https://developer.apple.com/documentation/xcode/supporting-associated-domains")
ins.AddBoolFlag("should-bind-phone", "是否需要绑定手机号码")

ins.AddStringFlag("redis-host", "127.0.0.1", "redis host")
ins.AddIntFlag("redis-port", 6379, "redis port")
Expand Down Expand Up @@ -104,7 +106,6 @@ func initCmdFlags(ins *app.App) {
ins.AddBoolFlag("enable-moonshot", "是否启用月之暗面")
ins.AddStringFlag("moonshot-apikey", "", "月之暗面 API Key")

ins.AddStringSliceFlag("oneapi-support-models", []string{}, "one-server 支持的模型,可选项 chatglm_turbo, chatglm_pro, chatglm_std, chatglm_lite, PaLM-2")
ins.AddBoolFlag("enable-oneapi", "是否启用 OneAPI")
ins.AddStringFlag("oneapi-server", "", "one-server server")
ins.AddStringFlag("oneapi-key", "", "one-server key")
Expand Down Expand Up @@ -213,13 +214,6 @@ func initCmdFlags(ins *app.App) {

ins.AddStringFlag("img2img-recognition-provider", "", "图生图图像识别处理模型,用于识别图像内容,生成图生图的提示语,目前支持 xfyun,留空则表示不启用")

ins.AddBoolFlag("enable-virtual-model", "是否启用虚拟模型")
ins.AddStringFlag("virtual-model-implementation", "openai", "虚拟模型实现厂商")
ins.AddStringFlag("virtual-model-nanxian-rel", "gpt-3.5-turbo", "南贤大模型实现")
ins.AddStringFlag("virtual-model-nanxian-prompt", "", "南贤大模型内置提示语")
ins.AddStringFlag("virtual-model-beichou-rel", "gpt-4", "北丑大模型实现")
ins.AddStringFlag("virtual-model-beichou-prompt", "", "北丑大模型内置提示语")

ins.AddStringFlag("price-table-file", "", "价格表文件路径,留空则使用默认价格表")

ins.AddStringFlag("font-path", "", "字体文件路径")
Expand All @@ -232,4 +226,12 @@ func initCmdFlags(ins *app.App) {

ins.AddStringFlag("wechat-appid", "", "微信开放平台 APP ID")
ins.AddStringFlag("wechat-secret", "", "微信开放平台 APP Secret")

ins.AddBoolFlag("enable-stripe", "是否启用 stripe 支付")
ins.AddStringFlag("stripe-publishable-key", "", "stripe publishable key")
ins.AddStringFlag("stripe-secret-key", "", "stripe secret key")
ins.AddStringFlag("stripe-webhook-secret", "", "stripe webhook secret")

ins.AddStringSliceFlag("default-home-models", []string{"gpt-3.5-turbo", "gpt-4"}, "默认的首页模型,值取自数据表 models.model_id")
ins.AddStringSliceFlag("default-home-models-ios", []string{"chat-3.5", "chat-4"}, "默认的首页模型(IOS),值取自数据表 models.model_id")
}
14 changes: 14 additions & 0 deletions config/stripe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package config

import "github.com/stripe/stripe-go/v76"

type StripeConfig struct {
Enabled bool `json:"enabled" yaml:"enabled"`
PublishableKey string `json:"publishable_key" yaml:"publishable_key"`
SecretKey string `json:"secret_key" yaml:"secret_key"`
WebhookSecret string `json:"webhook_secret" yaml:"webhook_secret"`
}

func (s StripeConfig) Init() {
stripe.Key = s.SecretKey
}
Loading

0 comments on commit 5536da9

Please sign in to comment.