fix: ensure chat log lines are newline-terminated
assistant events are streamed without trailing newlines, causing line-buffered 9P reads to lag one turn behind. Close the assistant block with \n on role transitions and after Submit returns. Set ChatOffset at EOF before the user event so offset spans the full exchange. Remove 500-char truncation of tool call args in FormatEvent.
This commit is contained in:
parent
f220d0ee96
commit
81fedb862c
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in New Issue