feat(conversation): cheap-default DeepSeek + Enter-send + model pill
- default-interactive@1 model: claude-haiku-4-5 → deepseek/deepseek-chat (input $0.28/$1.12 per 1M; haiku 대비 ~75% 절감). fallback 은 haiku 로 swap. - conversation textarea keydown: - Enter → 전송 (IME composition 중이면 무시) - Shift+Enter → 줄바꿈 - Cmd/Ctrl+Enter → 전송 (백워드 호환) - Placeholder 안내 갱신. - conversation top-bar 에 model pill 추가 (#session-model-pill) — 현재 세션의 활성 model 을 monospace badge 로 표시. 헷갈리던 "어느 모델인가?" 해소. - style.css 에 .conv-model-pill (회색 pill). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,8 @@ name: default-interactive
|
|||||||
version: 1
|
version: 1
|
||||||
description: "interactive 모드 만능 어시스턴트. 탐색·수정·실행 모두 지원."
|
description: "interactive 모드 만능 어시스턴트. 탐색·수정·실행 모두 지원."
|
||||||
backend: openrouter
|
backend: openrouter
|
||||||
model: "openrouter:anthropic/claude-haiku-4-5"
|
model: "openrouter:deepseek/deepseek-chat"
|
||||||
provider_origin: "US/Anthropic"
|
provider_origin: "CN/DeepSeek"
|
||||||
capabilities:
|
capabilities:
|
||||||
- spec_write
|
- spec_write
|
||||||
- code_edit
|
- code_edit
|
||||||
@@ -42,7 +42,7 @@ allowed_tools:
|
|||||||
- write_todos
|
- write_todos
|
||||||
- task
|
- task
|
||||||
deepagents_backend: local_shell
|
deepagents_backend: local_shell
|
||||||
fallback_model: "openrouter:deepseek/deepseek-chat"
|
fallback_model: "openrouter:anthropic/claude-haiku-4-5"
|
||||||
max_cost_per_call_usd: 0.05
|
max_cost_per_call_usd: 0.05
|
||||||
model_params:
|
model_params:
|
||||||
max_tokens: 2048
|
max_tokens: 2048
|
||||||
|
|||||||
@@ -757,6 +757,21 @@ function updateSessionStatePill(state) {
|
|||||||
pill.className = `conv-session-state state-${state}`;
|
pill.className = `conv-session-state state-${state}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateSessionModelPill(model) {
|
||||||
|
const pill = $conv("#session-model-pill");
|
||||||
|
if (!pill) return;
|
||||||
|
if (!model) {
|
||||||
|
pill.textContent = "";
|
||||||
|
pill.className = "conv-model-pill";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Trim the "openrouter:" prefix for display; keep full id in tooltip.
|
||||||
|
const display = model.replace(/^openrouter:/, "");
|
||||||
|
pill.textContent = display;
|
||||||
|
pill.title = `model: ${model}`;
|
||||||
|
pill.className = "conv-model-pill";
|
||||||
|
}
|
||||||
|
|
||||||
async function loadSessionList() {
|
async function loadSessionList() {
|
||||||
try {
|
try {
|
||||||
const list = await jsonFetch("/sessions?limit=50");
|
const list = await jsonFetch("/sessions?limit=50");
|
||||||
@@ -797,6 +812,7 @@ async function loadAndAttachSession(sessionId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateSessionStatePill(detail.session.state);
|
updateSessionStatePill(detail.session.state);
|
||||||
|
updateSessionModelPill(detail.session.model);
|
||||||
|
|
||||||
const messages = detail.messages || [];
|
const messages = detail.messages || [];
|
||||||
for (const m of messages) {
|
for (const m of messages) {
|
||||||
@@ -968,17 +984,14 @@ async function bootstrapConversationPage() {
|
|||||||
setTimeout(() => { input._composing = false; }, 0);
|
setTimeout(() => { input._composing = false; }, 0);
|
||||||
});
|
});
|
||||||
input.addEventListener("keydown", (ev) => {
|
input.addEventListener("keydown", (ev) => {
|
||||||
// Honor Cmd/Ctrl+Enter as explicit "send" override even during composition.
|
if (ev.key !== "Enter") return;
|
||||||
if ((ev.metaKey || ev.ctrlKey) && ev.key === "Enter") {
|
// Shift+Enter → newline (let the textarea handle it natively).
|
||||||
|
if (ev.shiftKey) return;
|
||||||
|
// IME composition (Korean/Japanese/Chinese candidate commit) → never send.
|
||||||
|
if (input._composing) return;
|
||||||
|
// Plain Enter (and Cmd/Ctrl+Enter for backwards compat) → send.
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
sendMessage(ev.target.value);
|
sendMessage(ev.target.value);
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Plain Enter during composition (e.g. Korean IME committing 한글) must
|
|
||||||
// pass through to the textarea — do nothing.
|
|
||||||
if (ev.key === "Enter" && input._composing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// v0.3 PR #8: deep link `?session=<id>` auto-loads the named session.
|
// v0.3 PR #8: deep link `?session=<id>` auto-loads the named session.
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
<option value="">(세션 선택…)</option>
|
<option value="">(세션 선택…)</option>
|
||||||
</select>
|
</select>
|
||||||
<button id="new-session-btn" type="button" class="conv-action-btn">새 대화</button>
|
<button id="new-session-btn" type="button" class="conv-action-btn">새 대화</button>
|
||||||
|
<span class="conv-model-pill" id="session-model-pill" title="이 세션의 활성 모델"></span>
|
||||||
<span class="conv-session-state" id="session-state-pill"></span>
|
<span class="conv-session-state" id="session-state-pill"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@
|
|||||||
<textarea
|
<textarea
|
||||||
id="message-input"
|
id="message-input"
|
||||||
rows="2"
|
rows="2"
|
||||||
placeholder="메시지를 입력하세요… (Cmd/Ctrl+Enter 로 전송)"
|
placeholder="메시지를 입력하세요… (Enter 전송, Shift+Enter 줄바꿈)"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
disabled
|
disabled
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|||||||
@@ -1211,3 +1211,13 @@ details[open] summary {
|
|||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conv-model-pill {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 11.5px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(0, 0, 0, 0.06);
|
||||||
|
color: var(--text-muted);
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user