small fix

This commit is contained in:
2026-03-06 10:02:40 +03:00
parent bca84ad269
commit 3b673d5e2b
5 changed files with 69 additions and 51 deletions

View File

@@ -18,6 +18,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
FROM alpine:3.23 AS runner FROM alpine:3.23 AS runner
WORKDIR /app WORKDIR /app
ENV TZ=Europe/Moscow
ENV GOMEMLIMIT=256MiB ENV GOMEMLIMIT=256MiB
COPY --from=builder /usr/local/bin/ymgb /app/ymgb COPY --from=builder /usr/local/bin/ymgb /app/ymgb
CMD ["/app/ymgb"] CMD ["/app/ymgb"]
USER nobody

View File

@@ -144,7 +144,7 @@ func (r *Request[P]) DoStreamWithContext(ctx context.Context, api *API) (iter.Se
var zero AIResponse var zero AIResponse
for { for {
line, err := reader.ReadString('\n') line, err := reader.ReadString('\n')
if err != nil && err != io.EOF { if err != nil {
yield(zero, err) yield(zero, err)
return return
} }

View File

@@ -1,37 +0,0 @@
package openai
import (
"bufio"
"io"
"iter"
"strings"
)
// Server-sent event
func ReadSSE(r io.ReadCloser) iter.Seq[string] {
reader := bufio.NewReader(r)
return func(yield func(string) bool) {
for {
line, err := reader.ReadString('\n')
if err != nil {
return
}
if line == "" || line == "\n" {
continue
}
if strings.HasPrefix(line, "data: ") {
line = line[len("data: "):]
}
line = strings.TrimSpace(line)
line = strings.Trim(line, "\r")
line = strings.Trim(line, "\n")
if strings.HasPrefix(line, "[DONE]") {
return
}
if !yield(line) {
return
}
}
}
}

View File

@@ -4,9 +4,11 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"ymgb/database" "ymgb/database"
"ymgb/database/mdb" "ymgb/database/mdb"
@@ -479,7 +481,6 @@ func newChat(ctx *laniakea.MsgContext, db *database.Context) {
return return
} }
log.Println(ctx.Args)
chatPrompt := "" chatPrompt := ""
settingId, err := strconv.Atoi(ctx.Args[0]) settingId, err := strconv.Atoi(ctx.Args[0])
if err != nil { if err != nil {
@@ -664,15 +665,50 @@ func generate(ctx *laniakea.MsgContext, db *database.Context) {
} }
answerContent := "" answerContent := ""
draft := ctx.NewDraft() type DraftQueue struct {
for r, err := range res { message string
if m != nil { mu sync.Mutex
m.Delete()
m = nil
} }
draft := ctx.NewDraft()
var mu sync.Mutex
buffer := strings.Builder{} // накапливаем фрагменты
ticker := time.NewTicker(time.Second)
done := make(chan struct{}) // сигнал завершения горутины
// Горутина для периодической отправки
go func() {
flush := func() {
mu.Lock()
msg := buffer.String()
buffer.Reset()
mu.Unlock()
if msg != "" {
if err := draft.Push(msg); err != nil {
log.Println(err)
}
}
}
for {
select {
case <-ticker.C:
// Каждую секунду отправляем накопленное
flush()
ctx.SendAction(tgapi.ChatActionTyping)
case <-done:
// Завершаем работу: отправляем остаток и выходим
flush()
ticker.Stop()
return
}
}
}()
for r, err := range res {
if err != nil { if err != nil {
if errors.Is(err, io.EOF) {
break
}
ctx.Error(err) ctx.Error(err)
close(done)
return return
} }
@@ -683,14 +719,30 @@ func generate(ctx *laniakea.MsgContext, db *database.Context) {
if content == "" { if content == "" {
continue continue
} }
answerContent += content
err = draft.Push(content) if m != nil {
if err != nil { m.Delete()
ctx.Error(err) m = nil
//draft.Flush()
break
} }
time.Sleep(time.Millisecond * 250) answerContent += content
mu.Lock()
buffer.WriteString(content)
mu.Unlock()
// Если нужна искусственная задержка, оставьте:
// time.Sleep(time.Millisecond * 50)
}
// Завершаем горутину и отправляем последнюю порцию
close(done)
if answerContent == "" {
if m != nil {
m.Delete()
m = nil
}
ctx.Answer("Не удалось сгенерировать ответ. Попробуйте снова")
return
} }
counter := redisRpRep.GetCounter(ctx.FromID, waifuId) counter := redisRpRep.GetCounter(ctx.FromID, waifuId)

View File

@@ -3,5 +3,6 @@ package ai
const GPTBaseUrl = "https://chat.gpt-chatbot.ru/api/openai" const GPTBaseUrl = "https://chat.gpt-chatbot.ru/api/openai"
const CompressPrompt = "Сделай подробную выжимку нашего диалога. Сохрани все ключевые моменты(например сколько одежды, расположение, основные действия и фразы и тд.) из каждого сообщения, но никогда не копируй описание персонажа(цвет волос и глаз, характер и т.д.). Для моих сообщений используй обращение во втором лице(ты, вы), для своих в первом(я). Всегда называй вещи своими именами." const CompressPrompt = "Сделай подробную выжимку нашего диалога. Сохрани все ключевые моменты(например сколько одежды, расположение, основные действия и фразы и тд.) из каждого сообщения, но никогда не копируй описание персонажа(цвет волос и глаз, характер и т.д.). Для моих сообщений используй обращение во втором лице(ты, вы), для своих в первом(я). Всегда называй вещи своими именами."
//Кратко подведите итоги содержимого беседы для использования в качестве последующего контекстного запроса, не более 200 слов
//const PawanBaseURL = "https://api.pawan.krd" //const PawanBaseURL = "https://api.pawan.krd"
//var CosmoRPUrl = fmt.Sprintf("%s/cosmosrp-2.5", PawanBaseURL) //var CosmoRPUrl = fmt.Sprintf("%s/cosmosrp-2.5", PawanBaseURL)