@camstack/addon-admin-ui 1.2.483 → 1.2.485
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/dist/assets/{AddonAssetIcon-DG82cOOB.js → AddonAssetIcon-3vq-0y-v.js} +1 -1
- package/dist/assets/{Addons-B7pn0v6S.js → Addons-CW_V36k4.js} +1 -1
- package/dist/assets/{AdminPage-CNutWOEU.js → AdminPage-QmLz5qjj.js} +1 -1
- package/dist/assets/{AdminSectionedPage-Dm8ND20L.js → AdminSectionedPage-D9jBOpIg.js} +1 -1
- package/dist/assets/AiProfiles-CP5xqeEk.js +3 -0
- package/dist/assets/{BrokerForm-DijcT6td.js → BrokerForm-D8mkRSYS.js} +1 -1
- package/dist/assets/Build-DVpLjguC.js +40 -0
- package/dist/assets/{Calendars-Ck9cG0iB.js → Calendars-Beo-YqjO.js} +1 -1
- package/dist/assets/{Cluster-yiPXhRl-.js → Cluster-B-_bS1Yq.js} +1 -1
- package/dist/assets/{CompositionBlockEditor-BxkWKOxd.js → CompositionBlockEditor-iMNTwm3C.js} +1 -1
- package/dist/assets/{CompositionEditorPage-C7aaI4Ga.js → CompositionEditorPage-BED3S8xk.js} +1 -1
- package/dist/assets/{Data-Cker1tA1.js → Data-CP80sADS.js} +1 -1
- package/dist/assets/DeviceDetail-DEfKCzwe.js +2 -0
- package/dist/assets/{DeviceDoActionFields-CP-EliT2.js → DeviceDoActionFields-BJfHVs6x.js} +1 -1
- package/dist/assets/{Devices-DmVvfG_b.js → Devices-_2nQ8QL2.js} +1 -1
- package/dist/assets/{EmbedPlayerPage-CoSlXnQ9.js → EmbedPlayerPage-D6aNp4TG.js} +1 -1
- package/dist/assets/HelperWizard-2-iOB1DP.js +2 -0
- package/dist/assets/{History-gocAbU36.js → History-DU5KjafA.js} +1 -1
- package/dist/assets/Identity-Bx1SUu2F.js +1 -0
- package/dist/assets/{IntegrationDetail-B17OUQKx.js → IntegrationDetail-BtGF0XsO.js} +1 -1
- package/dist/assets/{IntegrationHub-D6NA9UIc.js → IntegrationHub-D5yLfTfh.js} +1 -1
- package/dist/assets/{Integrations-UBtD6K0x.js → Integrations-C_kA-dpe.js} +1 -1
- package/dist/assets/{Integrations-DHGfNtpw.js → Integrations-nsyVrgEK.js} +1 -1
- package/dist/assets/{Library-BbuNPwa4.js → Library-Bx344878.js} +1 -1
- package/dist/assets/{Locations-BHhCef1F.js → Locations-Do1Y0voR.js} +2 -2
- package/dist/assets/{Logs-BdiPIKKN.js → Logs-svtt17dH.js} +1 -1
- package/dist/assets/{MaskShapeCanvas-B-Co3EcK.js → MaskShapeCanvas-CzHUGkc7.js} +1 -1
- package/dist/assets/{MotionZonesSettings-rYNi0IyL.js → MotionZonesSettings-sCDWBSMu.js} +1 -1
- package/dist/assets/{MyAccess-DqlunIKb.js → MyAccess-C3MmE-Hf.js} +1 -1
- package/dist/assets/{Network-rDYYtzyq.js → Network-D3RwGDhy.js} +1 -1
- package/dist/assets/{NodeAddonsSettingsPanel-mj1x8pib.js → NodeAddonsSettingsPanel-DUUGVGQU.js} +1 -1
- package/dist/assets/Notifications-CProzw2o.js +1 -0
- package/dist/assets/Pipeline-kOwhFjIj.js +1 -0
- package/dist/assets/{PrivacyMaskSettings-B_ZOhHsa.js → PrivacyMaskSettings-DH3PZaEy.js} +1 -1
- package/dist/assets/{Recordings-CHeLoIRU.js → Recordings-CUmSLBG6.js} +1 -1
- package/dist/assets/{ScanNetworkModal-DDNyXnXJ.js → ScanNetworkModal-PQbiE2mC.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-CyHwjdzH.js → SceneMonitorEditor-CLWf6Z9-.js} +1 -1
- package/dist/assets/{SessionsList-B27Ne5e_.js → SessionsList-BNTGQ-KG.js} +1 -1
- package/dist/assets/{Showroom-CxOhuFLC.js → Showroom-BOzjtIAL.js} +1 -1
- package/dist/assets/{System-T0PZXCE1.js → System-DrbzraIN.js} +1 -1
- package/dist/assets/{Terminal-BA3WpGbf.js → Terminal-B2SRyo3p.js} +1 -1
- package/dist/assets/{Viewer-BIZ2-AWC.js → Viewer-CTvuCeo6.js} +1 -1
- package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-XyNfp-21.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DAW63rZZ.js} +1 -1
- package/dist/assets/{addon-icons-context-IF2bAKB7.js → addon-icons-context-Bzdujcmt.js} +1 -1
- package/dist/assets/{archive-DwK992kq.js → archive-dvL2Bchb.js} +1 -1
- package/dist/assets/{assignment-candidates-BfYuVkll.js → assignment-candidates-D1rkNXjX.js} +1 -1
- package/dist/assets/{authed-media-2wArFI8C.js → authed-media-B6hJJcft.js} +1 -1
- package/dist/assets/{bell-off-BT9N_y5z.js → bell-off-C3flB_OF.js} +1 -1
- package/dist/assets/{board-model-C79CsHea.js → board-model-BJ20DSDr.js} +1 -1
- package/dist/assets/{boxes-Brm6PKBJ.js → boxes-BiMbpzNh.js} +1 -1
- package/dist/assets/chart-column-BMpUb2lF.js +1 -0
- package/dist/assets/circle-slash-B8Tjloe5.js +1 -0
- package/dist/assets/client-Ct1F5MoE.js +358 -0
- package/dist/assets/{cloud-upload-BWBb35pQ.js → cloud-upload-CAJgV_u1.js} +1 -1
- package/dist/assets/crop-CS-td_0y.js +1 -0
- package/dist/assets/{device-integration-icon-CfmyHq1L.js → device-integration-icon-Csh9ZCwn.js} +1 -1
- package/dist/assets/device-picker-model-P-UzQOB7.js +1 -0
- package/dist/assets/dist-B89wGMMB.js +358 -0
- package/dist/assets/{dist-v4PTiFhI.js → dist-CPp8d_RN.js} +1 -1
- package/dist/assets/{eraser-DOQYm-bd.js → eraser-BL6nSeLQ.js} +1 -1
- package/dist/assets/{format-DZdW_-La.js → format-Cl0i0-3O.js} +1 -1
- package/dist/assets/{hard-drive-download-BomHKdQ6.js → hard-drive-download-ysGKYLwW.js} +1 -1
- package/dist/assets/{hostInit-Y3_WOWpF.js → hostInit-CDPK_pyj.js} +1 -1
- package/dist/assets/i18n-sTui-nG3.js +1 -0
- package/dist/assets/icons-B7uNvSe0.js +1 -0
- package/dist/assets/index-Dow2-3ZC.js +4 -0
- package/dist/assets/{key-round-HMiyn866.js → key-round-BDT5O9Ed.js} +1 -1
- package/dist/assets/{key-BjcxiZfv.js → key-xS-HUgNI.js} +1 -1
- package/dist/assets/{layers-71beSjbX.js → layers-BeRWYCde.js} +1 -1
- package/dist/assets/{linked-devices-model-CGjAZM4f.js → linked-devices-model-zOoasg7W.js} +1 -1
- package/dist/assets/{list-ordered-B00NsDtF.js → list-ordered-DKzGLPr6.js} +1 -1
- package/dist/assets/{location-owned-usage-C-GlyOpT.js → location-owned-usage-CWUx1diZ.js} +1 -1
- package/dist/assets/{log-in-CqClOuyv.js → log-in-53JDrQ-P.js} +1 -1
- package/dist/assets/{memory-stick-GbtuW7Ii.js → memory-stick-B9PVELyF.js} +1 -1
- package/dist/assets/{message-square-plus-BCFV5CXr.js → message-square-plus-B32IU45x.js} +1 -1
- package/dist/assets/{mf-entry-bootstrap-0-426ce71a.js → mf-entry-bootstrap-0-40dc4d62.js} +2 -2
- package/dist/assets/{mic-off-COk2FYD5.js → mic-off-B0w-1GrV.js} +1 -1
- package/dist/assets/{monitor-off-nojFqJI5.js → monitor-off-Cz2SxBVE.js} +1 -1
- package/dist/assets/{monitor-smartphone-BuxgqmtR.js → monitor-smartphone-Cqk6Z8Hg.js} +1 -1
- package/dist/assets/mount-P-UzQOB7.js +1 -0
- package/dist/assets/{player-overlays-BoPcGTkt.js → player-overlays-Cs6l33cj.js} +1 -1
- package/dist/assets/{recycle-Cbhp7tZj.js → recycle-DpB4QxbX.js} +1 -1
- package/dist/assets/remoteEntry-BGbchE1L.js +1 -0
- package/dist/assets/{scan-eye-COINNEut.js → scan-eye-DcYrgFOu.js} +1 -1
- package/dist/assets/{scissors-CU5rKPA8.js → scissors-_j_D3ONm.js} +1 -1
- package/dist/assets/{search-x-BEiDgxD-.js → search-x-9dPd-b95.js} +1 -1
- package/dist/assets/{send-CNx75CN6.js → send-D42ODbS7.js} +1 -1
- package/dist/assets/{settings-2-yfTMebsz.js → settings-2-zgGmo4c8.js} +1 -1
- package/dist/assets/{speaker-DzqHMf19.js → speaker-DIPHxIQ6.js} +1 -1
- package/dist/assets/src-DFzrn-CX.js +67 -0
- package/dist/assets/{step-inspector-model-BPPs6HSK.js → step-inspector-model-DTr-lHt_.js} +1 -1
- package/dist/assets/{table-2-CysTnRKy.js → table-2-lftK0wHb.js} +1 -1
- package/dist/assets/{timer-reset-BgIXd7hf.js → timer-reset-catAE_r9.js} +1 -1
- package/dist/assets/{ungroup-fAQCZXka.js → ungroup-BKImeHER.js} +1 -1
- package/dist/assets/{unlink-DSg9bFwt.js → unlink-Behl018w.js} +1 -1
- package/dist/assets/{usb-D-DRV1uf.js → usb-D5kzB8kq.js} +1 -1
- package/dist/assets/{use-scenes-feed-DO_UdVPf.js → use-scenes-feed-CGDnep25.js} +1 -1
- package/dist/assets/{use-stationary-objects-BXlbjYsd.js → use-stationary-objects-D_R5OahX.js} +1 -1
- package/dist/assets/useEventInvalidation-P-UzQOB7.js +1 -0
- package/dist/assets/{useNodeUrlSelection-BtOB6Z9m.js → useNodeUrlSelection-nYjP8xK4.js} +1 -1
- package/dist/assets/user-round-BJVl6LX9.js +1 -0
- package/dist/assets/{user-x-CPWIU9qV.js → user-x-COQ6vhb4.js} +1 -1
- package/dist/assets/{video-BM3o6nmQ.js → video-Byw3ItoR.js} +1 -1
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-Bw4dQyg1.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CsFmgfi4.js} +2 -2
- package/dist/index.html +9 -9
- package/dist/server/addon.js +169 -29
- package/package.json +1 -1
- package/dist/assets/AiProfiles-CaJWaXuB.js +0 -3
- package/dist/assets/Build-Cq96yUoY.js +0 -40
- package/dist/assets/DeviceDetail-CIT2D5yf.js +0 -2
- package/dist/assets/HelperWizard-DS_R_NlR.js +0 -2
- package/dist/assets/Identity-CuazTQNS.js +0 -1
- package/dist/assets/Notifications-RMkYxLsU.js +0 -1
- package/dist/assets/Pipeline-DeamCmUq.js +0 -1
- package/dist/assets/circle-slash-DbVS3C3N.js +0 -1
- package/dist/assets/client-xX9FBBul.js +0 -358
- package/dist/assets/crop-Cwf2hMEp.js +0 -1
- package/dist/assets/device-picker-model-BqREn4Hm.js +0 -1
- package/dist/assets/dist-BBQqVqgg.js +0 -358
- package/dist/assets/i18n-B_TdOOX_.js +0 -1
- package/dist/assets/icons-GyTqKSGv.js +0 -1
- package/dist/assets/index-Df_Bqvin.js +0 -4
- package/dist/assets/mount-BqREn4Hm.js +0 -1
- package/dist/assets/remoteEntry-C1jeRZii.js +0 -1
- package/dist/assets/src-B9Sp1iss.js +0 -67
- package/dist/assets/useEventInvalidation-BqREn4Hm.js +0 -1
- package/dist/assets/user-round-DKD1XSci.js +0 -1
package/dist/server/addon.js
CHANGED
|
@@ -5443,7 +5443,7 @@ var ZodIssueCode = {
|
|
|
5443
5443
|
var ZodFirstPartyTypeKind;
|
|
5444
5444
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5445
5445
|
//#endregion
|
|
5446
|
-
//#region ../types/dist/sleep-
|
|
5446
|
+
//#region ../types/dist/sleep-0sD_LHLI.mjs
|
|
5447
5447
|
/**
|
|
5448
5448
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5449
5449
|
* window to float samples (D455).
|
|
@@ -8605,6 +8605,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8605
8605
|
"login-method",
|
|
8606
8606
|
"media-player",
|
|
8607
8607
|
"mesh-network",
|
|
8608
|
+
"meter",
|
|
8608
8609
|
"metrics-provider",
|
|
8609
8610
|
"model-convert",
|
|
8610
8611
|
"model-distributor",
|
|
@@ -9662,6 +9663,10 @@ Object.freeze({
|
|
|
9662
9663
|
]
|
|
9663
9664
|
}
|
|
9664
9665
|
],
|
|
9666
|
+
"meter": [{
|
|
9667
|
+
"path": "value",
|
|
9668
|
+
"valueType": "number"
|
|
9669
|
+
}],
|
|
9665
9670
|
"motion": [
|
|
9666
9671
|
{
|
|
9667
9672
|
"path": "detected",
|
|
@@ -10754,7 +10759,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10754
10759
|
return DeviceRole;
|
|
10755
10760
|
}({});
|
|
10756
10761
|
//#endregion
|
|
10757
|
-
//#region ../types/dist/composition-
|
|
10762
|
+
//#region ../types/dist/composition-CpETZ4HL.mjs
|
|
10758
10763
|
/**
|
|
10759
10764
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10760
10765
|
*
|
|
@@ -11530,6 +11535,77 @@ var APPLIANCE_KINDS = [
|
|
|
11530
11535
|
];
|
|
11531
11536
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11532
11537
|
/**
|
|
11538
|
+
* Statistics and integrals over a history read (D944).
|
|
11539
|
+
*
|
|
11540
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11541
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11542
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11543
|
+
* as zero. A truncated read is not published.
|
|
11544
|
+
*/
|
|
11545
|
+
var STATISTIC_STATS = [
|
|
11546
|
+
"min",
|
|
11547
|
+
"max",
|
|
11548
|
+
"mean",
|
|
11549
|
+
"sum",
|
|
11550
|
+
"count",
|
|
11551
|
+
"change"
|
|
11552
|
+
];
|
|
11553
|
+
/**
|
|
11554
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11555
|
+
*
|
|
11556
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11557
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11558
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11559
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11560
|
+
*/
|
|
11561
|
+
var MINUTE_MS = 6e4;
|
|
11562
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11563
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11564
|
+
var ROLLING_SPANS = [
|
|
11565
|
+
"1h",
|
|
11566
|
+
"24h",
|
|
11567
|
+
"2d",
|
|
11568
|
+
"7d",
|
|
11569
|
+
"30d",
|
|
11570
|
+
"custom"
|
|
11571
|
+
];
|
|
11572
|
+
var CALENDAR_PERIODS = [
|
|
11573
|
+
"today",
|
|
11574
|
+
"yesterday",
|
|
11575
|
+
"this-week",
|
|
11576
|
+
"this-month"
|
|
11577
|
+
];
|
|
11578
|
+
var RESET_PERIODS = [
|
|
11579
|
+
"never",
|
|
11580
|
+
"daily",
|
|
11581
|
+
"weekly",
|
|
11582
|
+
"monthly"
|
|
11583
|
+
];
|
|
11584
|
+
5 * MINUTE_MS;
|
|
11585
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11586
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11587
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [object({
|
|
11588
|
+
kind: literal("rolling"),
|
|
11589
|
+
span: _enum(ROLLING_SPANS),
|
|
11590
|
+
customMinutes: number().int().min(5).optional()
|
|
11591
|
+
}).check((payload) => {
|
|
11592
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11593
|
+
code: "custom",
|
|
11594
|
+
message: "a custom range needs a duration in minutes",
|
|
11595
|
+
path: ["customMinutes"],
|
|
11596
|
+
input: payload.value
|
|
11597
|
+
});
|
|
11598
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11599
|
+
code: "custom",
|
|
11600
|
+
message: "only a custom range carries a duration",
|
|
11601
|
+
path: ["customMinutes"],
|
|
11602
|
+
input: payload.value
|
|
11603
|
+
});
|
|
11604
|
+
}), object({
|
|
11605
|
+
kind: literal("calendar"),
|
|
11606
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11607
|
+
})]);
|
|
11608
|
+
/**
|
|
11533
11609
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11534
11610
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11535
11611
|
* `composition.ts` (D659).
|
|
@@ -11585,22 +11661,37 @@ var HelperMemberSchema = object({
|
|
|
11585
11661
|
cap: string().min(1),
|
|
11586
11662
|
fieldPath: string().min(1)
|
|
11587
11663
|
});
|
|
11588
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11664
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11665
|
+
object({
|
|
11666
|
+
kind: literal("group"),
|
|
11667
|
+
templateId: GroupTemplateIdSchema,
|
|
11668
|
+
aggregate: AggregateReducerSchema,
|
|
11669
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11670
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11671
|
+
active: ActiveCriterionSchema.optional()
|
|
11672
|
+
}),
|
|
11673
|
+
object({
|
|
11674
|
+
kind: literal("appliance"),
|
|
11675
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11676
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11677
|
+
thresholdWatts: number().positive(),
|
|
11678
|
+
startDwellMs: number().int().nonnegative(),
|
|
11679
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11680
|
+
member: HelperMemberSchema
|
|
11681
|
+
}),
|
|
11682
|
+
object({
|
|
11683
|
+
kind: literal("statistic"),
|
|
11684
|
+
stat: _enum(STATISTIC_STATS),
|
|
11685
|
+
window: StatisticWindowSchema,
|
|
11686
|
+
source: HelperMemberSchema
|
|
11687
|
+
}),
|
|
11688
|
+
object({
|
|
11689
|
+
kind: literal("integral"),
|
|
11690
|
+
reset: _enum(RESET_PERIODS),
|
|
11691
|
+
output: _enum(["energy", "meter"]),
|
|
11692
|
+
source: HelperMemberSchema
|
|
11693
|
+
})
|
|
11694
|
+
]);
|
|
11604
11695
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11605
11696
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11606
11697
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11674,6 +11765,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11674
11765
|
"omit",
|
|
11675
11766
|
"offline"
|
|
11676
11767
|
])
|
|
11768
|
+
}),
|
|
11769
|
+
object({
|
|
11770
|
+
kind: literal("series"),
|
|
11771
|
+
read: CompositionFieldReadSchema,
|
|
11772
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11773
|
+
publish: _enum([
|
|
11774
|
+
"value",
|
|
11775
|
+
"included",
|
|
11776
|
+
"excluded",
|
|
11777
|
+
"total"
|
|
11778
|
+
]),
|
|
11779
|
+
/**
|
|
11780
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11781
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11782
|
+
*/
|
|
11783
|
+
empty: _enum([
|
|
11784
|
+
"null",
|
|
11785
|
+
"omit",
|
|
11786
|
+
"offline"
|
|
11787
|
+
])
|
|
11677
11788
|
})
|
|
11678
11789
|
]);
|
|
11679
11790
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -17832,7 +17943,8 @@ var CompositionProblemSchema = object({
|
|
|
17832
17943
|
"native-capability-replace",
|
|
17833
17944
|
"mixed-quantity",
|
|
17834
17945
|
"helper-mismatch",
|
|
17835
|
-
"member-constraint"
|
|
17946
|
+
"member-constraint",
|
|
17947
|
+
"retention"
|
|
17836
17948
|
]),
|
|
17837
17949
|
path: string(),
|
|
17838
17950
|
message: string()
|
|
@@ -18072,7 +18184,7 @@ Object.freeze({
|
|
|
18072
18184
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18073
18185
|
* Data, not a form default written into the block.
|
|
18074
18186
|
*/
|
|
18075
|
-
var NOW = {
|
|
18187
|
+
var NOW$1 = {
|
|
18076
18188
|
fieldPath: "lastFetchedAt",
|
|
18077
18189
|
expr: "now"
|
|
18078
18190
|
};
|
|
@@ -18118,7 +18230,7 @@ var GROUP_TEMPLATES = [
|
|
|
18118
18230
|
quantity: "temperature",
|
|
18119
18231
|
defaultAggregate: "mean",
|
|
18120
18232
|
empty: "null",
|
|
18121
|
-
companions: [NOW]
|
|
18233
|
+
companions: [NOW$1]
|
|
18122
18234
|
}),
|
|
18123
18235
|
numeric({
|
|
18124
18236
|
id: "humidity",
|
|
@@ -18129,7 +18241,7 @@ var GROUP_TEMPLATES = [
|
|
|
18129
18241
|
quantity: "humidity",
|
|
18130
18242
|
defaultAggregate: "mean",
|
|
18131
18243
|
empty: "null",
|
|
18132
|
-
companions: [NOW]
|
|
18244
|
+
companions: [NOW$1]
|
|
18133
18245
|
}),
|
|
18134
18246
|
numeric({
|
|
18135
18247
|
id: "pressure",
|
|
@@ -18140,7 +18252,7 @@ var GROUP_TEMPLATES = [
|
|
|
18140
18252
|
quantity: "pressure",
|
|
18141
18253
|
defaultAggregate: "mean",
|
|
18142
18254
|
empty: "null",
|
|
18143
|
-
companions: [NOW]
|
|
18255
|
+
companions: [NOW$1]
|
|
18144
18256
|
}),
|
|
18145
18257
|
numeric({
|
|
18146
18258
|
id: "illuminance",
|
|
@@ -18151,7 +18263,7 @@ var GROUP_TEMPLATES = [
|
|
|
18151
18263
|
quantity: "illuminance",
|
|
18152
18264
|
defaultAggregate: "mean",
|
|
18153
18265
|
empty: "null",
|
|
18154
|
-
companions: [NOW]
|
|
18266
|
+
companions: [NOW$1]
|
|
18155
18267
|
}),
|
|
18156
18268
|
numeric({
|
|
18157
18269
|
id: "power",
|
|
@@ -18162,7 +18274,7 @@ var GROUP_TEMPLATES = [
|
|
|
18162
18274
|
quantity: "power",
|
|
18163
18275
|
defaultAggregate: "sum",
|
|
18164
18276
|
empty: "omit",
|
|
18165
|
-
companions: [NOW]
|
|
18277
|
+
companions: [NOW$1]
|
|
18166
18278
|
}),
|
|
18167
18279
|
numeric({
|
|
18168
18280
|
id: "energy",
|
|
@@ -18173,7 +18285,7 @@ var GROUP_TEMPLATES = [
|
|
|
18173
18285
|
quantity: "energy",
|
|
18174
18286
|
defaultAggregate: "sum",
|
|
18175
18287
|
empty: "omit",
|
|
18176
|
-
companions: [NOW]
|
|
18288
|
+
companions: [NOW$1]
|
|
18177
18289
|
}),
|
|
18178
18290
|
numeric({
|
|
18179
18291
|
id: "battery",
|
|
@@ -18208,7 +18320,7 @@ var GROUP_TEMPLATES = [
|
|
|
18208
18320
|
quantity: "device",
|
|
18209
18321
|
defaultAggregate: "mean",
|
|
18210
18322
|
empty: "null",
|
|
18211
|
-
companions: [NOW]
|
|
18323
|
+
companions: [NOW$1]
|
|
18212
18324
|
}),
|
|
18213
18325
|
binary({
|
|
18214
18326
|
id: "motion",
|
|
@@ -18337,6 +18449,7 @@ function actuator(input) {
|
|
|
18337
18449
|
}
|
|
18338
18450
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18339
18451
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18452
|
+
DeviceType.Camera;
|
|
18340
18453
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18341
18454
|
/**
|
|
18342
18455
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -59128,6 +59241,11 @@ DeviceType.Lock, method(object({
|
|
|
59128
59241
|
kind: "mutation",
|
|
59129
59242
|
auth: "protected"
|
|
59130
59243
|
});
|
|
59244
|
+
object({
|
|
59245
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
59246
|
+
lastFetchedAt: number()
|
|
59247
|
+
});
|
|
59248
|
+
DeviceType.Sensor;
|
|
59131
59249
|
/**
|
|
59132
59250
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59133
59251
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -69466,6 +69584,13 @@ Object.freeze({
|
|
|
69466
69584
|
access: "create",
|
|
69467
69585
|
role: "admin"
|
|
69468
69586
|
},
|
|
69587
|
+
"meter.getStatus": {
|
|
69588
|
+
capName: "meter",
|
|
69589
|
+
capScope: "device",
|
|
69590
|
+
addonId: null,
|
|
69591
|
+
access: "view",
|
|
69592
|
+
role: "viewer"
|
|
69593
|
+
},
|
|
69469
69594
|
"metricsProvider.collectSnapshot": {
|
|
69470
69595
|
capName: "metrics-provider",
|
|
69471
69596
|
capScope: "system",
|
|
@@ -78424,6 +78549,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78424
78549
|
}],
|
|
78425
78550
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78426
78551
|
},
|
|
78552
|
+
meter: {
|
|
78553
|
+
scope: "device",
|
|
78554
|
+
noun: t("Meter", "Contatore"),
|
|
78555
|
+
state: [{
|
|
78556
|
+
kind: "numeric",
|
|
78557
|
+
field: "value",
|
|
78558
|
+
quantity: t("the total", "il totale"),
|
|
78559
|
+
label: t("Total", "Totale"),
|
|
78560
|
+
icon: "gauge"
|
|
78561
|
+
}]
|
|
78562
|
+
},
|
|
78427
78563
|
"numeric-sensor": {
|
|
78428
78564
|
scope: "device",
|
|
78429
78565
|
noun: t("Sensor", "Sensore"),
|
|
@@ -80113,6 +80249,11 @@ Object.freeze({
|
|
|
80113
80249
|
form: "single",
|
|
80114
80250
|
optional: false
|
|
80115
80251
|
}],
|
|
80252
|
+
"meter.getStatus": [{
|
|
80253
|
+
name: "deviceId",
|
|
80254
|
+
form: "single",
|
|
80255
|
+
optional: false
|
|
80256
|
+
}],
|
|
80116
80257
|
"motion.getStatus": [{
|
|
80117
80258
|
name: "deviceId",
|
|
80118
80259
|
form: "single",
|
|
@@ -81720,7 +81861,6 @@ Object.freeze({
|
|
|
81720
81861
|
"network-access": "ingress",
|
|
81721
81862
|
"smtp-provider": "email"
|
|
81722
81863
|
});
|
|
81723
|
-
DeviceType.Camera;
|
|
81724
81864
|
/**
|
|
81725
81865
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
81726
81866
|
* `z.infer`, they do not restate the shape.
|
|
@@ -83045,7 +83185,7 @@ var AdminUIAddon = class extends BaseAddon {
|
|
|
83045
83185
|
capability: adminUiCapability,
|
|
83046
83186
|
provider: {
|
|
83047
83187
|
getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
|
|
83048
|
-
getVersion: async () => ({ version: "1.2.
|
|
83188
|
+
getVersion: async () => ({ version: "1.2.485" })
|
|
83049
83189
|
}
|
|
83050
83190
|
}];
|
|
83051
83191
|
}
|
package/package.json
CHANGED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{C as e,J as t,K as n,R as r,S as i,V as a,Y as o,a as s,et as c,t as l,x as u}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CEyXHAdg.js";import{An as d,D as f,G as p,Gr as m,In as h,L as g,Lt as _,Mi as v,Ni as y,Oi as b,Q as x,Qt as S,Xt as C,Zi as w,Zr as T,dt as E,ei as D,fn as O,kn as k,kr as A,ot as j,pn as M,sr as N,xn as P}from"./player-overlays-BoPcGTkt.js";import{Ar as F,Fa as ee,jr as I}from"./client-xX9FBBul.js";import{n as L,t as R}from"./send-CNx75CN6.js";import{t as te}from"./message-square-plus-BCFV5CXr.js";import{$n as z,Cn as B,Dr as V,Er as H,Gn as U,Ir as ne,Or as re,Qr as W,So as G,St as K,Un as ie,ei as q,ht as ae,id as oe,kr as J,ld as se,pt as ce,rt as le,si as Y,sr as ue,ud as de,wn as fe,xn as X,xt as pe}from"./src-B9Sp1iss.js";import{t as Z}from"./i18n-B_TdOOX_.js";import{t as Q}from"./useTranslation-BJr-n0es.js";import"./mount-BqREn4Hm.js";import{S as me,hr as he}from"./index-Df_Bqvin.js";import{t as ge}from"./AdminSectionedPage-Dm8ND20L.js";import{t as _e}from"./AdminPage-CNutWOEU.js";c();var ve=`__redacted__`,ye=[`llm`,`listProfiles`],be=[`llm`,`listProfileKinds`],xe=[`llm`,`getDefaults`],Se=[`llm`,`listRuntimeNodes`],Ce=[`llm`,`listModelCatalog`],we=[`llm`,`getUsage`],Te=[{purpose:`vision`,visionOnly:!0},{purpose:`text`,visionOnly:!1}],Ee=new Map([[`cloud`,D],[`plug`,k],[`cpu`,T],[`server`,O],[`sparkles`,S]]);function De(e){return Ee.get(e)??y}function Oe(e){return typeof e==`string`&&e.length>0?e:void 0}function ke(e){if(typeof e==`number`&&Number.isFinite(e))return e;if(typeof e==`string`&&e.trim()!==``){let t=Number(e);return Number.isFinite(t)?t:void 0}}function Ae(e){return e===!0}function je(e){let t=new Map;for(let n of e){let e=t.get(n.addonId)??[];e.push(n),t.set(n.addonId,e)}return[...t.entries()].map(([e,t])=>({addonId:e,kinds:t}))}var Me={deviceNotEligible:{key:`ai.appleNotEligible`,tone:`default`},appleIntelligenceNotEnabled:{key:`ai.appleIntelligenceOff`,tone:`warning`},modelNotReady:{key:`ai.appleModelNotReady`,tone:`warning`},osTooOld:{key:`ai.appleOsTooOld`,tone:`default`},helperMissing:{key:`ai.appleHelperMissing`,tone:`danger`},helperCrashed:{key:`ai.appleHelperCrashed`,tone:`danger`}};function Ne(e){let t=t=>({nodeId:e.nodeId,selectable:!1,labelKey:`ai.appleUnknown`,labelDefault:Z.t(`ai.appleUnknown`),detail:t,tone:`default`});if(!e.reachable)return t(e.error??null);let n=e.apple;if(n===void 0)return t(null);switch(n.state){case`available`:return{nodeId:e.nodeId,selectable:!0,labelKey:`ai.appleAvailable`,labelDefault:Z.t(`ai.appleAvailable`),detail:Z.t(n.imageInput?`helpers.aiPage.appleDetailImages`:`helpers.aiPage.appleDetailText`,{version:n.osVersion}),tone:`success`};case`unavailable`:{let t=Me[n.reason];return{nodeId:e.nodeId,selectable:!1,labelKey:t.key,labelDefault:Z.t(t.key),detail:n.detail,tone:t.tone}}case`unsupported-platform`:return{nodeId:e.nodeId,selectable:!1,labelKey:`ai.appleNotMac`,labelDefault:Z.t(`ai.appleNotMac`),detail:n.platform,tone:`default`};case`unknown`:return t(n.error)}}var Pe={ready:`success`,downloading:`info`,starting:`info`,stopped:`danger`,crashed:`danger`,failed:`danger`};function Fe(e){return e.reachable?e.status===void 0?`success`:Pe[e.status.state]:`danger`}function Ie(e){if(!e.reachable)return[];let t=[],n=e.apple;if(n?.state===`available`)t.push({id:`apple`,labelKey:`ai.featureApple`,tone:`success`,detail:Ne(e).detail}),n.imageInput&&t.push({id:`apple-images`,labelKey:`ai.featureAppleImages`,tone:`success`,detail:null});else if(n?.state===`unavailable`){let n=Ne(e);t.push({id:`apple`,labelKey:`ai.featureApple`,tone:n.tone,detail:n.labelDefault})}let r=e.status?.vramBytes;return r!==void 0&&r>0&&t.push({id:`gpu`,labelKey:`ai.featureGpu`,tone:`info`,detail:null}),t}function Le(){return{temperature:[{type:`slider`,key:`temperature`,label:Z.t(`helpers.aiProfileForm.temperature`),min:0,max:2,step:.1,showValue:!0,showStepper:!0,nullable:!0,nullLabel:`Provider default`,description:Z.t(`helpers.aiProfileForm.temperatureHint`)}],topP:[{type:`slider`,key:`topP`,label:Z.t(`helpers.aiProfileForm.topP`),min:0,max:1,step:.05,showValue:!0,showStepper:!0,nullable:!0,nullLabel:`Provider default`}],topK:[{type:`number`,key:`topK`,label:Z.t(`helpers.aiProfileForm.topK`),min:1}],maxTokens:[{type:`number`,key:`maxTokens`,label:Z.t(`helpers.aiProfileForm.maxTokens`),min:1}],contextLength:[{type:`number`,key:`contextLength`,label:Z.t(`helpers.aiProfileForm.contextLength`),min:512,unit:`tokens`,description:Z.t(`helpers.aiProfileForm.contextLengthHint`)}],systemPrompt:[{type:`textarea`,key:`systemPrompt`,label:Z.t(`helpers.aiProfileForm.systemPrompt`),rows:4,maxLength:4e3,span:2,description:Z.t(`helpers.aiProfileForm.systemPromptHint`)}],timeoutMs:[{type:`number`,key:`timeoutMs`,label:Z.t(`helpers.aiProfileForm.timeoutTotal`),min:1e3,default:I.totalMs,unit:`ms`,description:Z.t(`helpers.aiProfileForm.timeoutTotalHint`)}],connectTimeoutMs:[{type:`number`,key:`connectTimeoutMs`,label:Z.t(`helpers.aiProfileForm.timeoutConnect`),min:500,default:I.connectMs,unit:`ms`,description:Z.t(`helpers.aiProfileForm.timeoutConnectHint`)}],firstTokenTimeoutMs:[{type:`number`,key:`firstTokenTimeoutMs`,label:Z.t(`helpers.aiProfileForm.timeoutFirstToken`),min:1e3,default:I.firstTokenMs,unit:`ms`,description:Z.t(`helpers.aiProfileForm.timeoutFirstTokenHint`)}],idleTimeoutMs:[{type:`number`,key:`idleTimeoutMs`,label:Z.t(`helpers.aiProfileForm.timeoutIdle`),min:1e3,default:I.idleMs,unit:`ms`,description:Z.t(`helpers.aiProfileForm.timeoutIdleHint`)}],retry:[{type:`boolean`,key:`retryEnabled`,label:Z.t(`helpers.aiProfileForm.retry`),description:Z.t(`helpers.aiProfileForm.retryHint`)},{type:`number`,key:`retryMaxAttempts`,label:Z.t(`helpers.aiProfileForm.retryMaxAttempts`),min:1,max:5,default:1,showWhen:{field:`retryEnabled`,equals:!0}}],toolsEnabled:[{type:`boolean`,key:`toolsEnabled`,label:Z.t(`helpers.aiProfileForm.toolsEnabled`),description:Z.t(`helpers.aiProfileForm.toolsEnabledHint`)}]}}var Re=[`temperature`,`topP`,`topK`,`maxTokens`,`contextLength`,`systemPrompt`],ze=[`timeoutMs`,`connectTimeoutMs`,`firstTokenTimeoutMs`,`idleTimeoutMs`,`retry`,`toolsEnabled`];function Be(e,t){let n=Le();return t.filter(t=>e.includes(t)).flatMap(e=>n[e])}function Ve(e){let t=Be(e,Re);return t.length===0?null:{sections:[{id:`generation`,title:Z.t(`helpers.aiProfileForm.generation`),fields:t}]}}function He(e){let t=Be(e,ze);return t.length===0?null:{sections:[{id:`bounds`,title:Z.t(`helpers.aiProfileForm.bounds`),fields:t}]}}function Ue(e){return e===null?{}:{temperature:e.temperature,topP:e.topP,topK:e.topK,maxTokens:e.maxTokens,contextLength:e.contextLength,systemPrompt:e.systemPrompt,timeoutMs:e.timeoutMs,connectTimeoutMs:e.connectTimeoutMs,firstTokenTimeoutMs:e.firstTokenTimeoutMs,idleTimeoutMs:e.idleTimeoutMs,retryEnabled:e.retry.enabled,retryMaxAttempts:e.retry.maxAttempts,toolsEnabled:e.toolsEnabled}}function We(e,t){return{...e.features,...t?.features}}function Ge(e,t){return t===null?e.modelCatalog===`static`?e.staticModels??[]:[]:t}function Ke(e,t,n){let r=e.profileFields,i=n.common,a=(e,t,n)=>r.includes(e)?ke(i[e])??t:n??t,o=e=>r.includes(e)?ke(i[e]):t?.[e],s=o(`temperature`),c=o(`topP`),l=o(`topK`),u=o(`maxTokens`),d=o(`contextLength`),f=r.includes(`systemPrompt`)?Oe(i.systemPrompt):t?.systemPrompt;return{id:t?.id??crypto.randomUUID(),name:n.name,kind:e.kind,addonId:e.addonId.length>0?e.addonId:`ai`,enabled:t?.enabled??!0,model:n.model,supportsVision:n.supportsVision,timeoutMs:a(`timeoutMs`,I.totalMs,t?.timeoutMs),connectTimeoutMs:a(`connectTimeoutMs`,I.connectMs,t?.connectTimeoutMs),firstTokenTimeoutMs:a(`firstTokenTimeoutMs`,I.firstTokenMs,t?.firstTokenTimeoutMs),idleTimeoutMs:a(`idleTimeoutMs`,I.idleMs,t?.idleTimeoutMs),retry:r.includes(`retry`)?{enabled:Ae(i.retryEnabled),maxAttempts:ke(i.retryMaxAttempts)??1}:t?.retry??{enabled:!1,maxAttempts:1},toolsEnabled:r.includes(`toolsEnabled`)?Ae(i.toolsEnabled):t?.toolsEnabled??!1,...s===void 0?{}:{temperature:s},...c===void 0?{}:{topP:c},...l===void 0?{}:{topK:l},...u===void 0?{}:{maxTokens:u},...d===void 0?{}:{contextLength:d},...f===void 0?{}:{systemPrompt:f},providerConfig:n.providerConfig}}var qe=2e3;function $(e){return Z.t(`system.aiModelPicker.sizeGb`,{value:(e/1e9).toFixed(2)})}function Je(e){return e===null?``:e.model.kind===`catalog`?`catalog:${e.model.catalogId}`:e.model.kind===`path`?`node:${e.modelId}`:`custom`}function Ye({nodeId:t,value:r,onChange:a}){let{t:c}=Q(),u=j(),[d,f]=o(``),[p,h]=o(null),[g,_]=o(!1),v=s({queryKey:Ce,queryFn:()=>u.trpcClient.llm.listModelCatalog.query({})}),y=s({queryKey:[`llm`,`listNodeModels`,t],queryFn:()=>u.trpcClient.llm.listNodeModels.query({nodeId:t})}),b=l({mutationFn:e=>u.trpcClient.llm.resolveModelRef.mutate(e),onSuccess:e=>{h(e),_(!1),e.ok&&a({model:e.model,modelId:e.label,supportsVision:e.purpose===`vision`})}}),x=l({mutationFn:e=>u.trpcClient.llm.installModel.mutate({nodeId:t,model:e}),onSuccess:()=>{_(!0),y.refetch()}}),S=s({queryKey:Se,enabled:x.isPending,refetchInterval:x.isPending?qe:!1,queryFn:()=>u.trpcClient.llm.listRuntimeNodes.query({})}).data?.find(e=>e.nodeId===t)?.status?.download,C=n(()=>{let e=(v.data??[]).map(e=>({value:`catalog:${e.id}`,label:`${e.label} · ${e.quantization} · ${$(e.sizeBytes)}`})),n=(y.data??[]).filter(e=>e.catalogId===void 0&&e.path!==void 0).map(e=>({value:`node:${e.file}`,label:c(`ai.onNode`,`{{file}} · {{size}} · on {{node}}`,{file:e.file,size:$(e.sizeBytes),node:t})})),r=p?.ok===!0?[{value:`custom`,label:`${p.label} · ${$(p.totalBytes)}`}]:[];return[{value:``,label:c(`ai.selectModel`,`Select a model…`)},...e,...n,...r]},[v.data,y.data,p,t,c]),w=e=>{if(e===``){a(null);return}if(e===`custom`){if(p?.ok!==!0)return;a({model:p.model,modelId:p.label,supportsVision:p.purpose===`vision`});return}if(e.startsWith(`catalog:`)){let t=e.slice(8),n=v.data?.find(e=>e.id===t);a({model:{kind:`catalog`,catalogId:t},modelId:t,supportsVision:n?.purpose===`vision`});return}let t=e.slice(5),n=y.data?.find(e=>e.file===t);n?.path!==void 0&&a({model:{kind:`path`,path:n.path},modelId:t,supportsVision:!1})},T=e=>{d.trim()!==``&&b.mutate({ref:d.trim(),...e===void 0?{}:{maxBytes:e}})};return e(`div`,{className:`space-y-3`,children:[i(K,{label:c(`ai.model`,`Model`),required:!0,children:i(oe,{id:`ai-model`,"aria-label":c(`ai.model`,`Model`),value:Je(r),options:C,onChange:e=>w(e.target.value)})}),i(K,{label:c(`ai.hfTitle`,`Add a model from Hugging Face`),description:c(`ai.hfHint`,`Paste a GGUF file URL, or type org/repo — add :QUANT (e.g. unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q4_K_M) when the repo publishes more than one quantization.`),children:e(`div`,{className:`flex gap-2`,children:[i(se,{"aria-label":c(`ai.hfTitle`,`Add a model from Hugging Face`),value:d,onChange:e=>f(e.target.value),placeholder:c(`system.aiModelPicker.unslothQwen3635bA3b`,`unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q4_K_M`),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),T())}}),e(q,{size:`sm`,variant:`secondary`,type:`button`,disabled:d.trim()===``||b.isPending,onClick:()=>T(),children:[b.isPending?i(N,{className:`h-3.5 w-3.5 animate-spin`}):i(M,{className:`h-3.5 w-3.5`}),c(`ai.hfCheck`,`Check`)]})]})}),b.isError&&i(H,{message:b.error instanceof Error?b.error.message:c(`common.error`,`Error`)}),p?.ok===!1&&i(H,{message:p.message,action:e(`div`,{className:`flex flex-wrap items-center gap-1`,children:[(p.candidates??[]).map(e=>i(q,{size:`sm`,variant:`outline`,type:`button`,onClick:()=>{let t=`${d.trim().split(`:`)[0]??``}:${e}`;f(t),b.mutate({ref:t})},children:e},e)),p.requiredBytes!==void 0&&i(q,{size:`sm`,variant:`secondary`,type:`button`,onClick:()=>T(p.requiredBytes),children:c(`ai.hfOverride`,`Install anyway ({{size}})`,{size:$(p.requiredBytes)})})]})}),p?.ok===!0&&e(`div`,{className:`space-y-2 rounded-md border border-border bg-surface p-2.5`,children:[e(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[i(`span`,{className:`text-[11px] font-medium text-foreground`,children:p.label}),i(Y,{variant:p.purpose===`vision`?`info`:`default`,children:p.purpose}),i(Y,{variant:`default`,children:$(p.totalBytes)})]}),p.extraFilenames.length>0&&i(`p`,{className:`text-[10px] text-foreground-subtle`,children:c(`ai.hfExtras`,`Also downloads: {{files}}`,{files:p.extraFilenames.join(`, `)})}),e(`div`,{className:`flex items-center gap-2`,children:[e(q,{size:`sm`,type:`button`,disabled:x.isPending||g,onClick:()=>x.mutate(p.model),children:[x.isPending?i(N,{className:`h-3.5 w-3.5 animate-spin`}):i(m,{className:`h-3.5 w-3.5`}),g?c(`ai.hfInstalled`,`Downloaded`):c(`ai.hfInstall`,`Download to {{node}}`,{node:t})]}),S!==void 0&&i(`span`,{className:`text-[10px] text-foreground-subtle`,children:S.phase===`verifying`?c(`ai.hfVerifying`,`verifying {{file}}…`,{file:S.file}):c(`ai.hfDownloading`,`{{file}} ({{index}}/{{count}}) — {{done}}{{total}}`,{file:S.file,index:S.fileIndex,count:S.fileCount,done:$(S.downloadedBytes),total:S.totalBytes===void 0?``:` / ${$(S.totalBytes)}`})})]}),x.isError&&i(H,{message:x.error instanceof Error?x.error.message:c(`common.error`,`Error`)})]})]})}function Xe({value:t,onChange:n}){let{t:r}=Q(),a=j(),o=s({queryKey:Se,queryFn:()=>a.trpcClient.llm.listRuntimeNodes.query({})});return e(`div`,{children:[i(`div`,{className:`mb-1 text-[11px] font-medium text-foreground`,children:r(`ai.appleNode`,`Mac that runs it`)}),o.isPending&&e(`div`,{className:`flex items-center gap-1.5 text-[11px] text-foreground-subtle`,children:[i(N,{className:`h-3.5 w-3.5 animate-spin`}),r(`ai.appleAsking`,`Asking the nodes…`)]}),o.isError&&i(`p`,{className:`text-[11px] text-danger`,children:o.error instanceof Error?o.error.message:r(`ai.runtimesFailed`,`Failed to read runtime nodes`)}),o.isSuccess&&o.data.length===0&&i(`p`,{className:`text-[11px] text-foreground-subtle`,children:r(`ai.noRuntimes`,`No node advertises the llm-runtime capability.`)}),o.isSuccess&&o.data.length>0&&i(`div`,{role:`radiogroup`,className:`space-y-1.5`,children:o.data.map(a=>{let o=Ne(a),s=o.nodeId===t;return e(`button`,{type:`button`,role:`radio`,"aria-checked":s,disabled:!o.selectable&&!s,onClick:()=>n(o.nodeId),className:`flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-left text-xs transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${s?`border-primary bg-primary/10`:`border-border bg-surface hover:bg-surface-hover`}`,children:[e(`span`,{className:`min-w-0`,children:[i(`span`,{className:`block font-medium text-foreground`,children:o.nodeId}),o.detail!==null&&i(`span`,{className:`block truncate text-[10px] text-foreground-subtle`,children:o.detail})]}),i(Y,{variant:o.tone,children:r(o.labelKey,o.labelDefault)})]},o.nodeId)})}),i(`p`,{className:`mt-1.5 text-[10px] leading-relaxed text-foreground-subtle`,children:r(`ai.appleHint`,`Text only for now — notification titles and summaries. Apple refuses prompts framed as surveillance; when it does, the next profile in the chain answers instead.`)})]})}function Ze(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:null}function Qe({providerConfig:e,onProviderConfigChange:t}){return i(Xe,{value:Ze(e,`nodeId`),onChange:n=>t({...e,nodeId:n})})}function $e({providerConfig:e,onProviderConfigChange:t,model:n,onModelChange:r}){let a=F.safeParse(e.model),o=a.success?{model:a.data,modelId:n.id,supportsVision:n.supportsVision}:null;return i(Ye,{nodeId:Ze(e,`nodeId`)??`hub`,value:o,onChange:n=>{if(n===null){let{model:n,...i}=e;t(i),r({id:``,supportsVision:!1});return}t({...e,model:n.model}),r({id:n.modelId,supportsVision:n.supportsVision})}})}var et=new Map([[`ai/apple-node`,Qe],[`ai/managed-model`,$e]]);function tt(e){return et.get(e)??null}c();function nt({kind:e,className:t}){return i(De(e.icon),{className:t,"aria-hidden":!0})}function rt({kinds:e,onPick:t,onCancel:r}){let{t:a}=Q(),o=n(()=>je(e),[e]),s=n(()=>new Map(e.map(e=>[`${e.addonId}:${e.kind}`,e])),[e]);return i(ae,{open:!0,onClose:r,title:a(`ai.chooseKind`,`Choose a profile type`),width:`lg`,testId:`ai-kind-picker`,children:i(pe,{emptyMessage:a(`ai.noKinds`,`No AI provider is installed.`),onPick:e=>{let n=s.get(e);n!==void 0&&t(n)},groups:o.map(e=>({id:e.addonId,label:e.addonId,tiles:e.kinds.map(t=>({key:`${e.addonId}:${t.kind}`,label:t.label,testId:`ai-kind-${t.kind}`,icon:i(nt,{kind:t,className:`h-5 w-5 text-foreground-subtle`})}))}))})})}function it(e){return(e?.sections??[]).flatMap(e=>e.fields)}function at(...e){let t={};for(let n of e)for(let e of it(n))`default`in e&&e.default!==void 0&&(t[e.key]=e.default);return t}function ot(e){return e==null?!1:typeof e==`string`?e.trim().length>0:!0}function st(e,t){return it(e).filter(e=>`required`in e&&e.required===!0&&!ot(t[e.key])).map(e=>`label`in e&&typeof e.label==`string`?e.label:e.key)}var ct={auth:{key:`ai.listAuth`,fallback:`Credentials refused`},network:{key:`ai.listNetwork`,fallback:`Endpoint unreachable`},unsupported:{key:`ai.listUnsupported`,fallback:`No model list`},invalid:{key:`ai.listInvalid`,fallback:`Connection incomplete`}};function lt(e,t){if(t!==null)return{id:t.model,supportsVision:t.supportsVision};let n=e.modelCatalog===`static`&&e.staticModels?.length===1?e.staticModels?.[0]:void 0;return{id:n?.id??``,supportsVision:We(e,n).vision}}function ut({kind:t,existing:r,onSave:a,onCancel:s,onChangeKind:c,saving:d,error:p}){let{t:m}=Q(),h=j(),[_,v]=o(r?.name??t.label),[y,b]=o(()=>r===null?at(t.connectionSchema,t.advancedSchema):{...r.providerConfig}),[x,S]=o(()=>Ue(r)),[C,T]=o(()=>lt(t,r)),[E,D]=o(!1),O=t.providerWidgets??[],k=O.filter(e=>e.placement===`connection`),A=O.find(e=>e.placement===`model`)??null,M=n(()=>[...ee(t.connectionSchema)].some(e=>r?.providerConfig[e]===ve),[r,t.connectionSchema]),F=l({mutationFn:()=>h.trpcClient.llm.listModels.mutate({addonId:t.addonId,kind:t.kind,connection:y,...r===null?{}:{profileId:r.id}}),onSuccess:e=>{e.ok&&T(n=>{let r=e.models.find(e=>e.id===n.id);return r===void 0?n:{id:n.id,supportsVision:We(t,r).vision}})}}),I=Ge(t,F.data?.ok===!0?F.data.models:null),L=I.find(e=>e.id===C.id),R=We(t,L),te=Ve(t.profileFields),B=He(t.profileFields),V=st(t.connectionSchema,y),U=O.some(e=>(e.requires??[]).some(e=>!ot(y[e]))),ne=t.modelCatalog===`fetch`&&A===null,re=it(t.connectionSchema).length>0||k.length>0,W=e=>{T({id:e,supportsVision:We(t,I.find(t=>t.id===e)).vision})},G=d||_.trim()===``||C.id.trim()===``||V.length>0||U,J=()=>{a(Ke(t,r,{name:_.trim(),model:C.id.trim(),supportsVision:t.visionEditable?C.supportsVision:!1,common:x,providerConfig:y}))},ce=r===null?m(`ai.newProfile`,`New {{kind}} profile`,{kind:t.label}):m(`ai.editProfile`,`Edit {{name}}`,{name:r.name}),le=e=>{let n=tt(e);return n===null?i(H,{variant:`warning`,message:m(`ai.unknownWidget`,`This provider needs an editor part this build does not have ({{id}}).`,{id:e})}):i(n,{descriptor:t,providerConfig:y,onProviderConfigChange:b,model:C,onModelChange:T},e)};return i(ae,{open:!0,onClose:s,title:ce,error:p,width:`lg`,testId:`ai-profile-editor`,footer:e(u,{children:[V.length>0&&i(Y,{variant:`warning`,children:m(`ai.missingRequired`,`required: {{fields}}`,{fields:V.join(`, `)})}),V.length===0&&U&&i(Y,{variant:`warning`,children:m(`ai.completeProvider`,`complete the provider settings`)}),V.length===0&&!U&&C.id.trim()===``&&i(Y,{variant:`warning`,children:m(`ai.pickModelFirst`,`pick a model`)}),e(q,{size:`sm`,type:`button`,disabled:G,onClick:J,children:[d&&i(N,{className:`h-3.5 w-3.5 animate-spin`}),r===null?m(`ai.createProfile`,`Create profile`):m(`ai.saveChanges`,`Save changes`)]})]}),children:e(`div`,{className:g,children:[e(`div`,{className:`flex flex-wrap items-center gap-2`,"data-testid":`ai-editor-provider`,children:[i(nt,{kind:t,className:`h-4 w-4 text-foreground-subtle`}),i(`span`,{className:`text-xs font-medium text-foreground`,children:t.label}),i(Y,{variant:`neutral`,children:t.addonId}),c!==void 0&&e(q,{size:`sm`,variant:`ghost`,type:`button`,onClick:c,children:[i(w,{className:`h-3.5 w-3.5`}),m(`ai.changeKind`,`Change type`)]})]}),i(K,{label:m(`ai.name`,`Name`),required:!0,children:i(se,{id:`ai-profile-name`,"aria-label":m(`ai.name`,`Name`),value:_,onChange:e=>v(e.target.value),placeholder:t.label})}),re&&i(X,{headingId:`ai-editor-connection`,title:m(`ai.sectionConnection`,`Connection`),actions:ne?e(q,{size:`sm`,variant:`secondary`,type:`button`,disabled:F.isPending,onClick:()=>F.mutate(),"data-testid":`ai-verify-models`,children:[F.isPending?i(N,{className:`h-3.5 w-3.5 animate-spin`}):i(P,{className:`h-3.5 w-3.5`}),m(`ai.verifyModels`,`Verify & load models`)]}):void 0,children:e(`div`,{className:`p-2 sm:p-3 lg:p-4 space-y-3`,children:[it(t.connectionSchema).length>0&&i(ue,{bare:!0,schema:t.connectionSchema,values:y,onChange:b}),k.map(e=>le(e.id)),M&&i(`p`,{className:`text-[10px] text-foreground-subtle`,children:m(`ai.secretHint`,`A stored API key is never shown. Leave it as-is to keep it; type a new value to replace it.`)}),F.data?.ok===!0&&i(Y,{variant:`success`,"data-testid":`ai-models-found`,children:m(`ai.modelsFound`,`{{count}} models found`,{count:F.data.models.length})}),F.data?.ok===!1&&i(H,{title:m(ct[F.data.code]?.key??`ai.listNetwork`,ct[F.data.code]?.fallback??`Endpoint unreachable`),message:F.data.message}),F.isError&&i(H,{message:F.error instanceof Error?F.error.message:m(`common.error`,`Error`)})]})}),i(X,{headingId:`ai-editor-model`,title:m(`ai.sectionModel`,`Model`),children:e(`div`,{className:`${f} space-y-3`,children:[A===null?e(u,{children:[I.length>0&&i(oe,{id:`ai-model-pick`,"aria-label":m(`ai.selectModel`,`Select a model…`),value:L===void 0?``:L.id,options:[{value:``,label:m(`ai.selectModel`,`Select a model…`)},...I.map(e=>({value:e.id,label:e.label??e.id}))],onChange:e=>{e.target.value!==``&&W(e.target.value)}}),i(K,{label:m(`ai.customModel`,`Model id`),description:m(`ai.customModelHint`,`Pick one from the list, or type any model id the provider accepts.`),required:!0,children:i(se,{id:`ai-model-id`,"aria-label":m(`ai.customModel`,`Model id`),value:C.id,onChange:e=>T({...C,id:e.target.value}),placeholder:I[0]?.id??`model-id`})})]}):le(A.id),e(`div`,{className:`flex flex-wrap items-center gap-1.5`,"data-testid":`ai-model-features`,children:[(C.supportsVision||!t.visionEditable&&R.vision)&&i(Y,{variant:`info`,children:m(`ai.featureVision`,`vision`)}),R.tools&&i(Y,{variant:`neutral`,children:m(`ai.featureTools`,`tools`)}),R.streaming&&i(Y,{variant:`neutral`,children:m(`ai.featureStreaming`,`streaming`)})]}),t.visionEditable&&i(K,{orientation:`horizontal`,label:m(`ai.supportsVision`,`Supports vision`),description:m(`ai.supportsVisionHint`,`A vision call against a text-only profile is refused, never downgraded.`),children:i(ie,{checked:C.supportsVision,onCheckedChange:e=>T({...C,supportsVision:e}),"aria-label":m(`ai.supportsVision`,`Supports vision`)})})]})}),te!==null&&i(X,{headingId:`ai-editor-generation`,title:m(`ai.sectionGeneration`,`Generation`),children:i(`div`,{className:`p-2 sm:p-3 lg:p-4`,children:i(ue,{bare:!0,schema:te,values:x,onChange:S})})}),(B!==null||t.advancedSchema!==void 0)&&i(z,{expanded:E,onExpandedChange:D,header:i(`span`,{className:`text-[11px] font-semibold uppercase tracking-wider text-foreground-subtle`,children:m(`ai.sectionAdvanced`,`Advanced`)}),children:e(`div`,{className:`p-2 sm:p-3 lg:p-4 space-y-3`,children:[B!==null&&i(ue,{bare:!0,schema:B,values:x,onChange:S}),t.advancedSchema!==void 0&&i(ue,{bare:!0,schema:t.advancedSchema,values:y,onChange:b})]})})]})})}c();function dt(t){return[{key:`name`,header:t.t(`ai.colProfile`,`Profile`),render:n=>{let r=t.kindByName.get(n.kind);return e(`span`,{className:`flex items-center gap-2`,children:[i(`span`,{className:`flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-surface`,title:r?.label??n.kind,children:r===void 0?i(`span`,{className:`text-xs text-foreground-subtle`,children:`?`}):i(nt,{kind:r,className:`h-4 w-4 text-foreground-subtle`})}),e(`span`,{className:`min-w-0`,children:[i(`span`,{className:`block truncate font-medium text-foreground`,children:n.name}),t.testResult?.id===n.id&&i(`span`,{className:`block truncate ${t.testResult.ok?`text-success`:`text-danger`}`,children:t.testResult.text})]})]})}},{key:`kind`,header:t.t(`ai.colKind`,`Kind`),nowrap:!0,render:e=>i(`span`,{className:`text-foreground-muted`,children:t.kindByName.get(e.kind)?.label??e.kind})},{key:`model`,header:t.t(`ai.colModel`,`Model`),render:e=>i(`span`,{className:`text-foreground`,children:e.model})},{key:`vision`,header:t.t(`ai.colVision`,`Vision`),align:`center`,nowrap:!0,render:e=>e.supportsVision?i(Y,{variant:`info`,style:`outline`,children:t.t(`ai.vision`,`vision`)}):i(`span`,{className:`text-foreground-subtle`,children:`—`})},{key:`node`,header:t.t(`ai.colNode`,`Node`),nowrap:!0,render:e=>typeof e.providerConfig.nodeId==`string`?i(Y,{variant:`default`,children:e.providerConfig.nodeId}):i(`span`,{className:`text-foreground-subtle`,children:`—`})},{key:`enabled`,header:t.t(`ai.colOn`,`On`),align:`center`,nowrap:!0,render:e=>i(ie,{checked:e.enabled,onCheckedChange:()=>t.onToggle(e),"aria-label":Z.t(`system.aiProfilesTab.toggle`,`toggle {{name}}`,{name:e.name})})},{key:`actions`,header:``,align:`right`,nowrap:!0,render:n=>e(`span`,{className:`flex items-center justify-end gap-1`,children:[i(q,{size:`sm`,variant:`ghost`,type:`button`,onClick:()=>t.onTest(n),"aria-label":t.t(`ai.test`,`Test`),title:t.t(`ai.test`,`Test`),children:t.testingId===n.id?i(N,{className:`h-3.5 w-3.5 animate-spin`}):i(R,{className:`h-3.5 w-3.5`})}),i(q,{size:`sm`,variant:`ghost`,type:`button`,disabled:!t.kindByName.has(n.kind),onClick:()=>t.onEdit(n),"aria-label":t.t(`common.edit`,`Edit`),title:t.t(`common.edit`,`Edit`),children:i(h,{className:`h-3.5 w-3.5`})}),i(q,{size:`sm`,variant:`ghost`,type:`button`,onClick:()=>t.onDelete(n),"aria-label":t.t(`common.delete`,`Delete`),title:t.t(`common.delete`,`Delete`),children:i(_,{className:`h-3.5 w-3.5 text-danger`})})]})}]}function ft(){let{t}=Q(),c=j(),{state:u,openEdit:d,close:p}=ce(),m=W(),[h,_]=o(null),[v,y]=o(null),[b,x]=o(null),C=s({queryKey:ye,queryFn:()=>c.trpcClient.llm.listProfiles.query({})}),w=s({queryKey:be,queryFn:async()=>(await c.trpcClient.llm.listProfileKinds.query({})).map(({connectionSchema:e,advancedSchema:t,...n})=>({...n,connectionSchema:e,...t===void 0?{}:{advancedSchema:t}}))}),T=()=>{C.refetch()},E=r(()=>{_(null),x(null),p()},[p]);a(()=>{u.mode===`closed`&&_(null)},[u.mode]);let D=l({mutationFn:e=>c.trpcClient.llm.upsertProfile.mutate({profile:e}),onSuccess:()=>{E(),T()},onError:e=>x(e instanceof Error?e.message:t(`ai.saveFailed`,`Save failed`))}),O=l({mutationFn:e=>c.trpcClient.llm.deleteProfile.mutate({addonId:e.addonId,profileId:e.id}),onSuccess:T}),k=l({mutationFn:e=>c.trpcClient.llm.testProfile.mutate({addonId:e.addonId,profileId:e.id}),onSuccess:(e,t)=>y({id:t.id,ok:e.ok,text:e.ok?Z.t(`system.aiProfilesTab.testOk`,{text:e.text,tokens:e.usage.outputTokens,ms:e.latencyMs}):`${e.code}: ${e.message}`})}),A=C.data??[],M=n(()=>w.data??[],[w.data]),N=n(()=>{let e=new Map;for(let t of M)e.set(t.kind,t);return e},[M]),P=u.mode===`edit`?A.find(e=>e.id===u.id)??null:null,F=P===null?null:N.get(P.kind)??null,ee=u.mode===`new`&&h===null,I=u.mode===`new`?h:F,L=u.mode===`edit`?P:null,R=I!==null&&(u.mode===`new`||L!==null),te=async e=>{await m({title:t(`ai.deleteProfileTitle`,`Delete profile?`),message:t(`ai.deleteProfileMessage`,`Delete "{{name}}". Features that name it will no longer get an answer from it.`,{name:e.name}),confirmLabel:t(`common.delete`,`Delete`),variant:`danger`})&&O.mutate(e)};return e(`div`,{className:g,children:[i(pt,{profiles:A}),i(X,{headingId:`ai-profiles-list`,title:t(`ai.profilesList`,`Profiles`),children:C.isPending?e(`div`,{className:`${f} space-y-2`,"data-testid":`ai-profiles-loading`,children:[i(J,{className:`h-8 w-full`}),i(J,{className:`h-8 w-full`}),i(J,{className:`h-8 w-full`})]}):C.isError?i(`div`,{className:f,children:i(H,{title:t(`ai.loadFailed`,`Failed to load profiles`),message:C.error instanceof Error?C.error.message:t(`common.error`,`Error`),onRetry:()=>void C.refetch()})}):A.length===0?i(V,{icon:S,title:t(`ai.noProfilesTitle`,`No AI profiles yet`),description:t(`ai.noProfiles`,`No AI profiles yet. Click "Add profile" to configure one.`)}):i(B,{columns:dt({kindByName:N,testResult:v,testingId:k.isPending?k.variables?.id??null:null,t,onToggle:e=>D.mutate({...e,enabled:!e.enabled}),onTest:e=>k.mutate(e),onEdit:e=>{N.has(e.kind)&&(x(null),_(null),d(e.id))},onDelete:e=>void te(e)}),rows:A,rowKey:e=>e.id,minWidthPx:760,bordered:!1,maxBodyHeight:fe})}),ee&&i(rt,{kinds:M,onCancel:E,onPick:e=>{x(null),_(e)}}),R&&I!==null&&i(ut,{kind:I,existing:L,saving:D.isPending,error:b,onSave:e=>D.mutate(e),onCancel:E,...u.mode===`new`?{onChangeKind:()=>{x(null),_(null)}}:{}})]})}function pt({profiles:t}){let{t:n}=Q(),r=j(),a=s({queryKey:xe,queryFn:()=>r.trpcClient.llm.getDefaults.query({})}),o=l({mutationFn:e=>r.trpcClient.llm.setDefault.mutate({selector:{purpose:e.purpose},profileId:e.profileId}),onSuccess:()=>{a.refetch()}}),c=e=>(a.data??[]).find(t=>`purpose`in t.selector&&t.selector.purpose===e)?.profileId??``,u=e=>e===`vision`?n(`ai.defaultVision`,`Default vision profile`):n(`ai.defaultText`,`Default text profile`);return i(X,{headingId:`ai-profiles-defaults`,title:n(`ai.defaultsTitle`,`Defaults`),children:i(`div`,{className:`${f} grid gap-4 sm:grid-cols-2`,children:Te.map(({purpose:r,visionOnly:a})=>{let s=a?t.filter(e=>e.supportsVision):t,l=c(r),d=t.find(e=>e.id===l);return e(`div`,{children:[i(U,{className:`mb-1 block`,htmlFor:`llm-default-${r}`,children:u(r)}),i(oe,{id:`llm-default-${r}`,"aria-label":u(r),value:l,onChange:e=>o.mutate({purpose:r,profileId:e.target.value===``?null:e.target.value}),options:[{value:``,label:n(`ai.none`,`None`)},...l!==``&&!s.some(e=>e.id===l)?[{value:l,label:d?.name??l}]:[],...s.map(e=>({value:e.id,label:`${e.name} · ${e.model}`}))]}),l!==``&&d===void 0&&i(`p`,{className:`mt-1 text-xs text-danger`,children:n(`ai.defaultMissing`,`This default names a profile that no longer exists.`)}),d!==void 0&&!d.enabled&&i(`p`,{className:`mt-1 text-xs text-warning`,children:n(`ai.defaultDisabled`,`This default profile is disabled — callers resolve to no profile.`)}),o.error!=null&&i(`p`,{className:`mt-1 text-xs text-danger`,children:String(o.error)})]},r)})})})}c();var mt=5e3;function ht(e){return Z.t(`system.aiRuntimes.sizeGb`,{value:(e/1e9).toFixed(1)})}function gt(){let{t}=Q(),r=j(),a=s({queryKey:Se,refetchInterval:mt,queryFn:()=>r.trpcClient.llm.listRuntimeNodes.query({})}),o=n(()=>[{key:`node`,header:t(`ai.colNode`,`Node`),render:e=>i(`span`,{className:`font-medium text-foreground`,children:e.nodeId})},{key:`state`,header:t(`ai.colState`,`State`),nowrap:!0,render:n=>e(`span`,{className:`flex items-center gap-1.5`,children:[i(Y,{variant:Fe(n),children:n.reachable?n.status?.state??t(`ai.ready`,`ready`):t(`ai.unreachable`,`unreachable`)}),n.status?.downloadProgress!==void 0&&i(Y,{variant:`info`,children:`${String(Math.round(n.status.downloadProgress*100))}%`})]})},{key:`model`,header:t(`ai.colModel`,`Model`),render:e=>i(`span`,{className:`text-foreground`,children:e.status?.modelId??`—`})},{key:`disk`,header:t(`ai.colDisk`,`On disk`),align:`right`,nowrap:!0,render:e=>i(`span`,{className:`tabular-nums text-foreground-muted`,children:e.disk===void 0?`—`:ht(e.disk.modelsBytes)})},{key:`features`,header:t(`ai.colFeatures`,`Features`),render:n=>{let r=Ie(n);if(r.length===0)return i(`span`,{className:`text-foreground-subtle`,children:`—`});let a=r.flatMap(e=>e.detail===null?[]:[e.detail]);return e(`span`,{className:`flex flex-col items-start gap-0.5`,children:[i(`span`,{className:`flex flex-wrap gap-1`,children:r.map(e=>i(Y,{variant:e.tone,children:t(e.labelKey)},e.id))}),a.length>0&&i(`span`,{className:`text-foreground-subtle`,children:a.join(` · `)})]})}},{key:`error`,header:t(`ai.colError`,`Error`),render:e=>e.error===void 0?i(`span`,{className:`text-foreground-subtle`,children:`—`}):i(`span`,{className:`text-danger`,children:e.error})}],[t]),c=a.data??[];return i(X,{headingId:`ai-runtimes-list`,title:t(`ai.runtimesList`,`Nodes`),children:a.isPending?e(`div`,{className:`${f} space-y-2`,"data-testid":`ai-runtimes-loading`,children:[i(J,{className:`h-8 w-full`}),i(J,{className:`h-8 w-full`})]}):a.isError?i(`div`,{className:f,children:i(H,{title:t(`ai.runtimesFailed`,`Failed to read runtime nodes`),message:a.error instanceof Error?a.error.message:t(`common.error`,`Error`),onRetry:()=>void a.refetch()})}):c.length===0?i(V,{icon:O,title:t(`ai.noRuntimesTitle`,`No runtime nodes`),description:t(`ai.noRuntimes`,`No node advertises the llm-runtime capability.`)}):i(B,{columns:o,rows:c,rowKey:e=>e.nodeId,minWidthPx:760,bordered:!1,maxBodyHeight:fe})})}var _t=x(`/addon/ai/test-chat`),vt=x(`/addon/ai/test-chat/chats`),yt=6e5;function bt(e){let t=e.firstTokenTimeoutMs;if(!(typeof t!=`number`||!Number.isFinite(t)||t<=0))return Math.min(Math.round(t),yt)}function xt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function St(e){if(!xt(e))return null;let t=e.kind;return t!==`snapshot`&&t!==`track`||typeof e.mimeType!=`string`||typeof e.sizeBytes!=`number`?null:{kind:t,mimeType:e.mimeType,sizeBytes:e.sizeBytes,...typeof e.mediaKind==`string`?{mediaKind:e.mediaKind}:{},...typeof e.capturedAt==`number`?{capturedAt:e.capturedAt}:{},...typeof e.thumbnailBase64==`string`?{thumbnailBase64:e.thumbnailBase64}:{}}}var Ct=[`resolving-image`,`connecting`,`first-token-wait`,`streaming`];function wt(e){let t;try{t=JSON.parse(e)}catch{return null}if(!xt(t))return null;switch(t.kind){case`status`:{let e=Ct.find(e=>e===t.phase);return e===void 0?null:{kind:`status`,phase:e}}case`meta`:return typeof t.profileName!=`string`||typeof t.model!=`string`?null:{kind:`meta`,profileName:t.profileName,model:t.model,mediaSent:St(t.mediaSent),streamed:t.streamed===!0,firstTokenTimeoutMs:typeof t.firstTokenTimeoutMs==`number`?t.firstTokenTimeoutMs:0};case`token`:return typeof t.text==`string`?{kind:`token`,text:t.text}:null;case`done`:return{kind:`done`,inputTokens:typeof t.inputTokens==`number`?t.inputTokens:0,outputTokens:typeof t.outputTokens==`number`?t.outputTokens:0,latencyMs:typeof t.latencyMs==`number`?t.latencyMs:0,truncated:t.truncated===!0,...typeof t.conversationId==`string`?{conversationId:t.conversationId}:{}};case`error`:return{kind:`error`,code:typeof t.code==`string`?t.code:`adapter-error`,message:typeof t.message==`string`?t.message:Z.t(`helpers.aiTestChat.providerError`)};default:return null}}async function*Tt(e){let t=e.getReader(),n=new TextDecoder,r=``;try{for(;;){let{done:e,value:i}=await t.read();if(e)break;r+=n.decode(i,{stream:!0});let a=r.indexOf(`
|
|
2
|
-
`);for(;a>=0;){let e=r.slice(0,a).trim();if(r=r.slice(a+1),e.length>0){let t=wt(e);t!==null&&(yield t)}a=r.indexOf(`
|
|
3
|
-
`)}}let e=r.trim();if(e.length>0){let t=wt(e);t!==null&&(yield t)}}finally{t.releaseLock()}}function Et(e){return e.filter(e=>e.failed!==!0&&e.content.length>0).map(e=>({role:e.role,content:e.content}))}function Dt(e){return e.thumbnailBase64===void 0||e.thumbnailBase64.length===0?null:`data:${e.mimeType};base64,${e.thumbnailBase64}`}function Ot(e){return e.messages.map((t,n)=>{let r=t.mediaSent??void 0;return{id:`${e.id}-${String(n)}`,role:t.role,content:t.content,...t.attachment===void 0?{}:{attachmentRef:t.attachment,attachmentKind:t.attachment.kind},...r===void 0?{}:{attachment:r}}})}function kt(e){let t=e.sizeBytes<1024*1024?`${(e.sizeBytes/1024).toFixed(0)} KB`:`${(e.sizeBytes/(1024*1024)).toFixed(1)} MB`,n=[e.kind===`snapshot`?`camera snapshot`:`track best-shot`,t];return e.mediaKind!==void 0&&n.push(e.mediaKind),e.capturedAt!==void 0&&n.push(new Date(e.capturedAt).toLocaleTimeString()),n.join(` · `)}function At(e,t){switch(e){case`resolving-image`:return Z.t(`helpers.aiTestChat.phaseImage`);case`connecting`:return Z.t(`helpers.aiTestChat.phaseConnecting`);case`first-token-wait`:return t>0?Z.t(`helpers.aiTestChat.phaseWaitUpTo`,{seconds:Math.round(t/1e3)}):Z.t(`helpers.aiTestChat.phaseWait`);case`streaming`:return Z.t(`helpers.aiTestChat.phaseAnswering`)}}c();var jt=[`pipelineAnalytics`,`listRecentTracks`,`ai-test`],Mt=360*60*1e3,Nt=40,Pt=160,Ft={phase:`connecting`,firstTokenTimeoutMs:0,text:``,mediaSent:null};function It(){let{t:c}=Q(),l=j(),[u,d]=o(``),[p,m]=o(``),[h,y]=o(``),[x,S]=o([]),[w,T]=o(null),[D,O]=o(`none`),[k,A]=o(`throwaway`),[M,N]=o(null),[P,F]=o([]),[ee,I]=o(null),[L,z]=o(null),B=t(null);a(()=>()=>B.current?.abort(),[]);let V=r(async()=>{let e=await fetch(vt,{credentials:`same-origin`});e.ok&&F((await e.json()).chats??[])},[]);a(()=>{k===`persistent`&&V()},[k,V]);let ne=s({queryKey:ye,queryFn:()=>l.trpcClient.llm.listProfiles.query({})}),re=n(()=>(ne.data??[]).filter(e=>e.enabled),[ne.data]),W=re.find(e=>e.id===u)??null,G=L!==null,K=r(async(e,t)=>{let n=new AbortController;B.current=n,I(null);let r=bt(W??{});z({...Ft,firstTokenTimeoutMs:r??0});let i=``,a=null,o,s=null,l=null,d;try{let c=await fetch(_t,{method:`POST`,headers:{"content-type":`application/json`},credentials:`same-origin`,signal:n.signal,body:JSON.stringify({profileId:u,messages:e,...p.trim()===``?{}:{system:p.trim()},...t===void 0?{}:{attachment:t},...r===void 0?{}:{firstTokenTimeoutMs:r},...k===`persistent`?{persist:!0,...M===null?{}:{conversationId:M}}:{}})});if(!c.ok||c.body===null){let e=await c.text().catch(()=>``);throw Error(e.length>0?e:`HTTP ${String(c.status)}`)}for await(let e of Tt(c.body))switch(e.kind){case`status`:z(t=>({...t??Ft,phase:e.phase}));break;case`meta`:a=e.mediaSent,o=e.model,z(t=>({...t??Ft,firstTokenTimeoutMs:e.firstTokenTimeoutMs,mediaSent:e.mediaSent}));break;case`token`:i+=e.text,z(e=>({...e??Ft,text:i}));break;case`done`:l={outputTokens:e.outputTokens,latencyMs:e.latencyMs},d=e.conversationId;break;case`error`:s=`${e.code}: ${e.message}`;break}}catch(e){n.signal.aborted||I(e instanceof Error?e.message:c(`common.error`,`Error`))}finally{B.current=null,z(null)}d!==void 0&&(N(d),V());let f=n.signal.aborted&&i.length>0;s===null&&i.length===0&&!f||S(e=>[...e,{id:`a-${String(Date.now())}`,role:`assistant`,content:s??i,...s===null?{}:{failed:!0},...a===null?{}:{attachment:a},...o!==void 0&&s===null?{model:o}:{},...l===null?{}:l}])},[k,M,W,u,V,p,c]),ie=r(()=>{let e=h.trim();if(e===``||u===``||G)return;let t={id:`u-${String(Date.now())}`,role:`user`,content:e,...w===null?{}:{attachmentLabel:w.label,attachmentKind:w.ref.kind}},n=[...x,t];S(n),y(``);let r=w?.ref;T(null),O(`none`),K(k===`persistent`&&M!==null?[{role:`user`,content:e}]:Et(n),r)},[k,M,h,w,u,K,G,x]),ae=()=>B.current?.abort(),J=()=>{B.current?.abort(),S([]),T(null),y(``),I(null),z(null),N(null)},ce=async e=>{B.current?.abort();let t=await fetch(`${vt}/${e}`,{credentials:`same-origin`});if(!t.ok)return;let n=await t.json();N(e),S(Ot(n)),z(null),I(null)};return e(`div`,{className:g,children:[i(X,{headingId:`ai-test-setup`,title:c(`ai.testSetup`,`Setup`),children:e(`div`,{className:`${f} space-y-3`,children:[e(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[e(`div`,{children:[i(U,{className:`mb-1 block`,htmlFor:`ai-test-profile`,children:c(`ai.profile`,`Profile`)}),i(oe,{id:`ai-test-profile`,value:u,onChange:e=>d(e.target.value),options:[{value:``,label:c(`ai.selectProfile`,`Select a profile…`)},...re.map(e=>({value:e.id,label:`${e.name} · ${e.model}${e.supportsVision?` · vision`:``}`}))]}),re.length===0&&!ne.isLoading&&i(`p`,{className:`mt-1 text-xs text-foreground-subtle`,children:c(`ai.noEnabledProfiles`,`No enabled profile. Add one on the Profiles tab.`)})]}),e(`div`,{children:[i(U,{className:`mb-1 block`,htmlFor:`ai-test-system`,children:c(`ai.systemPrompt`,`System prompt (optional)`)}),i(se,{id:`ai-test-system`,value:p,onChange:e=>m(e.target.value),placeholder:c(`ai.systemPlaceholder`,`Answer in one short sentence.`)})]})]}),i(le,{label:c(`ai.chatMode`,`Conversation mode`),value:k,options:[{value:`throwaway`,label:c(`ai.throwawayMode`,`Throwaway`)},{value:`persistent`,label:c(`ai.saveConversation`,`Save conversation`)}],onChange:e=>{A(e),e===`throwaway`&&N(null)}}),k===`persistent`&&e(`div`,{className:`space-y-2`,children:[i(`p`,{className:`text-xs text-foreground-subtle`,children:c(`ai.testSubtitlePersistent`,`Conversations are saved for you and can be reopened. Throwaway mode is still available.`)}),e(q,{size:`sm`,variant:`secondary`,type:`button`,onClick:J,children:[i(te,{className:`h-3.5 w-3.5`}),c(`ai.newChat`,`New chat`)]}),P.length>0&&i(`div`,{className:`max-h-36 divide-y divide-border overflow-y-auto rounded-md border border-border`,children:P.map(e=>i(`button`,{type:`button`,onClick:()=>void ce(e.id),className:`flex w-full px-2.5 py-1.5 text-left text-xs hover:bg-surface-hover ${e.id===M?`bg-primary/10`:``}`,children:i(`span`,{className:`min-w-0 flex-1 truncate text-foreground`,children:e.title})},e.id))})]}),i(`p`,{className:`text-xs text-foreground-subtle`,children:c(`ai.streamNote`,`The answer streams as the model produces it. A cold model can take a while to load — the status line says which phase it is in.`)}),W!==null&&!W.supportsVision&&i(`p`,{className:`text-xs text-warning`,children:c(`ai.notVision`,`This profile is not vision-capable — an attached image will be refused before anything is read.`)})]})}),ee!==null&&i(H,{title:c(`ai.chatFailed`,`The test call failed`),message:ee}),e(X,{headingId:`ai-test-conversation`,title:c(`ai.testConversation`,`Conversation`),actions:e(q,{size:`sm`,variant:`ghost`,type:`button`,disabled:x.length===0&&w===null,onClick:J,children:[i(_,{className:`h-3.5 w-3.5`}),c(`ai.clearChat`,`Clear`)]}),children:[i(Lt,{turns:x,live:L}),e(`div`,{className:`${f} space-y-2 border-t border-border`,children:[w!==null&&e(`div`,{className:`flex items-center gap-2 rounded-md border border-border bg-background px-2.5 py-1.5`,children:[w.ref.kind===`snapshot`?i(b,{className:`h-3.5 w-3.5 text-foreground-subtle`}):i(v,{className:`h-3.5 w-3.5 text-foreground-subtle`}),i(`span`,{className:`min-w-0 flex-1 truncate text-xs text-foreground`,children:w.label}),i(de,{size:`sm`,variant:`ghost`,type:`button`,icon:E,"aria-label":c(`ai.removeAttachment`,`Remove attachment`),onClick:()=>T(null)})]}),e(`div`,{className:`flex flex-wrap items-center gap-2`,children:[e(q,{size:`sm`,variant:D===`snapshot`?`primary`:`outline`,type:`button`,onClick:()=>O(D===`snapshot`?`none`:`snapshot`),children:[i(b,{className:`h-3.5 w-3.5`}),c(`ai.attachSnapshot`,`Camera snapshot`)]}),e(q,{size:`sm`,variant:D===`track`?`primary`:`outline`,type:`button`,onClick:()=>O(D===`track`?`none`:`track`),children:[i(v,{className:`h-3.5 w-3.5`}),c(`ai.attachTrack`,`Recent track`)]})]}),D===`snapshot`&&i(Bt,{onPick:(e,t)=>{T({ref:{kind:`snapshot`,deviceId:e.id},label:c(`ai.snapshotOf`,`Snapshot of {{name}}`,{name:t})}),O(`none`)}}),D===`track`&&i(Ht,{onPick:(e,t)=>{T({ref:{kind:`track`,trackId:e.trackId,deviceId:e.deviceId},label:c(`ai.trackOf`,`{{class}} on {{name}}`,{class:e.label??e.className,name:t})}),O(`none`)}}),e(`div`,{className:`flex items-center gap-2`,children:[i(se,{value:h,onChange:e=>y(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),ie())},placeholder:c(`ai.messagePlaceholder`,`Ask the model something…`),"aria-label":c(`ai.message`,`Message`)}),G?e(q,{size:`sm`,variant:`secondary`,type:`button`,onClick:ae,children:[i(C,{className:`h-3.5 w-3.5`}),c(`ai.stop`,`Stop`)]}):e(q,{size:`sm`,type:`button`,disabled:h.trim()===``||u===``,onClick:ie,children:[i(R,{className:`h-3.5 w-3.5`}),c(`ai.send`,`Send`)]})]})]})]})]})}function Lt({turns:t,live:n}){let{t:r}=Q();return t.length===0&&n===null?i(V,{icon:L,title:r(`ai.chatEmptyTitle`,`No messages yet`),description:r(`ai.chatEmpty`,`Pick a profile, optionally attach a camera snapshot or a recent track, and send a message. Nothing here is saved.`)}):e(`div`,{className:`max-h-[50vh] space-y-2 overflow-y-auto ${f}`,children:[t.map(e=>i(Rt,{turn:e},e.id)),n!==null&&e(`div`,{className:`space-y-1`,children:[n.mediaSent!==null&&i(zt,{attachment:n.mediaSent}),n.text.length>0&&i(Rt,{turn:{id:`live`,role:`assistant`,content:n.text},streaming:!0}),e(`div`,{className:`flex items-center gap-2 text-xs text-foreground-subtle`,children:[i(N,{className:`h-3.5 w-3.5 animate-spin`}),At(n.phase,n.firstTokenTimeoutMs)]})]})]})}function Rt({turn:t,streaming:n=!1}){let{t:r}=Q(),a=t.role===`user`,o=t.failed===!0?`border-danger/40 bg-danger/10`:`border-border bg-surface`;return i(`div`,{className:`flex ${a?`justify-end`:`justify-start`}`,children:e(`div`,{className:`max-w-[85%] rounded-lg border px-3 py-2 ${a?`border-primary/40 bg-primary/10`:o}`,children:[e(`p`,{className:`whitespace-pre-wrap break-words text-xs text-foreground`,children:[t.content,n&&i(`span`,{className:`ml-0.5 animate-pulse text-primary`,children:`▌`})]}),t.attachment!==void 0&&i(zt,{attachment:t.attachment}),t.attachmentLabel!==void 0&&e(`p`,{className:`mt-1 flex items-center gap-1 text-[10px] text-foreground-subtle`,children:[t.attachmentKind===`track`?i(v,{className:`h-3 w-3`}):i(b,{className:`h-3 w-3`}),t.attachmentLabel]}),t.attachment!==void 0&&e(`p`,{className:`mt-1 flex items-center gap-1 text-[10px] text-foreground-subtle`,children:[t.attachment.kind===`snapshot`?i(b,{className:`h-3 w-3`}):i(v,{className:`h-3 w-3`}),kt(t.attachment)]}),t.model!==void 0&&i(`p`,{className:`mt-1 text-[10px] text-foreground-subtle`,children:r(`system.aiTestChat.tokMs`,`{{model}} · {{value2}} tok · {{value3}} ms`,{model:t.model,value2:String(t.outputTokens??0),value3:String(t.latencyMs??0)})})]})})}function zt({attachment:e}){let{t}=Q(),n=Dt(e);return n===null?null:i(`img`,{src:n,alt:t(`system.aiTestChat.sentToTheModel`,`sent to the model`),className:`mt-1 max-h-32 rounded-md border border-border object-contain`})}function Bt({onPick:e}){let{t}=Q(),n=G({isCamera:!0,projection:`slim`}),r=(n.data??[]).filter(e=>!e.disabled);return n.isLoading?i(N,{className:`h-4 w-4 animate-spin text-foreground-subtle`}):r.length===0?i(`p`,{className:`text-[11px] text-foreground-subtle`,children:t(`ai.noCameras`,`No camera found.`)}):i(`div`,{className:`grid max-h-56 grid-cols-2 gap-2 overflow-y-auto sm:grid-cols-4`,children:r.map(t=>i(Vt,{device:t,onPick:e},t.id))})}function Vt({device:t,onPick:n}){let{t:r}=Q(),a=ne(t,`compact`),{src:o}=p(t.id,{width:Pt});return e(`button`,{type:`button`,onClick:()=>n(t,a),className:`overflow-hidden rounded-md border border-border bg-surface text-left transition-colors hover:border-primary/50`,children:[i(`span`,{className:`block aspect-video w-full bg-background-elevated`,children:o!==null&&i(`img`,{src:o,alt:``,className:`h-full w-full object-cover`,loading:`lazy`})}),e(`span`,{className:`flex items-center gap-1 px-2 py-1`,children:[!t.online&&i(Y,{variant:`warning`,children:r(`common.off`)}),i(`span`,{className:`truncate text-[10px] text-foreground`,children:a})]})]})}function Ht({onPick:t}){let{t:r}=Q(),a=j(),o=G({isCamera:!0,projection:`slim`}),c=n(()=>(o.data??[]).map(e=>e.id),[o.data]),l=n(()=>{let e=new Map;for(let t of o.data??[])e.set(t.id,t.name);return e},[o.data]),u=s({queryKey:[...jt,c.length],enabled:c.length>0,queryFn:()=>a.trpcClient.pipelineAnalytics.listRecentTracks.query({deviceIds:[...c],since:Date.now()-Mt,limit:Nt,projection:`slim`})});if(o.isLoading||u.isLoading)return i(N,{className:`h-4 w-4 animate-spin text-foreground-subtle`});let d=u.data?.tracks??[];return d.length===0?i(`p`,{className:`text-[11px] text-foreground-subtle`,children:r(`ai.noTracks`,`No track in the last 6 hours.`)}):i(`div`,{className:`max-h-56 divide-y divide-border overflow-y-auto rounded-md border border-border`,children:d.map(n=>e(`button`,{type:`button`,onClick:()=>t(n,l.get(n.deviceId)??String(n.deviceId)),className:`flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-[11px] hover:bg-surface-hover`,children:[i(v,{className:`h-3.5 w-3.5 shrink-0 text-foreground-subtle`}),i(`span`,{className:`min-w-0 flex-1 truncate text-foreground`,children:n.label??n.className}),i(`span`,{className:`shrink-0 text-foreground-subtle`,children:l.get(n.deviceId)??n.deviceId}),i(`span`,{className:`shrink-0 text-foreground-subtle`,children:new Date(n.lastSeen).toLocaleTimeString()})]},n.trackId))})}c();var Ut=1440*60*1e3,Wt=[1,7,30,90];function Gt(){let{t}=Q(),r=j(),[a,c]=o(7),l=n(()=>{let e=new Date;return e.setHours(0,0,0,0),e.getTime()-(a-1)*Ut},[a]),u=s({queryKey:ye,queryFn:()=>r.trpcClient.llm.listProfiles.query({})}),d=s({queryKey:[...we,a],queryFn:()=>r.trpcClient.llm.getUsage.query({since:l})}),p=n(()=>{let e=new Map;for(let t of u.data??[])e.set(t.id,t.name);return e},[u.data]),m=n(()=>[{key:`day`,header:t(`ai.colDay`,`Day`),nowrap:!0,render:e=>i(`span`,{className:`tabular-nums`,children:e.day})},{key:`consumer`,header:t(`ai.colConsumer`,`Consumer`),nowrap:!0,render:e=>i(`span`,{className:`text-foreground`,children:e.consumer})},{key:`profile`,header:t(`ai.colProfile`,`Profile`),render:e=>i(`span`,{className:`text-foreground`,children:p.get(e.profileId)??e.profileId})},{key:`calls`,header:t(`ai.colCalls`,`Calls`),align:`right`,nowrap:!0,render:e=>i(`span`,{className:`tabular-nums`,children:String(e.calls)})},{key:`okErr`,header:t(`ai.colOkErr`,`OK / err`),align:`right`,nowrap:!0,render:e=>i(`span`,{className:`tabular-nums ${e.errorCalls>0?`text-danger`:``}`,children:`${String(e.okCalls)} / ${String(e.errorCalls)}`})},{key:`tokens`,header:t(`ai.colTokens`,`In / out tok`),align:`right`,nowrap:!0,render:e=>i(`span`,{className:`tabular-nums`,children:`${String(e.inputTokens)} / ${String(e.outputTokens)}`})},{key:`latency`,header:t(`ai.colAvgMs`,`Avg ms`),align:`right`,nowrap:!0,render:e=>i(`span`,{className:`tabular-nums`,children:String(Math.round(e.avgLatencyMs))})}],[p,t]),h=d.data??[],g=i(`div`,{className:`w-36`,children:i(oe,{"aria-label":t(`ai.window`,`Window`),value:String(a),options:Wt.map(e=>({value:String(e),label:t(`ai.lastDays`,`Last {{days}} days`,{days:e})})),onChange:e=>c(Number(e.target.value))})});return i(X,{headingId:`ai-usage-list`,title:t(`ai.usageList`,`Rollup`),actions:g,children:d.isPending?e(`div`,{className:`${f} space-y-2`,"data-testid":`ai-usage-loading`,children:[i(J,{className:`h-8 w-full`}),i(J,{className:`h-8 w-full`}),i(J,{className:`h-8 w-full`})]}):d.isError?i(`div`,{className:f,children:i(H,{title:t(`ai.usageFailed`,`Failed to read usage`),message:d.error instanceof Error?d.error.message:t(`common.error`,`Error`),onRetry:()=>void d.refetch()})}):h.length===0?i(V,{icon:A,title:t(`ai.noUsage`,`No AI calls in this window.`)}):i(B,{columns:m,rows:h,rowKey:e=>`${e.day}|${e.consumer}|${e.profileId}`,minWidthPx:720,bordered:!1,maxBodyHeight:fe})})}var Kt=`llm`,qt=[`profiles`,`runtimes`,`usage`,`test`],Jt=[`new`,`edit`];function Yt(e){return qt.some(t=>t===e)}function Xt(){let{t}=Q(),n=re(Kt),[r]=he(),{openNew:a}=ce(),o=me(`/system/ai`,{t,isAdmin:!0})??{icon:S,title:t(`system.ai`,`AI`)};if(n!==`present`)return i(_e,{icon:o.icon,title:o.title,children:i(Zt,{presence:n})});let s=r.get(`tab`),c=Yt(s)?s:`profiles`,l={profiles:t(`ai.profilesSubtitle`,`One row = one usable model endpoint. The defaults below decide who answers when a feature names no profile.`),runtimes:t(`ai.runtimesSubtitle`,`Nodes advertising the llm-runtime capability: what each has loaded, what it is downloading, and how much model data sits on its disk.`),usage:t(`ai.usageSubtitle`,`Server-side rollup per day, consumer and profile — never raw call rows. Errors are counted, so a profile that always fails is visible here before a feature reports it.`),test:t(`ai.testSubtitle`,`A throwaway conversation with one profile. Attach a live camera snapshot or a recent track to check the model can actually read a picture. Nothing is saved — only the usage row.`)},u=c===`profiles`?e(q,{size:`sm`,type:`button`,"data-testid":`ai-add-profile`,onClick:a,children:[i(d,{className:`h-3.5 w-3.5`}),t(`ai.addProfile`,`Add profile`)]}):void 0;return i(ge,{icon:o.icon,title:o.title,subtitle:l[c],actions:u,defaultSection:`profiles`,sectionsLabel:`${o.title} sections`,sections:[{id:`profiles`,label:t(`ai.tabProfiles`,`Profiles`),content:i(ft,{}),ownedParams:Jt},{id:`runtimes`,label:t(`ai.tabRuntimes`,`Runtimes`),content:i(gt,{})},{id:`usage`,label:t(`ai.tabUsage`,`Usage`),content:i(Gt,{})},{id:`test`,label:t(`ai.tabTest`,`Test`),content:i(It,{})}]})}function Zt({presence:t}){let{t:n}=Q();return t===`pending`?e(`div`,{className:`space-y-3`,"data-testid":`ai-presence-pending`,children:[i(J,{className:`h-8 w-64`}),i(J,{className:`h-40 w-full`})]}):t===`unknown`?i(H,{title:n(`ai.presenceUnknownTitle`,`Could not check whether AI is installed`),message:n(`ai.presenceUnknown`,`The hub did not answer the capability check. Reload the page to try again.`)}):i(V,{icon:S,title:n(`ai.absentTitle`,`AI is not installed`),description:n(`ai.absentDescription`,`Install the AI addon from System → Addons to add model profiles.`)})}export{Xt as AiProfilesPage,Xt as default};
|