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),
|
"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) {
|
callLLM := func(messagesForCall []providers.Message, toolDefsForCall []providers.ToolDefinition) (*providers.LLMResponse, error) {
|
||||||
providerCtx, providerCancel := context.WithCancel(turnCtx)
|
providerCtx, providerCancel := context.WithCancel(turnCtx)
|
||||||
ts.setProviderCancel(providerCancel)
|
ts.setProviderCancel(providerCancel)
|
||||||
|
|
@ -1864,10 +1887,42 @@ turnLoop:
|
||||||
providerCancel()
|
providerCancel()
|
||||||
ts.clearProviderCancel(providerCancel)
|
ts.clearProviderCancel(providerCancel)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
al.activeRequests.Add(1)
|
al.activeRequests.Add(1)
|
||||||
defer al.activeRequests.Done()
|
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 {
|
if len(activeCandidates) > 1 && al.fallback != nil {
|
||||||
fbResult, fbErr := al.fallback.Execute(
|
fbResult, fbErr := al.fallback.Execute(
|
||||||
providerCtx,
|
providerCtx,
|
||||||
|
|
@ -1891,7 +1946,6 @@ turnLoop:
|
||||||
}
|
}
|
||||||
return ts.agent.Provider.Chat(providerCtx, messagesForCall, toolDefsForCall, llmModel, llmOpts)
|
return ts.agent.Provider.Chat(providerCtx, messagesForCall, toolDefsForCall, llmModel, llmOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
var response *providers.LLMResponse
|
var response *providers.LLMResponse
|
||||||
var err error
|
var err error
|
||||||
maxRetries := 2
|
maxRetries := 2
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue