返回 DeepSeek-Reasonix
baseline_error.go
根目录 / internal / transcript / baseline_error.go
1 package transcript
2
3 import (
4 "crypto/sha256"
5 "fmt"
6 "log/slog"
7 )
8
9 // BaselineError retains the original error for callers and exposes only
10 // bounded, content-free diagnostics to structured loggers. Record identities
11 // can originate in imported data, so even those are logged as fingerprints.
12 type BaselineError struct {
13 cause error
14 code string
15 recordCount int
16 index int
17 previousIndex int
18 record Message
19 }
20
21 func (e *BaselineError) Error() string { return e.cause.Error() }
22 func (e *BaselineError) Unwrap() error { return e.cause }
23
24 // Code returns the bounded failure classification used by local diagnostics
25 // and crash aggregation. It never contains transcript or record data.
26 func (e *BaselineError) Code() string { return e.code }
27
28 func (e *BaselineError) LogValue() slog.Value {
29 attrs := []slog.Attr{slog.String("code", e.code), slog.Int("record_count", e.recordCount)}
30 if e.index >= 0 {
31 attrs = append(attrs, slog.Int("record_index", e.index), slog.String("role", diagnosticRole(e.record.Role)),
32 slog.String("record_key", diagnosticKey(e.record.RecordID)),
33 slog.String("message_key", diagnosticKey(e.record.MessageID)),
34 slog.String("tool_call_key", diagnosticKey(e.record.ToolCallID)))
35 }
36 if e.previousIndex >= 0 {
37 attrs = append(attrs, slog.Int("previous_record_index", e.previousIndex))
38 }
39 return slog.GroupValue(attrs...)
40 }
41
42 func newBaselineError(cause error, code string, count, index, previous int, record Message) error {
43 // Do not retain chat bodies or nested metadata through a returned error.
44 return &BaselineError{cause: cause, code: code, recordCount: count, index: index, previousIndex: previous,
45 record: Message{Role: record.Role, RecordID: record.RecordID, MessageID: record.MessageID, ToolCallID: record.ToolCallID}}
46 }
47
48 func diagnosticKey(identity string) string {
49 if identity == "" {
50 return ""
51 }
52 return fmt.Sprintf("%x", sha256.Sum256([]byte(identity)))
53 }
54
55 func diagnosticRole(role string) string {
56 switch role {
57 case "system", "user", "assistant", "tool", "notice":
58 return role
59 default:
60 return "other"
61 }
62 }
63
63 lines GO