fix: inject pending assistant reply into inbound turns and fill ReplyToMessageID
Gap 1: regular inbound turns now see the previous assistant reply in LLM context even when OnDelivered hasn't fired yet (fast follow-up scenario). Achieved by loading from pendingDeliveries sync.Map after captureRestorePoint and appending to history before BuildMessages. Gap 2: HandleMessage in BaseChannel now fills ReplyToMessageID from metadata so the first-class struct field is populated for all channels that set the key in metadata (e.g. Telegram).
This commit is contained in:
parent
9880cb343b
commit
942c3d3f6e
2 changed files with 43 additions and 22 deletions
|
|
@ -58,6 +58,7 @@ type AgentLoop struct {
|
|||
hookRuntime hookRuntime
|
||||
steering *steeringQueue
|
||||
pendingSkills sync.Map
|
||||
pendingDeliveries sync.Map // sessionKey -> string: last undelivered assistant content
|
||||
mu sync.RWMutex
|
||||
|
||||
// Concurrent turn management (from HEAD)
|
||||
|
|
@ -1697,9 +1698,14 @@ func (al *AgentLoop) runAgentLoop(
|
|||
}
|
||||
|
||||
if !opts.NoHistory && result.finalContent != "" {
|
||||
// Register the pending content so that fast follow-up inbound turns can
|
||||
// inject it into their LLM context before OnDelivered persists it.
|
||||
al.pendingDeliveries.Store(opts.SessionKey, result.finalContent)
|
||||
|
||||
var once sync.Once
|
||||
response.OnDelivered = func(msgIDs []string) {
|
||||
once.Do(func() {
|
||||
al.pendingDeliveries.Delete(opts.SessionKey)
|
||||
assistantMsg := providers.Message{
|
||||
Role: "assistant",
|
||||
Content: result.finalContent,
|
||||
|
|
@ -1843,6 +1849,20 @@ func (al *AgentLoop) runTurn(ctx context.Context, ts *turnState) (turnResult, er
|
|||
}
|
||||
ts.captureRestorePoint(history, summary)
|
||||
|
||||
// Inject pending undelivered assistant reply into history so regular inbound turns
|
||||
// see it in LLM context even before OnDelivered persists it to session storage.
|
||||
// Only inject if history doesn't already end with an assistant message (avoids duplication
|
||||
// when OnDelivered fires before the next turn starts).
|
||||
if !ts.opts.NoHistory {
|
||||
if pendingRaw, ok := al.pendingDeliveries.Load(ts.sessionKey); ok {
|
||||
if pendingContent, _ := pendingRaw.(string); pendingContent != "" {
|
||||
if len(history) == 0 || history[len(history)-1].Role != "assistant" {
|
||||
history = append(history, providers.Message{Role: "assistant", Content: pendingContent})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messages := ts.agent.ContextBuilder.BuildMessages(
|
||||
history,
|
||||
summary,
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ func (c *BaseChannel) HandleMessage(
|
|||
MessageID: messageID,
|
||||
MediaScope: scope,
|
||||
Metadata: metadata,
|
||||
ReplyToMessageID: metadata["reply_to_message_id"],
|
||||
}
|
||||
|
||||
// Auto-trigger typing indicator, message reaction, and placeholder before publishing.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue