feat(llm): add LLM call recording with admin panel integration

- llm.Adapter: SetCallLogger hook for recording every API call
- llm.CallLogger: ring-buffer with Recent+Stats for admin API
- main.go: wire DeepSeek adapter to CallLogger
- Fix: single CallLogger instance for both recording and display
- Metrics: model name, duration, success/fail, tokens
- All 16 packages pass
This commit is contained in:
Aska committed 2026-08-12 19:10:51 +08:00
1 parent 5b2bcc9441
commit 6a4887e52a
6 files changed
+131 -67

No files matched your search

+9 -4
View File
@@ -149,6 +149,11 @@ func main() {
llmCfg.Model = cfg.LLMModel
llmCfg.FallbackModel = cfg.LLMFallbackModel
llmSelector := llm.NewModelSelector(llmCfg)
// Wire LLM call logging to admin panel
llmCallLogger := llm.NewCallLogger(200)
llmSelector.DefaultAdapter().SetCallLogger(func(c llm.CallRecord) {
llmCallLogger.Record(c)
})
log.Printf("[llm] adapter ready (model=%s)", cfg.LLMModel)
// === 9. AI-Core: Context Store ===
@@ -211,7 +216,7 @@ func main() {
authMgr := api.NewRealAuthManager(cfg.JWTSecret, cfg.JWTExpiryHours, userStore)
// Build dependencies for gateway handlers
llmLogger := llmlog.NewLogger(200)
llmLogger := &llmLoggerAdapter{CallLogger: llmCallLogger}
traceLogger := tracepkg.NewLogger(500)
perfMon := perfpkg.NewMonitor(120, 10*time.Second)
perfMon.Start()
@@ -219,7 +224,7 @@ func main() {
gwDeps := api.Dependencies{
AuthMgr: authMgr,
Orchestrator: orch,
LLMLogger: &llmLoggerAdapter{Logger: llmLogger},
LLMLogger: llmLogger,
TraceLog: &traceAdapter{Logger: traceLogger},
PerfMon: &perfAdapter{Monitor: perfMon},
ModelConfig: api.NewModelConfigStore(),
@@ -269,9 +274,9 @@ func main() {
_ = orch
}
// llmLoggerAdapter adapts llm.Logger to api.LLMCallLogger interface.
type llmLoggerAdapter struct{ *llmlog.Logger }
type llmLoggerAdapter struct{ *llmlog.CallLogger }
func (a *llmLoggerAdapter) Recent(n int) []map[string]any { return a.Logger.RecentMaps(n) }
func (a *llmLoggerAdapter) Recent(n int) []map[string]any { return a.CallLogger.RecentMaps(n) }
func pluginNamesToMap(names []string) []map[string]string {
result := make([]map[string]string, len(names))