Compare commits
29 Commits
v2025.8.24
...
v2025.11.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8f063fd9b | ||
|
|
8b0b53fae7 | ||
|
|
b29c380055 | ||
|
|
cf58a707c7 | ||
|
|
1ae1bb0116 | ||
|
|
d8971935ee | ||
|
|
9c68458b81 | ||
|
|
b367d1eb40 | ||
|
|
8fe79adbb1 | ||
|
|
1d81fdba87 | ||
|
|
6aca0e15cc | ||
|
|
173ce6f243 | ||
|
|
e7875e73d3 | ||
|
|
ca4727db80 | ||
|
|
84ffe7c5fd | ||
|
|
da02d1bd1c | ||
|
|
bae2bf9c5c | ||
|
|
6568b5949a | ||
|
|
c4287f9b78 | ||
|
|
87441d8923 | ||
|
|
ebd166e72b | ||
|
|
494a60debe | ||
|
|
b3e2565a02 | ||
|
|
c0a87d5d2e | ||
|
|
d74ad3c03d | ||
|
|
6dff9d95c4 | ||
|
|
06967420f8 | ||
|
|
6f4eb0ac86 | ||
|
|
f59255cc6c |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
build-name: ${{ matrix.build.name }}
|
||||
build-platform: ${{ matrix.build.platform }}
|
||||
package: true
|
||||
go-version: '1.24'
|
||||
go-version: '1.25'
|
||||
build-tags: ${{ github.ref_name }}
|
||||
build-commit-message: ${{ steps.get_commit_message.outputs.commit_message }}
|
||||
build-statement: ${{ env.OFFICIAL_STATEMENT }}
|
||||
|
||||
@@ -37,11 +37,9 @@
|
||||
| [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 |
|
||||
| [AnythingLLM](https://anythingllm.com/) | ✅ | 本地知识库 |
|
||||
| [DeepSeek](https://www.deepseek.com/) | ✅ | deepseek-reasoner,deepseek-chat |
|
||||
| [大模型聚合平台](https://cloud.siliconflow.cn/i/foufCerk) | ✅ | 如:[302.AI](https://share.302.ai/1KUpfG),[硅基流动](https://cloud.siliconflow.cn/i/foufCerk),[火山方舟](https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=IJSE43PZ) |
|
||||
| [大模型聚合平台](https://cloud.siliconflow.cn/i/foufCerk) | ✅ | 如:[硅基流动](https://cloud.siliconflow.cn/i/foufCerk),[火山方舟](https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=IJSE43PZ) |
|
||||
|
||||
### <span style="color: #568DF4;">各位亲爱的朋友们,如果您对这个项目感兴趣,请先给我一个<i style="color: #EA2626;">star</i>吧,谢谢!</span>💕
|
||||
- 302.AI:新用户使用邀请码注册,即可领取 $1 测试额度
|
||||
|
||||
[//]: # (- 优云智算(by UCloud):万卡规模4090免费用10小时,新人注册另增50万tokens,海量热门源项目镜像一键部署,[注册链接](https://www.compshare.cn/image-community?ytag=GPU_YY-gh_gostock))
|
||||
- 火山方舟:新用户每个模型注册即送50万tokens,[注册链接](https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=IJSE43PZ)
|
||||
- 硅基流动(siliconflow),注册即送2000万Tokens,[注册链接](https://cloud.siliconflow.cn/i/foufCerk)
|
||||
@@ -62,7 +60,7 @@
|
||||
| 功能说明 | 状态 | 备注 |
|
||||
|-----------------|----|----------------------------------------------------------------------------------------------------------|
|
||||
| 股票分析知识库 | 🚧 | 未来计划 |
|
||||
| Ai智能选股 | 🚧 | Ai智能选股功能开发中(下半年重点开发计划) |
|
||||
| Ai智能选股 | ✅ | Ai智能选股功能(市场行情-》AI总结/AI智能体功能) |
|
||||
| ETF支持 | 🚧 | ETF数据支持 (目前可以查看净值和估值) |
|
||||
| 美股支持 | ✅ | 美股数据支持 |
|
||||
| 港股支持 | ✅ | 港股数据支持 |
|
||||
|
||||
156
app.go
156
app.go
@@ -131,6 +131,50 @@ func AddTools(tools []data.Tool) []data.Tool {
|
||||
},
|
||||
})
|
||||
|
||||
//tools = append(tools, data.Tool{
|
||||
// Type: "function",
|
||||
// Function: data.ToolFunction{
|
||||
// Name: "QueryBKDictInfo",
|
||||
// Description: "获取所有板块/行业名称或者代码(bkCode,bkName)",
|
||||
// },
|
||||
//})
|
||||
|
||||
//tools = append(tools, data.Tool{
|
||||
// Type: "function",
|
||||
// Function: data.ToolFunction{
|
||||
// Name: "GetIndustryResearchReport",
|
||||
// Description: "获取行业/板块研究报告,请先使用QueryBKDictInfo工具获取行业代码,然后输入行业代码调用",
|
||||
// Parameters: data.FunctionParameters{
|
||||
// Type: "object",
|
||||
// Properties: map[string]any{
|
||||
// "bkCode": map[string]any{
|
||||
// "type": "string",
|
||||
// "description": "板块/行业代码",
|
||||
// },
|
||||
// },
|
||||
// Required: []string{"bkCode"},
|
||||
// },
|
||||
// },
|
||||
//})
|
||||
|
||||
tools = append(tools, data.Tool{
|
||||
Type: "function",
|
||||
Function: data.ToolFunction{
|
||||
Name: "GetStockResearchReport",
|
||||
Description: "获取股票的分析/研究报告",
|
||||
Parameters: data.FunctionParameters{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"stockCode": map[string]any{
|
||||
"type": "string",
|
||||
"description": "股票代码",
|
||||
},
|
||||
},
|
||||
Required: []string{"stockCode"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return tools
|
||||
}
|
||||
|
||||
@@ -384,7 +428,8 @@ func (a *App) domReady(ctx context.Context) {
|
||||
a.cronEntrys["MonitorStockPrices"] = id
|
||||
}
|
||||
entryID, err := a.cron.AddFunc(fmt.Sprintf("@every %ds", interval+10), func() {
|
||||
news := data.NewMarketNewsApi().GetNewTelegraph(30)
|
||||
//news := data.NewMarketNewsApi().GetNewTelegraph(30)
|
||||
news := data.NewMarketNewsApi().TelegraphList(30)
|
||||
if config.EnablePushNews {
|
||||
go a.NewsPush(news)
|
||||
}
|
||||
@@ -465,6 +510,8 @@ func (a *App) domReady(ctx context.Context) {
|
||||
//检查新版本
|
||||
go func() {
|
||||
a.CheckUpdate(0)
|
||||
go a.CheckStockBaseInfo(a.ctx)
|
||||
|
||||
a.cron.AddFunc("0 0 2 * * *", func() {
|
||||
logger.SugaredLogger.Errorf("Checking for updates...")
|
||||
a.CheckStockBaseInfo(a.ctx)
|
||||
@@ -518,60 +565,84 @@ func (a *App) CheckStockBaseInfo(ctx context.Context) {
|
||||
SetResult(stockBasics).
|
||||
Get("http://8.134.249.145:18080/go-stock/stock_basic.json")
|
||||
|
||||
for _, stock := range *stockBasics {
|
||||
stockInfo := &data.StockBasic{
|
||||
TsCode: stock.TsCode,
|
||||
Name: stock.Name,
|
||||
Symbol: stock.Symbol,
|
||||
BKCode: stock.BKCode,
|
||||
BKName: stock.BKName,
|
||||
}
|
||||
db.Dao.Model(&data.StockBasic{}).Where("ts_code = ?", stock.TsCode).First(stockInfo)
|
||||
if stockInfo.ID == 0 {
|
||||
db.Dao.Model(&data.StockBasic{}).Create(stockInfo)
|
||||
} else {
|
||||
db.Dao.Model(&data.StockBasic{}).Where("ts_code = ?", stock.TsCode).Updates(stockInfo)
|
||||
}
|
||||
db.Dao.Unscoped().Model(&data.StockBasic{}).Where("1=1").Delete(&data.StockBasic{})
|
||||
err := db.Dao.CreateInBatches(stockBasics, 400).Error
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("保存StockBasic股票基础信息失败:%s", err.Error())
|
||||
}
|
||||
|
||||
//count := int64(0)
|
||||
//db.Dao.Model(&data.StockBasic{}).Count(&count)
|
||||
//if count == int64(len(*stockBasics)) {
|
||||
// return
|
||||
//}
|
||||
//for _, stock := range *stockBasics {
|
||||
// stockInfo := &data.StockBasic{
|
||||
// TsCode: stock.TsCode,
|
||||
// Name: stock.Name,
|
||||
// Symbol: stock.Symbol,
|
||||
// BKCode: stock.BKCode,
|
||||
// BKName: stock.BKName,
|
||||
// }
|
||||
// db.Dao.Model(&data.StockBasic{}).Where("ts_code = ?", stock.TsCode).First(stockInfo)
|
||||
// if stockInfo.ID == 0 {
|
||||
// db.Dao.Model(&data.StockBasic{}).Create(stockInfo)
|
||||
// } else {
|
||||
// db.Dao.Model(&data.StockBasic{}).Where("ts_code = ?", stock.TsCode).Updates(stockInfo)
|
||||
// }
|
||||
//}
|
||||
|
||||
stockHKBasics := &[]models.StockInfoHK{}
|
||||
resty.New().R().
|
||||
SetHeader("user", "go-stock").
|
||||
SetResult(stockHKBasics).
|
||||
Get("http://8.134.249.145:18080/go-stock/stock_base_info_hk.json")
|
||||
for _, stock := range *stockHKBasics {
|
||||
stockInfo := &models.StockInfoHK{
|
||||
Code: stock.Code,
|
||||
Name: stock.Name,
|
||||
BKName: stock.BKName,
|
||||
BKCode: stock.BKCode,
|
||||
}
|
||||
db.Dao.Model(&models.StockInfoHK{}).Where("code = ?", stock.Code).First(stockInfo)
|
||||
if stockInfo.ID == 0 {
|
||||
db.Dao.Model(&models.StockInfoHK{}).Create(stockInfo)
|
||||
} else {
|
||||
db.Dao.Model(&models.StockInfoHK{}).Where("code = ?", stock.Code).Updates(stockInfo)
|
||||
}
|
||||
|
||||
db.Dao.Unscoped().Model(&models.StockInfoHK{}).Where("1=1").Delete(&models.StockInfoHK{})
|
||||
err = db.Dao.CreateInBatches(stockHKBasics, 400).Error
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("保存StockInfoHK股票基础信息失败:%s", err.Error())
|
||||
}
|
||||
|
||||
//for _, stock := range *stockHKBasics {
|
||||
// stockInfo := &models.StockInfoHK{
|
||||
// Code: stock.Code,
|
||||
// Name: stock.Name,
|
||||
// BKName: stock.BKName,
|
||||
// BKCode: stock.BKCode,
|
||||
// }
|
||||
// db.Dao.Model(&models.StockInfoHK{}).Where("code = ?", stock.Code).First(stockInfo)
|
||||
// if stockInfo.ID == 0 {
|
||||
// db.Dao.Model(&models.StockInfoHK{}).Create(stockInfo)
|
||||
// } else {
|
||||
// db.Dao.Model(&models.StockInfoHK{}).Where("code = ?", stock.Code).Updates(stockInfo)
|
||||
// }
|
||||
//}
|
||||
stockUSBasics := &[]models.StockInfoUS{}
|
||||
resty.New().R().
|
||||
SetHeader("user", "go-stock").
|
||||
SetResult(stockUSBasics).
|
||||
Get("http://8.134.249.145:18080/go-stock/stock_base_info_us.json")
|
||||
for _, stock := range *stockUSBasics {
|
||||
stockInfo := &models.StockInfoUS{
|
||||
Code: stock.Code,
|
||||
Name: stock.Name,
|
||||
BKName: stock.BKName,
|
||||
BKCode: stock.BKCode,
|
||||
}
|
||||
db.Dao.Model(&models.StockInfoUS{}).Where("code = ?", stock.Code).First(stockInfo)
|
||||
if stockInfo.ID == 0 {
|
||||
db.Dao.Model(&models.StockInfoUS{}).Create(stockInfo)
|
||||
} else {
|
||||
db.Dao.Model(&models.StockInfoUS{}).Where("code = ?", stock.Code).Updates(stockInfo)
|
||||
}
|
||||
|
||||
db.Dao.Unscoped().Model(&models.StockInfoUS{}).Where("1=1").Delete(&models.StockInfoUS{})
|
||||
err = db.Dao.CreateInBatches(stockUSBasics, 400).Error
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("保存StockInfoUS股票基础信息失败:%s", err.Error())
|
||||
}
|
||||
//for _, stock := range *stockUSBasics {
|
||||
// stockInfo := &models.StockInfoUS{
|
||||
// Code: stock.Code,
|
||||
// Name: stock.Name,
|
||||
// BKName: stock.BKName,
|
||||
// BKCode: stock.BKCode,
|
||||
// }
|
||||
// db.Dao.Model(&models.StockInfoUS{}).Where("code = ?", stock.Code).First(stockInfo)
|
||||
// if stockInfo.ID == 0 {
|
||||
// db.Dao.Model(&models.StockInfoUS{}).Create(stockInfo)
|
||||
// } else {
|
||||
// db.Dao.Model(&models.StockInfoUS{}).Where("code = ?", stock.Code).Updates(stockInfo)
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
func (a *App) NewsPush(news *[]models.Telegraph) {
|
||||
@@ -1286,7 +1357,8 @@ func (a *App) GetTelegraphList(source string) *[]*models.Telegraph {
|
||||
}
|
||||
|
||||
func (a *App) ReFleshTelegraphList(source string) *[]*models.Telegraph {
|
||||
data.NewMarketNewsApi().GetNewTelegraph(30)
|
||||
//data.NewMarketNewsApi().GetNewTelegraph(30)
|
||||
data.NewMarketNewsApi().TelegraphList(30)
|
||||
data.NewMarketNewsApi().GetSinaNews(30)
|
||||
telegraphs := data.NewMarketNewsApi().GetTelegraphList(source)
|
||||
return telegraphs
|
||||
|
||||
@@ -73,13 +73,14 @@ func GetStockAiAgent(ctx *context.Context, aiConfig data.AIConfig) *react.Agent
|
||||
tools.GetFinancialReportTool(),
|
||||
tools.GetQueryStockNewsTool(),
|
||||
tools.GetIndustryResearchReportTool(),
|
||||
tools.GetQueryBKDictTool(),
|
||||
},
|
||||
}
|
||||
// 创建 agent
|
||||
agent, err := react.NewAgent(*ctx, &react.AgentConfig{
|
||||
ToolCallingModel: toolableChatModel,
|
||||
ToolsConfig: aiTools,
|
||||
MaxStep: len(aiTools.Tools)*3 + 2,
|
||||
MaxStep: len(aiTools.Tools)*1 + 3,
|
||||
MessageModifier: func(ctx context.Context, input []*schema.Message) []*schema.Message {
|
||||
return input
|
||||
},
|
||||
|
||||
34
backend/agent/tools/bk_dict_tool.go
Normal file
34
backend/agent/tools/bk_dict_tool.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"go-stock/backend/data"
|
||||
|
||||
"github.com/cloudwego/eino/components/tool"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
"github.com/coocood/freecache"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
// @Date 2025/9/27 14:09
|
||||
// @Desc
|
||||
// -----------------------------------------------------------------------------------
|
||||
type ToolQueryBKDict struct{}
|
||||
|
||||
func (t ToolQueryBKDict) Info(ctx context.Context) (*schema.ToolInfo, error) {
|
||||
return &schema.ToolInfo{
|
||||
Name: "QueryBKDictInfo",
|
||||
Desc: "获取所有板块/行业名称或者代码(bkCode,bkName)",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t ToolQueryBKDict) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) {
|
||||
resp := data.NewMarketNewsApi().EMDictCode("016", freecache.NewCache(100))
|
||||
bytes, err := json.Marshal(resp)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func GetQueryBKDictTool() tool.InvokableTool {
|
||||
return &ToolQueryBKDict{}
|
||||
}
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go-stock/backend/data"
|
||||
|
||||
"github.com/cloudwego/eino/components/tool"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
"go-stock/backend/data"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
@@ -55,7 +56,7 @@ func (c ChoiceStockByIndicators) InvokableRun(ctx context.Context, argumentsInJS
|
||||
}
|
||||
content := "无符合条件的数据"
|
||||
words := parms["words"].(string)
|
||||
res := data.NewSearchStockApi(words).SearchStock(random.RandInt(5, 10))
|
||||
res := data.NewSearchStockApi(words).SearchStock(random.RandInt(5, 20))
|
||||
if convertor.ToString(res["code"]) == "100" {
|
||||
resData := res["data"].(map[string]any)
|
||||
result := resData["result"].(map[string]any)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package data
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-toast/toast"
|
||||
"go-stock/backend/logger"
|
||||
|
||||
"github.com/go-toast/toast"
|
||||
)
|
||||
|
||||
// AlertWindowsApi @Author spark
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package data
|
||||
|
||||
import (
|
||||
"github.com/go-toast/toast"
|
||||
"go-stock/backend/logger"
|
||||
"testing"
|
||||
|
||||
"github.com/go-toast/toast"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
|
||||
@@ -33,6 +33,70 @@ func NewMarketNewsApi() *MarketNewsApi {
|
||||
return &MarketNewsApi{}
|
||||
}
|
||||
|
||||
func (m MarketNewsApi) TelegraphList(crawlTimeOut int64) *[]models.Telegraph {
|
||||
//https://www.cls.cn/nodeapi/telegraphList
|
||||
url := "https://www.cls.cn/nodeapi/telegraphList"
|
||||
res := map[string]any{}
|
||||
_, _ = resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R().
|
||||
SetHeader("Referer", "https://www.cls.cn/").
|
||||
SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60").
|
||||
SetResult(&res).
|
||||
Get(url)
|
||||
var telegraphs []models.Telegraph
|
||||
|
||||
if v, _ := convertor.ToInt(res["error"]); v == 0 {
|
||||
data := res["data"].(map[string]any)
|
||||
rollData := data["roll_data"].([]any)
|
||||
for _, v := range rollData {
|
||||
news := v.(map[string]any)
|
||||
ctime, _ := convertor.ToInt(news["ctime"])
|
||||
dataTime := time.Unix(ctime, 0)
|
||||
logger.SugaredLogger.Debugf("dataTime: %s", dataTime)
|
||||
telegraph := models.Telegraph{
|
||||
Content: news["content"].(string),
|
||||
Time: dataTime.Format("15:04:05"),
|
||||
DataTime: &dataTime,
|
||||
Url: news["shareurl"].(string),
|
||||
Source: "财联社电报",
|
||||
IsRed: GetLevel(news["level"].(string)),
|
||||
SentimentResult: AnalyzeSentiment(news["content"].(string)).Description,
|
||||
}
|
||||
cnt := int64(0)
|
||||
db.Dao.Model(telegraph).Where("time=? and content=?", telegraph.Time, telegraph.Content).Count(&cnt)
|
||||
if cnt > 0 {
|
||||
continue
|
||||
}
|
||||
telegraphs = append(telegraphs, telegraph)
|
||||
db.Dao.Model(&models.Telegraph{}).Create(&telegraph)
|
||||
logger.SugaredLogger.Debugf("telegraph: %+v", &telegraph)
|
||||
if news["subjects"] == nil {
|
||||
continue
|
||||
}
|
||||
subjects := news["subjects"].([]any)
|
||||
for _, subject := range subjects {
|
||||
name := subject.(map[string]any)["subject_name"].(string)
|
||||
tag := &models.Tags{
|
||||
Name: name,
|
||||
Type: "subject",
|
||||
}
|
||||
db.Dao.Model(tag).Where("name=? and type=?", name, "subject").FirstOrCreate(&tag)
|
||||
db.Dao.Model(models.TelegraphTags{}).Where("telegraph_id=? and tag_id=?", telegraph.ID, tag.ID).FirstOrCreate(&models.TelegraphTags{
|
||||
TelegraphId: telegraph.ID,
|
||||
TagId: tag.ID,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
//db.Dao.Model(&models.Telegraph{}).Create(&telegraphs)
|
||||
//logger.SugaredLogger.Debugf("telegraphs: %+v", &telegraphs)
|
||||
}
|
||||
|
||||
return &telegraphs
|
||||
}
|
||||
func GetLevel(s string) bool {
|
||||
return s >= "C"
|
||||
}
|
||||
|
||||
func (m MarketNewsApi) GetNewTelegraph(crawlTimeOut int64) *[]models.Telegraph {
|
||||
url := "https://www.cls.cn/telegraph"
|
||||
response, _ := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R().
|
||||
@@ -77,7 +141,7 @@ func (m MarketNewsApi) GetNewTelegraph(crawlTimeOut int64) *[]models.Telegraph {
|
||||
if telegraph.Content != "" {
|
||||
telegraph.SentimentResult = AnalyzeSentiment(telegraph.Content).Description
|
||||
cnt := int64(0)
|
||||
db.Dao.Model(telegraph).Where("time=? and source=?", telegraph.Time, telegraph.Source).Count(&cnt)
|
||||
db.Dao.Model(telegraph).Where("time=? and content=?", telegraph.Time, telegraph.Content).Count(&cnt)
|
||||
if cnt == 0 {
|
||||
db.Dao.Create(&telegraph)
|
||||
telegraphs = append(telegraphs, telegraph)
|
||||
@@ -117,6 +181,28 @@ func (m MarketNewsApi) GetNewsList(source string, limit int) *[]*models.Telegrap
|
||||
}
|
||||
return news
|
||||
}
|
||||
func (m MarketNewsApi) GetNewsList2(source string, limit int) *[]*models.Telegraph {
|
||||
NewMarketNewsApi().TelegraphList(30)
|
||||
news := &[]*models.Telegraph{}
|
||||
if source != "" {
|
||||
db.Dao.Model(news).Preload("TelegraphTags").Where("source=?", source).Order("id desc,is_red desc").Limit(limit).Find(news)
|
||||
} else {
|
||||
db.Dao.Model(news).Preload("TelegraphTags").Order("id desc,is_red desc").Limit(limit).Find(news)
|
||||
}
|
||||
for _, item := range *news {
|
||||
tags := &[]models.Tags{}
|
||||
db.Dao.Model(&models.Tags{}).Where("id in ?", lo.Map(item.TelegraphTags, func(item models.TelegraphTags, index int) uint {
|
||||
return item.TagId
|
||||
})).Find(&tags)
|
||||
tagNames := lo.Map(*tags, func(item models.Tags, index int) string {
|
||||
return item.Name
|
||||
})
|
||||
item.SubjectTags = tagNames
|
||||
logger.SugaredLogger.Infof("tagNames %v ,SubjectTags:%s", tagNames, item.SubjectTags)
|
||||
}
|
||||
return news
|
||||
}
|
||||
|
||||
func (m MarketNewsApi) GetTelegraphList(source string) *[]*models.Telegraph {
|
||||
news := &[]*models.Telegraph{}
|
||||
if source != "" {
|
||||
|
||||
@@ -4,11 +4,13 @@ import (
|
||||
"encoding/json"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"go-stock/backend/models"
|
||||
"go-stock/backend/util"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/coocood/freecache"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
@@ -37,7 +39,6 @@ func TestGetIndustryRank(t *testing.T) {
|
||||
res := NewMarketNewsApi().GetIndustryRank("0", 10)
|
||||
for s, a := range res["data"].([]any) {
|
||||
logger.SugaredLogger.Debugf("key: %+v, value: %+v", s, a)
|
||||
|
||||
}
|
||||
}
|
||||
func TestGetIndustryMoneyRankSina(t *testing.T) {
|
||||
@@ -72,9 +73,12 @@ func TestLongTiger(t *testing.T) {
|
||||
|
||||
func TestStockResearchReport(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
resp := NewMarketNewsApi().StockResearchReport("600584.sh", 7)
|
||||
resp := NewMarketNewsApi().StockResearchReport("688082", 7)
|
||||
for _, a := range resp {
|
||||
logger.SugaredLogger.Debugf("value: %+v", a)
|
||||
data := a.(map[string]any)
|
||||
logger.SugaredLogger.Debugf("value: %s infoCode:%s", data["title"], data["infoCode"])
|
||||
NewMarketNewsApi().GetIndustryReportInfo(data["infoCode"].(string))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +112,11 @@ func TestEMDictCode(t *testing.T) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dict := &[]models.BKDict{}
|
||||
json.Unmarshal(bytes, dict)
|
||||
logger.SugaredLogger.Debugf("value: %s", string(bytes))
|
||||
md := util.MarkdownTableWithTitle("行业/板块代码", dict)
|
||||
logger.SugaredLogger.Debugf(md)
|
||||
|
||||
}
|
||||
|
||||
@@ -226,3 +234,18 @@ func TestInteractiveAnswer(t *testing.T) {
|
||||
logger.SugaredLogger.Debugf(md)
|
||||
|
||||
}
|
||||
func TestGetNewsList2(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
news := NewMarketNewsApi().GetNewsList2("财联社电报", random.RandInt(100, 500))
|
||||
messageText := strings.Builder{}
|
||||
for _, telegraph := range *news {
|
||||
messageText.WriteString("## " + telegraph.Time + ":" + "\n")
|
||||
messageText.WriteString("### " + telegraph.Content + "\n")
|
||||
}
|
||||
logger.SugaredLogger.Debugf("value: %s", messageText.String())
|
||||
}
|
||||
|
||||
func TestTelegraphList(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
NewMarketNewsApi().TelegraphList(30)
|
||||
}
|
||||
|
||||
@@ -323,8 +323,7 @@ func (o *OpenAi) NewSummaryStockNewsStreamWithTools(userQuestion string, sysProm
|
||||
})
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
news := NewMarketNewsApi().GetNewsList("财联社电报", random.RandInt(100, 500))
|
||||
news := NewMarketNewsApi().GetNewsList2("财联社电报", random.RandInt(100, 500))
|
||||
messageText := strings.Builder{}
|
||||
for _, telegraph := range *news {
|
||||
messageText.WriteString("## " + telegraph.Time + ":" + "\n")
|
||||
@@ -473,7 +472,7 @@ func (o *OpenAi) NewSummaryStockNewsStream(userQuestion string, sysPromptId *int
|
||||
|
||||
wg.Wait()
|
||||
|
||||
news := NewMarketNewsApi().GetNewsList("", 100)
|
||||
news := NewMarketNewsApi().GetNewsList2("财联社电报", random.RandInt(100, 500))
|
||||
messageText := strings.Builder{}
|
||||
for _, telegraph := range *news {
|
||||
messageText.WriteString("## " + telegraph.Time + ":" + "\n")
|
||||
@@ -808,25 +807,25 @@ func (o *OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptI
|
||||
return
|
||||
}
|
||||
|
||||
messages := SearchGuShiTongStockInfo(stockCode, o.CrawlTimeOut)
|
||||
if messages == nil || len(*messages) == 0 {
|
||||
logger.SugaredLogger.Error("获取股势通资讯失败")
|
||||
//ch <- "***❗获取股势通资讯失败,分析结果可能不准确***<hr>"
|
||||
//go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股势通资讯失败,分析结果可能不准确")
|
||||
return
|
||||
}
|
||||
var newsText strings.Builder
|
||||
for _, message := range *messages {
|
||||
newsText.WriteString(message + "\n")
|
||||
}
|
||||
msg = append(msg, map[string]interface{}{
|
||||
"role": "user",
|
||||
"content": stock + "相关新闻资讯",
|
||||
})
|
||||
msg = append(msg, map[string]interface{}{
|
||||
"role": "assistant",
|
||||
"content": newsText.String(),
|
||||
})
|
||||
//messages := SearchGuShiTongStockInfo(stockCode, o.CrawlTimeOut)
|
||||
//if messages == nil || len(*messages) == 0 {
|
||||
// logger.SugaredLogger.Error("获取股势通资讯失败")
|
||||
// //ch <- "***❗获取股势通资讯失败,分析结果可能不准确***<hr>"
|
||||
// //go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股势通资讯失败,分析结果可能不准确")
|
||||
// return
|
||||
//}
|
||||
//var newsText strings.Builder
|
||||
//for _, message := range *messages {
|
||||
// newsText.WriteString(message + "\n")
|
||||
//}
|
||||
//msg = append(msg, map[string]interface{}{
|
||||
// "role": "user",
|
||||
// "content": stock + "相关新闻资讯",
|
||||
//})
|
||||
//msg = append(msg, map[string]interface{}{
|
||||
// "role": "assistant",
|
||||
// "content": newsText.String(),
|
||||
//})
|
||||
}()
|
||||
|
||||
go func() {
|
||||
@@ -1155,7 +1154,7 @@ func AskAiWithTools(o *OpenAi, err error, messages []map[string]interface{}, ch
|
||||
}
|
||||
|
||||
content := "无符合条件的数据"
|
||||
res := NewSearchStockApi(words).SearchStock(random.RandInt(5, 10))
|
||||
res := NewSearchStockApi(words).SearchStock(random.RandInt(5, 20))
|
||||
if convertor.ToString(res["code"]) == "100" {
|
||||
resData := res["data"].(map[string]any)
|
||||
result := resData["result"].(map[string]any)
|
||||
@@ -1366,6 +1365,140 @@ func AskAiWithTools(o *OpenAi, err error, messages []map[string]interface{}, ch
|
||||
"tool_call_id": currentCallId,
|
||||
})
|
||||
}
|
||||
//
|
||||
//if funcName == "QueryBKDictInfo" {
|
||||
// ch <- map[string]any{
|
||||
// "code": 1,
|
||||
// "question": question,
|
||||
// "chatId": streamResponse.Id,
|
||||
// "model": streamResponse.Model,
|
||||
// "content": "\r\n```\r\n开始调用工具:QueryBKDictInfo,\n参数:" + funcArguments + "\r\n```\r\n",
|
||||
// "time": time.Now().Format(time.DateTime),
|
||||
// }
|
||||
// res := NewMarketNewsApi().EMDictCode("016", freecache.NewCache(100))
|
||||
// bytes, err := json.Marshal(res)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// dict := &[]models.BKDict{}
|
||||
// json.Unmarshal(bytes, dict)
|
||||
// md := util.MarkdownTableWithTitle("行业/板块代码", dict)
|
||||
// logger.SugaredLogger.Infof("行业/板块代码=\n%s", md)
|
||||
// messages = append(messages, map[string]interface{}{
|
||||
// "role": "assistant",
|
||||
// "content": currentAIContent.String(),
|
||||
// "tool_calls": []map[string]any{
|
||||
// {
|
||||
// "id": currentCallId,
|
||||
// "tool_call_id": currentCallId,
|
||||
// "type": "function",
|
||||
// "function": map[string]string{
|
||||
// "name": funcName,
|
||||
// "arguments": funcArguments,
|
||||
// "parameters": funcArguments,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// messages = append(messages, map[string]interface{}{
|
||||
// "role": "tool",
|
||||
// "content": md,
|
||||
// "tool_call_id": currentCallId,
|
||||
// })
|
||||
//}
|
||||
|
||||
//if funcName == "GetIndustryResearchReport" {
|
||||
// bkCode := gjson.Get(funcArguments, "bkCode").String()
|
||||
// ch <- map[string]any{
|
||||
// "code": 1,
|
||||
// "question": question,
|
||||
// "chatId": streamResponse.Id,
|
||||
// "model": streamResponse.Model,
|
||||
// "content": "\r\n```\r\n开始调用工具:GetIndustryResearchReport,\n参数:" + bkCode + "\r\n```\r\n",
|
||||
// "time": time.Now().Format(time.DateTime),
|
||||
// }
|
||||
// bkCode = strutil.ReplaceWithMap(bkCode, map[string]string{
|
||||
// "-": "",
|
||||
// "_": "",
|
||||
// "bk": "",
|
||||
// "BK": "",
|
||||
// "bk0": "",
|
||||
// "BK0": "",
|
||||
// })
|
||||
//
|
||||
// logger.SugaredLogger.Debugf("code:%s", bkCode)
|
||||
// codeStr := convertor.ToString(bkCode)
|
||||
// res := NewMarketNewsApi().IndustryResearchReport(codeStr, 7)
|
||||
// md := strings.Builder{}
|
||||
// for _, a := range res {
|
||||
// d := a.(map[string]any)
|
||||
// md.WriteString(NewMarketNewsApi().GetIndustryReportInfo(d["infoCode"].(string)))
|
||||
// }
|
||||
// logger.SugaredLogger.Infof("bkCode:%s IndustryResearchReport:\n %s", bkCode, md.String())
|
||||
// messages = append(messages, map[string]interface{}{
|
||||
// "role": "assistant",
|
||||
// "content": currentAIContent.String(),
|
||||
// "tool_calls": []map[string]any{
|
||||
// {
|
||||
// "id": currentCallId,
|
||||
// "tool_call_id": currentCallId,
|
||||
// "type": "function",
|
||||
// "function": map[string]string{
|
||||
// "name": funcName,
|
||||
// "arguments": funcArguments,
|
||||
// "parameters": funcArguments,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// messages = append(messages, map[string]interface{}{
|
||||
// "role": "tool",
|
||||
// "content": md.String(),
|
||||
// "tool_call_id": currentCallId,
|
||||
// })
|
||||
//}
|
||||
|
||||
if funcName == "GetStockResearchReport" {
|
||||
stockCode := gjson.Get(funcArguments, "stockCode").String()
|
||||
ch <- map[string]any{
|
||||
"code": 1,
|
||||
"question": question,
|
||||
"chatId": streamResponse.Id,
|
||||
"model": streamResponse.Model,
|
||||
"content": "\r\n```\r\n开始调用工具:GetStockResearchReport,\n参数:" + stockCode + "\r\n```\r\n",
|
||||
"time": time.Now().Format(time.DateTime),
|
||||
}
|
||||
res := NewMarketNewsApi().StockResearchReport(stockCode, 7)
|
||||
md := strings.Builder{}
|
||||
for _, a := range res {
|
||||
logger.SugaredLogger.Debugf("value: %+v", a)
|
||||
d := a.(map[string]any)
|
||||
logger.SugaredLogger.Debugf("value: %s infoCode:%s", d["title"], d["infoCode"])
|
||||
md.WriteString(NewMarketNewsApi().GetIndustryReportInfo(d["infoCode"].(string)))
|
||||
}
|
||||
logger.SugaredLogger.Infof("stockCode:%s StockResearchReport:\n %s", stockCode, md.String())
|
||||
messages = append(messages, map[string]interface{}{
|
||||
"role": "assistant",
|
||||
"content": currentAIContent.String(),
|
||||
"tool_calls": []map[string]any{
|
||||
{
|
||||
"id": currentCallId,
|
||||
"tool_call_id": currentCallId,
|
||||
"type": "function",
|
||||
"function": map[string]string{
|
||||
"name": funcName,
|
||||
"arguments": funcArguments,
|
||||
"parameters": funcArguments,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
messages = append(messages, map[string]interface{}{
|
||||
"role": "tool",
|
||||
"content": md.String(),
|
||||
"tool_call_id": currentCallId,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
AskAiWithTools(o, err, messages, ch, question, tools)
|
||||
|
||||
@@ -3,6 +3,7 @@ package data
|
||||
import (
|
||||
"context"
|
||||
"go-stock/backend/db"
|
||||
log "go-stock/backend/logger"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -52,9 +53,12 @@ func TestGetTopNewsList(t *testing.T) {
|
||||
|
||||
func TestSearchGuShiTongStockInfo(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
SearchGuShiTongStockInfo("hk01810", 60)
|
||||
SearchGuShiTongStockInfo("sh600745", 60)
|
||||
SearchGuShiTongStockInfo("gb_goog", 60)
|
||||
//SearchGuShiTongStockInfo("hk01810", 60)
|
||||
msgs := SearchGuShiTongStockInfo("sh600745", 60)
|
||||
for _, msg := range *msgs {
|
||||
log.SugaredLogger.Infof("%s", msg)
|
||||
}
|
||||
//SearchGuShiTongStockInfo("gb_goog", 60)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@ package data
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"go-stock/backend/logger"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
@@ -25,25 +26,25 @@ func (s SearchStockApi) SearchStock(pageSize int) map[string]any {
|
||||
SetHeader("Host", "np-tjxg-g.eastmoney.com").
|
||||
SetHeader("Origin", "https://xuangu.eastmoney.com").
|
||||
SetHeader("Referer", "https://xuangu.eastmoney.com/").
|
||||
SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0").
|
||||
SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:145.0) Gecko/20100101 Firefox/145.0").
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(fmt.Sprintf(`{
|
||||
"keyWord": "%s",
|
||||
"pageSize": %d,
|
||||
"pageNo": 1,
|
||||
"fingerprint": "e38b5faabf9378c8238e57219f0ebc9b",
|
||||
"fingerprint": "02efa8944b1f90fbfe050e1e695a480d",
|
||||
"gids": [],
|
||||
"matchWord": "",
|
||||
"timestamp": "1751113883290349",
|
||||
"timestamp": "%d",
|
||||
"shareToGuba": false,
|
||||
"requestId": "8xTWgCDAjvQ5lmvz5mDA3Ydk2AE4yoiJ1751113883290",
|
||||
"requestId": "RMd3Y76AJI98axPvdhdbKvbBDVwLlUK61761559950168",
|
||||
"needCorrect": true,
|
||||
"removedConditionIdList": [],
|
||||
"xcId": "xc0af28549ab330013ed",
|
||||
"xcId": "xc0d61279aad33008260",
|
||||
"ownSelectAll": false,
|
||||
"dxInfo": [],
|
||||
"extraCondition": ""
|
||||
}`, s.words, pageSize)).Post(url)
|
||||
}`, s.words, pageSize, time.Now().Unix())).Post(url)
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("SearchStock-err:%+v", err)
|
||||
return map[string]any{}
|
||||
|
||||
@@ -2,16 +2,18 @@ package data
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
)
|
||||
|
||||
func TestSearchStock(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
|
||||
res := NewSearchStockApi("算力股;净利润连续3年增长").SearchStock(10)
|
||||
res := NewSearchStockApi("量比大于2,基本面优秀,2025年三季报已披露,主力连续3日净流入,非创业板非科创板非ST").SearchStock(20)
|
||||
logger.SugaredLogger.Infof("res:%+v", res)
|
||||
data := res["data"].(map[string]any)
|
||||
result := data["result"].(map[string]any)
|
||||
dataList := result["dataList"].([]any)
|
||||
|
||||
@@ -3,11 +3,12 @@ package data
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/samber/lo"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
@@ -35,6 +36,7 @@ type Settings struct {
|
||||
SponsorCode string `json:"sponsorCode"`
|
||||
HttpProxy string `json:"httpProxy"`
|
||||
HttpProxyEnabled bool `json:"httpProxyEnabled"`
|
||||
EnableAgent bool `json:"enableAgent"`
|
||||
}
|
||||
|
||||
func (receiver Settings) TableName() string {
|
||||
@@ -105,6 +107,7 @@ func UpdateConfig(s *SettingConfig) string {
|
||||
"sponsor_code": s.SponsorCode,
|
||||
"http_proxy": s.HttpProxy,
|
||||
"http_proxy_enabled": s.HttpProxyEnabled,
|
||||
"enable_agent": s.EnableAgent,
|
||||
})
|
||||
|
||||
//更新AiConfig
|
||||
|
||||
@@ -9,6 +9,14 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"go-stock/backend/models"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/chromedp/chromedp"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
@@ -17,17 +25,10 @@ import (
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/robertkrimen/otto"
|
||||
"github.com/samber/lo"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"go-stock/backend/models"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/plugin/soft_delete"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const sinaStockUrl = "http://hq.sinajs.cn/rn=%d&list=%s"
|
||||
@@ -1744,6 +1745,11 @@ func (receiver StockDataApi) GetCommonKLineData(stockCode string, kLineType stri
|
||||
return K
|
||||
}
|
||||
|
||||
// GetStockHistoryMoneyData 获取股票历史资金流向数据
|
||||
func (receiver StockDataApi) GetStockHistoryMoneyData() {
|
||||
|
||||
}
|
||||
|
||||
// JSONToMarkdownTable 将JSON数据转换为Markdown表格
|
||||
func JSONToMarkdownTable(jsonData []byte) (string, error) {
|
||||
var data []map[string]interface{}
|
||||
|
||||
@@ -265,3 +265,20 @@ func TestStockDataApi_GetIndexBasic(t *testing.T) {
|
||||
stockDataApi := NewStockDataApi()
|
||||
stockDataApi.GetIndexBasic()
|
||||
}
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
|
||||
stockBasics := &[]StockBasic{}
|
||||
resty.New().R().
|
||||
SetHeader("user", "go-stock").
|
||||
SetResult(stockBasics).
|
||||
Get("http://8.134.249.145:18080/go-stock/stock_basic.json")
|
||||
|
||||
db.Dao.Unscoped().Model(&StockBasic{}).Where("1=1").Delete(&StockBasic{})
|
||||
err := db.Dao.CreateInBatches(stockBasics, 400).Error
|
||||
if err != nil {
|
||||
t.Log(err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/plugin/soft_delete"
|
||||
"time"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
@@ -231,6 +232,7 @@ type Prompt struct {
|
||||
type Telegraph struct {
|
||||
gorm.Model
|
||||
Time string `json:"time"`
|
||||
DataTime *time.Time `json:"dataTime"`
|
||||
Content string `json:"content"`
|
||||
SubjectTags []string `json:"subjects" gorm:"-:all"`
|
||||
StocksTags []string `json:"stocks" gorm:"-:all"`
|
||||
@@ -238,7 +240,7 @@ type Telegraph struct {
|
||||
Url string `json:"url"`
|
||||
Source string `json:"source"`
|
||||
TelegraphTags []TelegraphTags `json:"tags" gorm:"-:migration;foreignKey:TelegraphId"`
|
||||
SentimentResult string `json:"sentimentResult" gorm:"-:all"`
|
||||
SentimentResult string `json:"sentimentResult"`
|
||||
}
|
||||
type TelegraphTags struct {
|
||||
gorm.Model
|
||||
@@ -687,3 +689,16 @@ type CailianpressWeb struct {
|
||||
Author string `json:"author" md:"资讯发布者"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
type BKDict struct {
|
||||
gorm.Model `md:"-"`
|
||||
BkCode string `json:"bkCode" md:"行业/板块代码"`
|
||||
BkName string `json:"bkName" md:"行业/板块名称"`
|
||||
FirstLetter string `json:"firstLetter" md:"first_letter"`
|
||||
FubkCode string `json:"fubkCode" md:"fubk_code"`
|
||||
PublishCode string `json:"publishCode" md:"publish_code"`
|
||||
}
|
||||
|
||||
func (b BKDict) TableName() string {
|
||||
return "bk_dict"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {
|
||||
Quit,
|
||||
WindowFullscreen,
|
||||
WindowHide,
|
||||
WindowUnfullscreen
|
||||
WindowUnfullscreen,
|
||||
WindowSetTitle
|
||||
} from '../wailsjs/runtime'
|
||||
import {h, onBeforeMount, onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import {RouterLink, useRouter} from 'vue-router'
|
||||
@@ -43,6 +44,7 @@ const loadingMsg = ref("加载数据中...")
|
||||
const enableNews = ref(false)
|
||||
const contentStyle = ref("")
|
||||
const enableFund = ref(false)
|
||||
const enableAgent = ref(false)
|
||||
const enableDarkTheme = ref(null)
|
||||
const content = ref('未经授权,禁止商业目的!\n\n数据来源于网络,仅供参考;投资有风险,入市需谨慎')
|
||||
const isFullscreen = ref(false)
|
||||
@@ -440,6 +442,7 @@ const menuOptions = ref([
|
||||
{default: () => 'Ai智能体'}
|
||||
),
|
||||
key: 'agent',
|
||||
show:enableAgent.value,
|
||||
icon: renderIcon(Robot),
|
||||
},
|
||||
{
|
||||
@@ -646,11 +649,15 @@ onBeforeMount(() => {
|
||||
GetConfig().then((res) => {
|
||||
//console.log(res)
|
||||
enableFund.value = res.enableFund
|
||||
enableAgent.value = res.enableAgent
|
||||
|
||||
menuOptions.value.filter((item) => {
|
||||
if (item.key === 'fund') {
|
||||
item.show = res.enableFund
|
||||
}
|
||||
if (item.key === 'agent') {
|
||||
item.show = res.enableAgent
|
||||
}
|
||||
})
|
||||
|
||||
if (res.darkTheme) {
|
||||
@@ -662,12 +669,14 @@ onBeforeMount(() => {
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
WindowSetTitle("go-stock:AI赋能股票分析✨ 未经授权,禁止商业目的! [数据来源于网络,仅供参考;投资有风险,入市需谨慎]")
|
||||
contentStyle.value = "max-height: calc(92vh);overflow: hidden"
|
||||
GetConfig().then((res) => {
|
||||
if (res.enableNews) {
|
||||
enableNews.value = true
|
||||
}
|
||||
enableFund.value = res.enableFund
|
||||
enableAgent.value = res.enableAgent
|
||||
const {notification } =createDiscreteApi(["notification"], {
|
||||
configProviderProps: {
|
||||
theme: enableDarkTheme.value ? darkTheme : lightTheme ,
|
||||
@@ -714,7 +723,7 @@ onMounted(() => {
|
||||
<n-modal-provider>
|
||||
<n-dialog-provider>
|
||||
<n-watermark
|
||||
:content="content"
|
||||
:content="''"
|
||||
cross
|
||||
selectable
|
||||
:font-size="16"
|
||||
|
||||
@@ -5,7 +5,9 @@ import 'md-editor-v3/lib/preview.css';
|
||||
import {h, onBeforeUnmount, onMounted, ref} from 'vue';
|
||||
import {CheckUpdate, GetVersionInfo,GetSponsorInfo,OpenURL} from "../../wailsjs/go/main/App";
|
||||
import {EventsOff, EventsOn,Environment} from "../../wailsjs/runtime";
|
||||
import {NAvatar, NButton, useNotification} from "naive-ui";
|
||||
import {NAvatar, NButton, useNotification,NText} from "naive-ui";
|
||||
import { addMonths, format ,parse} from 'date-fns';
|
||||
import { zhCN } from 'date-fns/locale';
|
||||
const updateLog = ref('');
|
||||
const versionInfo = ref('');
|
||||
const icon = ref('https://raw.githubusercontent.com/ArvinLovegood/go-stock/master/build/appicon.png');
|
||||
@@ -16,6 +18,7 @@ const notify = useNotification()
|
||||
const vipLevel=ref("");
|
||||
const vipStartTime=ref("");
|
||||
const vipEndTime=ref("");
|
||||
const expired=ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
document.title = '关于软件';
|
||||
@@ -31,6 +34,13 @@ onMounted(() => {
|
||||
vipLevel.value = res.vipLevel;
|
||||
vipStartTime.value = res.vipStartTime;
|
||||
vipEndTime.value = res.vipEndTime;
|
||||
//判断时间是否到期
|
||||
if (res.vipLevel) {
|
||||
if (res.vipEndTime < format(new Date(), 'yyyy-MM-dd HH:mm:ss')) {
|
||||
notify.warning({content: 'VIP已到期'})
|
||||
expired.value = true;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
@@ -115,10 +125,10 @@ EventsOn("updateVersion",async (msg) => {
|
||||
<n-gradient-text type="info" :size="50" >go-stock</n-gradient-text>
|
||||
</n-badge>
|
||||
<n-badge v-if="vipLevel" :value="versionInfo" :offset="[50,10]" type="success">
|
||||
<n-gradient-text type="warning" :size="50" >go-stock</n-gradient-text><n-tag :bordered="false" size="small" type="warning">VIP{{vipLevel}}</n-tag>
|
||||
<n-gradient-text :type="expired?'error':'warning'" :size="50" >go-stock</n-gradient-text><n-tag :bordered="false" size="small" type="warning">VIP{{vipLevel}}</n-tag>
|
||||
</n-badge>
|
||||
</h1>
|
||||
<n-gradient-text type="warning" v-if="vipLevel" >vip到期时间:{{vipEndTime}}</n-gradient-text>
|
||||
<n-gradient-text :type="expired?'error':'warning'" v-if="vipLevel" >vip到期时间:{{vipEndTime}}</n-gradient-text>
|
||||
<n-button size="tiny" @click="CheckUpdate(1)" type="info" tertiary >检查更新</n-button>
|
||||
<div style="justify-self: center;text-align: left" >
|
||||
<p>自选股行情实时监控,基于Wails和NaiveUI构建的AI赋能股票分析工具</p>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<template #content="{ item, index }">
|
||||
<t-chat-reasoning v-if="item.role === 'assistant'" expand-icon-placement="right">
|
||||
<t-chat-loading v-if="isStreamLoad" text="思考中..." />
|
||||
<!-- <t-chat-content v-if="item.reasoning.length > 0" :content="item.reasoning" />-->
|
||||
<t-chat-content v-if="item.reasoning.length > 0" :content="item.reasoning" />
|
||||
</t-chat-reasoning>
|
||||
<t-chat-content v-if="item.content.length > 0" :content="item.content" />
|
||||
</template>
|
||||
@@ -97,9 +97,9 @@ EventsOn("agent-message", (data) => {
|
||||
if(data['role']==="assistant"){
|
||||
loading.value = false;
|
||||
const lastItem = chatList.value[0];
|
||||
// if (data['reasoning_content']){
|
||||
// lastItem.reasoning = data['reasoning_content'];
|
||||
// }
|
||||
if (data['reasoning_content']){
|
||||
lastItem.reasoning += data['reasoning_content'];
|
||||
}
|
||||
if (data['content']){
|
||||
lastItem.content +=data['content'];
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ const updateMessage = () => {
|
||||
<n-text type="warning">查看原文</n-text>
|
||||
</a>
|
||||
</n-tag>
|
||||
<n-tag v-if="item.sentimentResult" :bordered="false" :type="item.sentimentResult==='看涨'?'error':item.sentimentResult==='看跌'?'success':'info'" size="small">
|
||||
{{ item.sentimentResult }}
|
||||
</n-tag>
|
||||
</n-space>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
|
||||
@@ -45,6 +45,7 @@ const formValue = ref({
|
||||
sponsorCode: "",
|
||||
httpProxy:"",
|
||||
httpProxyEnabled:false,
|
||||
enableAgent: false,
|
||||
})
|
||||
|
||||
// 添加一个新的AI配置到列表
|
||||
@@ -103,6 +104,7 @@ onMounted(() => {
|
||||
formValue.value.sponsorCode = res.sponsorCode
|
||||
formValue.value.httpProxy=res.httpProxy;
|
||||
formValue.value.httpProxyEnabled=res.httpProxyEnabled;
|
||||
formValue.value.enableAgent = res.enableAgent;
|
||||
|
||||
})
|
||||
|
||||
@@ -142,6 +144,7 @@ function saveConfig() {
|
||||
sponsorCode: formValue.value.sponsorCode,
|
||||
httpProxy:formValue.value.httpProxy,
|
||||
httpProxyEnabled:formValue.value.httpProxyEnabled,
|
||||
enableAgent: formValue.value.enableAgent,
|
||||
})
|
||||
|
||||
if (config.sponsorCode) {
|
||||
@@ -231,6 +234,7 @@ function importConfig() {
|
||||
formValue.value.sponsorCode = config.sponsorCode
|
||||
formValue.value.httpProxy=config.httpProxy
|
||||
formValue.value.httpProxyEnabled=config.httpProxyEnabled
|
||||
formValue.value.enableAgent = config.enableAgent
|
||||
};
|
||||
reader.readAsText(file);
|
||||
};
|
||||
@@ -321,6 +325,10 @@ function deletePrompt(ID) {
|
||||
<n-form-item-gi :span="3" label="指数基金:" path="enableFund">
|
||||
<n-switch v-model:value="formValue.enableFund"/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="3" label="AI智能体:" path="enableAgent">
|
||||
<n-switch v-model:value="formValue.enableAgent"/>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="11" label="赞助码:" path="sponsorCode">
|
||||
<n-input-group>
|
||||
<n-input :show-count="true" placeholder="赞助码" v-model:value="formValue.sponsorCode"/>
|
||||
|
||||
@@ -1853,8 +1853,8 @@ function updateTab(name) {
|
||||
})
|
||||
}
|
||||
|
||||
function delTab(name) {
|
||||
let infos = groupList.value = groupList.value.filter(item => item.ID === Number(name))
|
||||
function delTab(groupId) {
|
||||
let infos = groupList.value = groupList.value.filter(item => item.ID === Number(groupId))
|
||||
dialog.create({
|
||||
title: '删除分组',
|
||||
type: 'warning',
|
||||
@@ -1862,7 +1862,7 @@ function delTab(name) {
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
RemoveGroup(name).then(result => {
|
||||
RemoveGroup(Number(groupId)).then(result => {
|
||||
message.info(result)
|
||||
GetGroupList().then(result => {
|
||||
groupList.value = result
|
||||
|
||||
@@ -9,18 +9,21 @@ import EmbeddedUrl from "./EmbeddedUrl.vue";
|
||||
<n-tab-pane name="选股通" tab="选股通">
|
||||
<embedded-url url="https://xuangutong.com.cn" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
<!-- <n-tab-pane name="百度股市通" tab="百度股市通">-->
|
||||
<!-- <embedded-url url="https://gushitong.baidu.com" :height="'calc(100vh - 252px)'"/>-->
|
||||
<!-- </n-tab-pane>-->
|
||||
<n-tab-pane name="百度股市通" tab="百度股市通">
|
||||
<embedded-url url="https://gushitong.baidu.com" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="东财大盘星图" tab="东财大盘星图">
|
||||
<embedded-url url="https://quote.eastmoney.com/stockhotmap/" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="TopHub" tab="TopHub(今日热榜)">
|
||||
<embedded-url url="https://tophub.today/c/finance" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
<!-- <n-tab-pane name="摸鱼" tab="摸鱼">-->
|
||||
<!-- <embedded-url url="https://996.ninja/" :height="'calc(100vh - 252px)'"/>-->
|
||||
<!-- </n-tab-pane>-->
|
||||
<n-tab-pane name="摸鱼" tab="摸鱼">
|
||||
<embedded-url url="https://996.ninja/" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="财联社-行情数据" tab="财联社-行情数据">
|
||||
<embedded-url url="https://www.cls.cn/quotation" :height="'calc(100vh - 252px)'"/>
|
||||
</n-tab-pane>
|
||||
|
||||
|
||||
<n-tab-pane name="欢迎推荐更多有趣的财经网页" tab="欢迎推荐更多有趣的财经网页">
|
||||
|
||||
@@ -393,6 +393,7 @@ export namespace data {
|
||||
sponsorCode: string;
|
||||
httpProxy: string;
|
||||
httpProxyEnabled: boolean;
|
||||
enableAgent: boolean;
|
||||
aiConfigs: AIConfig[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
@@ -428,6 +429,7 @@ export namespace data {
|
||||
this.sponsorCode = source["sponsorCode"];
|
||||
this.httpProxy = source["httpProxy"];
|
||||
this.httpProxyEnabled = source["httpProxyEnabled"];
|
||||
this.enableAgent = source["enableAgent"];
|
||||
this.aiConfigs = this.convertValues(source["aiConfigs"], AIConfig);
|
||||
}
|
||||
|
||||
|
||||
21
go.mod
21
go.mod
@@ -1,12 +1,10 @@
|
||||
module go-stock
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.5
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.10.1
|
||||
github.com/chromedp/chromedp v0.11.2
|
||||
github.com/chromedp/chromedp v0.14.1
|
||||
github.com/cloudwego/eino v0.4.1
|
||||
github.com/cloudwego/eino-ext/components/model/ark v0.1.19
|
||||
github.com/cloudwego/eino-ext/components/model/deepseek v0.0.0-20250804092122-8845979a2228
|
||||
@@ -28,7 +26,7 @@ require (
|
||||
github.com/wailsapp/wails/v2 v2.10.1
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/net v0.38.0
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.org/x/sys v0.36.0
|
||||
golang.org/x/text v0.26.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gorm.io/gorm v1.25.12
|
||||
@@ -40,12 +38,12 @@ require (
|
||||
git.sr.ht/~jackmordaunt/go-toast v1.1.2 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/bytedance/sonic v1.14.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d // indirect
|
||||
github.com/chromedp/sysutil v1.1.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f // indirect
|
||||
github.com/cohesion-org/deepseek-go v1.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -54,6 +52,7 @@ require (
|
||||
github.com/evanphx/json-patch v0.5.2 // indirect
|
||||
github.com/getkin/kin-openapi v0.118.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
@@ -72,7 +71,7 @@ require (
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
|
||||
@@ -119,7 +118,7 @@ require (
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/yargevad/filepathx v1.0.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.11.0 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/crypto v0.39.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
|
||||
39
go.sum
39
go.sum
@@ -16,24 +16,23 @@ github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqR
|
||||
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8=
|
||||
github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
|
||||
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb h1:noKVm2SsG4v0Yd0lHNtFYc9EUxIVvrr4kJ6hM8wvIYU=
|
||||
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb/go.mod h1:4XqMl3iIW08jtieURWL6Tt5924w21pxirC6th662XUM=
|
||||
github.com/chromedp/chromedp v0.11.2 h1:ZRHTh7DjbNTlfIv3NFTbB7eVeu5XCNkgrpcGSpn2oX0=
|
||||
github.com/chromedp/chromedp v0.11.2/go.mod h1:lr8dFRLKsdTTWb75C/Ttol2vnBKOSnt0BW8R9Xaupi8=
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d h1:ZtA1sedVbEW7EW80Iz2GR3Ye6PwbJAJXjv7D74xG6HU=
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k=
|
||||
github.com/chromedp/chromedp v0.14.1 h1:0uAbnxewy/Q+Bg7oafVePE/6EXEho9hnaC38f+TTENg=
|
||||
github.com/chromedp/chromedp v0.14.1/go.mod h1:rHzAv60xDE7VNy/MYtTUrYreSc0ujt2O1/C3bzctYBo=
|
||||
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
|
||||
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/cloudwego/eino v0.4.1 h1:Jy9KWpCvd+Z75oIynhHsT9dEECUuCW8IPZlVjHgVu9s=
|
||||
github.com/cloudwego/eino v0.4.1/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY=
|
||||
github.com/cloudwego/eino-ext/components/model/ark v0.1.19 h1:XYnOeszXA28T1gxYOpTIjOjLCPO2gjexK+ShSan9u/8=
|
||||
@@ -44,7 +43,6 @@ github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250804092122-8845
|
||||
github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250804092122-8845979a2228/go.mod h1:3uBZ/GzJzh1izfY2w62282FZrQG3ISs6T/jTmmPffvE=
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f h1:J1tQBg6RDftrtm3vsv+ozlupdlNV+WGslpXiTDr/2xI=
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f/go.mod h1:4EBgz8+68n1iuKyWC37Tu9NG1WJkPm+yLxvyLik28Us=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cohesion-org/deepseek-go v1.3.2 h1:WTZ/2346KFYca+n+DL5p+Ar1RQxF2w/wGkU4jDvyXaQ=
|
||||
github.com/cohesion-org/deepseek-go v1.3.2/go.mod h1:bOVyKj38r90UEYZFrmJOzJKPxuAh8sIzHOCnLOpiXeI=
|
||||
github.com/coocood/freecache v1.2.4 h1:UdR6Yz/X1HW4fZOuH0Z94KwG851GWOSknua5VUbb/5M=
|
||||
@@ -78,6 +76,8 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJY
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
github.com/go-ego/gse v0.80.3 h1:YNFkjMhlhQnUeuoFcUEd1ivh6SOB764rT8GDsEbDiEg=
|
||||
github.com/go-ego/gse v0.80.3/go.mod h1:Gt3A9Ry1Eso2Kza4MRaiZ7f2DTAvActmETY46Lxg0gU=
|
||||
github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 h1:02WINGfSX5w0Mn+F28UyRoSt9uvMhKguwWMlOAh6U/0=
|
||||
github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
@@ -162,10 +162,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@@ -343,8 +341,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
|
||||
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
@@ -413,8 +411,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -512,4 +510,3 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
|
||||
Reference in New Issue
Block a user