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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* gets called first.
*/
import { useState } from "react";
import { Select } from "../../ui";
import { Select, Tooltip } from "../../ui";
import { IconInfo } from "../../icons";
import type { TKey } from "../../i18n/shared";
import { useT } from "../../i18n/shared";
import { formatNamespacedModelId } from "../../provider-icons";
import type { DelegationPatch, DelegationModelOption } from "../../pages/use-subagent-delegation";
Expand Down Expand Up @@ -63,6 +65,46 @@ export default function SubagentDelegationSection({
</button>
</div>
)}
{/*
The multi-agent surface switch (v1 / base / v2). It lived on Models and on the
dashboard; both were editors for the same /api/v2 value. It is a delegation
setting, so it sits above the model that gets delegated to. The long help text
stays reachable from the focusable info button.
*/}
<div className="swi-delegation-row">
<div className="setting-copy">
<div className="font-semibold" style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
{t("models.v2Label")}
<Tooltip content={t("models.v2Help")} side="top" maxWidth={380}>
<IconInfo width={13} height={13} aria-hidden="true" />
<span className="sr-only">{t("models.v2Label")}</span>
</Tooltip>
</div>
<div className="muted setting-hint">
<a className="text-control" href="https://opencodex.me/guides/sub-agent-surface/" target="_blank" rel="noreferrer" style={{ color: "var(--accent)" }}>
{t("models.v2DocsLink")}
</a>
</div>
</div>
<div className="swi-delegation-controls">
<div className="segmented models-segmented" role="radiogroup" aria-label={t("models.v2Label")}>
{(["v1", "default", "v2"] as const).map(mode => (
<button
key={mode}
type="button"
role="radio"
aria-checked={ultraMode.multiAgentMode === mode}
className={`btn btn-sm${ultraMode.multiAgentMode === mode ? " btn-primary" : " btn-ghost"}`}
style={{ background: ultraMode.multiAgentMode === mode ? undefined : "transparent", color: ultraMode.multiAgentMode === mode ? undefined : "var(--muted)" }}
disabled={ultraSaving || ultraLoadFailed}
onClick={() => { if (ultraMode.multiAgentMode !== mode) onUltraModeSave({ multiAgentMode: mode }); }}
>
{t(`models.v2Mode_${mode}` as TKey)}
</button>
))}
</div>
</div>
</div>
<div className="swi-delegation-row">
<div className="setting-copy">
<div className="font-semibold">{t("sub.delegation.model")}</div>
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ export const de: Record<TKey, string> = {
"models.subtitle.combos": "Geordnete Modellgruppen, die unter einer id antworten. Ziele mit Failover verketten oder die Last mit einer Balancing-Strategie verteilen.",
"models.subtitle.compatibility": "Schreibgeschützte Kompatibilitätsmatrix aus der Lab-Projektion.",
"models.subtitle.routing": "Policy-Profile, Dry-Run-Auswertung und quellenbasierte Routing-Analysen.",
"models.advanced": "Erweitert",
"models.groupMore": "Weitere Anbieteraktionen anzeigen",
"models.subtitleAria": "So funktioniert der Katalog",
"models.orderHintAria": "So wird die Reihenfolge im Picker bestimmt",
"models.subtitle": "Steuere, welche Modelle Codex sieht — natives GPT-Passthrough und geroutete Anbieter, nach Anbieter gruppiert (Kopfzeile zum Einklappen anklicken). Ausgeblendete Modelle fehlen in Katalog und Auswahl, bleiben aber per genauer ID aufrufbar. Änderungen gelten bei der nächsten Codex-Runde — opencodex invalidiert Codex 5-Minuten-Modell-Cache, kein Neustart nötig.",
"models.nativeGroupLabel": "OpenAI nativ",
"models.nativeHint": "Passthrough-Modelle verwenden die unter Anbieter gewählte Pool- oder Direkt-Option. Ausblenden entfernt sie aus der Codex-Auswahl (Katalogeintrag bleibt, Reaktivierung stellt exakt wieder her). Ein hier hinzugefügtes Modell wird als gerouteter `openai/<model>`-Selektor registriert, nicht als neue reine Passthrough-ID.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ export const en = {
"models.subtitle.combos": "Ordered groups of models that answer as one id. Chain targets with failover or spread the load with a balancing strategy.",
"models.subtitle.compatibility": "Read-only compatibility verdict matrix from lab projection evidence.",
"models.subtitle.routing": "Policy profiles, dry-run evaluation, and source-backed routing analytics.",
"models.advanced": "Advanced",
"models.groupMore": "Show more provider actions",
"models.subtitleAria": "How the catalog works",
"models.orderHintAria": "How picker order is decided",
"models.subtitle": "Toggle which models Codex sees — native GPT passthrough and routed providers, grouped by provider (click a header to collapse). Hidden models stay off the catalog + model picker but remain directly callable by exact id. Changes apply on the next Codex turn — opencodex invalidates Codex's 5-min model cache so no restart is needed.",
"models.nativeGroupLabel": "OpenAI native",
"models.nativeHint": "Passthrough models use the Pool or Direct account option selected on Providers. Toggling one off hides it from the Codex picker (the catalog entry is kept, so re-enabling restores it exactly). Adding a model here registers a routed `openai/<model>` selector, not a new bare passthrough id.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,10 @@ export const fr: Record<TKey, string> = {
"models.subtitle.combos": "Groupes ordonnés de modèles qui répondent sous un même identifiant. Enchaînez les cibles avec le repli ou répartissez la charge avec une stratégie d’équilibrage.",
"models.subtitle.compatibility": "Matrice en lecture seule des verdicts de compatibilité issus des preuves de projection du laboratoire.",
"models.subtitle.routing": "Profils de stratégie, évaluation à blanc et analyses de routage fondées sur les sources.",
"models.advanced": "Avancé",
"models.groupMore": "Afficher plus d’actions du fournisseur",
"models.subtitleAria": "Fonctionnement du catalogue",
"models.orderHintAria": "Comment l’ordre du sélecteur est décidé",
"models.subtitle": "Choisissez les modèles visibles par Codex — accès direct aux GPT natifs et fournisseurs routés, regroupés par fournisseur (cliquez sur un en-tête pour le réduire). Les modèles masqués sont retirés du catalogue et du sélecteur, mais restent directement accessibles par leur identifiant exact. Les modifications s’appliquent au prochain tour Codex — opencodex invalide le cache de modèles de Codex de 5 min, sans nécessiter de redémarrage.",
"models.nativeGroupLabel": "OpenAI natif",
"models.nativeHint": "Les modèles en accès direct utilisent l’option de compte Groupe ou Direct sélectionnée dans Fournisseurs. La désactivation d’un modèle le masque dans le sélecteur Codex (son entrée de catalogue est conservée afin que sa réactivation la restaure à l’identique). Ajouter un modèle ici enregistre un sélecteur routé `openai/<model>`, et non un nouvel identifiant passthrough brut.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ export const ja: Record<TKey, string> = {
"models.subtitle.combos": "複数のモデルを 1 つの id にまとめ、順に応答させます。failover でターゲットを連鎖させるか、分散戦略で負荷を分散します。",
"models.subtitle.compatibility": "ラボ投影証拠の読み取り専用互換性判定マトリクス。",
"models.subtitle.routing": "ポリシープロファイル、dry-run 評価、そして根拠の残るルーティング分析です。",
"models.advanced": "詳細設定",
"models.groupMore": "プロバイダーのその他の操作を表示",
"models.subtitleAria": "カタログの仕組み",
"models.orderHintAria": "ピッカー順序の決まり方",
"models.subtitle": "Codex に表示するモデルを切り替えます — ネイティブ GPT パススルーとルーティングプロバイダー、プロバイダー別(ヘッダーをクリックで折りたたみ)。非表示モデルはカタログとピッカーから外れますが、正確な id での直接呼び出しは可能です。変更は次回の Codex ターンで適用 — opencodex は Codex の 5 分間モデルキャッシュを無効化するので再起動は不要です。",
"models.nativeGroupLabel": "OpenAI ネイティブ",
"models.nativeHint": "パススルーモデルはプロバイダーで選択したプールまたはダイレクトアカウントオプションを使用します。一つオフにすると Codex ピッカーから隠します(カタログエントリは保持されるので、再有効化で正確に復元されます)。 ここでモデルを追加すると、bare passthrough id ではなくルーティングされた `openai/<model>` セレクタとして登録されます。",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@ export const ko: Record<TKey, string> = {
"models.subtitle.combos": "여러 모델을 하나의 id로 묶어 순서대로 응답하게 합니다. failover로 대상을 연결하거나 분산 전략으로 부하를 나눕니다.",
"models.subtitle.compatibility": "랩 프로젝션 증거의 읽기 전용 호환성 판정 행렬.",
"models.subtitle.routing": "정책 프로필, dry-run 평가, 그리고 근거가 남는 라우팅 분석입니다.",
"models.advanced": "고급",
"models.groupMore": "프로바이더 추가 작업 표시",
"models.subtitleAria": "카탈로그 동작 방식",
"models.orderHintAria": "피커 순서가 정해지는 방식",
"models.subtitle": "Codex가 보는 모델을 켜고 끕니다 — 네이티브 GPT passthrough와 라우팅된 모델을 프로바이더별로 묶어 보여줍니다(헤더를 클릭하면 접힘). 숨긴 모델은 카탈로그와 선택기에서 빠지지만 정확한 id로 직접 호출할 수 있습니다. 변경 사항은 다음 Codex 턴에 적용됩니다 — opencodex가 Codex의 5분 모델 캐시를 무효화하므로 재시작이 필요 없습니다.",
"models.nativeGroupLabel": "OpenAI 네이티브",
"models.nativeHint": "프로바이더에서 선택한 풀 또는 직접 계정 옵션으로 서빙되는 passthrough 모델입니다. 끄면 Codex 선택기에서 숨겨지고, 카탈로그 항목은 유지되므로 다시 켜면 그대로 복원됩니다. 여기서 모델을 추가하면 bare passthrough id가 아니라 라우팅된 `openai/<model>` selector로 등록됩니다.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,10 @@ export const ru: Record<TKey, string> = {
"models.subtitle.combos": "Упорядоченные группы моделей, отвечающие под одним id. Связывайте цели через failover или распределяйте нагрузку стратегией балансировки.",
"models.subtitle.compatibility": "Матрица совместимости только для чтения из проекции лаборатории.",
"models.subtitle.routing": "Профили политик, оценка в режиме dry-run и аналитика маршрутизации с подтверждением источников.",
"models.advanced": "Дополнительно",
"models.groupMore": "Показать дополнительные действия провайдера",
"models.subtitleAria": "Как работает каталог",
"models.orderHintAria": "Как определяется порядок в выборе",
"models.subtitle": "Управляйте тем, какие модели видит Codex — нативные GPT (сквозной проброс) и модели маршрутизируемых провайдеров, сгруппированные по провайдеру (нажмите на заголовок, чтобы свернуть группу). Скрытые модели исчезают из каталога и селектора, но остаются вызываемыми по точному id. Изменения применяются на следующем ходе Codex — opencodex сбрасывает 5-минутный кэш моделей Codex, поэтому перезапуск не требуется.",
"models.nativeGroupLabel": "Нативные OpenAI",
"models.nativeHint": "Модели сквозного проброса используют режим аккаунта (пул или прямое подключение), выбранный на странице «Провайдеры». Отключение модели скрывает её из селектора Codex (запись в каталоге сохраняется, поэтому при повторном включении она восстанавливается в точности). Добавление модели здесь регистрирует маршрутизируемый селектор `openai/<model>`, а не новый «голый» passthrough-идентификатор.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@ export const tr: Record<TKey, string> = {
"models.subtitle.combos": "Tek bir kimlik olarak yanıt veren sıralı model grupları. Hedefleri failover ile zincirleyin veya yükü dengeleme stratejisiyle dağıtın.",
"models.subtitle.compatibility": "Lab projeksiyon kanıtından salt okunur uyumluluk matrisi.",
"models.subtitle.routing": "Politika profilleri ve simülasyon değerlendirmesi.",
"models.advanced": "Gelişmiş",
"models.groupMore": "Daha fazla sağlayıcı işlemi göster",
"models.subtitleAria": "Katalog nasıl çalışır",
"models.orderHintAria": "Seçici sırası nasıl belirlenir",
"models.subtitle": "Codex'in göreceği modelleri açıp kapatın.",
"models.nativeGroupLabel": "Yerel OpenAI",
"models.nativeHint": "Doğrudan geçiş modelleri Sağlayıcılar bölümünde seçilen Havuz veya Doğrudan seçeneğini kullanır. Buradan model eklemek, yeni bir düz passthrough kimliği değil, yönlendirilmiş bir `openai/<model>` seçici kaydeder.",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,10 @@ export const zhTW: Record<TKey, string> = {
"prov.manageCodexAccounts": "管理 Codex 帳號",
"prov.openaiApiMissing": "需要 API 金鑰",
"prov.openaiApiSetup": "設定 API 金鑰",
"models.advanced": "進階",
"models.groupMore": "顯示更多供應商操作",
"models.subtitleAria": "目錄的運作方式",
"models.orderHintAria": "選擇器順序的決定方式",
"models.subtitle": "開關 Codex 可見的模型 — 原生 GPT passthrough 與已路由模型按供應商分組(點選標題可摺疊)。已停用的模型會從目錄和模型選擇器中隱藏。更改在下一個 Codex 回合生效 — opencodex 會使 Codex 的 5 分鐘模型快取失效,因此無需重新啟動。",
"models.nativeGroupLabel": "OpenAI 原生",
"models.nativeHint": "Passthrough 模型使用在供應商頁面選擇的帳號池或直連選項。關閉後會從 Codex 選擇器中隱藏(目錄條目保留,重新開啟即可完整恢復)。 在此新增模型會註冊為路由的 `openai/<model>` 選擇器,而非新的裸 passthrough id。",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ export const zh: Record<TKey, string> = {
"models.subtitle.combos": "把多个模型合成一个 id 依次应答。用 failover 串联目标,或用均衡策略分摊负载。",
"models.subtitle.compatibility": "来自实验室投影证据的只读兼容性判定矩阵。",
"models.subtitle.routing": "策略配置、dry-run 评估,以及有据可查的路由分析。",
"models.advanced": "高级",
"models.groupMore": "显示更多提供商操作",
"models.subtitleAria": "目录的工作方式",
"models.orderHintAria": "选择器顺序的决定方式",
"models.subtitle": "开关 Codex 可见的模型 — 原生 GPT passthrough 与已路由模型按提供方分组(点击标题可折叠)。隐藏的模型不会出现在目录和模型选择器中,但仍可按精确 id 直接调用。更改在下一个 Codex 回合生效 — opencodex 会使 Codex 的 5 分钟模型缓存失效,因此无需重启。",
"models.nativeGroupLabel": "OpenAI 原生",
"models.nativeHint": "Passthrough 模型使用在提供方页面选择的账户池或直连选项。关闭后会从 Codex 选择器中隐藏(目录条目保留,重新开启即可完整恢复)。 在此添加模型将注册为路由的 `openai/<model>` 选择器,而不是新的裸 passthrough id。",
Expand Down
Loading
Loading