@klarkxy/dsh-magpie 0.1.0 → 0.1.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/lib/client.js CHANGED
@@ -446,16 +446,27 @@ const inject = [
446
446
  "locale"
447
447
  ];
448
448
  const styles = `${officialUiCss(".mgp-root")}
449
+ .mgp-root .mgp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; min-width: 0; }
449
450
  .mgp-root .mgp-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
450
- .mgp-root .mgp-row > .mgp-grow { flex: 1 1 220px; }
451
+ .mgp-root .mgp-grow { flex: 1 1 220px; min-width: 0; }
451
452
  .mgp-root .mgp-danger { color: var(--dsw-alias-state-error-primary); }
453
+ /* The advanced disclosure: a plain details/summary, so it opens without any
454
+ * script and keeps the keyboard behaviour the platform gives it. */
455
+ .mgp-root .mgp-advanced { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 8px; min-width: 0; }
456
+ .mgp-root .mgp-advanced > summary { display: inline-flex; align-items: center; gap: 6px; width: fit-content; cursor: pointer; list-style: none; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }
457
+ .mgp-root .mgp-advanced > summary::-webkit-details-marker { display: none; }
458
+ .mgp-root .mgp-advanced > summary::before { content: ''; width: 5px; height: 5px; border-right: 1.5px solid currentcolor; border-bottom: 1.5px solid currentcolor; transform: rotate(-45deg) translate(-1px, -1px); transition: transform 120ms ease; }
459
+ .mgp-root .mgp-advanced[open] > summary::before { transform: rotate(45deg) translate(-1px, -1px); }
460
+ .mgp-root .mgp-advanced > summary:hover { color: var(--dsw-alias-label-primary); }
461
+ .mgp-root .mgp-advanced-body { display: flex; flex-direction: column; gap: 12px; padding-top: 12px; min-width: 0; }
452
462
  `;
453
463
  const copy = {
454
464
  zh: {
455
465
  loading: "正在读取状态…",
456
466
  failed: "操作失败:",
457
467
  retry: "重试",
458
- connection: "连接",
468
+ title: "Magpie",
469
+ intro: "连接本机、局域网或远程的 magpie 网关,把它的模型加入本 profile 的模型列表。",
459
470
  address: "网关地址",
460
471
  addressHelp: "本机、局域网或远程的 magpie 网关,例如 http://127.0.0.1:3425。",
461
472
  key: "网关 Key",
@@ -466,7 +477,6 @@ const copy = {
466
477
  test: "测试",
467
478
  save: "保存",
468
479
  saved: "已保存。",
469
- sync: "同步",
470
480
  syncNow: "立即同步",
471
481
  syncing: "正在同步…",
472
482
  syncOnStart: "启动时同步",
@@ -486,13 +496,15 @@ const copy = {
486
496
  confirmDisconnect: "确认断开?",
487
497
  disconnectHelp: "移除三条 magpie 供应商路由并还原默认模型与网络搜索;已保存的 Key 保留。",
488
498
  testOk: (n) => `连接正常,网关返回 ${n} 个模型。`,
489
- notConnected: "尚未连接。"
499
+ notConnected: "尚未连接。",
500
+ advanced: "高级设置"
490
501
  },
491
502
  en: {
492
503
  loading: "Loading status…",
493
504
  failed: "Action failed: ",
494
505
  retry: "Retry",
495
- connection: "Connection",
506
+ title: "Magpie",
507
+ intro: "Point DSH at a magpie gateway on this computer, your LAN, or elsewhere, and its models join this profile.",
496
508
  address: "Gateway address",
497
509
  addressHelp: "A magpie gateway on this computer, your LAN, or elsewhere, e.g. http://127.0.0.1:3425.",
498
510
  key: "Gateway key",
@@ -503,7 +515,6 @@ const copy = {
503
515
  test: "Test",
504
516
  save: "Save",
505
517
  saved: "Saved.",
506
- sync: "Sync",
507
518
  syncNow: "Sync now",
508
519
  syncing: "Syncing…",
509
520
  syncOnStart: "Sync at startup",
@@ -523,7 +534,8 @@ const copy = {
523
534
  confirmDisconnect: "Confirm disconnect?",
524
535
  disconnectHelp: "Removes the three magpie provider routes and reverts the default model and web search; the saved key is kept.",
525
536
  testOk: (n) => `Connection OK: the gateway returned ${n} models.`,
526
- notConnected: "Not connected yet."
537
+ notConnected: "Not connected yet.",
538
+ advanced: "Advanced"
527
539
  }
528
540
  };
529
541
  var RpcError = class extends Error {
@@ -625,23 +637,33 @@ function MagpieSettingsPage({ client }) {
625
637
  setAddress((current) => addressDirty ? current : next.address);
626
638
  };
627
639
  if (!status) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
628
- className: "mgp-root dsh-ui-page dsh-ui-form",
640
+ className: "mgp-root dsh-ui-card",
629
641
  "data-testid": "magpie-settings",
630
- children: [error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
631
- role: "alert",
632
- className: "dsh-ui-error",
633
- children: [text.failed, error]
634
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
635
- role: "status",
636
- className: "dsh-ui-hint",
637
- children: text.loading
638
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
639
- variant: "ghost",
640
- size: "sm",
641
- disabled: Boolean(busy),
642
- onClick: () => void load(),
643
- children: text.retry
644
- })]
642
+ children: [
643
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
644
+ className: "dsh-ui-heading",
645
+ children: text.title
646
+ }),
647
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
648
+ role: "alert",
649
+ className: "dsh-ui-error",
650
+ children: [text.failed, error]
651
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
652
+ role: "status",
653
+ className: "dsh-ui-hint",
654
+ children: text.loading
655
+ }),
656
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
657
+ className: "dsh-ui-actions",
658
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
659
+ variant: "ghost",
660
+ size: "sm",
661
+ disabled: Boolean(busy),
662
+ onClick: () => void load(),
663
+ children: text.retry
664
+ })
665
+ })
666
+ ]
645
667
  });
646
668
  const models = status.models;
647
669
  const defaultChoices = models.map((model) => model.id);
@@ -650,10 +672,25 @@ function MagpieSettingsPage({ client }) {
650
672
  const found = models.find((model) => model.id === id);
651
673
  return found ? `${found.name ?? id} · ${found.route}` : id;
652
674
  };
675
+ const gatewaySummary = status.gateway ? `${status.gateway.name}${status.gateway.version ? ` ${status.gateway.version}` : ""} · ${text.models(models.length)}` : text.notConnected;
653
676
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
654
- className: "mgp-root dsh-ui-page dsh-ui-form",
677
+ className: "mgp-root dsh-ui-card",
655
678
  "data-testid": "magpie-settings",
656
679
  children: [
680
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
681
+ className: "mgp-head",
682
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
683
+ className: "dsh-ui-heading",
684
+ children: text.title
685
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
686
+ className: "dsh-ui-meta",
687
+ children: gatewaySummary
688
+ })]
689
+ }),
690
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
691
+ className: "dsh-ui-help",
692
+ children: text.intro
693
+ }),
657
694
  status.writable === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
658
695
  role: "status",
659
696
  className: "dsh-ui-hint",
@@ -669,282 +706,257 @@ function MagpieSettingsPage({ client }) {
669
706
  className: "dsh-ui-notice",
670
707
  children: note
671
708
  }) : null,
672
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
673
- className: "dsh-ui-card",
709
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
710
+ className: "dsh-ui-fields-grid",
711
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
712
+ className: "dsh-ui-field",
713
+ children: [
714
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
715
+ className: "dsh-ui-label",
716
+ children: text.address
717
+ }),
718
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
719
+ value: addressDirty ? address : status.address,
720
+ placeholder: "http://127.0.0.1:3425",
721
+ onChange: (event) => {
722
+ setAddress(event.target.value);
723
+ setAddressDirty(true);
724
+ }
725
+ }),
726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
727
+ className: "dsh-ui-help",
728
+ children: text.addressHelp
729
+ })
730
+ ]
731
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
732
+ className: "dsh-ui-field",
733
+ children: [
734
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
735
+ className: "dsh-ui-label",
736
+ children: [
737
+ text.key,
738
+ " ",
739
+ status.keyConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
740
+ tone: "success",
741
+ children: text.keyConfigured
742
+ }) : null
743
+ ]
744
+ }),
745
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
746
+ className: "mgp-row",
747
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
748
+ className: "mgp-grow",
749
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
750
+ type: "password",
751
+ value: keyDraft,
752
+ placeholder: text.keyPlaceholder,
753
+ onChange: (event) => setKeyDraft(event.target.value)
754
+ })
755
+ }), status.keyConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
756
+ variant: "ghost",
757
+ size: "sm",
758
+ disabled: Boolean(busy),
759
+ onClick: () => void action("clear-key", async () => {
760
+ refresh(await call(RPC_ENDPOINTS.saveConnection, { clearKey: true }));
761
+ setNote(text.saved);
762
+ }),
763
+ children: text.keyClear
764
+ }) : null]
765
+ }),
766
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
767
+ className: "dsh-ui-help",
768
+ children: text.keyHelp
769
+ })
770
+ ]
771
+ })]
772
+ }),
773
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
774
+ className: "dsh-ui-actions",
674
775
  children: [
675
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
676
- className: "dsh-ui-label",
677
- children: text.connection
678
- }),
679
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
680
- className: "dsh-ui-field",
681
- children: [
682
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
683
- className: "dsh-ui-label",
684
- children: text.address
685
- }),
686
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
687
- value: addressDirty ? address : status.address,
688
- placeholder: "http://127.0.0.1:3425",
689
- onChange: (event) => {
690
- setAddress(event.target.value);
691
- setAddressDirty(true);
692
- }
693
- }),
694
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
695
- className: "dsh-ui-help",
696
- children: text.addressHelp
697
- })
698
- ]
699
- }),
700
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
701
- className: "dsh-ui-field",
702
- children: [
703
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
704
- className: "dsh-ui-label",
705
- children: [
706
- text.key,
707
- " ",
708
- status.keyConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
709
- tone: "success",
710
- children: text.keyConfigured
711
- }) : null
712
- ]
713
- }),
714
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
715
- className: "mgp-row",
716
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
717
- className: "mgp-grow",
718
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
719
- type: "password",
720
- value: keyDraft,
721
- placeholder: text.keyPlaceholder,
722
- onChange: (event) => setKeyDraft(event.target.value)
723
- })
724
- }), status.keyConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
725
- variant: "ghost",
726
- size: "sm",
727
- disabled: Boolean(busy),
728
- onClick: () => void action("clear-key", async () => {
729
- refresh(await call(RPC_ENDPOINTS.saveConnection, { clearKey: true }));
730
- setNote(text.saved);
731
- }),
732
- children: text.keyClear
733
- }) : null]
734
- }),
735
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
736
- className: "dsh-ui-help",
737
- children: text.keyHelp
738
- })
739
- ]
740
- }),
741
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
742
- className: "dsh-ui-form-footer mgp-row",
743
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
744
- variant: "outline",
745
- size: "md",
746
- disabled: Boolean(busy),
747
- onClick: () => void action("test", async () => {
748
- if (addressDirty || keyDraft) {
749
- refresh(await call(RPC_ENDPOINTS.saveConnection, {
750
- address,
751
- apiKey: keyDraft || void 0
752
- }));
753
- setKeyDraft("");
754
- setAddressDirty(false);
755
- }
756
- const result = await call(RPC_ENDPOINTS.test);
757
- setNote(text.testOk(result.models));
758
- await load();
759
- }),
760
- children: text.test
761
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
762
- variant: "primary",
763
- size: "md",
764
- disabled: Boolean(busy) || !addressDirty && !keyDraft,
765
- onClick: () => void action("save", async () => {
776
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
777
+ variant: "outline",
778
+ size: "sm",
779
+ disabled: Boolean(busy),
780
+ onClick: () => void action("test", async () => {
781
+ if (addressDirty || keyDraft) {
766
782
  refresh(await call(RPC_ENDPOINTS.saveConnection, {
767
783
  address,
768
784
  apiKey: keyDraft || void 0
769
785
  }));
770
786
  setKeyDraft("");
771
787
  setAddressDirty(false);
772
- setNote(text.saved);
773
- }),
774
- children: text.save
775
- })]
788
+ }
789
+ const result = await call(RPC_ENDPOINTS.test);
790
+ setNote(text.testOk(result.models));
791
+ await load();
792
+ }),
793
+ children: text.test
794
+ }),
795
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
796
+ variant: "primary",
797
+ size: "sm",
798
+ disabled: Boolean(busy) || !addressDirty && !keyDraft,
799
+ onClick: () => void action("save", async () => {
800
+ refresh(await call(RPC_ENDPOINTS.saveConnection, {
801
+ address,
802
+ apiKey: keyDraft || void 0
803
+ }));
804
+ setKeyDraft("");
805
+ setAddressDirty(false);
806
+ setNote(text.saved);
807
+ }),
808
+ children: text.save
809
+ }),
810
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
811
+ variant: "outline",
812
+ size: "sm",
813
+ disabled: Boolean(busy) || status.syncing,
814
+ onClick: () => void action("sync", async () => {
815
+ refresh(await call(RPC_ENDPOINTS.sync));
816
+ setNote(text.saved);
817
+ }),
818
+ children: status.syncing ? text.syncing : text.syncNow
776
819
  })
777
820
  ]
778
821
  }),
779
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
780
- className: "dsh-ui-card",
781
- children: [
782
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
783
- className: "mgp-row",
784
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
785
- className: "dsh-ui-label mgp-grow",
786
- children: text.sync
787
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
788
- variant: "outline",
789
- size: "md",
790
- disabled: Boolean(busy) || status.syncing,
791
- onClick: () => void action("sync", async () => {
792
- refresh(await call(RPC_ENDPOINTS.sync));
793
- setNote(text.saved);
794
- }),
795
- children: status.syncing ? text.syncing : text.syncNow
796
- })]
797
- }),
798
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
799
- className: "dsh-ui-field",
800
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
801
- className: "mgp-row",
802
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
823
+ className: "mgp-advanced",
824
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: text.advanced }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
825
+ className: "mgp-advanced-body",
826
+ children: [
827
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
828
+ className: "dsh-ui-field",
829
+ children: [
830
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
831
+ className: "dsh-ui-label",
832
+ children: text.defaultModel
833
+ }),
834
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
835
+ className: "dsh-ui-select",
836
+ value: status.options.defaultModel ?? "",
837
+ disabled: Boolean(busy),
838
+ onChange: (event) => void action("options", async () => {
839
+ refresh(await call(RPC_ENDPOINTS.setOptions, { defaultModel: event.target.value || null }));
840
+ }),
841
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
842
+ value: "",
843
+ children: text.keepCurrent
844
+ }), defaultChoices.map((id) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
845
+ value: id,
846
+ children: modelLabel(id)
847
+ }, id))]
848
+ }),
849
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
850
+ className: "dsh-ui-help",
851
+ children: text.defaultModelHelp
852
+ })
853
+ ]
854
+ }),
855
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
856
+ className: "dsh-ui-toggle-row",
857
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
858
+ className: "dsh-ui-toggle-text",
859
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
860
+ className: "dsh-ui-toggle-label",
861
+ children: text.webSearch
862
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
863
+ className: "dsh-ui-help",
864
+ children: text.webSearchHelp
865
+ })]
866
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
867
+ checked: status.options.webSearch,
868
+ disabled: Boolean(busy),
869
+ label: text.webSearch,
870
+ onChange: (next) => void action("options", async () => {
871
+ refresh(await call(RPC_ENDPOINTS.setOptions, { webSearch: next }));
872
+ })
873
+ })]
874
+ }),
875
+ status.options.webSearch ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
876
+ className: "dsh-ui-field",
877
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
878
+ className: "dsh-ui-select",
879
+ value: status.options.webSearchModel ?? "",
880
+ disabled: Boolean(busy),
881
+ onChange: (event) => void action("options", async () => {
882
+ refresh(await call(RPC_ENDPOINTS.setOptions, { webSearchModel: event.target.value || null }));
883
+ }),
884
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
885
+ value: "",
886
+ children: text.sameAsDefault
887
+ }), models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
888
+ value: model.id,
889
+ children: model.name ?? model.id
890
+ }, model.id))]
891
+ })
892
+ }) : null,
893
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
894
+ className: "dsh-ui-toggle-row",
895
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
896
+ className: "dsh-ui-toggle-text",
897
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
898
+ className: "dsh-ui-toggle-label",
899
+ children: text.syncOnStart
900
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
901
+ className: "dsh-ui-help",
902
+ children: text.syncOnStartHelp
903
+ })]
904
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
803
905
  checked: status.options.syncOnStart,
804
906
  disabled: Boolean(busy),
805
907
  label: text.syncOnStart,
806
908
  onChange: (next) => void action("options", async () => {
807
909
  refresh(await call(RPC_ENDPOINTS.setOptions, { syncOnStart: next }));
808
910
  })
809
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
810
- className: "dsh-ui-label",
811
- children: text.syncOnStart
812
911
  })]
813
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
814
- className: "dsh-ui-help",
815
- children: text.syncOnStartHelp
816
- })]
817
- }),
818
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
819
- className: "dsh-ui-meta",
820
- children: [
821
- text.lastSync,
822
- ": ",
823
- status.lastSync ? `${new Date(status.lastSync.at).toLocaleString()} · ${Object.entries(status.lastSync.routes).map(([route, count]) => `${route}: ${count}`).join(" · ")}` : text.never
824
- ]
825
- }),
826
- status.lastSync?.warnings.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
827
- className: "dsh-ui-label",
828
- children: text.warnings
829
- }), status.lastSync.warnings.map((warning, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
830
- className: "dsh-ui-hint",
831
- children: warning
832
- }, index))] }) : null,
833
- status.lastError ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
834
- role: "alert",
835
- className: "dsh-ui-error",
836
- children: [
837
- new Date(status.lastError.at).toLocaleString(),
838
- " · ",
839
- status.lastError.message
840
- ]
841
- }) : null,
842
- status.gateway ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
843
- className: "dsh-ui-hint",
844
- children: [
845
- status.gateway.name,
846
- status.gateway.version ? ` ${status.gateway.version}` : "",
847
- " · ",
848
- text.models(models.length)
849
- ]
850
- }) : null
851
- ]
852
- }),
853
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("article", {
854
- className: "dsh-ui-card",
855
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
856
- className: "dsh-ui-field",
857
- children: [
858
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
859
- className: "dsh-ui-label",
860
- children: text.defaultModel
861
912
  }),
862
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
863
- className: "dsh-ui-select",
864
- value: status.options.defaultModel ?? "",
865
- disabled: Boolean(busy),
866
- onChange: (event) => void action("options", async () => {
867
- refresh(await call(RPC_ENDPOINTS.setOptions, { defaultModel: event.target.value || null }));
868
- }),
869
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
870
- value: "",
871
- children: text.keepCurrent
872
- }), defaultChoices.map((id) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
873
- value: id,
874
- children: modelLabel(id)
875
- }, id))]
913
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
914
+ className: "dsh-ui-meta",
915
+ children: [
916
+ text.lastSync,
917
+ ": ",
918
+ status.lastSync ? `${new Date(status.lastSync.at).toLocaleString()} · ${Object.entries(status.lastSync.routes).map(([route, count]) => `${route}: ${count}`).join(" · ")}` : text.never
919
+ ]
876
920
  }),
877
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
878
- className: "dsh-ui-help",
879
- children: text.defaultModelHelp
880
- })
881
- ]
882
- })
883
- }),
884
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
885
- className: "dsh-ui-card",
886
- children: [
887
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
888
- className: "mgp-row",
889
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
890
- className: "dsh-ui-label mgp-grow",
891
- children: text.webSearch
892
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
893
- checked: status.options.webSearch,
894
- disabled: Boolean(busy),
895
- label: text.webSearch,
896
- onChange: (next) => void action("options", async () => {
897
- refresh(await call(RPC_ENDPOINTS.setOptions, { webSearch: next }));
898
- })
899
- })]
900
- }),
901
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
902
- className: "dsh-ui-help",
903
- children: text.webSearchHelp
904
- }),
905
- status.options.webSearch ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
906
- className: "dsh-ui-field",
907
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
908
- className: "dsh-ui-select",
909
- value: status.options.webSearchModel ?? "",
910
- disabled: Boolean(busy),
911
- onChange: (event) => void action("options", async () => {
912
- refresh(await call(RPC_ENDPOINTS.setOptions, { webSearchModel: event.target.value || null }));
913
- }),
914
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
915
- value: "",
916
- children: text.sameAsDefault
917
- }), models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
918
- value: model.id,
919
- children: model.name ?? model.id
920
- }, model.id))]
921
- })
922
- }) : null
923
- ]
924
- }),
925
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("article", {
926
- className: "dsh-ui-card",
927
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
928
- className: "mgp-row",
929
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
930
- className: "mgp-grow",
931
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
921
+ status.lastSync?.warnings.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
932
922
  className: "dsh-ui-label",
933
- children: text.disconnect
934
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
935
- className: "dsh-ui-help",
936
- children: text.disconnectHelp
937
- })]
938
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfirmButton, {
939
- label: text.disconnect,
940
- confirmLabel: text.confirmDisconnect,
941
- disabled: Boolean(busy),
942
- onConfirm: () => void action("disconnect", async () => {
943
- refresh(await call(RPC_ENDPOINTS.disconnect));
944
- setNote(text.saved);
923
+ children: text.warnings
924
+ }), status.lastSync.warnings.map((warning, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
925
+ className: "dsh-ui-hint",
926
+ children: warning
927
+ }, index))] }) : null,
928
+ status.lastError ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
929
+ role: "alert",
930
+ className: "dsh-ui-error",
931
+ children: [
932
+ new Date(status.lastError.at).toLocaleString(),
933
+ " · ",
934
+ status.lastError.message
935
+ ]
936
+ }) : null,
937
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
938
+ className: "mgp-row",
939
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
940
+ className: "mgp-grow",
941
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
942
+ className: "dsh-ui-label",
943
+ children: text.disconnect
944
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
945
+ className: "dsh-ui-help",
946
+ children: text.disconnectHelp
947
+ })]
948
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfirmButton, {
949
+ label: text.disconnect,
950
+ confirmLabel: text.confirmDisconnect,
951
+ disabled: Boolean(busy),
952
+ onConfirm: () => void action("disconnect", async () => {
953
+ refresh(await call(RPC_ENDPOINTS.disconnect));
954
+ setNote(text.saved);
955
+ })
956
+ })]
945
957
  })
946
- })]
947
- })
958
+ ]
959
+ })]
948
960
  })
949
961
  ]
950
962
  });
@@ -959,9 +971,10 @@ function apply(ctx) {
959
971
  document.head.appendChild(style);
960
972
  return () => style.remove();
961
973
  }, "magpie.styles");
962
- ctx.effect(() => client.slots.inject("plugins.bundle.config", () => client.slots.register({
963
- name: "plugins.bundle.config",
964
- key: PLUGIN_NAME
974
+ ctx.effect(() => client.slots.inject("settings.models.footer", () => client.slots.register({
975
+ name: "settings.models.footer",
976
+ id: "magpie",
977
+ order: 100
965
978
  }, () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MagpieSettingsPage, { client }))), "magpie.settings");
966
979
  }
967
980
  //#endregion