dsh-llm-fallbacks 0.4.4 → 0.5.1
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 +86 -25
- package/README.zh-CN.md +86 -25
- package/dist/client/SubagentRoleBadge.d.ts +40 -15
- package/dist/client/fallbacks-store.d.ts +0 -53
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +77 -150
- package/dist/client/locales.d.ts +2 -0
- package/dist/events.d.ts +2 -2
- package/dist/gateway.d.ts +2 -55
- package/dist/index.d.ts +6 -27
- package/dist/index.js +713 -129
- package/dist/role-notice.d.ts +156 -0
- package/dist/role-projection-key.d.ts +41 -0
- package/dist/role-projection.d.ts +151 -0
- package/dist/role-resolution.d.ts +11 -0
- package/dist/roles.d.ts +4 -1
- package/dist/seeds.d.ts +63 -21
- package/dist/subagents-seam.d.ts +292 -0
- package/dist/time-slots.d.ts +3 -2
- package/dist/virtual-adapter.d.ts +42 -6
- package/package.json +27 -25
- package/scripts/build-client.ts +1 -1
- package/scripts/repair-session-logs.ts +2040 -0
- package/scripts/session-logs/catalog.ts +547 -0
- package/scripts/session-logs/classify.ts +47 -0
- package/scripts/session-logs/publish.ts +583 -0
- package/scripts/session-logs/rules.ts +1227 -0
- package/scripts/repair-fallbacks-switch-logs.ts +0 -342
package/dist/client/index.js
CHANGED
|
@@ -413,7 +413,7 @@ window.__ModuleLoader__.load({
|
|
|
413
413
|
* are the ordered walk before that last-resort fallback. An empty chain or
|
|
414
414
|
* a chain whose tail is not an official model (including the retired V4
|
|
415
415
|
* ids) keeps slot rows inert and refuses the virtual-row
|
|
416
|
-
*
|
|
416
|
+
* delegate; the v0.2.2 failure walk over the raw chain stays
|
|
417
417
|
* verbatim.
|
|
418
418
|
*/
|
|
419
419
|
function isAllDayConforming(chain) {
|
|
@@ -610,48 +610,6 @@ window.__ModuleLoader__.load({
|
|
|
610
610
|
return parseSubagentPolicyWire(value.subagentPolicy);
|
|
611
611
|
}
|
|
612
612
|
/**
|
|
613
|
-
* Shape-guard one wire role record (`fallbacks/subagent-roles` readback).
|
|
614
|
-
* A non-object, a blank/non-string `role`, or a non-number `at` fails the
|
|
615
|
-
* WHOLE record (`undefined` → the badge renders nothing). A present-but-
|
|
616
|
-
* malformed `model` drops the FIELD while the record still parses (the
|
|
617
|
-
* `parseSeedsWire` `source` rule) — the badge then hovers the role alone
|
|
618
|
-
* instead of disappearing. Records are NORMALIZED to the known keys, so a
|
|
619
|
-
* wire record can never smuggle a non-string `model` past the guard's type.
|
|
620
|
-
*/
|
|
621
|
-
function parseSubagentRoleRecord(value) {
|
|
622
|
-
if (!isRecord(value)) return void 0;
|
|
623
|
-
if (typeof value.role !== "string" || value.role.trim() === "") return void 0;
|
|
624
|
-
if (typeof value.at !== "number") return void 0;
|
|
625
|
-
const model = parsePolicyRoute(value.model);
|
|
626
|
-
return {
|
|
627
|
-
role: value.role,
|
|
628
|
-
...model === void 0 ? {} : { model },
|
|
629
|
-
at: value.at
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Read this session's dispatch-resolved role record through the plugin
|
|
634
|
-
* gateway channel (plan subagent-role-badge T3): the batch-of-ids endpoint
|
|
635
|
-
* called with the one id the badge cares about. NEVER throws — a channel
|
|
636
|
-
* down, an old gateway without the endpoint (rpc failure), or a malformed
|
|
637
|
-
* payload all resolve `undefined` (the badge renders nothing —
|
|
638
|
-
* degrade-never-crash, the fail-closed shape of `parseSubagentPolicyWire`).
|
|
639
|
-
* @param rpc - the connection's generic RPC caller (`/api` channel).
|
|
640
|
-
* @param sessionId - the session whose record to read.
|
|
641
|
-
* @returns the parsed record, or `undefined` when absent/failed.
|
|
642
|
-
*/
|
|
643
|
-
async function fetchSubagentRoleRecord(rpc, sessionId) {
|
|
644
|
-
try {
|
|
645
|
-
const result = await rpc.call("/api", "fallbacks/subagent-roles", { args: { ids: [sessionId] } });
|
|
646
|
-
if (!result.ok) return void 0;
|
|
647
|
-
const value = result.value;
|
|
648
|
-
if (!isRecord(value)) return void 0;
|
|
649
|
-
return parseSubagentRoleRecord(value[sessionId]);
|
|
650
|
-
} catch {
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
613
|
* The provider dropdown's offer set (spec §2.5 D-4): catalog providers whose
|
|
656
614
|
* settings profile resolves in the describe namespaces — the Models page's
|
|
657
615
|
* `configured` predicate (`ui-models` store.ts): a provider is configured
|
|
@@ -1274,20 +1232,6 @@ window.__ModuleLoader__.load({
|
|
|
1274
1232
|
this.fail(error);
|
|
1275
1233
|
}
|
|
1276
1234
|
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Read one session's dispatch-resolved subagent role record through the
|
|
1279
|
-
* gateway channel (plan subagent-role-badge T3 — the session-header badge's
|
|
1280
|
-
* data face). Thin delegate over {@link fetchSubagentRoleRecord} on the
|
|
1281
|
-
* SAME rpc caller the store rides: the batch-of-ids readback called with
|
|
1282
|
-
* the one id the badge cares about. Never throws — a channel down, an old
|
|
1283
|
-
* gateway without the endpoint, or a malformed payload all resolve
|
|
1284
|
-
* `undefined` (the badge renders nothing).
|
|
1285
|
-
* @param sessionId - the session whose record to read.
|
|
1286
|
-
* @returns the parsed record, or `undefined` when absent/failed.
|
|
1287
|
-
*/
|
|
1288
|
-
fetchSubagentRole(sessionId) {
|
|
1289
|
-
return fetchSubagentRoleRecord(this.rpc, sessionId);
|
|
1290
|
-
}
|
|
1291
1235
|
/** Stop in-flight responses from publishing after plugin disposal. */
|
|
1292
1236
|
dispose() {
|
|
1293
1237
|
this.readGeneration += 1;
|
|
@@ -1492,6 +1436,7 @@ window.__ModuleLoader__.load({
|
|
|
1492
1436
|
"roles.persona.collapse": "收起人格提示",
|
|
1493
1437
|
"roles.persona.empty": "(未设置)",
|
|
1494
1438
|
"roles.seedSource.bundled": "内置",
|
|
1439
|
+
"roles.seedSource.external": "外部",
|
|
1495
1440
|
"roles.seedSource.user": "用户",
|
|
1496
1441
|
"roles.seedChainOptional": "角色 \"{id}\" 为 seed 角色:链可留空,保存不会被拦截",
|
|
1497
1442
|
"roles.fallback": "链拼接策略",
|
|
@@ -1561,7 +1506,7 @@ window.__ModuleLoader__.load({
|
|
|
1561
1506
|
"chat.switch.summary": "{from} → {to}({reason})",
|
|
1562
1507
|
"chat.switch.summary.roleInject": "({reason})",
|
|
1563
1508
|
"chat.switch.roleMap": "{role} → {model}",
|
|
1564
|
-
"subagentRole.hover": "{role} → {model}",
|
|
1509
|
+
"subagentRole.hover": "{role} → {model}(最近一次请求的路由)",
|
|
1565
1510
|
"defaults.prefix": "默认值",
|
|
1566
1511
|
"save": "保存",
|
|
1567
1512
|
"save.saving": "保存中…",
|
|
@@ -1688,6 +1633,7 @@ window.__ModuleLoader__.load({
|
|
|
1688
1633
|
"roles.persona.collapse": "Collapse persona",
|
|
1689
1634
|
"roles.persona.empty": "(not set)",
|
|
1690
1635
|
"roles.seedSource.bundled": "bundled",
|
|
1636
|
+
"roles.seedSource.external": "external",
|
|
1691
1637
|
"roles.seedSource.user": "User",
|
|
1692
1638
|
"roles.seedChainOptional": "Role \"{id}\" is a seed role: the chain may stay empty",
|
|
1693
1639
|
"roles.fallback": "Chain append",
|
|
@@ -1757,7 +1703,7 @@ window.__ModuleLoader__.load({
|
|
|
1757
1703
|
"chat.switch.summary": "{from} → {to} ({reason})",
|
|
1758
1704
|
"chat.switch.summary.roleInject": "({reason})",
|
|
1759
1705
|
"chat.switch.roleMap": "{role} → {model}",
|
|
1760
|
-
"subagentRole.hover": "{role} → {model}",
|
|
1706
|
+
"subagentRole.hover": "{role} → {model} (latest request route)",
|
|
1761
1707
|
"defaults.prefix": "Default",
|
|
1762
1708
|
"save": "Save",
|
|
1763
1709
|
"save.saving": "Saving…",
|
|
@@ -1805,7 +1751,7 @@ window.__ModuleLoader__.load({
|
|
|
1805
1751
|
}
|
|
1806
1752
|
//#endregion
|
|
1807
1753
|
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/FallbacksCard.module.css.mjs
|
|
1808
|
-
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";
|
|
1754
|
+
const css$3 = "\n\n\n._8827595f_card {\n list-style: none;\n min-width: 0;\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 min-width: 0;\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";
|
|
1809
1755
|
const tagId$3 = "dsh-llm-fallbacks/FallbacksCard.module.css";
|
|
1810
1756
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1811
1757
|
const tag = document.createElement("style");
|
|
@@ -2123,17 +2069,19 @@ window.__ModuleLoader__.load({
|
|
|
2123
2069
|
}
|
|
2124
2070
|
/**
|
|
2125
2071
|
* Badge label for one row's provenance (plan role-card-seeded-ux): every
|
|
2126
|
-
* row states where its seed state comes from.
|
|
2127
|
-
*
|
|
2128
|
-
*
|
|
2129
|
-
*
|
|
2130
|
-
*
|
|
2131
|
-
*
|
|
2072
|
+
* row states where its seed state comes from. The three reserved labels
|
|
2073
|
+
* localize — `bundled`, `external` (the shared unnamed-producer slice;
|
|
2074
|
+
* plan seeds-source-and-persona-width), and the operator's own rows —
|
|
2075
|
+
* while a live seed declared under a registered set name renders that
|
|
2076
|
+
* name VERBATIM (case-preserved — no case-folding). `null` = no badge: a
|
|
2077
|
+
* currently-seeded row whose wire entry lacks `source` (gateway version
|
|
2078
|
+
* skew) — the degradation path, never an error.
|
|
2132
2079
|
*/
|
|
2133
2080
|
function seedBadgeLabel(seed, t) {
|
|
2134
2081
|
if (seed === void 0) return t("roles.seedSource.user");
|
|
2135
2082
|
if (seed.source === void 0) return null;
|
|
2136
2083
|
if (seed.source === "bundled") return t("roles.seedSource.bundled");
|
|
2084
|
+
if (seed.source === "external") return t("roles.seedSource.external");
|
|
2137
2085
|
if (seed.source === "user") return t("roles.seedSource.user");
|
|
2138
2086
|
return seed.source;
|
|
2139
2087
|
}
|
|
@@ -4527,6 +4475,40 @@ window.__ModuleLoader__.load({
|
|
|
4527
4475
|
});
|
|
4528
4476
|
}
|
|
4529
4477
|
//#endregion
|
|
4478
|
+
//#region src/role-projection-key.ts
|
|
4479
|
+
/**
|
|
4480
|
+
* The session-projection contract of the subagent role pill (plan
|
|
4481
|
+
* role-based-subagent-adoption Task 3b): the ONE key the host fold
|
|
4482
|
+
* (`./role-projection.ts`) publishes and the session-header badge reads.
|
|
4483
|
+
*
|
|
4484
|
+
* PURE module — no `@deepseek-ai/*` import, no host-only dependency — because
|
|
4485
|
+
* BOTH halves import it: the host through the seam's install point, the client
|
|
4486
|
+
* through `SubagentRoleBadge`. Splitting the key (and the value guard) out of
|
|
4487
|
+
* the host module is what keeps the client half free of the fold's host
|
|
4488
|
+
* imports, and a single shared literal is what keeps the two halves from
|
|
4489
|
+
* drifting into a silent "no pill".
|
|
4490
|
+
*
|
|
4491
|
+
* @module dsh-llm-fallbacks/role-projection-key
|
|
4492
|
+
*/
|
|
4493
|
+
/**
|
|
4494
|
+
* The projection key the role pill reads (`useProjection(ROLE_PROJECTION_KEY)`).
|
|
4495
|
+
* Lower-camel like the host's own session-scoped keys (`modelSelection`,
|
|
4496
|
+
* `sessionListMetadata`); the `fallbacks` prefix keeps a third-party key
|
|
4497
|
+
* unambiguous inside the shared `SessionProjectionMap`.
|
|
4498
|
+
*/
|
|
4499
|
+
const ROLE_PROJECTION_KEY = "fallbacksSubagentRole";
|
|
4500
|
+
/**
|
|
4501
|
+
* Read a projection value defensively (degrade-never-crash): only a non-blank
|
|
4502
|
+
* string is a role. `undefined` — the key is not registered on this host, or no
|
|
4503
|
+
* baseline/frame has carried it yet — and every foreign value read as "no
|
|
4504
|
+
* role", so the pill collapses to nothing instead of naming something wrong.
|
|
4505
|
+
*
|
|
4506
|
+
* @param value - the raw `useProjection('<key>')` value.
|
|
4507
|
+
*/
|
|
4508
|
+
function readRoleProjectionValue(value) {
|
|
4509
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
4510
|
+
}
|
|
4511
|
+
//#endregion
|
|
4530
4512
|
//#region \0dsh-css:/home/runner/work/dsh-llm-fallbacks/dsh-llm-fallbacks/src/client/SubagentRoleBadge.module.css.mjs
|
|
4531
4513
|
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";
|
|
4532
4514
|
const tagId = "dsh-llm-fallbacks/SubagentRoleBadge.module.css";
|
|
@@ -4541,101 +4523,47 @@ window.__ModuleLoader__.load({
|
|
|
4541
4523
|
//#endregion
|
|
4542
4524
|
//#region src/client/SubagentRoleBadge.tsx
|
|
4543
4525
|
/**
|
|
4544
|
-
*
|
|
4545
|
-
*
|
|
4546
|
-
*
|
|
4547
|
-
*
|
|
4548
|
-
*
|
|
4549
|
-
* Contract notes (verified 2026-09-09 against the harness checkout):
|
|
4550
|
-
* - The slot is `kind: 'list'`, `scope: 'session'`, owner props an empty
|
|
4551
|
-
* marker (`ConversationHeaderActionOwnerProps`, `children?: never`) — the
|
|
4552
|
-
* header renders occupants with `renderSlot(..., {})`, so ALL data flows
|
|
4553
|
-
* through this component's inject face and the session standard kit.
|
|
4554
|
-
* - Every `scope: 'session'` occupant receives the session standard kit
|
|
4555
|
-
* (`sessionId` + `useSession` + `useProjection`; ui-session
|
|
4556
|
-
* `src/client/index.ts:112-119`, merged into the runtime share by ui-slots'
|
|
4557
|
-
* `PropsRuntime`) — the fetch keys off the `sessionId` prop directly (mount
|
|
4558
|
-
* + whenever the prop changes; the slot machinery remounts the occupant per
|
|
4559
|
-
* viewed session — no manual session subscription). The compiled peer types
|
|
4560
|
-
* do not carry the ui-session standard-props merge into this plugin's
|
|
4561
|
-
* typecheck program (that package is deliberately not a plugin peer), so
|
|
4562
|
-
* the seat is read structurally and guarded — a version-skewed host without
|
|
4563
|
-
* it renders nothing, never throws.
|
|
4564
|
-
* - Data: `fallbacks/subagent-roles` gateway readbacks via the injected fetch
|
|
4565
|
-
* face ({@link fetchSubagentRoleRecord} — never throws): one on mount +
|
|
4566
|
-
* whenever the viewed session changes, then a BOUNDED delayed re-probe
|
|
4567
|
-
* while no record has landed (the record is written at the subagent's first
|
|
4568
|
-
* dispatch request, which can land after this header mounted).
|
|
4569
|
-
* - Render-only discipline (C4 pattern, same as `ConversationFallbackSwitch`):
|
|
4570
|
-
* the badge contributes a view; no message construction, no model-context
|
|
4571
|
-
* injection. Degrade-never-crash: a missing record, an `inherit` role, or
|
|
4572
|
-
* ANY readback error renders `null` — the utilities strip collapses cleanly.
|
|
4526
|
+
* The host's own durable model-selection projection key (`dsh-api-session-
|
|
4527
|
+
* controller`, merged into `SessionProjectionMap`): its client value carries
|
|
4528
|
+
* `lastUsed` — the route the LATEST recorded request ran on. Read through the
|
|
4529
|
+
* same structural seat as the role key.
|
|
4573
4530
|
*/
|
|
4531
|
+
const MODEL_SELECTION_PROJECTION_KEY = "modelSelection";
|
|
4574
4532
|
/**
|
|
4575
|
-
*
|
|
4576
|
-
*
|
|
4577
|
-
*
|
|
4578
|
-
* first record, a session switch, or unmount. The record is written once, at
|
|
4579
|
-
* the subagent's FIRST dispatch request — a header opened before that moment
|
|
4580
|
-
* would otherwise never see the badge until remount.
|
|
4533
|
+
* `provider/model` of the model-selection projection's `lastUsed`, or
|
|
4534
|
+
* `undefined` when the value/key/fields are absent or foreign — the badge then
|
|
4535
|
+
* hovers the role alone instead of rendering a wrong route.
|
|
4581
4536
|
*/
|
|
4582
|
-
|
|
4583
|
-
|
|
4537
|
+
function latestRequestRoute(value) {
|
|
4538
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
4539
|
+
const { lastUsed } = value;
|
|
4540
|
+
if (typeof lastUsed !== "object" || lastUsed === null) return void 0;
|
|
4541
|
+
const { provider, model } = lastUsed;
|
|
4542
|
+
if (typeof provider !== "string" || provider === "" || typeof model !== "string" || model === "") return void 0;
|
|
4543
|
+
return `${provider}/${model}`;
|
|
4544
|
+
}
|
|
4584
4545
|
/**
|
|
4585
4546
|
* Render the viewed session's dispatch-resolved role badge.
|
|
4586
|
-
* @param props - composed slot props (the
|
|
4547
|
+
* @param props - composed slot props (the session-kit `useProjection` seat is
|
|
4587
4548
|
* read structurally — see the module docblock).
|
|
4588
4549
|
* @returns the badge element, or `null` when there is nothing to show.
|
|
4589
4550
|
*/
|
|
4590
4551
|
function SubagentRoleBadge(props) {
|
|
4591
|
-
const { t
|
|
4592
|
-
const
|
|
4593
|
-
|
|
4594
|
-
const
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
sessionId,
|
|
4600
|
-
record: void 0
|
|
4601
|
-
});
|
|
4602
|
-
const record = stamped.sessionId === sessionId ? stamped.record : void 0;
|
|
4603
|
-
(0, react.useEffect)(() => {
|
|
4604
|
-
if (sessionId === void 0) return;
|
|
4605
|
-
let cancelled = false;
|
|
4606
|
-
let timer;
|
|
4607
|
-
const probe = (attempt) => {
|
|
4608
|
-
controller.fetchSubagentRole(sessionId).then((next) => {
|
|
4609
|
-
if (cancelled) return;
|
|
4610
|
-
if (next !== void 0) {
|
|
4611
|
-
setStamped({
|
|
4612
|
-
sessionId,
|
|
4613
|
-
record: next
|
|
4614
|
-
});
|
|
4615
|
-
return;
|
|
4616
|
-
}
|
|
4617
|
-
if (attempt >= ROLE_RECORD_PROBES) return;
|
|
4618
|
-
timer = setTimeout(() => {
|
|
4619
|
-
timer = void 0;
|
|
4620
|
-
probe(attempt + 1);
|
|
4621
|
-
}, ROLE_RECORD_PROBE_DELAY_MS);
|
|
4622
|
-
});
|
|
4623
|
-
};
|
|
4624
|
-
probe(0);
|
|
4625
|
-
return () => {
|
|
4626
|
-
cancelled = true;
|
|
4627
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
4628
|
-
};
|
|
4629
|
-
}, [controller, sessionId]);
|
|
4630
|
-
if (record === void 0 || record.role === "inherit") return null;
|
|
4631
|
-
const model = record.model === void 0 ? void 0 : `${record.model.provider}/${record.model.model}`;
|
|
4552
|
+
const { t } = props;
|
|
4553
|
+
const readProjection = props.useProjection;
|
|
4554
|
+
if (typeof readProjection !== "function") return null;
|
|
4555
|
+
const rawRole = readProjection(ROLE_PROJECTION_KEY);
|
|
4556
|
+
const rawModelSelection = readProjection(MODEL_SELECTION_PROJECTION_KEY);
|
|
4557
|
+
const role = readRoleProjectionValue(rawRole);
|
|
4558
|
+
if (role === void 0 || role === "inherit") return null;
|
|
4559
|
+
const model = latestRequestRoute(rawModelSelection);
|
|
4632
4560
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4633
4561
|
className: SubagentRoleBadge_module_css_default.badge,
|
|
4634
|
-
title: model === void 0 ?
|
|
4635
|
-
role
|
|
4562
|
+
title: model === void 0 ? role : t("subagentRole.hover", {
|
|
4563
|
+
role,
|
|
4636
4564
|
model
|
|
4637
4565
|
}),
|
|
4638
|
-
children:
|
|
4566
|
+
children: role
|
|
4639
4567
|
});
|
|
4640
4568
|
}
|
|
4641
4569
|
//#endregion
|
|
@@ -4760,8 +4688,7 @@ window.__ModuleLoader__.load({
|
|
|
4760
4688
|
name: "conversation.session.header.utilities",
|
|
4761
4689
|
id: "fallbacks-subagent-role",
|
|
4762
4690
|
order: -20,
|
|
4763
|
-
locale: NS
|
|
4764
|
-
inject: () => ({ controller })
|
|
4691
|
+
locale: NS
|
|
4765
4692
|
}, SubagentRoleBadge);
|
|
4766
4693
|
});
|
|
4767
4694
|
}
|
package/dist/client/locales.d.ts
CHANGED
|
@@ -116,6 +116,7 @@ export declare const zh: {
|
|
|
116
116
|
'roles.persona.collapse': string;
|
|
117
117
|
'roles.persona.empty': string;
|
|
118
118
|
'roles.seedSource.bundled': string;
|
|
119
|
+
'roles.seedSource.external': string;
|
|
119
120
|
'roles.seedSource.user': string;
|
|
120
121
|
'roles.seedChainOptional': string;
|
|
121
122
|
'roles.fallback': string;
|
|
@@ -314,6 +315,7 @@ export declare const en: {
|
|
|
314
315
|
'roles.persona.collapse': string;
|
|
315
316
|
'roles.persona.empty': string;
|
|
316
317
|
'roles.seedSource.bundled': string;
|
|
318
|
+
'roles.seedSource.external': string;
|
|
317
319
|
'roles.seedSource.user': string;
|
|
318
320
|
'roles.seedChainOptional': string;
|
|
319
321
|
'roles.fallback': string;
|
package/dist/events.d.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* after a dsh restart. The event now exists only in history: old logs that
|
|
8
8
|
* contain it cannot be repaired by an `ignorable` flag (the released
|
|
9
9
|
* session-format chain refuses unknown event types even when marked
|
|
10
|
-
* ignorable), so `
|
|
11
|
-
*
|
|
10
|
+
* ignorable), so `pnpm repair:session-logs` only reports such logs by
|
|
11
|
+
* default; its opt-in lossy `--drop-legacy-events` mode is the sole recovery.
|
|
12
12
|
* The module is type-only — the augmentation is erased at runtime; the
|
|
13
13
|
* plugin's runtime behavior lives in `src/index.ts`.
|
|
14
14
|
*
|
package/dist/gateway.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* T1 (plan llm-fallbacks-settings-gateway) + T3 (plan fallbacks-role-seeds) —
|
|
3
3
|
* host-side `fallbacks` config gateway: the `/api/fallbacks/get` +
|
|
4
4
|
* `/api/fallbacks/set` + `/api/fallbacks/reset` + `/api/fallbacks/revert-seed`
|
|
5
|
-
*
|
|
5
|
+
* endpoints.
|
|
6
6
|
*
|
|
7
7
|
* Transport: the typertGateway `/api` interceptor is the single host-wide RPC
|
|
8
8
|
* slot (a plugin must NOT `connection.rpc.intercept('/api')` again — it would
|
|
@@ -43,11 +43,6 @@
|
|
|
43
43
|
* `revert-seed` exposes revert-to-current-seed-default for one id — both
|
|
44
44
|
* delegate to the per-apply `FallbacksSeedManager` passed into the
|
|
45
45
|
* constructor (single point of truth, no copied manager logic).
|
|
46
|
-
* `subagent-roles` (plan subagent-role-badge T2) is the read-only badge
|
|
47
|
-
* readback: it projects the per-apply dispatch-resolved role-record map
|
|
48
|
-
* (same T1 map the inject block writes, via the optional snapshot fn) for a
|
|
49
|
-
* batch of session ids — unknown ids are omitted, an unwired or throwing
|
|
50
|
-
* snapshot degrades to `{}`, never an error.
|
|
51
46
|
*
|
|
52
47
|
* The settings service is OPTIONAL (no settings service → the bridge source
|
|
53
48
|
* stays the entry, `get` still works; `set`/`reset` fail with a clear
|
|
@@ -131,29 +126,6 @@ export type SubagentPolicySnapshotFn = () => {
|
|
|
131
126
|
reason: string;
|
|
132
127
|
};
|
|
133
128
|
};
|
|
134
|
-
/**
|
|
135
|
-
* One dispatch-resolved subagent role record on the wire (plan
|
|
136
|
-
* subagent-role-badge T2): the role the subagent's dispatch resolved and the
|
|
137
|
-
* route it actually runs after the inject decision. `model` is optional on
|
|
138
|
-
* the WIRE type only — the writer (T1) always sets it, but a record without
|
|
139
|
-
* one still reads back as `{ role, at }` instead of failing the readback.
|
|
140
|
-
*/
|
|
141
|
-
export type SubagentRoleRecord = {
|
|
142
|
-
role: string;
|
|
143
|
-
model?: {
|
|
144
|
-
provider: string;
|
|
145
|
-
model: string;
|
|
146
|
-
};
|
|
147
|
-
at: number;
|
|
148
|
-
};
|
|
149
|
-
/**
|
|
150
|
-
* Live role-record snapshot the gateway reads through (plan
|
|
151
|
-
* subagent-role-badge T2) — the `SubagentPolicySnapshotFn` pattern: built in
|
|
152
|
-
* `apply()` over the SAME T1 map the dispatch inject block writes, no second
|
|
153
|
-
* record source. Optional: constructors that omit it make the
|
|
154
|
-
* `/api/fallbacks/subagent-roles` endpoint return `{}`.
|
|
155
|
-
*/
|
|
156
|
-
export type SubagentRolesSnapshotFn = () => ReadonlyMap<string, SubagentRoleRecord>;
|
|
157
129
|
/**
|
|
158
130
|
* The live configuration source for the gateway (guide §7 — the same bridge
|
|
159
131
|
* shape the runtime reads through). `source()` returns the live composed
|
|
@@ -212,12 +184,6 @@ export declare class FallbacksConfigGateway extends TypertRemoteService {
|
|
|
212
184
|
* used by gateway unit tests stays byte-identical to the pre-T5 payload.
|
|
213
185
|
*/
|
|
214
186
|
private readonly subagentPolicy;
|
|
215
|
-
/**
|
|
216
|
-
* Optional role-record snapshot (plan subagent-role-badge T2). When omitted
|
|
217
|
-
* the `subagentRoles` endpoint returns `{}` — every existing constructor
|
|
218
|
-
* call site keeps its payload byte-identical.
|
|
219
|
-
*/
|
|
220
|
-
private readonly subagentRolesSnapshot;
|
|
221
187
|
/**
|
|
222
188
|
* @param ctx - owning context (the plugin fiber's ctx inside `apply`).
|
|
223
189
|
* @param bridge - the same `FallbacksSettingsBridge` the runtime reads, so
|
|
@@ -227,11 +193,8 @@ export declare class FallbacksConfigGateway extends TypertRemoteService {
|
|
|
227
193
|
* copied manager logic), through the io seam built over this bridge.
|
|
228
194
|
* @param subagentPolicy - live host-policy snapshot from `apply()`; omit
|
|
229
195
|
* to leave the additive field off the wire.
|
|
230
|
-
* @param subagentRoles - live dispatch-resolved role-record snapshot from
|
|
231
|
-
* `apply()` (plan subagent-role-badge T2); omit to make the
|
|
232
|
-
* `subagent-roles` endpoint return `{}`.
|
|
233
196
|
*/
|
|
234
|
-
constructor(ctx: Context, bridge: FallbacksSettingsBridge, seeds: FallbacksSeedManager, subagentPolicy?: SubagentPolicySnapshotFn
|
|
197
|
+
constructor(ctx: Context, bridge: FallbacksSettingsBridge, seeds: FallbacksSeedManager, subagentPolicy?: SubagentPolicySnapshotFn);
|
|
235
198
|
/**
|
|
236
199
|
* Read the current composed config (schema defaults → entry base → settings
|
|
237
200
|
* user layer). No hard-gate resolver (ADR-2): the raw composed config is
|
|
@@ -290,22 +253,6 @@ export declare class FallbacksConfigGateway extends TypertRemoteService {
|
|
|
290
253
|
* write channel is unavailable (KD-G5).
|
|
291
254
|
*/
|
|
292
255
|
revertSeed(id: string): Promise<FallbacksRevertResult>;
|
|
293
|
-
/**
|
|
294
|
-
* Batch readback of dispatch-resolved subagent role records (plan
|
|
295
|
-
* subagent-role-badge T2) — the read side of the session-header role badge.
|
|
296
|
-
* Ids are agent ids (≡ session ids: the same id space the dispatch inject
|
|
297
|
-
* block records under). Unknown/absent ids are OMITTED from the result,
|
|
298
|
-
* never an error — the badge renders nothing for them. No snapshot wired
|
|
299
|
-
* (pre-T2 constructors) or a throwing snapshot ⇒ `{}` — degrade-never-crash,
|
|
300
|
-
* the same fail-closed shape as `projectSubagentPolicy`.
|
|
301
|
-
* @param ids - the session ids to read (at most
|
|
302
|
-
* {@link SUBAGENT_ROLES_MAX_IDS} entries).
|
|
303
|
-
* @returns a plain JSON object keyed by KNOWN id only, each carrying the
|
|
304
|
-
* wire record (`role`, `at`, `model` when the record has one).
|
|
305
|
-
* @throws TypeError when `ids` is not an array of strings or the batch
|
|
306
|
-
* exceeds {@link SUBAGENT_ROLES_MAX_IDS} entries.
|
|
307
|
-
*/
|
|
308
|
-
subagentRoles(ids: string[]): Record<string, SubagentRoleRecord>;
|
|
309
256
|
/**
|
|
310
257
|
* Read the live composed config and normalize it to the typertGateway JSON
|
|
311
258
|
* wire boundary. Containment (guide §10): a malformed stored user layer
|
package/dist/index.d.ts
CHANGED
|
@@ -19,10 +19,12 @@
|
|
|
19
19
|
* (provider/model override; the inherited `reasoningEffort` follows the
|
|
20
20
|
* upstream routeChanged rule — dropped on a route change unless explicitly
|
|
21
21
|
* named, preserved on a same-route override; spec D3); a
|
|
22
|
-
* root-origin `FallbacksChain/Auto` seed
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* root-origin `FallbacksChain/Auto` seed is served UNCHANGED (plan
|
|
23
|
+
* model-change-notice-loop Task 1 — the route the loop serves and records
|
|
24
|
+
* must equal the session selection, otherwise the host `model-selection`
|
|
25
|
+
* notice is re-armed on every step; the virtual adapter's `stream()`
|
|
26
|
+
* delegate is what reaches the chain head); then the always-mode cap check
|
|
27
|
+
* (count `llm/retry` events for the current turn/step/provider; ≥
|
|
26
28
|
* `alwaysModeRetryCap` → same decision path, reason `always-cap` —
|
|
27
29
|
* ADR-2).
|
|
28
30
|
* - Per-agent state (`FallbackStateStore`): `agent/disposed` removes it,
|
|
@@ -122,29 +124,6 @@ export declare function blockedAttempts(ctx: Context): ReadonlyMap<string, Block
|
|
|
122
124
|
* plugin is applied.
|
|
123
125
|
*/
|
|
124
126
|
export declare function chainHeads(ctx: Context): ReadonlyMap<string, EffectiveChainHead> | undefined;
|
|
125
|
-
/**
|
|
126
|
-
* One dispatch-resolved subagent role record (plan subagent-role-badge T1):
|
|
127
|
-
* the role `resolveRoleAtDispatch` resolved at the subagent's first request
|
|
128
|
-
* and the route the subagent will actually run after the inject decision
|
|
129
|
-
* (the override target when it applies, else the host seed).
|
|
130
|
-
*/
|
|
131
|
-
type SubagentRoleRecord = {
|
|
132
|
-
role: string;
|
|
133
|
-
model: {
|
|
134
|
-
provider: string;
|
|
135
|
-
model: string;
|
|
136
|
-
};
|
|
137
|
-
at: number;
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* @internal Test seam (mirrors `chainHeads`): the per-agent dispatch-resolved
|
|
141
|
-
* role records written by the role-inject block (plan subagent-role-badge T1)
|
|
142
|
-
* for the plugin applied to `ctx`. Not part of the plugin's public surface;
|
|
143
|
-
* lets tests read the badge record without reaching into the closure (the
|
|
144
|
-
* gateway readback closes over the per-apply map directly). `undefined` when
|
|
145
|
-
* no plugin is applied.
|
|
146
|
-
*/
|
|
147
|
-
export declare function subagentRoleRecords(ctx: Context): ReadonlyMap<string, SubagentRoleRecord> | undefined;
|
|
148
127
|
/**
|
|
149
128
|
* Count durable `llm/retry` events for the current (turn, step, provider) in
|
|
150
129
|
* **always mode** (ADR-2; spec §2 clause 5). Normal-mode retries belong to
|