switched kiro to use tmux instead of pty, probably still buggy
This commit is contained in:
parent
d33bede0f1
commit
9be10a14de
|
|
@ -3,7 +3,7 @@ package backends
|
|||
|
||||
import (
|
||||
"acme-q/internal/backend"
|
||||
"acme-q/internal/backend/pty"
|
||||
"acme-q/internal/backend/tmux"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
// NewKiroCLI creates a kiro-cli backend
|
||||
func NewKiroCLI() backend.Backend {
|
||||
return pty.New(pty.Config{
|
||||
return tmux.New(tmux.Config{
|
||||
Name: "kiro-cli",
|
||||
Command: []string{"kiro-cli", "chat", "--trust-all-tools"},
|
||||
Environment: map[string]string{
|
||||
|
|
@ -24,7 +24,7 @@ func NewKiroCLI() backend.Backend {
|
|||
"NO_COLOR": "1",
|
||||
"COLUMNS": "999",
|
||||
},
|
||||
PTYSize: pty.PTYSize{
|
||||
TmuxSize: tmux.TmuxSize{
|
||||
Rows: 40,
|
||||
Cols: 120,
|
||||
},
|
||||
|
|
@ -89,24 +89,88 @@ func (c *kiroCleaner) cleanResponse(raw string) string {
|
|||
|
||||
lines := strings.Split(clean, "\n")
|
||||
var result []string
|
||||
foundUserPrompt := false
|
||||
inResponse := false
|
||||
|
||||
for _, line := range lines {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
|
||||
// Check for response marker "> " (not in prompt brackets)
|
||||
if idx := strings.Index(line, "> "); idx >= 0 {
|
||||
if !strings.Contains(line, "[") || !strings.Contains(line, "]") {
|
||||
inResponse = true
|
||||
text := strings.TrimSpace(line[idx+2:])
|
||||
if text != "" {
|
||||
result = append(result, text)
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Look for user prompt (starts with "!>")
|
||||
if !foundUserPrompt && strings.HasPrefix(trimmed, "!>") {
|
||||
foundUserPrompt = true
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip noise
|
||||
// Skip echoed user input (the line right after !> that doesn't have markers)
|
||||
if foundUserPrompt && !inResponse && trimmed != "" &&
|
||||
!strings.Contains(trimmed, "Thinking...") &&
|
||||
!strings.Contains(trimmed, "I will run") &&
|
||||
!strings.Contains(trimmed, "using tool:") &&
|
||||
!strings.Contains(trimmed, "Purpose:") &&
|
||||
!strings.Contains(trimmed, ">") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Stop at next prompt (starts with "!>") - but only after we've started collecting
|
||||
if foundUserPrompt && inResponse && strings.HasPrefix(trimmed, "!>") {
|
||||
break
|
||||
}
|
||||
|
||||
// After user prompt, start collecting non-noise content
|
||||
if foundUserPrompt && trimmed != "" {
|
||||
// Check if line contains actual content (even if it has noise)
|
||||
// Important markers: "I will run", "using tool:", "Purpose:", ">", or actual content after spinners
|
||||
hasContent := false
|
||||
text := trimmed
|
||||
|
||||
// If line contains "Thinking..." followed by content, extract the content
|
||||
if strings.Contains(line, "Thinking...") {
|
||||
idx := strings.Index(line, "Thinking...")
|
||||
afterThinking := strings.TrimSpace(line[idx+11:]) // "Thinking..." is 11 chars
|
||||
if afterThinking != "" {
|
||||
text = afterThinking
|
||||
hasContent = true
|
||||
}
|
||||
}
|
||||
|
||||
// Check for important markers
|
||||
if !hasContent && (strings.Contains(trimmed, "I will run") ||
|
||||
strings.Contains(trimmed, "using tool:") ||
|
||||
strings.Contains(trimmed, "Purpose:") ||
|
||||
strings.Contains(trimmed, ">")) {
|
||||
hasContent = true
|
||||
}
|
||||
|
||||
// If no content markers and it's noise, skip
|
||||
if !hasContent && c.isNoise(line) {
|
||||
continue
|
||||
}
|
||||
|
||||
// If we got here, it's not pure noise
|
||||
if !hasContent {
|
||||
text = trimmed
|
||||
}
|
||||
|
||||
// Start collecting
|
||||
if !inResponse {
|
||||
inResponse = true
|
||||
}
|
||||
|
||||
// If line has ">", strip it (for assistant response lines)
|
||||
if strings.Contains(text, ">") {
|
||||
idx := strings.Index(text, ">")
|
||||
if idx == 0 || (idx > 0 && text[idx-1] != '!') {
|
||||
text = strings.TrimSpace(text[idx+1:])
|
||||
}
|
||||
}
|
||||
|
||||
if text != "" {
|
||||
result = append(result, text)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Before user prompt, skip noise and look for hooks
|
||||
if c.isNoise(line) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -116,10 +180,6 @@ func (c *kiroCleaner) cleanResponse(raw string) string {
|
|||
result = append(result, trimmed)
|
||||
continue
|
||||
}
|
||||
|
||||
if inResponse && trimmed != "" {
|
||||
result = append(result, line)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(result, "\n")
|
||||
|
|
@ -169,6 +229,7 @@ func (c *kiroCleaner) isNoise(line string) bool {
|
|||
// Check for noise patterns
|
||||
noisePatterns := []string{
|
||||
"Thinking...",
|
||||
"▸ Credits:",
|
||||
"▸ Time:",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package p9
|
|||
|
||||
import (
|
||||
"acme-q/internal/backend"
|
||||
"acme-q/internal/backend/pty"
|
||||
"acme-q/internal/backend/tmux"
|
||||
"acme-q/internal/backends"
|
||||
"acme-q/internal/session"
|
||||
"context"
|
||||
|
|
@ -374,9 +374,9 @@ func (s *Server) write(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
if err != nil {
|
||||
return errFcall(fc, "invalid winid")
|
||||
}
|
||||
// Set WinID if it's a PTY session
|
||||
if ptySess, ok := sess.(*pty.Session); ok {
|
||||
ptySess.SetWinID(id)
|
||||
// Set WinID if it's a tmux session
|
||||
if tmuxSess, ok := sess.(*tmux.Session); ok {
|
||||
tmuxSess.SetWinID(id)
|
||||
}
|
||||
return &plan9.Fcall{Type: plan9.Rwrite, Tag: fc.Tag, Count: uint32(len(fc.Data))}
|
||||
}
|
||||
|
|
@ -498,11 +498,11 @@ func (s *Server) getSessionFile(sess backend.Session, idx int) string {
|
|||
|
||||
switch idx {
|
||||
case fileOut:
|
||||
// Output from last command - only available for PTY sessions
|
||||
if ptySess, ok := sess.(*pty.Session); ok {
|
||||
// Output from last command - only available for tmux sessions
|
||||
if tmuxSess, ok := sess.(*tmux.Session); ok {
|
||||
// We don't have a direct Output() method anymore
|
||||
// This would need to be stored separately if needed
|
||||
_ = ptySess
|
||||
_ = tmuxSess
|
||||
}
|
||||
return ""
|
||||
case fileErr:
|
||||
|
|
|
|||
8
main.go
8
main.go
|
|
@ -3,7 +3,7 @@ package main
|
|||
|
||||
import (
|
||||
"acme-q/internal/backend"
|
||||
"acme-q/internal/backend/pty"
|
||||
"acme-q/internal/backend/tmux"
|
||||
"acme-q/internal/backends"
|
||||
"acme-q/internal/p9"
|
||||
"acme-q/internal/session"
|
||||
|
|
@ -270,9 +270,9 @@ func openChatWindow(sess backend.Session) (*acme.Win, error) {
|
|||
w.Fprintf("body", "# Session %s\n# cwd: %s\n\nUSER:\n", sess.ID(), meta.Cwd)
|
||||
w.Ctl("clean")
|
||||
|
||||
// Set window ID on session (if it's a PTY session)
|
||||
if ptySess, ok := sess.(*pty.Session); ok {
|
||||
ptySess.SetWinID(w.ID())
|
||||
// Set window ID on session (if it's a tmux session)
|
||||
if tmuxSess, ok := sess.(*tmux.Session); ok {
|
||||
tmuxSess.SetWinID(w.ID())
|
||||
}
|
||||
|
||||
go handleChatWindow(w, sess)
|
||||
|
|
|
|||
Reference in New Issue