mirror of
https://github.com/HugeFrog24/go-telegram-bot.git
synced 2026-10-27 21:35:26 +00:00
Dep upd
This commit is contained in:
+36
-15
@@ -27,7 +27,7 @@ var mcpUnsupportedCount atomic.Uint64
|
||||
|
||||
type mcpCall struct{ server, name, input string }
|
||||
|
||||
func (b *Bot) getAnthropicResponse(ctx context.Context, chatID int64, messages []anthropic.BetaMessageParam, isEmojiOnly bool, username string, firstName string, lastName string, isPremium bool, languageCode string, messageTime int, onSegment func(string) error) (string, error) {
|
||||
func (b *Bot) getAnthropicResponse(ctx context.Context, chatID int64, messages []anthropic.BetaMessageParam, isEmojiOnly bool, username string, firstName string, lastName string, isPremium bool, languageCode string, messageTime int, onSegment func(string) error, onProgress func(string)) (string, error) {
|
||||
staticPrompt := strings.TrimSpace(b.config.SystemPrompts["custom_instructions"])
|
||||
|
||||
InfoLogger.Printf("Sending %d messages to Anthropic", len(messages))
|
||||
@@ -107,11 +107,13 @@ func (b *Bot) getAnthropicResponse(ctx context.Context, chatID int64, messages [
|
||||
params.Tools = tools
|
||||
}
|
||||
|
||||
var fullText strings.Builder
|
||||
var full string
|
||||
var lastMsg anthropic.BetaMessage
|
||||
fileRetries, pauseContinuations := 0, 0
|
||||
for {
|
||||
joined, msg, streamErr := b.streamMessages(ctx, params, onSegment)
|
||||
// full is passed as the progress prefix so that, across pause_turn
|
||||
// continuations, the user watches the whole reply so far.
|
||||
joined, msg, streamErr := b.streamMessages(ctx, params, onSegment, onProgress, full)
|
||||
if streamErr != nil {
|
||||
var apiErr *anthropic.Error
|
||||
if !errors.As(streamErr, &apiErr) || apiErr.StatusCode != http.StatusNotFound {
|
||||
@@ -136,12 +138,7 @@ func (b *Bot) getAnthropicResponse(ctx context.Context, chatID int64, messages [
|
||||
}
|
||||
|
||||
lastMsg = msg
|
||||
if joined != "" {
|
||||
if fullText.Len() > 0 {
|
||||
fullText.WriteString("\n\n")
|
||||
}
|
||||
fullText.WriteString(joined)
|
||||
}
|
||||
full = joinNonEmpty(full, joined)
|
||||
|
||||
if msg.StopReason == anthropic.BetaStopReasonPauseTurn {
|
||||
pauseContinuations++
|
||||
@@ -156,11 +153,11 @@ func (b *Bot) getAnthropicResponse(ctx context.Context, chatID int64, messages [
|
||||
break
|
||||
}
|
||||
|
||||
if fullText.Len() == 0 {
|
||||
if full == "" {
|
||||
return "", emptyStreamError(string(lastMsg.StopReason),
|
||||
lastMsg.Usage.OutputTokensDetails.ThinkingTokens, params.MaxTokens)
|
||||
}
|
||||
return fullText.String(), nil
|
||||
return full, nil
|
||||
}
|
||||
|
||||
func webSearchTools(cfg *WebSearchConfig) []anthropic.BetaToolUnionParam {
|
||||
@@ -276,7 +273,12 @@ func thinkingParamFromConfig(mode, display string) (anthropic.BetaThinkingConfig
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNewParams, onSegment func(string) error) (string, anthropic.BetaMessage, error) {
|
||||
// streamMessages runs one streaming request and returns its text blocks joined.
|
||||
// onSegment fires with each completed text block; onProgress fires on every
|
||||
// text delta with the whole reply so far, prefix included, for sinks that
|
||||
// redraw in place rather than append. prefix is what earlier requests of the
|
||||
// same turn already produced and is not part of the returned text.
|
||||
func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNewParams, onSegment func(string) error, onProgress func(string), prefix string) (string, anthropic.BetaMessage, error) {
|
||||
stream := b.anthropicClient.Beta.Messages.NewStreaming(ctx, params)
|
||||
defer func() {
|
||||
if err := stream.Close(); err != nil {
|
||||
@@ -286,7 +288,8 @@ func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNe
|
||||
|
||||
var (
|
||||
message anthropic.BetaMessage
|
||||
allSegments []string
|
||||
done string // this request's completed text blocks, joined
|
||||
doneAll = prefix // same, with the turn's earlier requests in front
|
||||
currentKind string
|
||||
currentText strings.Builder
|
||||
currentThinking strings.Builder
|
||||
@@ -336,6 +339,9 @@ func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNe
|
||||
case "text_delta":
|
||||
if currentKind == "text" {
|
||||
currentText.WriteString(cbd.Delta.Text)
|
||||
if onProgress != nil {
|
||||
onProgress(joinNonEmpty(doneAll, currentText.String()))
|
||||
}
|
||||
}
|
||||
case "thinking_delta":
|
||||
if currentKind == "thinking" {
|
||||
@@ -352,7 +358,8 @@ func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNe
|
||||
case "text":
|
||||
seg := strings.TrimSpace(currentText.String())
|
||||
if seg != "" {
|
||||
allSegments = append(allSegments, seg)
|
||||
done = joinNonEmpty(done, seg)
|
||||
doneAll = joinNonEmpty(doneAll, seg)
|
||||
if onSegment != nil {
|
||||
if cbErr := onSegment(seg); cbErr != nil {
|
||||
ErrorLogger.Printf("[stream] onSegment failed: %v", cbErr)
|
||||
@@ -428,7 +435,21 @@ func (b *Bot) streamMessages(ctx context.Context, params anthropic.BetaMessageNe
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(allSegments, "\n\n"), message, nil
|
||||
return done, message, nil
|
||||
}
|
||||
|
||||
// joinNonEmpty is the one rule for assembling reply text from parts: a blank
|
||||
// line between them, empty parts skipped. The live draft, the final message,
|
||||
// and the stored partial all go through it, so they can never disagree.
|
||||
func joinNonEmpty(a, b string) string {
|
||||
switch {
|
||||
case a == "":
|
||||
return b
|
||||
case b == "":
|
||||
return a
|
||||
default:
|
||||
return a + "\n\n" + b
|
||||
}
|
||||
}
|
||||
|
||||
func emptyStreamError(stopReason string, thinkingTokens, maxTokens int64) error {
|
||||
|
||||
Reference in New Issue
Block a user