@victor-software-house/pi-openai-proxy 4.2.3 → 4.2.5
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/extensions/proxy.ts +72 -151
- package/package.json +1 -1
package/extensions/proxy.ts
CHANGED
|
@@ -33,9 +33,6 @@ import {
|
|
|
33
33
|
import {
|
|
34
34
|
type Component,
|
|
35
35
|
Container,
|
|
36
|
-
fuzzyFilter,
|
|
37
|
-
getKeybindings,
|
|
38
|
-
Input,
|
|
39
36
|
type SettingItem,
|
|
40
37
|
SettingsList,
|
|
41
38
|
Text,
|
|
@@ -553,180 +550,104 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
553
550
|
_currentValue: string,
|
|
554
551
|
done: (selectedValue?: string) => void,
|
|
555
552
|
): Component {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
provider: string;
|
|
559
|
-
}
|
|
553
|
+
const models = getAvailableModels();
|
|
554
|
+
const selected = new Set(config.customModels);
|
|
560
555
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
556
|
+
// Build provider order from sorted model list
|
|
557
|
+
const providerOrder: string[] = [];
|
|
558
|
+
for (const m of models) {
|
|
559
|
+
if (!providerOrder.includes(m.provider)) providerOrder.push(m.provider);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
const items: SettingItem[] = models.map((m) => {
|
|
563
|
+
const canonical = `${m.provider}/${m.id}`;
|
|
564
|
+
return {
|
|
565
|
+
id: canonical,
|
|
566
|
+
label: canonical,
|
|
567
|
+
description: `Provider: ${m.provider} | Left/Right: jump provider`,
|
|
568
|
+
currentValue: selected.has(canonical) ? "on" : "off",
|
|
569
|
+
values: ["on", "off"],
|
|
570
|
+
};
|
|
571
|
+
});
|
|
565
572
|
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
lastOf.set(entry.provider, i);
|
|
584
|
-
}
|
|
585
|
-
return { firstOf, lastOf };
|
|
586
|
-
}
|
|
573
|
+
const list = new SettingsList(
|
|
574
|
+
items,
|
|
575
|
+
Math.min(items.length + 2, 20),
|
|
576
|
+
getSettingsListTheme(),
|
|
577
|
+
(id: string, newValue: string) => {
|
|
578
|
+
if (newValue === "on") {
|
|
579
|
+
selected.add(id);
|
|
580
|
+
} else {
|
|
581
|
+
selected.delete(id);
|
|
582
|
+
}
|
|
583
|
+
config = { ...config, customModels: [...selected] };
|
|
584
|
+
saveConfigToFile(config);
|
|
585
|
+
config = loadConfigFromFile();
|
|
586
|
+
},
|
|
587
|
+
() => done(`${String(selected.size)} selected`),
|
|
588
|
+
{ enableSearch: true },
|
|
589
|
+
);
|
|
587
590
|
|
|
591
|
+
// SettingsList has no public selectedIndex setter.
|
|
592
|
+
// Access internals via bracket notation for provider jumping.
|
|
588
593
|
function jumpProvider(direction: "prev" | "next"): void {
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
const
|
|
594
|
+
const sl = list as unknown as Record<string, unknown>;
|
|
595
|
+
const idx = sl["selectedIndex"] as number;
|
|
596
|
+
const display = (
|
|
597
|
+
(sl["searchEnabled"] as boolean) ? sl["filteredItems"] : sl["items"]
|
|
598
|
+
) as SettingItem[];
|
|
599
|
+
if (display.length === 0) return;
|
|
600
|
+
|
|
601
|
+
const current = display[idx];
|
|
592
602
|
if (current === undefined) return;
|
|
603
|
+
const currentProv = current.id.split("/")[0] ?? "";
|
|
604
|
+
const provIdx = providerOrder.indexOf(currentProv);
|
|
593
605
|
|
|
594
|
-
|
|
595
|
-
const provIdx = providers.indexOf(current.provider);
|
|
596
|
-
|
|
606
|
+
let target: number;
|
|
597
607
|
if (direction === "prev") {
|
|
598
608
|
if (provIdx <= 0) {
|
|
599
|
-
|
|
609
|
+
target = 0;
|
|
600
610
|
} else {
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
611
|
+
const prev = providerOrder[provIdx - 1] ?? "";
|
|
612
|
+
target = 0;
|
|
613
|
+
for (let i = display.length - 1; i >= 0; i--) {
|
|
614
|
+
if (display[i]?.id.startsWith(`${prev}/`) === true) {
|
|
615
|
+
target = i;
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
604
618
|
}
|
|
605
619
|
}
|
|
606
620
|
} else {
|
|
607
|
-
if (provIdx >=
|
|
608
|
-
|
|
621
|
+
if (provIdx >= providerOrder.length - 1) {
|
|
622
|
+
target = display.length - 1;
|
|
609
623
|
} else {
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
624
|
+
const next = providerOrder[provIdx + 1] ?? "";
|
|
625
|
+
target = display.length - 1;
|
|
626
|
+
for (let i = 0; i < display.length; i++) {
|
|
627
|
+
if (display[i]?.id.startsWith(`${next}/`) === true) {
|
|
628
|
+
target = i;
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
613
631
|
}
|
|
614
632
|
}
|
|
615
633
|
}
|
|
634
|
+
sl["selectedIndex"] = target;
|
|
616
635
|
}
|
|
617
636
|
|
|
618
|
-
function toggle(idx: number): void {
|
|
619
|
-
const entry = filtered[idx];
|
|
620
|
-
if (entry === undefined) return;
|
|
621
|
-
if (selected.has(entry.canonical)) {
|
|
622
|
-
selected.delete(entry.canonical);
|
|
623
|
-
} else {
|
|
624
|
-
selected.add(entry.canonical);
|
|
625
|
-
}
|
|
626
|
-
config = { ...config, customModels: [...selected] };
|
|
627
|
-
saveConfigToFile(config);
|
|
628
|
-
config = loadConfigFromFile();
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
function applyFilter(query: string): void {
|
|
632
|
-
if (query === "") {
|
|
633
|
-
filtered = models;
|
|
634
|
-
} else {
|
|
635
|
-
filtered = fuzzyFilter(models, query, (m) => m.canonical);
|
|
636
|
-
}
|
|
637
|
-
selectedIndex = 0;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
const theme = getSettingsListTheme();
|
|
641
|
-
|
|
642
637
|
return {
|
|
643
638
|
render(width: number): string[] {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (filtered.length === 0) {
|
|
649
|
-
lines.push(theme.hint(" No matching models"));
|
|
650
|
-
lines.push("");
|
|
651
|
-
lines.push(theme.hint(" Type to filter | Left/Right: jump provider | Esc: done"));
|
|
652
|
-
return lines;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
const start = Math.max(
|
|
656
|
-
0,
|
|
657
|
-
Math.min(selectedIndex - Math.floor(maxVisible / 2), filtered.length - maxVisible),
|
|
658
|
-
);
|
|
659
|
-
const end = Math.min(start + maxVisible, filtered.length);
|
|
660
|
-
|
|
661
|
-
let lastProvider = "";
|
|
662
|
-
for (let i = start; i < end; i++) {
|
|
663
|
-
const entry = filtered[i];
|
|
664
|
-
if (entry === undefined) continue;
|
|
665
|
-
|
|
666
|
-
// Provider separator
|
|
667
|
-
if (entry.provider !== lastProvider) {
|
|
668
|
-
if (lastProvider !== "") lines.push("");
|
|
669
|
-
lastProvider = entry.provider;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
const check = selected.has(entry.canonical) ? "[x]" : "[ ]";
|
|
673
|
-
const cursor = i === selectedIndex ? theme.cursor : " ";
|
|
674
|
-
const label =
|
|
675
|
-
i === selectedIndex
|
|
676
|
-
? theme.label(`${check} ${entry.canonical}`, true)
|
|
677
|
-
: theme.label(`${check} ${entry.canonical}`, false);
|
|
678
|
-
lines.push(`${cursor}${label}`.slice(0, width));
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
if (start > 0 || end < filtered.length) {
|
|
682
|
-
lines.push(theme.hint(` (${String(selectedIndex + 1)}/${String(filtered.length)})`));
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
lines.push("");
|
|
686
|
-
lines.push(
|
|
687
|
-
theme.description(` ${String(selected.size)} of ${String(models.length)} selected`),
|
|
688
|
-
);
|
|
689
|
-
lines.push("");
|
|
690
|
-
lines.push(
|
|
691
|
-
theme.hint(" Type to filter | Space: toggle | Left/Right: jump provider | Esc: done"),
|
|
692
|
-
);
|
|
693
|
-
return lines;
|
|
639
|
+
return list.render(width);
|
|
640
|
+
},
|
|
641
|
+
invalidate(): void {
|
|
642
|
+
list.invalidate();
|
|
694
643
|
},
|
|
695
|
-
invalidate(): void {},
|
|
696
644
|
handleInput(data: string): void {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (kb.matches(data, "tui.select.cancel")) {
|
|
700
|
-
done(`${String(selected.size)} selected`);
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
if (filtered.length === 0) {
|
|
704
|
-
// Still allow typing to refine filter
|
|
705
|
-
const sanitized = data.replace(/ /g, "");
|
|
706
|
-
if (sanitized !== "") {
|
|
707
|
-
searchInput.handleInput(sanitized);
|
|
708
|
-
applyFilter(searchInput.getValue());
|
|
709
|
-
}
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
if (kb.matches(data, "tui.select.up")) {
|
|
713
|
-
selectedIndex = selectedIndex <= 0 ? filtered.length - 1 : selectedIndex - 1;
|
|
714
|
-
} else if (kb.matches(data, "tui.select.down")) {
|
|
715
|
-
selectedIndex = selectedIndex >= filtered.length - 1 ? 0 : selectedIndex + 1;
|
|
716
|
-
} else if (data === "\x1B[D") {
|
|
717
|
-
// Left arrow: previous provider
|
|
645
|
+
if (data === "\x1B[D") {
|
|
718
646
|
jumpProvider("prev");
|
|
719
647
|
} else if (data === "\x1B[C") {
|
|
720
|
-
// Right arrow: next provider
|
|
721
648
|
jumpProvider("next");
|
|
722
|
-
} else if (kb.matches(data, "tui.select.confirm") || data === " ") {
|
|
723
|
-
toggle(selectedIndex);
|
|
724
649
|
} else {
|
|
725
|
-
|
|
726
|
-
if (sanitized !== "") {
|
|
727
|
-
searchInput.handleInput(sanitized);
|
|
728
|
-
applyFilter(searchInput.getValue());
|
|
729
|
-
}
|
|
650
|
+
list.handleInput(data);
|
|
730
651
|
}
|
|
731
652
|
},
|
|
732
653
|
};
|
package/package.json
CHANGED