From 94a2756b8ea8df2e1b4c45b55bbd077a5a9e0035 Mon Sep 17 00:00:00 2001 From: stevef Date: Sun, 19 Apr 2026 10:19:42 +0200 Subject: [PATCH] =?UTF-8?q?feat(agent):=20add=20FreeRide=20provenance=20ma?= =?UTF-8?q?rker=20=F0=9F=A6=9E=20to=20responses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/agent/loop.go | 7 ++++++- pkg/agent/turn.go | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index bc65ca08d..9efaaa209 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -1776,10 +1776,14 @@ func (al *AgentLoop) runAgentLoop( } if opts.SendResponse && result.finalContent != "" { + finalContent := result.finalContent + if usedFallback, fallbackModel := ts.GetFallbackInfo(); usedFallback { + finalContent += fmt.Sprintf("\n\n🦞 _(FreeRide: %s)_", fallbackModel) + } al.bus.PublishOutbound(ctx, bus.OutboundMessage{ Channel: opts.Channel, ChatID: opts.ChatID, - Content: result.finalContent, + Content: finalContent, }) } @@ -2221,6 +2225,7 @@ turnLoop: fbResult.Provider, fbResult.Model, len(fbResult.Attempts)+1), map[string]any{"agent_id": ts.agent.ID, "iteration": iteration}, ) + ts.SetFallbackInfo(true, fbResult.Model) } return fbResult.Response, nil } diff --git a/pkg/agent/turn.go b/pkg/agent/turn.go index 8f099ed1d..1fe8cde22 100644 --- a/pkg/agent/turn.go +++ b/pkg/agent/turn.go @@ -103,6 +103,8 @@ type turnState struct { tokenBudget *atomic.Int64 // Shared token budget counter lastFinishReason string // Last LLM finish_reason lastUsage *providers.UsageInfo // Last LLM usage info + usedFallback bool // Whether a fallback/FreeRide model was used + fallbackModel string // The name of the fallback model used // Back-reference to the owning AgentLoop (set for SubTurns only, used for hard abort cascade) al *AgentLoop @@ -478,6 +480,21 @@ func (ts *turnState) SetLastUsage(usage *providers.UsageInfo) { ts.lastUsage = usage } +// SetFallbackInfo sets fallback model info +func (ts *turnState) SetFallbackInfo(used bool, model string) { + ts.mu.Lock() + defer ts.mu.Unlock() + ts.usedFallback = used + ts.fallbackModel = model +} + +// GetFallbackInfo returns fallback model info +func (ts *turnState) GetFallbackInfo() (bool, string) { + ts.mu.RLock() + defer ts.mu.RUnlock() + return ts.usedFallback, ts.fallbackModel +} + // Context helper functions for SubTurn type turnStateKeyType struct{}