diff --git a/pkg/store/batch.go b/pkg/store/batch.go index 4ebbcc4..6824eb6 100644 --- a/pkg/store/batch.go +++ b/pkg/store/batch.go @@ -373,13 +373,24 @@ func (s *BatchStore) executeJob(ctx context.Context, job *batchJob) (string, err assistantStarted = true } case "user", "call", "tool": - assistantStarted = false + if assistantStarted { + job.appendLog([]byte("\n")) + assistantStarted = false + } case "error": errBuf.WriteString(ev.Content) } job.appendLog(FormatEvent(ev)) }) + // Ensure log ends with newline (assistant content has no trailing \n). + job.mu.Lock() + if len(job.log) > 0 && job.log[len(job.log)-1] != '\n' { + job.log = append(job.log, '\n') + job.logVers++ + } + job.mu.Unlock() + usage := core.Usage() ctxsz := core.CtxSz() @@ -620,9 +631,6 @@ func FormatEvent(ev agent.Event) []byte { return []byte(ev.Content) case "call": args := squashWhitespace(ev.Content) - if len(args) > 500 { - args = args[:500] + "..." - } return []byte("-> " + ev.Name + "(" + args + ")\n") case "tool": return []byte(strings.TrimRight(ev.Content, "\n") + "\n") diff --git a/pkg/store/session.go b/pkg/store/session.go index 8cd7d31..d92516d 100644 --- a/pkg/store/session.go +++ b/pkg/store/session.go @@ -52,6 +52,16 @@ func (sess *Session) AppendLog(data []byte) { sess.mu.Unlock() } +// EnsureTrailingNewline appends a newline if the log doesn't already end with one. +func (sess *Session) EnsureTrailingNewline() { + sess.mu.Lock() + if len(sess.log) > 0 && sess.log[len(sess.log)-1] != '\n' { + sess.log = append(sess.log, '\n') + sess.logVers++ + } + sess.mu.Unlock() +} + // LogInfo returns the current log length and version atomically. func (sess *Session) LogInfo() (length int, vers uint32) { sess.mu.RLock() diff --git a/pkg/store/sessionfile.go b/pkg/store/sessionfile.go index 731a50b..c246807 100644 --- a/pkg/store/sessionfile.go +++ b/pkg/store/sessionfile.go @@ -159,7 +159,9 @@ func (s *SessionFileStore) writeFile(name string, data []byte) error { case "chat": return s.saveTranscript([]byte(input)) case "prompt": - s.sess.Core.Submit(s.sess.Ctx, input, s.makePublish()) + pub := s.makePublish() + s.sess.Core.Submit(s.sess.Ctx, input, pub) + s.sess.EnsureTrailingNewline() case "fifo.in": s.sess.Core.Queue(input) case "ctl": @@ -352,21 +354,29 @@ func (s *SessionFileStore) currentWaitValue(name string) string { func (s *SessionFileStore) makePublish() func(agent.Event) { assistantStarted := false return func(ev agent.Event) { - switch ev.Role { - case "user", "call", "tool": - assistantStarted = false - case "assistant": - if !assistantStarted { - s.sess.AppendLog([]byte("assistant: ")) - assistantStarted = true - } - } - s.sess.AppendLog(FormatEvent(ev)) if ev.Role == "user" { + if assistantStarted { + s.sess.AppendLog([]byte("\n")) + assistantStarted = false + } s.sess.mu.Lock() s.sess.ChatOffset = len(s.sess.log) s.sess.mu.Unlock() + } else { + switch ev.Role { + case "call", "tool": + if assistantStarted { + s.sess.AppendLog([]byte("\n")) + assistantStarted = false + } + case "assistant": + if !assistantStarted { + s.sess.AppendLog([]byte("assistant: ")) + assistantStarted = true + } + } } + s.sess.AppendLog(FormatEvent(ev)) } }