@lvce-editor/chat-view 6.70.0 → 7.0.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 +1043 -233
- package/package.json +1 -1
|
@@ -1775,6 +1775,17 @@ const clearInput = async state => {
|
|
|
1775
1775
|
};
|
|
1776
1776
|
};
|
|
1777
1777
|
|
|
1778
|
+
const closeGitBranchPicker = state => {
|
|
1779
|
+
if (!state.gitBranchPickerOpen && !state.gitBranchPickerErrorMessage) {
|
|
1780
|
+
return state;
|
|
1781
|
+
}
|
|
1782
|
+
return {
|
|
1783
|
+
...state,
|
|
1784
|
+
gitBranchPickerErrorMessage: '',
|
|
1785
|
+
gitBranchPickerOpen: false
|
|
1786
|
+
};
|
|
1787
|
+
};
|
|
1788
|
+
|
|
1778
1789
|
const clampSelectionIndex = (value, max) => {
|
|
1779
1790
|
if (!Number.isFinite(value)) {
|
|
1780
1791
|
return 0;
|
|
@@ -1852,6 +1863,7 @@ const BackToChatList = 'Back to chat list';
|
|
|
1852
1863
|
const Search$1 = 'Search';
|
|
1853
1864
|
const ScrollDown$1 = 'Scroll down';
|
|
1854
1865
|
const SearchModels = 'Search models';
|
|
1866
|
+
const PickModel = 'Pick Model';
|
|
1855
1867
|
const SearchChats = 'Search chats';
|
|
1856
1868
|
const Paste = 'Paste';
|
|
1857
1869
|
const Rename = 'Rename';
|
|
@@ -1859,9 +1871,13 @@ const Archive = 'Archive';
|
|
|
1859
1871
|
const AddProjectChat = 'Add Project';
|
|
1860
1872
|
const RemoveProject = 'Remove Project';
|
|
1861
1873
|
const Settings$1 = 'Settings';
|
|
1874
|
+
const Login$1 = 'Login';
|
|
1875
|
+
const Logout$1 = 'Logout';
|
|
1862
1876
|
const LoginToBackend = 'Login to backend';
|
|
1863
1877
|
const LogoutFromBackend = 'Logout from backend';
|
|
1864
1878
|
const LoggingInToBackend = 'Logging in to backend';
|
|
1879
|
+
const LoggingOutFromBackend = 'Logging out from backend';
|
|
1880
|
+
const SignedIn = 'Signed in';
|
|
1865
1881
|
const SwitchToChatFocusMode = 'Switch to chat focus mode';
|
|
1866
1882
|
const SwitchToNormalChatMode = 'Switch to normal chat mode';
|
|
1867
1883
|
const CloseChat$1 = 'Close Chat';
|
|
@@ -1941,18 +1957,33 @@ const scrollDown = () => {
|
|
|
1941
1957
|
const searchModels = () => {
|
|
1942
1958
|
return i18nString(SearchModels);
|
|
1943
1959
|
};
|
|
1960
|
+
const pickModel = modelName => {
|
|
1961
|
+
return `${i18nString(PickModel)}, ${modelName}`;
|
|
1962
|
+
};
|
|
1944
1963
|
const searchChats = () => {
|
|
1945
1964
|
return i18nString(SearchChats);
|
|
1946
1965
|
};
|
|
1966
|
+
const login = () => {
|
|
1967
|
+
return i18nString(Login$1);
|
|
1968
|
+
};
|
|
1969
|
+
const logout = () => {
|
|
1970
|
+
return i18nString(Logout$1);
|
|
1971
|
+
};
|
|
1947
1972
|
const loginToBackend = () => {
|
|
1948
1973
|
return i18nString(LoginToBackend);
|
|
1949
1974
|
};
|
|
1950
|
-
const logoutFromBackend = () => {
|
|
1975
|
+
const logoutFromBackend$1 = () => {
|
|
1951
1976
|
return i18nString(LogoutFromBackend);
|
|
1952
1977
|
};
|
|
1953
1978
|
const loggingInToBackend = () => {
|
|
1954
1979
|
return i18nString(LoggingInToBackend);
|
|
1955
1980
|
};
|
|
1981
|
+
const loggingOutFromBackend = () => {
|
|
1982
|
+
return i18nString(LoggingOutFromBackend);
|
|
1983
|
+
};
|
|
1984
|
+
const signedIn = () => {
|
|
1985
|
+
return i18nString(SignedIn);
|
|
1986
|
+
};
|
|
1956
1987
|
const chatFocusMode = () => {
|
|
1957
1988
|
return i18nString(SwitchToChatFocusMode);
|
|
1958
1989
|
};
|
|
@@ -2324,8 +2355,6 @@ const createDefaultState = () => {
|
|
|
2324
2355
|
authAccessToken: '',
|
|
2325
2356
|
authEnabled: false,
|
|
2326
2357
|
authErrorMessage: '',
|
|
2327
|
-
authRefreshToken: '',
|
|
2328
|
-
authStatus: 'signed-out',
|
|
2329
2358
|
backendUrl: '',
|
|
2330
2359
|
chatFocusContentMaxWidth: 700,
|
|
2331
2360
|
chatHistoryEnabled: true,
|
|
@@ -2357,6 +2386,10 @@ const createDefaultState = () => {
|
|
|
2357
2386
|
errorCount: 0,
|
|
2358
2387
|
focus: 'composer',
|
|
2359
2388
|
focused: false,
|
|
2389
|
+
gitBranches: [],
|
|
2390
|
+
gitBranchPickerErrorMessage: '',
|
|
2391
|
+
gitBranchPickerOpen: false,
|
|
2392
|
+
gitBranchPickerVisible: false,
|
|
2360
2393
|
headerHeight: 50,
|
|
2361
2394
|
height: 0,
|
|
2362
2395
|
...responsivePickerState,
|
|
@@ -2443,6 +2476,7 @@ const createDefaultState = () => {
|
|
|
2443
2476
|
useChatToolWorker: true,
|
|
2444
2477
|
useMockApi: false,
|
|
2445
2478
|
userName: '',
|
|
2479
|
+
userState: 'loggedOut',
|
|
2446
2480
|
userSubscriptionPlan: '',
|
|
2447
2481
|
userUsedTokens: 0,
|
|
2448
2482
|
viewMode: 'list',
|
|
@@ -2829,7 +2863,24 @@ const isEqualComposerAttachments = (a, b) => {
|
|
|
2829
2863
|
}
|
|
2830
2864
|
return true;
|
|
2831
2865
|
};
|
|
2866
|
+
const isEqualGitBranches = (a, b) => {
|
|
2867
|
+
if (a === b) {
|
|
2868
|
+
return true;
|
|
2869
|
+
}
|
|
2870
|
+
if (a.length !== b.length) {
|
|
2871
|
+
return false;
|
|
2872
|
+
}
|
|
2873
|
+
for (let i = 0; i < a.length; i++) {
|
|
2874
|
+
if (a[i].current !== b[i].current || a[i].name !== b[i].name) {
|
|
2875
|
+
return false;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
return true;
|
|
2879
|
+
};
|
|
2832
2880
|
const isEqualProjectExpandedIds = (a, b) => {
|
|
2881
|
+
if (a === b) {
|
|
2882
|
+
return true;
|
|
2883
|
+
}
|
|
2833
2884
|
if (a.length !== b.length) {
|
|
2834
2885
|
return false;
|
|
2835
2886
|
}
|
|
@@ -2840,6 +2891,20 @@ const isEqualProjectExpandedIds = (a, b) => {
|
|
|
2840
2891
|
}
|
|
2841
2892
|
return true;
|
|
2842
2893
|
};
|
|
2894
|
+
const isEqualProjects = (a, b) => {
|
|
2895
|
+
if (a === b) {
|
|
2896
|
+
return true;
|
|
2897
|
+
}
|
|
2898
|
+
if (a.length !== b.length) {
|
|
2899
|
+
return false;
|
|
2900
|
+
}
|
|
2901
|
+
for (let i = 0; i < a.length; i++) {
|
|
2902
|
+
if (a[i].id !== b[i].id || a[i].name !== b[i].name || a[i].uri !== b[i].uri) {
|
|
2903
|
+
return false;
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
return true;
|
|
2907
|
+
};
|
|
2843
2908
|
const isEqualVisibleModels = (a, b) => {
|
|
2844
2909
|
if (a === b) {
|
|
2845
2910
|
return true;
|
|
@@ -2856,7 +2921,7 @@ const isEqualVisibleModels = (a, b) => {
|
|
|
2856
2921
|
};
|
|
2857
2922
|
|
|
2858
2923
|
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 &&
|
|
2924
|
+
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
2925
|
};
|
|
2861
2926
|
|
|
2862
2927
|
const diffScrollTop = (oldState, newState) => {
|
|
@@ -2877,6 +2942,12 @@ const RenderIncremental = 11;
|
|
|
2877
2942
|
const RenderScrollTop = 12;
|
|
2878
2943
|
|
|
2879
2944
|
const diffValue = (oldState, newState) => {
|
|
2945
|
+
if (oldState.openApiApiKeyInput !== newState.openApiApiKeyInput) {
|
|
2946
|
+
return false;
|
|
2947
|
+
}
|
|
2948
|
+
if (oldState.openRouterApiKeyInput !== newState.openRouterApiKeyInput) {
|
|
2949
|
+
return false;
|
|
2950
|
+
}
|
|
2880
2951
|
return oldState.composerValue === newState.composerValue || newState.inputSource !== 'script';
|
|
2881
2952
|
};
|
|
2882
2953
|
|
|
@@ -2907,10 +2978,9 @@ const getAuthState = state => {
|
|
|
2907
2978
|
authAccessToken,
|
|
2908
2979
|
authEnabled,
|
|
2909
2980
|
authErrorMessage,
|
|
2910
|
-
authRefreshToken,
|
|
2911
|
-
authStatus,
|
|
2912
2981
|
backendUrl,
|
|
2913
2982
|
userName,
|
|
2983
|
+
userState,
|
|
2914
2984
|
userSubscriptionPlan,
|
|
2915
2985
|
userUsedTokens
|
|
2916
2986
|
} = state;
|
|
@@ -2918,10 +2988,9 @@ const getAuthState = state => {
|
|
|
2918
2988
|
authAccessToken,
|
|
2919
2989
|
authEnabled,
|
|
2920
2990
|
authErrorMessage,
|
|
2921
|
-
authRefreshToken,
|
|
2922
|
-
authStatus,
|
|
2923
2991
|
backendUrl,
|
|
2924
2992
|
userName,
|
|
2993
|
+
userState,
|
|
2925
2994
|
userSubscriptionPlan,
|
|
2926
2995
|
userUsedTokens
|
|
2927
2996
|
};
|
|
@@ -3387,9 +3456,11 @@ const ComposerAttachmentPreviewOverlay = 'composer-attachment-preview-overlay';
|
|
|
3387
3456
|
const AddContext = 'add-context';
|
|
3388
3457
|
const Dictate = 'dictate';
|
|
3389
3458
|
const CreatePullRequest$1 = 'create-pull-request';
|
|
3459
|
+
const GitBranchPickerToggle = 'git-branch-picker-toggle';
|
|
3460
|
+
const GitBranchPickerItemPrefix = 'git-branch-picker-item:';
|
|
3390
3461
|
const FocusAddAction = 'focus-add-action';
|
|
3391
|
-
const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
3392
3462
|
const FocusCommit = 'focus-commit';
|
|
3463
|
+
const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
3393
3464
|
const FocusOpenTerminal = 'focus-open-terminal';
|
|
3394
3465
|
const FocusShowDiff = 'focus-show-diff';
|
|
3395
3466
|
const Send = 'send';
|
|
@@ -3458,6 +3529,15 @@ const getRenameIdFromInputName = name => {
|
|
|
3458
3529
|
const getModelPickerItemInputName = modelId => {
|
|
3459
3530
|
return `${ModelPickerItemPrefix}${modelId}`;
|
|
3460
3531
|
};
|
|
3532
|
+
const getGitBranchPickerItemInputName = branchName => {
|
|
3533
|
+
return `${GitBranchPickerItemPrefix}${branchName}`;
|
|
3534
|
+
};
|
|
3535
|
+
const isGitBranchPickerItemInputName = name => {
|
|
3536
|
+
return name.startsWith(GitBranchPickerItemPrefix);
|
|
3537
|
+
};
|
|
3538
|
+
const getGitBranchFromGitBranchPickerItemInputName = name => {
|
|
3539
|
+
return name.slice(GitBranchPickerItemPrefix.length);
|
|
3540
|
+
};
|
|
3461
3541
|
const getComposerAttachmentInputName = attachmentId => {
|
|
3462
3542
|
return `${ComposerAttachmentPrefix}${attachmentId}`;
|
|
3463
3543
|
};
|
|
@@ -3818,6 +3898,236 @@ const openFolder = async () => {
|
|
|
3818
3898
|
}
|
|
3819
3899
|
};
|
|
3820
3900
|
|
|
3901
|
+
// cspell:ignore gitdir worktrees
|
|
3902
|
+
const FileTypeFile = 1;
|
|
3903
|
+
const FileTypeDirectory = 2;
|
|
3904
|
+
const slashAtEndRegex = /\/$/;
|
|
3905
|
+
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3906
|
+
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
3907
|
+
const toGitUri = (baseUri, ...segments) => {
|
|
3908
|
+
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3909
|
+
for (const segment of segments) {
|
|
3910
|
+
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3911
|
+
}
|
|
3912
|
+
return url.toString();
|
|
3913
|
+
};
|
|
3914
|
+
const decodeFileContent = content => {
|
|
3915
|
+
if (typeof content === 'string') {
|
|
3916
|
+
return content;
|
|
3917
|
+
}
|
|
3918
|
+
if (content instanceof Uint8Array) {
|
|
3919
|
+
return new TextDecoder().decode(content);
|
|
3920
|
+
}
|
|
3921
|
+
if (Array.isArray(content)) {
|
|
3922
|
+
return new TextDecoder().decode(new Uint8Array(content));
|
|
3923
|
+
}
|
|
3924
|
+
return '';
|
|
3925
|
+
};
|
|
3926
|
+
const toFileSystemPath = uri => {
|
|
3927
|
+
if (!uri.startsWith('file://')) {
|
|
3928
|
+
return uri;
|
|
3929
|
+
}
|
|
3930
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
3931
|
+
};
|
|
3932
|
+
const getRelativePath = (fromPath, toPath) => {
|
|
3933
|
+
if (!fromPath.startsWith('/') || !toPath.startsWith('/')) {
|
|
3934
|
+
return toPath;
|
|
3935
|
+
}
|
|
3936
|
+
const fromParts = fromPath.split('/').filter(Boolean);
|
|
3937
|
+
const toParts = toPath.split('/').filter(Boolean);
|
|
3938
|
+
let commonPrefixLength = 0;
|
|
3939
|
+
while (commonPrefixLength < fromParts.length && commonPrefixLength < toParts.length && fromParts[commonPrefixLength] === toParts[commonPrefixLength]) {
|
|
3940
|
+
commonPrefixLength++;
|
|
3941
|
+
}
|
|
3942
|
+
const parentSegments = fromParts.slice(commonPrefixLength).map(() => '..');
|
|
3943
|
+
const childSegments = toParts.slice(commonPrefixLength);
|
|
3944
|
+
return [...parentSegments, ...childSegments].join('/') || '.';
|
|
3945
|
+
};
|
|
3946
|
+
const toFileSystemTarget = (workspaceUri, uri) => {
|
|
3947
|
+
const workspacePath = toFileSystemPath(workspaceUri);
|
|
3948
|
+
const fileSystemPath = toFileSystemPath(uri);
|
|
3949
|
+
if (!workspaceUri.startsWith('file://') || !uri.startsWith('file://')) {
|
|
3950
|
+
return fileSystemPath;
|
|
3951
|
+
}
|
|
3952
|
+
return getRelativePath(workspacePath, fileSystemPath);
|
|
3953
|
+
};
|
|
3954
|
+
const parseEntries = value => {
|
|
3955
|
+
if (!Array.isArray(value)) {
|
|
3956
|
+
return [];
|
|
3957
|
+
}
|
|
3958
|
+
return value.map(entry => {
|
|
3959
|
+
if (Array.isArray(entry) && typeof entry[0] === 'string' && typeof entry[1] === 'number') {
|
|
3960
|
+
return {
|
|
3961
|
+
name: entry[0],
|
|
3962
|
+
type: entry[1]
|
|
3963
|
+
};
|
|
3964
|
+
}
|
|
3965
|
+
if (entry && typeof entry === 'object' && typeof Reflect.get(entry, 'name') === 'string' && typeof Reflect.get(entry, 'type') === 'number') {
|
|
3966
|
+
return {
|
|
3967
|
+
name: Reflect.get(entry, 'name'),
|
|
3968
|
+
type: Reflect.get(entry, 'type')
|
|
3969
|
+
};
|
|
3970
|
+
}
|
|
3971
|
+
return undefined;
|
|
3972
|
+
}).filter(entry => !!entry);
|
|
3973
|
+
};
|
|
3974
|
+
const readDir = async (workspaceUri, uri) => {
|
|
3975
|
+
const result = await invoke('FileSystem.readDirWithFileTypes', toFileSystemTarget(workspaceUri, uri));
|
|
3976
|
+
return parseEntries(result);
|
|
3977
|
+
};
|
|
3978
|
+
const readTextFile = async (workspaceUri, uri) => {
|
|
3979
|
+
const result = await invoke('FileSystem.readFile', toFileSystemTarget(workspaceUri, uri));
|
|
3980
|
+
return decodeFileContent(result);
|
|
3981
|
+
};
|
|
3982
|
+
const getGitDirUri = async workspaceUri => {
|
|
3983
|
+
const gitUri = toGitUri(workspaceUri, '.git');
|
|
3984
|
+
try {
|
|
3985
|
+
await readTextFile(workspaceUri, toGitUri(gitUri, 'HEAD'));
|
|
3986
|
+
return gitUri;
|
|
3987
|
+
} catch {
|
|
3988
|
+
// Fall through to support worktrees/submodules where .git is a pointer file.
|
|
3989
|
+
}
|
|
3990
|
+
const gitPointer = await readTextFile(workspaceUri, gitUri);
|
|
3991
|
+
const match = gitDirPointerRegex.exec(gitPointer);
|
|
3992
|
+
if (!match) {
|
|
3993
|
+
return '';
|
|
3994
|
+
}
|
|
3995
|
+
return new URL(match[1].trim(), workspaceUri.endsWith('/') ? workspaceUri : `${workspaceUri}/`).toString();
|
|
3996
|
+
};
|
|
3997
|
+
const collectBranchNames = async (workspaceUri, refsHeadsUri, prefix, branches) => {
|
|
3998
|
+
const entries = await readDir(workspaceUri, refsHeadsUri);
|
|
3999
|
+
for (const entry of entries) {
|
|
4000
|
+
if (entry.type === FileTypeDirectory) {
|
|
4001
|
+
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
4002
|
+
continue;
|
|
4003
|
+
}
|
|
4004
|
+
if (entry.type === FileTypeFile) {
|
|
4005
|
+
branches.add(`${prefix}${entry.name}`);
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
};
|
|
4009
|
+
const parseCurrentBranch = headContent => {
|
|
4010
|
+
const match = headRefRegex.exec(headContent.trim());
|
|
4011
|
+
if (match) {
|
|
4012
|
+
return match[1].trim();
|
|
4013
|
+
}
|
|
4014
|
+
return '';
|
|
4015
|
+
};
|
|
4016
|
+
const hasGitRepository = async workspaceUri => {
|
|
4017
|
+
try {
|
|
4018
|
+
return Boolean(await getGitDirUri(workspaceUri));
|
|
4019
|
+
} catch {
|
|
4020
|
+
return false;
|
|
4021
|
+
}
|
|
4022
|
+
};
|
|
4023
|
+
const getGitBranches = async workspaceUri => {
|
|
4024
|
+
const gitDirUri = await getGitDirUri(workspaceUri);
|
|
4025
|
+
if (!gitDirUri) {
|
|
4026
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4027
|
+
throw new globalThis.Error('Git repository not found.');
|
|
4028
|
+
}
|
|
4029
|
+
const branches = new Set();
|
|
4030
|
+
let currentBranch = '';
|
|
4031
|
+
try {
|
|
4032
|
+
const headContent = await readTextFile(workspaceUri, toGitUri(gitDirUri, 'HEAD'));
|
|
4033
|
+
currentBranch = parseCurrentBranch(headContent);
|
|
4034
|
+
if (currentBranch) {
|
|
4035
|
+
branches.add(currentBranch);
|
|
4036
|
+
}
|
|
4037
|
+
} catch {
|
|
4038
|
+
// Keep trying to discover branches from refs even if HEAD cannot be read.
|
|
4039
|
+
}
|
|
4040
|
+
try {
|
|
4041
|
+
await collectBranchNames(workspaceUri, toGitUri(gitDirUri, 'refs', 'heads'), '', branches);
|
|
4042
|
+
} catch {
|
|
4043
|
+
// Repositories without local refs should still open and surface any current branch we found.
|
|
4044
|
+
}
|
|
4045
|
+
if (branches.size === 0) {
|
|
4046
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4047
|
+
throw new globalThis.Error('No local git branches found.');
|
|
4048
|
+
}
|
|
4049
|
+
return [...branches].toSorted((a, b) => a.localeCompare(b)).map(name => ({
|
|
4050
|
+
current: name === currentBranch,
|
|
4051
|
+
name
|
|
4052
|
+
}));
|
|
4053
|
+
};
|
|
4054
|
+
|
|
4055
|
+
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
4056
|
+
return sessions.find(session => session.id === selectedSessionId);
|
|
4057
|
+
};
|
|
4058
|
+
|
|
4059
|
+
const getProjectUri$1 = (state, projectId) => {
|
|
4060
|
+
return state.projects.find(project => project.id === projectId)?.uri || '';
|
|
4061
|
+
};
|
|
4062
|
+
const getWorkspaceUri$1 = (state, session) => {
|
|
4063
|
+
if (session?.workspaceUri) {
|
|
4064
|
+
return session.workspaceUri;
|
|
4065
|
+
}
|
|
4066
|
+
return getProjectUri$1(state, session?.projectId || state.selectedProjectId);
|
|
4067
|
+
};
|
|
4068
|
+
|
|
4069
|
+
const withHiddenBranchPicker = state => {
|
|
4070
|
+
return {
|
|
4071
|
+
...state,
|
|
4072
|
+
gitBranches: [],
|
|
4073
|
+
gitBranchPickerErrorMessage: '',
|
|
4074
|
+
gitBranchPickerOpen: false,
|
|
4075
|
+
gitBranchPickerVisible: false
|
|
4076
|
+
};
|
|
4077
|
+
};
|
|
4078
|
+
const refreshGitBranchPickerVisibility = async state => {
|
|
4079
|
+
if (state.viewMode !== 'chat-focus') {
|
|
4080
|
+
return {
|
|
4081
|
+
...state,
|
|
4082
|
+
gitBranchPickerErrorMessage: '',
|
|
4083
|
+
gitBranchPickerOpen: false
|
|
4084
|
+
};
|
|
4085
|
+
}
|
|
4086
|
+
const selectedSession = getSelectedSession(state.sessions, state.selectedSessionId);
|
|
4087
|
+
const fallbackBranchName = selectedSession?.branchName || '';
|
|
4088
|
+
const workspaceUri = getWorkspaceUri$1(state, selectedSession);
|
|
4089
|
+
if (!workspaceUri) {
|
|
4090
|
+
return withHiddenBranchPicker(state);
|
|
4091
|
+
}
|
|
4092
|
+
const visible = await hasGitRepository(workspaceUri);
|
|
4093
|
+
if (!visible) {
|
|
4094
|
+
if (fallbackBranchName) {
|
|
4095
|
+
return {
|
|
4096
|
+
...state,
|
|
4097
|
+
gitBranches: [{
|
|
4098
|
+
current: true,
|
|
4099
|
+
name: fallbackBranchName
|
|
4100
|
+
}],
|
|
4101
|
+
gitBranchPickerVisible: true
|
|
4102
|
+
};
|
|
4103
|
+
}
|
|
4104
|
+
return withHiddenBranchPicker(state);
|
|
4105
|
+
}
|
|
4106
|
+
try {
|
|
4107
|
+
const gitBranches = await getGitBranches(workspaceUri);
|
|
4108
|
+
return {
|
|
4109
|
+
...state,
|
|
4110
|
+
gitBranches,
|
|
4111
|
+
gitBranchPickerVisible: true
|
|
4112
|
+
};
|
|
4113
|
+
} catch {
|
|
4114
|
+
if (fallbackBranchName) {
|
|
4115
|
+
return {
|
|
4116
|
+
...state,
|
|
4117
|
+
gitBranches: [{
|
|
4118
|
+
current: true,
|
|
4119
|
+
name: fallbackBranchName
|
|
4120
|
+
}],
|
|
4121
|
+
gitBranchPickerVisible: true
|
|
4122
|
+
};
|
|
4123
|
+
}
|
|
4124
|
+
return {
|
|
4125
|
+
...state,
|
|
4126
|
+
gitBranchPickerVisible: true
|
|
4127
|
+
};
|
|
4128
|
+
}
|
|
4129
|
+
};
|
|
4130
|
+
|
|
3821
4131
|
const selectProject = async (state, projectId) => {
|
|
3822
4132
|
const {
|
|
3823
4133
|
selectedProjectId,
|
|
@@ -3831,14 +4141,14 @@ const selectProject = async (state, projectId) => {
|
|
|
3831
4141
|
}
|
|
3832
4142
|
const visibleSessions = getVisibleSessions(sessions, projectId);
|
|
3833
4143
|
if (visibleSessions.length === 0) {
|
|
3834
|
-
return {
|
|
4144
|
+
return refreshGitBranchPickerVisibility({
|
|
3835
4145
|
...state,
|
|
3836
4146
|
composerAttachments: [],
|
|
3837
4147
|
composerAttachmentsHeight: 0,
|
|
3838
4148
|
selectedProjectId: projectId,
|
|
3839
4149
|
selectedSessionId: '',
|
|
3840
4150
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'list'
|
|
3841
|
-
};
|
|
4151
|
+
});
|
|
3842
4152
|
}
|
|
3843
4153
|
const currentSessionVisible = visibleSessions.some(session => session.id === selectedSessionId);
|
|
3844
4154
|
const nextSelectedSessionId = currentSessionVisible ? selectedSessionId : visibleSessions[0].id;
|
|
@@ -3850,7 +4160,7 @@ const selectProject = async (state, projectId) => {
|
|
|
3850
4160
|
}
|
|
3851
4161
|
return loadedSession;
|
|
3852
4162
|
});
|
|
3853
|
-
return {
|
|
4163
|
+
return refreshGitBranchPickerVisibility({
|
|
3854
4164
|
...state,
|
|
3855
4165
|
composerAttachments,
|
|
3856
4166
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, width),
|
|
@@ -3858,7 +4168,7 @@ const selectProject = async (state, projectId) => {
|
|
|
3858
4168
|
selectedSessionId: nextSelectedSessionId,
|
|
3859
4169
|
sessions: hydratedSessions,
|
|
3860
4170
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
3861
|
-
};
|
|
4171
|
+
});
|
|
3862
4172
|
};
|
|
3863
4173
|
|
|
3864
4174
|
const fileSchemeRegex = /^file:\/\//;
|
|
@@ -3993,6 +4303,148 @@ const handleClickCreatePullRequest = async state => {
|
|
|
3993
4303
|
};
|
|
3994
4304
|
};
|
|
3995
4305
|
|
|
4306
|
+
const trailingSlashesRegex$3 = /\/+$/;
|
|
4307
|
+
const trimTrailingSlashes = value => {
|
|
4308
|
+
return value.replace(trailingSlashesRegex$3, '');
|
|
4309
|
+
};
|
|
4310
|
+
|
|
4311
|
+
const getBackendAuthUrl = (backendUrl, path) => {
|
|
4312
|
+
return `${trimTrailingSlashes(backendUrl)}${path}`;
|
|
4313
|
+
};
|
|
4314
|
+
|
|
4315
|
+
const getBackendLoginUrl = backendUrl => {
|
|
4316
|
+
return getBackendAuthUrl(backendUrl, '/auth/login');
|
|
4317
|
+
};
|
|
4318
|
+
|
|
4319
|
+
const getLoggedOutBackendAuthState = (authErrorMessage = '') => {
|
|
4320
|
+
return {
|
|
4321
|
+
authAccessToken: '',
|
|
4322
|
+
authErrorMessage,
|
|
4323
|
+
userName: '',
|
|
4324
|
+
userState: 'loggedOut',
|
|
4325
|
+
userSubscriptionPlan: '',
|
|
4326
|
+
userUsedTokens: 0
|
|
4327
|
+
};
|
|
4328
|
+
};
|
|
4329
|
+
|
|
4330
|
+
const getBackendLogoutUrl = backendUrl => {
|
|
4331
|
+
return getBackendAuthUrl(backendUrl, '/auth/logout');
|
|
4332
|
+
};
|
|
4333
|
+
|
|
4334
|
+
const logoutFromBackend = async backendUrl => {
|
|
4335
|
+
if (!backendUrl) {
|
|
4336
|
+
return;
|
|
4337
|
+
}
|
|
4338
|
+
try {
|
|
4339
|
+
await fetch(getBackendLogoutUrl(backendUrl), {
|
|
4340
|
+
credentials: 'include',
|
|
4341
|
+
headers: {
|
|
4342
|
+
Accept: 'application/json'
|
|
4343
|
+
},
|
|
4344
|
+
method: 'POST'
|
|
4345
|
+
});
|
|
4346
|
+
} catch {
|
|
4347
|
+
// Ignore logout failures and still clear local auth state.
|
|
4348
|
+
}
|
|
4349
|
+
};
|
|
4350
|
+
|
|
4351
|
+
const getBackendRefreshUrl = backendUrl => {
|
|
4352
|
+
return getBackendAuthUrl(backendUrl, '/auth/refresh');
|
|
4353
|
+
};
|
|
4354
|
+
|
|
4355
|
+
const isObject$2 = value => {
|
|
4356
|
+
return !!value && typeof value === 'object';
|
|
4357
|
+
};
|
|
4358
|
+
|
|
4359
|
+
const isBackendAuthResponse = value => {
|
|
4360
|
+
return isObject$2(value);
|
|
4361
|
+
};
|
|
4362
|
+
|
|
4363
|
+
const getNumber = (value, fallback = 0) => {
|
|
4364
|
+
return typeof value === 'number' ? value : fallback;
|
|
4365
|
+
};
|
|
4366
|
+
|
|
4367
|
+
const getString = (value, fallback = '') => {
|
|
4368
|
+
return typeof value === 'string' ? value : fallback;
|
|
4369
|
+
};
|
|
4370
|
+
|
|
4371
|
+
const toBackendAuthState = value => {
|
|
4372
|
+
return {
|
|
4373
|
+
authAccessToken: getString(value.accessToken),
|
|
4374
|
+
authErrorMessage: getString(value.error),
|
|
4375
|
+
userName: getString(value.userName),
|
|
4376
|
+
userState: value.accessToken ? 'loggedIn' : 'loggedOut',
|
|
4377
|
+
userSubscriptionPlan: getString(value.subscriptionPlan),
|
|
4378
|
+
userUsedTokens: getNumber(value.usedTokens)
|
|
4379
|
+
};
|
|
4380
|
+
};
|
|
4381
|
+
|
|
4382
|
+
const parseBackendAuthResponse = value => {
|
|
4383
|
+
if (!isBackendAuthResponse(value)) {
|
|
4384
|
+
return getLoggedOutBackendAuthState('Backend returned an invalid authentication response.');
|
|
4385
|
+
}
|
|
4386
|
+
return toBackendAuthState(value);
|
|
4387
|
+
};
|
|
4388
|
+
|
|
4389
|
+
const syncBackendAuth = async backendUrl => {
|
|
4390
|
+
if (!backendUrl) {
|
|
4391
|
+
return getLoggedOutBackendAuthState('Backend URL is missing.');
|
|
4392
|
+
}
|
|
4393
|
+
try {
|
|
4394
|
+
const response = await fetch(getBackendRefreshUrl(backendUrl), {
|
|
4395
|
+
credentials: 'include',
|
|
4396
|
+
headers: {
|
|
4397
|
+
Accept: 'application/json'
|
|
4398
|
+
},
|
|
4399
|
+
method: 'POST'
|
|
4400
|
+
});
|
|
4401
|
+
if (response.status === 401 || response.status === 403) {
|
|
4402
|
+
return getLoggedOutBackendAuthState();
|
|
4403
|
+
}
|
|
4404
|
+
let payload = undefined;
|
|
4405
|
+
try {
|
|
4406
|
+
payload = await response.json();
|
|
4407
|
+
} catch {
|
|
4408
|
+
payload = undefined;
|
|
4409
|
+
}
|
|
4410
|
+
if (!response.ok) {
|
|
4411
|
+
const parsed = parseBackendAuthResponse(payload);
|
|
4412
|
+
return getLoggedOutBackendAuthState(parsed.authErrorMessage || 'Backend authentication failed.');
|
|
4413
|
+
}
|
|
4414
|
+
const parsed = parseBackendAuthResponse(payload);
|
|
4415
|
+
if (parsed.authErrorMessage) {
|
|
4416
|
+
return getLoggedOutBackendAuthState(parsed.authErrorMessage);
|
|
4417
|
+
}
|
|
4418
|
+
if (!parsed.authAccessToken) {
|
|
4419
|
+
return getLoggedOutBackendAuthState();
|
|
4420
|
+
}
|
|
4421
|
+
return parsed;
|
|
4422
|
+
} catch (error) {
|
|
4423
|
+
const authErrorMessage = error instanceof Error && error.message ? error.message : 'Backend authentication failed.';
|
|
4424
|
+
return getLoggedOutBackendAuthState(authErrorMessage);
|
|
4425
|
+
}
|
|
4426
|
+
};
|
|
4427
|
+
|
|
4428
|
+
const delay = async ms => {
|
|
4429
|
+
await new Promise(resolve => setTimeout(resolve, ms));
|
|
4430
|
+
};
|
|
4431
|
+
|
|
4432
|
+
const waitForBackendLogin = async (backendUrl, timeoutMs = 30_000, pollIntervalMs = 1000) => {
|
|
4433
|
+
const deadline = Date.now() + timeoutMs;
|
|
4434
|
+
let lastErrorMessage = '';
|
|
4435
|
+
while (Date.now() < deadline) {
|
|
4436
|
+
const authState = await syncBackendAuth(backendUrl);
|
|
4437
|
+
if (authState.userState === 'loggedIn') {
|
|
4438
|
+
return authState;
|
|
4439
|
+
}
|
|
4440
|
+
if (authState.authErrorMessage) {
|
|
4441
|
+
lastErrorMessage = authState.authErrorMessage;
|
|
4442
|
+
}
|
|
4443
|
+
await delay(pollIntervalMs);
|
|
4444
|
+
}
|
|
4445
|
+
return getLoggedOutBackendAuthState(lastErrorMessage);
|
|
4446
|
+
};
|
|
4447
|
+
|
|
3996
4448
|
let nextLoginResponse;
|
|
3997
4449
|
const setNextLoginResponse = response => {
|
|
3998
4450
|
nextLoginResponse = response;
|
|
@@ -4016,35 +4468,36 @@ const consumeNextLoginResponse = async () => {
|
|
|
4016
4468
|
return response.response;
|
|
4017
4469
|
};
|
|
4018
4470
|
|
|
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
4471
|
const isLoginResponse = value => {
|
|
4028
4472
|
if (!value || typeof value !== 'object') {
|
|
4029
4473
|
return false;
|
|
4030
4474
|
}
|
|
4031
4475
|
return true;
|
|
4032
4476
|
};
|
|
4033
|
-
const
|
|
4034
|
-
|
|
4477
|
+
const getLoggedInState = (state, response) => {
|
|
4478
|
+
const accessToken = typeof response.accessToken === 'string' ? response.accessToken : '';
|
|
4479
|
+
return {
|
|
4480
|
+
...state,
|
|
4481
|
+
authAccessToken: accessToken,
|
|
4482
|
+
authErrorMessage: '',
|
|
4483
|
+
userName: typeof response.userName === 'string' ? response.userName : state.userName,
|
|
4484
|
+
userState: accessToken ? 'loggedIn' : 'loggedOut',
|
|
4485
|
+
userSubscriptionPlan: typeof response.subscriptionPlan === 'string' ? response.subscriptionPlan : state.userSubscriptionPlan,
|
|
4486
|
+
userUsedTokens: typeof response.usedTokens === 'number' ? response.usedTokens : state.userUsedTokens
|
|
4487
|
+
};
|
|
4035
4488
|
};
|
|
4036
4489
|
const handleClickLogin = async state => {
|
|
4037
4490
|
if (!state.backendUrl) {
|
|
4038
4491
|
return {
|
|
4039
4492
|
...state,
|
|
4040
4493
|
authErrorMessage: 'Backend URL is missing.',
|
|
4041
|
-
|
|
4494
|
+
userState: 'loggedOut'
|
|
4042
4495
|
};
|
|
4043
4496
|
}
|
|
4044
4497
|
const signingInState = {
|
|
4045
4498
|
...state,
|
|
4046
4499
|
authErrorMessage: '',
|
|
4047
|
-
|
|
4500
|
+
userState: 'loggingIn'
|
|
4048
4501
|
};
|
|
4049
4502
|
if (state.uid) {
|
|
4050
4503
|
set(state.uid, state, signingInState);
|
|
@@ -4053,69 +4506,53 @@ const handleClickLogin = async state => {
|
|
|
4053
4506
|
let usedMockResponse = false;
|
|
4054
4507
|
try {
|
|
4055
4508
|
usedMockResponse = hasPendingMockLoginResponse();
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4509
|
+
if (usedMockResponse) {
|
|
4510
|
+
const response = await consumeNextLoginResponse();
|
|
4511
|
+
if (!isLoginResponse(response)) {
|
|
4512
|
+
return {
|
|
4513
|
+
...signingInState,
|
|
4514
|
+
authErrorMessage: 'Backend returned an invalid login response.',
|
|
4515
|
+
userState: 'loggedOut'
|
|
4516
|
+
};
|
|
4517
|
+
}
|
|
4518
|
+
if (typeof response.error === 'string' && response.error) {
|
|
4519
|
+
return {
|
|
4520
|
+
...signingInState,
|
|
4521
|
+
authErrorMessage: response.error,
|
|
4522
|
+
userState: 'loggedOut'
|
|
4523
|
+
};
|
|
4524
|
+
}
|
|
4525
|
+
return getLoggedInState(signingInState, response);
|
|
4070
4526
|
}
|
|
4071
|
-
|
|
4072
|
-
const
|
|
4073
|
-
await update({
|
|
4074
|
-
'secrets.chatBackendAccessToken': accessToken,
|
|
4075
|
-
'secrets.chatBackendRefreshToken': refreshToken
|
|
4076
|
-
});
|
|
4527
|
+
await invoke('Main.openUri', getBackendLoginUrl(state.backendUrl));
|
|
4528
|
+
const authState = await waitForBackendLogin(state.backendUrl);
|
|
4077
4529
|
return {
|
|
4078
4530
|
...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
|
|
4531
|
+
...authState
|
|
4086
4532
|
};
|
|
4087
4533
|
} catch (error) {
|
|
4088
4534
|
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
4535
|
return {
|
|
4093
4536
|
...signingInState,
|
|
4094
|
-
|
|
4095
|
-
authStatus: 'signed-out'
|
|
4537
|
+
...getLoggedOutBackendAuthState(errorMessage)
|
|
4096
4538
|
};
|
|
4097
4539
|
}
|
|
4098
4540
|
};
|
|
4099
4541
|
|
|
4100
4542
|
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 {
|
|
4543
|
+
const loggingOutState = {
|
|
4111
4544
|
...state,
|
|
4112
|
-
authAccessToken: '',
|
|
4113
4545
|
authErrorMessage: '',
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4546
|
+
userState: 'loggingOut'
|
|
4547
|
+
};
|
|
4548
|
+
if (state.uid) {
|
|
4549
|
+
set(state.uid, state, loggingOutState);
|
|
4550
|
+
await invoke('Chat.rerender');
|
|
4551
|
+
}
|
|
4552
|
+
await logoutFromBackend(state.backendUrl);
|
|
4553
|
+
return {
|
|
4554
|
+
...loggingOutState,
|
|
4555
|
+
...getLoggedOutBackendAuthState()
|
|
4119
4556
|
};
|
|
4120
4557
|
};
|
|
4121
4558
|
|
|
@@ -4440,10 +4877,6 @@ const getClientRequestIdHeader = () => {
|
|
|
4440
4877
|
};
|
|
4441
4878
|
};
|
|
4442
4879
|
|
|
4443
|
-
const delay = async ms => {
|
|
4444
|
-
await new Promise(resolve => setTimeout(resolve, ms));
|
|
4445
|
-
};
|
|
4446
|
-
|
|
4447
4880
|
const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
4448
4881
|
await delay(delayInMs);
|
|
4449
4882
|
return `Mock AI response: I received "${userMessage}".`;
|
|
@@ -6830,7 +7263,12 @@ const ChatFocusActions = 'ChatFocusActions';
|
|
|
6830
7263
|
const ChatFocusHeader = 'ChatFocusHeader';
|
|
6831
7264
|
const ChatFocusMainArea = 'ChatFocusMainArea';
|
|
6832
7265
|
const ChatFocusProject = 'ChatFocusProject';
|
|
7266
|
+
const ChatGitBranchPicker = 'ChatGitBranchPicker';
|
|
7267
|
+
const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
|
|
7268
|
+
const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
|
|
6833
7269
|
const ChatHeader = 'ChatHeader';
|
|
7270
|
+
const ChatHeaderAuth = 'ChatHeaderAuth';
|
|
7271
|
+
const ChatHeaderAuthName = 'ChatHeaderAuthName';
|
|
6834
7272
|
const ChatHeaderLabel = 'ChatHeaderLabel';
|
|
6835
7273
|
const ChatInputBox = 'ChatInputBox';
|
|
6836
7274
|
const ChatList = 'ChatList';
|
|
@@ -6844,6 +7282,7 @@ const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
|
|
|
6844
7282
|
const ChatListItemStatusRow = 'ChatListItemStatusRow';
|
|
6845
7283
|
const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
|
|
6846
7284
|
const ChatMessageContent = 'ChatMessageContent';
|
|
7285
|
+
const ChatImageMessageContent = 'ChatImageMessageContent';
|
|
6847
7286
|
const ChatMessageLink = 'ChatMessageLink';
|
|
6848
7287
|
const ChatModelPicker = 'ChatModelPicker';
|
|
6849
7288
|
const ChatModelPickerContainer = 'ChatModelPickerContainer';
|
|
@@ -6878,6 +7317,7 @@ const ChatAttachmentLabel = 'ChatAttachmentLabel';
|
|
|
6878
7317
|
const ChatAttachmentPreview = 'ChatAttachmentPreview';
|
|
6879
7318
|
const ChatAttachments = 'ChatAttachments';
|
|
6880
7319
|
const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
|
|
7320
|
+
const ChatMessageImage = 'ChatMessageImage';
|
|
6881
7321
|
const ChatSendArea = 'ChatSendArea';
|
|
6882
7322
|
const ChatSendAreaBottom = 'ChatSendAreaBottom';
|
|
6883
7323
|
const ChatSendAreaContent = 'ChatSendAreaContent';
|
|
@@ -6915,6 +7355,7 @@ const IconButtonDisabled = 'IconButtonDisabled';
|
|
|
6915
7355
|
const ImageElement = 'ImageElement';
|
|
6916
7356
|
const ImageErrorMessage = 'ImageErrorMessage';
|
|
6917
7357
|
const InputBox = 'InputBox';
|
|
7358
|
+
const InputInvalid = 'InputInvalid';
|
|
6918
7359
|
const Insertion = 'Insertion';
|
|
6919
7360
|
const Label = 'Label';
|
|
6920
7361
|
const LabelDetail = 'LabelDetail';
|
|
@@ -6923,7 +7364,6 @@ const MarkdownMathBlock = 'MarkdownMathBlock';
|
|
|
6923
7364
|
const MarkdownQuote = 'MarkdownQuote';
|
|
6924
7365
|
const MarkdownTable = 'MarkdownTable';
|
|
6925
7366
|
const MaskIcon = 'MaskIcon';
|
|
6926
|
-
const MaskIconAccount = 'MaskIconAccount';
|
|
6927
7367
|
const MaskIconAdd = 'MaskIconAdd';
|
|
6928
7368
|
const MaskIconArrowLeft = 'MaskIconArrowLeft';
|
|
6929
7369
|
const MaskIconChevronDown = 'MaskIconChevronDown';
|
|
@@ -6934,7 +7374,6 @@ const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
|
6934
7374
|
const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
|
|
6935
7375
|
const MaskIconSearch = 'MaskIconSearch';
|
|
6936
7376
|
const MaskIconSettingsGear = 'MaskIconSettingsGear';
|
|
6937
|
-
const MaskIconSignOut = 'MaskIconSignOut';
|
|
6938
7377
|
const Message = 'Message';
|
|
6939
7378
|
const MessageAssistant = 'MessageAssistant';
|
|
6940
7379
|
const MessageUser = 'MessageUser';
|
|
@@ -8288,6 +8727,12 @@ const parseAndStoreMessageContent = async (parsedMessages, message) => {
|
|
|
8288
8727
|
const parsedContent = message.text === '' ? emptyMessageContent : await parseMessage(message.text);
|
|
8289
8728
|
return setParsedMessageContent(parsedMessages, message.id, message.text, parsedContent);
|
|
8290
8729
|
};
|
|
8730
|
+
const parseAndStoreMessageContentWithWorkerPreference = async (parsedMessages, message, useChatMessageParsingWorker) => {
|
|
8731
|
+
if (useChatMessageParsingWorker) {
|
|
8732
|
+
return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
|
|
8733
|
+
}
|
|
8734
|
+
return parseAndStoreMessageContent(parsedMessages, message);
|
|
8735
|
+
};
|
|
8291
8736
|
const parseAndStoreMessagesContent = async (parsedMessages, messages) => {
|
|
8292
8737
|
let nextParsedMessages = parsedMessages;
|
|
8293
8738
|
for (const message of messages) {
|
|
@@ -8320,8 +8765,15 @@ const parseAndStoreMessagesContentWithWorkerPreference = async (parsedMessages,
|
|
|
8320
8765
|
}
|
|
8321
8766
|
return parseAndStoreMessagesContent(parsedMessages, messages);
|
|
8322
8767
|
};
|
|
8323
|
-
const getEmptyMessageContent = () => {
|
|
8324
|
-
return emptyMessageContent;
|
|
8768
|
+
const getEmptyMessageContent = () => {
|
|
8769
|
+
return emptyMessageContent;
|
|
8770
|
+
};
|
|
8771
|
+
|
|
8772
|
+
const get = async key => {
|
|
8773
|
+
return getPreference(key);
|
|
8774
|
+
};
|
|
8775
|
+
const update = async settings => {
|
|
8776
|
+
await invoke('Preferences.update', settings);
|
|
8325
8777
|
};
|
|
8326
8778
|
|
|
8327
8779
|
const setOpenApiApiKey = async (state, openApiApiKey, persist = true) => {
|
|
@@ -8738,10 +9190,6 @@ const getNextHandleTextChunkState = (latestState, parsedMessages, sessions) => {
|
|
|
8738
9190
|
};
|
|
8739
9191
|
};
|
|
8740
9192
|
|
|
8741
|
-
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
8742
|
-
return sessions.find(session => session.id === selectedSessionId);
|
|
8743
|
-
};
|
|
8744
|
-
|
|
8745
9193
|
const setAndRerenderHandleTextChunkState = async (uid, previousState, nextState) => {
|
|
8746
9194
|
set(uid, previousState, nextState);
|
|
8747
9195
|
// @ts-ignore
|
|
@@ -8828,7 +9276,7 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
|
|
|
8828
9276
|
};
|
|
8829
9277
|
};
|
|
8830
9278
|
|
|
8831
|
-
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
|
|
9279
|
+
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress, useChatMessageParsingWorker) => {
|
|
8832
9280
|
let updatedMessage;
|
|
8833
9281
|
const updatedSessions = sessions.map(session => {
|
|
8834
9282
|
if (session.id !== selectedSessionId) {
|
|
@@ -8851,7 +9299,7 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
|
|
|
8851
9299
|
});
|
|
8852
9300
|
let nextParsedMessages = parsedMessages;
|
|
8853
9301
|
if (updatedMessage) {
|
|
8854
|
-
nextParsedMessages = await
|
|
9302
|
+
nextParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, updatedMessage, useChatMessageParsingWorker);
|
|
8855
9303
|
}
|
|
8856
9304
|
return {
|
|
8857
9305
|
parsedMessages: nextParsedMessages,
|
|
@@ -8874,7 +9322,7 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
|
|
|
8874
9322
|
};
|
|
8875
9323
|
}
|
|
8876
9324
|
const updatedText = assistantMessage.text + chunk;
|
|
8877
|
-
const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true);
|
|
9325
|
+
const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true, handleTextChunkState.latestState.useChatMessageParsingWorker);
|
|
8878
9326
|
const nextState = {
|
|
8879
9327
|
...handleTextChunkState.latestState,
|
|
8880
9328
|
...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
|
|
@@ -9040,6 +9488,11 @@ const withProvisionedBackgroundSession = async (state, session) => {
|
|
|
9040
9488
|
};
|
|
9041
9489
|
};
|
|
9042
9490
|
const handleSubmit = async state => {
|
|
9491
|
+
const authState = state.authEnabled && state.backendUrl ? await syncBackendAuth(state.backendUrl) : undefined;
|
|
9492
|
+
const effectiveState = authState ? {
|
|
9493
|
+
...state,
|
|
9494
|
+
...authState
|
|
9495
|
+
} : state;
|
|
9043
9496
|
const {
|
|
9044
9497
|
agentMode,
|
|
9045
9498
|
aiSessionTitleGenerationEnabled,
|
|
@@ -9068,27 +9521,28 @@ const handleSubmit = async state => {
|
|
|
9068
9521
|
streamingEnabled,
|
|
9069
9522
|
toolEnablement,
|
|
9070
9523
|
useChatCoordinatorWorker,
|
|
9524
|
+
useChatMessageParsingWorker,
|
|
9071
9525
|
useChatNetworkWorkerForRequests,
|
|
9072
9526
|
useChatToolWorker,
|
|
9073
9527
|
useMockApi,
|
|
9074
9528
|
viewMode,
|
|
9075
9529
|
webSearchEnabled
|
|
9076
|
-
} =
|
|
9530
|
+
} = effectiveState;
|
|
9077
9531
|
const userText = composerValue.trim();
|
|
9078
9532
|
if (!userText) {
|
|
9079
|
-
return
|
|
9533
|
+
return effectiveState;
|
|
9080
9534
|
}
|
|
9081
9535
|
const slashCommand = getSlashCommand(userText);
|
|
9082
9536
|
if (slashCommand) {
|
|
9083
|
-
return executeSlashCommand(
|
|
9537
|
+
return executeSlashCommand(effectiveState, slashCommand);
|
|
9084
9538
|
}
|
|
9085
9539
|
const userTime = new Date().toLocaleTimeString([], {
|
|
9086
9540
|
hour: '2-digit',
|
|
9087
9541
|
minute: '2-digit'
|
|
9088
9542
|
});
|
|
9089
9543
|
const userMessageId = crypto.randomUUID();
|
|
9090
|
-
const composerAttachments =
|
|
9091
|
-
await clearComposerAttachments(
|
|
9544
|
+
const composerAttachments = effectiveState.composerAttachments.length > 0 ? effectiveState.composerAttachments : await getComposerAttachments(effectiveState.selectedSessionId);
|
|
9545
|
+
await clearComposerAttachments(effectiveState.selectedSessionId, composerAttachments.map(attachment => attachment.attachmentId));
|
|
9092
9546
|
const userMessage = {
|
|
9093
9547
|
...(composerAttachments.length > 0 ? {
|
|
9094
9548
|
attachments: composerAttachments
|
|
@@ -9112,9 +9566,9 @@ const handleSubmit = async state => {
|
|
|
9112
9566
|
};
|
|
9113
9567
|
let {
|
|
9114
9568
|
parsedMessages
|
|
9115
|
-
} =
|
|
9116
|
-
parsedMessages = await
|
|
9117
|
-
parsedMessages = await
|
|
9569
|
+
} = effectiveState;
|
|
9570
|
+
parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, userMessage, useChatMessageParsingWorker);
|
|
9571
|
+
parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, inProgressAssistantMessage, useChatMessageParsingWorker);
|
|
9118
9572
|
let workingSessions = sessions;
|
|
9119
9573
|
if (viewMode === 'detail') {
|
|
9120
9574
|
const loadedSession = await getChatSession(selectedSessionId);
|
|
@@ -9146,10 +9600,10 @@ const handleSubmit = async state => {
|
|
|
9146
9600
|
const provisionedSession = await withProvisionedBackgroundSession(state, newSession);
|
|
9147
9601
|
await saveChatSession(provisionedSession);
|
|
9148
9602
|
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
9149
|
-
...
|
|
9603
|
+
...effectiveState,
|
|
9150
9604
|
composerAttachments: [],
|
|
9151
9605
|
composerAttachmentsHeight: 0,
|
|
9152
|
-
composerHeight: getMinComposerHeightForState(
|
|
9606
|
+
composerHeight: getMinComposerHeightForState(effectiveState),
|
|
9153
9607
|
composerSelectionEnd: 0,
|
|
9154
9608
|
composerSelectionStart: 0,
|
|
9155
9609
|
composerValue: '',
|
|
@@ -9185,10 +9639,10 @@ const handleSubmit = async state => {
|
|
|
9185
9639
|
await saveChatSession(selectedSession);
|
|
9186
9640
|
}
|
|
9187
9641
|
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
9188
|
-
...
|
|
9642
|
+
...effectiveState,
|
|
9189
9643
|
composerAttachments: [],
|
|
9190
9644
|
composerAttachmentsHeight: 0,
|
|
9191
|
-
composerHeight: getMinComposerHeightForState(
|
|
9645
|
+
composerHeight: getMinComposerHeightForState(effectiveState),
|
|
9192
9646
|
composerSelectionEnd: 0,
|
|
9193
9647
|
composerSelectionStart: 0,
|
|
9194
9648
|
composerValue: '',
|
|
@@ -9200,7 +9654,7 @@ const handleSubmit = async state => {
|
|
|
9200
9654
|
}));
|
|
9201
9655
|
optimisticState = withUpdatedChatInputHistory(optimisticState, userText);
|
|
9202
9656
|
}
|
|
9203
|
-
set(
|
|
9657
|
+
set(effectiveState.uid, effectiveState, optimisticState);
|
|
9204
9658
|
// @ts-ignore
|
|
9205
9659
|
await invoke('Chat.rerender');
|
|
9206
9660
|
let handleTextChunkState = {
|
|
@@ -9289,11 +9743,11 @@ const handleSubmit = async state => {
|
|
|
9289
9743
|
let finalParsedMessages = latestState.parsedMessages;
|
|
9290
9744
|
let updatedSessions;
|
|
9291
9745
|
if (streamingEnabled) {
|
|
9292
|
-
const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false);
|
|
9746
|
+
const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false, latestState.useChatMessageParsingWorker);
|
|
9293
9747
|
updatedSessions = updated.sessions;
|
|
9294
9748
|
finalParsedMessages = updated.parsedMessages;
|
|
9295
9749
|
} else {
|
|
9296
|
-
finalParsedMessages = await
|
|
9750
|
+
finalParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(finalParsedMessages, assistantMessage, latestState.useChatMessageParsingWorker);
|
|
9297
9751
|
updatedSessions = appendMessageToSelectedSession(latestState.sessions, latestState.selectedSessionId, assistantMessage);
|
|
9298
9752
|
}
|
|
9299
9753
|
if (aiSessionTitleGenerationEnabled && createsNewSession) {
|
|
@@ -9322,6 +9776,84 @@ const handleClickSend = async state => {
|
|
|
9322
9776
|
return handleSubmit(state);
|
|
9323
9777
|
};
|
|
9324
9778
|
|
|
9779
|
+
const SwitchGitBranch = 'Chat.switchGitBranch';
|
|
9780
|
+
const switchGitBranch = async ({
|
|
9781
|
+
assetDir,
|
|
9782
|
+
branchName,
|
|
9783
|
+
platform,
|
|
9784
|
+
workspaceUri
|
|
9785
|
+
}) => {
|
|
9786
|
+
await executeProvider({
|
|
9787
|
+
assetDir,
|
|
9788
|
+
event: `onCommand:${SwitchGitBranch}`,
|
|
9789
|
+
method: CommandExecute,
|
|
9790
|
+
noProviderFoundMessage: 'No git branch switch command found',
|
|
9791
|
+
params: [SwitchGitBranch, {
|
|
9792
|
+
branchName,
|
|
9793
|
+
workspaceUri
|
|
9794
|
+
}],
|
|
9795
|
+
platform
|
|
9796
|
+
});
|
|
9797
|
+
};
|
|
9798
|
+
|
|
9799
|
+
const getGitBranchSwitchErrorMessage = (branchName, error) => {
|
|
9800
|
+
if (error instanceof Error && error.message) {
|
|
9801
|
+
return `Failed to switch to branch "${branchName}". ${error.message}`;
|
|
9802
|
+
}
|
|
9803
|
+
return `Failed to switch to branch "${branchName}".`;
|
|
9804
|
+
};
|
|
9805
|
+
const handleGitBranchChange = async (state, branchName) => {
|
|
9806
|
+
if (!branchName) {
|
|
9807
|
+
return state;
|
|
9808
|
+
}
|
|
9809
|
+
const selectedSession = getSelectedSession(state.sessions, state.selectedSessionId);
|
|
9810
|
+
const workspaceUri = getWorkspaceUri$1(state, selectedSession);
|
|
9811
|
+
if (!workspaceUri) {
|
|
9812
|
+
return {
|
|
9813
|
+
...state,
|
|
9814
|
+
gitBranchPickerErrorMessage: 'No workspace is selected.',
|
|
9815
|
+
gitBranchPickerOpen: true
|
|
9816
|
+
};
|
|
9817
|
+
}
|
|
9818
|
+
try {
|
|
9819
|
+
await switchGitBranch({
|
|
9820
|
+
assetDir: state.assetDir,
|
|
9821
|
+
branchName,
|
|
9822
|
+
platform: state.platform,
|
|
9823
|
+
workspaceUri
|
|
9824
|
+
});
|
|
9825
|
+
const updatedSessions = state.sessions.map(session => {
|
|
9826
|
+
if (session.id !== state.selectedSessionId) {
|
|
9827
|
+
return session;
|
|
9828
|
+
}
|
|
9829
|
+
return {
|
|
9830
|
+
...session,
|
|
9831
|
+
branchName
|
|
9832
|
+
};
|
|
9833
|
+
});
|
|
9834
|
+
const updatedSelectedSession = updatedSessions.find(session => session.id === state.selectedSessionId);
|
|
9835
|
+
if (updatedSelectedSession) {
|
|
9836
|
+
await saveChatSession(updatedSelectedSession);
|
|
9837
|
+
}
|
|
9838
|
+
return {
|
|
9839
|
+
...state,
|
|
9840
|
+
gitBranches: state.gitBranches.map(branch => ({
|
|
9841
|
+
...branch,
|
|
9842
|
+
current: branch.name === branchName
|
|
9843
|
+
})),
|
|
9844
|
+
gitBranchPickerErrorMessage: '',
|
|
9845
|
+
gitBranchPickerOpen: false,
|
|
9846
|
+
sessions: updatedSessions
|
|
9847
|
+
};
|
|
9848
|
+
} catch (error) {
|
|
9849
|
+
return {
|
|
9850
|
+
...state,
|
|
9851
|
+
gitBranchPickerErrorMessage: getGitBranchSwitchErrorMessage(branchName, error),
|
|
9852
|
+
gitBranchPickerOpen: true
|
|
9853
|
+
};
|
|
9854
|
+
}
|
|
9855
|
+
};
|
|
9856
|
+
|
|
9325
9857
|
const setReasoningEffort = (state, reasoningEffort) => {
|
|
9326
9858
|
return {
|
|
9327
9859
|
...state,
|
|
@@ -9452,7 +9984,7 @@ const selectSession = async (state, id) => {
|
|
|
9452
9984
|
}
|
|
9453
9985
|
return loadedSession;
|
|
9454
9986
|
});
|
|
9455
|
-
return {
|
|
9987
|
+
return refreshGitBranchPickerVisibility({
|
|
9456
9988
|
...state,
|
|
9457
9989
|
composerAttachments,
|
|
9458
9990
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, width),
|
|
@@ -9461,7 +9993,7 @@ const selectSession = async (state, id) => {
|
|
|
9461
9993
|
selectedSessionId: id,
|
|
9462
9994
|
sessions: hydratedSessions,
|
|
9463
9995
|
viewMode: viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
9464
|
-
};
|
|
9996
|
+
});
|
|
9465
9997
|
};
|
|
9466
9998
|
|
|
9467
9999
|
const startRename = (state, id) => {
|
|
@@ -9491,15 +10023,17 @@ const toggleChatFocusMode = async state => {
|
|
|
9491
10023
|
if (viewMode === 'chat-focus') {
|
|
9492
10024
|
return {
|
|
9493
10025
|
...state,
|
|
10026
|
+
gitBranchPickerErrorMessage: '',
|
|
10027
|
+
gitBranchPickerOpen: false,
|
|
9494
10028
|
viewMode: lastNormalViewMode
|
|
9495
10029
|
};
|
|
9496
10030
|
}
|
|
9497
10031
|
if (viewMode === 'list' || viewMode === 'detail') {
|
|
9498
|
-
return {
|
|
10032
|
+
return refreshGitBranchPickerVisibility({
|
|
9499
10033
|
...state,
|
|
9500
10034
|
lastNormalViewMode: viewMode,
|
|
9501
10035
|
viewMode: 'chat-focus'
|
|
9502
|
-
};
|
|
10036
|
+
});
|
|
9503
10037
|
}
|
|
9504
10038
|
return state;
|
|
9505
10039
|
};
|
|
@@ -9629,6 +10163,11 @@ const handleClick = async (state, name, id = '', eventX = 0, eventY = 0) => {
|
|
|
9629
10163
|
visibleModels: state.models
|
|
9630
10164
|
};
|
|
9631
10165
|
}
|
|
10166
|
+
case isGitBranchPickerItemInputName(name):
|
|
10167
|
+
{
|
|
10168
|
+
const branchName = getGitBranchFromGitBranchPickerItemInputName(name);
|
|
10169
|
+
return handleGitBranchChange(state, branchName);
|
|
10170
|
+
}
|
|
9632
10171
|
case isAgentModePickerItemInputName(name):
|
|
9633
10172
|
{
|
|
9634
10173
|
const agentMode = getAgentModeFromAgentModePickerItemInputName(name);
|
|
@@ -9753,6 +10292,71 @@ const handleClickFileName = async (state, uri) => {
|
|
|
9753
10292
|
return state;
|
|
9754
10293
|
};
|
|
9755
10294
|
|
|
10295
|
+
const getBranchPickerErrorMessage = error => {
|
|
10296
|
+
if (error instanceof Error && error.message) {
|
|
10297
|
+
return error.message;
|
|
10298
|
+
}
|
|
10299
|
+
return 'Failed to load git branches.';
|
|
10300
|
+
};
|
|
10301
|
+
const openGitBranchPicker = async state => {
|
|
10302
|
+
const visibleState = await refreshGitBranchPickerVisibility(state);
|
|
10303
|
+
const selectedSession = getSelectedSession(visibleState.sessions, visibleState.selectedSessionId);
|
|
10304
|
+
const fallbackBranchName = selectedSession?.branchName || '';
|
|
10305
|
+
if (visibleState.viewMode !== 'chat-focus' || !visibleState.gitBranchPickerVisible && !fallbackBranchName) {
|
|
10306
|
+
return {
|
|
10307
|
+
...visibleState,
|
|
10308
|
+
gitBranchPickerOpen: false
|
|
10309
|
+
};
|
|
10310
|
+
}
|
|
10311
|
+
const workspaceUri = getWorkspaceUri$1(visibleState, selectedSession);
|
|
10312
|
+
if (!workspaceUri) {
|
|
10313
|
+
return {
|
|
10314
|
+
...visibleState,
|
|
10315
|
+
gitBranches: [],
|
|
10316
|
+
gitBranchPickerErrorMessage: 'No workspace is selected.',
|
|
10317
|
+
gitBranchPickerOpen: true
|
|
10318
|
+
};
|
|
10319
|
+
}
|
|
10320
|
+
try {
|
|
10321
|
+
const gitBranches = await getGitBranches(workspaceUri);
|
|
10322
|
+
return {
|
|
10323
|
+
...visibleState,
|
|
10324
|
+
agentModePickerOpen: false,
|
|
10325
|
+
gitBranches,
|
|
10326
|
+
gitBranchPickerErrorMessage: '',
|
|
10327
|
+
gitBranchPickerOpen: true,
|
|
10328
|
+
modelPickerOpen: false,
|
|
10329
|
+
modelPickerSearchValue: '',
|
|
10330
|
+
reasoningEffortPickerOpen: false,
|
|
10331
|
+
runModePickerOpen: false,
|
|
10332
|
+
visibleModels: visibleState.models
|
|
10333
|
+
};
|
|
10334
|
+
} catch (error) {
|
|
10335
|
+
return {
|
|
10336
|
+
...visibleState,
|
|
10337
|
+
agentModePickerOpen: false,
|
|
10338
|
+
gitBranches: fallbackBranchName ? [{
|
|
10339
|
+
current: true,
|
|
10340
|
+
name: fallbackBranchName
|
|
10341
|
+
}] : [],
|
|
10342
|
+
gitBranchPickerErrorMessage: getBranchPickerErrorMessage(error),
|
|
10343
|
+
gitBranchPickerOpen: true,
|
|
10344
|
+
modelPickerOpen: false,
|
|
10345
|
+
modelPickerSearchValue: '',
|
|
10346
|
+
reasoningEffortPickerOpen: false,
|
|
10347
|
+
runModePickerOpen: false,
|
|
10348
|
+
visibleModels: visibleState.models
|
|
10349
|
+
};
|
|
10350
|
+
}
|
|
10351
|
+
};
|
|
10352
|
+
|
|
10353
|
+
const handleClickGitBranchPickerToggle = async state => {
|
|
10354
|
+
if (state.gitBranchPickerOpen) {
|
|
10355
|
+
return closeGitBranchPicker(state);
|
|
10356
|
+
}
|
|
10357
|
+
return openGitBranchPicker(state);
|
|
10358
|
+
};
|
|
10359
|
+
|
|
9756
10360
|
const handleClickModelPickerList = async (state, eventY) => {
|
|
9757
10361
|
const {
|
|
9758
10362
|
height,
|
|
@@ -10615,19 +11219,6 @@ const getSavedSessions = savedState => {
|
|
|
10615
11219
|
return sessions;
|
|
10616
11220
|
};
|
|
10617
11221
|
|
|
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
11222
|
const getSavedViewMode = savedState => {
|
|
10632
11223
|
if (!isObject$1(savedState)) {
|
|
10633
11224
|
return undefined;
|
|
@@ -10659,24 +11250,6 @@ const loadAuthEnabled = async () => {
|
|
|
10659
11250
|
}
|
|
10660
11251
|
};
|
|
10661
11252
|
|
|
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
11253
|
const loadBackendUrl = async () => {
|
|
10681
11254
|
try {
|
|
10682
11255
|
const savedBackendUrl = await get('chat.backendUrl');
|
|
@@ -10857,12 +11430,10 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
10857
11430
|
};
|
|
10858
11431
|
|
|
10859
11432
|
const loadPreferences = async () => {
|
|
10860
|
-
const [aiSessionTitleGenerationEnabled,
|
|
11433
|
+
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
11434
|
return {
|
|
10862
11435
|
aiSessionTitleGenerationEnabled,
|
|
10863
|
-
authAccessToken,
|
|
10864
11436
|
authEnabled,
|
|
10865
|
-
authRefreshToken,
|
|
10866
11437
|
backendUrl,
|
|
10867
11438
|
chatHistoryEnabled,
|
|
10868
11439
|
composerDropEnabled,
|
|
@@ -10934,9 +11505,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10934
11505
|
const [composerSelectionStart, composerSelectionEnd] = savedComposerSelection ?? [state.composerSelectionStart, state.composerSelectionEnd];
|
|
10935
11506
|
const {
|
|
10936
11507
|
aiSessionTitleGenerationEnabled,
|
|
10937
|
-
authAccessToken,
|
|
10938
11508
|
authEnabled,
|
|
10939
|
-
authRefreshToken,
|
|
10940
11509
|
backendUrl,
|
|
10941
11510
|
chatHistoryEnabled,
|
|
10942
11511
|
composerDropEnabled,
|
|
@@ -10952,11 +11521,13 @@ const loadContent = async (state, savedState) => {
|
|
|
10952
11521
|
toolEnablement,
|
|
10953
11522
|
useChatCoordinatorWorker,
|
|
10954
11523
|
useChatMathWorker,
|
|
10955
|
-
useChatMessageParsingWorker,
|
|
11524
|
+
// useChatMessageParsingWorker,
|
|
10956
11525
|
useChatNetworkWorkerForRequests,
|
|
10957
11526
|
useChatToolWorker,
|
|
10958
11527
|
voiceDictationEnabled
|
|
10959
11528
|
} = await loadPreferences();
|
|
11529
|
+
const useChatMessageParsingWorker = true;
|
|
11530
|
+
const authState = authEnabled && backendUrl ? await syncBackendAuth(backendUrl) : getLoggedOutBackendAuthState();
|
|
10960
11531
|
const legacySavedSessions = getSavedSessions(savedState);
|
|
10961
11532
|
const storedSessions = await listChatSessions();
|
|
10962
11533
|
let sessions = storedSessions;
|
|
@@ -10992,7 +11563,6 @@ const loadContent = async (state, savedState) => {
|
|
|
10992
11563
|
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
10993
11564
|
const reasoningEffort = getSavedReasoningEffort(savedState) ?? state.reasoningEffort;
|
|
10994
11565
|
const selectedModelId = state.models.some(model => model.id === preferredModelId) ? preferredModelId : state.models[0]?.id || '';
|
|
10995
|
-
const systemPrompt = getSavedSystemPrompt(savedState) ?? state.systemPrompt;
|
|
10996
11566
|
const visibleModels = getVisibleModels(state.models, '');
|
|
10997
11567
|
const visibleSessions = getVisibleSessions(sessions, selectedProjectId);
|
|
10998
11568
|
const selectedSessionId = visibleSessions.some(session => session.id === preferredSessionId) ? preferredSessionId : visibleSessions[0]?.id || '';
|
|
@@ -11008,15 +11578,14 @@ const loadContent = async (state, savedState) => {
|
|
|
11008
11578
|
const savedLastNormalViewMode = getSavedLastNormalViewMode(savedState);
|
|
11009
11579
|
const lastNormalViewMode = savedLastNormalViewMode || (preferredViewMode === 'detail' ? 'detail' : state.lastNormalViewMode);
|
|
11010
11580
|
const viewMode = sessions.length === 0 || !selectedSessionId ? 'list' : preferredViewMode;
|
|
11011
|
-
|
|
11581
|
+
const nextState = {
|
|
11012
11582
|
...state,
|
|
11013
11583
|
agentMode,
|
|
11014
11584
|
agentModePickerOpen: false,
|
|
11015
11585
|
aiSessionTitleGenerationEnabled,
|
|
11016
|
-
authAccessToken,
|
|
11586
|
+
authAccessToken: authState.authAccessToken,
|
|
11017
11587
|
authEnabled,
|
|
11018
|
-
|
|
11019
|
-
authStatus: authAccessToken ? 'signed-in' : 'signed-out',
|
|
11588
|
+
authErrorMessage: authState.authErrorMessage,
|
|
11020
11589
|
backendUrl,
|
|
11021
11590
|
chatHistoryEnabled,
|
|
11022
11591
|
chatListScrollTop,
|
|
@@ -11057,7 +11626,6 @@ const loadContent = async (state, savedState) => {
|
|
|
11057
11626
|
selectedSessionId,
|
|
11058
11627
|
sessions,
|
|
11059
11628
|
streamingEnabled,
|
|
11060
|
-
systemPrompt,
|
|
11061
11629
|
todoListToolEnabled,
|
|
11062
11630
|
toolEnablement,
|
|
11063
11631
|
useChatCoordinatorWorker,
|
|
@@ -11065,10 +11633,15 @@ const loadContent = async (state, savedState) => {
|
|
|
11065
11633
|
useChatMessageParsingWorker,
|
|
11066
11634
|
useChatNetworkWorkerForRequests,
|
|
11067
11635
|
useChatToolWorker,
|
|
11636
|
+
userName: authState.userName,
|
|
11637
|
+
userState: authState.userState,
|
|
11638
|
+
userSubscriptionPlan: authState.userSubscriptionPlan,
|
|
11639
|
+
userUsedTokens: authState.userUsedTokens,
|
|
11068
11640
|
viewMode,
|
|
11069
11641
|
visibleModels,
|
|
11070
11642
|
voiceDictationEnabled
|
|
11071
11643
|
};
|
|
11644
|
+
return refreshGitBranchPickerVisibility(nextState);
|
|
11072
11645
|
};
|
|
11073
11646
|
|
|
11074
11647
|
const isObject = value => {
|
|
@@ -11158,7 +11731,24 @@ const openMockProject = async (state, projectId, projectName, projectUri) => {
|
|
|
11158
11731
|
};
|
|
11159
11732
|
};
|
|
11160
11733
|
|
|
11161
|
-
const
|
|
11734
|
+
const applySessionOptions = (session, options) => {
|
|
11735
|
+
if (!options) {
|
|
11736
|
+
return session;
|
|
11737
|
+
}
|
|
11738
|
+
return {
|
|
11739
|
+
...session,
|
|
11740
|
+
...(options.branchName ? {
|
|
11741
|
+
branchName: options.branchName
|
|
11742
|
+
} : {}),
|
|
11743
|
+
...(options.projectId ? {
|
|
11744
|
+
projectId: options.projectId
|
|
11745
|
+
} : {}),
|
|
11746
|
+
...(options.workspaceUri ? {
|
|
11747
|
+
workspaceUri: options.workspaceUri
|
|
11748
|
+
} : {})
|
|
11749
|
+
};
|
|
11750
|
+
};
|
|
11751
|
+
const openMockSession = async (state, mockSessionId, mockChatMessages, options) => {
|
|
11162
11752
|
const {
|
|
11163
11753
|
sessions: currentSessions
|
|
11164
11754
|
} = state;
|
|
@@ -11171,20 +11761,20 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
|
|
|
11171
11761
|
if (session.id !== mockSessionId) {
|
|
11172
11762
|
return session;
|
|
11173
11763
|
}
|
|
11174
|
-
return {
|
|
11764
|
+
return applySessionOptions({
|
|
11175
11765
|
...session,
|
|
11176
11766
|
messages: mockChatMessages
|
|
11177
|
-
};
|
|
11178
|
-
}) : [...currentSessions, {
|
|
11767
|
+
}, options);
|
|
11768
|
+
}) : [...currentSessions, applySessionOptions({
|
|
11179
11769
|
id: mockSessionId,
|
|
11180
11770
|
messages: mockChatMessages,
|
|
11181
11771
|
title: mockSessionId
|
|
11182
|
-
}];
|
|
11772
|
+
}, options)];
|
|
11183
11773
|
const selectedSession = sessions.find(session => session.id === mockSessionId);
|
|
11184
11774
|
if (selectedSession) {
|
|
11185
11775
|
await saveChatSession(selectedSession);
|
|
11186
11776
|
}
|
|
11187
|
-
return {
|
|
11777
|
+
return refreshGitBranchPickerVisibility({
|
|
11188
11778
|
...state,
|
|
11189
11779
|
composerAttachments: [],
|
|
11190
11780
|
composerAttachmentsHeight: 0,
|
|
@@ -11193,7 +11783,7 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
|
|
|
11193
11783
|
selectedSessionId: mockSessionId,
|
|
11194
11784
|
sessions,
|
|
11195
11785
|
viewMode: 'detail'
|
|
11196
|
-
};
|
|
11786
|
+
});
|
|
11197
11787
|
};
|
|
11198
11788
|
|
|
11199
11789
|
const pasteInput = async state => {
|
|
@@ -11306,6 +11896,10 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11306
11896
|
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
11307
11897
|
}
|
|
11308
11898
|
|
|
11899
|
+
.InputInvalid{
|
|
11900
|
+
border-color: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground));
|
|
11901
|
+
}
|
|
11902
|
+
|
|
11309
11903
|
.ChatComposerAttachmentTextFile{
|
|
11310
11904
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
11311
11905
|
}
|
|
@@ -11360,6 +11954,23 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11360
11954
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
11361
11955
|
}
|
|
11362
11956
|
|
|
11957
|
+
.ChatImageMessageContent{
|
|
11958
|
+
padding: 6px;
|
|
11959
|
+
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
11960
|
+
border-radius: 12px;
|
|
11961
|
+
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
11962
|
+
overflow: hidden;
|
|
11963
|
+
}
|
|
11964
|
+
|
|
11965
|
+
.ChatMessageImage{
|
|
11966
|
+
display: block;
|
|
11967
|
+
max-width: min(320px, 100%);
|
|
11968
|
+
max-height: min(320px, calc(100vh - 220px));
|
|
11969
|
+
border-radius: 8px;
|
|
11970
|
+
object-fit: contain;
|
|
11971
|
+
background: color-mix(in srgb, var(--vscode-editor-background) 88%, black);
|
|
11972
|
+
}
|
|
11973
|
+
|
|
11363
11974
|
.Chat{
|
|
11364
11975
|
position: relative;
|
|
11365
11976
|
}
|
|
@@ -11403,6 +12014,14 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11403
12014
|
|
|
11404
12015
|
}
|
|
11405
12016
|
|
|
12017
|
+
.ChatGitBranchPickerMessage{
|
|
12018
|
+
padding: 6px 8px;
|
|
12019
|
+
}
|
|
12020
|
+
|
|
12021
|
+
.ChatGitBranchPickerErrorMessage{
|
|
12022
|
+
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
12023
|
+
}
|
|
12024
|
+
|
|
11406
12025
|
.RunModePickerContainer{
|
|
11407
12026
|
display: flex;
|
|
11408
12027
|
justify-content: flex-end;
|
|
@@ -11507,13 +12126,10 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11507
12126
|
.ChatFocus .ChatMessages > .Message > .ChatMessageContent{
|
|
11508
12127
|
max-inline-size: 100%;
|
|
11509
12128
|
}
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
12129
|
.Viewlet.Chat.ChatFocus{
|
|
11513
12130
|
display: flex !important;
|
|
11514
12131
|
min-width: 0;
|
|
11515
12132
|
}
|
|
11516
|
-
|
|
11517
12133
|
.ChatFocusMainArea{
|
|
11518
12134
|
display: flex;
|
|
11519
12135
|
flex: 1;
|
|
@@ -11525,7 +12141,6 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
11525
12141
|
flex: 1;
|
|
11526
12142
|
min-height: 0;
|
|
11527
12143
|
}
|
|
11528
|
-
|
|
11529
12144
|
`;
|
|
11530
12145
|
return `${baseCss}
|
|
11531
12146
|
|
|
@@ -11670,7 +12285,8 @@ const HandlePointerUpModelPickerList = 55;
|
|
|
11670
12285
|
const HandleClickReasoningEffortPickerToggle = 56;
|
|
11671
12286
|
const HandleClickAgentModePickerToggle = 57;
|
|
11672
12287
|
const HandleContextMenuChatImageAttachment = 58;
|
|
11673
|
-
const
|
|
12288
|
+
const HandleClickGitBranchPickerToggle = 59;
|
|
12289
|
+
const HandleErrorComposerAttachmentPreviewOverlay = 60;
|
|
11674
12290
|
|
|
11675
12291
|
const getAddContextButtonDom = () => {
|
|
11676
12292
|
return [{
|
|
@@ -11685,10 +12301,12 @@ const getAddContextButtonDom = () => {
|
|
|
11685
12301
|
}];
|
|
11686
12302
|
};
|
|
11687
12303
|
|
|
11688
|
-
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label) => {
|
|
12304
|
+
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
|
|
11689
12305
|
return [{
|
|
11690
12306
|
'aria-expanded': open ? 'true' : 'false',
|
|
11691
12307
|
'aria-haspopup': 'true',
|
|
12308
|
+
'aria-label': ariaLabel,
|
|
12309
|
+
ariaLabel,
|
|
11692
12310
|
childCount: 2,
|
|
11693
12311
|
className: Select,
|
|
11694
12312
|
inputType: 'button',
|
|
@@ -11711,12 +12329,12 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
|
|
|
11711
12329
|
}];
|
|
11712
12330
|
};
|
|
11713
12331
|
|
|
11714
|
-
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, containerChildCount = 1) => {
|
|
12332
|
+
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, containerChildCount = 1) => {
|
|
11715
12333
|
return [{
|
|
11716
12334
|
childCount: containerChildCount,
|
|
11717
12335
|
className: CustomSelectContainer,
|
|
11718
12336
|
type: Div
|
|
11719
|
-
}, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title)];
|
|
12337
|
+
}, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel)];
|
|
11720
12338
|
};
|
|
11721
12339
|
|
|
11722
12340
|
const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) => {
|
|
@@ -11726,7 +12344,8 @@ const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) =>
|
|
|
11726
12344
|
const getChatModelPickerToggleVirtualDom = (models, selectedModelId, modelPickerOpen) => {
|
|
11727
12345
|
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
11728
12346
|
const selectedModelLabel = selectedModel ? selectedModel.name : selectedModelId;
|
|
11729
|
-
|
|
12347
|
+
const pickModelLabel = pickModel(selectedModelLabel);
|
|
12348
|
+
return getCustomSelectPickerToggleVirtualDom(selectedModelLabel, ModelPickerToggle, modelPickerOpen, HandleClickModelPickerToggle, pickModelLabel, pickModelLabel);
|
|
11730
12349
|
};
|
|
11731
12350
|
|
|
11732
12351
|
const getCreatePullRequestButtonDom = () => {
|
|
@@ -11770,6 +12389,55 @@ const getCustomSelectOptionVirtualDom = (name, label, selected, detail = '') =>
|
|
|
11770
12389
|
}, text(detail)] : [])];
|
|
11771
12390
|
};
|
|
11772
12391
|
|
|
12392
|
+
const itemHeight = 28;
|
|
12393
|
+
const messageHeight = 32;
|
|
12394
|
+
const getCurrentBranchLabel = (gitBranches, fallbackBranchName) => {
|
|
12395
|
+
const currentBranch = gitBranches.find(branch => branch.current);
|
|
12396
|
+
if (currentBranch) {
|
|
12397
|
+
return currentBranch.name;
|
|
12398
|
+
}
|
|
12399
|
+
if (fallbackBranchName) {
|
|
12400
|
+
return fallbackBranchName;
|
|
12401
|
+
}
|
|
12402
|
+
return 'Branch';
|
|
12403
|
+
};
|
|
12404
|
+
const getBranchOptionsVirtualDom = gitBranches => {
|
|
12405
|
+
return gitBranches.flatMap(branch => {
|
|
12406
|
+
return getCustomSelectOptionVirtualDom(getGitBranchPickerItemInputName(branch.name), branch.name, branch.current, branch.current ? 'current' : '');
|
|
12407
|
+
});
|
|
12408
|
+
};
|
|
12409
|
+
const getBranchPickerMessageDom = (gitBranches, errorMessage) => {
|
|
12410
|
+
const message = errorMessage || (gitBranches.length === 0 ? 'No local git branches found.' : '');
|
|
12411
|
+
if (!message) {
|
|
12412
|
+
return [];
|
|
12413
|
+
}
|
|
12414
|
+
return [{
|
|
12415
|
+
childCount: 1,
|
|
12416
|
+
className: mergeClassNames(ChatGitBranchPickerMessage, errorMessage ? ChatGitBranchPickerErrorMessage : Empty),
|
|
12417
|
+
type: Div
|
|
12418
|
+
}, {
|
|
12419
|
+
text: message,
|
|
12420
|
+
type: Text
|
|
12421
|
+
}];
|
|
12422
|
+
};
|
|
12423
|
+
const getGitBranchPickerVirtualDom = (gitBranches, gitBranchPickerOpen, gitBranchPickerErrorMessage, fallbackBranchName) => {
|
|
12424
|
+
const label = getCurrentBranchLabel(gitBranches, fallbackBranchName);
|
|
12425
|
+
const branchOptions = getBranchOptionsVirtualDom(gitBranches);
|
|
12426
|
+
const messageDom = getBranchPickerMessageDom(gitBranches, gitBranchPickerErrorMessage);
|
|
12427
|
+
const showMessage = messageDom.length > 0;
|
|
12428
|
+
const popOverHeight = gitBranches.length * itemHeight + (showMessage ? messageHeight : 0);
|
|
12429
|
+
return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch', gitBranchPickerOpen ? 2 : 1), ...(gitBranchPickerOpen ? [{
|
|
12430
|
+
childCount: (showMessage ? 1 : 0) + 1,
|
|
12431
|
+
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver, ChatGitBranchPicker),
|
|
12432
|
+
style: `height: ${popOverHeight}px;`,
|
|
12433
|
+
type: Div
|
|
12434
|
+
}, ...messageDom, {
|
|
12435
|
+
childCount: branchOptions.length / 4,
|
|
12436
|
+
className: ChatModelPickerList,
|
|
12437
|
+
type: Ul
|
|
12438
|
+
}, ...branchOptions] : [])];
|
|
12439
|
+
};
|
|
12440
|
+
|
|
11773
12441
|
const reasoningEffortPickerHeight = reasoningEfforts.length * 28;
|
|
11774
12442
|
const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
|
|
11775
12443
|
return reasoningEfforts.flatMap(reasoningEffort => {
|
|
@@ -11779,7 +12447,7 @@ const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
|
|
|
11779
12447
|
});
|
|
11780
12448
|
};
|
|
11781
12449
|
const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEffortPickerOpen) => {
|
|
11782
|
-
return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
|
|
12450
|
+
return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
|
|
11783
12451
|
childCount: 1,
|
|
11784
12452
|
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver),
|
|
11785
12453
|
style: `height: ${reasoningEffortPickerHeight}px;`,
|
|
@@ -11946,6 +12614,7 @@ const getComposerAttachmentClassName = displayType => {
|
|
|
11946
12614
|
};
|
|
11947
12615
|
const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
11948
12616
|
return [{
|
|
12617
|
+
'aria-label': removeAttachment(),
|
|
11949
12618
|
buttonType: 'button',
|
|
11950
12619
|
childCount: 1,
|
|
11951
12620
|
className: ChatComposerAttachmentRemoveButton,
|
|
@@ -12017,12 +12686,13 @@ const getComposerTextAreaDom = () => {
|
|
|
12017
12686
|
type: TextArea
|
|
12018
12687
|
};
|
|
12019
12688
|
};
|
|
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) => {
|
|
12689
|
+
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
12690
|
const isSendDisabled = composerValue.trim() === '';
|
|
12022
12691
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
12692
|
+
const showGitBranchPicker = gitBranchPickerVisible || Boolean(fallbackBranchName);
|
|
12023
12693
|
const showResponsiveRunModePicker = showRunMode && hasSpaceForRunModePicker;
|
|
12024
12694
|
const showScrollDownButton = scrollDownButtonEnabled && !messagesAutoScrollEnabled;
|
|
12025
|
-
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
12695
|
+
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (showGitBranchPicker ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
12026
12696
|
const primaryControlsCount = 1 + (showAgentModePicker ? 1 : 0) + (reasoningPickerEnabled ? 1 : 0) + (showResponsiveRunModePicker ? 1 : 0);
|
|
12027
12697
|
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
12028
12698
|
const hasComposerAttachments = composerAttachments.length > 0;
|
|
@@ -12046,7 +12716,62 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
|
|
|
12046
12716
|
className: ChatSendAreaPrimaryControls,
|
|
12047
12717
|
role: 'toolbar',
|
|
12048
12718
|
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)];
|
|
12719
|
+
}, ...(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)];
|
|
12720
|
+
};
|
|
12721
|
+
|
|
12722
|
+
const authContainerStyle = 'align-items:center;display:flex;gap:8px;min-width:0;';
|
|
12723
|
+
const authNameStyle = 'max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
12724
|
+
const authButtonStyle = 'white-space:nowrap;';
|
|
12725
|
+
const getButtonLabel = (userState, isAuthenticated) => {
|
|
12726
|
+
if (userState === 'loggingIn') {
|
|
12727
|
+
return loggingInToBackend();
|
|
12728
|
+
}
|
|
12729
|
+
if (userState === 'loggingOut') {
|
|
12730
|
+
return loggingOutFromBackend();
|
|
12731
|
+
}
|
|
12732
|
+
return isAuthenticated ? logout() : login();
|
|
12733
|
+
};
|
|
12734
|
+
const getButtonTitle = (userState, isAuthenticated) => {
|
|
12735
|
+
if (userState === 'loggingIn') {
|
|
12736
|
+
return loggingInToBackend();
|
|
12737
|
+
}
|
|
12738
|
+
if (userState === 'loggingOut') {
|
|
12739
|
+
return loggingOutFromBackend();
|
|
12740
|
+
}
|
|
12741
|
+
return isAuthenticated ? logoutFromBackend$1() : loginToBackend();
|
|
12742
|
+
};
|
|
12743
|
+
const getChatHeaderAuthDom = (authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
12744
|
+
if (!authEnabled) {
|
|
12745
|
+
return [];
|
|
12746
|
+
}
|
|
12747
|
+
const isAuthenticated = userState === 'loggedIn' || userState === 'loggingOut';
|
|
12748
|
+
const buttonName = isAuthenticated ? Logout : Login;
|
|
12749
|
+
const buttonLabel = getButtonLabel(userState, isAuthenticated);
|
|
12750
|
+
const buttonTitle = getButtonTitle(userState, isAuthenticated);
|
|
12751
|
+
const isPending = userState === 'loggingIn' || userState === 'loggingOut';
|
|
12752
|
+
const displayName = userName || signedIn();
|
|
12753
|
+
return [{
|
|
12754
|
+
childCount: isAuthenticated ? 2 : 1,
|
|
12755
|
+
className: ChatHeaderAuth,
|
|
12756
|
+
style: authContainerStyle,
|
|
12757
|
+
type: Div
|
|
12758
|
+
}, ...(isAuthenticated ? [{
|
|
12759
|
+
childCount: 1,
|
|
12760
|
+
className: ChatHeaderAuthName,
|
|
12761
|
+
style: authNameStyle,
|
|
12762
|
+
title: displayName,
|
|
12763
|
+
type: Span
|
|
12764
|
+
}, text(displayName)] : []), {
|
|
12765
|
+
childCount: 1,
|
|
12766
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
12767
|
+
disabled: isPending,
|
|
12768
|
+
inputType: 'button',
|
|
12769
|
+
name: buttonName,
|
|
12770
|
+
onClick: HandleClick,
|
|
12771
|
+
style: authButtonStyle,
|
|
12772
|
+
title: buttonTitle,
|
|
12773
|
+
type: Button$1
|
|
12774
|
+
}, text(buttonLabel)];
|
|
12050
12775
|
};
|
|
12051
12776
|
|
|
12052
12777
|
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 +12792,15 @@ const getFocusHeaderActionButtonDom = (label, name) => {
|
|
|
12067
12792
|
type: Button$1
|
|
12068
12793
|
}, text(label)];
|
|
12069
12794
|
};
|
|
12070
|
-
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName) => {
|
|
12795
|
+
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
12071
12796
|
const items = [[addAction(), FocusAddAction], [openInVsCode(), FocusOpenInVsCode], [commit(), FocusCommit], [openTerminal(), FocusOpenTerminal], [showDiff(), FocusShowDiff]];
|
|
12072
12797
|
const hasProjectName = !!selectedProjectName;
|
|
12073
12798
|
return [{
|
|
12074
|
-
childCount: 2,
|
|
12799
|
+
childCount: 2 + (authEnabled ? 1 : 0),
|
|
12075
12800
|
className: ChatFocusHeader,
|
|
12076
12801
|
style: focusHeaderStyle,
|
|
12077
12802
|
type: Header
|
|
12078
|
-
}, {
|
|
12803
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
12079
12804
|
childCount: hasProjectName ? 2 : 1,
|
|
12080
12805
|
className: ChatName,
|
|
12081
12806
|
style: focusHeaderMetaStyle,
|
|
@@ -12658,6 +13383,7 @@ const getMissingApiActionsDom = ({
|
|
|
12658
13383
|
};
|
|
12659
13384
|
const getMissingApiKeyDom = ({
|
|
12660
13385
|
getApiKeyText,
|
|
13386
|
+
inputClassName,
|
|
12661
13387
|
inputName,
|
|
12662
13388
|
inputPattern,
|
|
12663
13389
|
inputRequired = false,
|
|
@@ -12680,7 +13406,7 @@ const getMissingApiKeyDom = ({
|
|
|
12680
13406
|
autocomplete: 'off',
|
|
12681
13407
|
autocorrect: 'off',
|
|
12682
13408
|
childCount: 0,
|
|
12683
|
-
className: InputBox,
|
|
13409
|
+
className: inputClassName ? mergeClassNames(InputBox, inputClassName) : InputBox,
|
|
12684
13410
|
name: inputName,
|
|
12685
13411
|
onInput: HandleInput,
|
|
12686
13412
|
...(inputPattern ? {
|
|
@@ -12700,13 +13426,17 @@ const getMissingApiKeyDom = ({
|
|
|
12700
13426
|
})];
|
|
12701
13427
|
};
|
|
12702
13428
|
|
|
12703
|
-
const getMissingOpenApiApiKeyDom = (openApiApiKeyState = 'idle', openSettingsUrl = 'https://platform.openai.com/api-keys', inputPattern = '^sk-.+') => {
|
|
13429
|
+
const getMissingOpenApiApiKeyDom = (openApiApiKeyInput = '', openApiApiKeyState = 'idle', openSettingsUrl = 'https://platform.openai.com/api-keys', inputPattern = '^sk-.+') => {
|
|
12704
13430
|
const isSaving = openApiApiKeyState === 'saving';
|
|
13431
|
+
const isInvalid = openApiApiKeyInput !== '' && !new RegExp(inputPattern).test(openApiApiKeyInput);
|
|
12705
13432
|
return getMissingApiKeyDom({
|
|
12706
13433
|
getApiKeyText: getOpenApiApiKey(),
|
|
13434
|
+
...(isInvalid ? {
|
|
13435
|
+
inputClassName: InputInvalid
|
|
13436
|
+
} : {}),
|
|
12707
13437
|
inputName: OpenApiApiKeyInput,
|
|
12708
13438
|
inputPattern,
|
|
12709
|
-
inputRequired:
|
|
13439
|
+
inputRequired: false,
|
|
12710
13440
|
onSubmit: HandleMissingOpenAiApiKeyFormSubmit,
|
|
12711
13441
|
openSettingsButtonName: OpenOpenApiApiKeyWebsite,
|
|
12712
13442
|
openSettingsUrl,
|
|
@@ -13696,14 +14426,27 @@ const getChatAttachmentsDom = attachments => {
|
|
|
13696
14426
|
}];
|
|
13697
14427
|
})];
|
|
13698
14428
|
};
|
|
13699
|
-
const
|
|
14429
|
+
const getStandaloneImageAttachmentDom = attachment => {
|
|
14430
|
+
if (!attachment.previewSrc) {
|
|
14431
|
+
return getChatAttachmentsDom([attachment]);
|
|
14432
|
+
}
|
|
14433
|
+
return [{
|
|
14434
|
+
alt: attachment.name,
|
|
14435
|
+
childCount: 0,
|
|
14436
|
+
className: ChatMessageImage,
|
|
14437
|
+
src: attachment.previewSrc,
|
|
14438
|
+
type: Img
|
|
14439
|
+
}];
|
|
14440
|
+
};
|
|
14441
|
+
const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput, openApiApiKeyInput = '', openApiApiKeyState = 'idle', openApiApiKeysSettingsUrl = 'https://platform.openai.com/api-keys', openApiApiKeyInputPattern = '^sk-.+', openRouterApiKeyState = 'idle', useChatMathWorker = false, standaloneImageAttachment) => {
|
|
13700
14442
|
const roleClassName = message.role === 'user' ? MessageUser : MessageAssistant;
|
|
13701
14443
|
const isOpenApiApiKeyMissingMessage = message.role === 'assistant' && message.text === openApiApiKeyRequiredMessage;
|
|
13702
14444
|
const isOpenRouterApiKeyMissingMessage = message.role === 'assistant' && message.text === openRouterApiKeyRequiredMessage;
|
|
13703
14445
|
const isOpenRouterRequestFailedMessage = message.role === 'assistant' && message.text === openRouterRequestFailedMessage;
|
|
13704
14446
|
const isOpenRouterTooManyRequestsMessage = message.role === 'assistant' && message.text.startsWith(openRouterTooManyRequestsMessage);
|
|
13705
|
-
const
|
|
13706
|
-
const
|
|
14447
|
+
const isStandaloneImageMessage = !!standaloneImageAttachment;
|
|
14448
|
+
const messageDom = isStandaloneImageMessage ? getStandaloneImageAttachmentDom(standaloneImageAttachment) : getMessageContentDom(parsedMessageContent, useChatMathWorker);
|
|
14449
|
+
const attachmentsDom = !isStandaloneImageMessage && message.role === 'user' ? getChatAttachmentsDom(message.attachments ?? []) : [];
|
|
13707
14450
|
const toolCallsDom = getToolCallsDom(message);
|
|
13708
14451
|
const toolCallsChildCount = toolCallsDom.length > 0 ? 1 : 0;
|
|
13709
14452
|
const messageDomChildCount = getTopLevelNodeCount(messageDom);
|
|
@@ -13715,9 +14458,9 @@ const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput
|
|
|
13715
14458
|
type: Div
|
|
13716
14459
|
}, {
|
|
13717
14460
|
childCount: extraChildCount,
|
|
13718
|
-
className: ChatMessageContent,
|
|
14461
|
+
className: isStandaloneImageMessage ? mergeClassNames(ChatMessageContent, ChatImageMessageContent) : ChatMessageContent,
|
|
13719
14462
|
type: Div
|
|
13720
|
-
}, ...toolCallsDom, ...messageDom, ...attachmentsDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
14463
|
+
}, ...toolCallsDom, ...messageDom, ...attachmentsDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
13721
14464
|
};
|
|
13722
14465
|
|
|
13723
14466
|
const parentNode$1 = {
|
|
@@ -13733,6 +14476,22 @@ const getEmptyMessagesDom = () => {
|
|
|
13733
14476
|
const hasMessageText = message => {
|
|
13734
14477
|
return message.text.trim().length > 0;
|
|
13735
14478
|
};
|
|
14479
|
+
const isImageAttachment = attachment => {
|
|
14480
|
+
return attachment.displayType === 'image';
|
|
14481
|
+
};
|
|
14482
|
+
const withAttachments = (message, attachments) => {
|
|
14483
|
+
const {
|
|
14484
|
+
attachments: _attachments,
|
|
14485
|
+
...messageWithoutAttachments
|
|
14486
|
+
} = message;
|
|
14487
|
+
if (attachments.length === 0) {
|
|
14488
|
+
return messageWithoutAttachments;
|
|
14489
|
+
}
|
|
14490
|
+
return {
|
|
14491
|
+
...messageWithoutAttachments,
|
|
14492
|
+
attachments
|
|
14493
|
+
};
|
|
14494
|
+
};
|
|
13736
14495
|
const getDisplayMessages = (messages, parsedMessages) => {
|
|
13737
14496
|
const displayMessages = [];
|
|
13738
14497
|
for (const message of messages) {
|
|
@@ -13740,6 +14499,30 @@ const getDisplayMessages = (messages, parsedMessages) => {
|
|
|
13740
14499
|
if (!parsedContent) {
|
|
13741
14500
|
continue;
|
|
13742
14501
|
}
|
|
14502
|
+
if (message.role === 'user') {
|
|
14503
|
+
const attachments = message.attachments ?? [];
|
|
14504
|
+
const imageAttachments = attachments.filter(isImageAttachment);
|
|
14505
|
+
if (imageAttachments.length > 0) {
|
|
14506
|
+
const nonImageAttachments = attachments.filter(attachment => !isImageAttachment(attachment));
|
|
14507
|
+
if (hasMessageText(message) || nonImageAttachments.length > 0) {
|
|
14508
|
+
displayMessages.push({
|
|
14509
|
+
message: withAttachments(message, nonImageAttachments),
|
|
14510
|
+
parsedContent: hasMessageText(message) ? parsedContent : getEmptyMessageContent()
|
|
14511
|
+
});
|
|
14512
|
+
}
|
|
14513
|
+
for (const attachment of imageAttachments) {
|
|
14514
|
+
displayMessages.push({
|
|
14515
|
+
message: {
|
|
14516
|
+
...withAttachments(message, [attachment]),
|
|
14517
|
+
text: ''
|
|
14518
|
+
},
|
|
14519
|
+
parsedContent: getEmptyMessageContent(),
|
|
14520
|
+
standaloneImageAttachment: attachment
|
|
14521
|
+
});
|
|
14522
|
+
}
|
|
14523
|
+
continue;
|
|
14524
|
+
}
|
|
14525
|
+
}
|
|
13743
14526
|
if (message.role !== 'assistant' || !message.toolCalls || message.toolCalls.length === 0) {
|
|
13744
14527
|
displayMessages.push({
|
|
13745
14528
|
message,
|
|
@@ -13795,7 +14578,7 @@ const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApi
|
|
|
13795
14578
|
role: 'log',
|
|
13796
14579
|
scrollTop: messagesScrollTop,
|
|
13797
14580
|
type: Div
|
|
13798
|
-
}, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker))];
|
|
14581
|
+
}, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker, item.standaloneImageAttachment))];
|
|
13799
14582
|
};
|
|
13800
14583
|
|
|
13801
14584
|
const arrowLeft$1 = {
|
|
@@ -13909,7 +14692,6 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13909
14692
|
agentModePickerOpen = false,
|
|
13910
14693
|
authEnabled = false,
|
|
13911
14694
|
authErrorMessage = '',
|
|
13912
|
-
authStatus = 'signed-out',
|
|
13913
14695
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
13914
14696
|
composerAttachmentPreviewOverlayError = false,
|
|
13915
14697
|
composerAttachments,
|
|
@@ -13920,6 +14702,10 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13920
14702
|
composerHeight = 28,
|
|
13921
14703
|
composerLineHeight = 20,
|
|
13922
14704
|
composerValue,
|
|
14705
|
+
gitBranches,
|
|
14706
|
+
gitBranchPickerErrorMessage,
|
|
14707
|
+
gitBranchPickerOpen,
|
|
14708
|
+
gitBranchPickerVisible,
|
|
13923
14709
|
hasSpaceForAgentModePicker,
|
|
13924
14710
|
hasSpaceForRunModePicker,
|
|
13925
14711
|
messagesAutoScrollEnabled,
|
|
@@ -13954,14 +14740,15 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13954
14740
|
tokensUsed,
|
|
13955
14741
|
usageOverviewEnabled,
|
|
13956
14742
|
useChatMathWorker = false,
|
|
14743
|
+
userName = '',
|
|
14744
|
+
userState = 'loggedOut',
|
|
13957
14745
|
visibleModels = models,
|
|
13958
14746
|
voiceDictationEnabled = false
|
|
13959
14747
|
}) => {
|
|
13960
14748
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
13961
|
-
const selectedProject = projects.find(project => project.id === selectedProjectId);
|
|
13962
|
-
const messages = selectedSession ? selectedSession.messages : [];
|
|
13963
14749
|
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
13964
|
-
const selectedProjectName =
|
|
14750
|
+
const selectedProjectName = projects.find(project => project.id === selectedProjectId)?.name || '';
|
|
14751
|
+
const messages = selectedSession ? selectedSession.messages : [];
|
|
13965
14752
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13966
14753
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
13967
14754
|
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
@@ -13980,7 +14767,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13980
14767
|
childCount: 3,
|
|
13981
14768
|
className: ChatFocusMainArea,
|
|
13982
14769
|
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({
|
|
14770
|
+
}, ...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
14771
|
agentMode,
|
|
13985
14772
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13986
14773
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14033,31 +14820,8 @@ const getHeaderActionVirtualDom = item => {
|
|
|
14033
14820
|
}];
|
|
14034
14821
|
};
|
|
14035
14822
|
|
|
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) => {
|
|
14823
|
+
const getChatHeaderActionsDom = (viewMode, searchEnabled = false) => {
|
|
14059
14824
|
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
14060
|
-
const authAction = getAuthAction(authEnabled, authStatus);
|
|
14061
14825
|
const items = [{
|
|
14062
14826
|
icon: mergeClassNames(MaskIcon, MaskIconLayoutPanelLeft),
|
|
14063
14827
|
name: ToggleChatFocus,
|
|
@@ -14083,7 +14847,7 @@ const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'si
|
|
|
14083
14847
|
name: Settings,
|
|
14084
14848
|
onClick: HandleClickSettings,
|
|
14085
14849
|
title: settings()
|
|
14086
|
-
},
|
|
14850
|
+
}, {
|
|
14087
14851
|
icon: mergeClassNames(MaskIcon, MaskIconClose),
|
|
14088
14852
|
name: CloseChat,
|
|
14089
14853
|
onClick: HandleClickClose,
|
|
@@ -14108,14 +14872,14 @@ const getAuthErrorDom = (hasAuthError, authErrorMessage) => {
|
|
|
14108
14872
|
type: Span
|
|
14109
14873
|
}, text(authErrorMessage)];
|
|
14110
14874
|
};
|
|
14111
|
-
const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false,
|
|
14875
|
+
const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '') => {
|
|
14112
14876
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
14113
14877
|
return [{
|
|
14114
|
-
childCount: hasAuthError ?
|
|
14878
|
+
childCount: 2 + (authEnabled ? 1 : 0) + (hasAuthError ? 1 : 0),
|
|
14115
14879
|
className: ChatHeader,
|
|
14116
14880
|
onContextMenu: HandleChatHeaderContextMenu,
|
|
14117
14881
|
type: Header
|
|
14118
|
-
}, {
|
|
14882
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
14119
14883
|
childCount: 2,
|
|
14120
14884
|
className: ChatName,
|
|
14121
14885
|
type: Div
|
|
@@ -14123,7 +14887,7 @@ const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, a
|
|
|
14123
14887
|
childCount: 1,
|
|
14124
14888
|
className: ChatHeaderLabel,
|
|
14125
14889
|
type: H2
|
|
14126
|
-
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail'
|
|
14890
|
+
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail'), ...getAuthErrorDom(hasAuthError, authErrorMessage)];
|
|
14127
14891
|
};
|
|
14128
14892
|
|
|
14129
14893
|
const getChatModeDetailVirtualDom = ({
|
|
@@ -14132,7 +14896,6 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14132
14896
|
agentModePickerOpen = false,
|
|
14133
14897
|
authEnabled = false,
|
|
14134
14898
|
authErrorMessage = '',
|
|
14135
|
-
authStatus = 'signed-out',
|
|
14136
14899
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14137
14900
|
composerAttachmentPreviewOverlayError = false,
|
|
14138
14901
|
composerAttachments,
|
|
@@ -14173,6 +14936,8 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14173
14936
|
tokensUsed,
|
|
14174
14937
|
usageOverviewEnabled,
|
|
14175
14938
|
useChatMathWorker = false,
|
|
14939
|
+
userName = '',
|
|
14940
|
+
userState = 'loggedOut',
|
|
14176
14941
|
visibleModels = models,
|
|
14177
14942
|
voiceDictationEnabled = false
|
|
14178
14943
|
}) => {
|
|
@@ -14193,7 +14958,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
14193
14958
|
onDragEnter: HandleDragEnterChatView,
|
|
14194
14959
|
onDragOver: HandleDragOverChatView,
|
|
14195
14960
|
type: Div
|
|
14196
|
-
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled,
|
|
14961
|
+
}, ...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
14962
|
agentMode,
|
|
14198
14963
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14199
14964
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14229,20 +14994,20 @@ const getChatSearchDom = (hasSearchField, searchValue) => {
|
|
|
14229
14994
|
value: searchValue
|
|
14230
14995
|
}];
|
|
14231
14996
|
};
|
|
14232
|
-
const getChatHeaderListModeDom = (authEnabled = false,
|
|
14997
|
+
const getChatHeaderListModeDom = (authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
|
|
14233
14998
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
14234
14999
|
const hasSearchField = searchEnabled && searchFieldVisible;
|
|
14235
|
-
const headerChildCount = 2 + (hasAuthError ? 1 : 0) + (hasSearchField ? 1 : 0);
|
|
15000
|
+
const headerChildCount = 2 + (authEnabled ? 1 : 0) + (hasAuthError ? 1 : 0) + (hasSearchField ? 1 : 0);
|
|
14236
15001
|
return [{
|
|
14237
15002
|
childCount: headerChildCount,
|
|
14238
15003
|
className: ChatHeader,
|
|
14239
15004
|
onContextMenu: HandleChatHeaderContextMenu,
|
|
14240
15005
|
type: Header
|
|
14241
|
-
}, {
|
|
15006
|
+
}, ...getChatHeaderAuthDom(authEnabled, userState, userName), {
|
|
14242
15007
|
childCount: 1,
|
|
14243
15008
|
className: ChatHeaderLabel,
|
|
14244
15009
|
type: H2
|
|
14245
|
-
}, text(chats()), ...getChatHeaderActionsDom('list',
|
|
15010
|
+
}, text(chats()), ...getChatHeaderActionsDom('list', searchEnabled), ...getChatSearchDom(hasSearchField, searchValue), ...(hasAuthError ? [{
|
|
14246
15011
|
childCount: 1,
|
|
14247
15012
|
className: ChatAuthError,
|
|
14248
15013
|
type: Span
|
|
@@ -14342,7 +15107,6 @@ const getChatModeListVirtualDom = ({
|
|
|
14342
15107
|
agentModePickerOpen = false,
|
|
14343
15108
|
authEnabled = false,
|
|
14344
15109
|
authErrorMessage = '',
|
|
14345
|
-
authStatus = 'signed-out',
|
|
14346
15110
|
chatListScrollTop = 0,
|
|
14347
15111
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14348
15112
|
composerAttachmentPreviewOverlayError = false,
|
|
@@ -14377,6 +15141,8 @@ const getChatModeListVirtualDom = ({
|
|
|
14377
15141
|
tokensMax,
|
|
14378
15142
|
tokensUsed,
|
|
14379
15143
|
usageOverviewEnabled,
|
|
15144
|
+
userName = '',
|
|
15145
|
+
userState = 'loggedOut',
|
|
14380
15146
|
visibleModels = models,
|
|
14381
15147
|
voiceDictationEnabled = false
|
|
14382
15148
|
}) => {
|
|
@@ -14395,7 +15161,7 @@ const getChatModeListVirtualDom = ({
|
|
|
14395
15161
|
onDragEnter: HandleDragEnterChatView,
|
|
14396
15162
|
onDragOver: HandleDragOverChatView,
|
|
14397
15163
|
type: Div
|
|
14398
|
-
}, ...getChatHeaderListModeDom(authEnabled,
|
|
15164
|
+
}, ...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
15165
|
agentMode,
|
|
14400
15166
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14401
15167
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14498,7 +15264,6 @@ const getChatVirtualDom = options => {
|
|
|
14498
15264
|
agentModePickerOpen = false,
|
|
14499
15265
|
authEnabled = false,
|
|
14500
15266
|
authErrorMessage = '',
|
|
14501
|
-
authStatus = 'signed-out',
|
|
14502
15267
|
chatListScrollTop,
|
|
14503
15268
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14504
15269
|
composerAttachmentPreviewOverlayError = false,
|
|
@@ -14510,6 +15275,10 @@ const getChatVirtualDom = options => {
|
|
|
14510
15275
|
composerHeight,
|
|
14511
15276
|
composerLineHeight,
|
|
14512
15277
|
composerValue,
|
|
15278
|
+
gitBranches = [],
|
|
15279
|
+
gitBranchPickerErrorMessage = '',
|
|
15280
|
+
gitBranchPickerOpen = false,
|
|
15281
|
+
gitBranchPickerVisible = false,
|
|
14513
15282
|
hasSpaceForAgentModePicker,
|
|
14514
15283
|
hasSpaceForRunModePicker,
|
|
14515
15284
|
listFocusedIndex = -1,
|
|
@@ -14547,6 +15316,8 @@ const getChatVirtualDom = options => {
|
|
|
14547
15316
|
tokensUsed,
|
|
14548
15317
|
usageOverviewEnabled,
|
|
14549
15318
|
useChatMathWorker = false,
|
|
15319
|
+
userName = '',
|
|
15320
|
+
userState = 'loggedOut',
|
|
14550
15321
|
viewMode,
|
|
14551
15322
|
visibleModels = models,
|
|
14552
15323
|
voiceDictationEnabled = false
|
|
@@ -14561,7 +15332,6 @@ const getChatVirtualDom = options => {
|
|
|
14561
15332
|
agentModePickerOpen,
|
|
14562
15333
|
authEnabled,
|
|
14563
15334
|
authErrorMessage,
|
|
14564
|
-
authStatus,
|
|
14565
15335
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14566
15336
|
composerAttachmentPreviewOverlayError,
|
|
14567
15337
|
composerAttachments,
|
|
@@ -14572,6 +15342,10 @@ const getChatVirtualDom = options => {
|
|
|
14572
15342
|
composerHeight,
|
|
14573
15343
|
composerLineHeight,
|
|
14574
15344
|
composerValue,
|
|
15345
|
+
gitBranches,
|
|
15346
|
+
gitBranchPickerErrorMessage,
|
|
15347
|
+
gitBranchPickerOpen,
|
|
15348
|
+
gitBranchPickerVisible,
|
|
14575
15349
|
hasSpaceForAgentModePicker,
|
|
14576
15350
|
hasSpaceForRunModePicker,
|
|
14577
15351
|
messagesAutoScrollEnabled,
|
|
@@ -14606,6 +15380,8 @@ const getChatVirtualDom = options => {
|
|
|
14606
15380
|
tokensUsed,
|
|
14607
15381
|
usageOverviewEnabled,
|
|
14608
15382
|
useChatMathWorker,
|
|
15383
|
+
userName,
|
|
15384
|
+
userState,
|
|
14609
15385
|
visibleModels,
|
|
14610
15386
|
voiceDictationEnabled
|
|
14611
15387
|
});
|
|
@@ -14616,7 +15392,6 @@ const getChatVirtualDom = options => {
|
|
|
14616
15392
|
agentModePickerOpen,
|
|
14617
15393
|
authEnabled,
|
|
14618
15394
|
authErrorMessage,
|
|
14619
|
-
authStatus,
|
|
14620
15395
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14621
15396
|
composerAttachmentPreviewOverlayError,
|
|
14622
15397
|
composerAttachments,
|
|
@@ -14657,6 +15432,8 @@ const getChatVirtualDom = options => {
|
|
|
14657
15432
|
tokensUsed,
|
|
14658
15433
|
usageOverviewEnabled,
|
|
14659
15434
|
useChatMathWorker,
|
|
15435
|
+
userName,
|
|
15436
|
+
userState,
|
|
14660
15437
|
visibleModels,
|
|
14661
15438
|
voiceDictationEnabled
|
|
14662
15439
|
});
|
|
@@ -14667,7 +15444,6 @@ const getChatVirtualDom = options => {
|
|
|
14667
15444
|
agentModePickerOpen,
|
|
14668
15445
|
authEnabled,
|
|
14669
15446
|
authErrorMessage,
|
|
14670
|
-
authStatus,
|
|
14671
15447
|
chatListScrollTop,
|
|
14672
15448
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14673
15449
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14702,6 +15478,8 @@ const getChatVirtualDom = options => {
|
|
|
14702
15478
|
tokensMax,
|
|
14703
15479
|
tokensUsed,
|
|
14704
15480
|
usageOverviewEnabled,
|
|
15481
|
+
userName,
|
|
15482
|
+
userState,
|
|
14705
15483
|
visibleModels,
|
|
14706
15484
|
voiceDictationEnabled
|
|
14707
15485
|
});
|
|
@@ -14717,7 +15495,6 @@ const renderItems = (oldState, newState) => {
|
|
|
14717
15495
|
agentModePickerOpen,
|
|
14718
15496
|
authEnabled,
|
|
14719
15497
|
authErrorMessage,
|
|
14720
|
-
authStatus,
|
|
14721
15498
|
chatListScrollTop,
|
|
14722
15499
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14723
15500
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14729,6 +15506,10 @@ const renderItems = (oldState, newState) => {
|
|
|
14729
15506
|
composerHeight,
|
|
14730
15507
|
composerLineHeight,
|
|
14731
15508
|
composerValue,
|
|
15509
|
+
gitBranches,
|
|
15510
|
+
gitBranchPickerErrorMessage,
|
|
15511
|
+
gitBranchPickerOpen,
|
|
15512
|
+
gitBranchPickerVisible,
|
|
14732
15513
|
hasSpaceForAgentModePicker,
|
|
14733
15514
|
hasSpaceForRunModePicker,
|
|
14734
15515
|
initial,
|
|
@@ -14768,6 +15549,8 @@ const renderItems = (oldState, newState) => {
|
|
|
14768
15549
|
uid,
|
|
14769
15550
|
usageOverviewEnabled,
|
|
14770
15551
|
useChatMathWorker,
|
|
15552
|
+
userName,
|
|
15553
|
+
userState,
|
|
14771
15554
|
viewMode,
|
|
14772
15555
|
visibleModels,
|
|
14773
15556
|
voiceDictationEnabled
|
|
@@ -14781,7 +15564,6 @@ const renderItems = (oldState, newState) => {
|
|
|
14781
15564
|
agentModePickerOpen,
|
|
14782
15565
|
authEnabled,
|
|
14783
15566
|
authErrorMessage,
|
|
14784
|
-
authStatus,
|
|
14785
15567
|
chatListScrollTop,
|
|
14786
15568
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
14787
15569
|
composerAttachmentPreviewOverlayError,
|
|
@@ -14793,6 +15575,10 @@ const renderItems = (oldState, newState) => {
|
|
|
14793
15575
|
composerHeight,
|
|
14794
15576
|
composerLineHeight,
|
|
14795
15577
|
composerValue,
|
|
15578
|
+
gitBranches,
|
|
15579
|
+
gitBranchPickerErrorMessage,
|
|
15580
|
+
gitBranchPickerOpen,
|
|
15581
|
+
gitBranchPickerVisible,
|
|
14796
15582
|
hasSpaceForAgentModePicker,
|
|
14797
15583
|
hasSpaceForRunModePicker,
|
|
14798
15584
|
listFocusedIndex,
|
|
@@ -14830,6 +15616,8 @@ const renderItems = (oldState, newState) => {
|
|
|
14830
15616
|
tokensUsed,
|
|
14831
15617
|
usageOverviewEnabled,
|
|
14832
15618
|
useChatMathWorker,
|
|
15619
|
+
userName,
|
|
15620
|
+
userState,
|
|
14833
15621
|
viewMode,
|
|
14834
15622
|
visibleModels,
|
|
14835
15623
|
voiceDictationEnabled
|
|
@@ -14876,8 +15664,16 @@ const renderSelection = (oldState, newState) => {
|
|
|
14876
15664
|
const renderValue = (oldState, newState) => {
|
|
14877
15665
|
const {
|
|
14878
15666
|
composerValue,
|
|
15667
|
+
openApiApiKeyInput,
|
|
15668
|
+
openRouterApiKeyInput,
|
|
14879
15669
|
uid
|
|
14880
15670
|
} = newState;
|
|
15671
|
+
if (oldState.openApiApiKeyInput !== openApiApiKeyInput) {
|
|
15672
|
+
return [SetValueByName, uid, OpenApiApiKeyInput, openApiApiKeyInput];
|
|
15673
|
+
}
|
|
15674
|
+
if (oldState.openRouterApiKeyInput !== openRouterApiKeyInput) {
|
|
15675
|
+
return [SetValueByName, uid, OpenRouterApiKeyInput, openRouterApiKeyInput];
|
|
15676
|
+
}
|
|
14881
15677
|
return [SetValueByName, uid, Composer, composerValue];
|
|
14882
15678
|
};
|
|
14883
15679
|
|
|
@@ -14971,6 +15767,9 @@ const renderEventListeners = () => {
|
|
|
14971
15767
|
}, {
|
|
14972
15768
|
name: HandleClickAgentModePickerToggle,
|
|
14973
15769
|
params: ['openAgentModePicker']
|
|
15770
|
+
}, {
|
|
15771
|
+
name: HandleClickGitBranchPickerToggle,
|
|
15772
|
+
params: ['handleClickGitBranchPickerToggle']
|
|
14974
15773
|
}, {
|
|
14975
15774
|
name: HandleClickModelPickerOverlay,
|
|
14976
15775
|
params: ['handleClickModelPickerOverlay', DefaultPrevented]
|
|
@@ -15129,6 +15928,10 @@ const reset = async state => {
|
|
|
15129
15928
|
composerSelectionEnd: 0,
|
|
15130
15929
|
composerSelectionStart: 0,
|
|
15131
15930
|
composerValue: '',
|
|
15931
|
+
gitBranches: [],
|
|
15932
|
+
gitBranchPickerErrorMessage: '',
|
|
15933
|
+
gitBranchPickerOpen: false,
|
|
15934
|
+
gitBranchPickerVisible: false,
|
|
15132
15935
|
mockAiResponseDelay: 0,
|
|
15133
15936
|
modelPickerHeight: getModelPickerHeight(state.modelPickerHeaderHeight, state.models.length),
|
|
15134
15937
|
modelPickerListScrollTop: 0,
|
|
@@ -15208,7 +16011,6 @@ const saveState = state => {
|
|
|
15208
16011
|
selectedModelId,
|
|
15209
16012
|
selectedProjectId,
|
|
15210
16013
|
selectedSessionId,
|
|
15211
|
-
systemPrompt,
|
|
15212
16014
|
viewMode
|
|
15213
16015
|
} = state;
|
|
15214
16016
|
return {
|
|
@@ -15231,7 +16033,6 @@ const saveState = state => {
|
|
|
15231
16033
|
selectedModelId,
|
|
15232
16034
|
selectedProjectId,
|
|
15233
16035
|
selectedSessionId,
|
|
15234
|
-
systemPrompt,
|
|
15235
16036
|
viewMode
|
|
15236
16037
|
};
|
|
15237
16038
|
};
|
|
@@ -15246,7 +16047,13 @@ const setAddContextButtonEnabled = (state, addContextButtonEnabled) => {
|
|
|
15246
16047
|
const setAuthEnabled = (state, authEnabled) => {
|
|
15247
16048
|
return {
|
|
15248
16049
|
...state,
|
|
15249
|
-
authEnabled
|
|
16050
|
+
authAccessToken: authEnabled ? state.authAccessToken : '',
|
|
16051
|
+
authEnabled,
|
|
16052
|
+
authErrorMessage: authEnabled ? state.authErrorMessage : '',
|
|
16053
|
+
userName: authEnabled ? state.userName : '',
|
|
16054
|
+
userState: authEnabled ? state.userState : 'loggedOut',
|
|
16055
|
+
userSubscriptionPlan: authEnabled ? state.userSubscriptionPlan : '',
|
|
16056
|
+
userUsedTokens: authEnabled ? state.userUsedTokens : 0
|
|
15250
16057
|
};
|
|
15251
16058
|
};
|
|
15252
16059
|
|
|
@@ -15440,6 +16247,7 @@ const commandMap = {
|
|
|
15440
16247
|
'Chat.chatListFocusNext': wrapCommand(chatListFocusNext),
|
|
15441
16248
|
'Chat.chatListFocusPrevious': wrapCommand(chatListFocusPrevious),
|
|
15442
16249
|
'Chat.clearInput': wrapCommand(clearInput),
|
|
16250
|
+
'Chat.closeGitBranchPicker': wrapCommand(closeGitBranchPicker),
|
|
15443
16251
|
'Chat.copyInput': wrapCommand(copyInput),
|
|
15444
16252
|
'Chat.create': create,
|
|
15445
16253
|
'Chat.cutInput': wrapCommand(cutInput),
|
|
@@ -15468,6 +16276,7 @@ const commandMap = {
|
|
|
15468
16276
|
'Chat.handleClickDelete': wrapCommand(handleClickDelete),
|
|
15469
16277
|
'Chat.handleClickDictationButton': wrapCommand(handleClickDictationButton),
|
|
15470
16278
|
'Chat.handleClickFileName': wrapCommand(handleClickFileName),
|
|
16279
|
+
'Chat.handleClickGitBranchPickerToggle': wrapCommand(handleClickGitBranchPickerToggle),
|
|
15471
16280
|
'Chat.handleClickList': wrapCommand(handleClickList),
|
|
15472
16281
|
'Chat.handleClickModelPickerList': wrapCommand(handleClickModelPickerList),
|
|
15473
16282
|
'Chat.handleClickModelPickerListIndex': wrapCommand(handleClickModelPickerListIndex),
|
|
@@ -15519,6 +16328,7 @@ const commandMap = {
|
|
|
15519
16328
|
'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
|
|
15520
16329
|
'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
|
|
15521
16330
|
'Chat.openAgentModePicker': wrapCommand(openAgentModePicker),
|
|
16331
|
+
'Chat.openGitBranchPicker': wrapCommand(openGitBranchPicker),
|
|
15522
16332
|
'Chat.openMockProject': wrapCommand(openMockProject),
|
|
15523
16333
|
'Chat.openMockSession': wrapCommand(openMockSession),
|
|
15524
16334
|
'Chat.openModelPicker': wrapCommand(openModelPicker),
|