feat: crush-inspired TUI improvements, activity bar polish, startup fresh session
TUI improvements: - semantic icon constants (✓ ◆ ▣ ✕ ⌘ ◌ ◔ ◉) - pill-style metadata bar with model/provider/session/context - fuzzy command palette with deterministic subsequence scoring - input history navigation (ctrl+p / ctrl+n) - structured tool log cards (▣ tool_name + args preview) - no-background activity indicator and meta bar for cleaner rendering Startup behavior: - default startup creates a fresh session - explicit --resume <id> restores saved context - added main_test.go for initializeSession coverage
This commit is contained in:
+101
@@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"agentu/internal/agent"
|
||||
"agentu/internal/session"
|
||||
"agentu/pkg/config"
|
||||
"agentu/pkg/llm"
|
||||
)
|
||||
|
||||
type startupProvider struct{}
|
||||
|
||||
func (p *startupProvider) ChatStream(ctx context.Context, req llm.ChatRequest, emit func(llm.StreamEvent) error) error {
|
||||
return emit(llm.StreamEvent{Content: "ok"})
|
||||
}
|
||||
|
||||
func startupTestManager(t *testing.T) (*session.Manager, *agent.Agent) {
|
||||
t.Helper()
|
||||
cfg := &config.Config{
|
||||
Providers: map[string]config.ProviderConfig{
|
||||
"one": {
|
||||
Name: "one",
|
||||
BaseURL: "https://one.example.com",
|
||||
APIKey: "sk-test",
|
||||
Model: "model-a",
|
||||
Models: []string{"model-a"},
|
||||
Thinking: "none",
|
||||
ThinkingParam: "thinking",
|
||||
},
|
||||
},
|
||||
}
|
||||
assistant := agent.New(agent.Options{
|
||||
Provider: &startupProvider{},
|
||||
ProviderName: "one",
|
||||
Model: "model-a",
|
||||
})
|
||||
store, err := session.NewStore(filepath.Join(t.TempDir(), "sessions"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
manager, err := session.NewManager(cfg, assistant, nil, store)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return manager, assistant
|
||||
}
|
||||
|
||||
func TestInitializeSessionStartsNewByDefault(t *testing.T) {
|
||||
manager, assistant := startupTestManager(t)
|
||||
if _, err := manager.NewSession(); err != nil {
|
||||
t.Fatalf("new session: %v", err)
|
||||
}
|
||||
savedID := manager.CurrentSessionID()
|
||||
assistant.SetMessages([]llm.Message{{Role: llm.RoleUser, Content: "old context"}})
|
||||
if err := manager.Save(); err != nil {
|
||||
t.Fatalf("save: %v", err)
|
||||
}
|
||||
|
||||
if err := initializeSession(manager, ""); err != nil {
|
||||
t.Fatalf("initialize: %v", err)
|
||||
}
|
||||
if manager.CurrentSessionID() == savedID {
|
||||
t.Fatalf("default startup resumed latest session %s", savedID)
|
||||
}
|
||||
for _, msg := range assistant.Messages() {
|
||||
if msg.Content == "old context" {
|
||||
t.Fatal("default startup carried old context into new session")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitializeSessionResumesExplicitID(t *testing.T) {
|
||||
manager, assistant := startupTestManager(t)
|
||||
if _, err := manager.NewSession(); err != nil {
|
||||
t.Fatalf("new session: %v", err)
|
||||
}
|
||||
savedID := manager.CurrentSessionID()
|
||||
assistant.SetMessages([]llm.Message{{Role: llm.RoleUser, Content: "old context"}})
|
||||
if err := manager.Save(); err != nil {
|
||||
t.Fatalf("save: %v", err)
|
||||
}
|
||||
|
||||
if err := initializeSession(manager, savedID); err != nil {
|
||||
t.Fatalf("initialize: %v", err)
|
||||
}
|
||||
if manager.CurrentSessionID() != savedID {
|
||||
t.Fatalf("expected resumed session %s, got %s", savedID, manager.CurrentSessionID())
|
||||
}
|
||||
found := false
|
||||
for _, msg := range assistant.Messages() {
|
||||
if msg.Content == "old context" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatal("explicit resume did not restore saved context")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user