fix: show codexapp steer insertion status
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const ASSET_VERSION = '20260615-reload-mcp';
|
const ASSET_VERSION = '20260615-codexapp-steer-status';
|
||||||
const WS_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/ws`;
|
const WS_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/ws`;
|
||||||
const RENDER_DEBOUNCE = 100;
|
const RENDER_DEBOUNCE = 100;
|
||||||
const COMPOSER_SUGGESTION_DEBOUNCE = 120;
|
const COMPOSER_SUGGESTION_DEBOUNCE = 120;
|
||||||
@@ -3066,7 +3066,16 @@
|
|||||||
|
|
||||||
case 'system_message':
|
case 'system_message':
|
||||||
if (!isCurrentSessionEvent(msg)) break;
|
if (!isCurrentSessionEvent(msg)) break;
|
||||||
appendSystemMessage(msg.message);
|
appendSystemMessage(msg.message, {
|
||||||
|
tone: msg.tone,
|
||||||
|
transient: msg.transient,
|
||||||
|
autoDismissMs: msg.autoDismissMs,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'codex_app_steer_status':
|
||||||
|
if (!isCurrentSessionEvent(msg)) break;
|
||||||
|
updateCodexAppSteerMessage(msg.clientMessageId, msg.status, msg.message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'codex_app_user_input_request':
|
case 'codex_app_user_input_request':
|
||||||
@@ -3167,7 +3176,10 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pendingNewSessionRequest) pendingNewSessionRequest = null;
|
if (pendingNewSessionRequest) pendingNewSessionRequest = null;
|
||||||
appendError(msg.message);
|
appendError(msg.message, {
|
||||||
|
transient: msg.transient,
|
||||||
|
autoDismissMs: msg.autoDismissMs,
|
||||||
|
});
|
||||||
clearSessionLoading();
|
clearSessionLoading();
|
||||||
if (!isGenerating && currentSessionId) {
|
if (!isGenerating && currentSessionId) {
|
||||||
setCurrentSessionRunningState(!!getSessionMeta(currentSessionId)?.isRunning);
|
setCurrentSessionRunningState(!!getSessionMeta(currentSessionId)?.isRunning);
|
||||||
@@ -3372,6 +3384,54 @@
|
|||||||
catch { return escapeHtml(text); }
|
catch { return escapeHtml(text); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function codexAppSteerStatusLabel(status) {
|
||||||
|
if (status === 'inserted') return '已插入';
|
||||||
|
if (status === 'failed') return '插入失败';
|
||||||
|
return '引导中...';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCodexAppSteerStatusElement(element, status, message) {
|
||||||
|
if (!element) return false;
|
||||||
|
const normalized = ['pending', 'inserted', 'failed'].includes(status) ? status : 'pending';
|
||||||
|
element.classList.add('codex-steer-message');
|
||||||
|
element.classList.toggle('codex-steer-pending', normalized === 'pending');
|
||||||
|
element.classList.toggle('codex-steer-inserted', normalized === 'inserted');
|
||||||
|
element.classList.toggle('codex-steer-failed', normalized === 'failed');
|
||||||
|
const bubble = element.querySelector('.msg-bubble');
|
||||||
|
if (!bubble) return false;
|
||||||
|
let statusEl = bubble.querySelector('.codex-steer-status');
|
||||||
|
if (!statusEl) {
|
||||||
|
statusEl = document.createElement('div');
|
||||||
|
statusEl.className = 'codex-steer-status';
|
||||||
|
bubble.appendChild(statusEl);
|
||||||
|
}
|
||||||
|
statusEl.dataset.status = normalized;
|
||||||
|
statusEl.textContent = message || codexAppSteerStatusLabel(normalized);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCodexAppSteerMessage(clientMessageId, status, message) {
|
||||||
|
const id = String(clientMessageId || '').trim();
|
||||||
|
if (!id) return false;
|
||||||
|
const indexed = userMessageIndex.get(id);
|
||||||
|
const element = indexed?.element || messagesDiv.querySelector(`[data-message-id="${cssEscape(id)}"]`);
|
||||||
|
return setCodexAppSteerStatusElement(element, status, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleTransientMessageRemoval(element, timeoutMs) {
|
||||||
|
const ttl = Number(timeoutMs);
|
||||||
|
if (!element || !Number.isFinite(ttl) || ttl <= 0) return;
|
||||||
|
window.setTimeout(() => {
|
||||||
|
if (!element || !element.isConnected) return;
|
||||||
|
element.classList.add('is-dismissing');
|
||||||
|
window.setTimeout(() => {
|
||||||
|
if (!element || !element.isConnected) return;
|
||||||
|
element.remove();
|
||||||
|
updateScrollbar();
|
||||||
|
}, 220);
|
||||||
|
}, ttl);
|
||||||
|
}
|
||||||
|
|
||||||
function createMsgElement(role, content, attachments = [], meta = {}) {
|
function createMsgElement(role, content, attachments = [], meta = {}) {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
const isCrossConversation = role === 'user' && !!meta.crossConversation;
|
const isCrossConversation = role === 'user' && !!meta.crossConversation;
|
||||||
@@ -3384,13 +3444,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (role === 'system') {
|
if (role === 'system') {
|
||||||
|
const tone = String(meta.tone || 'neutral').trim() || 'neutral';
|
||||||
const bubble = document.createElement('div');
|
const bubble = document.createElement('div');
|
||||||
bubble.className = 'msg-bubble';
|
bubble.className = 'msg-bubble';
|
||||||
|
bubble.dataset.tone = tone;
|
||||||
const text = document.createElement('span');
|
const text = document.createElement('span');
|
||||||
text.className = 'system-message-text';
|
text.className = 'system-message-text';
|
||||||
text.textContent = content;
|
text.textContent = content;
|
||||||
bubble.appendChild(text);
|
bubble.appendChild(text);
|
||||||
|
|
||||||
|
const transient = !!meta.transient;
|
||||||
|
if (transient) {
|
||||||
|
div.classList.add('transient');
|
||||||
|
}
|
||||||
|
|
||||||
const closeBtn = document.createElement('button');
|
const closeBtn = document.createElement('button');
|
||||||
closeBtn.type = 'button';
|
closeBtn.type = 'button';
|
||||||
closeBtn.className = 'system-message-close';
|
closeBtn.className = 'system-message-close';
|
||||||
@@ -3404,6 +3471,9 @@
|
|||||||
});
|
});
|
||||||
bubble.appendChild(closeBtn);
|
bubble.appendChild(closeBtn);
|
||||||
div.appendChild(bubble);
|
div.appendChild(bubble);
|
||||||
|
if (transient) {
|
||||||
|
scheduleTransientMessageRemoval(div, meta.autoDismissMs || 6000);
|
||||||
|
}
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3489,6 +3559,9 @@
|
|||||||
hydrateAttachmentPreviews(bubble, attachments);
|
hydrateAttachmentPreviews(bubble, attachments);
|
||||||
div.appendChild(avatar);
|
div.appendChild(avatar);
|
||||||
div.appendChild(bubble);
|
div.appendChild(bubble);
|
||||||
|
if (role === 'user' && meta.codexAppSteerStatus) {
|
||||||
|
setCodexAppSteerStatusElement(div, meta.codexAppSteerStatus, meta.codexAppSteerMessage);
|
||||||
|
}
|
||||||
if (role === 'user') {
|
if (role === 'user') {
|
||||||
registerUserMessage(resolvedMessageId, div, content);
|
registerUserMessage(resolvedMessageId, div, content);
|
||||||
}
|
}
|
||||||
@@ -4575,19 +4648,19 @@
|
|||||||
overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
|
overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendSystemMessage(message) {
|
function appendSystemMessage(message, options = {}) {
|
||||||
const welcome = messagesDiv.querySelector('.welcome-msg');
|
const welcome = messagesDiv.querySelector('.welcome-msg');
|
||||||
if (welcome) welcome.remove();
|
if (welcome) welcome.remove();
|
||||||
messagesDiv.appendChild(createMsgElement('system', message));
|
messagesDiv.appendChild(createMsgElement('system', message, [], options));
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendError(message) {
|
function appendError(message, options = {}) {
|
||||||
const div = document.createElement('div');
|
appendSystemMessage(`⚠ ${message}`, {
|
||||||
div.className = 'msg system';
|
tone: 'danger',
|
||||||
div.innerHTML = `<div class="msg-bubble" style="border-color:var(--danger);color:var(--danger)">⚠ ${escapeHtml(message)}</div>`;
|
transient: options.transient !== false,
|
||||||
messagesDiv.appendChild(div);
|
autoDismissMs: options.autoDismissMs || 7000,
|
||||||
scrollToBottom();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollToBottom() {
|
function scrollToBottom() {
|
||||||
@@ -5260,12 +5333,12 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const messageId = createLocalId('user');
|
const messageId = createLocalId('user');
|
||||||
const element = createMsgElement('user', text, [], { messageId });
|
const element = createMsgElement('user', text, [], { messageId, codexAppSteerStatus: 'pending' });
|
||||||
messagesDiv.appendChild(element);
|
messagesDiv.appendChild(element);
|
||||||
registerUserMessage(messageId, element, text);
|
registerUserMessage(messageId, element, text);
|
||||||
updateUserOutlinePanel();
|
updateUserOutlinePanel();
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
send({ type: 'message', text, sessionId: currentSessionId, mode: currentMode, agent: currentAgent });
|
send({ type: 'message', text, sessionId: currentSessionId, mode: currentMode, agent: currentAgent, clientMessageId: messageId });
|
||||||
msgInput.value = '';
|
msgInput.value = '';
|
||||||
autoResize();
|
autoResize();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
document.documentElement.dataset.dividerTime = dividerTime;
|
document.documentElement.dataset.dividerTime = dividerTime;
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<link rel="stylesheet" href="style.css?v=20260615-reload-mcp">
|
<link rel="stylesheet" href="style.css?v=20260615-codexapp-steer-status">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -150,6 +150,6 @@
|
|||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||||
<script src="app.js?v=20260615-reload-mcp"></script>
|
<script src="app.js?v=20260615-codexapp-steer-status"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1901,6 +1901,64 @@ body.session-loading-active {
|
|||||||
border-bottom-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
||||||
padding-right: 42px;
|
padding-right: 42px;
|
||||||
}
|
}
|
||||||
|
.msg.user.codex-steer-message .msg-bubble {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.msg.user.codex-steer-pending .msg-avatar,
|
||||||
|
.msg.user.codex-steer-inserted .msg-avatar,
|
||||||
|
.msg.user.codex-steer-failed .msg-avatar {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.msg.user.codex-steer-pending .msg-bubble {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border: 1px dashed var(--border-color);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
.msg.user.codex-steer-inserted .msg-bubble {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
opacity: 0.94;
|
||||||
|
}
|
||||||
|
.msg.user.codex-steer-failed .msg-bubble {
|
||||||
|
background: rgba(220, 53, 69, 0.1);
|
||||||
|
border: 1px solid rgba(220, 53, 69, 0.32);
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
.codex-steer-status {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
opacity: 0.88;
|
||||||
|
}
|
||||||
|
.codex-steer-status::before {
|
||||||
|
content: '';
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: currentColor;
|
||||||
|
opacity: 0.72;
|
||||||
|
}
|
||||||
|
.codex-steer-status[data-status='pending'] {
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.codex-steer-status[data-status='inserted'] {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
.codex-steer-status[data-status='failed'] {
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
.msg.user.codex-steer-pending .msg-copy-btn {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
.msg-copy-btn {
|
.msg-copy-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
@@ -2082,6 +2140,23 @@ body.session-loading-active {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
.msg.system.transient .msg-bubble {
|
||||||
|
border-style: solid;
|
||||||
|
box-shadow: 0 6px 18px rgba(27, 39, 51, 0.08);
|
||||||
|
}
|
||||||
|
.msg.system .msg-bubble[data-tone='danger'] {
|
||||||
|
border-color: rgba(220, 53, 69, 0.34);
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
.msg.system .msg-bubble[data-tone='info'] {
|
||||||
|
border-color: rgba(58, 134, 255, 0.26);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
.msg.system.is-dismissing {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-4px);
|
||||||
|
transition: opacity 0.22s ease, transform 0.22s ease;
|
||||||
|
}
|
||||||
.msg.system .system-message-text {
|
.msg.system .system-message-text {
|
||||||
display: block;
|
display: block;
|
||||||
padding-right: 26px;
|
padding-right: 26px;
|
||||||
|
|||||||
@@ -887,9 +887,37 @@ async function main() {
|
|||||||
ws.send(JSON.stringify({ type: 'message', text: 'slow codexapp prompt', sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
|
ws.send(JSON.stringify({ type: 'message', text: 'slow codexapp prompt', sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
|
||||||
await nextMessage(messages, ws, (msg) => msg.type === 'session_list' && msg.sessions.some((s) => s.id === codexAppSession.sessionId && s.isRunning));
|
await nextMessage(messages, ws, (msg) => msg.type === 'session_list' && msg.sessions.some((s) => s.id === codexAppSession.sessionId && s.isRunning));
|
||||||
await sleep(150);
|
await sleep(150);
|
||||||
ws.send(JSON.stringify({ type: 'message', text: 'runtime steer insert', sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
|
ws.send(JSON.stringify({
|
||||||
|
type: 'message',
|
||||||
|
text: 'runtime steer insert',
|
||||||
|
sessionId: codexAppSession.sessionId,
|
||||||
|
mode: 'yolo',
|
||||||
|
agent: 'codexapp',
|
||||||
|
clientMessageId: 'regression-steer-message',
|
||||||
|
}));
|
||||||
|
const steerPending = await nextMessage(messages, ws, (msg) =>
|
||||||
|
msg.type === 'codex_app_steer_status' &&
|
||||||
|
msg.sessionId === codexAppSession.sessionId &&
|
||||||
|
msg.clientMessageId === 'regression-steer-message' &&
|
||||||
|
msg.status === 'pending'
|
||||||
|
);
|
||||||
|
assert(/引导中/.test(steerPending.message || ''), 'Codex App steer should expose pending status');
|
||||||
const steerDelta = await nextMessage(messages, ws, (msg) => msg.type === 'text_delta' && msg.sessionId === codexAppSession.sessionId && /steer accepted: runtime steer insert/.test(msg.text || ''));
|
const steerDelta = await nextMessage(messages, ws, (msg) => msg.type === 'text_delta' && msg.sessionId === codexAppSession.sessionId && /steer accepted: runtime steer insert/.test(msg.text || ''));
|
||||||
assert(/runtime steer insert/.test(steerDelta.text || ''), 'Codex App running message should use turn/steer');
|
assert(/runtime steer insert/.test(steerDelta.text || ''), 'Codex App running message should use turn/steer');
|
||||||
|
const steerInserted = await nextMessage(messages, ws, (msg) =>
|
||||||
|
msg.type === 'codex_app_steer_status' &&
|
||||||
|
msg.sessionId === codexAppSession.sessionId &&
|
||||||
|
msg.clientMessageId === 'regression-steer-message' &&
|
||||||
|
msg.status === 'inserted'
|
||||||
|
);
|
||||||
|
assert(/已插入/.test(steerInserted.message || ''), 'Codex App steer should expose inserted status');
|
||||||
|
const steerSystemMessage = await nextMessage(messages, ws, (msg) =>
|
||||||
|
msg.type === 'system_message' &&
|
||||||
|
msg.sessionId === codexAppSession.sessionId &&
|
||||||
|
/已引导对话: runtime steer insert/.test(msg.message || '')
|
||||||
|
);
|
||||||
|
assert(steerSystemMessage.transient === true, 'Codex App steer marker should be transient');
|
||||||
|
assert(/已引导对话: runtime steer insert/.test(steerSystemMessage.message || ''), 'Codex App steer should show guided conversation marker with preview');
|
||||||
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
|
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
|
||||||
storedCodexApp = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
|
storedCodexApp = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
|
||||||
assert(storedCodexApp.codexAppThreadId === codexAppThreadId, 'Codex App follow-up should resume the same app-server thread');
|
assert(storedCodexApp.codexAppThreadId === codexAppThreadId, 'Codex App follow-up should resume the same app-server thread');
|
||||||
|
|||||||
39
server.js
39
server.js
@@ -4583,6 +4583,12 @@ function normalizeCodexAppUserInputAnswers(rawAnswers = {}) {
|
|||||||
return { answers };
|
return { answers };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function previewInlineText(text, maxLength = 36) {
|
||||||
|
const normalized = String(text || '').replace(/\s+/g, ' ').trim();
|
||||||
|
if (!normalized) return '空内容';
|
||||||
|
return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 1)}...` : normalized;
|
||||||
|
}
|
||||||
|
|
||||||
function requestCodexAppUserInput(routed, params = {}) {
|
function requestCodexAppUserInput(routed, params = {}) {
|
||||||
if (!routed?.entry?.ws) {
|
if (!routed?.entry?.ws) {
|
||||||
return Promise.resolve({ answers: {} });
|
return Promise.resolve({ answers: {} });
|
||||||
@@ -5046,8 +5052,23 @@ function handleCodexAppSteerMessage(ws, msg, options = {}) {
|
|||||||
const sessionId = sanitizeId(msg?.sessionId || '');
|
const sessionId = sanitizeId(msg?.sessionId || '');
|
||||||
const entry = activeCodexAppTurns.get(sessionId);
|
const entry = activeCodexAppTurns.get(sessionId);
|
||||||
if (!entry) return null;
|
if (!entry) return null;
|
||||||
|
const clientMessageId = String(msg?.clientMessageId || '').trim();
|
||||||
|
|
||||||
|
const sendSteerStatus = (status, message) => {
|
||||||
|
const targetWs = entry.ws || ws;
|
||||||
|
if (!targetWs) return;
|
||||||
|
const payload = {
|
||||||
|
type: 'codex_app_steer_status',
|
||||||
|
sessionId,
|
||||||
|
status,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
if (clientMessageId) payload.clientMessageId = clientMessageId;
|
||||||
|
wsSend(targetWs, payload);
|
||||||
|
};
|
||||||
|
|
||||||
const fail = (code, message) => {
|
const fail = (code, message) => {
|
||||||
|
sendSteerStatus('failed', '插入失败');
|
||||||
wsSend(ws, { type: 'error', code, message });
|
wsSend(ws, { type: 'error', code, message });
|
||||||
return { ok: false, code, message };
|
return { ok: false, code, message };
|
||||||
};
|
};
|
||||||
@@ -5099,18 +5120,32 @@ function handleCodexAppSteerMessage(ws, msg, options = {}) {
|
|||||||
wsSend(ws, { type: 'session_message', sessionId, message: persistedUserMessage });
|
wsSend(ws, { type: 'session_message', sessionId, message: persistedUserMessage });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendSteerStatus('pending', '引导中...');
|
||||||
const input = codexAppInputFromMessage(runtimeTextValue, []);
|
const input = codexAppInputFromMessage(runtimeTextValue, []);
|
||||||
const expectedTurnId = entry.turnId;
|
const expectedTurnId = entry.turnId;
|
||||||
codexAppClient.request('turn/steer', {
|
codexAppClient.request('turn/steer', {
|
||||||
threadId: entry.threadId,
|
threadId: entry.threadId,
|
||||||
expectedTurnId,
|
expectedTurnId,
|
||||||
input,
|
input,
|
||||||
clientUserMessageId: crypto.randomUUID(),
|
clientUserMessageId: clientMessageId || crypto.randomUUID(),
|
||||||
}, 60000).catch((err) => {
|
}, 60000).then(() => {
|
||||||
|
sendSteerStatus('inserted', '已插入');
|
||||||
|
wsSend(entry.ws || ws, {
|
||||||
|
type: 'system_message',
|
||||||
|
sessionId,
|
||||||
|
tone: 'info',
|
||||||
|
transient: true,
|
||||||
|
autoDismissMs: 5000,
|
||||||
|
message: `已引导对话: ${previewInlineText(textValue)}`,
|
||||||
|
});
|
||||||
|
}).catch((err) => {
|
||||||
|
sendSteerStatus('failed', '插入失败');
|
||||||
wsSend(entry.ws || ws, {
|
wsSend(entry.ws || ws, {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
sessionId,
|
sessionId,
|
||||||
code: 'codexapp_steer_failed',
|
code: 'codexapp_steer_failed',
|
||||||
|
transient: true,
|
||||||
|
autoDismissMs: 7000,
|
||||||
message: formatRuntimeError('codex', err?.message || err, { exitCode: null, signal: null }),
|
message: formatRuntimeError('codex', err?.message || err, { exitCode: null, signal: null }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user