diff --git a/README.md b/README.md index 1956061..77c571f 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,9 @@ You can use AgentAPI: Run an HTTP server that lets you control an agent. If you'd like to start an agent with additional arguments, pass the full agent command after the `--` flag. +> [!NOTE] +> When using Codex, always specify the agent type explicitly (`agentapi server --type=codex -- codex`), or message formatting may break. + ```bash agentapi server -- claude --allowedTools "Bash(git*) Edit Replace" ``` diff --git a/cmd/server/server.go b/cmd/server/server.go index 84ad594..4fc3943 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -78,6 +78,9 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er } if termHeight < 10 { return xerrors.Errorf("term height must be at least 10") + } else if agentType == AgentTypeCodex && termHeight > 930 { + logger.Warn(fmt.Sprintf("Term height is set to %d which may cause issues with Codex. Setting it to 930 instead.", termHeight)) + termHeight = 930 // codex has a bug where the TUI distorts the screen if the height is too large, see: https://github.com/openai/codex/issues/1608 } var process *termexec.Process diff --git a/lib/msgfmt/message_box.go b/lib/msgfmt/message_box.go index 2f95e06..d568280 100644 --- a/lib/msgfmt/message_box.go +++ b/lib/msgfmt/message_box.go @@ -51,3 +51,41 @@ func removeMessageBox(msg string) string { return strings.Join(lines, "\n") } + +func removeCodexMessageBox(msg string) string { + lines := strings.Split(msg, "\n") + messageBoxEndIdx := -1 + messageBoxStartIdx := -1 + + for i := len(lines) - 1; i >= 0; i-- { + if messageBoxEndIdx == -1 { + if strings.Contains(lines[i], "╰────────") && strings.Contains(lines[i], "───────╯") { + messageBoxEndIdx = i + } + } else { + // We reached the start of the message box (we don't want to show this line), also exit the loop + if strings.Contains(lines[i], "╭") && strings.Contains(lines[i], "───────╮") { + // We only want this to be i in case the top of the box is visible + messageBoxStartIdx = i + break + } + + // We are in between the start and end of the message box, so remove the │ from the start and end of the line, let the trimEmptyLines handle the rest + if strings.HasPrefix(lines[i], "│") { + lines[i] = strings.TrimPrefix(lines[i], "│") + } + if strings.HasSuffix(lines[i], "│") { + lines[i] = strings.TrimSuffix(lines[i], "│") + lines[i] = strings.TrimRight(lines[i], " \t") + } + } + } + + // If we didn't find messageBoxEndIdx, set it to the end of the lines + if messageBoxEndIdx == -1 { + messageBoxEndIdx = len(lines) + } + + return strings.Join(lines[messageBoxStartIdx+1:messageBoxEndIdx], "\n") + +} diff --git a/lib/msgfmt/msgfmt.go b/lib/msgfmt/msgfmt.go index cca75d1..3560aa7 100644 --- a/lib/msgfmt/msgfmt.go +++ b/lib/msgfmt/msgfmt.go @@ -216,6 +216,14 @@ func formatGenericMessage(message string, userInput string) string { return message } +func formatCodexMessage(message string, userInput string) string { + message = RemoveUserInput(message, userInput) + message = removeMessageBox(message) + message = removeCodexMessageBox(message) + message = trimEmptyLines(message) + return message +} + func FormatAgentMessage(agentType AgentType, message string, userInput string) string { switch agentType { case AgentTypeClaude: @@ -225,7 +233,7 @@ func FormatAgentMessage(agentType AgentType, message string, userInput string) s case AgentTypeAider: return formatGenericMessage(message, userInput) case AgentTypeCodex: - return formatGenericMessage(message, userInput) + return formatCodexMessage(message, userInput) case AgentTypeGemini: return formatGenericMessage(message, userInput) case AgentTypeCustom: diff --git a/lib/msgfmt/testdata/format/codex/confirmation_box/expected.txt b/lib/msgfmt/testdata/format/codex/confirmation_box/expected.txt index 14faa87..9363e91 100644 --- a/lib/msgfmt/testdata/format/codex/confirmation_box/expected.txt +++ b/lib/msgfmt/testdata/format/codex/confirmation_box/expected.txt @@ -1,19 +1,10 @@ - thinking for 9s +Shell Command +~/Documents/work/agentapi$ git rev-parse --show-toplevel - command +Allow command? - $ git rev-parse --show-toplevel - -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│Shell Command │ -│ │ -│$ git rev-parse --show-toplevel │ -│ │ -│Allow command? │ -│ │ -│ ❯ Yes (y) │ -│ Yes, always approve this exact command for this session (a) │ -│ Edit or give feedback (e) │ -│ No, and keep going (n) │ -│ No, and stop for now (esc) │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file + ▶ Yes (y) + Yes, always approve this exact command for this session (a) + Edit or give feedback (e) + No, and keep going (n) + No, and stop for now (esc) \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/confirmation_box/msg.txt b/lib/msgfmt/testdata/format/codex/confirmation_box/msg.txt index ff26827..eccfd92 100644 --- a/lib/msgfmt/testdata/format/codex/confirmation_box/msg.txt +++ b/lib/msgfmt/testdata/format/codex/confirmation_box/msg.txt @@ -1,22 +1,28 @@ -user -what repository are you in? - - thinking for 9s - - command - - $ git rev-parse --show-toplevel - -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│Shell Command │ -│ │ -│$ git rev-parse --show-toplevel │ -│ │ -│Allow command? │ -│ │ -│ ❯ Yes (y) │ -│ Yes, always approve this exact command for this session (a) │ -│ Edit or give feedback (e) │ -│ No, and keep going (n) │ -│ No, and stop for now (esc) │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file +╭Messages (tab to focus)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│OpenAI Codex v0.10.0 (research preview) │ +│ │ +│codex session 790ba389-ab4d-47be-bb16-9cc7f36bcf2b │ +│workdir: /Users/jkmr/Documents/work/agentapi │ +│model: codex-mini-latest │ +│provider: openai │ +│approval: untrusted │ +│sandbox: read-only │ +│reasoning effort: medium │ +│reasoning summaries: auto │ +│ │ +│user │ +│what repository are you in? │ +│ │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭Review───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│Shell Command │ +│~/Documents/work/agentapi$ git rev-parse --show-toplevel │ +│ │ +│Allow command? │ +│ │ +│ ▶ Yes (y) │ +│ Yes, always approve this exact command for this session (a) │ +│ Edit or give feedback (e) │ +│ No, and keep going (n) │ +│ No, and stop for now (esc) │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/lib/msgfmt/testdata/format/codex/first_message/expected.txt b/lib/msgfmt/testdata/format/codex/first_message/expected.txt index f5e1bb1..660ecde 100644 --- a/lib/msgfmt/testdata/format/codex/first_message/expected.txt +++ b/lib/msgfmt/testdata/format/codex/first_message/expected.txt @@ -1,12 +1,10 @@ -╭──────────────────────────────────────────────────────────────╮ -│ ● OpenAI Codex (research preview) v0.1.2504161551 │ -╰──────────────────────────────────────────────────────────────╯ -╭──────────────────────────────────────────────────────────────╮ -│ localhost session: c4bf4c89c3fb483c935bdff223394646 │ -│ ↳ workdir: ~/dev/agentapi │ -│ ↳ model: o4-mini │ -│ ↳ approval: suggest │ -╰──────────────────────────────────────────────────────────────╯ +OpenAI Codex v0.10.0 (research preview) - system - Warning: model "o4-mini" is not in the list of available models returned by OpenAI. \ No newline at end of file +codex session 56576d81-529d-42f3-843b-78d870054a75 +workdir: /Users/jkmr/Documents/work/agentapi +model: codex-mini-latest +provider: openai +approval: untrusted +sandbox: read-only +reasoning effort: medium +reasoning summaries: auto \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/first_message/msg.txt b/lib/msgfmt/testdata/format/codex/first_message/msg.txt index 64dabcc..a779309 100644 --- a/lib/msgfmt/testdata/format/codex/first_message/msg.txt +++ b/lib/msgfmt/testdata/format/codex/first_message/msg.txt @@ -1,16 +1,29 @@ -╭──────────────────────────────────────────────────────────────╮ -│ ● OpenAI Codex (research preview) v0.1.2504161551 │ -╰──────────────────────────────────────────────────────────────╯ -╭──────────────────────────────────────────────────────────────╮ -│ localhost session: c4bf4c89c3fb483c935bdff223394646 │ -│ ↳ workdir: ~/dev/agentapi │ -│ ↳ model: o4-mini │ -│ ↳ approval: suggest │ -╰──────────────────────────────────────────────────────────────╯ - - system - Warning: model "o4-mini" is not in the list of available models returned by OpenAI. -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ send a message │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ - send q or ctrl+c to exit | send "/clear" to reset | send "/help" for commands | press enter to send \ No newline at end of file +╭Messages (tab to focus)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│OpenAI Codex v0.10.0 (research preview) │ +│ │ +│codex session 56576d81-529d-42f3-843b-78d870054a75 │ +│workdir: /Users/jkmr/Documents/work/agentapi │ +│model: codex-mini-latest │ +│provider: openai │ +│approval: untrusted │ +│sandbox: read-only │ +│reasoning effort: medium │ +│reasoning summaries: auto │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ send a message │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Enter to send | Ctrl+D to quit | Ctrl+J for newline╯ \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi-line-input/expected.txt b/lib/msgfmt/testdata/format/codex/multi-line-input/expected.txt new file mode 100644 index 0000000..a42ca83 --- /dev/null +++ b/lib/msgfmt/testdata/format/codex/multi-line-input/expected.txt @@ -0,0 +1,14 @@ +command (code: 127, duration: 10ms) +$ bash -lc 'rg -n "func formatCodexMessage"' +bash: line 1: rg: command not found + +command (code: 0, duration: 8.23s) +$ bash -lc 'grep -R "formatCodexMessage" -n .' +./lib/msgfmt/testdata/format/claude/multi-line-input/user.txt:3:func formatCodexMessage(message string, userInput string) string { +./lib/msgfmt/msgfmt.go:219:func formatCodexMessage(message string, userInput string) string { +./lib/msgfmt/msgfmt.go:236: return formatCodexMessage(message, userInput) + +codex +The formatCodexMessage function is defined in: + +lib/msgfmt/msgfmt.go (around line 219) \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi-line-input/msg.txt b/lib/msgfmt/testdata/format/codex/multi-line-input/msg.txt new file mode 100644 index 0000000..b409343 --- /dev/null +++ b/lib/msgfmt/testdata/format/codex/multi-line-input/msg.txt @@ -0,0 +1,27 @@ +│command (code: 127, duration: 10ms) │ +│$ bash -lc 'rg -n "func formatCodexMessage"' │ +│bash: line 1: rg: command not found │ +│ │ +│command (code: 0, duration: 8.23s) │ +│$ bash -lc 'grep -R "formatCodexMessage" -n .' │ +│./lib/msgfmt/testdata/format/claude/multi-line-input/user.txt:3:func formatCodexMessage(message string, userInput string) string { │ +│./lib/msgfmt/msgfmt.go:219:func formatCodexMessage(message string, userInput string) string { │ +│./lib/msgfmt/msgfmt.go:236: return formatCodexMessage(message, userInput) │ +│ │ +│codex │ +│The formatCodexMessage function is defined in: │ +│ │ +│lib/msgfmt/msgfmt.go (around line 219) │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ send a message — 97% context left │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Enter to send | Ctrl+D to quit | Ctrl+J for newline╯ \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi-line-input/user.txt b/lib/msgfmt/testdata/format/codex/multi-line-input/user.txt new file mode 100644 index 0000000..4250545 --- /dev/null +++ b/lib/msgfmt/testdata/format/codex/multi-line-input/user.txt @@ -0,0 +1,4 @@ +Which file is this function from? +```go +func formatCodexMessage(message string, userInput string) string {} +``` diff --git a/lib/msgfmt/testdata/format/codex/multi_line/expected.txt b/lib/msgfmt/testdata/format/codex/multi_line/expected.txt deleted file mode 100644 index 2c27535..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line/expected.txt +++ /dev/null @@ -1,16 +0,0 @@ - thinking for 5s - - command - - $ grep -R 'Closecloses the process' -n . - - command.stdout (code: 0, duration: 7.2s) - - ./lib/termexec/termexec.go:74:// Closecloses the process using a SIGINT signal or forcefully killing it - if the process - - - thinking for 15s - - codex - That’s in the termexec package, in lib/termexec/termexec.go (around line 74). \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi_line/msg.txt b/lib/msgfmt/testdata/format/codex/multi_line/msg.txt deleted file mode 100644 index b54d226..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line/msg.txt +++ /dev/null @@ -1,60 +0,0 @@ -user -what file does this code come from? - - // Closecloses the process using a SIGINT signal or forcefully killing it if the process - // does not exit after the timeout. It then closes the pseudo terminal. - func (p *Process) Close(logger *slog.Logger, timeout time.Duration) error { - logger.Info("Closing process") - if err := p.execCmd.Process.Signal(os.Interrupt); err != nil { - return xerrors.Errorf("failed to send SIGINT to process: %w", err) - } - - exited := make(chan error, 1) - go func() { - _, err := p.execCmd.Process.Wait() - exited <- err - close(exited) - }() - - var exitErr error - select { - case <-time.After(timeout): - if err := p.execCmd.Process.Kill(); err != nil { - exitErr = xerrors.Errorf("failed to forcefully kill the process: %w", err) - } - // don't wait for the process to exit to avoid hanging indefinitely - // if the process never exits - case err := <-exited: - var pathErr *os.SyscallError - // ECHILD is expected if the process has already exited - if err != nil && !(errors.As(err, &pathErr) && pathErr.Err == syscall.ECHILD) { - exitErr = xerrors.Errorf("process exited with error: %w", err) - } - } - if err := p.xp.Close(); err != nil { - return xerrors.Errorf("failed to close pseudo terminal: %w, exitErr: %w", err, exitErr) - } - return exitErr - } - - thinking for 5s - - command - - $ grep -R 'Closecloses the process' -n . - - command.stdout (code: 0, duration: 7.2s) - - ./lib/termexec/termexec.go:74:// Closecloses the process using a SIGINT signal or forcefully killing it - if the process - - - thinking for 15s - - codex - That’s in the termexec package, in lib/termexec/termexec.go (around line 74). -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ send a message │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ - send q or ctrl+c to exit | send "/clear" to reset | send "/help" for commands | press enter to send - diff --git a/lib/msgfmt/testdata/format/codex/multi_line/user.txt b/lib/msgfmt/testdata/format/codex/multi_line/user.txt deleted file mode 100644 index 5df1314..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line/user.txt +++ /dev/null @@ -1,39 +0,0 @@ -what file does this code come from? - -``` -// Closecloses the process using a SIGINT signal or forcefully killing it if the process -// does not exit after the timeout. It then closes the pseudo terminal. -func (p *Process) Close(logger *slog.Logger, timeout time.Duration) error { - logger.Info("Closing process") - if err := p.execCmd.Process.Signal(os.Interrupt); err != nil { - return xerrors.Errorf("failed to send SIGINT to process: %w", err) - } - - exited := make(chan error, 1) - go func() { - _, err := p.execCmd.Process.Wait() - exited <- err - close(exited) - }() - - var exitErr error - select { - case <-time.After(timeout): - if err := p.execCmd.Process.Kill(); err != nil { - exitErr = xerrors.Errorf("failed to forcefully kill the process: %w", err) - } - // don't wait for the process to exit to avoid hanging indefinitely - // if the process never exits - case err := <-exited: - var pathErr *os.SyscallError - // ECHILD is expected if the process has already exited - if err != nil && !(errors.As(err, &pathErr) && pathErr.Err == syscall.ECHILD) { - exitErr = xerrors.Errorf("process exited with error: %w", err) - } - } - if err := p.xp.Close(); err != nil { - return xerrors.Errorf("failed to close pseudo terminal: %w, exitErr: %w", err, exitErr) - } - return exitErr -} -``` \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi_line2/expected.txt b/lib/msgfmt/testdata/format/codex/multi_line2/expected.txt deleted file mode 100644 index a6752a0..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line2/expected.txt +++ /dev/null @@ -1,45 +0,0 @@ - thinking for 10s - - command - - $ grep -R "Process) Close" -n . - - command.stdout (code: 0, duration: 6.9s) - - ./lib/termexec/termexec.go:76:func (p *Process) Close(logger *slog.Logger, - timeout time.Duration) error { - ./lib/msgfmt/testdata/format/codex/multi_line2/msg.txt:9:│ func (p *Process) - Close(logger *slog.Logger, timeout time.Duration) error { │ - ./lib/msgfmt/testdata/format/codex/multi_line2/msg.txt:37: func (p - *Process) Close(logger *slog.Logger, timeout time.Duration) error { - ./lib/msgfmt/testdata/format/codex/multi_line/user.txt:6:func (p *Process) - Close(logger *slog.Logger, timeout time.Duration) error { - ... (2 more lines) - - thinking for 20s - - command - - $ sed -n '1,150p' lib/termexec/termexec.go - - command.stdout (code: 0, duration: 0s) - - package termexec - - import ( - "context" - ... (113 more lines) - - thinking for 26s - - codex - That’s the Close method on the Process type in the termexec package. You can - find it here: - - lib/termexec/termexec.go, starting at line 76: - - // Closecloses the process using a SIGINT signal … - func (p *Process) Close(logger *slog.Logger, timeout time.Duration) - error { - … - } \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi_line2/msg.txt b/lib/msgfmt/testdata/format/codex/multi_line2/msg.txt deleted file mode 100644 index 7f3192d..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line2/msg.txt +++ /dev/null @@ -1,98 +0,0 @@ -user -[200~what file does this code come from? - - // Closecloses the process using a SIGINT signal or forcefully killing it if - the process - // does not exit after the timeout. It then closes the pseudo terminal. - func (p *Process) Close(logger *slog.Logger, timeout time.Duration) error { - logger.Info("Closing process") - if err := p.execCmd.Process.Signal(os.Interrupt); err != nil { - return xerrors.Errorf("failed to send SIGINT to process: %w", er -r) - } - - exited := make(chan error, 1) - go func() { - _, err := p.execCmd.Process.Wait() - exited <- err - close(exited) - }() - - var exitErr error - select { - case <-time.After(timeout): - if err := p.execCmd.Process.Kill(); err != nil { - exitErr = xerrors.Errorf("failed to forcefully kill the -process: %w", err) - } - // don't wait for the process to exit to avoid hanging indefinit -ely - // if the process never exits - case err := <-exited: - var pathErr *os.SyscallError - // ECHILD is expected if the process has already exited - if err != nil && !(errors.As(err, &pathErr) && pathErr.Err == -syscall.ECHILD) { - exitErr = xerrors.Errorf("process exited with error: %w" -, err) - } - } - if err := p.xp.Close(); err != nil { - return xerrors.Errorf("failed to close pseudo terminal: %w, exit -Err: %w", -err, exitErr) - } - return exitErr - } - ```[201~ - - thinking for 10s - - command - - $ grep -R "Process) Close" -n . - - command.stdout (code: 0, duration: 6.9s) - - ./lib/termexec/termexec.go:76:func (p *Process) Close(logger *slog.Logger, - timeout time.Duration) error { - ./lib/msgfmt/testdata/format/codex/multi_line2/msg.txt:9:│ func (p *Process) - Close(logger *slog.Logger, timeout time.Duration) error { │ - ./lib/msgfmt/testdata/format/codex/multi_line2/msg.txt:37: func (p - *Process) Close(logger *slog.Logger, timeout time.Duration) error { - ./lib/msgfmt/testdata/format/codex/multi_line/user.txt:6:func (p *Process) - Close(logger *slog.Logger, timeout time.Duration) error { - ... (2 more lines) - - thinking for 20s - - command - - $ sed -n '1,150p' lib/termexec/termexec.go - - command.stdout (code: 0, duration: 0s) - - package termexec - - import ( - "context" - ... (113 more lines) - - thinking for 26s - - codex - That’s the Close method on the Process type in the termexec package. You can - find it here: - - lib/termexec/termexec.go, starting at line 76: - - // Closecloses the process using a SIGINT signal … - func (p *Process) Close(logger *slog.Logger, timeout time.Duration) - error { - … - } -╭──────────────────────────────────────────────────────────────────────────────╮ -│ send a message │ -╰──────────────────────────────────────────────────────────────────────────────╯ - send q or ctrl+c to exit | send "/clear" to reset | send "/help" for - commands | press enter to send \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/multi_line2/user.txt b/lib/msgfmt/testdata/format/codex/multi_line2/user.txt deleted file mode 100644 index 5df1314..0000000 --- a/lib/msgfmt/testdata/format/codex/multi_line2/user.txt +++ /dev/null @@ -1,39 +0,0 @@ -what file does this code come from? - -``` -// Closecloses the process using a SIGINT signal or forcefully killing it if the process -// does not exit after the timeout. It then closes the pseudo terminal. -func (p *Process) Close(logger *slog.Logger, timeout time.Duration) error { - logger.Info("Closing process") - if err := p.execCmd.Process.Signal(os.Interrupt); err != nil { - return xerrors.Errorf("failed to send SIGINT to process: %w", err) - } - - exited := make(chan error, 1) - go func() { - _, err := p.execCmd.Process.Wait() - exited <- err - close(exited) - }() - - var exitErr error - select { - case <-time.After(timeout): - if err := p.execCmd.Process.Kill(); err != nil { - exitErr = xerrors.Errorf("failed to forcefully kill the process: %w", err) - } - // don't wait for the process to exit to avoid hanging indefinitely - // if the process never exits - case err := <-exited: - var pathErr *os.SyscallError - // ECHILD is expected if the process has already exited - if err != nil && !(errors.As(err, &pathErr) && pathErr.Err == syscall.ECHILD) { - exitErr = xerrors.Errorf("process exited with error: %w", err) - } - } - if err := p.xp.Close(); err != nil { - return xerrors.Errorf("failed to close pseudo terminal: %w, exitErr: %w", err, exitErr) - } - return exitErr -} -``` \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/response/expected.txt b/lib/msgfmt/testdata/format/codex/response/expected.txt deleted file mode 100644 index 3ca55a7..0000000 --- a/lib/msgfmt/testdata/format/codex/response/expected.txt +++ /dev/null @@ -1,4 +0,0 @@ - thinking for 3s - - codex - I’m doing great—thanks for asking! How can I help you with your project today? \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/response/msg.txt b/lib/msgfmt/testdata/format/codex/response/msg.txt deleted file mode 100644 index 2f92eff..0000000 --- a/lib/msgfmt/testdata/format/codex/response/msg.txt +++ /dev/null @@ -1,11 +0,0 @@ -user -how are you? - - thinking for 3s - - codex - I’m doing great—thanks for asking! How can I help you with your project today? -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ send a message │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ - send q or ctrl+c to exit | send "/clear" to reset | send "/help" for commands | press enter to send \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/response/user.txt b/lib/msgfmt/testdata/format/codex/response/user.txt deleted file mode 100644 index c01e0f3..0000000 --- a/lib/msgfmt/testdata/format/codex/response/user.txt +++ /dev/null @@ -1 +0,0 @@ -how are you? \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/second_message/expected.txt b/lib/msgfmt/testdata/format/codex/second_message/expected.txt index c0c4e9e..2ce98fe 100644 --- a/lib/msgfmt/testdata/format/codex/second_message/expected.txt +++ b/lib/msgfmt/testdata/format/codex/second_message/expected.txt @@ -1,17 +1,2 @@ - thinking for 9s - - command - - $ git rev-parse --show-toplevel - - command.stdout (code: 0, duration: 0s) - - /Users/hugodutka/dev/agentapi - - - codex - The current Git repository root is at: - - /Users/hugodutka/dev/agentapi - - Let me know if you need anything else! \ No newline at end of file +codex +I’m doing great, thanks for asking! How can I help you today? \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/second_message/msg.txt b/lib/msgfmt/testdata/format/codex/second_message/msg.txt index 6441972..03ece28 100644 --- a/lib/msgfmt/testdata/format/codex/second_message/msg.txt +++ b/lib/msgfmt/testdata/format/codex/second_message/msg.txt @@ -1,24 +1,17 @@ -user -what repository are you in? - - thinking for 9s - - command - - $ git rev-parse --show-toplevel - - command.stdout (code: 0, duration: 0s) - - /Users/hugodutka/dev/agentapi - - - codex - The current Git repository root is at: - - /Users/hugodutka/dev/agentapi - - Let me know if you need anything else! -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ send a message │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ - send q or ctrl+c to exit | send "/clear" to reset | send "/help" for commands | press enter to send \ No newline at end of file +│user │ +│how are you? │ +│ │ +│codex │ +│I’m doing great, thanks for asking! How can I help you today? │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ send a message — 99% context left │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Enter to send | Ctrl+D to quit | Ctrl+J for newline╯ \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/codex/second_message/user.txt b/lib/msgfmt/testdata/format/codex/second_message/user.txt index 338205d..c01e0f3 100644 --- a/lib/msgfmt/testdata/format/codex/second_message/user.txt +++ b/lib/msgfmt/testdata/format/codex/second_message/user.txt @@ -1 +1 @@ -what repository are you in? \ No newline at end of file +how are you? \ No newline at end of file