Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions crates/agent-gateway/web/src/app/GatewayApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import {
updateRightDockWidth,
updateSkills,
updateSshProjectHostIds,
updateSystem,
type WorkspaceProject,
workspaceProjectPathKey,
} from "@/lib/settings";
Expand Down Expand Up @@ -4114,6 +4115,20 @@ export default function GatewayApp() {
>
<ChatHeader
settings={settings}
onSelectExecutionMode={(mode) =>
setSettings((prev) => {
const current = prev.system.executionMode;
if (mode === "text") {
return current === "text"
? prev
: updateSystem(prev, { executionMode: "text" });
}
// 切回 Agent:仅从 Chat 切换;agent-dev 视为 Agent,保持不降级。
return current === "text"
? updateSystem(prev, { executionMode: "tools" })
: prev;
})
}
hasModels={modelOptions.length > 0}
currentModelLabel={currentModelLabel}
modelOptions={modelOptions}
Expand Down
2 changes: 2 additions & 0 deletions crates/agent-gateway/web/src/i18n/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export const translations: Record<Locale, Record<string, string>> = {
"chat.expandProvider": "展开该提供商的模型",
"chat.collapseProvider": "收起该提供商的模型",
"chat.searchModel": "搜索模型...",
"chat.executionModeHint": "切换对下一条消息生效,当前对话继续",
"chat.noModelFound": "未找到匹配的模型",
"chat.aborted": "已取消",
"chat.contextWindow": "上下文窗口",
Expand Down Expand Up @@ -2027,6 +2028,7 @@ export const translations: Record<Locale, Record<string, string>> = {
"chat.expandProvider": "Expand provider models",
"chat.collapseProvider": "Collapse provider models",
"chat.searchModel": "Search models...",
"chat.executionModeHint": "Applies from the next message; the conversation continues",
"chat.noModelFound": "No matching models found",
"chat.aborted": "Cancelled",
"chat.contextWindow": "Context Window",
Expand Down
48 changes: 17 additions & 31 deletions crates/agent-gateway/web/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -1217,52 +1217,37 @@
}

/* Chat header model selector: grow out of the trigger with a soft slide.
* Radix keeps the popup mounted while the data-state="closed" animation
* plays, so exit stays keyframe-driven; `forwards` holds the final frame
* until unmount. */
* Base UI drives the popup lifecycle, so enter/exit are keyed off
* data-starting-style / data-ending-style and the transition delays
* unmount. */
.model-selector-dropdown {
/* Slide from the anchor side; flipped placement overrides per data-side. */
--model-menu-slide-y: -6px;
transform-origin: var(--radix-dropdown-menu-content-transform-origin, top left);
transform-origin: var(--transform-origin);
transition:
opacity 0.18s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}

.model-selector-dropdown[data-side="top"] {
--model-menu-slide-y: 6px;
}

.model-selector-dropdown[data-state="open"] {
animation: modelSelectorDropdownIn 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}

.model-selector-dropdown[data-state="closed"] {
animation: modelSelectorDropdownOut 0.12s cubic-bezier(0.4, 0, 1, 1) forwards;
}

@keyframes modelSelectorDropdownIn {
from {
opacity: 0;
transform: translateY(var(--model-menu-slide-y)) scale(0.96);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
.model-selector-dropdown[data-starting-style],
.model-selector-dropdown[data-ending-style] {
opacity: 0;
transform: translateY(var(--model-menu-slide-y)) scale(0.96);
}

@keyframes modelSelectorDropdownOut {
from {
opacity: 1;
transform: translateY(0) scale(1);
}
to {
opacity: 0;
transform: translateY(calc(var(--model-menu-slide-y) / 2)) scale(0.98);
}
.model-selector-dropdown[data-ending-style] {
transition-duration: 0.12s;
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
transform: translateY(calc(var(--model-menu-slide-y) / 2)) scale(0.98);
}

/* `backwards` (not `both`): a filled forwards animation would keep holding
* transform after it ends and suppress the item highlight translate. */
.model-selector-dropdown[data-state="open"] .model-selector-item {
.model-selector-dropdown[data-open] .model-selector-item {
animation: modelSelectorItemIn 0.18s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

Expand All @@ -1289,6 +1274,7 @@

.composer-reasoning-trigger,
.composer-reasoning-trigger > svg:last-child,
.model-selector-dropdown,
.model-selector-trigger,
.model-selector-trigger svg {
transition: none !important;
Expand Down
Loading
Loading