92 lines
4.3 KiB
Go
92 lines
4.3 KiB
Go
// This file makes runSession satisfy cli.Host: the accessor and mutator methods
|
|
// let the /status command (and future /goal, /btw) read the session's live
|
|
// collaborators and mutable state through the cli.Host contract rather than the
|
|
// concrete aggregate — the same seam the REPL's replDeps implements. The
|
|
// compile-time assertion below fails the build if runSession drifts out of
|
|
// conformance.
|
|
package tui
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/smallnest/pigo/internal/agentcore"
|
|
"github.com/smallnest/pigo/internal/agenttool"
|
|
"github.com/smallnest/pigo/internal/cli"
|
|
"github.com/smallnest/pigo/internal/cli/run"
|
|
"github.com/smallnest/pigo/internal/compaction"
|
|
"github.com/smallnest/pigo/internal/hooks"
|
|
"github.com/smallnest/pigo/internal/plugin"
|
|
"github.com/smallnest/pigo/internal/provider"
|
|
"github.com/smallnest/pigo/internal/runtime"
|
|
"github.com/smallnest/pigo/internal/session"
|
|
"github.com/smallnest/pigo/internal/trust"
|
|
)
|
|
|
|
var _ cli.Host = (*runSession)(nil)
|
|
|
|
func (s *runSession) Store() *session.Store { return s.store }
|
|
func (s *runSession) Header() session.SessionHeader { return s.header }
|
|
func (s *runSession) AgentCtx() *agentcore.AgentContext { return s.agentCtx }
|
|
func (s *runSession) Live() *cli.LiveConfig { return s.live }
|
|
func (s *runSession) Registry() *agenttool.ToolRegistry { return s.reg }
|
|
func (s *runSession) Reminders() *runtime.ReminderRegistry { return s.reminders }
|
|
func (s *runSession) Slash() *runtime.SlashRegistry { return s.slash }
|
|
func (s *runSession) Creds() *provider.CredentialStore { return s.creds }
|
|
func (s *runSession) Notifier() *plugin.EventNotifier { return nil }
|
|
func (s *runSession) NotifierHandle() func(agentcore.AgentEvent) { return s.onEvent }
|
|
func (s *runSession) Trust() *trust.Manager { return s.trust }
|
|
func (s *runSession) Goal() *agenttool.GoalState { return nil }
|
|
func (s *runSession) Telemetry() *cli.TelemetryHolder { return s.telemetry }
|
|
func (s *runSession) Dispatcher() *hooks.Dispatcher { return s.dispatcher }
|
|
func (s *runSession) HookDeps() run.HookDeps { return s.hookDeps }
|
|
func (s *runSession) Cwd() string { return s.cwd }
|
|
func (s *runSession) Input() *bufio.Reader { return nil }
|
|
func (s *runSession) ConfirmMu() *sync.Mutex { return nil }
|
|
|
|
func (s *runSession) CurLeaf() string { return s.curLeaf }
|
|
func (s *runSession) SetCurLeaf(id string) { s.curLeaf = id }
|
|
func (s *runSession) Persisted() int { return s.persisted }
|
|
func (s *runSession) SetPersisted(n int) { s.persisted = n }
|
|
|
|
func (s *runSession) LastBtw() *agentcore.AgentContext { return s.lastBtw }
|
|
func (s *runSession) SetLastBtw(ctx *agentcore.AgentContext) { s.lastBtw = ctx }
|
|
func (s *runSession) LastBtwBase() int { return s.lastBtwBase }
|
|
func (s *runSession) SetLastBtwBase(n int) { s.lastBtwBase = n }
|
|
|
|
// renderSession writes the /session summary (US-009, #125) to out — the same
|
|
// format the REPL's runSession prints: session id, message count, estimated
|
|
// token usage, model/provider, creation time, and compaction-checkpoint count.
|
|
// It lives on runSession so the TUI's /session intercept and the REPL share one
|
|
// rendering; counts derive from the in-memory context (the source of truth for
|
|
// the live turn), so unsaved messages are counted too.
|
|
func (s *runSession) renderSession(out io.Writer) {
|
|
msgs := s.agentCtx.Messages
|
|
tokens := compaction.EstimateContextTokens(msgs).Tokens
|
|
compactions := 0
|
|
for _, m := range msgs {
|
|
if _, ok := m.(agentcore.CompactionMessage); ok {
|
|
compactions++
|
|
}
|
|
}
|
|
fmt.Fprintf(out, "session: %s\n", s.header.ID)
|
|
fmt.Fprintf(out, "messages: %d\n", len(msgs))
|
|
fmt.Fprintf(out, "tokens (est): %d\n", tokens)
|
|
model := s.live.Model
|
|
providerName := s.live.ProviderName
|
|
if model == "" {
|
|
model = s.header.Model
|
|
}
|
|
if providerName == "" {
|
|
providerName = s.header.Provider
|
|
}
|
|
fmt.Fprintf(out, "model: %s (provider: %s)\n", model, providerName)
|
|
if !s.header.CreatedAt.IsZero() {
|
|
fmt.Fprintf(out, "created: %s\n", s.header.CreatedAt.Format(time.RFC3339))
|
|
}
|
|
fmt.Fprintf(out, "compactions: %d\n", compactions)
|
|
}
|