Skip to content

Commit aa4d3f4

Browse files
authored
Merge pull request #2549 from github/koesie10/consistent-sorting
Sort methods sent to LLM the same way as the UI
2 parents 75d2f76 + 90c8391 commit aa4d3f4

File tree

10 files changed

+173
-128
lines changed

10 files changed

+173
-128
lines changed

extensions/ql-vscode/src/data-extensions-editor/auto-model.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
ModelRequest,
88
} from "./auto-model-api";
99
import type { UsageSnippetsBySignature } from "./auto-model-usages-query";
10+
import { groupMethods, sortGroupNames, sortMethods } from "./shared/sorting";
11+
import { Mode } from "./shared/mode";
1012

1113
// Soft limit on the number of candidates to send to the model.
1214
// Note that the model may return fewer than this number of candidates.
@@ -19,18 +21,22 @@ export function createAutoModelRequest(
1921
externalApiUsages: ExternalApiUsage[],
2022
modeledMethods: Record<string, ModeledMethod>,
2123
usages: UsageSnippetsBySignature,
24+
mode: Mode,
2225
): ModelRequest {
2326
const request: ModelRequest = {
2427
language,
2528
samples: [],
2629
candidates: [],
2730
};
2831

29-
// Sort by number of usages so we always send the most used methods first
30-
externalApiUsages = [...externalApiUsages];
31-
externalApiUsages.sort((a, b) => b.usages.length - a.usages.length);
32+
// Sort the same way as the UI so we send the first ones listed in the UI first
33+
const grouped = groupMethods(externalApiUsages, mode);
34+
const sortedGroupNames = sortGroupNames(grouped);
35+
const sortedExternalApiUsages = sortedGroupNames.flatMap((name) =>
36+
sortMethods(grouped[name]),
37+
);
3238

33-
for (const externalApiUsage of externalApiUsages) {
39+
for (const externalApiUsage of sortedExternalApiUsages) {
3440
const modeledMethod: ModeledMethod = modeledMethods[
3541
externalApiUsage.signature
3642
] ?? {

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
457457
externalApiUsages,
458458
modeledMethods,
459459
usages,
460+
this.mode,
460461
);
461462

462463
await this.showProgress({

extensions/ql-vscode/src/view/data-extensions-editor/modeled.ts renamed to extensions/ql-vscode/src/data-extensions-editor/shared/modeled-percentage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
1+
import { ExternalApiUsage } from "../external-api-usage";
22

33
export function calculateModeledPercentage(
44
externalApiUsages: Array<Pick<ExternalApiUsage, "supported">>,
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { ExternalApiUsage } from "../external-api-usage";
2+
import { Mode } from "./mode";
3+
import { calculateModeledPercentage } from "./modeled-percentage";
4+
5+
export function groupMethods(
6+
externalApiUsages: ExternalApiUsage[],
7+
mode: Mode,
8+
): Record<string, ExternalApiUsage[]> {
9+
const groupedByLibrary: Record<string, ExternalApiUsage[]> = {};
10+
11+
for (const externalApiUsage of externalApiUsages) {
12+
// Group by package if using framework mode
13+
const key =
14+
mode === Mode.Framework
15+
? externalApiUsage.packageName
16+
: externalApiUsage.library;
17+
18+
groupedByLibrary[key] ??= [];
19+
groupedByLibrary[key].push(externalApiUsage);
20+
}
21+
22+
return groupedByLibrary;
23+
}
24+
25+
export function sortGroupNames(
26+
methods: Record<string, ExternalApiUsage[]>,
27+
): string[] {
28+
return Object.keys(methods).sort((a, b) =>
29+
compareGroups(methods[a], a, methods[b], b),
30+
);
31+
}
32+
33+
export function sortMethods(
34+
externalApiUsages: ExternalApiUsage[],
35+
): ExternalApiUsage[] {
36+
const sortedExternalApiUsages = [...externalApiUsages];
37+
sortedExternalApiUsages.sort((a, b) => compareMethod(a, b));
38+
return sortedExternalApiUsages;
39+
}
40+
41+
function compareGroups(
42+
a: ExternalApiUsage[],
43+
aName: string,
44+
b: ExternalApiUsage[],
45+
bName: string,
46+
): number {
47+
const supportedPercentageA = calculateModeledPercentage(a);
48+
const supportedPercentageB = calculateModeledPercentage(b);
49+
50+
// Sort first by supported percentage ascending
51+
if (supportedPercentageA > supportedPercentageB) {
52+
return 1;
53+
}
54+
if (supportedPercentageA < supportedPercentageB) {
55+
return -1;
56+
}
57+
58+
const numberOfUsagesA = a.reduce((acc, curr) => acc + curr.usages.length, 0);
59+
const numberOfUsagesB = b.reduce((acc, curr) => acc + curr.usages.length, 0);
60+
61+
// If the number of usages is equal, sort by number of methods descending
62+
if (numberOfUsagesA === numberOfUsagesB) {
63+
const numberOfMethodsA = a.length;
64+
const numberOfMethodsB = b.length;
65+
66+
// If the number of methods is equal, sort by library name ascending
67+
if (numberOfMethodsA === numberOfMethodsB) {
68+
return aName.localeCompare(bName);
69+
}
70+
71+
return numberOfMethodsB - numberOfMethodsA;
72+
}
73+
74+
// Then sort by number of usages descending
75+
return numberOfUsagesB - numberOfUsagesA;
76+
}
77+
78+
function compareMethod(a: ExternalApiUsage, b: ExternalApiUsage): number {
79+
// Sort first by supported, putting unmodeled methods first.
80+
if (a.supported && !b.supported) {
81+
return 1;
82+
}
83+
if (!a.supported && b.supported) {
84+
return -1;
85+
}
86+
// Then sort by number of usages descending
87+
return b.usages.length - a.usages.length;
88+
}

extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
1010
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
1111
import { assertNever } from "../../common/helpers-pure";
1212
import { vscode } from "../vscode-api";
13-
import { calculateModeledPercentage } from "./modeled";
13+
import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
1414
import { LinkIconButton } from "../variant-analysis/LinkIconButton";
1515
import { ViewTitle } from "../common";
1616
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";

extensions/ql-vscode/src/view/data-extensions-editor/LibraryRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
55
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
66
import { pluralize } from "../../common/word";
77
import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid";
8-
import { calculateModeledPercentage } from "./modeled";
8+
import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
99
import { decimalFormatter, percentFormatter } from "./formatters";
1010
import { Codicon } from "../common";
1111
import { Mode } from "../../data-extensions-editor/shared/mode";

extensions/ql-vscode/src/view/data-extensions-editor/ModeledMethodDataGrid.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
99
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
1010
import { useMemo } from "react";
1111
import { Mode } from "../../data-extensions-editor/shared/mode";
12+
import { sortMethods } from "../../data-extensions-editor/shared/sorting";
1213

1314
type Props = {
1415
externalApiUsages: ExternalApiUsage[];
@@ -26,21 +27,10 @@ export const ModeledMethodDataGrid = ({
2627
mode,
2728
onChange,
2829
}: Props) => {
29-
const sortedExternalApiUsages = useMemo(() => {
30-
const sortedExternalApiUsages = [...externalApiUsages];
31-
sortedExternalApiUsages.sort((a, b) => {
32-
// Sort first by supported, putting unmodeled methods first.
33-
if (a.supported && !b.supported) {
34-
return 1;
35-
}
36-
if (!a.supported && b.supported) {
37-
return -1;
38-
}
39-
// Then sort by number of usages descending
40-
return b.usages.length - a.usages.length;
41-
});
42-
return sortedExternalApiUsages;
43-
}, [externalApiUsages]);
30+
const sortedExternalApiUsages = useMemo(
31+
() => sortMethods(externalApiUsages),
32+
[externalApiUsages],
33+
);
4434

4535
return (
4636
<VSCodeDataGrid>

extensions/ql-vscode/src/view/data-extensions-editor/ModeledMethodsList.tsx

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import * as React from "react";
22
import { useMemo } from "react";
33
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
44
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
5-
import { calculateModeledPercentage } from "./modeled";
65
import { LibraryRow } from "./LibraryRow";
76
import { Mode } from "../../data-extensions-editor/shared/mode";
7+
import {
8+
groupMethods,
9+
sortGroupNames,
10+
} from "../../data-extensions-editor/shared/sorting";
811

912
type Props = {
1013
externalApiUsages: ExternalApiUsage[];
@@ -22,62 +25,12 @@ export const ModeledMethodsList = ({
2225
mode,
2326
onChange,
2427
}: Props) => {
25-
const grouped = useMemo(() => {
26-
const groupedByLibrary: Record<string, ExternalApiUsage[]> = {};
27-
28-
for (const externalApiUsage of externalApiUsages) {
29-
// Group by package if using framework mode
30-
const key =
31-
mode === Mode.Framework
32-
? externalApiUsage.packageName
33-
: externalApiUsage.library;
34-
35-
groupedByLibrary[key] ??= [];
36-
groupedByLibrary[key].push(externalApiUsage);
37-
}
38-
39-
return groupedByLibrary;
40-
}, [externalApiUsages, mode]);
41-
42-
const sortedGroupNames = useMemo(() => {
43-
return Object.keys(grouped).sort((a, b) => {
44-
const supportedPercentageA = calculateModeledPercentage(grouped[a]);
45-
const supportedPercentageB = calculateModeledPercentage(grouped[b]);
46-
47-
// Sort first by supported percentage ascending
48-
if (supportedPercentageA > supportedPercentageB) {
49-
return 1;
50-
}
51-
if (supportedPercentageA < supportedPercentageB) {
52-
return -1;
53-
}
54-
55-
const numberOfUsagesA = grouped[a].reduce(
56-
(acc, curr) => acc + curr.usages.length,
57-
0,
58-
);
59-
const numberOfUsagesB = grouped[b].reduce(
60-
(acc, curr) => acc + curr.usages.length,
61-
0,
62-
);
63-
64-
// If the number of usages is equal, sort by number of methods descending
65-
if (numberOfUsagesA === numberOfUsagesB) {
66-
const numberOfMethodsA = grouped[a].length;
67-
const numberOfMethodsB = grouped[b].length;
68-
69-
// If the number of methods is equal, sort by library name ascending
70-
if (numberOfMethodsA === numberOfMethodsB) {
71-
return a.localeCompare(b);
72-
}
73-
74-
return numberOfMethodsB - numberOfMethodsA;
75-
}
28+
const grouped = useMemo(
29+
() => groupMethods(externalApiUsages, mode),
30+
[externalApiUsages, mode],
31+
);
7632

77-
// Then sort by number of usages descending
78-
return numberOfUsagesB - numberOfUsagesA;
79-
});
80-
}, [grouped]);
33+
const sortedGroupNames = useMemo(() => sortGroupNames(grouped), [grouped]);
8134

8235
return (
8336
<>

0 commit comments

Comments
 (0)