mirror of
https://github.com/danielmiessler/fabric.git
synced 2026-09-10 07:36:44 -04:00
feat: add wire debug level (4) for full LLM request/response debug logging
## CHANGES - Add `Wire` log level constant to debug level enum - Expose `GetLevel()` function for safe concurrent level reads - Log outbound message roles and content at wire debug level - Log inbound stream updates and token usage at wire level - Log non-streaming LLM responses at wire debug level - Update `--debug` flag description to include new level 4 - Update `set_debug_level` locale strings across all 10 languages
This commit is contained in:
parent
98a5ad54e3
commit
e7d0d64511
|
|
@ -106,7 +106,7 @@ type Flags struct {
|
|||
NotificationCommand string `long:"notification-command" yaml:"notificationCommand" description:"Custom command to run for notifications (overrides built-in notifications)"`
|
||||
Thinking domain.ThinkingLevel `long:"thinking" yaml:"thinking" description:"Set reasoning/thinking level (e.g., off, low, medium, high, or numeric tokens for Anthropic or Google Gemini)"`
|
||||
ShowMetadata bool `long:"show-metadata" description:"Print metadata to stderr"`
|
||||
Debug int `long:"debug" description:"Set debug level (0=off, 1=basic, 2=detailed, 3=trace)" default:"0"`
|
||||
Debug int `long:"debug" description:"Set debug level (0=off, 1=basic, 2=detailed, 3=trace, 4=wire)" default:"0"`
|
||||
}
|
||||
|
||||
// Init Initialize flags. returns a Flags struct and an error
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/danielmiessler/fabric/internal/domain"
|
||||
"github.com/danielmiessler/fabric/internal/i18n"
|
||||
debuglog "github.com/danielmiessler/fabric/internal/log"
|
||||
"github.com/danielmiessler/fabric/internal/plugins/ai"
|
||||
"github.com/danielmiessler/fabric/internal/plugins/db/fsdb"
|
||||
"github.com/danielmiessler/fabric/internal/plugins/strategy"
|
||||
|
|
@ -41,6 +42,16 @@ func (o *Chatter) Send(request *domain.ChatRequest, opts *domain.ChatOptions) (s
|
|||
}
|
||||
|
||||
vendorMessages := session.GetVendorMessages()
|
||||
|
||||
if debuglog.GetLevel() >= debuglog.Wire {
|
||||
debuglog.Debug(debuglog.Wire, "FABRIC->LLM request messages (%d)\n", len(vendorMessages))
|
||||
for i, msg := range vendorMessages {
|
||||
debuglog.Debug(debuglog.Wire, "FABRIC->LLM [%d] role=%s content=%q\n", i, msg.Role, msg.Content)
|
||||
if len(msg.MultiContent) > 0 {
|
||||
debuglog.Debug(debuglog.Wire, "FABRIC->LLM [%d] parts=%d\n", i, len(msg.MultiContent))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(vendorMessages) == 0 {
|
||||
if session.Name != "" {
|
||||
err = o.db.Sessions.SaveSession(session)
|
||||
|
|
@ -76,6 +87,12 @@ func (o *Chatter) Send(request *domain.ChatRequest, opts *domain.ChatOptions) (s
|
|||
}()
|
||||
|
||||
for update := range responseChan {
|
||||
if debuglog.GetLevel() >= debuglog.Wire {
|
||||
debuglog.Debug(debuglog.Wire, "LLM->FABRIC stream update type=%s content=%q\n", update.Type, update.Content)
|
||||
if update.Usage != nil {
|
||||
debuglog.Debug(debuglog.Wire, "LLM->FABRIC stream usage input=%d output=%d total=%d\n", update.Usage.InputTokens, update.Usage.OutputTokens, update.Usage.TotalTokens)
|
||||
}
|
||||
}
|
||||
if opts.UpdateChan != nil {
|
||||
opts.UpdateChan <- update
|
||||
}
|
||||
|
|
@ -128,6 +145,9 @@ func (o *Chatter) Send(request *domain.ChatRequest, opts *domain.ChatOptions) (s
|
|||
if message, err = o.vendor.Send(context.Background(), session.GetVendorMessages(), opts); err != nil {
|
||||
return
|
||||
}
|
||||
if debuglog.GetLevel() >= debuglog.Wire {
|
||||
debuglog.Debug(debuglog.Wire, "LLM->FABRIC response content=%q\n", message)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.SuppressThink && !o.DryRun {
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "Fehler beim Schreiben der Antwort: %v",
|
||||
"server_invalid_request_format": "ungültiges Anfrageformat: %v",
|
||||
"sessions_creating_new": "Erstelle neue Sitzung: %s\n",
|
||||
"set_debug_level": "Debug-Level festlegen (0=aus, 1=grundlegend, 2=detailliert, 3=Trace)",
|
||||
"set_debug_level": "Debug-Level festlegen (0=aus, 1=grundlegend, 2=detailliert, 3=Trace, 4=wire)",
|
||||
"set_frequency_penalty": "Häufigkeitsstrafe festlegen",
|
||||
"set_location_web_search": "Standort für Web-Suchergebnisse festlegen (z.B., 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Präsenzstrafe festlegen",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "error writing response: %v",
|
||||
"server_invalid_request_format": "invalid request format: %v",
|
||||
"sessions_creating_new": "Creating new session: %s\n",
|
||||
"set_debug_level": "Set debug level (0=off, 1=basic, 2=detailed, 3=trace)",
|
||||
"set_debug_level": "Set debug level (0=off, 1=basic, 2=detailed, 3=trace, 4=wire)",
|
||||
"set_frequency_penalty": "Set frequency penalty",
|
||||
"set_location_web_search": "Set location for web search results (e.g., 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Set presence penalty",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "error al escribir la respuesta: %v",
|
||||
"server_invalid_request_format": "formato de solicitud no válido: %v",
|
||||
"sessions_creating_new": "Creando nueva sesión: %s\n",
|
||||
"set_debug_level": "Establecer nivel de depuración (0=apagado, 1=básico, 2=detallado, 3=rastreo)",
|
||||
"set_debug_level": "Establecer nivel de depuración (0=apagado, 1=básico, 2=detallado, 3=rastreo, 4=wire)",
|
||||
"set_frequency_penalty": "Establecer penalización de frecuencia",
|
||||
"set_location_web_search": "Establecer ubicación para resultados de búsqueda web (ej., 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Establecer penalización de presencia",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "خطا در نوشتن پاسخ: %v",
|
||||
"server_invalid_request_format": "فرمت درخواست نامعتبر: %v",
|
||||
"sessions_creating_new": "ایجاد نشست جدید: %s\n",
|
||||
"set_debug_level": "تنظیم سطح اشکالزدایی (0=خاموش، 1=پایه، 2=تفصیلی، 3=ردیابی)",
|
||||
"set_debug_level": "تنظیم سطح اشکالزدایی (0=خاموش، 1=پایه، 2=تفصیلی، 3=ردیابی، 4=wire)",
|
||||
"set_frequency_penalty": "تنظیم جریمه فرکانس",
|
||||
"set_location_web_search": "تنظیم مکان برای نتایج جستجوی وب (مثال: 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "تنظیم جریمه حضور",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "erreur d'écriture de la réponse : %v",
|
||||
"server_invalid_request_format": "format de requête invalide : %v",
|
||||
"sessions_creating_new": "Création d'une nouvelle session : %s\n",
|
||||
"set_debug_level": "Définir le niveau de débogage (0=désactivé, 1=basique, 2=détaillé, 3=trace)",
|
||||
"set_debug_level": "Définir le niveau de débogage (0=désactivé, 1=basique, 2=détaillé, 3=trace, 4=wire)",
|
||||
"set_frequency_penalty": "Définir la pénalité de fréquence",
|
||||
"set_location_web_search": "Définir l'emplacement pour les résultats de recherche web (ex. 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Définir la pénalité de présence",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "errore nella scrittura della risposta: %v",
|
||||
"server_invalid_request_format": "formato della richiesta non valido: %v",
|
||||
"sessions_creating_new": "Creazione nuova sessione: %s\n",
|
||||
"set_debug_level": "Imposta livello di debug (0=spento, 1=base, 2=dettagliato, 3=traccia)",
|
||||
"set_debug_level": "Imposta livello di debug (0=spento, 1=base, 2=dettagliato, 3=traccia, 4=wire)",
|
||||
"set_frequency_penalty": "Imposta penalità di frequenza",
|
||||
"set_location_web_search": "Imposta posizione per risultati ricerca web (es. 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Imposta penalità di presenza",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "レスポンスの書き込みエラー: %v",
|
||||
"server_invalid_request_format": "無効なリクエスト形式: %v",
|
||||
"sessions_creating_new": "新しいセッションを作成中: %s\n",
|
||||
"set_debug_level": "デバッグレベルを設定(0=オフ、1=基本、2=詳細、3=トレース)",
|
||||
"set_debug_level": "デバッグレベルを設定(0=オフ、1=基本、2=詳細、3=トレース、4=wire)",
|
||||
"set_frequency_penalty": "頻度ペナルティを設定",
|
||||
"set_location_web_search": "ウェブ検索結果の場所を設定(例:'America/Los_Angeles')",
|
||||
"set_presence_penalty": "プレゼンスペナルティを設定",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "erro ao escrever resposta: %v",
|
||||
"server_invalid_request_format": "formato de solicitação inválido: %v",
|
||||
"sessions_creating_new": "Criando nova sessão: %s\n",
|
||||
"set_debug_level": "Definir nível de debug (0=desligado, 1=básico, 2=detalhado, 3=rastreamento)",
|
||||
"set_debug_level": "Definir nível de debug (0=desligado, 1=básico, 2=detalhado, 3=rastreamento, 4=wire)",
|
||||
"set_frequency_penalty": "Definir penalidade de frequência",
|
||||
"set_location_web_search": "Definir localização para resultados de busca web (ex. 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Definir penalidade de presença",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "erro ao escrever resposta: %v",
|
||||
"server_invalid_request_format": "formato de pedido inválido: %v",
|
||||
"sessions_creating_new": "A criar nova sessão: %s\n",
|
||||
"set_debug_level": "Definir nível de debug (0=desligado, 1=básico, 2=detalhado, 3=rastreio)",
|
||||
"set_debug_level": "Definir nível de debug (0=desligado, 1=básico, 2=detalhado, 3=rastreio, 4=wire)",
|
||||
"set_frequency_penalty": "Definir penalidade de frequência",
|
||||
"set_location_web_search": "Definir localização para resultados de pesquisa web (ex. 'America/Los_Angeles')",
|
||||
"set_presence_penalty": "Definir penalidade de presença",
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@
|
|||
"server_error_writing_response": "写入响应错误: %v",
|
||||
"server_invalid_request_format": "无效的请求格式: %v",
|
||||
"sessions_creating_new": "正在创建新会话:%s\n",
|
||||
"set_debug_level": "设置调试级别(0=关闭,1=基本,2=详细,3=跟踪)",
|
||||
"set_debug_level": "设置调试级别(0=关闭,1=基本,2=详细,3=跟踪,4=wire)",
|
||||
"set_frequency_penalty": "设置频率惩罚",
|
||||
"set_location_web_search": "设置网络搜索结果的位置(例如,'America/Los_Angeles')",
|
||||
"set_presence_penalty": "设置存在惩罚",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ const (
|
|||
Detailed
|
||||
// Trace is the most verbose level.
|
||||
Trace
|
||||
// Wire logs full request/response exchanges with model backends.
|
||||
Wire
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -43,8 +45,10 @@ func LevelFromInt(i int) Level {
|
|||
return Basic
|
||||
case i == 2:
|
||||
return Detailed
|
||||
case i >= 3:
|
||||
case i == 3:
|
||||
return Trace
|
||||
case i >= 4:
|
||||
return Wire
|
||||
default:
|
||||
return Off
|
||||
}
|
||||
|
|
@ -76,3 +80,10 @@ func SetOutput(w io.Writer) {
|
|||
output = w
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
// GetLevel returns the current global debug level.
|
||||
func GetLevel() Level {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
return level
|
||||
}
|
||||
|
|
|
|||
24
internal/log/log_test.go
Normal file
24
internal/log/log_test.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package log
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLevelFromInt(t *testing.T) {
|
||||
tests := []struct {
|
||||
in int
|
||||
want Level
|
||||
}{
|
||||
{in: -1, want: Off},
|
||||
{in: 0, want: Off},
|
||||
{in: 1, want: Basic},
|
||||
{in: 2, want: Detailed},
|
||||
{in: 3, want: Trace},
|
||||
{in: 4, want: Wire},
|
||||
{in: 9, want: Wire},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
if got := LevelFromInt(tc.in); got != tc.want {
|
||||
t.Fatalf("LevelFromInt(%d) = %v, want %v", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue