fix: for telegram streaming response
This commit is contained in:
parent
4d84bd90cd
commit
ae729d5fea
1 changed files with 88 additions and 34 deletions
|
|
@ -1857,6 +1857,29 @@ turnLoop:
|
|||
"tools_json": formatToolsForLog(providerToolDefs),
|
||||
})
|
||||
|
||||
// Acquire a streamer once per turn before entering the retry loop.
|
||||
// GetStreamer calls BeginStream on the channel (e.g. Telegram's
|
||||
// sendMessageDraft path). Returns nil when streaming is disabled
|
||||
// in config or the channel doesn't implement StreamingCapable.
|
||||
var activeStreamer bus.Streamer
|
||||
if ts.opts.SendResponse && ts.channel != "" && ts.chatID != "" {
|
||||
if s, ok := al.bus.GetStreamer(turnCtx, ts.channel, ts.chatID); ok {
|
||||
activeStreamer = s
|
||||
}
|
||||
}
|
||||
|
||||
// streamingProvider is the interface subset of ChatStream we need.
|
||||
type streamingProvider interface {
|
||||
ChatStream(
|
||||
ctx context.Context,
|
||||
messages []providers.Message,
|
||||
tools []providers.ToolDefinition,
|
||||
model string,
|
||||
options map[string]any,
|
||||
onChunk func(accumulated string),
|
||||
) (*providers.LLMResponse, error)
|
||||
}
|
||||
|
||||
callLLM := func(messagesForCall []providers.Message, toolDefsForCall []providers.ToolDefinition) (*providers.LLMResponse, error) {
|
||||
providerCtx, providerCancel := context.WithCancel(turnCtx)
|
||||
ts.setProviderCancel(providerCancel)
|
||||
|
|
@ -1864,10 +1887,42 @@ turnLoop:
|
|||
providerCancel()
|
||||
ts.clearProviderCancel(providerCancel)
|
||||
}()
|
||||
|
||||
al.activeRequests.Add(1)
|
||||
defer al.activeRequests.Done()
|
||||
|
||||
// Streaming path: only when a streamer is available AND there are
|
||||
// no tool definitions for this call (tool-calling iterations use
|
||||
// normal Chat() so tool JSON is parsed correctly).
|
||||
if activeStreamer != nil && len(toolDefsForCall) == 0 {
|
||||
if sp, ok := ts.agent.Provider.(streamingProvider); ok {
|
||||
resp, streamErr := sp.ChatStream(
|
||||
providerCtx,
|
||||
messagesForCall,
|
||||
toolDefsForCall,
|
||||
llmModel,
|
||||
llmOpts,
|
||||
func(accumulated string) {
|
||||
_ = activeStreamer.Update(providerCtx, accumulated)
|
||||
},
|
||||
)
|
||||
if streamErr == nil {
|
||||
// Deliver the final formatted message and mark streamActive
|
||||
// so preSend skips the duplicate PublishOutbound send.
|
||||
if finalizeErr := activeStreamer.Finalize(providerCtx, resp.Content); finalizeErr != nil {
|
||||
logger.WarnCF("agent", "Streamer finalize failed",
|
||||
map[string]any{"error": finalizeErr.Error()})
|
||||
}
|
||||
activeStreamer = nil // prevent double-finalize on retry
|
||||
return resp, nil
|
||||
}
|
||||
// ChatStream failed — cancel streamer and fall through to Chat()
|
||||
logger.WarnCF("agent", "ChatStream failed, falling back to Chat()",
|
||||
map[string]any{"error": streamErr.Error()})
|
||||
activeStreamer.Cancel(providerCtx)
|
||||
activeStreamer = nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(activeCandidates) > 1 && al.fallback != nil {
|
||||
fbResult, fbErr := al.fallback.Execute(
|
||||
providerCtx,
|
||||
|
|
@ -1891,7 +1946,6 @@ turnLoop:
|
|||
}
|
||||
return ts.agent.Provider.Chat(providerCtx, messagesForCall, toolDefsForCall, llmModel, llmOpts)
|
||||
}
|
||||
|
||||
var response *providers.LLMResponse
|
||||
var err error
|
||||
maxRetries := 2
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue