mirror of
https://github.com/openai/codex.git
synced 2026-05-02 04:11:39 +03:00
Wait for newlines, then render markdown on a line by line basis. Word wrap it for the current terminal size and then spit it out line by line into the UI. Also adds tests and fixes some UI regressions.
90 lines
2.9 KiB
Rust
90 lines
2.9 KiB
Rust
use std::collections::VecDeque;
|
|
|
|
use codex_core::protocol::ApplyPatchApprovalRequestEvent;
|
|
use codex_core::protocol::ExecApprovalRequestEvent;
|
|
use codex_core::protocol::ExecCommandBeginEvent;
|
|
use codex_core::protocol::ExecCommandEndEvent;
|
|
use codex_core::protocol::McpToolCallBeginEvent;
|
|
use codex_core::protocol::McpToolCallEndEvent;
|
|
use codex_core::protocol::PatchApplyEndEvent;
|
|
|
|
use super::ChatWidget;
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) enum QueuedInterrupt {
|
|
ExecApproval(String, ExecApprovalRequestEvent),
|
|
ApplyPatchApproval(String, ApplyPatchApprovalRequestEvent),
|
|
ExecBegin(ExecCommandBeginEvent),
|
|
ExecEnd(ExecCommandEndEvent),
|
|
McpBegin(McpToolCallBeginEvent),
|
|
McpEnd(McpToolCallEndEvent),
|
|
PatchEnd(PatchApplyEndEvent),
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub(crate) struct InterruptManager {
|
|
queue: VecDeque<QueuedInterrupt>,
|
|
}
|
|
|
|
impl InterruptManager {
|
|
pub(crate) fn new() -> Self {
|
|
Self {
|
|
queue: VecDeque::new(),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub(crate) fn is_empty(&self) -> bool {
|
|
self.queue.is_empty()
|
|
}
|
|
|
|
pub(crate) fn push_exec_approval(&mut self, id: String, ev: ExecApprovalRequestEvent) {
|
|
self.queue.push_back(QueuedInterrupt::ExecApproval(id, ev));
|
|
}
|
|
|
|
pub(crate) fn push_apply_patch_approval(
|
|
&mut self,
|
|
id: String,
|
|
ev: ApplyPatchApprovalRequestEvent,
|
|
) {
|
|
self.queue
|
|
.push_back(QueuedInterrupt::ApplyPatchApproval(id, ev));
|
|
}
|
|
|
|
pub(crate) fn push_exec_begin(&mut self, ev: ExecCommandBeginEvent) {
|
|
self.queue.push_back(QueuedInterrupt::ExecBegin(ev));
|
|
}
|
|
|
|
pub(crate) fn push_exec_end(&mut self, ev: ExecCommandEndEvent) {
|
|
self.queue.push_back(QueuedInterrupt::ExecEnd(ev));
|
|
}
|
|
|
|
pub(crate) fn push_mcp_begin(&mut self, ev: McpToolCallBeginEvent) {
|
|
self.queue.push_back(QueuedInterrupt::McpBegin(ev));
|
|
}
|
|
|
|
pub(crate) fn push_mcp_end(&mut self, ev: McpToolCallEndEvent) {
|
|
self.queue.push_back(QueuedInterrupt::McpEnd(ev));
|
|
}
|
|
|
|
pub(crate) fn push_patch_end(&mut self, ev: PatchApplyEndEvent) {
|
|
self.queue.push_back(QueuedInterrupt::PatchEnd(ev));
|
|
}
|
|
|
|
pub(crate) fn flush_all(&mut self, chat: &mut ChatWidget<'_>) {
|
|
while let Some(q) = self.queue.pop_front() {
|
|
match q {
|
|
QueuedInterrupt::ExecApproval(id, ev) => chat.handle_exec_approval_now(id, ev),
|
|
QueuedInterrupt::ApplyPatchApproval(id, ev) => {
|
|
chat.handle_apply_patch_approval_now(id, ev)
|
|
}
|
|
QueuedInterrupt::ExecBegin(ev) => chat.handle_exec_begin_now(ev),
|
|
QueuedInterrupt::ExecEnd(ev) => chat.handle_exec_end_now(ev),
|
|
QueuedInterrupt::McpBegin(ev) => chat.handle_mcp_begin_now(ev),
|
|
QueuedInterrupt::McpEnd(ev) => chat.handle_mcp_end_now(ev),
|
|
QueuedInterrupt::PatchEnd(ev) => chat.handle_patch_apply_end_now(ev),
|
|
}
|
|
}
|
|
}
|
|
}
|