Commit a1665fde authored by Wade's avatar Wade

qa chat

parent b9d1f783
...@@ -2,6 +2,7 @@ package main ...@@ -2,6 +2,7 @@ package main
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
...@@ -27,6 +28,11 @@ type Input struct { ...@@ -27,6 +28,11 @@ type Input struct {
func main() { func main() {
mainQA()
ctx := context.Background() ctx := context.Background()
ds := deepseek.DeepSeek{ ds := deepseek.DeepSeek{
...@@ -47,8 +53,14 @@ func main() { ...@@ -47,8 +53,14 @@ func main() {
// Define a simple flow that generates jokes about a given topic // Define a simple flow that generates jokes about a given topic
genkit.DefineFlow(g, "chat", func(ctx context.Context, input *Input) (string, error) { genkit.DefineFlow(g, "chat", func(ctx context.Context, input *Input) (string, error) {
inputAsJson, err := json.Marshal(input)
if err != nil{
return "",err
}
fmt.Println("input-------------------------------",input.Content) fmt.Println("input-------------------------------",string(inputAsJson))
resp, err := genkit.Generate(ctx, g, resp, err := genkit.Generate(ctx, g,
ai.WithModel(m), ai.WithModel(m),
...@@ -80,12 +92,6 @@ func main() { ...@@ -80,12 +92,6 @@ func main() {
mux.Handle("POST /"+a.Name(), handler) mux.Handle("POST /"+a.Name(), handler)
} }
//mux.HandleFunc("/swagger/", httpSwagger.WrapHandler)
// 暴露 Swagger UI,使用 swagger.yaml
// mux.HandleFunc("/swagger/", httpSwagger.Handler(
// httpSwagger.URL("/swagger/doc.yaml"), // 指定 YAML 文件路径
// ))
// 暴露 Swagger UI,使用 swagger.yaml // 暴露 Swagger UI,使用 swagger.yaml
mux.HandleFunc("/swagger/", httpSwagger.Handler( mux.HandleFunc("/swagger/", httpSwagger.Handler(
......
...@@ -15,14 +15,14 @@ var ( ...@@ -15,14 +15,14 @@ var (
connString = flag.String("dbconn", "", "database connection string") connString = flag.String("dbconn", "", "database connection string")
) )
// QA 结构体表示 qa 表的记录
type QA struct { type QA struct {
ID int64 // 主键 ID int64 // 主键
CreatedAt time.Time // 创建时间 CreatedAt time.Time // 创建时间
UserID *int64 // 可空的用户 ID UserID *int64 // 可空的用户 ID
Username *string // 可空的用户名 Username *string // 可空的用户名
Question *string // 可空的问题 Question *string // 可空的问题
Answer *string // 可空的答案 Answer *string // 可空的答案
Summary *string // 可空的摘要
} }
// QAStore 定义 DAO 接口 // QAStore 定义 DAO 接口
...@@ -43,138 +43,146 @@ func NewQAStore(db *sql.DB) QAStore { ...@@ -43,138 +43,146 @@ func NewQAStore(db *sql.DB) QAStore {
return &qaStore{db: db} return &qaStore{db: db}
} }
// GetLatestQA 从 latest_qa 视图读取数据
func (s *qaStore) GetLatestQA(ctx context.Context, userID *int64) ([]QA, error) { func (s *qaStore) GetLatestQA(ctx context.Context, userID *int64) ([]QA, error) {
query := ` query := `
SELECT id, created_at, user_id, username, question, answer SELECT id, created_at, user_id, username, question, answer, summary
FROM latest_qa FROM latest_qa
WHERE user_id = $1 OR (user_id IS NULL AND $1 IS NULL)` WHERE user_id = $1 OR (user_id IS NULL AND $1 IS NULL)`
args := []interface{}{userID} args := []interface{}{userID}
if userID == nil { if userID == nil {
args = []interface{}{nil} args = []interface{}{nil}
} }
rows, err := s.db.QueryContext(ctx, query, args...) rows, err := s.db.QueryContext(ctx, query, args...)
if err != nil { if err != nil {
return nil, fmt.Errorf("query latest_qa: %w", err) return nil, fmt.Errorf("query latest_qa: %w", err)
} }
defer rows.Close() defer rows.Close()
var results []QA var results []QA
for rows.Next() { for rows.Next() {
var qa QA var qa QA
var userIDVal sql.NullInt64 var userIDVal sql.NullInt64
var username, question, answer sql.NullString var username, question, answer, summary sql.NullString
if err := rows.Scan(&qa.ID, &qa.CreatedAt, &userIDVal, &username, &question, &answer); err != nil { if err := rows.Scan(&qa.ID, &qa.CreatedAt, &userIDVal, &username, &question, &answer, &summary); err != nil {
return nil, fmt.Errorf("scan row: %w", err) return nil, fmt.Errorf("scan row: %w", err)
} }
if userIDVal.Valid { if userIDVal.Valid {
qa.UserID = &userIDVal.Int64 qa.UserID = &userIDVal.Int64
} }
if username.Valid { if username.Valid {
qa.Username = &username.String qa.Username = &username.String
} }
if question.Valid { if question.Valid {
qa.Question = &question.String qa.Question = &question.String
} }
if answer.Valid { if answer.Valid {
qa.Answer = &answer.String qa.Answer = &answer.String
} }
results = append(results, qa) if summary.Valid {
} qa.Summary = &summary.String
if err := rows.Err(); err != nil { }
return nil, fmt.Errorf("row iteration: %w", err) results = append(results, qa)
} }
return results, nil if err := rows.Err(); err != nil {
return nil, fmt.Errorf("row iteration: %w", err)
}
return results, nil
} }
// WriteQA 插入或更新 qa 表记录
func (s *qaStore) WriteQA(ctx context.Context, qa QA) (int64, error) { func (s *qaStore) WriteQA(ctx context.Context, qa QA) (int64, error) {
if qa.ID != 0 { if qa.ID != 0 {
// 更新记录 // 更新记录
query := ` query := `
UPDATE qa UPDATE qa
SET user_id = $1, username = $2, question = $3, answer = $4 SET user_id = $1, username = $2, question = $3, answer = $4, summary = $5
WHERE id = $5 WHERE id = $6
RETURNING id` RETURNING id`
var updatedID int64 var updatedID int64
err := s.db.QueryRowContext(ctx, query, qa.UserID, qa.Username, qa.Question, qa.Answer, qa.ID).Scan(&updatedID) err := s.db.QueryRowContext(ctx, query, qa.UserID, qa.Username, qa.Question, qa.Answer, qa.Summary, qa.ID).Scan(&updatedID)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return 0, fmt.Errorf("no record found with id %d", qa.ID) return 0, fmt.Errorf("no record found with id %d", qa.ID)
} }
if err != nil { if err != nil {
return 0, fmt.Errorf("update qa: %w", err) return 0, fmt.Errorf("update qa: %w", err)
} }
return updatedID, nil return updatedID, nil
} }
// 插入新记录 // 插入新记录
query := ` query := `
INSERT INTO qa (user_id, username, question, answer) INSERT INTO qa (user_id, username, question, answer, summary)
VALUES ($1, $2, $3, $4) VALUES ($1, $2, $3, $4, $5)
RETURNING id` RETURNING id`
var newID int64 var newID int64
err := s.db.QueryRowContext(ctx, query, qa.UserID, qa.Username, qa.Question, qa.Answer).Scan(&newID) err := s.db.QueryRowContext(ctx, query, qa.UserID, qa.Username, qa.Question, qa.Answer, qa.Summary).Scan(&newID)
if err != nil { if err != nil {
return 0, fmt.Errorf("insert qa: %w", err) return 0, fmt.Errorf("insert qa: %w", err)
} }
return newID, nil return newID, nil
} }
func mainQA() { func mainQA() {
flag.Parse()
ctx := context.Background()
if *connString == "" { // postgres://postgres.awcfgdodiuqnlsobcivq:[YOUR-PASSWORD]@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres
log.Fatal("need -dbconn") // postgres://postgres.awcfgdodiuqnlsobcivq:rNVrqxaapXypEGg8@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres
} //connString := "postgres://postgres.awcfgdodiuqnlsobcivq:rNVrqxaapXypEGg8@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres"
// var connString = "postgres://postgres.awcfgdodiuqnlsobcivq:rNVrqxaapXypEGg8@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres"
db, err := sql.Open("postgres", *connString) var connString = "postgresql://postgres.awcfgdodiuqnlsobcivq:P8L00j7k3wHRwUJw@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres"
if err != nil {
log.Fatalf("open database: %v", err)
}
defer db.Close()
store := NewQAStore(db) db, err := sql.Open("postgres", connString)
if err != nil {
log.Fatalf("open database: %v", err)
}
defer db.Close()
// 示例:读取 user_id=101 的最新 QA store := NewQAStore(db)
results, err := store.GetLatestQA(ctx, int64Ptr(101))
if err != nil {
log.Fatalf("get latest QA: %v", err)
}
for _, qa := range results {
fmt.Printf("ID: %d, CreatedAt: %v, UserID: %v, Username: %v, Question: %v, Answer: %v\n",
qa.ID, qa.CreatedAt, derefInt64(qa.UserID), derefString(qa.Username), derefString(qa.Question), derefString(qa.Answer))
}
// 示例:插入新 QA ctx := context.Background()
newQA := QA{
UserID: int64Ptr(101), // 示例:读取 user_id=101 的最新 QA
Username: stringPtr("alice"), results, err := store.GetLatestQA(ctx, int64Ptr(101))
Question: stringPtr("What is AI?"), if err != nil {
Answer: stringPtr("AI is..."), log.Fatalf("get latest QA: %v", err)
} }
newID, err := store.WriteQA(ctx, newQA) for _, qa := range results {
if err != nil { fmt.Printf("ID: %d, CreatedAt: %v, UserID: %v, Username: %v, Question: %v, Answer: %v, Summary: %v\n",
log.Fatalf("write QA: %v", err) qa.ID, qa.CreatedAt, derefInt64(qa.UserID), derefString(qa.Username),
} derefString(qa.Question), derefString(qa.Answer), derefString(qa.Summary))
fmt.Printf("Inserted QA with ID: %d\n", newID) }
// 示例:更新 QA // 示例:插入新 QA
updateQA := QA{ newQA := QA{
ID: newID, UserID: int64Ptr(101),
UserID: int64Ptr(101), Username: stringPtr("alice"),
Username: stringPtr("alice_updated"), Question: stringPtr("What is AI?"),
Question: stringPtr("What is NLP?"), Answer: stringPtr("AI is..."),
Answer: stringPtr("NLP is..."), Summary: stringPtr("AI overview"),
} }
updatedID, err := store.WriteQA(ctx, updateQA) newID, err := store.WriteQA(ctx, newQA)
if err != nil { if err != nil {
log.Fatalf("update QA: %v", err) log.Fatalf("write QA: %v", err)
} }
fmt.Printf("Updated QA with ID: %d\n", updatedID) fmt.Printf("Inserted QA with ID: %d\n", newID)
// 示例:更新 QA
updateQA := QA{
ID: newID,
UserID: int64Ptr(101),
Username: stringPtr("alice_updated"),
Question: stringPtr("What is NLP?"),
Answer: stringPtr("NLP is..."),
Summary: stringPtr("NLP overview"),
}
updatedID, err := store.WriteQA(ctx, updateQA)
if err != nil {
log.Fatalf("update QA: %v", err)
}
fmt.Printf("Updated QA with ID: %d\n", updatedID)
} }
// 辅助函数:处理指针类型的空值 // 辅助函数:处理指针类型的空值
func int64Ptr(i int64) *int64 { func int64Ptr(i int64) *int64 {
return &i return &i
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment