dsh-llm-fallbacks 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,33 +4,9 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
- //#region \0rolldown/runtime.js
8
- var __create = Object.create;
9
- var __defProp = Object.defineProperty;
10
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
- var __getOwnPropNames = Object.getOwnPropertyNames;
12
- var __getProtoOf = Object.getPrototypeOf;
13
- var __hasOwnProp = Object.prototype.hasOwnProperty;
14
- var __copyProps = (to, from, except, desc) => {
15
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
- key = keys[i];
17
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
- get: ((k) => from[k]).bind(null, key),
19
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
- });
21
- }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
25
- value: mod,
26
- enumerable: true
27
- }) : target, mod));
28
- //#endregion
29
7
  let _deepseek_ai_dsh_client_web_react = require("@deepseek-ai/dsh-client-web-react");
30
8
  let react = require("react");
31
9
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
32
- let _deepseek_ai_schemastery = require("@deepseek-ai/schemastery");
33
- _deepseek_ai_schemastery = __toESM(_deepseek_ai_schemastery, 1);
34
10
  let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
35
11
  let react_jsx_runtime = require("react/jsx-runtime");
36
12
  //#region src/selectors.ts
@@ -65,32 +41,6 @@ window.__ModuleLoader__.load({
65
41
  //#endregion
66
42
  //#region src/config.ts
67
43
  /**
68
- * The `fallbacks` settings namespace: plugin config schema + defaults.
69
- *
70
- * Two-block config model (plan fallbacks-role-config-model): block 1
71
- * `rootChain` — the root agent's single fallback chain (empty = no
72
- * degradation) — plus block 2 declared role entities: `roles.list`
73
- * (id/label/description/prompt?/permissions?/chain?/fallback) and
74
- * `roles.rules` enum references into the declared ids (or the built-in
75
- * `'inherit'` role). The legacy `chains` / `roles.default` keys are gone
76
- * from the schema and type (zero residual, migration table excepted); the
77
- * runtime consumes the new shape directly and flags surviving legacy keys
78
- * at startup via `detectLegacyKeys` (see `src/index.ts` apply()).
79
- *
80
- * Spec §4 is authoritative for field names and default values — notably
81
- * `triggerCodes` defaults to dsh's stable failure codes `['AUTH', 'QUOTA',
82
- * 'RATE_LIMIT']` (there is no `QUOTA_EXCEEDED` code in dsh), and an
83
- * unconfigured install (`enabled: false`, empty `rootChain`, empty roles)
84
- * is a no-op pass-through exactly like an uninstalled plugin (AC-8).
85
- *
86
- * This module is pure logic: it must not import any `@deepseek-ai/*` package
87
- * (types included) — `FallbacksConfig` is the plugin's own type. Task 3
88
- * registers this schema with `installSettingsSection` under the `fallbacks`
89
- * settings namespace.
90
- *
91
- * @module dsh-llm-fallbacks/config
92
- */
93
- /**
94
44
  * Spec §4 defaults — `Config({})` must equal this (no-op install).
95
45
  * `enabled` defaults to `false` (readme-settings spec §1.2): the feature
96
46
  * switch is off until the user turns it on in the settings page; an
@@ -121,42 +71,6 @@ window.__ModuleLoader__.load({
121
71
  const INHERIT_ROLE_ID = "inherit";
122
72
  /** Role id format (aligned with yet-another-subagent `isValidProfileId`). */
123
73
  const ROLE_ID_PATTERN = /^[a-z0-9-]{1,32}$/;
124
- _deepseek_ai_schemastery.default.object({
125
- enabled: _deepseek_ai_schemastery.default.boolean().default(false),
126
- triggerCodes: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.string()).default([
127
- "AUTH",
128
- "QUOTA",
129
- "RATE_LIMIT"
130
- ]),
131
- rootChain: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.string()).default([]),
132
- roles: _deepseek_ai_schemastery.default.object({
133
- list: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.object({
134
- id: _deepseek_ai_schemastery.default.string().required(),
135
- label: _deepseek_ai_schemastery.default.string().default(""),
136
- description: _deepseek_ai_schemastery.default.string().default(""),
137
- prompt: _deepseek_ai_schemastery.default.string(),
138
- permissions: _deepseek_ai_schemastery.default.object({
139
- allow: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.string()),
140
- deny: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.string())
141
- }),
142
- chain: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.string()),
143
- fallback: _deepseek_ai_schemastery.default.union([_deepseek_ai_schemastery.default.const("inherit-root"), _deepseek_ai_schemastery.default.const("none")]).default("inherit-root")
144
- })).default([]),
145
- rules: _deepseek_ai_schemastery.default.array(_deepseek_ai_schemastery.default.object({
146
- origin: _deepseek_ai_schemastery.default.union([_deepseek_ai_schemastery.default.const("root"), _deepseek_ai_schemastery.default.const("subagent")]),
147
- provider: _deepseek_ai_schemastery.default.string(),
148
- model: _deepseek_ai_schemastery.default.string(),
149
- role: _deepseek_ai_schemastery.default.string().required()
150
- })).default([])
151
- }).default({
152
- list: [],
153
- rules: []
154
- }),
155
- cooldownMs: _deepseek_ai_schemastery.default.number().default(3e5),
156
- revertPolicy: _deepseek_ai_schemastery.default.union([_deepseek_ai_schemastery.default.const("cooldown-expiry"), _deepseek_ai_schemastery.default.const("never")]).default("cooldown-expiry"),
157
- maxSwitchesPerStep: _deepseek_ai_schemastery.default.number().default(8),
158
- alwaysModeRetryCap: _deepseek_ai_schemastery.default.number().default(5)
159
- });
160
74
  //#endregion
161
75
  //#region src/client/fallbacks-store.ts
162
76
  /** The plugin's settings namespace on the host wire (settings/document-updated ns filter). */
@@ -215,10 +129,8 @@ window.__ModuleLoader__.load({
215
129
  const roles = isRecord(value.roles) ? value.roles : {};
216
130
  const parsedList = (Array.isArray(roles.list) ? roles.list : []).map((role, index) => {
217
131
  if (!isRecord(role) || typeof role.id !== "string") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}] must have a string id`);
218
- const label = role.label;
219
- if (label !== void 0 && typeof label !== "string") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}].label must be a string`);
220
- const description = role.description;
221
- if (description !== void 0 && typeof description !== "string") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}].description must be a string`);
132
+ const persona = role.persona;
133
+ if (persona !== void 0 && typeof persona !== "string") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}].persona must be a string`);
222
134
  const prompt = role.prompt;
223
135
  if (prompt !== void 0 && typeof prompt !== "string") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}].prompt must be a string`);
224
136
  const permissions = role.permissions;
@@ -229,8 +141,7 @@ window.__ModuleLoader__.load({
229
141
  if (fallback !== void 0 && fallback !== "inherit-root" && fallback !== "none") throw new TypeError(`fallbacks descriptor roles.list[${String(index)}].fallback must be inherit-root|none`);
230
142
  return {
231
143
  id: role.id,
232
- label: label ?? "",
233
- description: description ?? "",
144
+ persona: persona ?? "",
234
145
  ...prompt === void 0 ? {} : { prompt },
235
146
  ...permissions === void 0 ? {} : { permissions },
236
147
  chain: chain ?? [],
@@ -421,8 +332,7 @@ window.__ModuleLoader__.load({
421
332
  function rolesToRows(roles, catalog) {
422
333
  return roles.map((role) => ({
423
334
  id: role.id,
424
- label: role.label,
425
- description: role.description,
335
+ persona: role.persona,
426
336
  selectors: (role.chain ?? []).map((entry) => entryToSelectorRow(entry, catalog)),
427
337
  fallback: role.fallback ?? "inherit-root"
428
338
  }));
@@ -431,8 +341,7 @@ window.__ModuleLoader__.load({
431
341
  function rowsToRoles(rows) {
432
342
  return rows.map((row) => ({
433
343
  id: row.id.trim(),
434
- label: row.label,
435
- description: row.description,
344
+ persona: row.persona,
436
345
  chain: row.selectors.map(selectorRowToRaw).filter((entry) => entry !== ""),
437
346
  fallback: row.fallback
438
347
  }));
@@ -454,8 +363,7 @@ window.__ModuleLoader__.load({
454
363
  if (original === void 0) return role;
455
364
  return {
456
365
  id: role.id,
457
- label: role.label,
458
- description: role.description,
366
+ persona: role.persona,
459
367
  ...original.prompt === void 0 ? {} : { prompt: original.prompt },
460
368
  ...original.permissions === void 0 ? {} : { permissions: original.permissions },
461
369
  chain: role.chain,
@@ -512,7 +420,14 @@ window.__ModuleLoader__.load({
512
420
  switchesError: null,
513
421
  switches: []
514
422
  });
515
- generation = 0;
423
+ /** Read guard: a newer load() supersedes an older one's publish. */
424
+ readGeneration = 0;
425
+ /**
426
+ * Write guard: save()/resetToDefaults() completions ALWAYS publish unless
427
+ * dispose() invalidated them — an overlapping read must never discard a
428
+ * successful write's accept() (audit F1).
429
+ */
430
+ writeGeneration = 0;
516
431
  catalogGeneration = 0;
517
432
  switchesGeneration = 0;
518
433
  /** Every settings namespace from the last describe, keyed by ns — the configured-provider join's other input. */
@@ -543,14 +458,16 @@ window.__ModuleLoader__.load({
543
458
  * @returns nothing; {@link store} carries success or failure.
544
459
  */
545
460
  async load() {
546
- const generation = ++this.generation;
461
+ const generation = ++this.readGeneration;
462
+ const writeGenerationAtStart = this.writeGeneration;
547
463
  this.store.update((state) => {
548
464
  state.status = "loading";
549
465
  state.error = null;
550
466
  });
551
467
  try {
552
468
  const [describeResult, getResult] = await Promise.all([this.api.settings.describe({}), this.rpc.call("/api", "fallbacks/get", { args: {} }).catch(() => void 0)]);
553
- if (generation !== this.generation) return;
469
+ if (generation !== this.readGeneration) return;
470
+ if (writeGenerationAtStart !== this.writeGeneration) return;
554
471
  if (!describeResult.result.ok) throw describeResult.result.error;
555
472
  this.namespaces = new Map(describeResult.result.value.namespaces.map((entry) => [entry.ns, entry]));
556
473
  const writable = describeResult.result.value.writable;
@@ -565,7 +482,8 @@ window.__ModuleLoader__.load({
565
482
  }
566
483
  this.accept(config, writable, legacyKeys);
567
484
  } catch (error) {
568
- if (generation !== this.generation) return;
485
+ if (generation !== this.readGeneration) return;
486
+ if (writeGenerationAtStart !== this.writeGeneration) return;
569
487
  this.fail(error);
570
488
  }
571
489
  }
@@ -682,14 +600,14 @@ window.__ModuleLoader__.load({
682
600
  async save(next) {
683
601
  const state = this.store.getSnapshot();
684
602
  if (!state.writable || state.status === "saving") return;
685
- const generation = ++this.generation;
603
+ const generation = ++this.writeGeneration;
686
604
  this.store.update((draft) => {
687
605
  draft.status = "saving";
688
606
  draft.error = null;
689
607
  });
690
608
  try {
691
609
  const result = await this.rpc.call("/api", "fallbacks/set", { args: { patch: next } });
692
- if (generation !== this.generation) return;
610
+ if (generation !== this.writeGeneration) return;
693
611
  if (!result.ok) throw result.error;
694
612
  const value = result.value;
695
613
  const config = value !== null && typeof value === "object" && "config" in value ? value.config : void 0;
@@ -700,7 +618,7 @@ window.__ModuleLoader__.load({
700
618
  }
701
619
  this.accept(config, true, legacyKeys);
702
620
  } catch (error) {
703
- if (generation !== this.generation) return;
621
+ if (generation !== this.writeGeneration) return;
704
622
  this.fail(error);
705
623
  }
706
624
  }
@@ -713,14 +631,14 @@ window.__ModuleLoader__.load({
713
631
  async resetToDefaults() {
714
632
  const state = this.store.getSnapshot();
715
633
  if (!state.writable || state.status === "saving") return;
716
- const generation = ++this.generation;
634
+ const generation = ++this.writeGeneration;
717
635
  this.store.update((draft) => {
718
636
  draft.status = "saving";
719
637
  draft.error = null;
720
638
  });
721
639
  try {
722
640
  const result = await this.rpc.call("/api", "fallbacks/reset", { args: {} });
723
- if (generation !== this.generation) return;
641
+ if (generation !== this.writeGeneration) return;
724
642
  if (!result.ok) throw result.error;
725
643
  const value = result.value;
726
644
  const config = value !== null && typeof value === "object" && "config" in value ? value.config : void 0;
@@ -731,13 +649,14 @@ window.__ModuleLoader__.load({
731
649
  }
732
650
  this.accept(config, true, legacyKeys);
733
651
  } catch (error) {
734
- if (generation !== this.generation) return;
652
+ if (generation !== this.writeGeneration) return;
735
653
  this.fail(error);
736
654
  }
737
655
  }
738
656
  /** Stop in-flight responses from publishing after plugin disposal. */
739
657
  dispose() {
740
- this.generation += 1;
658
+ this.readGeneration += 1;
659
+ this.writeGeneration += 1;
741
660
  this.catalogGeneration += 1;
742
661
  this.switchesGeneration += 1;
743
662
  this.namespaces = /* @__PURE__ */ new Map();
@@ -850,6 +769,9 @@ window.__ModuleLoader__.load({
850
769
  "alwaysModeRetryCap.label": "always 模式重试上限",
851
770
  "alwaysModeRetryCap.hint": "达到上限次数后切换;0 表示禁用",
852
771
  "alwaysModeRetryCap.tooltip": "retryPolicy 为 always 的模型在同一请求内重试达到该次数后切换;0 表示禁用。",
772
+ "advanced.label": "高级选项",
773
+ "advanced.expand": "展开高级选项",
774
+ "advanced.collapse": "收起高级选项",
853
775
  "rootChain.label": "root 主代理降级链",
854
776
  "rootChain.hint": "未配置 = root 不降级",
855
777
  "rootChain.tooltip": "root 主代理失败时按此有序选择器列表依次降级;未配置时行为与未安装插件一致。",
@@ -857,16 +779,16 @@ window.__ModuleLoader__.load({
857
779
  "chains.selector.remove": "删除该选择器",
858
780
  "chains.selector.providerPlaceholder": "选择 provider",
859
781
  "chains.selector.modelPlaceholder": "选择 model",
860
- "chains.selector.wildcard": "通配该 provider(provider/*)",
861
- "chains.selector.noModels": "该 provider 暂无可用模型(目录查询失败),请使用通配或改选。",
782
+ "chains.selector.wildcardLegacy": "该条目为通配(provider/*):选择具体模型后将转为精确条目",
783
+ "chains.selector.noModelsStrict": "该 provider 暂无可用模型(目录查询失败),请改选其他 provider。",
862
784
  "roles.list.label": "角色实体",
863
785
  "roles.list.hint": "先声明角色,规则才能引用",
864
786
  "roles.list.tooltip": "角色 id 须匹配 /^[a-z0-9-]{1,32}$/ 且唯一;\"inherit\" 为保留字,不能用作角色 id。",
865
787
  "roles.id": "id",
866
788
  "roles.id.hint": "小写字母/数字/连字符,1–32 字符",
867
789
  "roles.idPlaceholder": "例如 reviewer",
868
- "roles.label": "名称",
869
- "roles.description": "描述",
790
+ "roles.persona": "人格提示",
791
+ "roles.personaPlaceholder": "例如:你是资深代码审查员",
870
792
  "roles.fallback": "链拼接策略",
871
793
  "roles.fallback.inherit-root": "继承 root(角色链后追加 rootChain)",
872
794
  "roles.fallback.none": "仅角色链(不追加 rootChain)",
@@ -977,6 +899,9 @@ window.__ModuleLoader__.load({
977
899
  "alwaysModeRetryCap.label": "Always-mode retry cap",
978
900
  "alwaysModeRetryCap.hint": "Switches after the cap; 0 disables",
979
901
  "alwaysModeRetryCap.tooltip": "Models whose retryPolicy is always switch after this many retries within one request; 0 disables.",
902
+ "advanced.label": "Advanced options",
903
+ "advanced.expand": "Show advanced options",
904
+ "advanced.collapse": "Hide advanced options",
980
905
  "rootChain.label": "Root agent fallback chain",
981
906
  "rootChain.hint": "Unset = root does not fall back",
982
907
  "rootChain.tooltip": "When the root agent fails it falls back down this ordered selector list; unset behaves like an uninstalled plugin.",
@@ -984,16 +909,16 @@ window.__ModuleLoader__.load({
984
909
  "chains.selector.remove": "Remove this selector",
985
910
  "chains.selector.providerPlaceholder": "Select provider",
986
911
  "chains.selector.modelPlaceholder": "Select model",
987
- "chains.selector.wildcard": "Wildcard this provider (provider/*)",
988
- "chains.selector.noModels": "No models available for this provider (catalog lookup failed); use the wildcard or pick another provider.",
912
+ "chains.selector.wildcardLegacy": "This entry is a wildcard (provider/*): picking a model converts it to an exact entry",
913
+ "chains.selector.noModelsStrict": "No models available for this provider (catalog lookup failed); pick another provider.",
989
914
  "roles.list.label": "Declared roles",
990
915
  "roles.list.hint": "Declare roles before rules can reference them",
991
916
  "roles.list.tooltip": "Role ids must match /^[a-z0-9-]{1,32}$/ and be unique; \"inherit\" is reserved and cannot be used as a role id.",
992
917
  "roles.id": "ID",
993
918
  "roles.id.hint": "lowercase letters, digits, hyphens; 1–32 chars",
994
919
  "roles.idPlaceholder": "e.g. reviewer",
995
- "roles.label": "Label",
996
- "roles.description": "Description",
920
+ "roles.persona": "Persona",
921
+ "roles.personaPlaceholder": "e.g. you are a senior code reviewer",
997
922
  "roles.fallback": "Chain append",
998
923
  "roles.fallback.inherit-root": "Inherit root (append rootChain after the role chain)",
999
924
  "roles.fallback.none": "Role chain only (no rootChain)",
@@ -1103,7 +1028,7 @@ window.__ModuleLoader__.load({
1103
1028
  }
1104
1029
  //#endregion
1105
1030
  //#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/FallbacksCard.module.css.mjs
1106
- const css$2 = "\n\n\n._8827595f_card {\n list-style: none;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3);\n transition: border-color .16s, background .16s;\n}\n\n._8827595f_card:hover {\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n\n._06704203_cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n\n._e488d460_header {\n width: 100%;\n appearance: none;\n border: 0;\n background: none;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 12px;\n}\n\n._e488d460_header:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n\n._f5dfe084_headText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n._8d39bde6_name {\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--dsw-alias-label-primary);\n}\n\n._346f3b69_description {\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._631094a0_chevron {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n transition: transform .16s;\n}\n\n._44836ce8_chevronOpen {\n transform: rotate(180deg);\n}\n\n\n._dbaa7975_body {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px;\n padding-bottom: 8px;\n}\n\n._4e39cf17_readOnly {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._99bf7f3c_pending {\n flex: none;\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n}\n\n._114985b2_footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 0 4px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n\n\n._9860a5b1_notice {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-business-primary);\n}\n\n\n._5006d43e_legacyNotice {\n margin: 12px 0 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform);\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-business-primary);\n}\n\n._21918751_error {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary);\n}\n\n\n._7cea4b2f_noticeRow {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 12px 0 0;\n}\n\n._7cea4b2f_noticeRow ._21918751_error {\n flex: 1;\n min-width: 0;\n margin: 0;\n}\n\n\n._4058c747_form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px 0 0;\n}\n\n\n._9998065c_checkboxRow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n._02c2f6df_checkLabel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 14px;\n line-height: 22px;\n font-weight: 400;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._f2d47237_checkLabelTitle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 400;\n}\n\n._c1bed8ea_checkLabelDesc {\n font-size: 12px;\n line-height: 18px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._06389b18_checkbox {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n._06389b18_checkbox:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n\n._94c91bfd_fieldset {\n margin: 0;\n padding: 0;\n border: none;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n\n._67826267_field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding: 0;\n border: none;\n min-width: 0;\n}\n\n._13e68c3f_fieldLabel {\n \n display: inline-flex;\n align-items: center;\n gap: 10px;\n padding: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._4bc809b8_hint {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._579f813a_defaultNote {\n font-size: 12px;\n line-height: 18px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._a6244318_infoHint {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n font-size: 14px;\n line-height: 1;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-interactive-bg-hover);\n cursor: help;\n user-select: none;\n}\n\n._a6244318_infoHint:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n\n._e655c840_infoHintDisabled {\n opacity: 0.4;\n cursor: default;\n}\n\n\n._a2521bb0_optionRow {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._a2521bb0_optionRow:hover:has(input:not(:disabled)) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n\n._06389b18_checkbox,\n._a2521bb0_optionRow input,\n._929f3ef3_wildcardCell input {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n._06389b18_checkbox:focus-visible,\n._a2521bb0_optionRow input:focus-visible,\n._929f3ef3_wildcardCell input:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._a2521bb0_optionRow input:disabled,\n._929f3ef3_wildcardCell input:disabled {\n cursor: default;\n}\n\n\n._f9d86f7b_input {\n box-sizing: border-box;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n}\n\n._f9d86f7b_input:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n\n._f9d86f7b_input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n._f9d86f7b_input:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n\n._7b60337a_inputInvalid,\n._7b60337a_inputInvalid:focus {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n\nselect._f9d86f7b_input {\n max-width: 240px;\n cursor: pointer;\n}\n\n\n._16eb7153_selectInput {\n appearance: none;\n padding-right: 32px;\n \n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n background-size: 12px 12px;\n}\n\n\n._3e95886d_numberFields {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 8px;\n}\n\n._0cfb5881_list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n}\n\n\n._f5c620d6_editorCard {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-module-platform);\n}\n\n._224b1387_cardFoot {\n display: flex;\n justify-content: flex-end;\n}\n\n._8e220e07_ruleGrid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n._24a12a2f_ruleCell {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 120px;\n flex: 1;\n}\n\n._1014c097_ruleCellLabel {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._15a12620_chainSelectors {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n._240cbbf8_selectorRow {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n\n._929f3ef3_wildcardCell {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n min-width: 200px;\n align-self: center;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n}\n\n._929f3ef3_wildcardCell:hover:has(input:not(:disabled)) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n\n._70effa64_iconButton {\n position: relative;\n box-sizing: border-box;\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 6px;\n background: none;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._70effa64_iconButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n._70effa64_iconButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._70effa64_iconButton:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._70effa64_iconButton::after {\n content: attr(data-tip);\n position: absolute;\n bottom: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n font-size: 11px;\n line-height: 17px;\n white-space: nowrap;\n opacity: 0;\n pointer-events: none;\n transition: opacity .12s;\n}\n\n._70effa64_iconButton:hover::after,\n._70effa64_iconButton:focus-visible::after {\n opacity: 1;\n}\n\n\n._a0968257_iconButtonDanger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n color: var(--dsw-alias-state-error-primary);\n}\n\n\n._28202c90_addButton {\n align-self: flex-start;\n}\n\n\n._747fd56d_primaryButton,\n._7e855445_secondaryButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n}\n\n._747fd56d_primaryButton {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n._747fd56d_primaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n}\n\n._7e855445_secondaryButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n}\n\n._7e855445_secondaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n}\n\n._747fd56d_primaryButton:disabled,\n._7e855445_secondaryButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n._747fd56d_primaryButton:focus-visible,\n._7e855445_secondaryButton:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n\n._fbd045e0_statusBlock {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px 14px;\n margin-top: 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n}\n\n._d4f70367_statusTitle {\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._8ab300ed_statusLine {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n._e8cedbf5_statusLineLabel {\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._b48dfcba_offNotice {\n margin: 0;\n padding: 12px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n text-align: center;\n}\n\n\n._ec8bd970_resetDialog {\n width: min(480px, 100%);\n}\n\n._8677165c_confirmDanger:not(:disabled) {\n border-color: var(--dsw-alias-state-error-primary);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._8677165c_confirmDanger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._70effa64_iconButton::after {\n transition: none;\n }\n}\n";
1031
+ const css$2 = "\n\n\n._8827595f_card {\n list-style: none;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3);\n transition: border-color .16s, background .16s;\n}\n\n._8827595f_card:hover {\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n\n._06704203_cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n\n._e488d460_header {\n width: 100%;\n appearance: none;\n border: 0;\n background: none;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 12px;\n}\n\n._e488d460_header:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n\n._f5dfe084_headText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n._8d39bde6_name {\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--dsw-alias-label-primary);\n}\n\n._346f3b69_description {\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._631094a0_chevron {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n transition: transform .16s;\n}\n\n._44836ce8_chevronOpen {\n transform: rotate(180deg);\n}\n\n\n._dbaa7975_body {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px;\n padding-bottom: 8px;\n}\n\n._4e39cf17_readOnly {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._99bf7f3c_pending {\n flex: none;\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n}\n\n._114985b2_footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 0 4px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n\n\n._9860a5b1_notice {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-business-primary);\n}\n\n\n._5006d43e_legacyNotice {\n margin: 12px 0 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform);\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-business-primary);\n}\n\n._21918751_error {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary);\n}\n\n\n._7cea4b2f_noticeRow {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 12px 0 0;\n}\n\n._7cea4b2f_noticeRow ._21918751_error {\n flex: 1;\n min-width: 0;\n margin: 0;\n}\n\n\n._4058c747_form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px 0 0;\n}\n\n\n._9998065c_checkboxRow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n._02c2f6df_checkLabel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 14px;\n line-height: 22px;\n font-weight: 400;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._f2d47237_checkLabelTitle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 400;\n}\n\n._c1bed8ea_checkLabelDesc {\n font-size: 12px;\n line-height: 18px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._06389b18_checkbox {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n._06389b18_checkbox:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n\n._94c91bfd_fieldset {\n margin: 0;\n padding: 0;\n border: none;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n\n._67826267_field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding: 0;\n border: none;\n min-width: 0;\n}\n\n._13e68c3f_fieldLabel {\n \n display: inline-flex;\n align-items: center;\n gap: 10px;\n padding: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._b116c758_sectionToggle {\n width: 100%;\n appearance: none;\n border: 0;\n background: none;\n font: inherit;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n cursor: pointer;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._b116c758_sectionToggle:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._b116c758_sectionToggle:disabled {\n cursor: default;\n}\n\n._b116c758_sectionToggle:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 2px;\n border-radius: 6px;\n}\n\n._a5313fdf_sectionToggleText {\n flex: 1;\n min-width: 0;\n text-align: left;\n}\n\n._4bc809b8_hint {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._579f813a_defaultNote {\n font-size: 12px;\n line-height: 18px;\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._a6244318_infoHint {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n font-size: 14px;\n line-height: 1;\n color: var(--dsw-alias-label-tertiary);\n background: var(--dsw-alias-interactive-bg-hover);\n cursor: help;\n user-select: none;\n}\n\n._a6244318_infoHint:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n\n._e655c840_infoHintDisabled {\n opacity: 0.4;\n cursor: default;\n}\n\n\n._a2521bb0_optionRow {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._a2521bb0_optionRow:hover:has(input:not(:disabled)) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n\n._06389b18_checkbox,\n._a2521bb0_optionRow input {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n._06389b18_checkbox:focus-visible,\n._a2521bb0_optionRow input:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._a2521bb0_optionRow input:disabled {\n cursor: default;\n}\n\n\n._f9d86f7b_input {\n box-sizing: border-box;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n}\n\n._f9d86f7b_input:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n\n._f9d86f7b_input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n._f9d86f7b_input:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n\n._3a9b42fd_inputTextarea {\n height: auto;\n min-height: 72px;\n padding: 6px 10px;\n resize: vertical;\n line-height: 20px;\n}\n\n\n._7b60337a_inputInvalid,\n._7b60337a_inputInvalid:focus {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n\nselect._f9d86f7b_input {\n max-width: 240px;\n cursor: pointer;\n}\n\n\n._16eb7153_selectInput {\n appearance: none;\n padding-right: 32px;\n \n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n background-size: 12px 12px;\n}\n\n\n._3e95886d_numberFields {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 8px;\n}\n\n._0cfb5881_list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 4px;\n}\n\n\n._f5c620d6_editorCard {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-module-platform);\n}\n\n._224b1387_cardFoot {\n display: flex;\n justify-content: flex-end;\n}\n\n._8e220e07_ruleGrid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n._24a12a2f_ruleCell {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 120px;\n flex: 1;\n}\n\n._1014c097_ruleCellLabel {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._15a12620_chainSelectors {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n._240cbbf8_selectorRow {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n\n._70effa64_iconButton {\n position: relative;\n box-sizing: border-box;\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 6px;\n background: none;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._70effa64_iconButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n._70effa64_iconButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._70effa64_iconButton:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._70effa64_iconButton::after {\n content: attr(data-tip);\n position: absolute;\n bottom: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n font-size: 11px;\n line-height: 17px;\n white-space: nowrap;\n opacity: 0;\n pointer-events: none;\n transition: opacity .12s;\n}\n\n._70effa64_iconButton:hover::after,\n._70effa64_iconButton:focus-visible::after {\n opacity: 1;\n}\n\n\n._a0968257_iconButtonDanger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n color: var(--dsw-alias-state-error-primary);\n}\n\n\n._28202c90_addButton {\n align-self: flex-start;\n}\n\n\n._747fd56d_primaryButton,\n._7e855445_secondaryButton {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n}\n\n._747fd56d_primaryButton {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n._747fd56d_primaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n}\n\n._7e855445_secondaryButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n}\n\n._7e855445_secondaryButton:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n}\n\n._747fd56d_primaryButton:disabled,\n._7e855445_secondaryButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n._747fd56d_primaryButton:focus-visible,\n._7e855445_secondaryButton:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n\n._fbd045e0_statusBlock {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px 14px;\n margin-top: 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n}\n\n._d4f70367_statusTitle {\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._8ab300ed_statusLine {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n._e8cedbf5_statusLineLabel {\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._b48dfcba_offNotice {\n margin: 0;\n padding: 12px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n text-align: center;\n}\n\n\n._ec8bd970_resetDialog {\n width: min(480px, 100%);\n}\n\n._8677165c_confirmDanger:not(:disabled) {\n border-color: var(--dsw-alias-state-error-primary);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._8677165c_confirmDanger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover-danger);\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._70effa64_iconButton::after {\n transition: none;\n }\n}\n";
1107
1032
  const tagId$2 = "dsh-llm-fallbacks/FallbacksCard.module.css";
1108
1033
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
1109
1034
  const tag = document.createElement("style");
@@ -1138,13 +1063,15 @@ window.__ModuleLoader__.load({
1138
1063
  "fieldset": "_94c91bfd_fieldset",
1139
1064
  "field": "_67826267_field",
1140
1065
  "fieldLabel": "_13e68c3f_fieldLabel",
1066
+ "sectionToggle": "_b116c758_sectionToggle",
1067
+ "sectionToggleText": "_a5313fdf_sectionToggleText",
1141
1068
  "hint": "_4bc809b8_hint",
1142
1069
  "defaultNote": "_579f813a_defaultNote",
1143
1070
  "infoHint": "_a6244318_infoHint",
1144
1071
  "infoHintDisabled": "_e655c840_infoHintDisabled",
1145
1072
  "optionRow": "_a2521bb0_optionRow",
1146
- "wildcardCell": "_929f3ef3_wildcardCell",
1147
1073
  "input": "_f9d86f7b_input",
1074
+ "inputTextarea": "_3a9b42fd_inputTextarea",
1148
1075
  "inputInvalid": "_7b60337a_inputInvalid",
1149
1076
  "selectInput": "_16eb7153_selectInput",
1150
1077
  "numberFields": "_3e95886d_numberFields",
@@ -1277,7 +1204,7 @@ window.__ModuleLoader__.load({
1277
1204
  * itself constrains normal edits), and illegal selector entries in
1278
1205
  * rootChain and role chains. Returns one localized message per violation;
1279
1206
  * a non-empty result blocks {@link save} — the draft is never written.
1280
- * `label`/`description` are free text and never validated.
1207
+ * `persona` is free text and never validated.
1281
1208
  */
1282
1209
  function validateDraft(draft, t) {
1283
1210
  const errors = [];
@@ -1376,11 +1303,16 @@ window.__ModuleLoader__.load({
1376
1303
  });
1377
1304
  }
1378
1305
  /**
1379
- * One chain entry selector row: provider select + model select (cascade) +
1380
- * wildcard checkbox (spec §2.5 D-3). The provider options are the catalog
1381
- * providers **configured on the Models page** (`configuredProviders`, the
1382
- * Models-page `configured` join) — unconfigured directory providers never
1383
- * become offerable. Out-of-catalog values read back from the server render as
1306
+ * One chain entry selector row: provider select + model select (cascade).
1307
+ * The GUI never offers a `provider/*` wildcard (root agent and role chains
1308
+ * alike; provider-any matching lives in the role rules) — but `provider/*`
1309
+ * stays a legal YAML entry, so a wildcard row read back from the server
1310
+ * renders with the legacy-conversion hint and an enabled model select:
1311
+ * picking a model converts the row to an exact entry (the patch carries
1312
+ * `wildcard: false`). The provider options are the catalog providers
1313
+ * **configured on the Models page** (`configuredProviders`, the Models-page
1314
+ * `configured` join) — unconfigured directory providers never become
1315
+ * offerable. Out-of-catalog values read back from the server render as
1384
1316
  * a synthetic option with the short "outside catalog" annotation and stay
1385
1317
  * selected — keeping them saves verbatim; picking a catalog option is an
1386
1318
  * intentional change. A directory provider that is not configured is offered
@@ -1395,100 +1327,86 @@ window.__ModuleLoader__.load({
1395
1327
  const modelRaw = selectionToRaw(selector.model);
1396
1328
  const modelOutside = selector.model?.kind === "outside";
1397
1329
  const group = catalog?.groups.find((entry) => entry.id === providerRaw);
1398
- const groupMissing = providerRaw !== "" && !providerOutside && !selector.wildcard && group === void 0;
1399
- const modelDisabled = disabled || selector.wildcard || providerRaw === "" || groupMissing || providerOutside && modelRaw === "";
1330
+ const groupMissing = providerRaw !== "" && !providerOutside && group === void 0;
1331
+ const modelDisabled = disabled || providerRaw === "" || groupMissing || providerOutside && modelRaw === "";
1400
1332
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1401
1333
  className: FallbacksCard_module_css_default.selectorRow,
1402
1334
  children: [
1403
1335
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1404
1336
  className: FallbacksCard_module_css_default.ruleGrid,
1405
- children: [
1406
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1407
- className: FallbacksCard_module_css_default.ruleCell,
1408
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1337
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1338
+ className: FallbacksCard_module_css_default.ruleCell,
1339
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1340
+ className: FallbacksCard_module_css_default.ruleCellLabel,
1341
+ children: t("roles.rule.provider")
1342
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1343
+ className: `${FallbacksCard_module_css_default.input} ${FallbacksCard_module_css_default.selectInput}`,
1344
+ value: providerRaw,
1345
+ disabled,
1346
+ onChange: (event) => {
1347
+ if (event.target.value === providerRaw) return;
1348
+ onChange({
1349
+ provider: classifyProvider(event.target.value, catalog),
1350
+ model: null
1351
+ });
1352
+ },
1353
+ children: [
1354
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1355
+ value: "",
1356
+ children: t("chains.selector.providerPlaceholder")
1357
+ }),
1358
+ configuredProviders.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1359
+ value: entry.provider,
1360
+ children: entry.displayName
1361
+ }, entry.provider)),
1362
+ providerUnconfigured && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1363
+ value: providerRaw,
1364
+ children: `${providerRaw}${t("catalog.unconfigured.short")}`
1365
+ }),
1366
+ providerOutside && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1367
+ value: providerRaw,
1368
+ children: `${providerRaw}${t("catalog.outside.short")}`
1369
+ })
1370
+ ]
1371
+ })]
1372
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1373
+ className: FallbacksCard_module_css_default.ruleCell,
1374
+ children: [
1375
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1409
1376
  className: FallbacksCard_module_css_default.ruleCellLabel,
1410
- children: t("roles.rule.provider")
1411
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1377
+ children: t("roles.rule.model")
1378
+ }),
1379
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1412
1380
  className: `${FallbacksCard_module_css_default.input} ${FallbacksCard_module_css_default.selectInput}`,
1413
- value: providerRaw,
1414
- disabled,
1381
+ value: modelRaw,
1382
+ disabled: modelDisabled,
1415
1383
  onChange: (event) => {
1416
- if (event.target.value === providerRaw) return;
1417
1384
  onChange({
1418
- provider: classifyProvider(event.target.value, catalog),
1419
- model: null
1385
+ model: classifyModel(providerRaw, event.target.value, catalog),
1386
+ ...selector.wildcard ? { wildcard: false } : {}
1420
1387
  });
1421
1388
  },
1422
1389
  children: [
1423
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1390
+ modelRaw === "" && !providerOutside && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1424
1391
  value: "",
1425
- children: t("chains.selector.providerPlaceholder")
1426
- }),
1427
- configuredProviders.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1428
- value: entry.provider,
1429
- children: entry.displayName
1430
- }, entry.provider)),
1431
- providerUnconfigured && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1432
- value: providerRaw,
1433
- children: `${providerRaw}${t("catalog.unconfigured.short")}`
1392
+ children: t("chains.selector.modelPlaceholder")
1434
1393
  }),
1435
- providerOutside && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1436
- value: providerRaw,
1437
- children: `${providerRaw}${t("catalog.outside.short")}`
1394
+ (group?.models ?? []).map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1395
+ value: model.id,
1396
+ children: model.name
1397
+ }, model.id)),
1398
+ modelOutside && !selector.wildcard && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1399
+ value: modelRaw,
1400
+ children: `${modelRaw}${t("catalog.outside.short")}`
1438
1401
  })
1439
1402
  ]
1440
- })]
1441
- }),
1442
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1443
- className: FallbacksCard_module_css_default.ruleCell,
1444
- children: [
1445
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1446
- className: FallbacksCard_module_css_default.ruleCellLabel,
1447
- children: t("roles.rule.model")
1448
- }),
1449
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1450
- className: `${FallbacksCard_module_css_default.input} ${FallbacksCard_module_css_default.selectInput}`,
1451
- value: selector.wildcard ? "" : modelRaw,
1452
- disabled: modelDisabled,
1453
- onChange: (event) => {
1454
- onChange({ model: classifyModel(providerRaw, event.target.value, catalog) });
1455
- },
1456
- children: [
1457
- modelRaw === "" && !providerOutside && !selector.wildcard && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1458
- value: "",
1459
- children: t("chains.selector.modelPlaceholder")
1460
- }),
1461
- (group?.models ?? []).map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1462
- value: model.id,
1463
- children: model.name
1464
- }, model.id)),
1465
- modelOutside && !selector.wildcard && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1466
- value: modelRaw,
1467
- children: `${modelRaw}${t("catalog.outside.short")}`
1468
- })
1469
- ]
1470
- }),
1471
- groupMissing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1472
- className: FallbacksCard_module_css_default.hint,
1473
- children: t("chains.selector.noModels")
1474
- })
1475
- ]
1476
- }),
1477
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1478
- className: `${FallbacksCard_module_css_default.ruleCell} ${FallbacksCard_module_css_default.wildcardCell}`,
1479
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1480
- type: "checkbox",
1481
- checked: selector.wildcard,
1482
- disabled: disabled || providerRaw === "",
1483
- onChange: (event) => {
1484
- onChange({
1485
- wildcard: event.target.checked,
1486
- ...event.target.checked ? { model: null } : {}
1487
- });
1488
- }
1489
- }), t("chains.selector.wildcard")]
1490
- })
1491
- ]
1403
+ }),
1404
+ groupMissing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1405
+ className: FallbacksCard_module_css_default.hint,
1406
+ children: t("chains.selector.noModelsStrict")
1407
+ })
1408
+ ]
1409
+ })]
1492
1410
  }),
1493
1411
  (providerOutside || modelOutside) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1494
1412
  className: FallbacksCard_module_css_default.hint,
@@ -1497,6 +1415,10 @@ window.__ModuleLoader__.load({
1497
1415
  disabled
1498
1416
  })]
1499
1417
  }),
1418
+ selector.wildcard && !modelDisabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1419
+ className: FallbacksCard_module_css_default.hint,
1420
+ children: t("chains.selector.wildcardLegacy")
1421
+ }),
1500
1422
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1501
1423
  className: FallbacksCard_module_css_default.cardFoot,
1502
1424
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -1624,8 +1546,7 @@ window.__ModuleLoader__.load({
1624
1546
  const addRole = () => {
1625
1547
  setRoleRows((rows) => [...rows, {
1626
1548
  id: "",
1627
- label: "",
1628
- description: "",
1549
+ persona: "",
1629
1550
  selectors: [],
1630
1551
  fallback: "inherit-root"
1631
1552
  }]);
@@ -1723,6 +1644,7 @@ window.__ModuleLoader__.load({
1723
1644
  });
1724
1645
  };
1725
1646
  const [userOpen, setUserOpen] = (0, react.useState)(false);
1647
+ const [advancedOpen, setAdvancedOpen] = (0, react.useState)(false);
1726
1648
  const degradedLatch = (0, react.useRef)(false);
1727
1649
  const errorLatch = (0, react.useRef)(false);
1728
1650
  if (state.status === "ready") {
@@ -1731,6 +1653,7 @@ window.__ModuleLoader__.load({
1731
1653
  } else if (state.status === "error") errorLatch.current = true;
1732
1654
  const degraded = state.status === "ready" ? !state.present : degradedLatch.current;
1733
1655
  const open = userOpen || errorLatch.current || degraded;
1656
+ const advancedVisible = advancedOpen || !writable;
1734
1657
  const title = t("title");
1735
1658
  const header = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1736
1659
  type: "button",
@@ -1841,211 +1764,6 @@ window.__ModuleLoader__.load({
1841
1764
  className: FallbacksCard_module_css_default.fieldset,
1842
1765
  disabled: !writable,
1843
1766
  children: [
1844
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1845
- className: FallbacksCard_module_css_default.field,
1846
- role: "group",
1847
- "aria-labelledby": "fallbacks-trigger-codes",
1848
- children: [
1849
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1850
- className: FallbacksCard_module_css_default.fieldLabel,
1851
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1852
- id: "fallbacks-trigger-codes",
1853
- children: t("triggerCodes.label")
1854
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
1855
- label: t("triggerCodes.tooltip"),
1856
- disabled: !writable
1857
- })]
1858
- }),
1859
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1860
- className: FallbacksCard_module_css_default.hint,
1861
- children: t("triggerCodes.hint")
1862
- }),
1863
- KNOWN_TRIGGER_CODES.map((code) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1864
- className: FallbacksCard_module_css_default.optionRow,
1865
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1866
- type: "checkbox",
1867
- checked: scalars.triggerCodes.includes(code),
1868
- onChange: (event) => {
1869
- updateScalars((draft) => {
1870
- draft.triggerCodes = withTriggerCode(draft.triggerCodes, code, event.target.checked);
1871
- });
1872
- }
1873
- }), t(TRIGGER_CODE_LABELS[code])]
1874
- }, code)),
1875
- unknownCodes.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1876
- className: FallbacksCard_module_css_default.hint,
1877
- children: t("triggerCodes.extra", { codes: unknownCodes.join(", ") })
1878
- })
1879
- ]
1880
- }),
1881
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1882
- className: FallbacksCard_module_css_default.field,
1883
- role: "group",
1884
- "aria-labelledby": "fallbacks-revert-policy",
1885
- children: [
1886
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1887
- className: FallbacksCard_module_css_default.fieldLabel,
1888
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1889
- id: "fallbacks-revert-policy",
1890
- children: t("revertPolicy.label")
1891
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
1892
- label: t("revertPolicy.tooltip"),
1893
- disabled: !writable
1894
- })]
1895
- }),
1896
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1897
- className: FallbacksCard_module_css_default.hint,
1898
- children: t("revertPolicy.hint")
1899
- }),
1900
- ["cooldown-expiry", "never"].map((policy) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1901
- className: FallbacksCard_module_css_default.optionRow,
1902
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1903
- type: "radio",
1904
- name: "fallbacks-revert-policy",
1905
- checked: scalars.revertPolicy === policy,
1906
- onChange: () => {
1907
- updateScalars((draft) => {
1908
- draft.revertPolicy = policy;
1909
- });
1910
- }
1911
- }), t(`revertPolicy.${policy}`)]
1912
- }, policy))
1913
- ]
1914
- }),
1915
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1916
- className: FallbacksCard_module_css_default.numberFields,
1917
- children: [
1918
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1919
- className: FallbacksCard_module_css_default.field,
1920
- children: [
1921
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1922
- className: FallbacksCard_module_css_default.fieldLabel,
1923
- children: [
1924
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1925
- htmlFor: "fallbacks-cooldown-ms",
1926
- children: t("cooldownMs.label")
1927
- }),
1928
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
1929
- label: t("cooldownMs.tooltip"),
1930
- disabled: !writable
1931
- }),
1932
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1933
- className: FallbacksCard_module_css_default.defaultNote,
1934
- children: [
1935
- t("defaults.prefix"),
1936
- ": ",
1937
- state.config.cooldownMs
1938
- ]
1939
- })
1940
- ]
1941
- }),
1942
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1943
- id: "fallbacks-cooldown-ms",
1944
- className: FallbacksCard_module_css_default.input,
1945
- type: "number",
1946
- min: 0,
1947
- value: String(scalars.cooldownMs),
1948
- disabled: !writable,
1949
- onChange: (event) => {
1950
- updateScalars((draft) => {
1951
- draft.cooldownMs = parseCount(event.target.value);
1952
- });
1953
- }
1954
- }),
1955
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1956
- className: FallbacksCard_module_css_default.hint,
1957
- children: t("cooldownMs.hint")
1958
- })
1959
- ]
1960
- }),
1961
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1962
- className: FallbacksCard_module_css_default.field,
1963
- children: [
1964
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1965
- className: FallbacksCard_module_css_default.fieldLabel,
1966
- children: [
1967
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1968
- htmlFor: "fallbacks-max-switches",
1969
- children: t("maxSwitchesPerStep.label")
1970
- }),
1971
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
1972
- label: t("maxSwitchesPerStep.tooltip"),
1973
- disabled: !writable
1974
- }),
1975
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1976
- className: FallbacksCard_module_css_default.defaultNote,
1977
- children: [
1978
- t("defaults.prefix"),
1979
- ": ",
1980
- state.config.maxSwitchesPerStep
1981
- ]
1982
- })
1983
- ]
1984
- }),
1985
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1986
- id: "fallbacks-max-switches",
1987
- className: FallbacksCard_module_css_default.input,
1988
- type: "number",
1989
- min: 0,
1990
- value: String(scalars.maxSwitchesPerStep),
1991
- disabled: !writable,
1992
- onChange: (event) => {
1993
- updateScalars((draft) => {
1994
- draft.maxSwitchesPerStep = parseCount(event.target.value);
1995
- });
1996
- }
1997
- }),
1998
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1999
- className: FallbacksCard_module_css_default.hint,
2000
- children: t("maxSwitchesPerStep.hint")
2001
- })
2002
- ]
2003
- }),
2004
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2005
- className: FallbacksCard_module_css_default.field,
2006
- children: [
2007
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2008
- className: FallbacksCard_module_css_default.fieldLabel,
2009
- children: [
2010
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2011
- htmlFor: "fallbacks-always-cap",
2012
- children: t("alwaysModeRetryCap.label")
2013
- }),
2014
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2015
- label: t("alwaysModeRetryCap.tooltip"),
2016
- disabled: !writable
2017
- }),
2018
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2019
- className: FallbacksCard_module_css_default.defaultNote,
2020
- children: [
2021
- t("defaults.prefix"),
2022
- ": ",
2023
- state.config.alwaysModeRetryCap
2024
- ]
2025
- })
2026
- ]
2027
- }),
2028
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2029
- id: "fallbacks-always-cap",
2030
- className: FallbacksCard_module_css_default.input,
2031
- type: "number",
2032
- min: 0,
2033
- value: String(scalars.alwaysModeRetryCap),
2034
- disabled: !writable,
2035
- onChange: (event) => {
2036
- updateScalars((draft) => {
2037
- draft.alwaysModeRetryCap = parseCount(event.target.value);
2038
- });
2039
- }
2040
- }),
2041
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2042
- className: FallbacksCard_module_css_default.hint,
2043
- children: t("alwaysModeRetryCap.hint")
2044
- })
2045
- ]
2046
- })
2047
- ]
2048
- }),
2049
1767
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2050
1768
  className: FallbacksCard_module_css_default.field,
2051
1769
  role: "group",
@@ -2134,64 +1852,52 @@ window.__ModuleLoader__.load({
2134
1852
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2135
1853
  className: FallbacksCard_module_css_default.editorCard,
2136
1854
  children: [
2137
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1855
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2138
1856
  className: FallbacksCard_module_css_default.ruleGrid,
2139
- children: [
2140
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2141
- className: FallbacksCard_module_css_default.ruleCell,
2142
- children: [
2143
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2144
- className: FallbacksCard_module_css_default.ruleCellLabel,
2145
- children: t("roles.id")
2146
- }),
2147
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2148
- className: `${FallbacksCard_module_css_default.input} ${invalid ? FallbacksCard_module_css_default.inputInvalid : ""}`,
2149
- value: row.id,
2150
- placeholder: t("roles.idPlaceholder"),
2151
- "aria-label": t("roles.id"),
2152
- "aria-invalid": invalid ? true : void 0,
2153
- disabled: !writable,
2154
- onChange: (event) => {
2155
- updateRoleRow(index, { id: event.target.value });
2156
- }
2157
- }),
2158
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2159
- className: FallbacksCard_module_css_default.hint,
2160
- children: t("roles.id.hint")
2161
- })
2162
- ]
2163
- }),
2164
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2165
- className: FallbacksCard_module_css_default.ruleCell,
2166
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2167
- className: FallbacksCard_module_css_default.ruleCellLabel,
2168
- children: t("roles.label")
2169
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2170
- className: FallbacksCard_module_css_default.input,
2171
- value: row.label,
2172
- "aria-label": t("roles.label"),
2173
- disabled: !writable,
2174
- onChange: (event) => {
2175
- updateRoleRow(index, { label: event.target.value });
2176
- }
2177
- })]
2178
- }),
2179
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2180
- className: FallbacksCard_module_css_default.ruleCell,
2181
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1857
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1858
+ className: FallbacksCard_module_css_default.ruleCell,
1859
+ children: [
1860
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2182
1861
  className: FallbacksCard_module_css_default.ruleCellLabel,
2183
- children: t("roles.description")
2184
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2185
- className: FallbacksCard_module_css_default.input,
2186
- value: row.description,
2187
- "aria-label": t("roles.description"),
1862
+ children: t("roles.id")
1863
+ }),
1864
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1865
+ className: `${FallbacksCard_module_css_default.input} ${invalid ? FallbacksCard_module_css_default.inputInvalid : ""}`,
1866
+ value: row.id,
1867
+ placeholder: t("roles.idPlaceholder"),
1868
+ "aria-label": t("roles.id"),
1869
+ "aria-invalid": invalid ? true : void 0,
2188
1870
  disabled: !writable,
2189
1871
  onChange: (event) => {
2190
- updateRoleRow(index, { description: event.target.value });
1872
+ updateRoleRow(index, { id: event.target.value });
2191
1873
  }
2192
- })]
2193
- })
2194
- ]
1874
+ }),
1875
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1876
+ className: FallbacksCard_module_css_default.hint,
1877
+ children: t("roles.id.hint")
1878
+ })
1879
+ ]
1880
+ })
1881
+ }),
1882
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1883
+ className: FallbacksCard_module_css_default.ruleGrid,
1884
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1885
+ className: FallbacksCard_module_css_default.ruleCell,
1886
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1887
+ className: FallbacksCard_module_css_default.ruleCellLabel,
1888
+ children: t("roles.persona")
1889
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1890
+ rows: 3,
1891
+ className: `${FallbacksCard_module_css_default.input} ${FallbacksCard_module_css_default.inputTextarea}`,
1892
+ value: row.persona,
1893
+ placeholder: t("roles.personaPlaceholder"),
1894
+ "aria-label": t("roles.persona"),
1895
+ disabled: !writable,
1896
+ onChange: (event) => {
1897
+ updateRoleRow(index, { persona: event.target.value });
1898
+ }
1899
+ })]
1900
+ })
2195
1901
  }),
2196
1902
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2197
1903
  className: FallbacksCard_module_css_default.chainSelectors,
@@ -2484,6 +2190,236 @@ window.__ModuleLoader__.load({
2484
2190
  children: t("roles.addRule")
2485
2191
  })
2486
2192
  ]
2193
+ }),
2194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2195
+ className: FallbacksCard_module_css_default.field,
2196
+ role: "group",
2197
+ "aria-labelledby": "fallbacks-advanced",
2198
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2199
+ type: "button",
2200
+ className: FallbacksCard_module_css_default.sectionToggle,
2201
+ disabled: !writable,
2202
+ "aria-expanded": advancedVisible,
2203
+ "aria-controls": advancedVisible ? "fallbacks-advanced-body" : void 0,
2204
+ "aria-label": t(advancedVisible ? "advanced.collapse" : "advanced.expand"),
2205
+ onClick: () => {
2206
+ if (writable) setAdvancedOpen(!advancedOpen);
2207
+ },
2208
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2209
+ id: "fallbacks-advanced",
2210
+ className: FallbacksCard_module_css_default.sectionToggleText,
2211
+ children: t("advanced.label")
2212
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: advancedVisible ? `${FallbacksCard_module_css_default.chevron} ${FallbacksCard_module_css_default.chevronOpen}` : FallbacksCard_module_css_default.chevron })]
2213
+ }), advancedVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2214
+ id: "fallbacks-advanced-body",
2215
+ children: [
2216
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2217
+ className: FallbacksCard_module_css_default.field,
2218
+ role: "group",
2219
+ "aria-labelledby": "fallbacks-trigger-codes",
2220
+ children: [
2221
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2222
+ className: FallbacksCard_module_css_default.fieldLabel,
2223
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2224
+ id: "fallbacks-trigger-codes",
2225
+ children: t("triggerCodes.label")
2226
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2227
+ label: t("triggerCodes.tooltip"),
2228
+ disabled: !writable
2229
+ })]
2230
+ }),
2231
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2232
+ className: FallbacksCard_module_css_default.hint,
2233
+ children: t("triggerCodes.hint")
2234
+ }),
2235
+ KNOWN_TRIGGER_CODES.map((code) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2236
+ className: FallbacksCard_module_css_default.optionRow,
2237
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2238
+ type: "checkbox",
2239
+ checked: scalars.triggerCodes.includes(code),
2240
+ onChange: (event) => {
2241
+ updateScalars((draft) => {
2242
+ draft.triggerCodes = withTriggerCode(draft.triggerCodes, code, event.target.checked);
2243
+ });
2244
+ }
2245
+ }), t(TRIGGER_CODE_LABELS[code])]
2246
+ }, code)),
2247
+ unknownCodes.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2248
+ className: FallbacksCard_module_css_default.hint,
2249
+ children: t("triggerCodes.extra", { codes: unknownCodes.join(", ") })
2250
+ })
2251
+ ]
2252
+ }),
2253
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2254
+ className: FallbacksCard_module_css_default.field,
2255
+ role: "group",
2256
+ "aria-labelledby": "fallbacks-revert-policy",
2257
+ children: [
2258
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2259
+ className: FallbacksCard_module_css_default.fieldLabel,
2260
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2261
+ id: "fallbacks-revert-policy",
2262
+ children: t("revertPolicy.label")
2263
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2264
+ label: t("revertPolicy.tooltip"),
2265
+ disabled: !writable
2266
+ })]
2267
+ }),
2268
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2269
+ className: FallbacksCard_module_css_default.hint,
2270
+ children: t("revertPolicy.hint")
2271
+ }),
2272
+ ["cooldown-expiry", "never"].map((policy) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2273
+ className: FallbacksCard_module_css_default.optionRow,
2274
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2275
+ type: "radio",
2276
+ name: "fallbacks-revert-policy",
2277
+ checked: scalars.revertPolicy === policy,
2278
+ onChange: () => {
2279
+ updateScalars((draft) => {
2280
+ draft.revertPolicy = policy;
2281
+ });
2282
+ }
2283
+ }), t(`revertPolicy.${policy}`)]
2284
+ }, policy))
2285
+ ]
2286
+ }),
2287
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2288
+ className: FallbacksCard_module_css_default.numberFields,
2289
+ children: [
2290
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2291
+ className: FallbacksCard_module_css_default.field,
2292
+ children: [
2293
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2294
+ className: FallbacksCard_module_css_default.fieldLabel,
2295
+ children: [
2296
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2297
+ htmlFor: "fallbacks-cooldown-ms",
2298
+ children: t("cooldownMs.label")
2299
+ }),
2300
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2301
+ label: t("cooldownMs.tooltip"),
2302
+ disabled: !writable
2303
+ }),
2304
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2305
+ className: FallbacksCard_module_css_default.defaultNote,
2306
+ children: [
2307
+ t("defaults.prefix"),
2308
+ ": ",
2309
+ state.config.cooldownMs
2310
+ ]
2311
+ })
2312
+ ]
2313
+ }),
2314
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2315
+ id: "fallbacks-cooldown-ms",
2316
+ className: FallbacksCard_module_css_default.input,
2317
+ type: "number",
2318
+ min: 0,
2319
+ value: String(scalars.cooldownMs),
2320
+ disabled: !writable,
2321
+ onChange: (event) => {
2322
+ updateScalars((draft) => {
2323
+ draft.cooldownMs = parseCount(event.target.value);
2324
+ });
2325
+ }
2326
+ }),
2327
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2328
+ className: FallbacksCard_module_css_default.hint,
2329
+ children: t("cooldownMs.hint")
2330
+ })
2331
+ ]
2332
+ }),
2333
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2334
+ className: FallbacksCard_module_css_default.field,
2335
+ children: [
2336
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2337
+ className: FallbacksCard_module_css_default.fieldLabel,
2338
+ children: [
2339
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2340
+ htmlFor: "fallbacks-max-switches",
2341
+ children: t("maxSwitchesPerStep.label")
2342
+ }),
2343
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2344
+ label: t("maxSwitchesPerStep.tooltip"),
2345
+ disabled: !writable
2346
+ }),
2347
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2348
+ className: FallbacksCard_module_css_default.defaultNote,
2349
+ children: [
2350
+ t("defaults.prefix"),
2351
+ ": ",
2352
+ state.config.maxSwitchesPerStep
2353
+ ]
2354
+ })
2355
+ ]
2356
+ }),
2357
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2358
+ id: "fallbacks-max-switches",
2359
+ className: FallbacksCard_module_css_default.input,
2360
+ type: "number",
2361
+ min: 0,
2362
+ value: String(scalars.maxSwitchesPerStep),
2363
+ disabled: !writable,
2364
+ onChange: (event) => {
2365
+ updateScalars((draft) => {
2366
+ draft.maxSwitchesPerStep = parseCount(event.target.value);
2367
+ });
2368
+ }
2369
+ }),
2370
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2371
+ className: FallbacksCard_module_css_default.hint,
2372
+ children: t("maxSwitchesPerStep.hint")
2373
+ })
2374
+ ]
2375
+ }),
2376
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2377
+ className: FallbacksCard_module_css_default.field,
2378
+ children: [
2379
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2380
+ className: FallbacksCard_module_css_default.fieldLabel,
2381
+ children: [
2382
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2383
+ htmlFor: "fallbacks-always-cap",
2384
+ children: t("alwaysModeRetryCap.label")
2385
+ }),
2386
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoHint, {
2387
+ label: t("alwaysModeRetryCap.tooltip"),
2388
+ disabled: !writable
2389
+ }),
2390
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2391
+ className: FallbacksCard_module_css_default.defaultNote,
2392
+ children: [
2393
+ t("defaults.prefix"),
2394
+ ": ",
2395
+ state.config.alwaysModeRetryCap
2396
+ ]
2397
+ })
2398
+ ]
2399
+ }),
2400
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2401
+ id: "fallbacks-always-cap",
2402
+ className: FallbacksCard_module_css_default.input,
2403
+ type: "number",
2404
+ min: 0,
2405
+ value: String(scalars.alwaysModeRetryCap),
2406
+ disabled: !writable,
2407
+ onChange: (event) => {
2408
+ updateScalars((draft) => {
2409
+ draft.alwaysModeRetryCap = parseCount(event.target.value);
2410
+ });
2411
+ }
2412
+ }),
2413
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2414
+ className: FallbacksCard_module_css_default.hint,
2415
+ children: t("alwaysModeRetryCap.hint")
2416
+ })
2417
+ ]
2418
+ })
2419
+ ]
2420
+ })
2421
+ ]
2422
+ })]
2487
2423
  })
2488
2424
  ]
2489
2425
  })