@lvce-editor/chat-view 6.70.0 → 7.1.0
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/chatViewWorkerMain.js +1041 -236
- package/package.json +1 -1
|
@@ -1214,7 +1214,6 @@ const Home = 12;
|
|
|
1214
1214
|
const UpArrow = 14;
|
|
1215
1215
|
const DownArrow = 16;
|
|
1216
1216
|
const KeyN = 42;
|
|
1217
|
-
const KeyV = 50;
|
|
1218
1217
|
|
|
1219
1218
|
const CtrlCmd = 1 << 11 >>> 0;
|
|
1220
1219
|
const Shift = 1 << 10 >>> 0;
|
|
@@ -1775,6 +1774,17 @@ const clearInput = async state => {
|
|
|
1775
1774
|
};
|
|
1776
1775
|
};
|
|
1777
1776
|
|
|
1777
|
+
const closeGitBranchPicker = state => {
|
|
1778
|
+
if (!state.gitBranchPickerOpen && !state.gitBranchPickerErrorMessage) {
|
|
1779
|
+
return state;
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
...state,
|
|
1783
|
+
gitBranchPickerErrorMessage: '',
|
|
1784
|
+
gitBranchPickerOpen: false
|
|
1785
|
+
};
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1778
1788
|
const clampSelectionIndex = (value, max) => {
|
|
1779
1789
|
if (!Number.isFinite(value)) {
|
|
1780
1790
|
return 0;
|
|
@@ -1852,6 +1862,7 @@ const BackToChatList = 'Back to chat list';
|
|
|
1852
1862
|
const Search$1 = 'Search';
|
|
1853
1863
|
const ScrollDown$1 = 'Scroll down';
|
|
1854
1864
|
const SearchModels = 'Search models';
|
|
1865
|
+
const PickModel = 'Pick Model';
|
|
1855
1866
|
const SearchChats = 'Search chats';
|
|
1856
1867
|
const Paste = 'Paste';
|
|
1857
1868
|
const Rename = 'Rename';
|
|
@@ -1859,9 +1870,13 @@ const Archive = 'Archive';
|
|
|
1859
1870
|
const AddProjectChat = 'Add Project';
|
|
1860
1871
|
const RemoveProject = 'Remove Project';
|
|
1861
1872
|
const Settings$1 = 'Settings';
|
|
1873
|
+
const Login$1 = 'Login';
|
|
1874
|
+
const Logout$1 = 'Logout';
|
|
1862
1875
|
const LoginToBackend = 'Login to backend';
|
|
1863
1876
|
const LogoutFromBackend = 'Logout from backend';
|
|
1864
1877
|
const LoggingInToBackend = 'Logging in to backend';
|
|
1878
|
+
const LoggingOutFromBackend = 'Logging out from backend';
|
|
1879
|
+
const SignedIn = 'Signed in';
|
|
1865
1880
|
const SwitchToChatFocusMode = 'Switch to chat focus mode';
|
|
1866
1881
|
const SwitchToNormalChatMode = 'Switch to normal chat mode';
|
|
1867
1882
|
const CloseChat$1 = 'Close Chat';
|
|
@@ -1941,18 +1956,33 @@ const scrollDown = () => {
|
|
|
1941
1956
|
const searchModels = () => {
|
|
1942
1957
|
return i18nString(SearchModels);
|
|
1943
1958
|
};
|
|
1959
|
+
const pickModel = modelName => {
|
|
1960
|
+
return `${i18nString(PickModel)}, ${modelName}`;
|
|
1961
|
+
};
|
|
1944
1962
|
const searchChats = () => {
|
|
1945
1963
|
return i18nString(SearchChats);
|
|
1946
1964
|
};
|
|
1965
|
+
const login = () => {
|
|
1966
|
+
return i18nString(Login$1);
|
|
1967
|
+
};
|
|
1968
|
+
const logout = () => {
|
|
1969
|
+
return i18nString(Logout$1);
|
|
1970
|
+
};
|
|
1947
1971
|
const loginToBackend = () => {
|
|
1948
1972
|
return i18nString(LoginToBackend);
|
|
1949
1973
|
};
|
|
1950
|
-
const logoutFromBackend = () => {
|
|
1974
|
+
const logoutFromBackend$1 = () => {
|
|
1951
1975
|
return i18nString(LogoutFromBackend);
|
|
1952
1976
|
};
|
|
1953
1977
|
const loggingInToBackend = () => {
|
|
1954
1978
|
return i18nString(LoggingInToBackend);
|
|
1955
1979
|
};
|
|
1980
|
+
const loggingOutFromBackend = () => {
|
|
1981
|
+
return i18nString(LoggingOutFromBackend);
|
|
1982
|
+
};
|
|
1983
|
+
const signedIn = () => {
|
|
1984
|
+
return i18nString(SignedIn);
|
|
1985
|
+
};
|
|
1956
1986
|
const chatFocusMode = () => {
|
|
1957
1987
|
return i18nString(SwitchToChatFocusMode);
|
|
1958
1988
|
};
|
|
@@ -2324,8 +2354,6 @@ const createDefaultState = () => {
|
|
|
2324
2354
|
authAccessToken: '',
|
|
2325
2355
|
authEnabled: false,
|
|
2326
2356
|
authErrorMessage: '',
|
|
2327
|
-
authRefreshToken: '',
|
|
2328
|
-
authStatus: 'signed-out',
|
|
2329
2357
|
backendUrl: '',
|
|
2330
2358
|
chatFocusContentMaxWidth: 700,
|
|
2331
2359
|
chatHistoryEnabled: true,
|
|
@@ -2357,6 +2385,10 @@ const createDefaultState = () => {
|
|
|
2357
2385
|
errorCount: 0,
|
|
2358
2386
|
focus: 'composer',
|
|
2359
2387
|
focused: false,
|
|
2388
|
+
gitBranches: [],
|
|
2389
|
+
gitBranchPickerErrorMessage: '',
|
|
2390
|
+
gitBranchPickerOpen: false,
|
|
2391
|
+
gitBranchPickerVisible: false,
|
|
2360
2392
|
headerHeight: 50,
|
|
2361
2393
|
height: 0,
|
|
2362
2394
|
...responsivePickerState,
|
|
@@ -2443,6 +2475,7 @@ const createDefaultState = () => {
|
|
|
2443
2475
|
useChatToolWorker: true,
|
|
2444
2476
|
useMockApi: false,
|
|
2445
2477
|
userName: '',
|
|
2478
|
+
userState: 'loggedOut',
|
|
2446
2479
|
userSubscriptionPlan: '',
|
|
2447
2480
|
userUsedTokens: 0,
|
|
2448
2481
|
viewMode: 'list',
|
|
@@ -2829,7 +2862,24 @@ const isEqualComposerAttachments = (a, b) => {
|
|
|
2829
2862
|
}
|
|
2830
2863
|
return true;
|
|
2831
2864
|
};
|
|
2865
|
+
const isEqualGitBranches = (a, b) => {
|
|
2866
|
+
if (a === b) {
|
|
2867
|
+
return true;
|
|
2868
|
+
}
|
|
2869
|
+
if (a.length !== b.length) {
|
|
2870
|
+
return false;
|
|
2871
|
+
}
|
|
2872
|
+
for (let i = 0; i < a.length; i++) {
|
|
2873
|
+
if (a[i].current !== b[i].current || a[i].name !== b[i].name) {
|
|
2874
|
+
return false;
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
return true;
|
|
2878
|
+
};
|
|
2832
2879
|
const isEqualProjectExpandedIds = (a, b) => {
|
|
2880
|
+
if (a === b) {
|
|
2881
|
+
return true;
|
|
2882
|
+
}
|
|
2833
2883
|
if (a.length !== b.length) {
|
|
2834
2884
|
return false;
|
|
2835
2885
|
}
|
|
@@ -2840,6 +2890,20 @@ const isEqualProjectExpandedIds = (a, b) => {
|
|
|
2840
2890
|
}
|
|
2841
2891
|
return true;
|
|
2842
2892
|
};
|
|
2893
|
+
const isEqualProjects = (a, b) => {
|
|
2894
|
+
if (a === b) {
|
|
2895
|
+
return true;
|
|
2896
|
+
}
|
|
2897
|
+
if (a.length !== b.length) {
|
|
2898
|
+
return false;
|
|
2899
|
+
}
|
|
2900
|
+
for (let i = 0; i < a.length; i++) {
|
|
2901
|
+
if (a[i].id !== b[i].id || a[i].name !== b[i].name || a[i].uri !== b[i].uri) {
|
|
2902
|
+
return false;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
return true;
|
|
2906
|
+
};
|
|
2843
2907
|
const isEqualVisibleModels = (a, b) => {
|
|
2844
2908
|
if (a === b) {
|
|
2845
2909
|
return true;
|
|
@@ -2856,7 +2920,7 @@ const isEqualVisibleModels = (a, b) => {
|
|
|
2856
2920
|
};
|
|
2857
2921
|
|
|
2858
2922
|
const isEqual = (oldState, newState) => {
|
|
2859
|
-
return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.agentMode === newState.agentMode && oldState.agentModePickerOpen === newState.agentModePickerOpen && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage &&
|
|
2923
|
+
return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.agentMode === newState.agentMode && oldState.agentModePickerOpen === newState.agentModePickerOpen && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && isEqualComposerAttachments(oldState.composerAttachments, newState.composerAttachments) && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.gitBranchPickerErrorMessage === newState.gitBranchPickerErrorMessage && oldState.gitBranchPickerOpen === newState.gitBranchPickerOpen && oldState.gitBranchPickerVisible === newState.gitBranchPickerVisible && isEqualGitBranches(oldState.gitBranches, newState.gitBranches) && oldState.hasSpaceForAgentModePicker === newState.hasSpaceForAgentModePicker && oldState.hasSpaceForRunModePicker === newState.hasSpaceForRunModePicker && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && isEqualVisibleModels(oldState.visibleModels, newState.visibleModels) && oldState.listFocusedIndex === newState.listFocusedIndex && oldState.openApiApiKeyInput === newState.openApiApiKeyInput && oldState.openRouterApiKeyInput === newState.openRouterApiKeyInput && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && isEqualProjects(oldState.projects, newState.projects) && oldState.reasoningEffort === newState.reasoningEffort && oldState.reasoningEffortPickerOpen === newState.reasoningEffortPickerOpen && oldState.reasoningPickerEnabled === newState.reasoningPickerEnabled && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.searchEnabled === newState.searchEnabled && oldState.searchFieldVisible === newState.searchFieldVisible && oldState.searchValue === newState.searchValue && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.runModePickerOpen === newState.runModePickerOpen && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.userName === newState.userName && oldState.userState === newState.userState && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
|
|
2860
2924
|
};
|
|
2861
2925
|
|
|
2862
2926
|
const diffScrollTop = (oldState, newState) => {
|
|
@@ -2877,6 +2941,12 @@ const RenderIncremental = 11;
|
|
|
2877
2941
|
const RenderScrollTop = 12;
|
|
2878
2942
|
|
|
2879
2943
|
const diffValue = (oldState, newState) => {
|
|
2944
|
+
if (oldState.openApiApiKeyInput !== newState.openApiApiKeyInput) {
|
|
2945
|
+
return false;
|
|
2946
|
+
}
|
|
2947
|
+
if (oldState.openRouterApiKeyInput !== newState.openRouterApiKeyInput) {
|
|
2948
|
+
return false;
|
|
2949
|
+
}
|
|
2880
2950
|
return oldState.composerValue === newState.composerValue || newState.inputSource !== 'script';
|
|
2881
2951
|
};
|
|
2882
2952
|
|
|
@@ -2907,10 +2977,9 @@ const getAuthState = state => {
|
|
|
2907
2977
|
authAccessToken,
|
|
2908
2978
|
authEnabled,
|
|
2909
2979
|
authErrorMessage,
|
|
2910
|
-
authRefreshToken,
|
|
2911
|
-
authStatus,
|
|
2912
2980
|
backendUrl,
|
|
2913
2981
|
userName,
|
|
2982
|
+
userState,
|
|
2914
2983
|
userSubscriptionPlan,
|
|
2915
2984
|
userUsedTokens
|
|
2916
2985
|
} = state;
|
|
@@ -2918,10 +2987,9 @@ const getAuthState = state => {
|
|
|
2918
2987
|
authAccessToken,
|
|
2919
2988
|
authEnabled,
|
|
2920
2989
|
authErrorMessage,
|
|
2921
|
-
authRefreshToken,
|
|
2922
|
-
authStatus,
|
|
2923
2990
|
backendUrl,
|
|
2924
2991
|
userName,
|
|
2992
|
+
userState,
|
|
2925
2993
|
userSubscriptionPlan,
|
|
2926
2994
|
userUsedTokens
|
|
2927
2995
|
};
|
|
@@ -3257,10 +3325,6 @@ const getKeyBindings = () => {
|
|
|
3257
3325
|
command: 'Chat.chatInputHistoryDown',
|
|
3258
3326
|
key: DownArrow,
|
|
3259
3327
|
when: FocusChatInput
|
|
3260
|
-
}, {
|
|
3261
|
-
command: 'Chat.pasteInput',
|
|
3262
|
-
key: CtrlCmd | KeyV,
|
|
3263
|
-
when: FocusChatInput
|
|
3264
3328
|
}, {
|
|
3265
3329
|
command: 'Chat.chatInputHistoryUp',
|
|
3266
3330
|
key: UpArrow,
|
|
@@ -3387,9 +3451,11 @@ const ComposerAttachmentPreviewOverlay = 'composer-attachment-preview-overlay';
|
|
|
3387
3451
|
const AddContext = 'add-context';
|
|
3388
3452
|
const Dictate = 'dictate';
|
|
3389
3453
|
const CreatePullRequest$1 = 'create-pull-request';
|
|
3454
|
+
const GitBranchPickerToggle = 'git-branch-picker-toggle';
|
|
3455
|
+
const GitBranchPickerItemPrefix = 'git-branch-picker-item:';
|
|
3390
3456
|
const FocusAddAction = 'focus-add-action';
|
|
3391
|
-
const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
3392
3457
|
const FocusCommit = 'focus-commit';
|
|
3458
|
+
const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
3393
3459
|
const FocusOpenTerminal = 'focus-open-terminal';
|
|
3394
3460
|
const FocusShowDiff = 'focus-show-diff';
|
|
3395
3461
|
const Send = 'send';
|
|
@@ -3458,6 +3524,15 @@ const getRenameIdFromInputName = name => {
|
|
|
3458
3524
|
const getModelPickerItemInputName = modelId => {
|
|
3459
3525
|
return `${ModelPickerItemPrefix}${modelId}`;
|
|
3460
3526
|
};
|
|
3527
|
+
const getGitBranchPickerItemInputName = branchName => {
|
|
3528
|
+
return `${GitBranchPickerItemPrefix}${branchName}`;
|
|
3529
|
+
};
|
|
3530
|
+
const isGitBranchPickerItemInputName = name => {
|
|
3531
|
+
return name.startsWith(GitBranchPickerItemPrefix);
|
|
3532
|
+
};
|
|
3533
|
+
const getGitBranchFromGitBranchPickerItemInputName = name => {
|
|
3534
|
+
return name.slice(GitBranchPickerItemPrefix.length);
|
|
3535
|
+
};
|
|
3461
3536
|
const getComposerAttachmentInputName = attachmentId => {
|
|
3462
3537
|
return `${ComposerAttachmentPrefix}${attachmentId}`;
|
|
3463
3538
|
};
|
|
@@ -3818,6 +3893,236 @@ const openFolder = async () => {
|
|
|
3818
3893
|
}
|
|
3819
3894
|
};
|
|
3820
3895
|
|
|
3896
|
+
// cspell:ignore gitdir worktrees
|
|
3897
|
+
const FileTypeFile = 1;
|
|
3898
|
+
const FileTypeDirectory = 2;
|
|
3899
|
+
const slashAtEndRegex = /\/$/;
|
|
3900
|
+
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3901
|
+
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
3902
|
+
const toGitUri = (baseUri, ...segments) => {
|
|
3903
|
+
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3904
|
+
for (const segment of segments) {
|
|
3905
|
+
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3906
|
+
}
|
|
3907
|
+
return url.toString();
|
|
3908
|
+
};
|
|
3909
|
+
const decodeFileContent = content => {
|
|
3910
|
+
if (typeof content === 'string') {
|
|
3911
|
+
return content;
|
|
3912
|
+
}
|
|
3913
|
+
if (content instanceof Uint8Array) {
|
|
3914
|
+
return new TextDecoder().decode(content);
|
|
3915
|
+
}
|
|
3916
|
+
if (Array.isArray(content)) {
|
|
3917
|
+
return new TextDecoder().decode(new Uint8Array(content));
|
|
3918
|
+
}
|
|
3919
|
+
return '';
|
|
3920
|
+
};
|
|
3921
|
+
const toFileSystemPath = uri => {
|
|
3922
|
+
if (!uri.startsWith('file://')) {
|
|
3923
|
+
return uri;
|
|
3924
|
+
}
|
|
3925
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
3926
|
+
};
|
|
3927
|
+
const getRelativePath = (fromPath, toPath) => {
|
|
3928
|
+
if (!fromPath.startsWith('/') || !toPath.startsWith('/')) {
|
|
3929
|
+
return toPath;
|
|
3930
|
+
}
|
|
3931
|
+
const fromParts = fromPath.split('/').filter(Boolean);
|
|
3932
|
+
const toParts = toPath.split('/').filter(Boolean);
|
|
3933
|
+
let commonPrefixLength = 0;
|
|
3934
|
+
while (commonPrefixLength < fromParts.length && commonPrefixLength < toParts.length && fromParts[commonPrefixLength] === toParts[commonPrefixLength]) {
|
|
3935
|
+
commonPrefixLength++;
|
|
3936
|
+
}
|
|
3937
|
+
const parentSegments = fromParts.slice(commonPrefixLength).map(() => '..');
|
|
3938
|
+
const childSegments = toParts.slice(commonPrefixLength);
|
|
3939
|
+
return [...parentSegments, ...childSegments].join('/') || '.';
|
|
3940
|
+
};
|
|
3941
|
+
const toFileSystemTarget = (workspaceUri, uri) => {
|
|
3942
|
+
const workspacePath = toFileSystemPath(workspaceUri);
|
|
3943
|
+
const fileSystemPath = toFileSystemPath(uri);
|
|
3944
|
+
if (!workspaceUri.startsWith('file://') || !uri.startsWith('file://')) {
|
|
3945
|
+
return fileSystemPath;
|
|
3946
|
+
}
|
|
3947
|
+
return getRelativePath(workspacePath, fileSystemPath);
|
|
3948
|
+
};
|
|
3949
|
+
const parseEntries = value => {
|
|
3950
|
+
if (!Array.isArray(value)) {
|
|
3951
|
+
return [];
|
|
3952
|
+
}
|
|
3953
|
+
return value.map(entry => {
|
|
3954
|
+
if (Array.isArray(entry) && typeof entry[0] === 'string' && typeof entry[1] === 'number') {
|
|
3955
|
+
return {
|
|
3956
|
+
name: entry[0],
|
|
3957
|
+
type: entry[1]
|
|
3958
|
+
};
|
|
3959
|
+
}
|
|
3960
|
+
if (entry && typeof entry === 'object' && typeof Reflect.get(entry, 'name') === 'string' && typeof Reflect.get(entry, 'type') === 'number') {
|
|
3961
|
+
return {
|
|
3962
|
+
name: Reflect.get(entry, 'name'),
|
|
3963
|
+
type: Reflect.get(entry, 'type')
|
|
3964
|
+
};
|
|
3965
|
+
}
|
|
3966
|
+
return undefined;
|
|
3967
|
+
}).filter(entry => !!entry);
|
|
3968
|
+
};
|
|
3969
|
+
const readDir = async (workspaceUri, uri) => {
|
|
3970
|
+
const result = await invoke('FileSystem.readDirWithFileTypes', toFileSystemTarget(workspaceUri, uri));
|
|
3971
|
+
return parseEntries(result);
|
|
3972
|
+
};
|
|
3973
|
+
const readTextFile = async (workspaceUri, uri) => {
|
|
3974
|
+
const result = await invoke('FileSystem.readFile', toFileSystemTarget(workspaceUri, uri));
|
|
3975
|
+
return decodeFileContent(result);
|
|
3976
|
+
};
|
|
3977
|
+
const getGitDirUri = async workspaceUri => {
|
|
3978
|
+
const gitUri = toGitUri(workspaceUri, '.git');
|
|
3979
|
+
try {
|
|
3980
|
+
await readTextFile(workspaceUri, toGitUri(gitUri, 'HEAD'));
|
|
3981
|
+
return gitUri;
|
|
3982
|
+
} catch {
|
|
3983
|
+
// Fall through to support worktrees/submodules where .git is a pointer file.
|
|
3984
|
+
}
|
|
3985
|
+
const gitPointer = await readTextFile(workspaceUri, gitUri);
|
|
3986
|
+
const match = gitDirPointerRegex.exec(gitPointer);
|
|
3987
|
+
if (!match) {
|
|
3988
|
+
return '';
|
|
3989
|
+
}
|
|
3990
|
+
return new URL(match[1].trim(), workspaceUri.endsWith('/') ? workspaceUri : `${workspaceUri}/`).toString();
|
|
3991
|
+
};
|
|
3992
|
+
const collectBranchNames = async (workspaceUri, refsHeadsUri, prefix, branches) => {
|
|
3993
|
+
const entries = await readDir(workspaceUri, refsHeadsUri);
|
|
3994
|
+
for (const entry of entries) {
|
|
3995
|
+
if (entry.type === FileTypeDirectory) {
|
|
3996
|
+
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
3997
|
+
continue;
|
|
3998
|
+
}
|
|
3999
|
+
if (entry.type === FileTypeFile) {
|
|
4000
|
+
branches.add(`${prefix}${entry.name}`);
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
};
|
|
4004
|
+
const parseCurrentBranch = headContent => {
|
|
4005
|
+
const match = headRefRegex.exec(headContent.trim());
|
|
4006
|
+
if (match) {
|
|
4007
|
+
return match[1].trim();
|
|
4008
|
+
}
|
|
4009
|
+
return '';
|
|
4010
|
+
};
|
|
4011
|
+
const hasGitRepository = async workspaceUri => {
|
|
4012
|
+
try {
|
|
4013
|
+
return Boolean(await getGitDirUri(workspaceUri));
|
|
4014
|
+
} catch {
|
|
4015
|
+
return false;
|
|
4016
|
+
}
|
|
4017
|
+
};
|
|
4018
|
+
const getGitBranches = async workspaceUri => {
|
|
4019
|
+
const gitDirUri = await getGitDirUri(workspaceUri);
|
|
4020
|
+
if (!gitDirUri) {
|
|
4021
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4022
|
+
throw new globalThis.Error('Git repository not found.');
|
|
4023
|
+
}
|
|
4024
|
+
const branches = new Set();
|
|
4025
|
+
let currentBranch = '';
|
|
4026
|
+
try {
|
|
4027
|
+
const headContent = await readTextFile(workspaceUri, toGitUri(gitDirUri, 'HEAD'));
|
|
4028
|
+
currentBranch = parseCurrentBranch(headContent);
|
|
4029
|
+
if (currentBranch) {
|
|
4030
|
+
branches.add(currentBranch);
|
|
4031
|
+
}
|
|
4032
|
+
} catch {
|
|
4033
|
+
// Keep trying to discover branches from refs even if HEAD cannot be read.
|
|
4034
|
+
}
|
|
4035
|
+
try {
|
|
4036
|
+
await collectBranchNames(workspaceUri, toGitUri(gitDirUri, 'refs', 'heads'), '', branches);
|
|
4037
|
+
} catch {
|
|
4038
|
+
// Repositories without local refs should still open and surface any current branch we found.
|
|
4039
|
+
}
|
|
4040
|
+
if (branches.size === 0) {
|
|
4041
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4042
|
+
throw new globalThis.Error('No local git branches found.');
|
|
4043
|
+
}
|
|
4044
|
+
return [...branches].toSorted((a, b) => a.localeCompare(b)).map(name => ({
|
|
4045
|
+
current: name === currentBranch,
|
|
4046
|
+
name
|
|
4047
|
+
}));
|
|
4048
|
+
};
|
|
4049
|
+
|
|
4050
|
+
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
4051
|
+
return sessions.find(session => session.id === selectedSessionId);
|
|
4052
|
+
};
|
|
4053
|
+
|
|
4054
|
+
const getProjectUri$1 = (state, projectId) => {
|
|
4055
|
+
return state.projects.find(project => project.id === projectId)?.uri || '';
|
|
4056
|
+
};
|
|
4057
|
+
const getWorkspaceUri$1 = (state, session) => {
|
|
4058
|
+
if (session?.workspaceUri) {
|
|
4059
|
+
return session.workspaceUri;
|
|
4060
|
+
}
|
|
4061
|
+
return getProjectUri$1(state, session?.projectId || state.selectedProjectId);
|
|
4062
|
+
};
|
|
4063
|
+
|
|
4064
|
+
const withHiddenBranchPicker = state => {
|
|
4065
|
+
return {
|
|
4066
|
+
...state,
|
|
4067
|
+
gitBranches: [],
|
|
4068
|
+
gitBranchPickerErrorMessage: '',
|
|
4069
|
+
gitBranchPickerOpen: false,
|
|
4070
|
+
gitBranchPickerVisible: false
|
|
4071
|
+
};
|
|
4072
|
+
};
|
|
4073
|
+
const refreshGitBranchPickerVisibility = async state => {
|
|
4074
|
+
if (state.viewMode !== 'chat-focus') {
|
|
4075
|
+
return {
|
|
4076
|
+
...state,
|
|
4077
|
+
gitBranchPickerErrorMessage: '',
|
|
4078
|
+
gitBranchPickerOpen: false
|
|
4079
|
+
};
|
|
4080
|
+
}
|
|
4081
|
+
const selectedSession = getSelectedSession(state.sessions, state.selectedSessionId);
|
|
4082
|
+
const fallbackBranchName = selectedSession?.branchName || '';
|
|
4083
|
+
const workspaceUri = getWorkspaceUri$1(state, selectedSession);
|
|
4084
|
+
if (!workspaceUri) {
|
|
4085
|
+
return withHiddenBranchPicker(state);
|
|
4086
|
+
}
|
|
4087
|
+
const visible = await hasGitRepository(workspaceUri);
|
|
4088
|
+
if (!visible) {
|
|
4089
|
+
if (fallbackBranchName) {
|
|
4090
|
+
return {
|
|
4091
|
+
...state,
|
|
4092
|
+
gitBranches: [{
|
|
4093
|
+
current: true,
|
|
4094
|
+
name: fallbackBranchName
|
|
4095
|
+
}],
|
|
4096
|
+
gitBranchPickerVisible: true
|
|
4097
|
+
};
|
|
4098
|
+
}
|
|
4099
|
+
return withHiddenBranchPicker(state);
|
|
4100
|
+
}
|
|
4101
|
+
try {
|
|
4102
|
+
const gitBranches = await getGitBranches(workspaceUri);
|
|
4103
|
+
return {
|
|
4104
|
+
...state,
|
|
4105
|
+
gitBranches,
|
|
4106
|
+
gitBranchPickerVisible: true
|
|
4107
|
+
};
|
|
4108
|
+
} catch {
|
|
4109
|
+
if (fallbackBranchName) {
|
|
4110
|
+
return {
|
|
4111
|
+
...state,
|
|
4112
|
+
gitBranches: [{
|
|
4113
|
+
current: true,
|
|
4114
|
+
name: fallbackBranchName
|
|
4115
|
+
}],
|
|
4116
|
+
gitBranchPickerVisible: true
|
|
4117
|
+
};
|
|
4118
|
+
}
|
|
4119
|
+
return {
|
|
4120
|
+
...state,
|
|
4121
|
+
gitBranchPickerVisible: true
|
|
4122
|
+
};
|
|
4123
|
+
}
|
|
4124
|
+
};
|
|
4125
|
+
|
|
3821
4126
|
const selectProject = async (state, projectId) => {
|
|
3822
4127
|
const {
|
|
3823
4128
|
selectedProjectId,
|
|
@@ -3831,14 +4136,14 @@ const selectProject = async (state, projectId) => {
|
|
|
3831
4136
|
}
|
|
3832
4137
|
const visibleSessions = getVisibleSessions(sessions, projectId);
|
|
3833
4138
|
if (visibleSessions.length === 0) {
|
|
3834
|
-
return {
|
|
4139
|
+
return refreshGitBranchPickerVisibility({
|
|
3835
4140
|
...state,
|
|
3836
4141
|
composerAttachments: [],
|
|
3837
4142
|
composerAttachmentsHeight: 0,
|
|
3838
4143
|
selectedProjectId: projectId,
|
|
3839
4144
|
selectedSessionId: '',
|
|
3840
4145
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'list'
|
|
3841
|
-
};
|
|
4146
|
+
});
|
|
3842
4147
|
}
|
|
3843
4148
|
const currentSessionVisible = visibleSessions.some(session => session.id === selectedSessionId);
|
|
3844
4149
|
const nextSelectedSessionId = currentSessionVisible ? selectedSessionId : visibleSessions[0].id;
|
|
@@ -3850,7 +4155,7 @@ const selectProject = async (state, projectId) => {
|
|
|
3850
4155
|
}
|
|
3851
4156
|
return loadedSession;
|
|
3852
4157
|
});
|
|
3853
|
-
return {
|
|
4158
|
+
return refreshGitBranchPickerVisibility({
|
|
3854
4159
|
...state,
|
|
3855
4160
|
composerAttachments,
|
|
3856
4161
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, width),
|
|
@@ -3858,7 +4163,7 @@ const selectProject = async (state, projectId) => {
|
|
|
3858
4163
|
selectedSessionId: nextSelectedSessionId,
|
|
3859
4164
|
sessions: hydratedSessions,
|
|
3860
4165
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
3861
|
-
};
|
|
4166
|
+
});
|
|
3862
4167
|
};
|
|
3863
4168
|
|
|
3864
4169
|
const fileSchemeRegex = /^file:\/\//;
|
|
@@ -3993,6 +4298,148 @@ const handleClickCreatePullRequest = async state => {
|
|
|
3993
4298
|
};
|
|
3994
4299
|
};
|
|
3995
4300
|
|
|
4301
|
+
const trailingSlashesRegex$3 = /\/+$/;
|
|
4302
|
+
const trimTrailingSlashes = value => {
|
|
4303
|
+
return value.replace(trailingSlashesRegex$3, '');
|
|
4304
|
+
};
|
|
4305
|
+
|
|
4306
|
+
const getBackendAuthUrl = (backendUrl, path) => {
|
|
4307
|
+
return `${trimTrailingSlashes(backendUrl)}${path}`;
|
|
4308
|
+
};
|
|
4309
|
+
|
|
4310
|
+
const getBackendLoginUrl = backendUrl => {
|
|
4311
|
+
return getBackendAuthUrl(backendUrl, '/auth/login');
|
|
4312
|
+
};
|
|
4313
|
+
|
|
4314
|
+
const getLoggedOutBackendAuthState = (authErrorMessage = '') => {
|
|
4315
|
+
return {
|
|
4316
|
+
authAccessToken: '',
|
|
4317
|
+
authErrorMessage,
|
|
4318
|
+
userName: '',
|
|
4319
|
+
userState: 'loggedOut',
|
|
4320
|
+
userSubscriptionPlan: '',
|
|
4321
|
+
userUsedTokens: 0
|
|
4322
|
+
};
|
|
4323
|
+
};
|
|
4324
|
+
|
|
4325
|
+
const getBackendLogoutUrl = backendUrl => {
|
|
4326
|
+
return getBackendAuthUrl(backendUrl, '/auth/logout');
|
|
4327
|
+
};
|
|
4328
|
+
|
|
4329
|
+
const logoutFromBackend = async backendUrl => {
|
|
4330
|
+
if (!backendUrl) {
|
|
4331
|
+
return;
|
|
4332
|
+
}
|
|
4333
|
+
try {
|
|
4334
|
+
await fetch(getBackendLogoutUrl(backendUrl), {
|
|
4335
|
+
credentials: 'include',
|
|
4336
|
+
headers: {
|
|
4337
|
+
Accept: 'application/json'
|
|
4338
|
+
},
|
|
4339
|
+
method: 'POST'
|
|
4340
|
+
});
|
|
4341
|
+
} catch {
|
|
4342
|
+
// Ignore logout failures and still clear local auth state.
|
|
4343
|
+
}
|
|
4344
|
+
};
|
|
4345
|
+
|
|
4346
|
+
const getBackendRefreshUrl = backendUrl => {
|
|
4347
|
+
return getBackendAuthUrl(backendUrl, '/auth/refresh');
|
|
4348
|
+
};
|
|
4349
|
+
|
|
4350
|
+
const isObject$2 = value => {
|
|
4351
|
+
return !!value && typeof value === 'object';
|
|
4352
|
+
};
|
|
4353
|
+
|
|
4354
|
+
const isBackendAuthResponse = value => {
|
|
4355
|
+
return isObject$2(value);
|
|
4356
|
+
};
|
|
4357
|
+
|
|
4358
|
+
const getNumber = (value, fallback = 0) => {
|
|
4359
|
+
return typeof value === 'number' ? value : fallback;
|
|
4360
|
+
};
|
|
4361
|
+
|
|
4362
|
+
const getString = (value, fallback = '') => {
|
|
4363
|
+
return typeof value === 'string' ? value : fallback;
|
|
4364
|
+
};
|
|
4365
|
+
|
|
4366
|
+
const toBackendAuthState = value => {
|
|
4367
|
+
return {
|
|
4368
|
+
authAccessToken: getString(value.accessToken),
|
|
4369
|
+
authErrorMessage: getString(value.error),
|
|
4370
|
+
userName: getString(value.userName),
|
|
4371
|
+
userState: value.accessToken ? 'loggedIn' : 'loggedOut',
|
|
4372
|
+
userSubscriptionPlan: getString(value.subscriptionPlan),
|
|
4373
|
+
userUsedTokens: getNumber(value.usedTokens)
|
|
4374
|
+
};
|
|
4375
|
+
};
|
|
4376
|
+
|
|
4377
|
+
const parseBackendAuthResponse = value => {
|
|
4378
|
+
if (!isBackendAuthResponse(value)) {
|
|
4379
|
+
return getLoggedOutBackendAuthState('Backend returned an invalid authentication response.');
|
|
4380
|
+
}
|
|
4381
|
+
return toBackendAuthState(value);
|
|
4382
|
+
};
|
|
4383
|
+
|
|
4384
|
+
const syncBackendAuth = async backendUrl => {
|
|
4385
|
+
if (!backendUrl) {
|
|
4386
|
+
return getLoggedOutBackendAuthState('Backend URL is missing.');
|
|
4387
|
+
}
|
|
4388
|
+
try {
|
|
4389
|
+
const response = await fetch(getBackendRefreshUrl(backendUrl), {
|
|
4390
|
+
credentials: 'include',
|
|
4391
|
+
headers: {
|
|
4392
|
+
Accept: 'application/json'
|
|
4393
|
+
},
|
|
4394
|
+
method: 'POST'
|
|
4395
|
+
});
|
|
4396
|
+
if (response.status === 401 || response.status === 403) {
|
|
4397
|
+
return getLoggedOutBackendAuthState();
|
|
4398
|
+
}
|
|
4399
|
+
let payload = undefined;
|
|
4400
|
+
try {
|
|
4401
|
+
payload = await response.json();
|
|
4402
|
+
} catch {
|
|
4403
|
+
payload = undefined;
|
|
4404
|
+
}
|
|
4405
|
+
if (!response.ok) {
|
|
4406
|
+
const parsed = parseBackendAuthResponse(payload);
|
|
4407
|
+
return getLoggedOutBackendAuthState(parsed.authErrorMessage || 'Backend authentication failed.');
|
|
4408
|
+
}
|
|
4409
|
+
const parsed = parseBackendAuthResponse(payload);
|
|
4410
|
+
if (parsed.authErrorMessage) {
|
|
4411
|
+
return getLoggedOutBackendAuthState(parsed.authErrorMessage);
|
|
4412
|
+
}
|
|
4413
|
+
if (!parsed.authAccessToken) {
|
|
4414
|
+
return getLoggedOutBackendAuthState();
|
|
4415
|
+
}
|
|
4416
|
+
return parsed;
|
|
4417
|
+
} catch (error) {
|
|
4418
|
+
const authErrorMessage = error instanceof Error && error.message ? error.message : 'Backend authentication failed.';
|
|
4419
|
+
return getLoggedOutBackendAuthState(authErrorMessage);
|
|
4420
|
+
}
|
|
4421
|
+
};
|
|
4422
|
+
|
|
4423
|
+
const delay = async ms => {
|
|
4424
|
+
await new Promise(resolve => setTimeout(resolve, ms));
|
|
4425
|
+
};
|
|
4426
|
+
|
|
4427
|
+
const waitForBackendLogin = async (backendUrl, timeoutMs = 30_000, pollIntervalMs = 1000) => {
|
|
4428
|
+
const deadline = Date.now() + timeoutMs;
|
|
4429
|
+
let lastErrorMessage = '';
|
|
4430
|
+
while (Date.now() < deadline) {
|
|
4431
|
+
const authState = await syncBackendAuth(backendUrl);
|
|
4432
|
+
if (authState.userState === 'loggedIn') {
|
|
4433
|
+
return authState;
|
|
4434
|
+
}
|
|
4435
|
+
if (authState.authErrorMessage) {
|
|
4436
|
+
lastErrorMessage = authState.authErrorMessage;
|
|
4437
|
+
}
|
|
4438
|
+
await delay(pollIntervalMs);
|
|
4439
|
+
}
|
|
4440
|
+
return getLoggedOutBackendAuthState(lastErrorMessage);
|
|
4441
|
+
};
|
|
4442
|
+
|
|
3996
4443
|
let nextLoginResponse;
|
|
3997
4444
|
const setNextLoginResponse = response => {
|
|
3998
4445
|
nextLoginResponse = response;
|
|
@@ -4016,35 +4463,36 @@ const consumeNextLoginResponse = async () => {
|
|
|
4016
4463
|
return response.response;
|
|
4017
4464
|
};
|
|
4018
4465
|
|
|
4019
|
-
const get = async key => {
|
|
4020
|
-
return getPreference(key);
|
|
4021
|
-
};
|
|
4022
|
-
const update = async settings => {
|
|
4023
|
-
await invoke('Preferences.update', settings);
|
|
4024
|
-
};
|
|
4025
|
-
|
|
4026
|
-
const trailingSlashesRegex$3 = /\/+$/;
|
|
4027
4466
|
const isLoginResponse = value => {
|
|
4028
4467
|
if (!value || typeof value !== 'object') {
|
|
4029
4468
|
return false;
|
|
4030
4469
|
}
|
|
4031
4470
|
return true;
|
|
4032
4471
|
};
|
|
4033
|
-
const
|
|
4034
|
-
|
|
4472
|
+
const getLoggedInState = (state, response) => {
|
|
4473
|
+
const accessToken = typeof response.accessToken === 'string' ? response.accessToken : '';
|
|
4474
|
+
return {
|
|
4475
|
+
...state,
|
|
4476
|
+
authAccessToken: accessToken,
|
|
4477
|
+
authErrorMessage: '',
|
|
4478
|
+
userName: typeof response.userName === 'string' ? response.userName : state.userName,
|
|
4479
|
+
userState: accessToken ? 'loggedIn' : 'loggedOut',
|
|
4480
|
+
userSubscriptionPlan: typeof response.subscriptionPlan === 'string' ? response.subscriptionPlan : state.userSubscriptionPlan,
|
|
4481
|
+
userUsedTokens: typeof response.usedTokens === 'number' ? response.usedTokens : state.userUsedTokens
|
|
4482
|
+
};
|
|
4035
4483
|
};
|
|
4036
4484
|
const handleClickLogin = async state => {
|
|
4037
4485
|
if (!state.backendUrl) {
|
|
4038
4486
|
return {
|
|
4039
4487
|
...state,
|
|
4040
4488
|
authErrorMessage: 'Backend URL is missing.',
|
|
4041
|
-
|
|
4489
|
+
userState: 'loggedOut'
|
|
4042
4490
|
};
|
|
4043
4491
|
}
|
|
4044
4492
|
const signingInState = {
|
|
4045
4493
|
...state,
|
|
4046
4494
|
authErrorMessage: '',
|
|
4047
|
-
|
|
4495
|
+
userState: 'loggingIn'
|
|
4048
4496
|
};
|
|
4049
4497
|
if (state.uid) {
|
|
4050
4498
|
set(state.uid, state, signingInState);
|
|
@@ -4053,69 +4501,53 @@ const handleClickLogin = async state => {
|
|
|
4053
4501
|
let usedMockResponse = false;
|
|
4054
4502
|
try {
|
|
4055
4503
|
usedMockResponse = hasPendingMockLoginResponse();
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4504
|
+
if (usedMockResponse) {
|
|
4505
|
+
const response = await consumeNextLoginResponse();
|
|
4506
|
+
if (!isLoginResponse(response)) {
|
|
4507
|
+
return {
|
|
4508
|
+
...signingInState,
|
|
4509
|
+
authErrorMessage: 'Backend returned an invalid login response.',
|
|
4510
|
+
userState: 'loggedOut'
|
|
4511
|
+
};
|
|
4512
|
+
}
|
|
4513
|
+
if (typeof response.error === 'string' && response.error) {
|
|
4514
|
+
return {
|
|
4515
|
+
...signingInState,
|
|
4516
|
+
authErrorMessage: response.error,
|
|
4517
|
+
userState: 'loggedOut'
|
|
4518
|
+
};
|
|
4519
|
+
}
|
|
4520
|
+
return getLoggedInState(signingInState, response);
|
|
4070
4521
|
}
|
|
4071
|
-
|
|
4072
|
-
const
|
|
4073
|
-
await update({
|
|
4074
|
-
'secrets.chatBackendAccessToken': accessToken,
|
|
4075
|
-
'secrets.chatBackendRefreshToken': refreshToken
|
|
4076
|
-
});
|
|
4522
|
+
await invoke('Main.openUri', getBackendLoginUrl(state.backendUrl));
|
|
4523
|
+
const authState = await waitForBackendLogin(state.backendUrl);
|
|
4077
4524
|
return {
|
|
4078
4525
|
...signingInState,
|
|
4079
|
-
|
|
4080
|
-
authErrorMessage: '',
|
|
4081
|
-
authRefreshToken: refreshToken,
|
|
4082
|
-
authStatus: accessToken ? 'signed-in' : 'signed-out',
|
|
4083
|
-
userName: typeof response.userName === 'string' ? response.userName : state.userName,
|
|
4084
|
-
userSubscriptionPlan: typeof response.subscriptionPlan === 'string' ? response.subscriptionPlan : state.userSubscriptionPlan,
|
|
4085
|
-
userUsedTokens: typeof response.usedTokens === 'number' ? response.usedTokens : state.userUsedTokens
|
|
4526
|
+
...authState
|
|
4086
4527
|
};
|
|
4087
4528
|
} catch (error) {
|
|
4088
4529
|
const errorMessage = error instanceof Error && error.message ? error.message : 'Backend authentication failed.';
|
|
4089
|
-
if (!usedMockResponse) {
|
|
4090
|
-
await invoke('Main.openUri', `${trimTrailingSlashes(state.backendUrl)}/auth/login`);
|
|
4091
|
-
}
|
|
4092
4530
|
return {
|
|
4093
4531
|
...signingInState,
|
|
4094
|
-
|
|
4095
|
-
authStatus: 'signed-out'
|
|
4532
|
+
...getLoggedOutBackendAuthState(errorMessage)
|
|
4096
4533
|
};
|
|
4097
4534
|
}
|
|
4098
4535
|
};
|
|
4099
4536
|
|
|
4100
4537
|
const handleClickLogout = async state => {
|
|
4101
|
-
|
|
4102
|
-
await invoke('Auth.logout', state.backendUrl);
|
|
4103
|
-
} catch {
|
|
4104
|
-
// Ignore logout bridge errors and still clear local auth state.
|
|
4105
|
-
}
|
|
4106
|
-
await update({
|
|
4107
|
-
'secrets.chatBackendAccessToken': '',
|
|
4108
|
-
'secrets.chatBackendRefreshToken': ''
|
|
4109
|
-
});
|
|
4110
|
-
return {
|
|
4538
|
+
const loggingOutState = {
|
|
4111
4539
|
...state,
|
|
4112
|
-
authAccessToken: '',
|
|
4113
4540
|
authErrorMessage: '',
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4541
|
+
userState: 'loggingOut'
|
|
4542
|
+
};
|
|
4543
|
+
if (state.uid) {
|
|
4544
|
+
set(state.uid, state, loggingOutState);
|
|
4545
|
+
await invoke('Chat.rerender');
|
|
4546
|
+
}
|
|
4547
|
+
await logoutFromBackend(state.backendUrl);
|
|
4548
|
+
return {
|
|
4549
|
+
...loggingOutState,
|
|
4550
|
+
...getLoggedOutBackendAuthState()
|
|
4119
4551
|
};
|
|
4120
4552
|
};
|
|
4121
4553
|
|
|
@@ -4440,10 +4872,6 @@ const getClientRequestIdHeader = () => {
|
|
|
4440
4872
|
};
|
|
4441
4873
|
};
|
|
4442
4874
|
|
|
4443
|
-
const delay = async ms => {
|
|
4444
|
-
await new Promise(resolve => setTimeout(resolve, ms));
|
|
4445
|
-
};
|
|
4446
|
-
|
|
4447
4875
|
const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
4448
4876
|
await delay(delayInMs);
|
|
4449
4877
|
return `Mock AI response: I received "${userMessage}".`;
|
|
@@ -6830,7 +7258,12 @@ const ChatFocusActions = 'ChatFocusActions';
|
|
|
6830
7258
|
const ChatFocusHeader = 'ChatFocusHeader';
|
|
6831
7259
|
const ChatFocusMainArea = 'ChatFocusMainArea';
|
|
6832
7260
|
const ChatFocusProject = 'ChatFocusProject';
|
|
7261
|
+
const ChatGitBranchPicker = 'ChatGitBranchPicker';
|
|
7262
|
+
const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
|
|
7263
|
+
const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
|
|
6833
7264
|
const ChatHeader = 'ChatHeader';
|
|
7265
|
+
const ChatHeaderAuth = 'ChatHeaderAuth';
|
|
7266
|
+
const ChatHeaderAuthName = 'ChatHeaderAuthName';
|
|
6834
7267
|
const ChatHeaderLabel = 'ChatHeaderLabel';
|
|
6835
7268
|
const ChatInputBox = 'ChatInputBox';
|
|
6836
7269
|
const ChatList = 'ChatList';
|
|
@@ -6844,6 +7277,7 @@ const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
|
|
|
6844
7277
|
const ChatListItemStatusRow = 'ChatListItemStatusRow';
|
|
6845
7278
|
const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
|
|
6846
7279
|
const ChatMessageContent = 'ChatMessageContent';
|
|
7280
|
+
const ChatImageMessageContent = 'ChatImageMessageContent';
|
|
6847
7281
|
const ChatMessageLink = 'ChatMessageLink';
|
|
6848
7282
|
const ChatModelPicker = 'ChatModelPicker';
|
|
6849
7283
|
const ChatModelPickerContainer = 'ChatModelPickerContainer';
|
|
@@ -6878,6 +7312,7 @@ const ChatAttachmentLabel = 'ChatAttachmentLabel';
|
|
|
6878
7312
|
const ChatAttachmentPreview = 'ChatAttachmentPreview';
|
|
6879
7313
|
const ChatAttachments = 'ChatAttachments';
|
|
6880
7314
|
const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
|
|
7315
|
+
const ChatMessageImage = 'ChatMessageImage';
|
|
6881
7316
|
const ChatSendArea = 'ChatSendArea';
|
|
6882
7317
|
const ChatSendAreaBottom = 'ChatSendAreaBottom';
|
|
6883
7318
|
const ChatSendAreaContent = 'ChatSendAreaContent';
|
|
@@ -6915,6 +7350,7 @@ const IconButtonDisabled = 'IconButtonDisabled';
|
|
|
6915
7350
|
const ImageElement = 'ImageElement';
|
|
6916
7351
|
const ImageErrorMessage = 'ImageErrorMessage';
|
|
6917
7352
|
const InputBox = 'InputBox';
|
|
7353
|
+
const InputInvalid = 'InputInvalid';
|
|
6918
7354
|
const Insertion = 'Insertion';
|
|
6919
7355
|
const Label = 'Label';
|
|
6920
7356
|
const LabelDetail = 'LabelDetail';
|
|
@@ -6923,7 +7359,6 @@ const MarkdownMathBlock = 'MarkdownMathBlock';
|
|
|
6923
7359
|
const MarkdownQuote = 'MarkdownQuote';
|
|
6924
7360
|
const MarkdownTable = 'MarkdownTable';
|
|
6925
7361
|
const MaskIcon = 'MaskIcon';
|
|
6926
|
-
const MaskIconAccount = 'MaskIconAccount';
|
|
6927
7362
|
const MaskIconAdd = 'MaskIconAdd';
|
|
6928
7363
|
const MaskIconArrowLeft = 'MaskIconArrowLeft';
|
|
6929
7364
|
const MaskIconChevronDown = 'MaskIconChevronDown';
|
|
@@ -6934,7 +7369,6 @@ const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
|
6934
7369
|
const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
|
|
6935
7370
|
const MaskIconSearch = 'MaskIconSearch';
|
|
6936
7371
|
const MaskIconSettingsGear = 'MaskIconSettingsGear';
|
|
6937
|
-
const MaskIconSignOut = 'MaskIconSignOut';
|
|
6938
7372
|
const Message = 'Message';
|
|
6939
7373
|
const MessageAssistant = 'MessageAssistant';
|
|
6940
7374
|
const MessageUser = 'MessageUser';
|
|
@@ -8288,6 +8722,12 @@ const parseAndStoreMessageContent = async (parsedMessages, message) => {
|
|
|
8288
8722
|
const parsedContent = message.text === '' ? emptyMessageContent : await parseMessage(message.text);
|
|
8289
8723
|
return setParsedMessageContent(parsedMessages, message.id, message.text, parsedContent);
|
|
8290
8724
|
};
|
|
8725
|
+
const parseAndStoreMessageContentWithWorkerPreference = async (parsedMessages, message, useChatMessageParsingWorker) => {
|
|
8726
|
+
if (useChatMessageParsingWorker) {
|
|
8727
|
+
return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
|
|
8728
|
+
}
|
|
8729
|
+
return parseAndStoreMessageContent(parsedMessages, message);
|
|
8730
|
+
};
|
|
8291
8731
|
const parseAndStoreMessagesContent = async (parsedMessages, messages) => {
|
|
8292
8732
|
let nextParsedMessages = parsedMessages;
|
|
8293
8733
|
for (const message of messages) {
|
|
@@ -8324,6 +8764,13 @@ const getEmptyMessageContent = () => {
|
|
|
8324
8764
|
return emptyMessageContent;
|
|
8325
8765
|
};
|
|
8326
8766
|
|
|
8767
|
+
const get = async key => {
|
|
8768
|
+
return getPreference(key);
|
|
8769
|
+
};
|
|
8770
|
+
const update = async settings => {
|
|
8771
|
+
await invoke('Preferences.update', settings);
|
|
8772
|
+
};
|
|
8773
|
+
|
|
8327
8774
|
const setOpenApiApiKey = async (state, openApiApiKey, persist = true) => {
|
|
8328
8775
|
if (persist) {
|
|
8329
8776
|
await update({
|
|
@@ -8738,10 +9185,6 @@ const getNextHandleTextChunkState = (latestState, parsedMessages, sessions) => {
|
|
|
8738
9185
|
};
|
|
8739
9186
|
};
|
|
8740
9187
|
|
|
8741
|
-
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
8742
|
-
return sessions.find(session => session.id === selectedSessionId);
|
|
8743
|
-
};
|
|
8744
|
-
|
|
8745
9188
|
const setAndRerenderHandleTextChunkState = async (uid, previousState, nextState) => {
|
|
8746
9189
|
set(uid, previousState, nextState);
|
|
8747
9190
|
// @ts-ignore
|
|
@@ -8828,7 +9271,7 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
|
|
|
8828
9271
|
};
|
|
8829
9272
|
};
|
|
8830
9273
|
|
|
8831
|
-
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
|
|
9274
|
+
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress, useChatMessageParsingWorker) => {
|
|
8832
9275
|
let updatedMessage;
|
|
8833
9276
|
const updatedSessions = sessions.map(session => {
|
|
8834
9277
|
if (session.id !== selectedSessionId) {
|
|
@@ -8851,7 +9294,7 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
|
|
|
8851
9294
|
});
|
|
8852
9295
|
let nextParsedMessages = parsedMessages;
|
|
8853
9296
|
if (updatedMessage) {
|
|
8854
|
-
nextParsedMessages = await
|
|
9297
|
+
nextParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, updatedMessage, useChatMessageParsingWorker);
|
|
8855
9298
|
}
|
|
8856
9299
|
return {
|
|
8857
9300
|
parsedMessages: nextParsedMessages,
|
|
@@ -8874,7 +9317,7 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
|
|
|
8874
9317
|
};
|
|
8875
9318
|
}
|
|
8876
9319
|
const updatedText = assistantMessage.text + chunk;
|
|
8877
|
-
const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true);
|
|
9320
|
+
const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true, handleTextChunkState.latestState.useChatMessageParsingWorker);
|
|
8878
9321
|
const nextState = {
|
|
8879
9322
|
...handleTextChunkState.latestState,
|
|
8880
9323
|
...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
|
|
@@ -9040,6 +9483,11 @@ const withProvisionedBackgroundSession = async (state, session) => {
|
|
|
9040
9483
|
};
|
|
9041
9484
|
};
|
|
9042
9485
|
const handleSubmit = async state => {
|
|
9486
|
+
const authState = state.authEnabled && state.backendUrl ? await syncBackendAuth(state.backendUrl) : undefined;
|
|
9487
|
+
const effectiveState = authState ? {
|
|
9488
|
+
...state,
|
|
9489
|
+
...authState
|
|
9490
|
+
} : state;
|
|
9043
9491
|
const {
|
|
9044
9492
|
agentMode,
|
|
9045
9493
|
aiSessionTitleGenerationEnabled,
|
|
@@ -9068,27 +9516,28 @@ const handleSubmit = async state => {
|
|
|
9068
9516
|
streamingEnabled,
|
|
9069
9517
|
toolEnablement,
|
|
9070
9518
|
useChatCoordinatorWorker,
|
|
9519
|
+
useChatMessageParsingWorker,
|
|
9071
9520
|
useChatNetworkWorkerForRequests,
|
|
9072
9521
|
useChatToolWorker,
|
|
9073
9522
|
useMockApi,
|
|
9074
9523
|
viewMode,
|
|
9075
9524
|
webSearchEnabled
|
|
9076
|
-
} =
|
|
9525
|
+
} = effectiveState;
|
|
9077
9526
|
const userText = composerValue.trim();
|
|
9078
9527
|
if (!userText) {
|
|
9079
|
-
return
|
|
9528
|
+
return effectiveState;
|
|
9080
9529
|
}
|
|
9081
9530
|
const slashCommand = getSlashCommand(userText);
|
|
9082
9531
|
if (slashCommand) {
|
|
9083
|
-
return executeSlashCommand(
|
|
9532
|
+
return executeSlashCommand(effectiveState, slashCommand);
|
|
9084
9533
|
}
|
|
9085
9534
|
const userTime = new Date().toLocaleTimeString([], {
|
|
9086
9535
|
hour: '2-digit',
|
|
9087
9536
|
minute: '2-digit'
|
|
9088
9537
|
});
|
|
9089
9538
|
const userMessageId = crypto.randomUUID();
|
|
9090
|
-
const composerAttachments =
|
|
9091
|
-
await clearComposerAttachments(
|
|
9539
|
+
const composerAttachments = effectiveState.composerAttachments.length > 0 ? effectiveState.composerAttachments : await getComposerAttachments(effectiveState.selectedSessionId);
|
|
9540
|
+
await clearComposerAttachments(effectiveState.selectedSessionId, composerAttachments.map(attachment => attachment.attachmentId));
|
|
9092
9541
|
const userMessage = {
|
|
9093
9542
|
...(composerAttachments.length > 0 ? {
|
|
9094
9543
|
attachments: composerAttachments
|
|
@@ -9112,9 +9561,9 @@ const handleSubmit = async state => {
|
|
|
9112
9561
|
};
|
|
9113
9562
|
let {
|
|
9114
9563
|
parsedMessages
|
|
9115
|
-
} =
|
|
9116
|
-
parsedMessages = await
|
|
9117
|
-
parsedMessages = await
|
|
9564
|
+
} = effectiveState;
|
|
9565
|
+
parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, userMessage, useChatMessageParsingWorker);
|
|
9566
|
+
parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, inProgressAssistantMessage, useChatMessageParsingWorker);
|
|
9118
9567
|
let workingSessions = sessions;
|
|
9119
9568
|
if (viewMode === 'detail') {
|
|
9120
9569
|
const loadedSession = await getChatSession(selectedSessionId);
|
|
@@ -9146,10 +9595,10 @@ const handleSubmit = async state => {
|
|
|
9146
9595
|
const provisionedSession = await withProvisionedBackgroundSession(state, newSession);
|
|
9147
9596
|
await saveChatSession(provisionedSession);
|
|
9148
9597
|
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
9149
|
-
...
|
|
9598
|
+
...effectiveState,
|
|
9150
9599
|
composerAttachments: [],
|
|
9151
9600
|
composerAttachmentsHeight: 0,
|
|
9152
|
-
composerHeight: getMinComposerHeightForState(
|
|
9601
|
+
composerHeight: getMinComposerHeightForState(effectiveState),
|
|
9153
9602
|
composerSelectionEnd: 0,
|
|
9154
9603
|
composerSelectionStart: 0,
|
|
9155
9604
|
composerValue: '',
|
|
@@ -9185,10 +9634,10 @@ const handleSubmit = async state => {
|
|
|
9185
9634
|
await saveChatSession(selectedSession);
|
|
9186
9635
|
}
|
|
9187
9636
|
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
9188
|
-
...
|
|
9637
|
+
...effectiveState,
|
|
9189
9638
|
composerAttachments: [],
|
|
9190
9639
|
composerAttachmentsHeight: 0,
|
|
9191
|
-
composerHeight: getMinComposerHeightForState(
|
|
9640
|
+
composerHeight: getMinComposerHeightForState(effectiveState),
|
|
9192
9641
|
composerSelectionEnd: 0,
|
|
9193
9642
|
composerSelectionStart: 0,
|
|
9194
9643
|
composerValue: '',
|
|
@@ -9200,7 +9649,7 @@ const handleSubmit = async state => {
|
|
|
9200
9649
|
}));
|
|
9201
9650
|
optimisticState = withUpdatedChatInputHistory(optimisticState, userText);
|
|
9202
9651
|
}
|
|
9203
|
-
set(
|
|
9652
|
+
set(effectiveState.uid, effectiveState, optimisticState);
|
|
9204
9653
|
// @ts-ignore
|
|
9205
9654
|
await invoke('Chat.rerender');
|
|
9206
9655
|
let handleTextChunkState = {
|
|
@@ -9289,11 +9738,11 @@ const handleSubmit = async state => {
|
|
|
9289
9738
|
let finalParsedMessages = latestState.parsedMessages;
|
|
9290
9739
|
let updatedSessions;
|
|
9291
9740
|
if (streamingEnabled) {
|
|
9292
|
-
const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false);
|
|
9741
|
+
const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false, latestState.useChatMessageParsingWorker);
|
|
9293
9742
|
updatedSessions = updated.sessions;
|
|
9294
9743
|
finalParsedMessages = updated.parsedMessages;
|
|
9295
9744
|
} else {
|
|
9296
|
-
finalParsedMessages = await
|
|
9745
|
+
finalParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(finalParsedMessages, assistantMessage, latestState.useChatMessageParsingWorker);
|
|
9297
9746
|
updatedSessions = appendMessageToSelectedSession(latestState.sessions, latestState.selectedSessionId, assistantMessage);
|
|
9298
9747
|
}
|
|
9299
9748
|
if (aiSessionTitleGenerationEnabled && createsNewSession) {
|
|
@@ -9322,6 +9771,84 @@ const handleClickSend = async state => {
|
|
|
9322
9771
|
return handleSubmit(state);
|
|
9323
9772
|
};
|
|
9324
9773
|
|
|
9774
|
+
const SwitchGitBranch = 'Chat.switchGitBranch';
|
|
9775
|
+
const switchGitBranch = async ({
|
|
9776
|
+
assetDir,
|
|
9777
|
+
branchName,
|
|
9778
|
+
platform,
|
|
9779
|
+
workspaceUri
|
|
9780
|
+
}) => {
|
|
9781
|
+
await executeProvider({
|
|
9782
|
+
assetDir,
|
|
9783
|
+
event: `onCommand:${SwitchGitBranch}`,
|
|
9784
|
+
method: CommandExecute,
|
|
9785
|
+
noProviderFoundMessage: 'No git branch switch command found',
|
|
9786
|
+
params: [SwitchGitBranch, {
|
|
9787
|
+
branchName,
|
|
9788
|
+
workspaceUri
|
|
9789
|
+
}],
|
|
9790
|
+
platform
|
|
9791
|
+
});
|
|
9792
|
+
};
|
|
9793
|
+
|
|
9794
|
+
const getGitBranchSwitchErrorMessage = (branchName, error) => {
|
|
9795
|
+
if (error instanceof Error && error.message) {
|
|
9796
|
+
return `Failed to switch to branch "${branchName}". ${error.message}`;
|
|
9797
|
+
}
|
|
9798
|
+
return `Failed to switch to branch "${branchName}".`;
|
|
9799
|
+
};
|
|
9800
|
+
const handleGitBranchChange = async (state, branchName) => {
|
|
9801
|
+
if (!branchName) {
|
|
9802
|
+
return state;
|
|
9803
|
+
}
|
|
9804
|
+
const selectedSession = getSelectedSession(state.sessions, state.selectedSessionId);
|
|
9805
|
+
const workspaceUri = getWorkspaceUri$1(state, selectedSession);
|
|
9806
|
+
if (!workspaceUri) {
|
|
9807
|
+
return {
|
|
9808
|
+
...state,
|
|
9809
|
+
gitBranchPickerErrorMessage: 'No workspace is selected.',
|
|
9810
|
+
gitBranchPickerOpen: true
|
|
9811
|
+
};
|
|
9812
|
+
}
|
|
9813
|
+
try {
|
|
9814
|
+
await switchGitBranch({
|
|
9815
|
+
assetDir: state.assetDir,
|
|
9816
|
+
branchName,
|
|
9817
|
+
platform: state.platform,
|
|
9818
|
+
workspaceUri
|
|
9819
|
+
});
|
|
9820
|
+
const updatedSessions = state.sessions.map(session => {
|
|
9821
|
+
if (session.id !== state.selectedSessionId) {
|
|
9822
|
+
return session;
|
|
9823
|
+
}
|
|
9824
|
+
return {
|
|
9825
|
+
...session,
|
|
9826
|
+
branchName
|
|
9827
|
+
};
|
|
9828
|
+
});
|
|
9829
|
+
const updatedSelectedSession = updatedSessions.find(session => session.id === state.selectedSessionId);
|
|
9830
|
+
if (updatedSelectedSession) {
|
|
9831
|
+
await saveChatSession(updatedSelectedSession);
|
|
9832
|
+
}
|
|
9833
|
+
return {
|
|
9834
|
+
...state,
|
|
9835
|
+
gitBranches: state.gitBranches.map(branch => ({
|
|
9836
|
+
...branch,
|
|
9837
|
+
current: branch.name === branchName
|
|
9838
|
+
})),
|
|
9839
|
+
gitBranchPickerErrorMessage: '',
|
|
9840
|
+
gitBranchPickerOpen: false,
|
|
9841
|
+
sessions: updatedSessions
|
|
9842
|
+
};
|
|
9843
|
+
} catch (error) {
|
|
9844
|
+
return {
|
|
9845
|
+
...state,
|
|
9846
|
+
gitBranchPickerErrorMessage: getGitBranchSwitchErrorMessage(branchName, error),
|
|
9847
|
+
gitBranchPickerOpen: true
|
|
9848
|
+
};
|
|
9849
|
+
}
|
|
9850
|
+
};
|
|
9851
|
+
|
|
9325
9852
|
const setReasoningEffort = (state, reasoningEffort) => {
|
|
9326
9853
|
return {
|
|
9327
9854
|
...state,
|
|
@@ -9452,7 +9979,7 @@ const selectSession = async (state, id) => {
|
|
|
9452
9979
|
}
|
|
9453
9980
|
return loadedSession;
|
|
9454
9981
|
});
|
|
9455
|
-
return {
|
|
9982
|
+
return refreshGitBranchPickerVisibility({
|
|
9456
9983
|
...state,
|
|
9457
9984
|
composerAttachments,
|
|
9458
9985
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, width),
|
|
@@ -9461,7 +9988,7 @@ const selectSession = async (state, id) => {
|
|
|
9461
9988
|
selectedSessionId: id,
|
|
9462
9989
|
sessions: hydratedSessions,
|
|
9463
9990
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
9464
|
-
};
|
|
9991
|
+
});
|
|
9465
9992
|
};
|
|
9466
9993
|
|
|
9467
9994
|
const startRename = (state, id) => {
|
|
@@ -9491,15 +10018,17 @@ const toggleChatFocusMode = async state => {
|
|
|
9491
10018
|
if (viewMode === 'chat-focus') {
|
|
9492
10019
|
return {
|
|
9493
10020
|
...state,
|
|
10021
|
+
gitBranchPickerErrorMessage: '',
|
|
10022
|
+
gitBranchPickerOpen: false,
|
|
9494
10023
|
viewMode: lastNormalViewMode
|
|
9495
10024
|
};
|
|
9496
10025
|
}
|
|
9497
10026
|
if (viewMode === 'list' || viewMode === 'detail') {
|
|
9498
|
-
return {
|
|
10027
|
+
return refreshGitBranchPickerVisibility({
|
|
9499
10028
|
...state,
|
|
9500
10029
|
lastNormalViewMode: viewMode,
|
|
9501
10030
|
viewMode: 'chat-focus'
|
|
9502
|
-
};
|
|
10031
|
+
});
|
|
9503
10032
|
}
|
|
9504
10033
|
return state;
|
|
9505
10034
|
};
|
|
@@ -9629,6 +10158,11 @@ const handleClick = async (state, name, id = '', eventX = 0, eventY = 0) => {
|
|
|
9629
10158
|
visibleModels: state.models
|
|
9630
10159
|
};
|
|
9631
10160
|
}
|
|
10161
|
+
case isGitBranchPickerItemInputName(name):
|
|
10162
|
+
{
|
|
10163
|
+
const branchName = getGitBranchFromGitBranchPickerItemInputName(name);
|
|
10164
|
+
return handleGitBranchChange(state, branchName);
|
|
10165
|
+
}
|
|
9632
10166
|
case isAgentModePickerItemInputName(name):
|
|
9633
10167
|
{
|
|
9634
10168
|
const agentMode = getAgentModeFromAgentModePickerItemInputName(name);
|
|
@@ -9753,6 +10287,71 @@ const handleClickFileName = async (state, uri) => {
|
|
|
9753
10287
|
return state;
|
|
9754
10288
|
};
|
|
9755
10289
|
|
|
10290
|
+
const getBranchPickerErrorMessage = error => {
|
|
10291
|
+
if (error instanceof Error && error.message) {
|
|
10292
|
+
return error.message;
|
|
10293
|
+
}
|
|
10294
|
+
return 'Failed to load git branches.';
|
|
10295
|
+
};
|
|
10296
|
+
const openGitBranchPicker = async state => {
|
|
10297
|
+
const visibleState = await refreshGitBranchPickerVisibility(state);
|
|
10298
|
+
const selectedSession = getSelectedSession(visibleState.sessions, visibleState.selectedSessionId);
|
|
10299
|
+
const fallbackBranchName = selectedSession?.branchName || '';
|
|
10300
|
+
if (visibleState.viewMode !== 'chat-focus' || !visibleState.gitBranchPickerVisible && !fallbackBranchName) {
|
|
10301
|
+
return {
|
|
10302
|
+
...visibleState,
|
|
10303
|
+
gitBranchPickerOpen: false
|
|
10304
|
+
};
|
|
10305
|
+
}
|
|
10306
|
+
const workspaceUri = getWorkspaceUri$1(visibleState, selectedSession);
|
|
10307
|
+
if (!workspaceUri) {
|
|
10308
|
+
return {
|
|
10309
|
+
...visibleState,
|
|
10310
|
+
gitBranches: [],
|
|
10311
|
+
gitBranchPickerErrorMessage: 'No workspace is selected.',
|
|
10312
|
+
gitBranchPickerOpen: true
|
|
10313
|
+
};
|
|
10314
|
+
}
|
|
10315
|
+
try {
|
|
10316
|
+
const gitBranches = await getGitBranches(workspaceUri);
|
|
10317
|
+
return {
|
|
10318
|
+
...visibleState,
|
|
10319
|
+
agentModePickerOpen: false,
|
|
10320
|
+
gitBranches,
|
|
10321
|
+
gitBranchPickerErrorMessage: '',
|
|
10322
|
+
gitBranchPickerOpen: true,
|
|
10323
|
+
modelPickerOpen: false,
|
|
10324
|
+
modelPickerSearchValue: '',
|
|
10325
|
+
reasoningEffortPickerOpen: false,
|
|
10326
|
+
runModePickerOpen: false,
|
|
10327
|
+
visibleModels: visibleState.models
|
|
10328
|
+
};
|
|
10329
|
+
} catch (error) {
|
|
10330
|
+
return {
|
|
10331
|
+
...visibleState,
|
|
10332
|
+
agentModePickerOpen: false,
|
|
10333
|
+
gitBranches: fallbackBranchName ? [{
|
|
10334
|
+
current: true,
|
|
10335
|
+
name: fallbackBranchName
|
|
10336
|
+
}] : [],
|
|
10337
|
+
gitBranchPickerErrorMessage: getBranchPickerErrorMessage(error),
|
|
10338
|
+
gitBranchPickerOpen: true,
|
|
10339
|
+
modelPickerOpen: false,
|
|
10340
|
+
modelPickerSearchValue: '',
|
|
10341
|
+
reasoningEffortPickerOpen: false,
|
|
10342
|
+
runModePickerOpen: false,
|
|
10343
|
+
visibleModels: visibleState.models
|
|
10344
|
+
};
|
|
10345
|
+
}
|
|
10346
|
+
};
|
|
10347
|
+
|
|
10348
|
+
const handleClickGitBranchPickerToggle = async state => {
|
|
10349
|
+
if (state.gitBranchPickerOpen) {
|
|
10350
|
+
return closeGitBranchPicker(state);
|
|
10351
|
+
}
|
|
10352
|
+
return openGitBranchPicker(state);
|
|
10353
|
+
};
|
|
10354
|
+
|
|
9756
10355
|
const handleClickModelPickerList = async (state, eventY) => {
|
|
9757
10356
|
const {
|
|
9758
10357
|
height,
|
|
@@ -10615,19 +11214,6 @@ const getSavedSessions = savedState => {
|
|
|
10615
11214
|
return sessions;
|
|
10616
11215
|
};
|
|
10617
11216
|
|
|
10618
|
-
const getSavedSystemPrompt = savedState => {
|
|
10619
|
-
if (!isObject$1(savedState)) {
|
|
10620
|
-
return undefined;
|
|
10621
|
-
}
|
|
10622
|
-
const {
|
|
10623
|
-
systemPrompt
|
|
10624
|
-
} = savedState;
|
|
10625
|
-
if (typeof systemPrompt !== 'string') {
|
|
10626
|
-
return undefined;
|
|
10627
|
-
}
|
|
10628
|
-
return systemPrompt;
|
|
10629
|
-
};
|
|
10630
|
-
|
|
10631
11217
|
const getSavedViewMode = savedState => {
|
|
10632
11218
|
if (!isObject$1(savedState)) {
|
|
10633
11219
|
return undefined;
|
|
@@ -10659,24 +11245,6 @@ const loadAuthEnabled = async () => {
|
|
|
10659
11245
|
}
|
|
10660
11246
|
};
|
|
10661
11247
|
|
|
10662
|
-
const loadBackendAccessToken = async () => {
|
|
10663
|
-
try {
|
|
10664
|
-
const savedAccessToken = await get('secrets.chatBackendAccessToken');
|
|
10665
|
-
return typeof savedAccessToken === 'string' ? savedAccessToken : '';
|
|
10666
|
-
} catch {
|
|
10667
|
-
return '';
|
|
10668
|
-
}
|
|
10669
|
-
};
|
|
10670
|
-
|
|
10671
|
-
const loadBackendRefreshToken = async () => {
|
|
10672
|
-
try {
|
|
10673
|
-
const savedRefreshToken = await get('secrets.chatBackendRefreshToken');
|
|
10674
|
-
return typeof savedRefreshToken === 'string' ? savedRefreshToken : '';
|
|
10675
|
-
} catch {
|
|
10676
|
-
return '';
|
|
10677
|
-
}
|
|
10678
|
-
};
|
|
10679
|
-
|
|
10680
11248
|
const loadBackendUrl = async () => {
|
|
10681
11249
|
try {
|
|
10682
11250
|
const savedBackendUrl = await get('chat.backendUrl');
|
|
@@ -10857,12 +11425,10 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
10857
11425
|
};
|
|
10858
11426
|
|
|
10859
11427
|
const loadPreferences = async () => {
|
|
10860
|
-
const [aiSessionTitleGenerationEnabled,
|
|
11428
|
+
const [aiSessionTitleGenerationEnabled, authEnabled, backendUrl, chatHistoryEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, reasoningPickerEnabled, scrollDownButtonEnabled, searchEnabled, streamingEnabled, todoListToolEnabled, toolEnablement, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatMessageParsingWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadAuthEnabled(), loadBackendUrl(), loadChatHistoryEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadReasoningPickerEnabled(), loadScrollDownButtonEnabled(), loadSearchEnabled(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadToolEnablement(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatMessageParsingWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
10861
11429
|
return {
|
|
10862
11430
|
aiSessionTitleGenerationEnabled,
|
|
10863
|
-
authAccessToken,
|
|
10864
11431
|
authEnabled,
|
|
10865
|
-
authRefreshToken,
|
|
10866
11432
|
backendUrl,
|
|
10867
11433
|
chatHistoryEnabled,
|
|
10868
11434
|
composerDropEnabled,
|
|
@@ -10934,9 +11500,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10934
11500
|
const [composerSelectionStart, composerSelectionEnd] = savedComposerSelection ?? [state.composerSelectionStart, state.composerSelectionEnd];
|
|
10935
11501
|
const {
|
|
10936
11502
|
aiSessionTitleGenerationEnabled,
|
|
10937
|
-
authAccessToken,
|
|
10938
11503
|
authEnabled,
|
|
10939
|
-
authRefreshToken,
|
|
10940
11504
|
backendUrl,
|
|
10941
11505
|
chatHistoryEnabled,
|
|
10942
11506
|
composerDropEnabled,
|
|
@@ -10952,11 +11516,13 @@ const loadContent = async (state, savedState) => {
|
|
|
10952
11516
|
toolEnablement,
|
|
10953
11517
|
useChatCoordinatorWorker,
|
|
10954
11518
|
useChatMathWorker,
|
|
10955
|
-
useChatMessageParsingWorker,
|
|
11519
|
+
// useChatMessageParsingWorker,
|
|
10956
11520
|
useChatNetworkWorkerForRequests,
|
|
10957
11521
|
useChatToolWorker,
|
|
10958
11522
|
voiceDictationEnabled
|
|
10959
11523
|
} = await loadPreferences();
|
|
11524
|
+
const useChatMessageParsingWorker = true;
|
|
11525
|
+
const authState = authEnabled && backendUrl ? await syncBackendAuth(backendUrl) : getLoggedOutBackendAuthState();
|
|
10960
11526
|
const legacySavedSessions = getSavedSessions(savedState);
|
|
10961
11527
|
const storedSessions = await listChatSessions();
|
|
10962
11528
|
let sessions = storedSessions;
|
|
@@ -10992,7 +11558,6 @@ const loadContent = async (state, savedState) => {
|
|
|
10992
11558
|
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
10993
11559
|
const reasoningEffort = getSavedReasoningEffort(savedState) ?? state.reasoningEffort;
|
|
10994
11560
|
const selectedModelId = state.models.some(model => model.id === preferredModelId) ? preferredModelId : state.models[0]?.id || '';
|
|
10995
|
-
const systemPrompt = getSavedSystemPrompt(savedState) ?? state.systemPrompt;
|
|
10996
11561
|
const visibleModels = getVisibleModels(state.models, '');
|
|
10997
11562
|
const visibleSessions = getVisibleSessions(sessions, selectedProjectId);
|
|
10998
11563
|
const selectedSessionId = visibleSessions.some(session => session.id === preferredSessionId) ? preferredSessionId : visibleSessions[0]?.id || '';
|
|
@@ -11008,15 +11573,14 @@ const loadContent = async (state, savedState) => {
|
|
|
11008
11573
|
const savedLastNormalViewMode = getSavedLastNormalViewMode(savedState);
|
|
11009
11574
|
const lastNormalViewMode = savedLastNormalViewMode || (preferredViewMode === 'detail' ? 'detail' : state.lastNormalViewMode);
|
|
11010
11575
|
const viewMode = sessions.length === 0 || !selectedSessionId ? 'list' : preferredViewMode;
|
|
11011
|
-
|
|
11576
|
+
const nextState = {
|
|
11012
11577
|
...state,
|
|
11013
11578
|
agentMode,
|
|
11014
11579
|
agentModePickerOpen: false,
|
|
11015
11580
|
aiSessionTitleGenerationEnabled,
|
|
11016
|
-
authAccessToken,
|
|
11581
|
+
authAccessToken: authState.authAccessToken,
|
|
11017
11582
|
authEnabled,
|
|
11018
|
-
|
|
11019
|
-
authStatus: authAccessToken ? 'signed-in' : 'signed-out',
|
|
11583
|
+
authErrorMessage: authState.authErrorMessage,
|
|
11020
11584
|
backendUrl,
|
|
11021
11585
|
chatHistoryEnabled,
|
|
11022
11586
|
chatListScrollTop,
|
|
@@ -11057,7 +11621,6 @@ const loadContent = async (state, savedState) => {
|
|
|
11057
11621
|
selectedSessionId,
|
|
11058
11622
|
sessions,
|
|
11059
11623
|
streamingEnabled,
|
|
11060
|
-
systemPrompt,
|
|
11061
11624
|
todoListToolEnabled,
|
|
11062
11625
|
toolEnablement,
|
|
11063
11626
|
useChatCoordinatorWorker,
|
|
@@ -11065,10 +11628,15 @@ const loadContent = async (state, savedState) => {
|
|
|
11065
11628
|
useChatMessageParsingWorker,
|
|
11066
11629
|
useChatNetworkWorkerForRequests,
|
|
11067
11630
|
useChatToolWorker,
|
|
11631
|
+
userName: authState.userName,
|
|
11632
|
+
userState: authState.userState,
|
|
11633
|
+
userSubscriptionPlan: authState.userSubscriptionPlan,
|
|
11634
|
+
userUsedTokens: authState.userUsedTokens,
|
|
11068
11635
|
viewMode,
|
|
11069
11636
|
visibleModels,
|
|
11070
11637
|
voiceDictationEnabled
|
|
11071
11638
|
};
|
|
11639
|
+
return refreshGitBranchPickerVisibility(nextState);
|
|
11072
11640
|
};
|
|
11073
11641
|
|
|
11074
11642
|
const isObject = value => {
|
|
@@ -11158,7 +11726,24 @@ const openMockProject = async (state, projectId, projectName, projectUri) => {
|
|
|
11158
11726
|
};
|
|
11159
11727
|
};
|
|
11160
11728
|
|
|
11161
|
-
const
|
|
11729
|
+
const applySessionOptions = (session, options) => {
|
|
11730
|
+
if (!options) {
|
|
11731
|
+
return session;
|
|
11732
|
+
}
|
|
11733
|
+
return {
|
|
11734
|
+
...session,
|
|
11735
|
+
...(options.branchName ? {
|
|
11736
|
+
branchName: options.branchName
|
|
11737
|
+
} : {}),
|
|
11738
|
+
...(options.projectId ? {
|
|
11739
|
+
projectId: options.projectId
|
|
11740
|
+
} : {}),
|
|
11741
|
+
...(options.workspaceUri ? {
|
|
11742
|
+
workspaceUri: options.workspaceUri
|
|
11743
|
+
} : {})
|
|
11744
|
+
};
|
|
11745
|
+
};
|
|
11746
|
+
const openMockSession = async (state, mockSessionId, mockChatMessages, options) => {
|
|
11162
11747
|
const {
|
|
11163
11748
|
sessions: currentSessions
|
|
11164
11749
|
} = state;
|
|
@@ -11171,20 +11756,20 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
|
|
|
11171
11756
|
if (session.id !== mockSessionId) {
|
|
11172
11757
|
return session;
|
|
11173
11758
|
}
|
|
11174
|
-
return {
|
|
11759
|
+
return applySessionOptions({
|
|
11175
11760
|
...session,
|
|
11176
11761
|
messages: mockChatMessages
|
|
11177
|
-
};
|
|
11178
|
-
}) : [...currentSessions, {
|
|
11762
|
+
}, options);
|
|
11763
|
+
}) : [...currentSessions, applySessionOptions({
|
|
11179
11764
|
id: mockSessionId,
|
|
11180
11765
|
messages: mockChatMessages,
|
|
11181
11766
|
title: mockSessionId
|
|
11182
|
-
}];
|
|
11767
|
+
}, options)];
|
|
11183
11768
|
const selectedSession = sessions.find(session => session.id === mockSessionId);
|
|
11184
11769
|
if (selectedSession) {
|
|
11185
11770
|
await saveChatSession(selectedSession);
|
|
11186
11771
|
}
|
|
11187
|
-
return {
|
|
11772
|
+
return refreshGitBranchPickerVisibility({
|
|
11188
11773
|
...state,
|
|
11189
11774
|
composerAttachments: [],
|
|
11190
11775
|
composerAttachmentsHeight: 0,
|
|
@@ -11193,7 +11778,7 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
|
|
|
11193
11778
|
selectedSessionId: mockSessionId,
|
|
11194
11779
|
sessions,
|
|
11195
11780
|
viewMode: 'detail'
|
|
11196
|
-
};
|
|
11781
|
+
});
|
|
11197
11782
|
};
|
|
11198
11783
|
|
|
11199
11784
|
const pasteInput = async state => {
|
|
@@ -11306,6 +11891,10 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11306
11891
|
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
11307
11892
|
}
|
|
11308
11893
|
|
|
11894
|
+
.InputInvalid{
|
|
11895
|
+
border-color: var(--InputValidationErrorBorder, red);
|
|
11896
|
+
}
|
|
11897
|
+
|
|
11309
11898
|
.ChatComposerAttachmentTextFile{
|
|
11310
11899
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
11311
11900
|
}
|
|
@@ -11360,6 +11949,23 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11360
11949
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
11361
11950
|
}
|
|
11362
11951
|
|
|
11952
|
+
.ChatImageMessageContent{
|
|
11953
|
+
padding: 6px;
|
|
11954
|
+
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
11955
|
+
border-radius: 12px;
|
|
11956
|
+
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
11957
|
+
overflow: hidden;
|
|
11958
|
+
}
|
|
11959
|
+
|
|
11960
|
+
.ChatMessageImage{
|
|
11961
|
+
display: block;
|
|
11962
|
+
max-width: min(320px, 100%);
|
|
11963
|
+
max-height: min(320px, calc(100vh - 220px));
|
|
11964
|
+
border-radius: 8px;
|
|
11965
|
+
object-fit: contain;
|
|
11966
|
+
background: color-mix(in srgb, var(--vscode-editor-background) 88%, black);
|
|
11967
|
+
}
|
|
11968
|
+
|
|
11363
11969
|
.Chat{
|
|
11364
11970
|
position: relative;
|
|
11365
11971
|
}
|
|
@@ -11403,6 +12009,14 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11403
12009
|
|
|
11404
12010
|
}
|
|
11405
12011
|
|
|
12012
|
+
.ChatGitBranchPickerMessage{
|
|
12013
|
+
padding: 6px 8px;
|
|
12014
|
+
}
|
|
12015
|
+
|
|
12016
|
+
.ChatGitBranchPickerErrorMessage{
|
|
12017
|
+
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
12018
|
+
}
|
|
12019
|
+
|
|
11406
12020
|
.RunModePickerContainer{
|
|
11407
12021
|
display: flex;
|
|
11408
12022
|
justify-content: flex-end;
|
|
@@ -11507,13 +12121,10 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11507
12121
|
.ChatFocus .ChatMessages > .Message > .ChatMessageContent{
|
|
11508
12122
|
max-inline-size: 100%;
|
|
11509
12123
|
}
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
12124
|
.Viewlet.Chat.ChatFocus{
|
|
11513
12125
|
display: flex !important;
|
|
11514
12126
|
min-width: 0;
|
|
11515
12127
|
}
|
|
11516
|
-
|
|
11517
12128
|
.ChatFocusMainArea{
|
|
11518
12129
|
display: flex;
|
|
11519
12130
|
flex: 1;
|
|
@@ -11525,7 +12136,6 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11525
12136
|
flex: 1;
|
|
11526
12137
|
min-height: 0;
|
|
11527
12138
|
}
|
|
11528
|
-
|
|
11529
12139
|
`;
|
|
11530
12140
|
return `${baseCss}
|
|
11531
12141
|
|
|
@@ -11670,7 +12280,8 @@ const HandlePointerUpModelPickerList = 55;
|
|
|
11670
12280
|
const HandleClickReasoningEffortPickerToggle = 56;
|
|
11671
12281
|
const HandleClickAgentModePickerToggle = 57;
|
|
11672
12282
|
const HandleContextMenuChatImageAttachment = 58;
|
|
11673
|
-
const
|
|
12283
|
+
const HandleClickGitBranchPickerToggle = 59;
|
|
12284
|
+
const HandleErrorComposerAttachmentPreviewOverlay = 60;
|
|
11674
12285
|
|
|
11675
12286
|
const getAddContextButtonDom = () => {
|
|
11676
12287
|
return [{
|
|
@@ -11685,10 +12296,12 @@ const getAddContextButtonDom = () => {
|
|
|
11685
12296
|
}];
|
|
11686
12297
|
};
|
|
11687
12298
|
|
|
11688
|
-
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label) => {
|
|
12299
|
+
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
|
|
11689
12300
|
return [{
|
|
11690
12301
|
'aria-expanded': open ? 'true' : 'false',
|
|
11691
12302
|
'aria-haspopup': 'true',
|
|
12303
|
+
'aria-label': ariaLabel,
|
|
12304
|
+
ariaLabel,
|
|
11692
12305
|
childCount: 2,
|
|
11693
12306
|
className: Select,
|
|
11694
12307
|
inputType: 'button',
|
|
@@ -11711,12 +12324,12 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
|
|
|
11711
12324
|
}];
|
|
11712
12325
|
};
|
|
11713
12326
|
|
|
11714
|
-
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, containerChildCount = 1) => {
|
|
12327
|
+
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, containerChildCount = 1) => {
|
|
11715
12328
|
return [{
|
|
11716
12329
|
childCount: containerChildCount,
|
|
11717
12330
|
className: CustomSelectContainer,
|
|
11718
12331
|
type: Div
|
|
11719
|
-
}, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title)];
|
|
12332
|
+
}, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel)];
|
|
11720
12333
|
};
|
|
11721
12334
|
|
|
11722
12335
|
const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) => {
|
|
@@ -11726,7 +12339,8 @@ const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) =>
|
|
|
11726
12339
|
const getChatModelPickerToggleVirtualDom = (models, selectedModelId, modelPickerOpen) => {
|
|
11727
12340
|
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
11728
12341
|
const selectedModelLabel = selectedModel ? selectedModel.name : selectedModelId;
|
|
11729
|
-
|
|
12342
|
+
const pickModelLabel = pickModel(selectedModelLabel);
|
|
12343
|
+
return getCustomSelectPickerToggleVirtualDom(selectedModelLabel, ModelPickerToggle, modelPickerOpen, HandleClickModelPickerToggle, pickModelLabel, pickModelLabel);
|
|
11730
12344
|
};
|
|
11731
12345
|
|
|
11732
12346
|
const getCreatePullRequestButtonDom = () => {
|
|
@@ -11770,6 +12384,55 @@ const getCustomSelectOptionVirtualDom = (name, label, selected, detail = '') =>
|
|
|
11770
12384
|
}, text(detail)] : [])];
|
|
11771
12385
|
};
|
|
11772
12386
|
|
|
12387
|
+
const itemHeight = 28;
|
|
12388
|
+
const messageHeight = 32;
|
|
12389
|
+
const getCurrentBranchLabel = (gitBranches, fallbackBranchName) => {
|
|
12390
|
+
const currentBranch = gitBranches.find(branch => branch.current);
|
|
12391
|
+
if (currentBranch) {
|
|
12392
|
+
return currentBranch.name;
|
|
12393
|
+
}
|
|
12394
|
+
if (fallbackBranchName) {
|
|
12395
|
+
return fallbackBranchName;
|
|
12396
|
+
}
|
|
12397
|
+
return 'Branch';
|
|
12398
|
+
};
|
|
12399
|
+
const getBranchOptionsVirtualDom = gitBranches => {
|
|
12400
|
+
return gitBranches.flatMap(branch => {
|
|
12401
|
+
return getCustomSelectOptionVirtualDom(getGitBranchPickerItemInputName(branch.name), branch.name, branch.current, branch.current ? 'current' : '');
|
|
12402
|
+
});
|
|
12403
|
+
};
|
|
12404
|
+
const getBranchPickerMessageDom = (gitBranches, errorMessage) => {
|
|
12405
|
+
const message = errorMessage || (gitBranches.length === 0 ? 'No local git branches found.' : '');
|
|
12406
|
+
if (!message) {
|
|
12407
|
+
return [];
|
|
12408
|
+
}
|
|
12409
|
+
return [{
|
|
12410
|
+
childCount: 1,
|
|
12411
|
+
className: mergeClassNames(ChatGitBranchPickerMessage, errorMessage ? ChatGitBranchPickerErrorMessage : Empty),
|
|
12412
|
+
type: Div
|
|
12413
|
+
}, {
|
|
12414
|
+
text: message,
|
|
12415
|
+
type: Text
|
|
12416
|
+
}];
|
|
12417
|
+
};
|
|
12418
|
+
const getGitBranchPickerVirtualDom = (gitBranches, gitBranchPickerOpen, gitBranchPickerErrorMessage, fallbackBranchName) => {
|
|
12419
|
+
const label = getCurrentBranchLabel(gitBranches, fallbackBranchName);
|
|
12420
|
+
const branchOptions = getBranchOptionsVirtualDom(gitBranches);
|
|
12421
|
+
const messageDom = getBranchPickerMessageDom(gitBranches, gitBranchPickerErrorMessage);
|
|
12422
|
+
const showMessage = messageDom.length > 0;
|
|
12423
|
+
const popOverHeight = gitBranches.length * itemHeight + (showMessage ? messageHeight : 0);
|
|
12424
|
+
return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch', gitBranchPickerOpen ? 2 : 1), ...(gitBranchPickerOpen ? [{
|
|
12425
|
+
childCount: (showMessage ? 1 : 0) + 1,
|
|
12426
|
+
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver, ChatGitBranchPicker),
|
|
12427
|
+
style: `height: ${popOverHeight}px;`,
|
|
12428
|
+
type: Div
|
|
12429
|
+
}, ...messageDom, {
|
|
12430
|
+
childCount: branchOptions.length / 4,
|
|
12431
|
+
className: ChatModelPickerList,
|
|
12432
|
+
type: Ul
|
|
12433
|
+
}, ...branchOptions] : [])];
|
|
12434
|
+
};
|
|
12435
|
+
|
|
11773
12436
|
const reasoningEffortPickerHeight = reasoningEfforts.length * 28;
|
|
11774
12437
|
const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
|
|
11775
12438
|
return reasoningEfforts.flatMap(reasoningEffort => {
|
|
@@ -11779,7 +12442,7 @@ const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
|
|
|
11779
12442
|
});
|
|
11780
12443
|
};
|
|
11781
12444
|
const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEffortPickerOpen) => {
|
|
11782
|
-
return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
|
|
12445
|
+
return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
|
|
11783
12446
|
childCount: 1,
|
|
11784
12447
|
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver),
|
|
11785
12448
|
style: `height: ${reasoningEffortPickerHeight}px;`,
|
|
@@ -11946,6 +12609,7 @@ const getComposerAttachmentClassName = displayType => {
|
|
|
11946
12609
|
};
|
|
11947
12610
|
const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
11948
12611
|
return [{
|
|
12612
|
+
'aria-label': removeAttachment(),
|
|
11949
12613
|
buttonType: 'button',
|
|
11950
12614
|
childCount: 1,
|
|
11951
12615
|
className: ChatComposerAttachmentRemoveButton,
|
|
@@ -12017,12 +12681,13 @@ const getComposerTextAreaDom = () => {
|
|
|
12017
12681
|
type: TextArea
|
|
12018
12682
|
};
|
|
12019
12683
|
};
|
|
12020
|
-
const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton = false, voiceDictationEnabled = false, scrollDownButtonEnabled = false, messagesAutoScrollEnabled = true) => {
|
|
12684
|
+
const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agentModePickerOpen, gitBranchPickerVisible, gitBranchPickerOpen, gitBranchPickerErrorMessage, gitBranches, fallbackBranchName, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton = false, voiceDictationEnabled = false, scrollDownButtonEnabled = false, messagesAutoScrollEnabled = true) => {
|
|
12021
12685
|
const isSendDisabled = composerValue.trim() === '';
|
|
12022
12686
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
12687
|
+
const showGitBranchPicker = gitBranchPickerVisible || Boolean(fallbackBranchName);
|
|
12023
12688
|
const showResponsiveRunModePicker = showRunMode && hasSpaceForRunModePicker;
|
|
12024
12689
|
const showScrollDownButton = scrollDownButtonEnabled && !messagesAutoScrollEnabled;
|
|
12025
|
-
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
12690
|
+
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (showGitBranchPicker ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
12026
12691
|
const primaryControlsCount = 1 + (showAgentModePicker ? 1 : 0) + (reasoningPickerEnabled ? 1 : 0) + (showResponsiveRunModePicker ? 1 : 0);
|
|
12027
12692
|
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
12028
12693
|
const hasComposerAttachments = composerAttachments.length > 0;
|
|
@@ -12046,7 +12711,62 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
|
|
|
12046
12711
|
className: ChatSendAreaPrimaryControls,
|
|
12047
12712
|
role: 'toolbar',
|
|
12048
12713
|
type: Div
|
|
12049
|
-
}, ...(showAgentModePicker ? getAgentModePickerVirtualDom(agentMode, agentModePickerOpen) : []), ...getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen), ...(reasoningPickerEnabled ? getReasoningEffortPickerVirtualDom(reasoningEffort, reasoningEffortPickerOpen) : []), ...(showResponsiveRunModePicker ? getRunModePickerVirtualDom(runMode, runModePickerOpen) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showCreatePullRequestButton ? getCreatePullRequestButtonDom() : []), ...(showScrollDownButton ? getScrollDownButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
12714
|
+
}, ...(showAgentModePicker ? getAgentModePickerVirtualDom(agentMode, agentModePickerOpen) : []), ...getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen), ...(reasoningPickerEnabled ? getReasoningEffortPickerVirtualDom(reasoningEffort, reasoningEffortPickerOpen) : []), ...(showResponsiveRunModePicker ? getRunModePickerVirtualDom(runMode, runModePickerOpen) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showCreatePullRequestButton ? getCreatePullRequestButtonDom() : []), ...(showGitBranchPicker ? getGitBranchPickerVirtualDom(gitBranches, gitBranchPickerOpen, gitBranchPickerErrorMessage, fallbackBranchName) : []), ...(showScrollDownButton ? getScrollDownButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
12715
|
+
};
|
|
12716
|
+
|
|
12717
|
+
const authContainerStyle = 'align-items:center;display:flex;gap:8px;min-width:0;';
|
|
12718
|
+
const authNameStyle = 'max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
12719
|
+
const authButtonStyle = 'white-space:nowrap;';
|
|
12720
|
+
const getButtonLabel = (userState, isAuthenticated) => {
|
|
12721
|
+
if (userState === 'loggingIn') {
|
|
12722
|
+
return loggingInToBackend();
|
|
12723
|
+
}
|
|
12724
|
+
if (userState === 'loggingOut') {
|
|
12725
|
+
return loggingOutFromBackend();
|
|
12726
|
+
}
|
|
12727
|
+
return isAuthenticated ? logout() : login();
|
|
12728
|
+
};
|
|
12729
|
+
const getButtonTitle = (userState, isAuthenticated) => {
|
|
12730
|
+
if (userState === 'loggingIn') {
|
|
12731
|
+
return loggingInToBackend();
|
|
12732
|
+
}
|
|
12733
|
+
if (userState === 'loggingOut') {
|
|
12734
|
+
return loggingOutFromBackend();
|
|
12735
|
+
}
|
|
12736
|
+
return isAuthenticated ? logoutFromBackend$1() : loginToBackend();
|
|
12737
|
+
};
|
|
12738
|
+
const getChatHeaderAuthDom = (authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
12739
|
+
if (!authEnabled) {
|
|
12740
|
+
return [];
|
|
12741
|
+
}
|
|
12742
|
+
const isAuthenticated = userState === 'loggedIn' || userState === 'loggingOut';
|
|
12743
|
+
const buttonName = isAuthenticated ? Logout : Login;
|
|
12744
|
+
const buttonLabel = getButtonLabel(userState, isAuthenticated);
|
|
12745
|
+
const buttonTitle = getButtonTitle(userState, isAuthenticated);
|
|
12746
|
+
const isPending = userState === 'loggingIn' || userState === 'loggingOut';
|
|
12747
|
+
const displayName = userName || signedIn();
|
|
12748
|
+
return [{
|
|
12749
|
+
childCount: isAuthenticated ? 2 : 1,
|
|
12750
|
+
className: ChatHeaderAuth,
|
|
12751
|
+
style: authContainerStyle,
|
|
12752
|
+
type: Div
|
|
12753
|
+
}, ...(isAuthenticated ? [{
|
|
12754
|
+
childCount: 1,
|
|
12755
|
+
className: ChatHeaderAuthName,
|
|
12756
|
+
style: authNameStyle,
|
|
12757
|
+
title: displayName,
|
|
12758
|
+
type: Span
|
|
12759
|
+
}, text(displayName)] : []), {
|
|
12760
|
+
childCount: 1,
|
|
12761
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
12762
|
+
disabled: isPending,
|
|
12763
|
+
inputType: 'button',
|
|
12764
|
+
name: buttonName,
|
|
12765
|
+
onClick: HandleClick,
|
|
12766
|
+
style: authButtonStyle,
|
|
12767
|
+
title: buttonTitle,
|
|
12768
|
+
type: Button$1
|
|
12769
|
+
}, text(buttonLabel)];
|
|
12050
12770
|
};
|
|
12051
12771
|
|
|
12052
12772
|
const focusHeaderStyle = 'align-items:center;border-bottom:1px solid var(--vscode-panel-border, transparent);display:flex;gap:12px;justify-content:space-between;padding:8px 12px;';
|
|
@@ -12067,15 +12787,15 @@ const getFocusHeaderActionButtonDom = (label, name) => {
|
|
|
12067
12787
|
type: Button$1
|
|
12068
12788
|
}, text(label)];
|
|
12069
12789
|
};
|
|
12070
|
-
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName) => {
|
|
12790
|
+
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
12071
12791
|
const items = [[addAction(), FocusAddAction], [openInVsCode(), FocusOpenInVsCode], [commit(), FocusCommit], [openTerminal(), FocusOpenTerminal], [showDiff(), FocusShowDiff]];
|
|
12072
12792
|
const hasProjectName = !!selectedProjectName;
|
|
12073
12793
|
return [{
|
|
12074
|
-
childCount: 2,
|
|
12794
|
+
childCount: 2 + (authEnabled ? 1 : 0),
|
|
12075
12795
|
className: ChatFocusHeader,
|
|
12076
12796
|
style: focusHeaderStyle,
|
|
12077
12797
|
type: Header
|
|
12078
|
-
}, {
|
|
12798
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
12079
12799
|
childCount: hasProjectName ? 2 : 1,
|
|
12080
12800
|
className: ChatName,
|
|
12081
12801
|
style: focusHeaderMetaStyle,
|
|
@@ -12658,6 +13378,7 @@ const getMissingApiActionsDom = ({
|
|
|
12658
13378
|
};
|
|
12659
13379
|
const getMissingApiKeyDom = ({
|
|
12660
13380
|
getApiKeyText,
|
|
13381
|
+
inputClassName,
|
|
12661
13382
|
inputName,
|
|
12662
13383
|
inputPattern,
|
|
12663
13384
|
inputRequired = false,
|
|
@@ -12680,7 +13401,7 @@ const getMissingApiKeyDom = ({
|
|
|
12680
13401
|
autocomplete: 'off',
|
|
12681
13402
|
autocorrect: 'off',
|
|
12682
13403
|
childCount: 0,
|
|
12683
|
-
className: InputBox,
|
|
13404
|
+
className: inputClassName ? mergeClassNames(InputBox, inputClassName) : InputBox,
|
|
12684
13405
|
name: inputName,
|
|
12685
13406
|
onInput: HandleInput,
|
|
12686
13407
|
...(inputPattern ? {
|
|
@@ -12700,13 +13421,17 @@ const getMissingApiKeyDom = ({
|
|
|
12700
13421
|
})];
|
|
12701
13422
|
};
|
|
12702
13423
|
|
|
12703
|
-
const getMissingOpenApiApiKeyDom = (openApiApiKeyState = 'idle', openSettingsUrl = 'https://platform.openai.com/api-keys', inputPattern = '^sk-.+') => {
|
|
13424
|
+
const getMissingOpenApiApiKeyDom = (openApiApiKeyInput = '', openApiApiKeyState = 'idle', openSettingsUrl = 'https://platform.openai.com/api-keys', inputPattern = '^sk-.+') => {
|
|
12704
13425
|
const isSaving = openApiApiKeyState === 'saving';
|
|
13426
|
+
const isInvalid = openApiApiKeyInput !== '' && !new RegExp(inputPattern).test(openApiApiKeyInput);
|
|
12705
13427
|
return getMissingApiKeyDom({
|
|
12706
13428
|
getApiKeyText: getOpenApiApiKey(),
|
|
13429
|
+
...(isInvalid ? {
|
|
13430
|
+
inputClassName: InputInvalid
|
|
13431
|
+
} : {}),
|
|
12707
13432
|
inputName: OpenApiApiKeyInput,
|
|
12708
13433
|
inputPattern,
|
|
12709
|
-
inputRequired:
|
|
13434
|
+
inputRequired: false,
|
|
12710
13435
|
onSubmit: HandleMissingOpenAiApiKeyFormSubmit,
|
|
12711
13436
|
openSettingsButtonName: OpenOpenApiApiKeyWebsite,
|
|
12712
13437
|
openSettingsUrl,
|
|
@@ -13696,14 +14421,27 @@ const getChatAttachmentsDom = attachments => {
|
|
|
13696
14421
|
}];
|
|
13697
14422
|
})];
|
|
13698
14423
|
};
|
|
13699
|
-
const
|
|
14424
|
+
const getStandaloneImageAttachmentDom = attachment => {
|
|
14425
|
+
if (!attachment.previewSrc) {
|
|
14426
|
+
return getChatAttachmentsDom([attachment]);
|
|
14427
|
+
}
|
|
14428
|
+
return [{
|
|
14429
|
+
alt: attachment.name,
|
|
14430
|
+
childCount: 0,
|
|
14431
|
+
className: ChatMessageImage,
|
|
14432
|
+
src: attachment.previewSrc,
|
|
14433
|
+
type: Img
|
|
14434
|
+
}];
|
|
14435
|
+
};
|
|
14436
|
+
const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput, openApiApiKeyInput = '', openApiApiKeyState = 'idle', openApiApiKeysSettingsUrl = 'https://platform.openai.com/api-keys', openApiApiKeyInputPattern = '^sk-.+', openRouterApiKeyState = 'idle', useChatMathWorker = false, standaloneImageAttachment) => {
|
|
13700
14437
|
const roleClassName = message.role === 'user' ? MessageUser : MessageAssistant;
|
|
13701
14438
|
const isOpenApiApiKeyMissingMessage = message.role === 'assistant' && message.text === openApiApiKeyRequiredMessage;
|
|
13702
14439
|
const isOpenRouterApiKeyMissingMessage = message.role === 'assistant' && message.text === openRouterApiKeyRequiredMessage;
|
|
13703
14440
|
const isOpenRouterRequestFailedMessage = message.role === 'assistant' && message.text === openRouterRequestFailedMessage;
|
|
13704
14441
|
const isOpenRouterTooManyRequestsMessage = message.role === 'assistant' && message.text.startsWith(openRouterTooManyRequestsMessage);
|
|
13705
|
-
const
|
|
13706
|
-
const
|
|
14442
|
+
const isStandaloneImageMessage = !!standaloneImageAttachment;
|
|
14443
|
+
const messageDom = isStandaloneImageMessage ? getStandaloneImageAttachmentDom(standaloneImageAttachment) : getMessageContentDom(parsedMessageContent, useChatMathWorker);
|
|
14444
|
+
const attachmentsDom = !isStandaloneImageMessage && message.role === 'user' ? getChatAttachmentsDom(message.attachments ?? []) : [];
|
|
13707
14445
|
const toolCallsDom = getToolCallsDom(message);
|
|
13708
14446
|
const toolCallsChildCount = toolCallsDom.length > 0 ? 1 : 0;
|
|
13709
14447
|
const messageDomChildCount = getTopLevelNodeCount(messageDom);
|
|
@@ -13715,9 +14453,9 @@ const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput
|
|
|
13715
14453
|
type: Div
|
|
13716
14454
|
}, {
|
|
13717
14455
|
childCount: extraChildCount,
|
|
13718
|
-
className: ChatMessageContent,
|
|
14456
|
+
className: isStandaloneImageMessage ? mergeClassNames(ChatMessageContent, ChatImageMessageContent) : ChatMessageContent,
|
|
13719
14457
|
type: Div
|
|
13720
|
-
}, ...toolCallsDom, ...messageDom, ...attachmentsDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
14458
|
+
}, ...toolCallsDom, ...messageDom, ...attachmentsDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
13721
14459
|
};
|
|
13722
14460
|
|
|
13723
14461
|
const parentNode$1 = {
|
|
@@ -13733,6 +14471,22 @@ const getEmptyMessagesDom = () => {
|
|
|
13733
14471
|
const hasMessageText = message => {
|
|
13734
14472
|
return message.text.trim().length > 0;
|
|
13735
14473
|
};
|
|
14474
|
+
const isImageAttachment = attachment => {
|
|
14475
|
+
return attachment.displayType === 'image';
|
|
14476
|
+
};
|
|
14477
|
+
const withAttachments = (message, attachments) => {
|
|
14478
|
+
const {
|
|
14479
|
+
attachments: _attachments,
|
|
14480
|
+
...messageWithoutAttachments
|
|
14481
|
+
} = message;
|
|
14482
|
+
if (attachments.length === 0) {
|
|
14483
|
+
return messageWithoutAttachments;
|
|
14484
|
+
}
|
|
14485
|
+
return {
|
|
14486
|
+
...messageWithoutAttachments,
|
|
14487
|
+
attachments
|
|
14488
|
+
};
|
|
14489
|
+
};
|
|
13736
14490
|
const getDisplayMessages = (messages, parsedMessages) => {
|
|
13737
14491
|
const displayMessages = [];
|
|
13738
14492
|
for (const message of messages) {
|
|
@@ -13740,6 +14494,30 @@ const getDisplayMessages = (messages, parsedMessages) => {
|
|
|
13740
14494
|
if (!parsedContent) {
|
|
13741
14495
|
continue;
|
|
13742
14496
|
}
|
|
14497
|
+
if (message.role === 'user') {
|
|
14498
|
+
const attachments = message.attachments ?? [];
|
|
14499
|
+
const imageAttachments = attachments.filter(isImageAttachment);
|
|
14500
|
+
if (imageAttachments.length > 0) {
|
|
14501
|
+
const nonImageAttachments = attachments.filter(attachment => !isImageAttachment(attachment));
|
|
14502
|
+
if (hasMessageText(message) || nonImageAttachments.length > 0) {
|
|
14503
|
+
displayMessages.push({
|
|
14504
|
+
message: withAttachments(message, nonImageAttachments),
|
|
14505
|
+
parsedContent: hasMessageText(message) ? parsedContent : getEmptyMessageContent()
|
|
14506
|
+
});
|
|
14507
|
+
}
|
|
14508
|
+
for (const attachment of imageAttachments) {
|
|
14509
|
+
displayMessages.push({
|
|
14510
|
+
message: {
|
|
14511
|
+
...withAttachments(message, [attachment]),
|
|
14512
|
+
text: ''
|
|
14513
|
+
},
|
|
14514
|
+
parsedContent: getEmptyMessageContent(),
|
|
14515
|
+
standaloneImageAttachment: attachment
|
|
14516
|
+
});
|
|
14517
|
+
}
|
|
14518
|
+
continue;
|
|
14519
|
+
}
|
|
14520
|
+
}
|
|
13743
14521
|
if (message.role !== 'assistant' || !message.toolCalls || message.toolCalls.length === 0) {
|
|
13744
14522
|
displayMessages.push({
|
|
13745
14523
|
message,
|
|
@@ -13795,7 +14573,7 @@ const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApi
|
|
|
13795
14573
|
role: 'log',
|
|
13796
14574
|
scrollTop: messagesScrollTop,
|
|
13797
14575
|
type: Div
|
|
13798
|
-
}, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker))];
|
|
14576
|
+
}, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker, item.standaloneImageAttachment))];
|
|
13799
14577
|
};
|
|
13800
14578
|
|
|
13801
14579
|
const arrowLeft$1 = {
|
|
@@ -13909,7 +14687,6 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13909
14687
|
agentModePickerOpen = false,
|
|
13910
14688
|
authEnabled = false,
|
|
13911
14689
|
authErrorMessage = '',
|
|
13912
|
-
authStatus = 'signed-out',
|
|
13913
14690
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
13914
14691
|
composerAttachmentPreviewOverlayError = false,
|
|
13915
14692
|
composerAttachments,
|
|
@@ -13920,6 +14697,10 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13920
14697
|
composerHeight = 28,
|
|
13921
14698
|
composerLineHeight = 20,
|
|
13922
14699
|
composerValue,
|
|
14700
|
+
gitBranches,
|
|
14701
|
+
gitBranchPickerErrorMessage,
|
|
14702
|
+
gitBranchPickerOpen,
|
|
14703
|
+
gitBranchPickerVisible,
|
|
13923
14704
|
hasSpaceForAgentModePicker,
|
|
13924
14705
|
hasSpaceForRunModePicker,
|
|
13925
14706
|
messagesAutoScrollEnabled,
|
|
@@ -13954,14 +14735,15 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13954
14735
|
tokensUsed,
|
|
13955
14736
|
usageOverviewEnabled,
|
|
13956
14737
|
useChatMathWorker = false,
|
|
14738
|
+
userName = '',
|
|
14739
|
+
userState = 'loggedOut',
|
|
13957
14740
|
visibleModels = models,
|
|
13958
14741
|
voiceDictationEnabled = false
|
|
13959
14742
|
}) => {
|
|
13960
14743
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
13961
|
-
const selectedProject = projects.find(project => project.id === selectedProjectId);
|
|
13962
|
-
const messages = selectedSession ? selectedSession.messages : [];
|
|
13963
14744
|
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
13964
|
-
const selectedProjectName =
|
|
14745
|
+
const selectedProjectName = projects.find(project => project.id === selectedProjectId)?.name || '';
|
|
14746
|
+
const messages = selectedSession ? selectedSession.messages : [];
|
|
13965
14747
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13966
14748
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
13967
14749
|
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
@@ -13980,7 +14762,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13980
14762
|
childCount: 3,
|
|
13981
14763
|
className: ChatFocusMainArea,
|
|
13982
14764
|
type: Div
|
|
13983
|
-
}, ...getChatHeaderDomFocusMode(selectedSessionTitle, selectedProjectName), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
14765
|
+
}, ...getChatHeaderDomFocusMode(selectedSessionTitle, selectedProjectName, authEnabled, userState, userName), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, gitBranchPickerVisible, gitBranchPickerOpen, gitBranchPickerErrorMessage, gitBranches, selectedSession?.branchName || '', hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
13984
14766
|
agentMode,
|
|
13985
14767
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13986
14768
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14033,31 +14815,8 @@ const getHeaderActionVirtualDom = item => {
|
|
|
14033
14815
|
}];
|
|
14034
14816
|
};
|
|
14035
14817
|
|
|
14036
|
-
const
|
|
14037
|
-
const isSigningIn = authStatus === 'signing-in';
|
|
14038
|
-
if (!authEnabled) {
|
|
14039
|
-
return undefined;
|
|
14040
|
-
}
|
|
14041
|
-
if (authStatus !== 'signed-in') {
|
|
14042
|
-
return {
|
|
14043
|
-
disabled: isSigningIn,
|
|
14044
|
-
icon: mergeClassNames(MaskIcon, MaskIconAccount),
|
|
14045
|
-
name: Login,
|
|
14046
|
-
onClick: HandleClick,
|
|
14047
|
-
title: isSigningIn ? loggingInToBackend() : loginToBackend()
|
|
14048
|
-
};
|
|
14049
|
-
}
|
|
14050
|
-
return {
|
|
14051
|
-
disabled: false,
|
|
14052
|
-
icon: mergeClassNames(MaskIcon, MaskIconSignOut),
|
|
14053
|
-
name: Logout,
|
|
14054
|
-
onClick: HandleClick,
|
|
14055
|
-
title: logoutFromBackend()
|
|
14056
|
-
};
|
|
14057
|
-
};
|
|
14058
|
-
const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'signed-out', searchEnabled = false) => {
|
|
14818
|
+
const getChatHeaderActionsDom = (viewMode, searchEnabled = false) => {
|
|
14059
14819
|
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
14060
|
-
const authAction = getAuthAction(authEnabled, authStatus);
|
|
14061
14820
|
const items = [{
|
|
14062
14821
|
icon: mergeClassNames(MaskIcon, MaskIconLayoutPanelLeft),
|
|
14063
14822
|
name: ToggleChatFocus,
|
|
@@ -14083,7 +14842,7 @@ const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'si
|
|
|
14083
14842
|
name: Settings,
|
|
14084
14843
|
onClick: HandleClickSettings,
|
|
14085
14844
|
title: settings()
|
|
14086
|
-
},
|
|
14845
|
+
}, {
|
|
14087
14846
|
icon: mergeClassNames(MaskIcon, MaskIconClose),
|
|
14088
14847
|
name: CloseChat,
|
|
14089
14848
|
onClick: HandleClickClose,
|
|
@@ -14108,14 +14867,14 @@ const getAuthErrorDom = (hasAuthError, authErrorMessage) => {
|
|
|
14108
14867
|
type: Span
|
|
14109
14868
|
}, text(authErrorMessage)];
|
|
14110
14869
|
};
|
|
14111
|
-
const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false,
|
|
14870
|
+
const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '') => {
|
|
14112
14871
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
14113
14872
|
return [{
|
|
14114
|
-
childCount: hasAuthError ?
|
|
14873
|
+
childCount: 2 + (authEnabled ? 1 : 0) + (hasAuthError ? 1 : 0),
|
|
14115
14874
|
className: ChatHeader,
|
|
14116
14875
|
onContextMenu: HandleChatHeaderContextMenu,
|
|
14117
14876
|
type: Header
|
|
14118
|
-
}, {
|
|
14877
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
14119
14878
|
childCount: 2,
|
|
14120
14879
|
className: ChatName,
|
|
14121
14880
|
type: Div
|
|
@@ -14123,7 +14882,7 @@ const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, a
|
|
|
14123
14882
|
childCount: 1,
|
|
14124
14883
|
className: ChatHeaderLabel,
|
|
14125
14884
|
type: H2
|
|
14126
|
-
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail'
|
|
14885
|
+
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail'), ...getAuthErrorDom(hasAuthError, authErrorMessage)];
|
|
14127
14886
|
};
|
|
14128
14887
|
|
|
14129
14888
|
const getChatModeDetailVirtualDom = ({
|
|
@@ -14132,7 +14891,6 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14132
14891
|
agentModePickerOpen = false,
|
|
14133
14892
|
authEnabled = false,
|
|
14134
14893
|
authErrorMessage = '',
|
|
14135
|
-
authStatus = 'signed-out',
|
|
14136
14894
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14137
14895
|
composerAttachmentPreviewOverlayError = false,
|
|
14138
14896
|
composerAttachments,
|
|
@@ -14173,6 +14931,8 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14173
14931
|
tokensUsed,
|
|
14174
14932
|
usageOverviewEnabled,
|
|
14175
14933
|
useChatMathWorker = false,
|
|
14934
|
+
userName = '',
|
|
14935
|
+
userState = 'loggedOut',
|
|
14176
14936
|
visibleModels = models,
|
|
14177
14937
|
voiceDictationEnabled = false
|
|
14178
14938
|
}) => {
|
|
@@ -14193,7 +14953,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14193
14953
|
onDragEnter: HandleDragEnterChatView,
|
|
14194
14954
|
onDragOver: HandleDragOverChatView,
|
|
14195
14955
|
type: Div
|
|
14196
|
-
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled,
|
|
14956
|
+
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, userState, userName, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, false, false, '', [], '', hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
14197
14957
|
agentMode,
|
|
14198
14958
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14199
14959
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14229,20 +14989,20 @@ const getChatSearchDom = (hasSearchField, searchValue) => {
|
|
|
14229
14989
|
value: searchValue
|
|
14230
14990
|
}];
|
|
14231
14991
|
};
|
|
14232
|
-
const getChatHeaderListModeDom = (authEnabled = false,
|
|
14992
|
+
const getChatHeaderListModeDom = (authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
|
|
14233
14993
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
14234
14994
|
const hasSearchField = searchEnabled && searchFieldVisible;
|
|
14235
|
-
const headerChildCount = 2 + (hasAuthError ? 1 : 0) + (hasSearchField ? 1 : 0);
|
|
14995
|
+
const headerChildCount = 2 + (authEnabled ? 1 : 0) + (hasAuthError ? 1 : 0) + (hasSearchField ? 1 : 0);
|
|
14236
14996
|
return [{
|
|
14237
14997
|
childCount: headerChildCount,
|
|
14238
14998
|
className: ChatHeader,
|
|
14239
14999
|
onContextMenu: HandleChatHeaderContextMenu,
|
|
14240
15000
|
type: Header
|
|
14241
|
-
}, {
|
|
15001
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
14242
15002
|
childCount: 1,
|
|
14243
15003
|
className: ChatHeaderLabel,
|
|
14244
15004
|
type: H2
|
|
14245
|
-
}, text(chats()), ...getChatHeaderActionsDom('list',
|
|
15005
|
+
}, text(chats()), ...getChatHeaderActionsDom('list', searchEnabled), ...getChatSearchDom(hasSearchField, searchValue), ...(hasAuthError ? [{
|
|
14246
15006
|
childCount: 1,
|
|
14247
15007
|
className: ChatAuthError,
|
|
14248
15008
|
type: Span
|
|
@@ -14342,7 +15102,6 @@ const getChatModeListVirtualDom = ({
|
|
|
14342
15102
|
agentModePickerOpen = false,
|
|
14343
15103
|
authEnabled = false,
|
|
14344
15104
|
authErrorMessage = '',
|
|
14345
|
-
authStatus = 'signed-out',
|
|
14346
15105
|
chatListScrollTop = 0,
|
|
14347
15106
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14348
15107
|
composerAttachmentPreviewOverlayError = false,
|
|
@@ -14377,6 +15136,8 @@ const getChatModeListVirtualDom = ({
|
|
|
14377
15136
|
tokensMax,
|
|
14378
15137
|
tokensUsed,
|
|
14379
15138
|
usageOverviewEnabled,
|
|
15139
|
+
userName = '',
|
|
15140
|
+
userState = 'loggedOut',
|
|
14380
15141
|
visibleModels = models,
|
|
14381
15142
|
voiceDictationEnabled = false
|
|
14382
15143
|
}) => {
|
|
@@ -14395,7 +15156,7 @@ const getChatModeListVirtualDom = ({
|
|
|
14395
15156
|
onDragEnter: HandleDragEnterChatView,
|
|
14396
15157
|
onDragOver: HandleDragOverChatView,
|
|
14397
15158
|
type: Div
|
|
14398
|
-
}, ...getChatHeaderListModeDom(authEnabled,
|
|
15159
|
+
}, ...getChatHeaderListModeDom(authEnabled, userState, userName, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, false, false, '', [], '', hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, false, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
|
|
14399
15160
|
agentMode,
|
|
14400
15161
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14401
15162
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14498,7 +15259,6 @@ const getChatVirtualDom = options => {
|
|
|
14498
15259
|
agentModePickerOpen = false,
|
|
14499
15260
|
authEnabled = false,
|
|
14500
15261
|
authErrorMessage = '',
|
|
14501
|
-
authStatus = 'signed-out',
|
|
14502
15262
|
chatListScrollTop,
|
|
14503
15263
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14504
15264
|
composerAttachmentPreviewOverlayError = false,
|
|
@@ -14510,6 +15270,10 @@ const getChatVirtualDom = options => {
|
|
|
14510
15270
|
composerHeight,
|
|
14511
15271
|
composerLineHeight,
|
|
14512
15272
|
composerValue,
|
|
15273
|
+
gitBranches = [],
|
|
15274
|
+
gitBranchPickerErrorMessage = '',
|
|
15275
|
+
gitBranchPickerOpen = false,
|
|
15276
|
+
gitBranchPickerVisible = false,
|
|
14513
15277
|
hasSpaceForAgentModePicker,
|
|
14514
15278
|
hasSpaceForRunModePicker,
|
|
14515
15279
|
listFocusedIndex = -1,
|
|
@@ -14547,6 +15311,8 @@ const getChatVirtualDom = options => {
|
|
|
14547
15311
|
tokensUsed,
|
|
14548
15312
|
usageOverviewEnabled,
|
|
14549
15313
|
useChatMathWorker = false,
|
|
15314
|
+
userName = '',
|
|
15315
|
+
userState = 'loggedOut',
|
|
14550
15316
|
viewMode,
|
|
14551
15317
|
visibleModels = models,
|
|
14552
15318
|
voiceDictationEnabled = false
|
|
@@ -14561,7 +15327,6 @@ const getChatVirtualDom = options => {
|
|
|
14561
15327
|
agentModePickerOpen,
|
|
14562
15328
|
authEnabled,
|
|
14563
15329
|
authErrorMessage,
|
|
14564
|
-
authStatus,
|
|
14565
15330
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14566
15331
|
composerAttachmentPreviewOverlayError,
|
|
14567
15332
|
composerAttachments,
|
|
@@ -14572,6 +15337,10 @@ const getChatVirtualDom = options => {
|
|
|
14572
15337
|
composerHeight,
|
|
14573
15338
|
composerLineHeight,
|
|
14574
15339
|
composerValue,
|
|
15340
|
+
gitBranches,
|
|
15341
|
+
gitBranchPickerErrorMessage,
|
|
15342
|
+
gitBranchPickerOpen,
|
|
15343
|
+
gitBranchPickerVisible,
|
|
14575
15344
|
hasSpaceForAgentModePicker,
|
|
14576
15345
|
hasSpaceForRunModePicker,
|
|
14577
15346
|
messagesAutoScrollEnabled,
|
|
@@ -14606,6 +15375,8 @@ const getChatVirtualDom = options => {
|
|
|
14606
15375
|
tokensUsed,
|
|
14607
15376
|
usageOverviewEnabled,
|
|
14608
15377
|
useChatMathWorker,
|
|
15378
|
+
userName,
|
|
15379
|
+
userState,
|
|
14609
15380
|
visibleModels,
|
|
14610
15381
|
voiceDictationEnabled
|
|
14611
15382
|
});
|
|
@@ -14616,7 +15387,6 @@ const getChatVirtualDom = options => {
|
|
|
14616
15387
|
agentModePickerOpen,
|
|
14617
15388
|
authEnabled,
|
|
14618
15389
|
authErrorMessage,
|
|
14619
|
-
authStatus,
|
|
14620
15390
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14621
15391
|
composerAttachmentPreviewOverlayError,
|
|
14622
15392
|
composerAttachments,
|
|
@@ -14657,6 +15427,8 @@ const getChatVirtualDom = options => {
|
|
|
14657
15427
|
tokensUsed,
|
|
14658
15428
|
usageOverviewEnabled,
|
|
14659
15429
|
useChatMathWorker,
|
|
15430
|
+
userName,
|
|
15431
|
+
userState,
|
|
14660
15432
|
visibleModels,
|
|
14661
15433
|
voiceDictationEnabled
|
|
14662
15434
|
});
|
|
@@ -14667,7 +15439,6 @@ const getChatVirtualDom = options => {
|
|
|
14667
15439
|
agentModePickerOpen,
|
|
14668
15440
|
authEnabled,
|
|
14669
15441
|
authErrorMessage,
|
|
14670
|
-
authStatus,
|
|
14671
15442
|
chatListScrollTop,
|
|
14672
15443
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14673
15444
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14702,6 +15473,8 @@ const getChatVirtualDom = options => {
|
|
|
14702
15473
|
tokensMax,
|
|
14703
15474
|
tokensUsed,
|
|
14704
15475
|
usageOverviewEnabled,
|
|
15476
|
+
userName,
|
|
15477
|
+
userState,
|
|
14705
15478
|
visibleModels,
|
|
14706
15479
|
voiceDictationEnabled
|
|
14707
15480
|
});
|
|
@@ -14717,7 +15490,6 @@ const renderItems = (oldState, newState) => {
|
|
|
14717
15490
|
agentModePickerOpen,
|
|
14718
15491
|
authEnabled,
|
|
14719
15492
|
authErrorMessage,
|
|
14720
|
-
authStatus,
|
|
14721
15493
|
chatListScrollTop,
|
|
14722
15494
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14723
15495
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14729,6 +15501,10 @@ const renderItems = (oldState, newState) => {
|
|
|
14729
15501
|
composerHeight,
|
|
14730
15502
|
composerLineHeight,
|
|
14731
15503
|
composerValue,
|
|
15504
|
+
gitBranches,
|
|
15505
|
+
gitBranchPickerErrorMessage,
|
|
15506
|
+
gitBranchPickerOpen,
|
|
15507
|
+
gitBranchPickerVisible,
|
|
14732
15508
|
hasSpaceForAgentModePicker,
|
|
14733
15509
|
hasSpaceForRunModePicker,
|
|
14734
15510
|
initial,
|
|
@@ -14768,6 +15544,8 @@ const renderItems = (oldState, newState) => {
|
|
|
14768
15544
|
uid,
|
|
14769
15545
|
usageOverviewEnabled,
|
|
14770
15546
|
useChatMathWorker,
|
|
15547
|
+
userName,
|
|
15548
|
+
userState,
|
|
14771
15549
|
viewMode,
|
|
14772
15550
|
visibleModels,
|
|
14773
15551
|
voiceDictationEnabled
|
|
@@ -14781,7 +15559,6 @@ const renderItems = (oldState, newState) => {
|
|
|
14781
15559
|
agentModePickerOpen,
|
|
14782
15560
|
authEnabled,
|
|
14783
15561
|
authErrorMessage,
|
|
14784
|
-
authStatus,
|
|
14785
15562
|
chatListScrollTop,
|
|
14786
15563
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14787
15564
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14793,6 +15570,10 @@ const renderItems = (oldState, newState) => {
|
|
|
14793
15570
|
composerHeight,
|
|
14794
15571
|
composerLineHeight,
|
|
14795
15572
|
composerValue,
|
|
15573
|
+
gitBranches,
|
|
15574
|
+
gitBranchPickerErrorMessage,
|
|
15575
|
+
gitBranchPickerOpen,
|
|
15576
|
+
gitBranchPickerVisible,
|
|
14796
15577
|
hasSpaceForAgentModePicker,
|
|
14797
15578
|
hasSpaceForRunModePicker,
|
|
14798
15579
|
listFocusedIndex,
|
|
@@ -14830,6 +15611,8 @@ const renderItems = (oldState, newState) => {
|
|
|
14830
15611
|
tokensUsed,
|
|
14831
15612
|
usageOverviewEnabled,
|
|
14832
15613
|
useChatMathWorker,
|
|
15614
|
+
userName,
|
|
15615
|
+
userState,
|
|
14833
15616
|
viewMode,
|
|
14834
15617
|
visibleModels,
|
|
14835
15618
|
voiceDictationEnabled
|
|
@@ -14876,8 +15659,16 @@ const renderSelection = (oldState, newState) => {
|
|
|
14876
15659
|
const renderValue = (oldState, newState) => {
|
|
14877
15660
|
const {
|
|
14878
15661
|
composerValue,
|
|
15662
|
+
openApiApiKeyInput,
|
|
15663
|
+
openRouterApiKeyInput,
|
|
14879
15664
|
uid
|
|
14880
15665
|
} = newState;
|
|
15666
|
+
if (oldState.openApiApiKeyInput !== openApiApiKeyInput) {
|
|
15667
|
+
return [SetValueByName, uid, OpenApiApiKeyInput, openApiApiKeyInput];
|
|
15668
|
+
}
|
|
15669
|
+
if (oldState.openRouterApiKeyInput !== openRouterApiKeyInput) {
|
|
15670
|
+
return [SetValueByName, uid, OpenRouterApiKeyInput, openRouterApiKeyInput];
|
|
15671
|
+
}
|
|
14881
15672
|
return [SetValueByName, uid, Composer, composerValue];
|
|
14882
15673
|
};
|
|
14883
15674
|
|
|
@@ -14971,6 +15762,9 @@ const renderEventListeners = () => {
|
|
|
14971
15762
|
}, {
|
|
14972
15763
|
name: HandleClickAgentModePickerToggle,
|
|
14973
15764
|
params: ['openAgentModePicker']
|
|
15765
|
+
}, {
|
|
15766
|
+
name: HandleClickGitBranchPickerToggle,
|
|
15767
|
+
params: ['handleClickGitBranchPickerToggle']
|
|
14974
15768
|
}, {
|
|
14975
15769
|
name: HandleClickModelPickerOverlay,
|
|
14976
15770
|
params: ['handleClickModelPickerOverlay', DefaultPrevented]
|
|
@@ -15129,6 +15923,10 @@ const reset = async state => {
|
|
|
15129
15923
|
composerSelectionEnd: 0,
|
|
15130
15924
|
composerSelectionStart: 0,
|
|
15131
15925
|
composerValue: '',
|
|
15926
|
+
gitBranches: [],
|
|
15927
|
+
gitBranchPickerErrorMessage: '',
|
|
15928
|
+
gitBranchPickerOpen: false,
|
|
15929
|
+
gitBranchPickerVisible: false,
|
|
15132
15930
|
mockAiResponseDelay: 0,
|
|
15133
15931
|
modelPickerHeight: getModelPickerHeight(state.modelPickerHeaderHeight, state.models.length),
|
|
15134
15932
|
modelPickerListScrollTop: 0,
|
|
@@ -15208,7 +16006,6 @@ const saveState = state => {
|
|
|
15208
16006
|
selectedModelId,
|
|
15209
16007
|
selectedProjectId,
|
|
15210
16008
|
selectedSessionId,
|
|
15211
|
-
systemPrompt,
|
|
15212
16009
|
viewMode
|
|
15213
16010
|
} = state;
|
|
15214
16011
|
return {
|
|
@@ -15231,7 +16028,6 @@ const saveState = state => {
|
|
|
15231
16028
|
selectedModelId,
|
|
15232
16029
|
selectedProjectId,
|
|
15233
16030
|
selectedSessionId,
|
|
15234
|
-
systemPrompt,
|
|
15235
16031
|
viewMode
|
|
15236
16032
|
};
|
|
15237
16033
|
};
|
|
@@ -15246,7 +16042,13 @@ const setAddContextButtonEnabled = (state, addContextButtonEnabled) => {
|
|
|
15246
16042
|
const setAuthEnabled = (state, authEnabled) => {
|
|
15247
16043
|
return {
|
|
15248
16044
|
...state,
|
|
15249
|
-
authEnabled
|
|
16045
|
+
authAccessToken: authEnabled ? state.authAccessToken : '',
|
|
16046
|
+
authEnabled,
|
|
16047
|
+
authErrorMessage: authEnabled ? state.authErrorMessage : '',
|
|
16048
|
+
userName: authEnabled ? state.userName : '',
|
|
16049
|
+
userState: authEnabled ? state.userState : 'loggedOut',
|
|
16050
|
+
userSubscriptionPlan: authEnabled ? state.userSubscriptionPlan : '',
|
|
16051
|
+
userUsedTokens: authEnabled ? state.userUsedTokens : 0
|
|
15250
16052
|
};
|
|
15251
16053
|
};
|
|
15252
16054
|
|
|
@@ -15440,6 +16242,7 @@ const commandMap = {
|
|
|
15440
16242
|
'Chat.chatListFocusNext': wrapCommand(chatListFocusNext),
|
|
15441
16243
|
'Chat.chatListFocusPrevious': wrapCommand(chatListFocusPrevious),
|
|
15442
16244
|
'Chat.clearInput': wrapCommand(clearInput),
|
|
16245
|
+
'Chat.closeGitBranchPicker': wrapCommand(closeGitBranchPicker),
|
|
15443
16246
|
'Chat.copyInput': wrapCommand(copyInput),
|
|
15444
16247
|
'Chat.create': create,
|
|
15445
16248
|
'Chat.cutInput': wrapCommand(cutInput),
|
|
@@ -15468,6 +16271,7 @@ const commandMap = {
|
|
|
15468
16271
|
'Chat.handleClickDelete': wrapCommand(handleClickDelete),
|
|
15469
16272
|
'Chat.handleClickDictationButton': wrapCommand(handleClickDictationButton),
|
|
15470
16273
|
'Chat.handleClickFileName': wrapCommand(handleClickFileName),
|
|
16274
|
+
'Chat.handleClickGitBranchPickerToggle': wrapCommand(handleClickGitBranchPickerToggle),
|
|
15471
16275
|
'Chat.handleClickList': wrapCommand(handleClickList),
|
|
15472
16276
|
'Chat.handleClickModelPickerList': wrapCommand(handleClickModelPickerList),
|
|
15473
16277
|
'Chat.handleClickModelPickerListIndex': wrapCommand(handleClickModelPickerListIndex),
|
|
@@ -15519,6 +16323,7 @@ const commandMap = {
|
|
|
15519
16323
|
'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
|
|
15520
16324
|
'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
|
|
15521
16325
|
'Chat.openAgentModePicker': wrapCommand(openAgentModePicker),
|
|
16326
|
+
'Chat.openGitBranchPicker': wrapCommand(openGitBranchPicker),
|
|
15522
16327
|
'Chat.openMockProject': wrapCommand(openMockProject),
|
|
15523
16328
|
'Chat.openMockSession': wrapCommand(openMockSession),
|
|
15524
16329
|
'Chat.openModelPicker': wrapCommand(openModelPicker),
|