fix(providers): prevent crash on cancel, capture thinking signature, nil guard (#287, #188, #566, #335)

- anthropic_stream.go: check ctx.Err() in scanner loop, bounds check toolCallJSON index,
  accumulate signature_delta events into ThinkingSignature
- anthropic_request.go: include signature field in buildRawBlock for thinking blocks
- types.go: add ThinkingSignature field to ChatResponse
- loop_run.go: nil guard on result before FinishTrace access
- gateway.go: defensive ApplyDBSecrets before setupTTS in config reload subscriber
This commit is contained in:
viettranx committed 2026-03-30 14:11:52 +07:00
1 parent 011f5f1a3d
commit e1c52cbda8
6 files changed
+223 -3

No files matched your search

+27
View File
@@ -10,6 +10,7 @@ import (
"path/filepath"
"strings"
"syscall"
"time"
"github.com/google/uuid"
@@ -1049,6 +1050,11 @@ func runGateway() {
if !ok {
return
}
if pgStores.ConfigSecrets != nil {
if secrets, err := pgStores.ConfigSecrets.GetAll(context.Background()); err == nil && len(secrets) > 0 {
updatedCfg.ApplyDBSecrets(secrets)
}
}
newMgr := setupTTS(updatedCfg)
if newMgr == nil {
return
@@ -1057,6 +1063,21 @@ func runGateway() {
slog.Info("tts config reloaded", "provider", newMgr.PrimaryProvider(), "auto", string(newMgr.AutoMode()))
})
// Log orphaned providers on agent deletion. Auto-delete is unsafe because
// providers can be referenced by heartbeats (FK), OAuth tokens, media chains.
// Users should clean up orphaned providers manually via UI/API.
msgBus.Subscribe("agent-deleted-provider-log", func(evt bus.Event) {
if evt.Name != bus.TopicAgentDeleted {
return
}
payload, ok := evt.Payload.(bus.AgentDeletedPayload)
if !ok || payload.Provider == "" {
return
}
slog.Info("agent deleted, provider may be orphaned — verify via UI",
"agent", payload.AgentKey, "provider", payload.Provider)
})
// Contact collector: auto-collect user info from channels with in-memory dedup cache.
var contactCollector *store.ContactCollector
if pgStores.Contacts != nil {
@@ -1103,6 +1124,12 @@ func runGateway() {
sandboxMgr.ReleaseAll(context.Background())
}
if sched != nil {
slog.Info("gateway: draining active runs", "timeout", "5s")
sched.Stop() // MarkDraining + StopAll
time.Sleep(5 * time.Second)
}
cancel()
}()