Refine onboarding model setup flow

Remove composer blocking so sends always create or enter a chat and route missing-model messages through the in-thread gate.

Make Utility model selection explicit by removing same-as-main sync and defaulting to each provider's utility model when available.

Compact onboarding success channel cards and update static regressions for the new onboarding/gate behavior.
This commit is contained in:
Alessandro 2026-07-02 15:48:03 +02:00
parent 8d887e6f6d
commit caf5c2f129
9 changed files with 30 additions and 123 deletions

View file

@ -46,8 +46,7 @@
<div id="chat-buttons-wrapper">
<!-- Send button -->
<button class="chat-button" id="send-button" aria-label="Send message" @click="$store.chatInput.sendMessage()"
:class="$store.chatInput.sendButtonClass" :title="$store.chatInput.sendButtonTitle"
:disabled="$store.chatInput.sendDisabled">
:class="$store.chatInput.sendButtonClass" :title="$store.chatInput.sendButtonTitle">
<span class="material-symbols-outlined" x-text="$store.chatInput.sendButtonIcon"></span>
</button>
</div>
@ -388,14 +387,6 @@
filter: none;
}
#send-button.model-gate-blocked,
#send-button.model-gate-blocked:hover {
background-color: color-mix(in srgb, var(--color-border) 55%, transparent);
color: color-mix(in srgb, var(--color-text) 45%, transparent);
cursor: not-allowed;
opacity: 0.78;
}
#send-button:active {
background-color: #2b309c;
transform: translateY(1px) scale(0.98);

View file

@ -5,7 +5,6 @@ import { openLatest as openLatestSurface } from "/js/surfaces.js";
import { store as messageQueueStore } from "/components/chat/message-queue/message-queue-store.js";
import { store as attachmentsStore } from "/components/chat/attachments/attachmentsStore.js";
import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
import { store as modelGateStore } from "/components/chat/model-gate-store.js";
const ICON_MARKER_RE = /icon:\/\/([a-zA-Z0-9_]+)(\[(?:\\.|[^\]])*\])?/g;
const FENCE_LINE_RE = /^```([A-Za-z0-9_-]*)?$/;
@ -84,7 +83,6 @@ const model = {
const hasQueue = !!messageQueueStore?.hasQueue;
const running = !!chatsStore.selectedContext?.running;
if (modelGateStore?.isBlockingSend) return "blocked";
if (hasQueue && !hasInput) return "all";
if ((running || hasQueue) && hasInput) return "queue";
return "normal";
@ -93,7 +91,6 @@ const model = {
get inputPlaceholder() {
if (!chatsStore.selected) return "Ask anything to start a new chat";
const state = this._getSendState();
if (state === "blocked") return "Connect a model to send";
if (state === "all") return "Press Enter to send queued messages";
if (this.showProgressPlaceholder) return "";
return "Type your message here...";
@ -102,7 +99,7 @@ const model = {
get showProgressPlaceholder() {
return (
!!chatsStore.selected &&
!["all", "blocked"].includes(this._getSendState()) &&
this._getSendState() !== "all" &&
!!this.progressText &&
!this.message
);
@ -118,7 +115,6 @@ const model = {
// Computed: send button icon type
get sendButtonIcon() {
const state = this._getSendState();
if (state === "blocked") return "settings";
if (state === "all") return "send_and_archive";
if (state === "queue") return "schedule_send";
return "arrow_forward";
@ -127,7 +123,6 @@ const model = {
// Computed: send button CSS class
get sendButtonClass() {
const state = this._getSendState();
if (state === "blocked") return "model-gate-blocked";
if (state === "all") return "send-queue send-all";
if (state === "queue") return "send-queue queue";
return "";
@ -136,23 +131,17 @@ const model = {
// Computed: send button title
get sendButtonTitle() {
const state = this._getSendState();
if (state === "blocked") return "Connect a model to send";
if (state === "all") return "Send all queued messages";
if (state === "queue") return "Add to queue";
return "Send message";
},
get sendDisabled() {
return this._getSendState() === "blocked";
},
init() {
console.log("Input store initialized");
// Event listeners are now handled via Alpine directives in the component
},
async sendMessage() {
if (this.sendDisabled) return;
this._syncMessageFromEditor();
// Capture sent prompt to per-chat history (bash-style)

View file

@ -21,13 +21,6 @@ export const store = createStore("modelGate", {
dispatching: false,
_initialized: false,
get isBlockingSend() {
this.init();
if (!this.active || this.connected) return false;
const currentContext = globalThis.getContext?.();
return !this.pending?.context || !currentContext || this.pending.context === currentContext;
},
get introText() {
if (this.connected) {
return `Model connected: ${this.connectedLabel || "ready"}`;

View file

@ -42,8 +42,6 @@ let skipOneSpeech = false;
export async function sendMessage(options = {}) {
try {
if (!options.bypassModelGate && modelGateStore.isBlockingSend) return;
const hasProvidedMessage = Object.prototype.hasOwnProperty.call(options, "message");
let message = String(hasProvidedMessage ? options.message : inputStore.message).trim();
let attachmentsWithUrls = options.attachments || attachmentsStore.getAttachmentsForSending();