dsh-llm-fallbacks 0.4.1 → 0.4.3
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.
- package/README.md +31 -2
- package/README.zh-CN.md +31 -2
- package/dist/chains.d.ts +24 -5
- package/dist/client/SubagentRoleBadge.d.ts +23 -0
- package/dist/client/fallbacks-store.d.ts +58 -17
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +311 -141
- package/dist/client/locales.d.ts +12 -6
- package/dist/config.d.ts +1 -1
- package/dist/gateway.d.ts +55 -2
- package/dist/index.d.ts +34 -5
- package/dist/index.js +196 -61
- package/dist/presets.d.ts +7 -4
- package/dist/seeds.d.ts +61 -7
- package/dist/state.d.ts +32 -4
- package/dist/tui-settings.d.ts +8 -6
- package/dist/tui.d.ts +12 -5
- package/package.json +1 -1
- package/scripts/build-client.ts +6 -1
- package/scripts/prepare-release.ts +1 -1
package/dist/client/index.js
CHANGED
|
@@ -527,16 +527,30 @@ window.__ModuleLoader__.load({
|
|
|
527
527
|
/**
|
|
528
528
|
* Shape-guard the wire `seeds` badge field (spec §9.4): only `{ id,
|
|
529
529
|
* overridden }` entries survive — the `legacyKeys` element-filter
|
|
530
|
-
* precedent.
|
|
531
|
-
*
|
|
532
|
-
*
|
|
530
|
+
* precedent. `source` is optional on the wire (gateway version skew): a
|
|
531
|
+
* present-and-string label is kept, an absent/malformed one drops the
|
|
532
|
+
* field while the entry itself still parses — consumers treat a missing
|
|
533
|
+
* label as "no badge" (the degradation path, never an error). A blank or
|
|
534
|
+
* whitespace-only label counts as malformed (it would render a textless
|
|
535
|
+
* badge). Entries are
|
|
536
|
+
* NORMALIZED to the known keys, so a wire entry can never smuggle a
|
|
537
|
+
* non-string `source` past the guard's type. A non-array value resolves
|
|
538
|
+
* to `[]`; malformed entries are dropped, so an all-bad array also lands
|
|
539
|
+
* `[]`. The store never trusts a misshapen badge field.
|
|
533
540
|
*/
|
|
534
541
|
function parseSeedsWire(value) {
|
|
535
542
|
if (!Array.isArray(value)) return [];
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
543
|
+
const entries = [];
|
|
544
|
+
for (const entry of value) {
|
|
545
|
+
if (!isRecord(entry)) continue;
|
|
546
|
+
if (typeof entry.id !== "string" || typeof entry.overridden !== "boolean") continue;
|
|
547
|
+
entries.push({
|
|
548
|
+
id: entry.id,
|
|
549
|
+
overridden: entry.overridden,
|
|
550
|
+
...typeof entry.source === "string" && entry.source.trim() !== "" ? { source: entry.source } : {}
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return entries;
|
|
540
554
|
}
|
|
541
555
|
function parsePolicyRoute(value) {
|
|
542
556
|
if (!isRecord(value)) return void 0;
|
|
@@ -588,14 +602,47 @@ window.__ModuleLoader__.load({
|
|
|
588
602
|
if (!isRecord(value) || !("subagentPolicy" in value)) return fallback;
|
|
589
603
|
return parseSubagentPolicyWire(value.subagentPolicy);
|
|
590
604
|
}
|
|
591
|
-
/**
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
605
|
+
/**
|
|
606
|
+
* Shape-guard one wire role record (`fallbacks/subagent-roles` readback).
|
|
607
|
+
* A non-object, a blank/non-string `role`, or a non-number `at` fails the
|
|
608
|
+
* WHOLE record (`undefined` → the badge renders nothing). A present-but-
|
|
609
|
+
* malformed `model` drops the FIELD while the record still parses (the
|
|
610
|
+
* `parseSeedsWire` `source` rule) — the badge then hovers the role alone
|
|
611
|
+
* instead of disappearing. Records are NORMALIZED to the known keys, so a
|
|
612
|
+
* wire record can never smuggle a non-string `model` past the guard's type.
|
|
613
|
+
*/
|
|
614
|
+
function parseSubagentRoleRecord(value) {
|
|
615
|
+
if (!isRecord(value)) return void 0;
|
|
616
|
+
if (typeof value.role !== "string" || value.role.trim() === "") return void 0;
|
|
617
|
+
if (typeof value.at !== "number") return void 0;
|
|
618
|
+
const model = parsePolicyRoute(value.model);
|
|
619
|
+
return {
|
|
620
|
+
role: value.role,
|
|
621
|
+
...model === void 0 ? {} : { model },
|
|
622
|
+
at: value.at
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Read this session's dispatch-resolved role record through the plugin
|
|
627
|
+
* gateway channel (plan subagent-role-badge T3): the batch-of-ids endpoint
|
|
628
|
+
* called with the one id the badge cares about. NEVER throws — a channel
|
|
629
|
+
* down, an old gateway without the endpoint (rpc failure), or a malformed
|
|
630
|
+
* payload all resolve `undefined` (the badge renders nothing —
|
|
631
|
+
* degrade-never-crash, the fail-closed shape of `parseSubagentPolicyWire`).
|
|
632
|
+
* @param rpc - the connection's generic RPC caller (`/api` channel).
|
|
633
|
+
* @param sessionId - the session whose record to read.
|
|
634
|
+
* @returns the parsed record, or `undefined` when absent/failed.
|
|
635
|
+
*/
|
|
636
|
+
async function fetchSubagentRoleRecord(rpc, sessionId) {
|
|
637
|
+
try {
|
|
638
|
+
const result = await rpc.call("/api", "fallbacks/subagent-roles", { args: { ids: [sessionId] } });
|
|
639
|
+
if (!result.ok) return void 0;
|
|
640
|
+
const value = result.value;
|
|
641
|
+
if (!isRecord(value)) return void 0;
|
|
642
|
+
return parseSubagentRoleRecord(value[sessionId]);
|
|
643
|
+
} catch {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
599
646
|
}
|
|
600
647
|
/**
|
|
601
648
|
* The provider dropdown's offer set (spec §2.5 D-4): catalog providers whose
|
|
@@ -862,7 +909,8 @@ window.__ModuleLoader__.load({
|
|
|
862
909
|
persona: role.persona,
|
|
863
910
|
selectors: (role.chain ?? []).map((entry) => entryToSelectorRow(entry, catalog)),
|
|
864
911
|
fallback: role.fallback ?? "inherit-root",
|
|
865
|
-
collapsed: true
|
|
912
|
+
collapsed: true,
|
|
913
|
+
personaOpen: false
|
|
866
914
|
}));
|
|
867
915
|
}
|
|
868
916
|
/** Rebuild the declared roles from edited rows; empty selectors drop out. */
|
|
@@ -1220,55 +1268,18 @@ window.__ModuleLoader__.load({
|
|
|
1220
1268
|
}
|
|
1221
1269
|
}
|
|
1222
1270
|
/**
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
*
|
|
1227
|
-
*
|
|
1228
|
-
*
|
|
1229
|
-
*
|
|
1230
|
-
*
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
1233
|
-
* Returns the seed-default persona when the outcome is `{ reverted:
|
|
1234
|
-
* true, persona }` — including the persist no-op (persisted already
|
|
1235
|
-
* equals the seed). The card applies that string to the row's **draft**
|
|
1236
|
-
* so an unsaved persona edit still snaps back (issue #59).
|
|
1237
|
-
* @param id - the seeded role id; the host matches it by trimmed id
|
|
1238
|
-
* against the seed registry (spec §9.3).
|
|
1271
|
+
* Read one session's dispatch-resolved subagent role record through the
|
|
1272
|
+
* gateway channel (plan subagent-role-badge T3 — the session-header badge's
|
|
1273
|
+
* data face). Thin delegate over {@link fetchSubagentRoleRecord} on the
|
|
1274
|
+
* SAME rpc caller the store rides: the batch-of-ids readback called with
|
|
1275
|
+
* the one id the badge cares about. Never throws — a channel down, an old
|
|
1276
|
+
* gateway without the endpoint, or a malformed payload all resolve
|
|
1277
|
+
* `undefined` (the badge renders nothing).
|
|
1278
|
+
* @param sessionId - the session whose record to read.
|
|
1279
|
+
* @returns the parsed record, or `undefined` when absent/failed.
|
|
1239
1280
|
*/
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
if (!state.writable || state.status === "saving") return void 0;
|
|
1243
|
-
const generation = ++this.writeGeneration;
|
|
1244
|
-
this.store.update((draft) => {
|
|
1245
|
-
draft.status = "saving";
|
|
1246
|
-
draft.error = null;
|
|
1247
|
-
});
|
|
1248
|
-
try {
|
|
1249
|
-
const result = await this.rpc.call("/api", "fallbacks/revert-seed", { args: { id } });
|
|
1250
|
-
if (generation !== this.writeGeneration) return void 0;
|
|
1251
|
-
if (!result.ok) throw result.error;
|
|
1252
|
-
const value = result.value;
|
|
1253
|
-
const config = value !== null && typeof value === "object" && "config" in value ? value.config : void 0;
|
|
1254
|
-
let legacyKeys = this.store.getSnapshot().legacyKeys;
|
|
1255
|
-
if (value !== null && typeof value === "object" && "legacyKeys" in value) {
|
|
1256
|
-
const wireLegacyKeys = value.legacyKeys;
|
|
1257
|
-
if (Array.isArray(wireLegacyKeys)) legacyKeys = wireLegacyKeys.filter((key) => typeof key === "string");
|
|
1258
|
-
}
|
|
1259
|
-
let seeds = this.store.getSnapshot().seeds;
|
|
1260
|
-
if (value !== null && typeof value === "object" && "seeds" in value) {
|
|
1261
|
-
const wireSeeds = value.seeds;
|
|
1262
|
-
if (Array.isArray(wireSeeds)) seeds = parseSeedsWire(wireSeeds);
|
|
1263
|
-
}
|
|
1264
|
-
const subagentPolicy = subagentPolicyFromWire(value, this.store.getSnapshot().subagentPolicy);
|
|
1265
|
-
this.accept(config, true, legacyKeys, seeds, subagentPolicy);
|
|
1266
|
-
return revertOutcomePersona(value);
|
|
1267
|
-
} catch (error) {
|
|
1268
|
-
if (generation !== this.writeGeneration) return void 0;
|
|
1269
|
-
this.fail(error);
|
|
1270
|
-
return;
|
|
1271
|
-
}
|
|
1281
|
+
fetchSubagentRole(sessionId) {
|
|
1282
|
+
return fetchSubagentRoleRecord(this.rpc, sessionId);
|
|
1272
1283
|
}
|
|
1273
1284
|
/** Stop in-flight responses from publishing after plugin disposal. */
|
|
1274
1285
|
dispose() {
|
|
@@ -1469,9 +1480,11 @@ window.__ModuleLoader__.load({
|
|
|
1469
1480
|
"roles.idPlaceholder": "例如 reviewer",
|
|
1470
1481
|
"roles.persona": "人格提示",
|
|
1471
1482
|
"roles.personaPlaceholder": "例如:你是资深代码审查员",
|
|
1472
|
-
"roles.
|
|
1473
|
-
"roles.
|
|
1474
|
-
"roles.
|
|
1483
|
+
"roles.persona.expand": "展开人格提示",
|
|
1484
|
+
"roles.persona.collapse": "收起人格提示",
|
|
1485
|
+
"roles.persona.empty": "(未设置)",
|
|
1486
|
+
"roles.seedSource.bundled": "内置",
|
|
1487
|
+
"roles.seedSource.user": "用户",
|
|
1475
1488
|
"roles.seedChainOptional": "角色 \"{id}\" 为 seed 角色:链可留空,保存不会被拦截",
|
|
1476
1489
|
"roles.fallback": "链拼接策略",
|
|
1477
1490
|
"roles.fallback.inherit-root": "继承 root(角色链后追加 rootChain)",
|
|
@@ -1540,6 +1553,7 @@ window.__ModuleLoader__.load({
|
|
|
1540
1553
|
"chat.switch.summary": "{from} → {to}({reason})",
|
|
1541
1554
|
"chat.switch.summary.roleInject": "({reason})",
|
|
1542
1555
|
"chat.switch.roleMap": "{role} → {model}",
|
|
1556
|
+
"subagentRole.hover": "{role} → {model}",
|
|
1543
1557
|
"defaults.prefix": "默认值",
|
|
1544
1558
|
"save": "保存",
|
|
1545
1559
|
"save.saving": "保存中…",
|
|
@@ -1661,9 +1675,11 @@ window.__ModuleLoader__.load({
|
|
|
1661
1675
|
"roles.idPlaceholder": "e.g. reviewer",
|
|
1662
1676
|
"roles.persona": "Persona",
|
|
1663
1677
|
"roles.personaPlaceholder": "e.g. you are a senior code reviewer",
|
|
1664
|
-
"roles.
|
|
1665
|
-
"roles.
|
|
1666
|
-
"roles.
|
|
1678
|
+
"roles.persona.expand": "Expand persona",
|
|
1679
|
+
"roles.persona.collapse": "Collapse persona",
|
|
1680
|
+
"roles.persona.empty": "(not set)",
|
|
1681
|
+
"roles.seedSource.bundled": "bundled",
|
|
1682
|
+
"roles.seedSource.user": "User",
|
|
1667
1683
|
"roles.seedChainOptional": "Role \"{id}\" is a seed role: the chain may stay empty",
|
|
1668
1684
|
"roles.fallback": "Chain append",
|
|
1669
1685
|
"roles.fallback.inherit-root": "Inherit root (append rootChain after the role chain)",
|
|
@@ -1732,6 +1748,7 @@ window.__ModuleLoader__.load({
|
|
|
1732
1748
|
"chat.switch.summary": "{from} → {to} ({reason})",
|
|
1733
1749
|
"chat.switch.summary.roleInject": "({reason})",
|
|
1734
1750
|
"chat.switch.roleMap": "{role} → {model}",
|
|
1751
|
+
"subagentRole.hover": "{role} → {model}",
|
|
1735
1752
|
"defaults.prefix": "Default",
|
|
1736
1753
|
"save": "Save",
|
|
1737
1754
|
"save.saving": "Saving…",
|
|
@@ -1779,13 +1796,13 @@ window.__ModuleLoader__.load({
|
|
|
1779
1796
|
}
|
|
1780
1797
|
//#endregion
|
|
1781
1798
|
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/FallbacksCard.module.css.mjs
|
|
1782
|
-
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\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._ba240d82_sectionHeading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._ddbc1b49_sectionHeadingText {\n flex: 1;\n min-width: 0;\n}\n\n\n._c41f9db7_sectionActions {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-left: auto;\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._b1962759_slotPresetName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\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._c4ecbdf3_dayRow {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n._0330c1ed_dayCell {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: 6px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._0330c1ed_dayCell:hover:has(input:not(:disabled)) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._0330c1ed_dayCell 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._0330c1ed_dayCell input:disabled {\n cursor: default;\n}\n\n._0330c1ed_dayCell input:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\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\n._86bc52d2_collapseRow {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n._a73efcc6_collapseToggle {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n font: inherit;\n text-align: left;\n}\n\n._a73efcc6_collapseToggle:disabled {\n cursor: default;\n}\n\n._af017718_collapseTitle {\n \n flex: none;\n max-width: 55%;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._2cabe603_collapseMeta {\n \n flex: none;\n margin-left: auto;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n._7b04f727_slotTag {\n flex: none;\n display: inline-flex;\n align-items: center;\n border-radius: 999px;\n padding: 0 6px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n border: 1px solid;\n}\n\n._c381e792_slotTagHighCost {\n color: var(--dsw-alias-state-error-primary);\n border-color: var(--dsw-alias-state-error-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n._23bdb6fc_slotTagMultiplier {\n color: var(--dsw-alias-state-warn-primary);\n border-color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 10%, transparent);\n}\n\n._f000eed9_slotTagActive {\n color: var(--dsw-alias-state-success-primary);\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n}\n\n\n._cd905ce5_dragHandle {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: grab;\n color: var(--dsw-alias-label-tertiary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 6px;\n flex: none;\n}\n\n._cd905ce5_dragHandle:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._cd905ce5_dragHandle:active {\n cursor: grabbing;\n}\n\n._cd905ce5_dragHandle:disabled {\n cursor: default;\n opacity: 0.4;\n}\n\n._cd905ce5_dragHandle:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._49f0c4f0_dragHandleIcon {\n transform: rotate(90deg);\n}\n\n\n._fee63b7e_slotCardDragging {\n opacity: 0.45;\n}\n\n._6f108491_slotCardOver {\n outline: 1px dashed var(--dsw-alias-brand-primary);\n outline-offset: 2px;\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._6a2bd54c_slotAddRow {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n\n._4e77523e_rowActions {\n display: flex;\n align-items: center;\n gap: 4px;\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._238d19be_sectionAction {\n height: 28px;\n padding: 0 12px;\n border-radius: 14px;\n font-size: 12px;\n line-height: 18px;\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._700006c9_policyStatus {\n margin: 12px 0 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n._d4b67a81_policyStatusLabel {\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n\n._278bb4b3_policyStatusLine {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n}\n\n._da6387e5_policyStatusWarn {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._70effa64_iconButton::after {\n transition: none;\n }\n}\n";
|
|
1783
|
-
const tagId$
|
|
1784
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
1799
|
+
const css$3 = "\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\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._ba240d82_sectionHeading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._ddbc1b49_sectionHeadingText {\n flex: 1;\n min-width: 0;\n}\n\n\n._c41f9db7_sectionActions {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-left: auto;\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._b1962759_slotPresetName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\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._c4ecbdf3_dayRow {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n._0330c1ed_dayCell {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: 6px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._0330c1ed_dayCell:hover:has(input:not(:disabled)) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._0330c1ed_dayCell 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._0330c1ed_dayCell input:disabled {\n cursor: default;\n}\n\n._0330c1ed_dayCell input:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\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._1285c19b_personaBriefRow {\n display: flex;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n\n._4b8f7345_personaBrief {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n}\n\n\n._2686400e_personaBriefEmpty {\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._4e4a07be_personaFull {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-secondary);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\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\n._86bc52d2_collapseRow {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n._a73efcc6_collapseToggle {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n font: inherit;\n text-align: left;\n}\n\n._a73efcc6_collapseToggle:disabled {\n cursor: default;\n}\n\n._af017718_collapseTitle {\n \n flex: none;\n max-width: 55%;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._2cabe603_collapseMeta {\n \n flex: none;\n margin-left: auto;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n._52d6df87_seedBadge {\n flex: none;\n max-width: 40%;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\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-layer-1);\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._7b04f727_slotTag {\n flex: none;\n display: inline-flex;\n align-items: center;\n border-radius: 999px;\n padding: 0 6px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n border: 1px solid;\n}\n\n._c381e792_slotTagHighCost {\n color: var(--dsw-alias-state-error-primary);\n border-color: var(--dsw-alias-state-error-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n._23bdb6fc_slotTagMultiplier {\n color: var(--dsw-alias-state-warn-primary);\n border-color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 10%, transparent);\n}\n\n._f000eed9_slotTagActive {\n color: var(--dsw-alias-state-success-primary);\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n}\n\n\n._cd905ce5_dragHandle {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: grab;\n color: var(--dsw-alias-label-tertiary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 6px;\n flex: none;\n}\n\n._cd905ce5_dragHandle:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._cd905ce5_dragHandle:active {\n cursor: grabbing;\n}\n\n._cd905ce5_dragHandle:disabled {\n cursor: default;\n opacity: 0.4;\n}\n\n._cd905ce5_dragHandle:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n._49f0c4f0_dragHandleIcon {\n transform: rotate(90deg);\n}\n\n\n._fee63b7e_slotCardDragging {\n opacity: 0.45;\n}\n\n._6f108491_slotCardOver {\n outline: 1px dashed var(--dsw-alias-brand-primary);\n outline-offset: 2px;\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._6a2bd54c_slotAddRow {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n\n._4e77523e_rowActions {\n display: flex;\n align-items: center;\n gap: 4px;\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._238d19be_sectionAction {\n height: 28px;\n padding: 0 12px;\n border-radius: 14px;\n font-size: 12px;\n line-height: 18px;\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._700006c9_policyStatus {\n margin: 12px 0 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n._d4b67a81_policyStatusLabel {\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n\n._278bb4b3_policyStatusLine {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n}\n\n._da6387e5_policyStatusWarn {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._70effa64_iconButton::after {\n transition: none;\n }\n}\n";
|
|
1800
|
+
const tagId$3 = "dsh-llm-fallbacks/FallbacksCard.module.css";
|
|
1801
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1785
1802
|
const tag = document.createElement("style");
|
|
1786
1803
|
tag.dataset.plugin = "dsh-llm-fallbacks";
|
|
1787
|
-
tag.dataset.pluginCss = tagId$
|
|
1788
|
-
tag.textContent = css$
|
|
1804
|
+
tag.dataset.pluginCss = tagId$3;
|
|
1805
|
+
tag.textContent = css$3;
|
|
1789
1806
|
document.head.appendChild(tag);
|
|
1790
1807
|
}
|
|
1791
1808
|
var FallbacksCard_module_css_default = {
|
|
@@ -1828,6 +1845,10 @@ window.__ModuleLoader__.load({
|
|
|
1828
1845
|
"dayCell": "_0330c1ed_dayCell",
|
|
1829
1846
|
"input": "_f9d86f7b_input",
|
|
1830
1847
|
"inputTextarea": "_3a9b42fd_inputTextarea",
|
|
1848
|
+
"personaBriefRow": "_1285c19b_personaBriefRow",
|
|
1849
|
+
"personaBrief": "_4b8f7345_personaBrief",
|
|
1850
|
+
"personaBriefEmpty": "_2686400e_personaBriefEmpty",
|
|
1851
|
+
"personaFull": "_4e4a07be_personaFull",
|
|
1831
1852
|
"inputInvalid": "_7b60337a_inputInvalid",
|
|
1832
1853
|
"selectInput": "_16eb7153_selectInput",
|
|
1833
1854
|
"numberFields": "_3e95886d_numberFields",
|
|
@@ -1840,6 +1861,7 @@ window.__ModuleLoader__.load({
|
|
|
1840
1861
|
"collapseToggle": "_a73efcc6_collapseToggle",
|
|
1841
1862
|
"collapseTitle": "_af017718_collapseTitle",
|
|
1842
1863
|
"collapseMeta": "_2cabe603_collapseMeta",
|
|
1864
|
+
"seedBadge": "_52d6df87_seedBadge",
|
|
1843
1865
|
"slotTag": "_7b04f727_slotTag",
|
|
1844
1866
|
"slotTagHighCost": "_c381e792_slotTagHighCost",
|
|
1845
1867
|
"slotTagMultiplier": "_23bdb6fc_slotTagMultiplier",
|
|
@@ -2089,6 +2111,22 @@ window.__ModuleLoader__.load({
|
|
|
2089
2111
|
};
|
|
2090
2112
|
}
|
|
2091
2113
|
/**
|
|
2114
|
+
* Badge label for one row's provenance (plan role-card-seeded-ux): every
|
|
2115
|
+
* row states where its seed state comes from. A live seed renders its
|
|
2116
|
+
* declaring set's label VERBATIM (case-preserved — no case-folding; the
|
|
2117
|
+
* unnamed case is the literal `external`), the bundled presets and the
|
|
2118
|
+
* operator's own rows resolve to their localized labels. `null` = no
|
|
2119
|
+
* badge: a currently-seeded row whose wire entry lacks `source` (gateway
|
|
2120
|
+
* version skew) — the degradation path, never an error.
|
|
2121
|
+
*/
|
|
2122
|
+
function seedBadgeLabel(seed, t) {
|
|
2123
|
+
if (seed === void 0) return t("roles.seedSource.user");
|
|
2124
|
+
if (seed.source === void 0) return null;
|
|
2125
|
+
if (seed.source === "bundled") return t("roles.seedSource.bundled");
|
|
2126
|
+
if (seed.source === "user") return t("roles.seedSource.user");
|
|
2127
|
+
return seed.source;
|
|
2128
|
+
}
|
|
2129
|
+
/**
|
|
2092
2130
|
* Pre-save validation of the assembled draft (spec §8 / plan Task 3):
|
|
2093
2131
|
* role id format/reserved word/duplicates, undeclared rule role references
|
|
2094
2132
|
* (only reachable through the synthetic outside option — the dropdown
|
|
@@ -2102,13 +2140,13 @@ window.__ModuleLoader__.load({
|
|
|
2102
2140
|
* {@link save} — the draft is never written. `persona` is free text and
|
|
2103
2141
|
* never validated.
|
|
2104
2142
|
*
|
|
2105
|
-
* `
|
|
2143
|
+
* `seedInfo` is the live trimmed-id → seed-entry map derived from
|
|
2106
2144
|
* `state.seeds` (spec §9.4): the empty-chain block relaxes for seeded ids
|
|
2107
2145
|
* only (spec §9.6 / AC-3 — a seeded role's chain is legitimately empty by
|
|
2108
|
-
* design, R4, and
|
|
2109
|
-
* behavior is byte-identical.
|
|
2146
|
+
* design, R4, and the row must stay persistable through a section save);
|
|
2147
|
+
* non-seeded behavior is byte-identical.
|
|
2110
2148
|
*/
|
|
2111
|
-
function validateDraft(draft, t,
|
|
2149
|
+
function validateDraft(draft, t, seedInfo) {
|
|
2112
2150
|
const errors = emptyValidationErrors();
|
|
2113
2151
|
const declaredIds = /* @__PURE__ */ new Set();
|
|
2114
2152
|
for (const role of draft.roles.list) {
|
|
@@ -2124,7 +2162,7 @@ window.__ModuleLoader__.load({
|
|
|
2124
2162
|
message: error.message
|
|
2125
2163
|
}));
|
|
2126
2164
|
}
|
|
2127
|
-
if ((role.chain ?? []).length === 0 && !
|
|
2165
|
+
if ((role.chain ?? []).length === 0 && !seedInfo.has(role.id.trim())) errors.sub.push(t("validation.roleChainRequired", { id: role.id }));
|
|
2128
2166
|
}
|
|
2129
2167
|
const allDayTail = draft.rootChain.length >= 1 ? draft.rootChain[draft.rootChain.length - 1] : void 0;
|
|
2130
2168
|
if (allDayTail !== ALL_DAY_FLASH && allDayTail !== ALL_DAY_PRO) errors.main.push(t("validation.allDayRequired"));
|
|
@@ -2422,7 +2460,6 @@ window.__ModuleLoader__.load({
|
|
|
2422
2460
|
]);
|
|
2423
2461
|
const dirty = mainDirty || subDirty || advancedDirty;
|
|
2424
2462
|
const firstSeedDone = (0, react.useRef)(false);
|
|
2425
|
-
const forceReseed = (0, react.useRef)(false);
|
|
2426
2463
|
(0, react.useEffect)(() => {
|
|
2427
2464
|
if (state.status !== "ready") return;
|
|
2428
2465
|
const key = JSON.stringify(state.config);
|
|
@@ -2430,10 +2467,8 @@ window.__ModuleLoader__.load({
|
|
|
2430
2467
|
seededConfigKey.current = key;
|
|
2431
2468
|
const firstSeed = !firstSeedDone.current;
|
|
2432
2469
|
firstSeedDone.current = true;
|
|
2433
|
-
const force = forceReseed.current;
|
|
2434
|
-
forceReseed.current = false;
|
|
2435
2470
|
const catalog = catalogOf(state);
|
|
2436
|
-
if (firstSeed ||
|
|
2471
|
+
if (firstSeed || !mainDirty) {
|
|
2437
2472
|
setAllDayModel(allDayModelOf(state.config.rootChain));
|
|
2438
2473
|
setAllDayChainRow(allDayChainRowOf(state.config.rootChain, catalog));
|
|
2439
2474
|
setTimeSlotRows(timeSlotsToRows(state.config.timeSlots ?? [], catalog));
|
|
@@ -2443,11 +2478,11 @@ window.__ModuleLoader__.load({
|
|
|
2443
2478
|
tz: state.config.tz ?? "Asia/Shanghai"
|
|
2444
2479
|
}));
|
|
2445
2480
|
}
|
|
2446
|
-
if (firstSeed ||
|
|
2481
|
+
if (firstSeed || !subDirty) {
|
|
2447
2482
|
setRoleRows(rolesToRows(state.config.roles.list, catalog));
|
|
2448
2483
|
setRuleRows(rulesToRows(state.config.roles.rules, catalog));
|
|
2449
2484
|
}
|
|
2450
|
-
if (firstSeed ||
|
|
2485
|
+
if (firstSeed || !advancedDirty) setScalars((prev) => ({
|
|
2451
2486
|
...prev,
|
|
2452
2487
|
triggerCodes: [...state.config.triggerCodes],
|
|
2453
2488
|
cooldownMs: state.config.cooldownMs,
|
|
@@ -2635,7 +2670,8 @@ window.__ModuleLoader__.load({
|
|
|
2635
2670
|
persona: "",
|
|
2636
2671
|
selectors: [],
|
|
2637
2672
|
fallback: "inherit-root",
|
|
2638
|
-
collapsed: true
|
|
2673
|
+
collapsed: true,
|
|
2674
|
+
personaOpen: false
|
|
2639
2675
|
}]);
|
|
2640
2676
|
};
|
|
2641
2677
|
const removeRole = (index) => {
|
|
@@ -2666,8 +2702,11 @@ window.__ModuleLoader__.load({
|
|
|
2666
2702
|
const roleOptions = ruleRoleOptions({ list: roleRows });
|
|
2667
2703
|
const invalidRoleIds = validationAttempted ? collectInvalidRoleIds(roleRows) : null;
|
|
2668
2704
|
const invalidSlotRows = validationAttempted ? collectInvalidSlotRows(timeSlotRows) : null;
|
|
2669
|
-
const
|
|
2670
|
-
for (const seed of state.seeds)
|
|
2705
|
+
const seedInfo = /* @__PURE__ */ new Map();
|
|
2706
|
+
for (const seed of state.seeds) seedInfo.set(seed.id.trim(), {
|
|
2707
|
+
overridden: seed.overridden,
|
|
2708
|
+
source: seed.source
|
|
2709
|
+
});
|
|
2671
2710
|
const latestSwitch = state.switches[0];
|
|
2672
2711
|
let switchesLine;
|
|
2673
2712
|
if (state.switchesStatus === "error") switchesLine = t("status.switches.error", { message: state.switchesError });
|
|
@@ -2745,7 +2784,7 @@ window.__ModuleLoader__.load({
|
|
|
2745
2784
|
};
|
|
2746
2785
|
const save = (section) => {
|
|
2747
2786
|
setLastSaveSection(section);
|
|
2748
|
-
const errors = validateDraft(draft, t,
|
|
2787
|
+
const errors = validateDraft(draft, t, seedInfo);
|
|
2749
2788
|
if (section === "sub" && hasEmptyRuleRows) errors.sub.push(t("validation.ruleRoleRequired"));
|
|
2750
2789
|
if (errors[section].length > 0) {
|
|
2751
2790
|
setValidationErrors(errors);
|
|
@@ -2804,7 +2843,7 @@ window.__ModuleLoader__.load({
|
|
|
2804
2843
|
};
|
|
2805
2844
|
(0, react.useEffect)(() => {
|
|
2806
2845
|
if (!validationAttempted) return;
|
|
2807
|
-
const errors = validateDraft(draft, t,
|
|
2846
|
+
const errors = validateDraft(draft, t, seedInfo);
|
|
2808
2847
|
if (errors.main.length === 0 && errors.sub.length === 0 && errors.advanced.length === 0 && !ruleRows.some((row) => row.role === "")) {
|
|
2809
2848
|
setValidationErrors(emptyValidationErrors());
|
|
2810
2849
|
setValidationAttempted(false);
|
|
@@ -2817,7 +2856,6 @@ window.__ModuleLoader__.load({
|
|
|
2817
2856
|
]);
|
|
2818
2857
|
(0, react.useEffect)(() => {
|
|
2819
2858
|
if (state.status === "ready") setLastSaveSection(null);
|
|
2820
|
-
if (state.status === "error") forceReseed.current = false;
|
|
2821
2859
|
}, [state.status]);
|
|
2822
2860
|
const [userOpen, setUserOpen] = (0, react.useState)(false);
|
|
2823
2861
|
const [advancedOpen, setAdvancedOpen] = (0, react.useState)(false);
|
|
@@ -3536,7 +3574,9 @@ window.__ModuleLoader__.load({
|
|
|
3536
3574
|
className: FallbacksCard_module_css_default.list,
|
|
3537
3575
|
children: roleRows.map((row, index) => {
|
|
3538
3576
|
const invalid = invalidRoleIds?.has(row.id.trim()) ?? false;
|
|
3539
|
-
const seed =
|
|
3577
|
+
const seed = seedInfo.get(row.id.trim());
|
|
3578
|
+
const seedBadge = seedBadgeLabel(seed, t);
|
|
3579
|
+
const personaBlank = row.persona.trim() === "";
|
|
3540
3580
|
const roleSummary = row.selectors.map(selectorRowToRaw).find((entry) => entry !== "") ?? row.fallback;
|
|
3541
3581
|
const roleExpanded = !row.collapsed || !writable;
|
|
3542
3582
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -3558,6 +3598,11 @@ window.__ModuleLoader__.load({
|
|
|
3558
3598
|
className: FallbacksCard_module_css_default.collapseTitle,
|
|
3559
3599
|
children: row.id
|
|
3560
3600
|
}),
|
|
3601
|
+
seedBadge !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3602
|
+
className: FallbacksCard_module_css_default.seedBadge,
|
|
3603
|
+
title: seedBadge,
|
|
3604
|
+
children: seedBadge
|
|
3605
|
+
}),
|
|
3561
3606
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3562
3607
|
className: FallbacksCard_module_css_default.collapseMeta,
|
|
3563
3608
|
children: roleSummary
|
|
@@ -3565,7 +3610,7 @@ window.__ModuleLoader__.load({
|
|
|
3565
3610
|
]
|
|
3566
3611
|
})
|
|
3567
3612
|
}), roleExpanded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3568
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3613
|
+
seed === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3569
3614
|
className: FallbacksCard_module_css_default.ruleGrid,
|
|
3570
3615
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3571
3616
|
className: FallbacksCard_module_css_default.ruleCell,
|
|
@@ -3580,7 +3625,7 @@ window.__ModuleLoader__.load({
|
|
|
3580
3625
|
placeholder: t("roles.idPlaceholder"),
|
|
3581
3626
|
"aria-label": t("roles.id"),
|
|
3582
3627
|
"aria-invalid": invalid ? true : void 0,
|
|
3583
|
-
disabled: !writable
|
|
3628
|
+
disabled: !writable,
|
|
3584
3629
|
onChange: (event) => {
|
|
3585
3630
|
updateRoleRow(index, { id: event.target.value });
|
|
3586
3631
|
}
|
|
@@ -3596,42 +3641,46 @@ window.__ModuleLoader__.load({
|
|
|
3596
3641
|
className: FallbacksCard_module_css_default.ruleGrid,
|
|
3597
3642
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3598
3643
|
className: FallbacksCard_module_css_default.ruleCell,
|
|
3599
|
-
children: [
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3644
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3645
|
+
className: FallbacksCard_module_css_default.ruleCellLabel,
|
|
3646
|
+
children: t("roles.persona")
|
|
3647
|
+
}), seed === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
3648
|
+
rows: 3,
|
|
3649
|
+
className: `${FallbacksCard_module_css_default.input} ${FallbacksCard_module_css_default.inputTextarea}`,
|
|
3650
|
+
value: row.persona,
|
|
3651
|
+
placeholder: t("roles.personaPlaceholder"),
|
|
3652
|
+
"aria-label": t("roles.persona"),
|
|
3653
|
+
disabled: !writable,
|
|
3654
|
+
onChange: (event) => {
|
|
3655
|
+
updateRoleRow(index, { persona: event.target.value });
|
|
3656
|
+
}
|
|
3657
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3658
|
+
className: FallbacksCard_module_css_default.personaBriefRow,
|
|
3659
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3660
|
+
className: personaBlank ? `${FallbacksCard_module_css_default.personaBrief} ${FallbacksCard_module_css_default.personaBriefEmpty}` : FallbacksCard_module_css_default.personaBrief,
|
|
3661
|
+
children: personaBlank ? t("roles.persona.empty") : row.persona
|
|
3662
|
+
}), !personaBlank && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3663
|
+
role: "button",
|
|
3664
|
+
tabIndex: 0,
|
|
3665
|
+
className: FallbacksCard_module_css_default.iconButton,
|
|
3666
|
+
"aria-expanded": row.personaOpen,
|
|
3667
|
+
"aria-label": t(row.personaOpen ? "roles.persona.collapse" : "roles.persona.expand"),
|
|
3668
|
+
"data-tip": t(row.personaOpen ? "roles.persona.collapse" : "roles.persona.expand"),
|
|
3669
|
+
onClick: () => {
|
|
3670
|
+
updateRoleRow(index, { personaOpen: !row.personaOpen });
|
|
3671
|
+
},
|
|
3672
|
+
onKeyDown: (event) => {
|
|
3673
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
3674
|
+
event.preventDefault();
|
|
3675
|
+
updateRoleRow(index, { personaOpen: !row.personaOpen });
|
|
3676
|
+
}
|
|
3677
|
+
},
|
|
3678
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: row.personaOpen ? `${FallbacksCard_module_css_default.chevron} ${FallbacksCard_module_css_default.chevronOpen}` : FallbacksCard_module_css_default.chevron })
|
|
3679
|
+
})]
|
|
3680
|
+
}), row.personaOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3681
|
+
className: FallbacksCard_module_css_default.personaFull,
|
|
3682
|
+
children: row.persona
|
|
3683
|
+
})] })]
|
|
3635
3684
|
})
|
|
3636
3685
|
}),
|
|
3637
3686
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -4212,13 +4261,13 @@ window.__ModuleLoader__.load({
|
|
|
4212
4261
|
}
|
|
4213
4262
|
//#endregion
|
|
4214
4263
|
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/GeneralFallbacksRow.module.css.mjs
|
|
4215
|
-
const css$
|
|
4216
|
-
const tagId$
|
|
4217
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
4264
|
+
const css$2 = "\n\n._440e1d7b_row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 0;\n border-bottom: 1px solid var(--dsw-alias-border-l2);\n}\n\n._a4f2ceec_rowText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-right: 48px;\n}\n\n._9865b509_title {\n font-size: 14px;\n font-weight: 400;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n}\n\n\n._10a44713_summary {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n._35648278_badge {\n flex: none;\n padding: 2px 10px;\n border-radius: 9px;\n font-size: 12px;\n line-height: 18px;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._3b9e8609_badgeEnabled {\n color: var(--dsw-alias-state-success-primary);\n}\n";
|
|
4265
|
+
const tagId$2 = "dsh-llm-fallbacks/GeneralFallbacksRow.module.css";
|
|
4266
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
4218
4267
|
const tag = document.createElement("style");
|
|
4219
4268
|
tag.dataset.plugin = "dsh-llm-fallbacks";
|
|
4220
|
-
tag.dataset.pluginCss = tagId$
|
|
4221
|
-
tag.textContent = css$
|
|
4269
|
+
tag.dataset.pluginCss = tagId$2;
|
|
4270
|
+
tag.textContent = css$2;
|
|
4222
4271
|
document.head.appendChild(tag);
|
|
4223
4272
|
}
|
|
4224
4273
|
var GeneralFallbacksRow_module_css_default = {
|
|
@@ -4337,13 +4386,13 @@ window.__ModuleLoader__.load({
|
|
|
4337
4386
|
}
|
|
4338
4387
|
//#endregion
|
|
4339
4388
|
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/ConversationFallbackSwitch.module.css.mjs
|
|
4340
|
-
const css = "\n\n._ea99bbef_switchRow {\n display: flex;\n align-items: center;\n padding: 2px 0;\n font-size: 14px;\n line-height: 24px;\n}\n\n\n._02580bfd_switchTitle {\n flex: none;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._88b2d18b_switchSep {\n flex: none;\n width: 2px;\n height: 2px;\n margin: 0 8px;\n border-radius: 1px;\n background: var(--dsw-alias-label-caption);\n}\n\n\n._7c8c1b6f_switchSummary {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._fdc977bc_roleBadge {\n flex: none;\n max-width: 96px;\n padding: 0 8px;\n border-radius: 999px;\n font-size: 12px;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-primary);\n}\n\n\n._dce8ba28_roleModelMap {\n flex: 0 1 auto;\n min-width: 0;\n margin-left: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-secondary);\n}\n";
|
|
4341
|
-
const tagId = "dsh-llm-fallbacks/ConversationFallbackSwitch.module.css";
|
|
4342
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
4389
|
+
const css$1 = "\n\n._ea99bbef_switchRow {\n display: flex;\n align-items: center;\n padding: 2px 0;\n font-size: 14px;\n line-height: 24px;\n}\n\n\n._02580bfd_switchTitle {\n flex: none;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._88b2d18b_switchSep {\n flex: none;\n width: 2px;\n height: 2px;\n margin: 0 8px;\n border-radius: 1px;\n background: var(--dsw-alias-label-caption);\n}\n\n\n._7c8c1b6f_switchSummary {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n\n._fdc977bc_roleBadge {\n flex: none;\n max-width: 96px;\n padding: 0 8px;\n border-radius: 999px;\n font-size: 12px;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-primary);\n}\n\n\n._dce8ba28_roleModelMap {\n flex: 0 1 auto;\n min-width: 0;\n margin-left: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-secondary);\n}\n";
|
|
4390
|
+
const tagId$1 = "dsh-llm-fallbacks/ConversationFallbackSwitch.module.css";
|
|
4391
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
4343
4392
|
const tag = document.createElement("style");
|
|
4344
4393
|
tag.dataset.plugin = "dsh-llm-fallbacks";
|
|
4345
|
-
tag.dataset.pluginCss = tagId;
|
|
4346
|
-
tag.textContent = css;
|
|
4394
|
+
tag.dataset.pluginCss = tagId$1;
|
|
4395
|
+
tag.textContent = css$1;
|
|
4347
4396
|
document.head.appendChild(tag);
|
|
4348
4397
|
}
|
|
4349
4398
|
var ConversationFallbackSwitch_module_css_default = {
|
|
@@ -4475,6 +4524,118 @@ window.__ModuleLoader__.load({
|
|
|
4475
4524
|
});
|
|
4476
4525
|
}
|
|
4477
4526
|
//#endregion
|
|
4527
|
+
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/SubagentRoleBadge.module.css.mjs
|
|
4528
|
+
const css = "\n\n._35648278_badge {\n display: inline-block;\n max-width: 120px;\n padding: 0 8px;\n border-radius: 999px;\n font-size: 12px;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: middle;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-primary);\n}\n";
|
|
4529
|
+
const tagId = "dsh-llm-fallbacks/SubagentRoleBadge.module.css";
|
|
4530
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
4531
|
+
const tag = document.createElement("style");
|
|
4532
|
+
tag.dataset.plugin = "dsh-llm-fallbacks";
|
|
4533
|
+
tag.dataset.pluginCss = tagId;
|
|
4534
|
+
tag.textContent = css;
|
|
4535
|
+
document.head.appendChild(tag);
|
|
4536
|
+
}
|
|
4537
|
+
var SubagentRoleBadge_module_css_default = { "badge": "_35648278_badge" };
|
|
4538
|
+
//#endregion
|
|
4539
|
+
//#region src/client/SubagentRoleBadge.tsx
|
|
4540
|
+
/**
|
|
4541
|
+
* Session-header subagent role badge (plan subagent-role-badge T3): a
|
|
4542
|
+
* compact read-only pill in `conversation.session.header.utilities` showing
|
|
4543
|
+
* which Subagent role the viewed session's dispatch resolved, hovering as
|
|
4544
|
+
* `role → provider/model`.
|
|
4545
|
+
*
|
|
4546
|
+
* Contract notes (verified 2026-09-09 against the harness checkout):
|
|
4547
|
+
* - The slot is `kind: 'list'`, `scope: 'session'`, owner props an empty
|
|
4548
|
+
* marker (`ConversationHeaderActionOwnerProps`, `children?: never`) — the
|
|
4549
|
+
* header renders occupants with `renderSlot(..., {})`, so ALL data flows
|
|
4550
|
+
* through this component's inject face and the session standard kit.
|
|
4551
|
+
* - Every `scope: 'session'` occupant receives the session standard kit
|
|
4552
|
+
* (`sessionId` + `useSession` + `useProjection`; ui-session
|
|
4553
|
+
* `src/client/index.ts:112-119`, merged into the runtime share by ui-slots'
|
|
4554
|
+
* `PropsRuntime`) — the fetch keys off the `sessionId` prop directly (mount
|
|
4555
|
+
* + whenever the prop changes; the slot machinery remounts the occupant per
|
|
4556
|
+
* viewed session — no manual session subscription). The compiled peer types
|
|
4557
|
+
* do not carry the ui-session standard-props merge into this plugin's
|
|
4558
|
+
* typecheck program (that package is deliberately not a plugin peer), so
|
|
4559
|
+
* the seat is read structurally and guarded — a version-skewed host without
|
|
4560
|
+
* it renders nothing, never throws.
|
|
4561
|
+
* - Data: `fallbacks/subagent-roles` gateway readbacks via the injected fetch
|
|
4562
|
+
* face ({@link fetchSubagentRoleRecord} — never throws): one on mount +
|
|
4563
|
+
* whenever the viewed session changes, then a BOUNDED delayed re-probe
|
|
4564
|
+
* while no record has landed (the record is written at the subagent's first
|
|
4565
|
+
* dispatch request, which can land after this header mounted).
|
|
4566
|
+
* - Render-only discipline (C4 pattern, same as `ConversationFallbackSwitch`):
|
|
4567
|
+
* the badge contributes a view; no message construction, no model-context
|
|
4568
|
+
* injection. Degrade-never-crash: a missing record, an `inherit` role, or
|
|
4569
|
+
* ANY readback error renders `null` — the utilities strip collapses cleanly.
|
|
4570
|
+
*/
|
|
4571
|
+
/**
|
|
4572
|
+
* Bounded delayed re-probe (QC fix wave F-001): while the viewed session has
|
|
4573
|
+
* no record yet, re-fetch up to {@link ROLE_RECORD_PROBES} times
|
|
4574
|
+
* {@link ROLE_RECORD_PROBE_DELAY_MS} apart (~10s window) and stop on the
|
|
4575
|
+
* first record, a session switch, or unmount. The record is written once, at
|
|
4576
|
+
* the subagent's FIRST dispatch request — a header opened before that moment
|
|
4577
|
+
* would otherwise never see the badge until remount.
|
|
4578
|
+
*/
|
|
4579
|
+
const ROLE_RECORD_PROBE_DELAY_MS = 2e3;
|
|
4580
|
+
const ROLE_RECORD_PROBES = 5;
|
|
4581
|
+
/**
|
|
4582
|
+
* Render the viewed session's dispatch-resolved role badge.
|
|
4583
|
+
* @param props - composed slot props (the `sessionId` session-kit seat is
|
|
4584
|
+
* read structurally — see the module docblock).
|
|
4585
|
+
* @returns the badge element, or `null` when there is nothing to show.
|
|
4586
|
+
*/
|
|
4587
|
+
function SubagentRoleBadge(props) {
|
|
4588
|
+
const { t, controller } = props;
|
|
4589
|
+
const seatSessionId = props.sessionId;
|
|
4590
|
+
const sessionId = typeof seatSessionId === "string" && seatSessionId !== "" ? seatSessionId : void 0;
|
|
4591
|
+
const [stamped, setStamped] = (0, react.useState)({
|
|
4592
|
+
sessionId,
|
|
4593
|
+
record: void 0
|
|
4594
|
+
});
|
|
4595
|
+
if (stamped.sessionId !== sessionId) setStamped({
|
|
4596
|
+
sessionId,
|
|
4597
|
+
record: void 0
|
|
4598
|
+
});
|
|
4599
|
+
const record = stamped.sessionId === sessionId ? stamped.record : void 0;
|
|
4600
|
+
(0, react.useEffect)(() => {
|
|
4601
|
+
if (sessionId === void 0) return;
|
|
4602
|
+
let cancelled = false;
|
|
4603
|
+
let timer;
|
|
4604
|
+
const probe = (attempt) => {
|
|
4605
|
+
controller.fetchSubagentRole(sessionId).then((next) => {
|
|
4606
|
+
if (cancelled) return;
|
|
4607
|
+
if (next !== void 0) {
|
|
4608
|
+
setStamped({
|
|
4609
|
+
sessionId,
|
|
4610
|
+
record: next
|
|
4611
|
+
});
|
|
4612
|
+
return;
|
|
4613
|
+
}
|
|
4614
|
+
if (attempt >= ROLE_RECORD_PROBES) return;
|
|
4615
|
+
timer = setTimeout(() => {
|
|
4616
|
+
timer = void 0;
|
|
4617
|
+
probe(attempt + 1);
|
|
4618
|
+
}, ROLE_RECORD_PROBE_DELAY_MS);
|
|
4619
|
+
});
|
|
4620
|
+
};
|
|
4621
|
+
probe(0);
|
|
4622
|
+
return () => {
|
|
4623
|
+
cancelled = true;
|
|
4624
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
4625
|
+
};
|
|
4626
|
+
}, [controller, sessionId]);
|
|
4627
|
+
if (record === void 0 || record.role === "inherit") return null;
|
|
4628
|
+
const model = record.model === void 0 ? void 0 : `${record.model.provider}/${record.model.model}`;
|
|
4629
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4630
|
+
className: SubagentRoleBadge_module_css_default.badge,
|
|
4631
|
+
title: model === void 0 ? record.role : t("subagentRole.hover", {
|
|
4632
|
+
role: record.role,
|
|
4633
|
+
model
|
|
4634
|
+
}),
|
|
4635
|
+
children: record.role
|
|
4636
|
+
});
|
|
4637
|
+
}
|
|
4638
|
+
//#endregion
|
|
4478
4639
|
//#region src/client/index.ts
|
|
4479
4640
|
/**
|
|
4480
4641
|
* Required services (cordis fiber inject); registrations wait on the slot
|
|
@@ -4591,6 +4752,15 @@ window.__ModuleLoader__.load({
|
|
|
4591
4752
|
locale: NS
|
|
4592
4753
|
}, ConversationFallbackSwitch);
|
|
4593
4754
|
});
|
|
4755
|
+
ctx.slots.inject("conversation.session.header.utilities", function* () {
|
|
4756
|
+
yield ctx.slots.register({
|
|
4757
|
+
name: "conversation.session.header.utilities",
|
|
4758
|
+
id: "fallbacks-subagent-role",
|
|
4759
|
+
order: -20,
|
|
4760
|
+
locale: NS,
|
|
4761
|
+
inject: () => ({ controller })
|
|
4762
|
+
}, SubagentRoleBadge);
|
|
4763
|
+
});
|
|
4594
4764
|
}
|
|
4595
4765
|
//#endregion
|
|
4596
4766
|
exports.FALLBACKS_SETTINGS_NS = FALLBACKS_SETTINGS_NS;
|