fix: Add pony-alpha model and fix model lookup for prefixed model IDs
- Add openrouter/pony-alpha model to models-api.json fixture - Fix getModel() to lookup models with provider prefix (e.g., openrouter/pony-alpha) When user specifies openrouter/pony-alpha, the code now correctly looks for the full model ID including prefix in the provider's models object This fixes the 'ModelNotFoundError' when using OpenRouter models that have prefixed IDs in the database.
This commit is contained in:
@@ -384,6 +384,8 @@ const state = {
|
||||
usageSummary: null,
|
||||
todos: [], // Current todos from OpenCode
|
||||
currentMessageId: null, // Track which message we're displaying todos for
|
||||
isSending: false, // Track if a message is currently being sent
|
||||
currentSendingMessageId: null, // Track the ID of the message being sent for cancellation
|
||||
};
|
||||
|
||||
// Expose state for builder.html
|
||||
@@ -1824,7 +1826,7 @@ function renderMessages(session) {
|
||||
// Don't hide loading indicator during streaming - only hide when completely done
|
||||
// This allows the spinner to continue until the OpenCode session is fully complete
|
||||
const assistantCard = document.createElement('div');
|
||||
assistantCard.className = 'message assistant';
|
||||
assistantCard.className = 'message assistant' + (status === 'cancelled' ? ' cancelled' : '');
|
||||
const assistantMeta = document.createElement('div');
|
||||
assistantMeta.className = 'meta';
|
||||
const msgCliLabel = (msg.cli || session.cli || 'opencode');
|
||||
@@ -1841,10 +1843,10 @@ function renderMessages(session) {
|
||||
rawBtn.textContent = 'Plugin Compass';
|
||||
assistantMeta.appendChild(rawBtn);
|
||||
|
||||
// Add Undo/Redo buttons - only show for latest message and for opencode messages when done
|
||||
// Add Undo/Redo buttons - show for latest message when done, errored, or cancelled
|
||||
const isOpencodeMsg = msg.cli === 'opencode' || msg.phase === 'build';
|
||||
const isLatestMessage = latestMessage && latestMessage.id === msg.id;
|
||||
const shouldShowUndoRedo = isOpencodeMsg && isLatestMessage && (status === 'done' || status === 'error');
|
||||
const shouldShowUndoRedo = isOpencodeMsg && isLatestMessage && (status === 'done' || status === 'error' || status === 'cancelled');
|
||||
|
||||
if (shouldShowUndoRedo) {
|
||||
const undoBtn = document.createElement('button');
|
||||
@@ -3721,7 +3723,9 @@ async function sendMessage() {
|
||||
}
|
||||
}
|
||||
|
||||
if (el.miniSendBtn) el.miniSendBtn.disabled = true;
|
||||
// Set sending state and update button
|
||||
state.isSending = true;
|
||||
updateSendButtonState();
|
||||
|
||||
// Ensure we have a valid current session before proceeding
|
||||
if (!state.currentSessionId) {
|
||||
@@ -3801,6 +3805,12 @@ async function sendMessage() {
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
// Track the message ID being sent for potential cancellation
|
||||
if (response?.message?.id) {
|
||||
state.currentSendingMessageId = response.message.id;
|
||||
console.log('[BUILDER] Tracking message for cancellation:', response.message.id);
|
||||
}
|
||||
|
||||
// Clear attachments after successful send
|
||||
pendingAttachments.length = 0;
|
||||
renderAttachmentPreview();
|
||||
@@ -3862,12 +3872,143 @@ async function sendMessage() {
|
||||
renderMessages(currentSession);
|
||||
}
|
||||
} finally {
|
||||
if (el.miniSendBtn) el.miniSendBtn.disabled = false;
|
||||
// Reset sending state when message completes, is cancelled, or errors out
|
||||
// Only reset if we're not currently in a cancellation (cancelMessage handles that)
|
||||
if (state.isSending && state.currentSendingMessageId) {
|
||||
const session = state.sessions.find(s => s.id === state.currentSessionId);
|
||||
const messageId = state.currentSendingMessageId;
|
||||
const message = session?.messages.find(m => m.id === messageId);
|
||||
|
||||
// Reset if message is done, errored, or cancelled
|
||||
if (!message || message.status === 'done' || message.status === 'error' || message.status === 'cancelled') {
|
||||
state.isSending = false;
|
||||
state.currentSendingMessageId = null;
|
||||
updateSendButtonState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the current message being sent
|
||||
async function cancelMessage() {
|
||||
if (!state.isSending || !state.currentSendingMessageId) {
|
||||
console.log('[CANCEL] No message to cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
const messageId = state.currentSendingMessageId;
|
||||
const sessionId = state.currentSessionId;
|
||||
|
||||
console.log('[CANCEL] Cancelling message:', messageId);
|
||||
setStatus('Cancelling...');
|
||||
|
||||
// Close any active SSE streams for this message
|
||||
if (state.activeStreams.has(messageId)) {
|
||||
const stream = state.activeStreams.get(messageId);
|
||||
stream.close();
|
||||
state.activeStreams.delete(messageId);
|
||||
console.log('[CANCEL] Closed SSE stream for message:', messageId);
|
||||
}
|
||||
|
||||
// Find and update the message status
|
||||
const session = state.sessions.find(s => s.id === sessionId);
|
||||
if (session) {
|
||||
const message = session.messages.find(m => m.id === messageId);
|
||||
if (message) {
|
||||
message.status = 'cancelled';
|
||||
message.reply = message.reply || '(Cancelled by user)';
|
||||
message.cancelled = true;
|
||||
|
||||
// Show undo/redo buttons for the cancelled message
|
||||
message.showUndoRedo = true;
|
||||
|
||||
console.log('[CANCEL] Message marked as cancelled:', messageId);
|
||||
}
|
||||
|
||||
// Remove temp messages
|
||||
const tempMessages = session.messages.filter(m => m.id.startsWith('temp-') && m.status === 'queued');
|
||||
tempMessages.forEach(tempMsg => {
|
||||
const idx = session.messages.indexOf(tempMsg);
|
||||
if (idx > -1) {
|
||||
session.messages.splice(idx, 1);
|
||||
}
|
||||
});
|
||||
|
||||
renderMessages(session);
|
||||
}
|
||||
|
||||
// Reset sending state
|
||||
state.isSending = false;
|
||||
state.currentSendingMessageId = null;
|
||||
|
||||
// Reset send button
|
||||
updateSendButtonState();
|
||||
|
||||
hideLoadingIndicator();
|
||||
setStatus('Message cancelled');
|
||||
|
||||
// Refresh session to sync with server
|
||||
try {
|
||||
await refreshCurrentSession();
|
||||
} catch (err) {
|
||||
console.warn('[CANCEL] Failed to refresh session:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Update send button appearance based on state
|
||||
function updateSendButtonState() {
|
||||
const btn = el.miniSendBtn;
|
||||
if (!btn) return;
|
||||
|
||||
if (state.isSending) {
|
||||
// Show cancel button (square icon)
|
||||
btn.innerHTML = `
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="6" y="6" width="12" height="12" rx="2" ry="2"></rect>
|
||||
</svg>
|
||||
`;
|
||||
btn.title = 'Cancel message';
|
||||
btn.classList.add('cancel-mode');
|
||||
btn.disabled = false;
|
||||
} else {
|
||||
// Show send button (paper plane icon)
|
||||
btn.innerHTML = `
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="22" y1="2" x2="11" y2="13"></line>
|
||||
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
||||
</svg>
|
||||
`;
|
||||
btn.title = 'Send message';
|
||||
btn.classList.remove('cancel-mode');
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle send button click - either send or cancel
|
||||
function handleSendButtonClick(e) {
|
||||
if (state.isSending) {
|
||||
// Cancel the current message
|
||||
cancelMessage();
|
||||
} else {
|
||||
// Check if we're in plan mode and call the appropriate handler
|
||||
if (builderState.mode === 'plan') {
|
||||
// Use handleSend from builder.html which handles plan mode
|
||||
if (typeof handleSend === 'function') {
|
||||
handleSend(e);
|
||||
} else {
|
||||
console.warn('[BUILDER] handleSend not available');
|
||||
}
|
||||
} else {
|
||||
// Send a new message in build mode
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expose for builder.html
|
||||
window.sendMessage = sendMessage;
|
||||
window.cancelMessage = cancelMessage;
|
||||
window.handleSendButtonClick = handleSendButtonClick;
|
||||
|
||||
function hookEvents() {
|
||||
if (el.newChat) {
|
||||
@@ -4205,7 +4346,11 @@ function hookEvents() {
|
||||
|
||||
el.messageInput.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
||||
sendMessage();
|
||||
if (state.isSending) {
|
||||
cancelMessage();
|
||||
} else {
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user