@lvce-editor/chat-view 7.4.0 → 7.6.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 +703 -217
- package/package.json +1 -1
|
@@ -1350,6 +1350,9 @@ const sendMessagePortToChatStorageWorker$1 = async port => {
|
|
|
1350
1350
|
const activateByEvent$1 = (event, assetDir, platform) => {
|
|
1351
1351
|
return invoke('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
|
|
1352
1352
|
};
|
|
1353
|
+
const getWorkspacePath = () => {
|
|
1354
|
+
return invoke('Workspace.getPath');
|
|
1355
|
+
};
|
|
1353
1356
|
const sendMessagePortToTextMeasurementWorker$1 = async port => {
|
|
1354
1357
|
const command = 'TextMeasurement.handleMessagePort';
|
|
1355
1358
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToTextMeasurementWorker', port, command, 0);
|
|
@@ -1896,6 +1899,7 @@ const Commit = 'Commit';
|
|
|
1896
1899
|
const OpenTerminal = 'Open Terminal';
|
|
1897
1900
|
const ShowDiff = 'Show Diff';
|
|
1898
1901
|
const CreatePullRequest$2 = 'Create PR';
|
|
1902
|
+
const Stop$1 = 'stop';
|
|
1899
1903
|
const Save = 'Save';
|
|
1900
1904
|
const Saving = 'Saving...';
|
|
1901
1905
|
const GetApiKey = 'Get API Key';
|
|
@@ -2046,6 +2050,9 @@ const showDiff = () => {
|
|
|
2046
2050
|
const createPullRequest = () => {
|
|
2047
2051
|
return i18nString(CreatePullRequest$2);
|
|
2048
2052
|
};
|
|
2053
|
+
const stop = () => {
|
|
2054
|
+
return i18nString(Stop$1);
|
|
2055
|
+
};
|
|
2049
2056
|
const save = () => {
|
|
2050
2057
|
return i18nString(Save);
|
|
2051
2058
|
};
|
|
@@ -2222,6 +2229,7 @@ Use available project context to provide accurate, practical coding help.
|
|
|
2222
2229
|
Prefer using available tools to inspect and modify files in the current workspace.
|
|
2223
2230
|
When asked to create or update code, read relevant files first and apply changes directly in files instead of only pasting raw code in chat.
|
|
2224
2231
|
Only provide raw code snippets when explicitly requested or when file editing tools are unavailable.
|
|
2232
|
+
When mentioning inline commands, file names, identifiers, or short code fragments in responses, wrap them in markdown backticks, for example \`nvm install 24.14.1\`.
|
|
2225
2233
|
When displaying code blocks in responses, use markdown triple backticks (\`\`\`) fences.
|
|
2226
2234
|
When referencing workspace files in responses (including "files added/changed" lists), use markdown links so users can click them.
|
|
2227
2235
|
Prefer file links like [src/index.ts]({{workspaceUri}}/src/index.ts) and avoid plain text file paths when a link is appropriate.
|
|
@@ -2291,11 +2299,16 @@ const getReasoningEffortLabel = reasoningEffort => {
|
|
|
2291
2299
|
}
|
|
2292
2300
|
};
|
|
2293
2301
|
|
|
2302
|
+
const defaultToolEnablement = {
|
|
2303
|
+
run_in_terminal: false
|
|
2304
|
+
};
|
|
2294
2305
|
const parseToolEnablement = value => {
|
|
2295
2306
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
2296
|
-
return
|
|
2307
|
+
return defaultToolEnablement;
|
|
2297
2308
|
}
|
|
2298
|
-
const toolEnablement = {
|
|
2309
|
+
const toolEnablement = {
|
|
2310
|
+
...defaultToolEnablement
|
|
2311
|
+
};
|
|
2299
2312
|
for (const [key, enabled] of Object.entries(value)) {
|
|
2300
2313
|
if (typeof enabled === 'boolean') {
|
|
2301
2314
|
toolEnablement[key] = enabled;
|
|
@@ -2320,10 +2333,13 @@ const validateToolEnablement = value => {
|
|
|
2320
2333
|
};
|
|
2321
2334
|
const isToolEnabled = (toolEnablement, toolName) => {
|
|
2322
2335
|
if (!toolEnablement) {
|
|
2323
|
-
return true;
|
|
2336
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2324
2337
|
}
|
|
2325
2338
|
const enabled = toolEnablement[toolName];
|
|
2326
|
-
|
|
2339
|
+
if (typeof enabled === 'boolean') {
|
|
2340
|
+
return enabled;
|
|
2341
|
+
}
|
|
2342
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2327
2343
|
};
|
|
2328
2344
|
const filterEnabledTools = (tools, toolEnablement) => {
|
|
2329
2345
|
return tools.filter(tool => isToolEnabled(toolEnablement, tool.function.name));
|
|
@@ -2399,7 +2415,7 @@ const createDefaultState = () => {
|
|
|
2399
2415
|
maxToolCalls: defaultMaxToolCalls,
|
|
2400
2416
|
messagesAutoScrollEnabled: true,
|
|
2401
2417
|
messagesScrollTop: 0,
|
|
2402
|
-
mockAiResponseDelay:
|
|
2418
|
+
mockAiResponseDelay: 0,
|
|
2403
2419
|
mockApiCommandId: '',
|
|
2404
2420
|
mockOpenApiRequests: [],
|
|
2405
2421
|
modelPickerHeaderHeight,
|
|
@@ -2431,6 +2447,8 @@ const createDefaultState = () => {
|
|
|
2431
2447
|
name: '_blank',
|
|
2432
2448
|
uri: ''
|
|
2433
2449
|
}],
|
|
2450
|
+
projectSidebarResizing: false,
|
|
2451
|
+
projectSidebarWidth: 280,
|
|
2434
2452
|
questionToolEnabled: false,
|
|
2435
2453
|
reasoningEffort: defaultReasoningEffort,
|
|
2436
2454
|
reasoningEffortPickerOpen: false,
|
|
@@ -2450,6 +2468,7 @@ const createDefaultState = () => {
|
|
|
2450
2468
|
id: defaultSessionId,
|
|
2451
2469
|
messages: [],
|
|
2452
2470
|
projectId: defaultProjectId,
|
|
2471
|
+
status: 'idle',
|
|
2453
2472
|
title: defaultSessionTitle()
|
|
2454
2473
|
}],
|
|
2455
2474
|
showRunMode: true,
|
|
@@ -2525,6 +2544,9 @@ const listChatSessions = async () => {
|
|
|
2525
2544
|
...(session.pullRequestUrl ? {
|
|
2526
2545
|
pullRequestUrl: session.pullRequestUrl
|
|
2527
2546
|
} : {}),
|
|
2547
|
+
...(session.status ? {
|
|
2548
|
+
status: session.status
|
|
2549
|
+
} : {}),
|
|
2528
2550
|
title: session.title,
|
|
2529
2551
|
...(session.workspaceUri ? {
|
|
2530
2552
|
workspaceUri: session.workspaceUri
|
|
@@ -2553,6 +2575,9 @@ const getChatSession = async id => {
|
|
|
2553
2575
|
...(session.pullRequestUrl ? {
|
|
2554
2576
|
pullRequestUrl: session.pullRequestUrl
|
|
2555
2577
|
} : {}),
|
|
2578
|
+
...(session.status ? {
|
|
2579
|
+
status: session.status
|
|
2580
|
+
} : {}),
|
|
2556
2581
|
title: session.title,
|
|
2557
2582
|
...(session.workspaceUri ? {
|
|
2558
2583
|
workspaceUri: session.workspaceUri
|
|
@@ -2574,6 +2599,9 @@ const saveChatSession = async session => {
|
|
|
2574
2599
|
...(session.pullRequestUrl ? {
|
|
2575
2600
|
pullRequestUrl: session.pullRequestUrl
|
|
2576
2601
|
} : {}),
|
|
2602
|
+
...(session.status ? {
|
|
2603
|
+
status: session.status
|
|
2604
|
+
} : {}),
|
|
2577
2605
|
title: session.title,
|
|
2578
2606
|
...(session.workspaceUri ? {
|
|
2579
2607
|
workspaceUri: session.workspaceUri
|
|
@@ -2835,7 +2863,7 @@ const getRenderHtmlCss = (sessions, selectedSessionId) => {
|
|
|
2835
2863
|
const isEqual$1 = (oldState, newState) => {
|
|
2836
2864
|
const oldRenderHtmlCss = getRenderHtmlCss(oldState.sessions, oldState.selectedSessionId);
|
|
2837
2865
|
const newRenderHtmlCss = getRenderHtmlCss(newState.sessions, newState.selectedSessionId);
|
|
2838
|
-
return oldState.initial === newState.initial && oldState.chatMessageFontFamily === newState.chatMessageFontFamily && oldState.chatMessageFontSize === newState.chatMessageFontSize && oldState.chatMessageLineHeight === newState.chatMessageLineHeight && oldState.chatFocusContentMaxWidth === newState.chatFocusContentMaxWidth && oldState.chatSendAreaPaddingTop === newState.chatSendAreaPaddingTop && oldState.chatSendAreaPaddingLeft === newState.chatSendAreaPaddingLeft && oldState.chatSendAreaPaddingRight === newState.chatSendAreaPaddingRight && oldState.chatSendAreaPaddingBottom === newState.chatSendAreaPaddingBottom && oldState.composerHeight === newState.composerHeight && oldState.composerAttachmentsHeight === newState.composerAttachmentsHeight && oldState.modelPickerHeight === newState.modelPickerHeight && oldState.composerLineHeight === newState.composerLineHeight && oldState.composerFontFamily === newState.composerFontFamily && oldState.composerFontSize === newState.composerFontSize && oldState.listItemHeight === newState.listItemHeight && oldState.textAreaPaddingTop === newState.textAreaPaddingTop && oldState.textAreaPaddingLeft === newState.textAreaPaddingLeft && oldState.textAreaPaddingRight === newState.textAreaPaddingRight && oldState.textAreaPaddingBottom === newState.textAreaPaddingBottom && oldRenderHtmlCss === newRenderHtmlCss;
|
|
2866
|
+
return oldState.initial === newState.initial && oldState.chatMessageFontFamily === newState.chatMessageFontFamily && oldState.chatMessageFontSize === newState.chatMessageFontSize && oldState.chatMessageLineHeight === newState.chatMessageLineHeight && oldState.chatFocusContentMaxWidth === newState.chatFocusContentMaxWidth && oldState.projectSidebarWidth === newState.projectSidebarWidth && oldState.chatSendAreaPaddingTop === newState.chatSendAreaPaddingTop && oldState.chatSendAreaPaddingLeft === newState.chatSendAreaPaddingLeft && oldState.chatSendAreaPaddingRight === newState.chatSendAreaPaddingRight && oldState.chatSendAreaPaddingBottom === newState.chatSendAreaPaddingBottom && oldState.composerHeight === newState.composerHeight && oldState.composerAttachmentsHeight === newState.composerAttachmentsHeight && oldState.modelPickerHeight === newState.modelPickerHeight && oldState.composerLineHeight === newState.composerLineHeight && oldState.composerFontFamily === newState.composerFontFamily && oldState.composerFontSize === newState.composerFontSize && oldState.listItemHeight === newState.listItemHeight && oldState.textAreaPaddingTop === newState.textAreaPaddingTop && oldState.textAreaPaddingLeft === newState.textAreaPaddingLeft && oldState.textAreaPaddingRight === newState.textAreaPaddingRight && oldState.textAreaPaddingBottom === newState.textAreaPaddingBottom && oldRenderHtmlCss === newRenderHtmlCss;
|
|
2839
2867
|
};
|
|
2840
2868
|
|
|
2841
2869
|
const diffFocus = (oldState, newState) => {
|
|
@@ -3459,6 +3487,7 @@ const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
|
3459
3487
|
const FocusOpenTerminal = 'focus-open-terminal';
|
|
3460
3488
|
const FocusShowDiff = 'focus-show-diff';
|
|
3461
3489
|
const Send = 'send';
|
|
3490
|
+
const Stop = 'stop';
|
|
3462
3491
|
const ScrollDown = 'scroll-down';
|
|
3463
3492
|
const Back = 'back';
|
|
3464
3493
|
const ModelPickerToggle = 'model-picker-toggle';
|
|
@@ -3890,37 +3919,27 @@ const openFolder = async () => {
|
|
|
3890
3919
|
}
|
|
3891
3920
|
};
|
|
3892
3921
|
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
const slashAtEndRegex = /\/$/;
|
|
3897
|
-
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3898
|
-
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
3899
|
-
const toGitUri = (baseUri, ...segments) => {
|
|
3900
|
-
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3901
|
-
for (const segment of segments) {
|
|
3902
|
-
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3903
|
-
}
|
|
3904
|
-
return url.toString();
|
|
3905
|
-
};
|
|
3906
|
-
const decodeFileContent = content => {
|
|
3907
|
-
if (typeof content === 'string') {
|
|
3908
|
-
return content;
|
|
3909
|
-
}
|
|
3910
|
-
if (content instanceof Uint8Array) {
|
|
3911
|
-
return new TextDecoder().decode(content);
|
|
3912
|
-
}
|
|
3913
|
-
if (Array.isArray(content)) {
|
|
3914
|
-
return new TextDecoder().decode(new Uint8Array(content));
|
|
3915
|
-
}
|
|
3916
|
-
return '';
|
|
3917
|
-
};
|
|
3918
|
-
const toFileSystemPath = uri => {
|
|
3919
|
-
if (!uri.startsWith('file://')) {
|
|
3920
|
-
return uri;
|
|
3922
|
+
const parseEntries = value => {
|
|
3923
|
+
if (!Array.isArray(value)) {
|
|
3924
|
+
return [];
|
|
3921
3925
|
}
|
|
3922
|
-
return
|
|
3926
|
+
return value.map(entry => {
|
|
3927
|
+
if (Array.isArray(entry) && typeof entry[0] === 'string' && typeof entry[1] === 'number') {
|
|
3928
|
+
return {
|
|
3929
|
+
name: entry[0],
|
|
3930
|
+
type: entry[1]
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3933
|
+
if (entry && typeof entry === 'object' && typeof Reflect.get(entry, 'name') === 'string' && typeof Reflect.get(entry, 'type') === 'number') {
|
|
3934
|
+
return {
|
|
3935
|
+
name: Reflect.get(entry, 'name'),
|
|
3936
|
+
type: Reflect.get(entry, 'type')
|
|
3937
|
+
};
|
|
3938
|
+
}
|
|
3939
|
+
return undefined;
|
|
3940
|
+
}).filter(entry => !!entry);
|
|
3923
3941
|
};
|
|
3942
|
+
|
|
3924
3943
|
const getRelativePath = (fromPath, toPath) => {
|
|
3925
3944
|
if (!fromPath.startsWith('/') || !toPath.startsWith('/')) {
|
|
3926
3945
|
return toPath;
|
|
@@ -3935,6 +3954,14 @@ const getRelativePath = (fromPath, toPath) => {
|
|
|
3935
3954
|
const childSegments = toParts.slice(commonPrefixLength);
|
|
3936
3955
|
return [...parentSegments, ...childSegments].join('/') || '.';
|
|
3937
3956
|
};
|
|
3957
|
+
|
|
3958
|
+
const toFileSystemPath = uri => {
|
|
3959
|
+
if (!uri.startsWith('file://')) {
|
|
3960
|
+
return uri;
|
|
3961
|
+
}
|
|
3962
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
3963
|
+
};
|
|
3964
|
+
|
|
3938
3965
|
const toFileSystemTarget = (workspaceUri, uri) => {
|
|
3939
3966
|
const workspacePath = toFileSystemPath(workspaceUri);
|
|
3940
3967
|
const fileSystemPath = toFileSystemPath(uri);
|
|
@@ -3943,34 +3970,56 @@ const toFileSystemTarget = (workspaceUri, uri) => {
|
|
|
3943
3970
|
}
|
|
3944
3971
|
return getRelativePath(workspacePath, fileSystemPath);
|
|
3945
3972
|
};
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3973
|
+
|
|
3974
|
+
const readDir = async (workspaceUri, uri) => {
|
|
3975
|
+
const result = await invoke('FileSystem.readDirWithFileTypes', toFileSystemTarget(workspaceUri, uri));
|
|
3976
|
+
return parseEntries(result);
|
|
3977
|
+
};
|
|
3978
|
+
|
|
3979
|
+
const slashAtEndRegex = /\/$/;
|
|
3980
|
+
const toGitUri = (baseUri, ...segments) => {
|
|
3981
|
+
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3982
|
+
for (const segment of segments) {
|
|
3983
|
+
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3949
3984
|
}
|
|
3950
|
-
return
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3985
|
+
return url.toString();
|
|
3986
|
+
};
|
|
3987
|
+
|
|
3988
|
+
const FileTypeFile = 1;
|
|
3989
|
+
const FileTypeDirectory = 2;
|
|
3990
|
+
const collectBranchNames = async (workspaceUri, refsHeadsUri, prefix, branches) => {
|
|
3991
|
+
const entries = await readDir(workspaceUri, refsHeadsUri);
|
|
3992
|
+
for (const entry of entries) {
|
|
3993
|
+
if (entry.type === FileTypeDirectory) {
|
|
3994
|
+
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
3995
|
+
continue;
|
|
3956
3996
|
}
|
|
3957
|
-
if (entry
|
|
3958
|
-
|
|
3959
|
-
name: Reflect.get(entry, 'name'),
|
|
3960
|
-
type: Reflect.get(entry, 'type')
|
|
3961
|
-
};
|
|
3997
|
+
if (entry.type === FileTypeFile) {
|
|
3998
|
+
branches.add(`${prefix}${entry.name}`);
|
|
3962
3999
|
}
|
|
3963
|
-
|
|
3964
|
-
}).filter(entry => !!entry);
|
|
4000
|
+
}
|
|
3965
4001
|
};
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
4002
|
+
|
|
4003
|
+
const decodeFileContent = content => {
|
|
4004
|
+
if (typeof content === 'string') {
|
|
4005
|
+
return content;
|
|
4006
|
+
}
|
|
4007
|
+
if (content instanceof Uint8Array) {
|
|
4008
|
+
return new TextDecoder().decode(content);
|
|
4009
|
+
}
|
|
4010
|
+
if (Array.isArray(content)) {
|
|
4011
|
+
return new TextDecoder().decode(new Uint8Array(content));
|
|
4012
|
+
}
|
|
4013
|
+
return '';
|
|
3969
4014
|
};
|
|
4015
|
+
|
|
3970
4016
|
const readTextFile = async (workspaceUri, uri) => {
|
|
3971
4017
|
const result = await invoke('FileSystem.readFile', toFileSystemTarget(workspaceUri, uri));
|
|
3972
4018
|
return decodeFileContent(result);
|
|
3973
4019
|
};
|
|
4020
|
+
|
|
4021
|
+
// cspell:ignore gitdir worktrees
|
|
4022
|
+
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3974
4023
|
const getGitDirUri = async workspaceUri => {
|
|
3975
4024
|
const gitUri = toGitUri(workspaceUri, '.git');
|
|
3976
4025
|
try {
|
|
@@ -3986,18 +4035,8 @@ const getGitDirUri = async workspaceUri => {
|
|
|
3986
4035
|
}
|
|
3987
4036
|
return new URL(match[1].trim(), workspaceUri.endsWith('/') ? workspaceUri : `${workspaceUri}/`).toString();
|
|
3988
4037
|
};
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
for (const entry of entries) {
|
|
3992
|
-
if (entry.type === FileTypeDirectory) {
|
|
3993
|
-
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
3994
|
-
continue;
|
|
3995
|
-
}
|
|
3996
|
-
if (entry.type === FileTypeFile) {
|
|
3997
|
-
branches.add(`${prefix}${entry.name}`);
|
|
3998
|
-
}
|
|
3999
|
-
}
|
|
4000
|
-
};
|
|
4038
|
+
|
|
4039
|
+
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
4001
4040
|
const parseCurrentBranch = headContent => {
|
|
4002
4041
|
const match = headRefRegex.exec(headContent.trim());
|
|
4003
4042
|
if (match) {
|
|
@@ -4005,13 +4044,7 @@ const parseCurrentBranch = headContent => {
|
|
|
4005
4044
|
}
|
|
4006
4045
|
return '';
|
|
4007
4046
|
};
|
|
4008
|
-
|
|
4009
|
-
try {
|
|
4010
|
-
return Boolean(await getGitDirUri(workspaceUri));
|
|
4011
|
-
} catch {
|
|
4012
|
-
return false;
|
|
4013
|
-
}
|
|
4014
|
-
};
|
|
4047
|
+
|
|
4015
4048
|
const getGitBranches = async workspaceUri => {
|
|
4016
4049
|
const gitDirUri = await getGitDirUri(workspaceUri);
|
|
4017
4050
|
if (!gitDirUri) {
|
|
@@ -4044,6 +4077,14 @@ const getGitBranches = async workspaceUri => {
|
|
|
4044
4077
|
}));
|
|
4045
4078
|
};
|
|
4046
4079
|
|
|
4080
|
+
const hasGitRepository = async workspaceUri => {
|
|
4081
|
+
try {
|
|
4082
|
+
return Boolean(await getGitDirUri(workspaceUri));
|
|
4083
|
+
} catch {
|
|
4084
|
+
return false;
|
|
4085
|
+
}
|
|
4086
|
+
};
|
|
4087
|
+
|
|
4047
4088
|
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
4048
4089
|
return sessions.find(session => session.id === selectedSessionId);
|
|
4049
4090
|
};
|
|
@@ -4206,12 +4247,26 @@ const handleClickCreateProject = async state => {
|
|
|
4206
4247
|
};
|
|
4207
4248
|
};
|
|
4208
4249
|
|
|
4250
|
+
const getChatSessionStatus = session => {
|
|
4251
|
+
if (session.status) {
|
|
4252
|
+
return session.status;
|
|
4253
|
+
}
|
|
4254
|
+
const hasInProgressAssistantMessage = session.messages.some(message => message.role === 'assistant' && message.inProgress);
|
|
4255
|
+
if (hasInProgressAssistantMessage) {
|
|
4256
|
+
return 'in-progress';
|
|
4257
|
+
}
|
|
4258
|
+
const hasAssistantMessage = session.messages.some(message => message.role === 'assistant');
|
|
4259
|
+
if (hasAssistantMessage) {
|
|
4260
|
+
return 'finished';
|
|
4261
|
+
}
|
|
4262
|
+
return 'idle';
|
|
4263
|
+
};
|
|
4264
|
+
|
|
4209
4265
|
const canCreatePullRequest = session => {
|
|
4210
4266
|
if (!session?.branchName || !session.workspaceUri || session.pullRequestUrl) {
|
|
4211
4267
|
return false;
|
|
4212
4268
|
}
|
|
4213
|
-
|
|
4214
|
-
if (hasInProgressAssistantMessage) {
|
|
4269
|
+
if (getChatSessionStatus(session) !== 'finished') {
|
|
4215
4270
|
return false;
|
|
4216
4271
|
}
|
|
4217
4272
|
return session.messages.some(message => message.role === 'assistant');
|
|
@@ -4642,6 +4697,30 @@ const hasToolError = value => {
|
|
|
4642
4697
|
const error = Reflect.get(value, 'error');
|
|
4643
4698
|
return typeof error === 'string' && error.trim().length > 0;
|
|
4644
4699
|
};
|
|
4700
|
+
const getTrackedToolExecutionValue = value => {
|
|
4701
|
+
if (typeof value !== 'string') {
|
|
4702
|
+
return value;
|
|
4703
|
+
}
|
|
4704
|
+
try {
|
|
4705
|
+
return JSON.parse(value);
|
|
4706
|
+
} catch {
|
|
4707
|
+
return value;
|
|
4708
|
+
}
|
|
4709
|
+
};
|
|
4710
|
+
const getStoredToolExecutionStatus = result => {
|
|
4711
|
+
let parsed = result;
|
|
4712
|
+
if (typeof result === 'string') {
|
|
4713
|
+
try {
|
|
4714
|
+
parsed = JSON.parse(result);
|
|
4715
|
+
} catch {
|
|
4716
|
+
return 'error';
|
|
4717
|
+
}
|
|
4718
|
+
}
|
|
4719
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4720
|
+
return 'error';
|
|
4721
|
+
}
|
|
4722
|
+
return hasToolError(parsed) ? 'error' : 'success';
|
|
4723
|
+
};
|
|
4645
4724
|
const parseWriteFileArguments = rawArguments => {
|
|
4646
4725
|
let parsed = rawArguments;
|
|
4647
4726
|
if (typeof rawArguments === 'string') {
|
|
@@ -4749,15 +4828,60 @@ const executeChatTool = async (name, rawArguments, options) => {
|
|
|
4749
4828
|
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4750
4829
|
throw new Error('Chat tools must be executed in a web worker environment. Please set useChatToolWorker to true in the options.');
|
|
4751
4830
|
}
|
|
4752
|
-
const
|
|
4831
|
+
const executionOptions = {
|
|
4753
4832
|
assetDir: options.assetDir,
|
|
4754
4833
|
platform: options.platform,
|
|
4755
4834
|
...(options.workspaceUri ? {
|
|
4756
4835
|
workspaceUri: options.workspaceUri
|
|
4757
4836
|
} : {})
|
|
4758
|
-
}
|
|
4759
|
-
const
|
|
4760
|
-
|
|
4837
|
+
};
|
|
4838
|
+
const executionId = options.toolCallId || `${name}-${Date.now()}`;
|
|
4839
|
+
const startedAt = new Date().toISOString();
|
|
4840
|
+
if (options.sessionId) {
|
|
4841
|
+
await appendChatViewEvent({
|
|
4842
|
+
arguments: getTrackedToolExecutionValue(rawArguments),
|
|
4843
|
+
id: executionId,
|
|
4844
|
+
name,
|
|
4845
|
+
options: executionOptions,
|
|
4846
|
+
sessionId: options.sessionId,
|
|
4847
|
+
time: startedAt,
|
|
4848
|
+
timestamp: startedAt,
|
|
4849
|
+
type: 'tool-execution-started'
|
|
4850
|
+
});
|
|
4851
|
+
}
|
|
4852
|
+
try {
|
|
4853
|
+
const workerOutput = await execute(name, rawArguments, executionOptions);
|
|
4854
|
+
const outputWithLineCounts = name === 'write_file' ? await withWriteFileLineCounts(workerOutput, rawArguments) : workerOutput;
|
|
4855
|
+
const result = stringifyToolOutput(outputWithLineCounts);
|
|
4856
|
+
if (options.sessionId) {
|
|
4857
|
+
await appendChatViewEvent({
|
|
4858
|
+
id: executionId,
|
|
4859
|
+
name,
|
|
4860
|
+
result: outputWithLineCounts,
|
|
4861
|
+
sessionId: options.sessionId,
|
|
4862
|
+
status: getStoredToolExecutionStatus(outputWithLineCounts),
|
|
4863
|
+
timestamp: new Date().toISOString(),
|
|
4864
|
+
type: 'tool-execution-finished'
|
|
4865
|
+
});
|
|
4866
|
+
}
|
|
4867
|
+
return result;
|
|
4868
|
+
} catch (error) {
|
|
4869
|
+
const errorResult = {
|
|
4870
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4871
|
+
};
|
|
4872
|
+
if (options.sessionId) {
|
|
4873
|
+
await appendChatViewEvent({
|
|
4874
|
+
id: executionId,
|
|
4875
|
+
name,
|
|
4876
|
+
result: errorResult,
|
|
4877
|
+
sessionId: options.sessionId,
|
|
4878
|
+
status: 'error',
|
|
4879
|
+
timestamp: new Date().toISOString(),
|
|
4880
|
+
type: 'tool-execution-finished'
|
|
4881
|
+
});
|
|
4882
|
+
}
|
|
4883
|
+
throw error;
|
|
4884
|
+
}
|
|
4761
4885
|
};
|
|
4762
4886
|
|
|
4763
4887
|
const getAskQuestionTool = () => {
|
|
@@ -4839,6 +4963,7 @@ const getAttachmentTextPart = attachment => {
|
|
|
4839
4963
|
};
|
|
4840
4964
|
}
|
|
4841
4965
|
};
|
|
4966
|
+
|
|
4842
4967
|
const getChatMessageOpenAiContent = message => {
|
|
4843
4968
|
if (!message.attachments || message.attachments.length === 0) {
|
|
4844
4969
|
return message.text;
|
|
@@ -4870,7 +4995,9 @@ const getClientRequestIdHeader = () => {
|
|
|
4870
4995
|
};
|
|
4871
4996
|
|
|
4872
4997
|
const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
4873
|
-
|
|
4998
|
+
if (delayInMs > 0) {
|
|
4999
|
+
await delay(delayInMs);
|
|
5000
|
+
}
|
|
4874
5001
|
return `Mock AI response: I received "${userMessage}".`;
|
|
4875
5002
|
};
|
|
4876
5003
|
|
|
@@ -5354,6 +5481,51 @@ const makeStreamingApiRequest = async options => {
|
|
|
5354
5481
|
return invoke$6('ChatNetwork.makeStreamingApiRequest', options);
|
|
5355
5482
|
};
|
|
5356
5483
|
|
|
5484
|
+
const getNumericCount = parsed => {
|
|
5485
|
+
const count = Reflect.get(parsed, 'count');
|
|
5486
|
+
if (typeof count === 'number' && Number.isFinite(count)) {
|
|
5487
|
+
return count;
|
|
5488
|
+
}
|
|
5489
|
+
const matchCount = Reflect.get(parsed, 'matchCount');
|
|
5490
|
+
if (typeof matchCount === 'number' && Number.isFinite(matchCount)) {
|
|
5491
|
+
return matchCount;
|
|
5492
|
+
}
|
|
5493
|
+
return undefined;
|
|
5494
|
+
};
|
|
5495
|
+
const getArrayCount = parsed => {
|
|
5496
|
+
const matches = Reflect.get(parsed, 'matches');
|
|
5497
|
+
if (Array.isArray(matches)) {
|
|
5498
|
+
return matches.length;
|
|
5499
|
+
}
|
|
5500
|
+
const files = Reflect.get(parsed, 'files');
|
|
5501
|
+
if (Array.isArray(files)) {
|
|
5502
|
+
return files.length;
|
|
5503
|
+
}
|
|
5504
|
+
const results = Reflect.get(parsed, 'results');
|
|
5505
|
+
if (Array.isArray(results)) {
|
|
5506
|
+
return results.length;
|
|
5507
|
+
}
|
|
5508
|
+
return undefined;
|
|
5509
|
+
};
|
|
5510
|
+
const getGlobMatchCount = result => {
|
|
5511
|
+
if (!result) {
|
|
5512
|
+
return undefined;
|
|
5513
|
+
}
|
|
5514
|
+
let parsed;
|
|
5515
|
+
try {
|
|
5516
|
+
parsed = JSON.parse(result);
|
|
5517
|
+
} catch {
|
|
5518
|
+
return undefined;
|
|
5519
|
+
}
|
|
5520
|
+
if (Array.isArray(parsed)) {
|
|
5521
|
+
return parsed.length;
|
|
5522
|
+
}
|
|
5523
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
5524
|
+
return undefined;
|
|
5525
|
+
}
|
|
5526
|
+
return getNumericCount(parsed) ?? getArrayCount(parsed);
|
|
5527
|
+
};
|
|
5528
|
+
|
|
5357
5529
|
const getTextContent = content => {
|
|
5358
5530
|
if (typeof content === 'string') {
|
|
5359
5531
|
return content;
|
|
@@ -5518,6 +5690,9 @@ const getToolCallResult = (name, content) => {
|
|
|
5518
5690
|
}
|
|
5519
5691
|
return content;
|
|
5520
5692
|
}
|
|
5693
|
+
if (name === 'glob') {
|
|
5694
|
+
return getGlobMatchCount(content) === undefined ? undefined : content;
|
|
5695
|
+
}
|
|
5521
5696
|
if (name !== 'getWorkspaceUri') {
|
|
5522
5697
|
return undefined;
|
|
5523
5698
|
}
|
|
@@ -6029,6 +6204,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6029
6204
|
onToolCallsChunk,
|
|
6030
6205
|
questionToolEnabled = false,
|
|
6031
6206
|
reasoningEffort,
|
|
6207
|
+
sessionId,
|
|
6032
6208
|
stream,
|
|
6033
6209
|
supportsReasoningEffort = false,
|
|
6034
6210
|
systemPrompt = '',
|
|
@@ -6145,6 +6321,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6145
6321
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6146
6322
|
assetDir,
|
|
6147
6323
|
platform,
|
|
6324
|
+
...(sessionId ? {
|
|
6325
|
+
sessionId
|
|
6326
|
+
} : {}),
|
|
6327
|
+
toolCallId: toolCall.callId,
|
|
6148
6328
|
...(toolEnablement ? {
|
|
6149
6329
|
toolEnablement
|
|
6150
6330
|
} : {}),
|
|
@@ -6298,6 +6478,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6298
6478
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6299
6479
|
assetDir,
|
|
6300
6480
|
platform,
|
|
6481
|
+
...(sessionId ? {
|
|
6482
|
+
sessionId
|
|
6483
|
+
} : {}),
|
|
6484
|
+
toolCallId: toolCall.callId,
|
|
6301
6485
|
...(toolEnablement ? {
|
|
6302
6486
|
toolEnablement
|
|
6303
6487
|
} : {}),
|
|
@@ -6378,6 +6562,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6378
6562
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6379
6563
|
assetDir,
|
|
6380
6564
|
platform,
|
|
6565
|
+
...(sessionId ? {
|
|
6566
|
+
sessionId
|
|
6567
|
+
} : {}),
|
|
6568
|
+
toolCallId: id,
|
|
6381
6569
|
useChatToolWorker,
|
|
6382
6570
|
workspaceUri
|
|
6383
6571
|
}) : '{}';
|
|
@@ -6653,7 +6841,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, us
|
|
|
6653
6841
|
}
|
|
6654
6842
|
return normalizedLimitInfo;
|
|
6655
6843
|
};
|
|
6656
|
-
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = true, questionToolEnabled = false, systemPrompt = '', workspaceUri = '', agentMode = defaultAgentMode, toolEnablement) => {
|
|
6844
|
+
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = true, questionToolEnabled = false, systemPrompt = '', workspaceUri = '', agentMode = defaultAgentMode, toolEnablement, sessionId) => {
|
|
6657
6845
|
const effectiveAgentMode = typeof agentMode === 'boolean' ? defaultAgentMode : agentMode;
|
|
6658
6846
|
const completionMessages = [...(systemPrompt ? [{
|
|
6659
6847
|
content: systemPrompt,
|
|
@@ -6815,6 +7003,10 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
|
|
|
6815
7003
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6816
7004
|
assetDir,
|
|
6817
7005
|
platform,
|
|
7006
|
+
...(sessionId ? {
|
|
7007
|
+
sessionId
|
|
7008
|
+
} : {}),
|
|
7009
|
+
toolCallId: id,
|
|
6818
7010
|
...(toolEnablement ? {
|
|
6819
7011
|
toolEnablement
|
|
6820
7012
|
} : {}),
|
|
@@ -6990,6 +7182,7 @@ const getAiResponse = async ({
|
|
|
6990
7182
|
questionToolEnabled = false,
|
|
6991
7183
|
reasoningEffort,
|
|
6992
7184
|
selectedModelId,
|
|
7185
|
+
sessionId,
|
|
6993
7186
|
streamingEnabled = true,
|
|
6994
7187
|
systemPrompt = '',
|
|
6995
7188
|
toolEnablement,
|
|
@@ -7001,6 +7194,7 @@ const getAiResponse = async ({
|
|
|
7001
7194
|
webSearchEnabled = false,
|
|
7002
7195
|
workspaceUri
|
|
7003
7196
|
}) => {
|
|
7197
|
+
useChatCoordinatorWorker = false; // TODO enable this
|
|
7004
7198
|
if (useChatCoordinatorWorker && !authEnabled) {
|
|
7005
7199
|
try {
|
|
7006
7200
|
const result = await getAiResponse$1({
|
|
@@ -7115,6 +7309,10 @@ const getAiResponse = async ({
|
|
|
7115
7309
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
7116
7310
|
assetDir,
|
|
7117
7311
|
platform,
|
|
7312
|
+
...(sessionId ? {
|
|
7313
|
+
sessionId
|
|
7314
|
+
} : {}),
|
|
7315
|
+
toolCallId: toolCall.callId,
|
|
7118
7316
|
...(toolEnablement ? {
|
|
7119
7317
|
toolEnablement
|
|
7120
7318
|
} : {}),
|
|
@@ -7173,6 +7371,9 @@ const getAiResponse = async ({
|
|
|
7173
7371
|
...(reasoningEffort ? {
|
|
7174
7372
|
reasoningEffort
|
|
7175
7373
|
} : {}),
|
|
7374
|
+
...(sessionId ? {
|
|
7375
|
+
sessionId
|
|
7376
|
+
} : {}),
|
|
7176
7377
|
stream: streamingEnabled,
|
|
7177
7378
|
supportsReasoningEffort,
|
|
7178
7379
|
systemPrompt,
|
|
@@ -7210,7 +7411,7 @@ const getAiResponse = async ({
|
|
|
7210
7411
|
text = getOpenRouterErrorMessage(result);
|
|
7211
7412
|
}
|
|
7212
7413
|
} else if (openRouterApiKey) {
|
|
7213
|
-
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement);
|
|
7414
|
+
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement, sessionId);
|
|
7214
7415
|
if (result.type === 'success') {
|
|
7215
7416
|
const {
|
|
7216
7417
|
text: assistantText
|
|
@@ -7792,24 +7993,31 @@ const updateMessageToolCallsInSelectedSession = (sessions, parsedMessages, selec
|
|
|
7792
7993
|
};
|
|
7793
7994
|
};
|
|
7794
7995
|
|
|
7795
|
-
const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls, handleTextChunkState) => {
|
|
7796
|
-
const
|
|
7996
|
+
const handleToolCallsChunkFunction = async (uid, sessionId, assistantMessageId, toolCalls, handleTextChunkState) => {
|
|
7997
|
+
const liveState = get$1(uid)?.newState || handleTextChunkState.latestState;
|
|
7998
|
+
const selectedSession = liveState.sessions.find(session => session.id === sessionId);
|
|
7797
7999
|
if (!selectedSession) {
|
|
7798
8000
|
return {
|
|
7799
|
-
latestState:
|
|
7800
|
-
previousState:
|
|
8001
|
+
latestState: liveState,
|
|
8002
|
+
previousState: liveState
|
|
8003
|
+
};
|
|
8004
|
+
}
|
|
8005
|
+
if (getChatSessionStatus(selectedSession) === 'stopped') {
|
|
8006
|
+
return {
|
|
8007
|
+
latestState: liveState,
|
|
8008
|
+
previousState: liveState
|
|
7801
8009
|
};
|
|
7802
8010
|
}
|
|
7803
8011
|
const assistantMessage = getMessageById(selectedSession.messages, assistantMessageId);
|
|
7804
8012
|
if (!assistantMessage) {
|
|
7805
8013
|
return {
|
|
7806
|
-
latestState:
|
|
7807
|
-
previousState:
|
|
8014
|
+
latestState: liveState,
|
|
8015
|
+
previousState: liveState
|
|
7808
8016
|
};
|
|
7809
8017
|
}
|
|
7810
|
-
const updated = updateMessageToolCallsInSelectedSession(
|
|
7811
|
-
const nextState = getNextHandleTextChunkState(
|
|
7812
|
-
await setAndRerenderHandleTextChunkState(uid,
|
|
8018
|
+
const updated = updateMessageToolCallsInSelectedSession(liveState.sessions, liveState.parsedMessages, sessionId, assistantMessageId, toolCalls);
|
|
8019
|
+
const nextState = getNextHandleTextChunkState(liveState, updated.parsedMessages, updated.sessions);
|
|
8020
|
+
await setAndRerenderHandleTextChunkState(uid, liveState, nextState);
|
|
7813
8021
|
return {
|
|
7814
8022
|
latestState: nextState,
|
|
7815
8023
|
previousState: nextState
|
|
@@ -7846,32 +8054,39 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
|
|
|
7846
8054
|
sessions: updatedSessions
|
|
7847
8055
|
};
|
|
7848
8056
|
};
|
|
7849
|
-
const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTextChunkState) => {
|
|
7850
|
-
const
|
|
8057
|
+
const handleTextChunkFunction = async (uid, sessionId, assistantMessageId, chunk, handleTextChunkState) => {
|
|
8058
|
+
const liveState = get$1(uid)?.newState || handleTextChunkState.latestState;
|
|
8059
|
+
const selectedSession = liveState.sessions.find(session => session.id === sessionId);
|
|
7851
8060
|
if (!selectedSession) {
|
|
7852
8061
|
return {
|
|
7853
|
-
latestState:
|
|
7854
|
-
previousState:
|
|
8062
|
+
latestState: liveState,
|
|
8063
|
+
previousState: liveState
|
|
8064
|
+
};
|
|
8065
|
+
}
|
|
8066
|
+
if (getChatSessionStatus(selectedSession) === 'stopped') {
|
|
8067
|
+
return {
|
|
8068
|
+
latestState: liveState,
|
|
8069
|
+
previousState: liveState
|
|
7855
8070
|
};
|
|
7856
8071
|
}
|
|
7857
8072
|
const assistantMessage = selectedSession.messages.find(message => message.id === assistantMessageId);
|
|
7858
8073
|
if (!assistantMessage) {
|
|
7859
8074
|
return {
|
|
7860
|
-
latestState:
|
|
7861
|
-
previousState:
|
|
8075
|
+
latestState: liveState,
|
|
8076
|
+
previousState: liveState
|
|
7862
8077
|
};
|
|
7863
8078
|
}
|
|
7864
8079
|
const updatedText = assistantMessage.text + chunk;
|
|
7865
|
-
const updated = await updateMessageTextInSelectedSession(
|
|
8080
|
+
const updated = await updateMessageTextInSelectedSession(liveState.sessions, liveState.parsedMessages, sessionId, assistantMessageId, updatedText, true);
|
|
7866
8081
|
const nextState = {
|
|
7867
|
-
...
|
|
7868
|
-
...(
|
|
7869
|
-
messagesScrollTop: getNextAutoScrollTop(
|
|
8082
|
+
...liveState,
|
|
8083
|
+
...(liveState.messagesAutoScrollEnabled ? {
|
|
8084
|
+
messagesScrollTop: getNextAutoScrollTop(liveState.messagesScrollTop)
|
|
7870
8085
|
} : {}),
|
|
7871
8086
|
parsedMessages: updated.parsedMessages,
|
|
7872
8087
|
sessions: updated.sessions
|
|
7873
8088
|
};
|
|
7874
|
-
set(uid,
|
|
8089
|
+
set(uid, liveState, nextState);
|
|
7875
8090
|
await invoke('Chat.rerender');
|
|
7876
8091
|
return {
|
|
7877
8092
|
latestState: nextState,
|
|
@@ -7970,6 +8185,32 @@ const withUpdatedMessageScrollTop = state => {
|
|
|
7970
8185
|
};
|
|
7971
8186
|
};
|
|
7972
8187
|
const workspaceUriPlaceholder = '{{workspaceUri}}';
|
|
8188
|
+
const getLiveState = uid => {
|
|
8189
|
+
const entry = get$1(uid);
|
|
8190
|
+
return entry?.newState;
|
|
8191
|
+
};
|
|
8192
|
+
const updateSessionStatus = (sessions, sessionId, status) => {
|
|
8193
|
+
return sessions.map(session => {
|
|
8194
|
+
if (session.id !== sessionId) {
|
|
8195
|
+
return session;
|
|
8196
|
+
}
|
|
8197
|
+
return {
|
|
8198
|
+
...session,
|
|
8199
|
+
status
|
|
8200
|
+
};
|
|
8201
|
+
});
|
|
8202
|
+
};
|
|
8203
|
+
const isSessionStopped = (uid, sessionId) => {
|
|
8204
|
+
const liveState = getLiveState(uid);
|
|
8205
|
+
if (!liveState) {
|
|
8206
|
+
return false;
|
|
8207
|
+
}
|
|
8208
|
+
const session = liveState.sessions.find(item => item.id === sessionId);
|
|
8209
|
+
if (!session) {
|
|
8210
|
+
return false;
|
|
8211
|
+
}
|
|
8212
|
+
return getChatSessionStatus(session) === 'stopped';
|
|
8213
|
+
};
|
|
7973
8214
|
const clearComposerAttachments = async (sessionId, attachmentIds) => {
|
|
7974
8215
|
if (!sessionId) {
|
|
7975
8216
|
return;
|
|
@@ -7995,11 +8236,22 @@ const getWorkspaceUri = (state, session) => {
|
|
|
7995
8236
|
}
|
|
7996
8237
|
return getProjectUri(state, session?.projectId || state.selectedProjectId);
|
|
7997
8238
|
};
|
|
7998
|
-
const
|
|
7999
|
-
const
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8239
|
+
const resolveWorkspaceUri = async (state, session) => {
|
|
8240
|
+
const workspaceUri = getWorkspaceUri(state, session);
|
|
8241
|
+
if (workspaceUri) {
|
|
8242
|
+
return workspaceUri;
|
|
8243
|
+
}
|
|
8244
|
+
try {
|
|
8245
|
+
return await getWorkspacePath();
|
|
8246
|
+
} catch {
|
|
8247
|
+
return '';
|
|
8248
|
+
}
|
|
8249
|
+
};
|
|
8250
|
+
const getEffectiveSystemPrompt = (state, workspaceUri) => {
|
|
8251
|
+
const resolvedSystemPrompt = state.systemPrompt.replaceAll(workspaceUriPlaceholder, workspaceUri || 'unknown');
|
|
8252
|
+
const currentDateInstructions = `Current date: ${getCurrentDate()}.
|
|
8253
|
+
|
|
8254
|
+
Do not assume your knowledge cutoff is the same as the current date.`;
|
|
8003
8255
|
if (!resolvedSystemPrompt) {
|
|
8004
8256
|
return currentDateInstructions;
|
|
8005
8257
|
}
|
|
@@ -8134,6 +8386,7 @@ const handleSubmit = async state => {
|
|
|
8134
8386
|
id: newSessionId,
|
|
8135
8387
|
messages: streamingEnabled ? [userMessage, inProgressAssistantMessage] : [userMessage],
|
|
8136
8388
|
projectId: state.selectedProjectId,
|
|
8389
|
+
status: 'in-progress',
|
|
8137
8390
|
title: `Chat ${workingSessions.length + 1}`
|
|
8138
8391
|
};
|
|
8139
8392
|
const provisionedSession = await withProvisionedBackgroundSession(state, newSession);
|
|
@@ -8173,7 +8426,8 @@ const handleSubmit = async state => {
|
|
|
8173
8426
|
}) : workingSessions;
|
|
8174
8427
|
const updatedWithUser = appendMessageToSelectedSession(workingSessionsWithProvisionedSession, selectedSessionId, userMessage);
|
|
8175
8428
|
const updatedSessions = streamingEnabled ? appendMessageToSelectedSession(updatedWithUser, selectedSessionId, inProgressAssistantMessage) : updatedWithUser;
|
|
8176
|
-
const
|
|
8429
|
+
const updatedSessionsWithStatus = updateSessionStatus(updatedSessions, selectedSessionId, 'in-progress');
|
|
8430
|
+
const selectedSession = updatedSessionsWithStatus.find(session => session.id === selectedSessionId);
|
|
8177
8431
|
if (selectedSession) {
|
|
8178
8432
|
await saveChatSession(selectedSession);
|
|
8179
8433
|
}
|
|
@@ -8189,7 +8443,7 @@ const handleSubmit = async state => {
|
|
|
8189
8443
|
lastSubmittedSessionId: selectedSessionId,
|
|
8190
8444
|
nextMessageId: nextMessageId + 1,
|
|
8191
8445
|
parsedMessages,
|
|
8192
|
-
sessions:
|
|
8446
|
+
sessions: updatedSessionsWithStatus
|
|
8193
8447
|
}));
|
|
8194
8448
|
optimisticState = withUpdatedChatInputHistory(optimisticState, userText);
|
|
8195
8449
|
}
|
|
@@ -8204,13 +8458,13 @@ const handleSubmit = async state => {
|
|
|
8204
8458
|
mockOpenApiRequests
|
|
8205
8459
|
} = optimisticState;
|
|
8206
8460
|
const selectedOptimisticSession = optimisticState.sessions.find(session => session.id === optimisticState.selectedSessionId);
|
|
8207
|
-
const
|
|
8208
|
-
const
|
|
8461
|
+
const workspaceUri = useMockApi ? getWorkspaceUri(optimisticState, selectedOptimisticSession) : await resolveWorkspaceUri(optimisticState, selectedOptimisticSession);
|
|
8462
|
+
const systemPrompt = getEffectiveSystemPrompt(optimisticState, workspaceUri);
|
|
8209
8463
|
const messages = (selectedOptimisticSession?.messages ?? []).filter(message => !message.inProgress);
|
|
8210
8464
|
const mentionContextMessage = await getMentionContextMessage(userText);
|
|
8211
8465
|
const messagesWithMentionContext = mentionContextMessage ? [...messages, mentionContextMessage] : messages;
|
|
8212
8466
|
const handleTextChunkFunctionRef = streamingEnabled ? async chunk => {
|
|
8213
|
-
handleTextChunkState = await handleTextChunkFunction(state.uid, assistantMessageId, chunk, handleTextChunkState);
|
|
8467
|
+
handleTextChunkState = await handleTextChunkFunction(state.uid, optimisticState.selectedSessionId, assistantMessageId, chunk, handleTextChunkState);
|
|
8214
8468
|
} : undefined;
|
|
8215
8469
|
const assistantMessage = await getAiResponse({
|
|
8216
8470
|
agentMode,
|
|
@@ -8226,6 +8480,9 @@ const handleSubmit = async state => {
|
|
|
8226
8480
|
models,
|
|
8227
8481
|
nextMessageId: optimisticState.nextMessageId,
|
|
8228
8482
|
onDataEvent: async value => {
|
|
8483
|
+
if (isSessionStopped(state.uid, optimisticState.selectedSessionId)) {
|
|
8484
|
+
return;
|
|
8485
|
+
}
|
|
8229
8486
|
if (!emitStreamingFunctionCallEvents && isStreamingFunctionCallEvent(value)) {
|
|
8230
8487
|
return;
|
|
8231
8488
|
}
|
|
@@ -8238,6 +8495,9 @@ const handleSubmit = async state => {
|
|
|
8238
8495
|
});
|
|
8239
8496
|
},
|
|
8240
8497
|
onEventStreamFinished: async () => {
|
|
8498
|
+
if (isSessionStopped(state.uid, optimisticState.selectedSessionId)) {
|
|
8499
|
+
return;
|
|
8500
|
+
}
|
|
8241
8501
|
await appendChatViewEvent({
|
|
8242
8502
|
sessionId: optimisticState.selectedSessionId,
|
|
8243
8503
|
timestamp: new Date().toISOString(),
|
|
@@ -8252,7 +8512,7 @@ const handleSubmit = async state => {
|
|
|
8252
8512
|
onTextChunk: handleTextChunkFunctionRef
|
|
8253
8513
|
} : {}),
|
|
8254
8514
|
onToolCallsChunk: async toolCalls => {
|
|
8255
|
-
handleTextChunkState = await handleToolCallsChunkFunction(state.uid, assistantMessageId, toolCalls, handleTextChunkState);
|
|
8515
|
+
handleTextChunkState = await handleToolCallsChunkFunction(state.uid, optimisticState.selectedSessionId, assistantMessageId, toolCalls, handleTextChunkState);
|
|
8256
8516
|
},
|
|
8257
8517
|
openApiApiBaseUrl,
|
|
8258
8518
|
openApiApiKey,
|
|
@@ -8265,6 +8525,7 @@ const handleSubmit = async state => {
|
|
|
8265
8525
|
} : {}),
|
|
8266
8526
|
reasoningEffort,
|
|
8267
8527
|
selectedModelId,
|
|
8528
|
+
sessionId: optimisticState.selectedSessionId,
|
|
8268
8529
|
streamingEnabled,
|
|
8269
8530
|
systemPrompt,
|
|
8270
8531
|
toolEnablement,
|
|
@@ -8276,6 +8537,9 @@ const handleSubmit = async state => {
|
|
|
8276
8537
|
webSearchEnabled,
|
|
8277
8538
|
workspaceUri
|
|
8278
8539
|
});
|
|
8540
|
+
if (isSessionStopped(state.uid, optimisticState.selectedSessionId)) {
|
|
8541
|
+
return getLiveState(state.uid) || handleTextChunkState.latestState;
|
|
8542
|
+
}
|
|
8279
8543
|
const {
|
|
8280
8544
|
latestState
|
|
8281
8545
|
} = handleTextChunkState;
|
|
@@ -8298,6 +8562,7 @@ const handleSubmit = async state => {
|
|
|
8298
8562
|
}
|
|
8299
8563
|
}
|
|
8300
8564
|
}
|
|
8565
|
+
updatedSessions = updateSessionStatus(updatedSessions, latestState.selectedSessionId, 'finished');
|
|
8301
8566
|
const selectedSession = updatedSessions.find(session => session.id === latestState.selectedSessionId);
|
|
8302
8567
|
if (selectedSession) {
|
|
8303
8568
|
await saveChatSession(selectedSession);
|
|
@@ -8315,6 +8580,36 @@ const handleClickSend = async state => {
|
|
|
8315
8580
|
return handleSubmit(state);
|
|
8316
8581
|
};
|
|
8317
8582
|
|
|
8583
|
+
const handleClickStop = async state => {
|
|
8584
|
+
const selectedSession = state.sessions.find(session => session.id === state.selectedSessionId);
|
|
8585
|
+
if (!selectedSession || getChatSessionStatus(selectedSession) !== 'in-progress') {
|
|
8586
|
+
return state;
|
|
8587
|
+
}
|
|
8588
|
+
const updatedSelectedSession = {
|
|
8589
|
+
...selectedSession,
|
|
8590
|
+
messages: selectedSession.messages.map(message => {
|
|
8591
|
+
if (message.role !== 'assistant' || !message.inProgress) {
|
|
8592
|
+
return message;
|
|
8593
|
+
}
|
|
8594
|
+
return {
|
|
8595
|
+
...message,
|
|
8596
|
+
inProgress: false
|
|
8597
|
+
};
|
|
8598
|
+
}),
|
|
8599
|
+
status: 'stopped'
|
|
8600
|
+
};
|
|
8601
|
+
await saveChatSession(updatedSelectedSession);
|
|
8602
|
+
return {
|
|
8603
|
+
...state,
|
|
8604
|
+
sessions: state.sessions.map(session => {
|
|
8605
|
+
if (session.id !== updatedSelectedSession.id) {
|
|
8606
|
+
return session;
|
|
8607
|
+
}
|
|
8608
|
+
return updatedSelectedSession;
|
|
8609
|
+
})
|
|
8610
|
+
};
|
|
8611
|
+
};
|
|
8612
|
+
|
|
8318
8613
|
const SwitchGitBranch = 'Chat.switchGitBranch';
|
|
8319
8614
|
const switchGitBranch = async ({
|
|
8320
8615
|
assetDir,
|
|
@@ -8765,6 +9060,8 @@ const handleClick = async (state, name, id = '', eventX = 0, eventY = 0) => {
|
|
|
8765
9060
|
return deleteProject(state, id);
|
|
8766
9061
|
case name === Send:
|
|
8767
9062
|
return handleClickSend(state);
|
|
9063
|
+
case name === Stop:
|
|
9064
|
+
return handleClickStop(state);
|
|
8768
9065
|
case name === ScrollDown:
|
|
8769
9066
|
return {
|
|
8770
9067
|
...state,
|
|
@@ -9412,10 +9709,57 @@ const handlePointerDownModelPickerList = async state => {
|
|
|
9412
9709
|
return state;
|
|
9413
9710
|
};
|
|
9414
9711
|
|
|
9712
|
+
const handlePointerDownProjectSidebarSash = async state => {
|
|
9713
|
+
if (state.projectSidebarResizing) {
|
|
9714
|
+
return state;
|
|
9715
|
+
}
|
|
9716
|
+
return {
|
|
9717
|
+
...state,
|
|
9718
|
+
projectSidebarResizing: true
|
|
9719
|
+
};
|
|
9720
|
+
};
|
|
9721
|
+
|
|
9722
|
+
const minimumProjectSidebarWidth = 180;
|
|
9723
|
+
const minimumChatAreaWidth = 320;
|
|
9724
|
+
const getProjectSidebarWidth = (state, clientX) => {
|
|
9725
|
+
const availableWidth = state.width > 0 ? state.width : state.projectSidebarWidth + minimumChatAreaWidth;
|
|
9726
|
+
const maximumProjectSidebarWidth = Math.max(minimumProjectSidebarWidth, availableWidth - minimumChatAreaWidth);
|
|
9727
|
+
const nextWidth = Math.round(clientX - state.x);
|
|
9728
|
+
return Math.min(Math.max(nextWidth, minimumProjectSidebarWidth), maximumProjectSidebarWidth);
|
|
9729
|
+
};
|
|
9730
|
+
const resizeProjectSidebar = (state, clientX) => {
|
|
9731
|
+
const projectSidebarWidth = getProjectSidebarWidth(state, clientX);
|
|
9732
|
+
if (projectSidebarWidth === state.projectSidebarWidth) {
|
|
9733
|
+
return state;
|
|
9734
|
+
}
|
|
9735
|
+
return {
|
|
9736
|
+
...state,
|
|
9737
|
+
projectSidebarWidth
|
|
9738
|
+
};
|
|
9739
|
+
};
|
|
9740
|
+
|
|
9741
|
+
const handlePointerMoveProjectSidebarSash = async (state, clientX) => {
|
|
9742
|
+
if (!state.projectSidebarResizing) {
|
|
9743
|
+
return state;
|
|
9744
|
+
}
|
|
9745
|
+
return resizeProjectSidebar(state, clientX);
|
|
9746
|
+
};
|
|
9747
|
+
|
|
9415
9748
|
const handlePointerUpModelPickerList = async (state, eventY = 0) => {
|
|
9416
9749
|
return state;
|
|
9417
9750
|
};
|
|
9418
9751
|
|
|
9752
|
+
const handlePointerUpProjectSidebarSash = async (state, clientX) => {
|
|
9753
|
+
if (!state.projectSidebarResizing) {
|
|
9754
|
+
return state;
|
|
9755
|
+
}
|
|
9756
|
+
const nextState = resizeProjectSidebar(state, clientX);
|
|
9757
|
+
return {
|
|
9758
|
+
...nextState,
|
|
9759
|
+
projectSidebarResizing: false
|
|
9760
|
+
};
|
|
9761
|
+
};
|
|
9762
|
+
|
|
9419
9763
|
const handleProjectAddButtonContextMenu = async (state, button, x, y) => {
|
|
9420
9764
|
const {
|
|
9421
9765
|
uid
|
|
@@ -9703,6 +10047,19 @@ const getSavedProjects = savedState => {
|
|
|
9703
10047
|
return validProjects;
|
|
9704
10048
|
};
|
|
9705
10049
|
|
|
10050
|
+
const getSavedProjectSidebarWidth = savedState => {
|
|
10051
|
+
if (!isObject$1(savedState)) {
|
|
10052
|
+
return undefined;
|
|
10053
|
+
}
|
|
10054
|
+
const {
|
|
10055
|
+
projectSidebarWidth
|
|
10056
|
+
} = savedState;
|
|
10057
|
+
if (typeof projectSidebarWidth !== 'number') {
|
|
10058
|
+
return undefined;
|
|
10059
|
+
}
|
|
10060
|
+
return projectSidebarWidth;
|
|
10061
|
+
};
|
|
10062
|
+
|
|
9706
10063
|
const getSavedReasoningEffort = savedState => {
|
|
9707
10064
|
if (!isObject$1(savedState)) {
|
|
9708
10065
|
return undefined;
|
|
@@ -9923,7 +10280,7 @@ const loadToolEnablement = async () => {
|
|
|
9923
10280
|
const savedToolEnablement = await get('chat.toolEnablement');
|
|
9924
10281
|
return parseToolEnablement(savedToolEnablement);
|
|
9925
10282
|
} catch {
|
|
9926
|
-
return
|
|
10283
|
+
return parseToolEnablement(undefined);
|
|
9927
10284
|
}
|
|
9928
10285
|
};
|
|
9929
10286
|
|
|
@@ -10099,6 +10456,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10099
10456
|
const chatListScrollTop = getSavedChatListScrollTop(savedState) ?? state.chatListScrollTop;
|
|
10100
10457
|
const messagesScrollTop = getSavedMessagesScrollTop(savedState) ?? state.messagesScrollTop;
|
|
10101
10458
|
const projectListScrollTop = getSavedProjectListScrollTop(savedState) ?? state.projectListScrollTop;
|
|
10459
|
+
const projectSidebarWidth = getSavedProjectSidebarWidth(savedState) ?? state.projectSidebarWidth;
|
|
10102
10460
|
const savedProjectExpandedIds = getSavedProjectExpandedIds(savedState);
|
|
10103
10461
|
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
10104
10462
|
const reasoningEffort = getSavedReasoningEffort(savedState) ?? state.reasoningEffort;
|
|
@@ -10153,6 +10511,8 @@ const loadContent = async (state, savedState) => {
|
|
|
10153
10511
|
projectExpandedIds,
|
|
10154
10512
|
projectListScrollTop,
|
|
10155
10513
|
projects,
|
|
10514
|
+
projectSidebarResizing: false,
|
|
10515
|
+
projectSidebarWidth,
|
|
10156
10516
|
reasoningEffort,
|
|
10157
10517
|
reasoningEffortPickerOpen: false,
|
|
10158
10518
|
reasoningPickerEnabled,
|
|
@@ -10341,7 +10701,7 @@ const removeComposerAttachment = async (state, attachmentId) => {
|
|
|
10341
10701
|
return handleRemoveComposerAttachment(state, attachmentId);
|
|
10342
10702
|
};
|
|
10343
10703
|
|
|
10344
|
-
const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
|
|
10704
|
+
const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, projectSidebarWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
|
|
10345
10705
|
const buttonsHeight = 20;
|
|
10346
10706
|
const gap = 10;
|
|
10347
10707
|
const contentPadding = 10;
|
|
@@ -10366,6 +10726,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10366
10726
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
10367
10727
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
10368
10728
|
--ChatFocusContentMaxWidth: ${chatFocusContentMaxWidth}px;
|
|
10729
|
+
--ProjectSidebarWidth: ${projectSidebarWidth}px;
|
|
10369
10730
|
--RunModePickerHeight: ${runModePickerHeight}px;
|
|
10370
10731
|
}
|
|
10371
10732
|
|
|
@@ -10418,6 +10779,14 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10418
10779
|
object-fit: cover;
|
|
10419
10780
|
}
|
|
10420
10781
|
|
|
10782
|
+
.ChatComposerAttachmentPreview,
|
|
10783
|
+
.ChatAttachmentPreview,
|
|
10784
|
+
.ChatMessageImage,
|
|
10785
|
+
.ChatComposerAttachmentPreviewOverlayImage,
|
|
10786
|
+
.ImageElement{
|
|
10787
|
+
cursor: default;
|
|
10788
|
+
}
|
|
10789
|
+
|
|
10421
10790
|
.ChatComposerAttachmentRemoveButton{
|
|
10422
10791
|
appearance: none;
|
|
10423
10792
|
background: transparent;
|
|
@@ -10679,7 +11048,41 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10679
11048
|
.Viewlet.Chat.ChatFocus{
|
|
10680
11049
|
display: flex !important;
|
|
10681
11050
|
min-width: 0;
|
|
11051
|
+
flex-direction: row !important;
|
|
11052
|
+
}
|
|
11053
|
+
|
|
11054
|
+
.ChatFocus > .ProjectSidebar{
|
|
11055
|
+
display: flex;
|
|
11056
|
+
flex: none;
|
|
11057
|
+
flex-direction: column;
|
|
11058
|
+
inline-size: var(--ProjectSidebarWidth);
|
|
11059
|
+
min-inline-size: 0;
|
|
11060
|
+
}
|
|
11061
|
+
|
|
11062
|
+
.ChatFocus > .ProjectSidebar > .ProjectList{
|
|
11063
|
+
flex: 1;
|
|
11064
|
+
min-height: 0;
|
|
11065
|
+
}
|
|
11066
|
+
|
|
11067
|
+
.ChatFocus > .Sash.SashVertical{
|
|
11068
|
+
position: relative;
|
|
11069
|
+
flex: none;
|
|
11070
|
+
inline-size: 4px;
|
|
11071
|
+
cursor: col-resize;
|
|
11072
|
+
touch-action: none;
|
|
11073
|
+
}
|
|
11074
|
+
|
|
11075
|
+
.ChatFocus > .Sash.SashVertical::before{
|
|
11076
|
+
content: '';
|
|
11077
|
+
position: absolute;
|
|
11078
|
+
inset: 0;
|
|
11079
|
+
background: color-mix(in srgb, var(--vscode-sideBar-border, var(--WidgetBorder, white)) 75%, transparent);
|
|
10682
11080
|
}
|
|
11081
|
+
|
|
11082
|
+
.ChatFocus > .Sash.SashVertical:hover::before{
|
|
11083
|
+
background: var(--vscode-focusBorder, var(--vscode-button-background));
|
|
11084
|
+
}
|
|
11085
|
+
|
|
10683
11086
|
.ChatFocusMainArea{
|
|
10684
11087
|
display: flex;
|
|
10685
11088
|
flex: 1;
|
|
@@ -10794,6 +11197,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10794
11197
|
composerHeight,
|
|
10795
11198
|
listItemHeight,
|
|
10796
11199
|
modelPickerHeight,
|
|
11200
|
+
projectSidebarWidth,
|
|
10797
11201
|
selectedSessionId,
|
|
10798
11202
|
sessions,
|
|
10799
11203
|
textAreaPaddingBottom,
|
|
@@ -10803,7 +11207,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10803
11207
|
uid
|
|
10804
11208
|
} = newState;
|
|
10805
11209
|
const renderHtmlCss = getRenderHtmlCss(sessions, selectedSessionId);
|
|
10806
|
-
const css = getCss(composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
11210
|
+
const css = getCss(composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, projectSidebarWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
10807
11211
|
return [SetCss, uid, css];
|
|
10808
11212
|
};
|
|
10809
11213
|
|
|
@@ -10982,9 +11386,13 @@ const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
|
10982
11386
|
const MaskIconChevronUp = 'MaskIconChevronUp';
|
|
10983
11387
|
const MaskIconClose = 'MaskIconClose';
|
|
10984
11388
|
const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
11389
|
+
const MaskIconDiff = 'MaskIconDiff';
|
|
11390
|
+
const MaskIconFolder = 'MaskIconFolder';
|
|
11391
|
+
const MaskIconGitCommit = 'MaskIconGitCommit';
|
|
10985
11392
|
const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
|
|
10986
11393
|
const MaskIconSearch = 'MaskIconSearch';
|
|
10987
11394
|
const MaskIconSettingsGear = 'MaskIconSettingsGear';
|
|
11395
|
+
const MaskIconTerminal = 'MaskIconTerminal';
|
|
10988
11396
|
const Message = 'Message';
|
|
10989
11397
|
const MessageAssistant = 'MessageAssistant';
|
|
10990
11398
|
const MessageUser = 'MessageUser';
|
|
@@ -11003,6 +11411,8 @@ const ProjectSessionItem = 'ProjectSessionItem';
|
|
|
11003
11411
|
const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
|
|
11004
11412
|
const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
|
|
11005
11413
|
const ProjectSidebar = 'ProjectSidebar';
|
|
11414
|
+
const Sash = 'Sash';
|
|
11415
|
+
const SashVertical = 'SashVertical';
|
|
11006
11416
|
const SearchFieldContainer = 'SearchFieldContainer';
|
|
11007
11417
|
const RunModePickerContainer = 'RunModePickerContainer';
|
|
11008
11418
|
const RunModePickerPopOver = 'RunModePickerPopOver';
|
|
@@ -11071,6 +11481,9 @@ const HandleContextMenuChatImageAttachment = 58;
|
|
|
11071
11481
|
const HandleClickGitBranchPickerToggle = 59;
|
|
11072
11482
|
const HandleErrorComposerAttachmentPreviewOverlay = 60;
|
|
11073
11483
|
const HandleClickCustomSelectOverlay = 61;
|
|
11484
|
+
const HandlePointerDownProjectSidebarSash = 62;
|
|
11485
|
+
const HandlePointerMoveProjectSidebarSash = 63;
|
|
11486
|
+
const HandlePointerUpProjectSidebarSash = 64;
|
|
11074
11487
|
|
|
11075
11488
|
const getAddContextButtonDom = () => {
|
|
11076
11489
|
return [{
|
|
@@ -11280,7 +11693,7 @@ const getSendButtonClassName = isSendDisabled => {
|
|
|
11280
11693
|
return mergeClassNames(IconButton, isSendDisabled ? SendButtonDisabled : '');
|
|
11281
11694
|
};
|
|
11282
11695
|
|
|
11283
|
-
const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
|
|
11696
|
+
const getSendButtonDom = (isSendDisabled, voiceDictationEnabled, isSessionInProgress) => {
|
|
11284
11697
|
const sendButtonClassName = getSendButtonClassName(isSendDisabled);
|
|
11285
11698
|
return [...(voiceDictationEnabled ? [{
|
|
11286
11699
|
childCount: 1,
|
|
@@ -11293,7 +11706,15 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
|
|
|
11293
11706
|
childCount: 0,
|
|
11294
11707
|
className: 'MaskIcon MaskIconMic',
|
|
11295
11708
|
type: Div
|
|
11296
|
-
}] : []), {
|
|
11709
|
+
}] : []), ...(isSessionInProgress ? [{
|
|
11710
|
+
buttonType: 'button',
|
|
11711
|
+
childCount: 1,
|
|
11712
|
+
className: Button,
|
|
11713
|
+
name: Stop,
|
|
11714
|
+
onClick: HandleClick,
|
|
11715
|
+
title: stop(),
|
|
11716
|
+
type: Button$1
|
|
11717
|
+
}, text(stop())] : [{
|
|
11297
11718
|
buttonType: 'submit',
|
|
11298
11719
|
childCount: 1,
|
|
11299
11720
|
className: sendButtonClassName,
|
|
@@ -11306,7 +11727,7 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
|
|
|
11306
11727
|
className: 'MaskIcon MaskIconArrowUp',
|
|
11307
11728
|
role: 'none',
|
|
11308
11729
|
type: Div
|
|
11309
|
-
}];
|
|
11730
|
+
}])];
|
|
11310
11731
|
};
|
|
11311
11732
|
|
|
11312
11733
|
const getTodoItemClassName = status => {
|
|
@@ -11380,34 +11801,51 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
11380
11801
|
}, text(usageLabel)];
|
|
11381
11802
|
};
|
|
11382
11803
|
|
|
11383
|
-
const
|
|
11804
|
+
const getComposerAttachmentClassName = displayType => {
|
|
11384
11805
|
switch (displayType) {
|
|
11385
11806
|
case 'file':
|
|
11386
|
-
return
|
|
11807
|
+
return ChatComposerAttachment;
|
|
11387
11808
|
case 'image':
|
|
11388
|
-
return
|
|
11809
|
+
return ChatComposerAttachmentImage;
|
|
11389
11810
|
case 'invalid-image':
|
|
11390
|
-
return
|
|
11811
|
+
return ChatComposerAttachmentInvalidImage;
|
|
11391
11812
|
case 'text-file':
|
|
11392
|
-
return
|
|
11813
|
+
return ChatComposerAttachmentTextFile;
|
|
11393
11814
|
default:
|
|
11394
|
-
return
|
|
11815
|
+
return ChatComposerAttachment;
|
|
11395
11816
|
}
|
|
11396
11817
|
};
|
|
11397
|
-
|
|
11818
|
+
|
|
11819
|
+
const getComposerAttachmentLabel = displayType => {
|
|
11398
11820
|
switch (displayType) {
|
|
11399
11821
|
case 'file':
|
|
11400
|
-
return
|
|
11822
|
+
return 'File';
|
|
11401
11823
|
case 'image':
|
|
11402
|
-
return
|
|
11824
|
+
return 'Image';
|
|
11403
11825
|
case 'invalid-image':
|
|
11404
|
-
return
|
|
11826
|
+
return 'Invalid image';
|
|
11405
11827
|
case 'text-file':
|
|
11406
|
-
return
|
|
11828
|
+
return 'Text file';
|
|
11407
11829
|
default:
|
|
11408
|
-
return
|
|
11830
|
+
return displayType;
|
|
11831
|
+
}
|
|
11832
|
+
};
|
|
11833
|
+
|
|
11834
|
+
const getComposerAttachmentPreviewDom = attachment => {
|
|
11835
|
+
if (!attachment.previewSrc) {
|
|
11836
|
+
return [];
|
|
11409
11837
|
}
|
|
11838
|
+
return [{
|
|
11839
|
+
alt: `Image preview for ${attachment.name}`,
|
|
11840
|
+
childCount: 0,
|
|
11841
|
+
className: ChatComposerAttachmentPreview,
|
|
11842
|
+
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11843
|
+
onContextMenu: HandleContextMenuChatImageAttachment,
|
|
11844
|
+
src: attachment.previewSrc,
|
|
11845
|
+
type: Img
|
|
11846
|
+
}];
|
|
11410
11847
|
};
|
|
11848
|
+
|
|
11411
11849
|
const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
11412
11850
|
return [{
|
|
11413
11851
|
'aria-label': removeAttachment(),
|
|
@@ -11423,20 +11861,7 @@ const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
|
11423
11861
|
type: Text
|
|
11424
11862
|
}];
|
|
11425
11863
|
};
|
|
11426
|
-
|
|
11427
|
-
if (!attachment.previewSrc) {
|
|
11428
|
-
return [];
|
|
11429
|
-
}
|
|
11430
|
-
return [{
|
|
11431
|
-
alt: `Image preview for ${attachment.name}`,
|
|
11432
|
-
childCount: 0,
|
|
11433
|
-
className: ChatComposerAttachmentPreview,
|
|
11434
|
-
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11435
|
-
onContextMenu: HandleContextMenuChatImageAttachment,
|
|
11436
|
-
src: attachment.previewSrc,
|
|
11437
|
-
type: Img
|
|
11438
|
-
}];
|
|
11439
|
-
};
|
|
11864
|
+
|
|
11440
11865
|
const getComposerAttachmentsDom = composerAttachments => {
|
|
11441
11866
|
if (composerAttachments.length === 0) {
|
|
11442
11867
|
return [];
|
|
@@ -11468,6 +11893,7 @@ const getComposerAttachmentsDom = composerAttachments => {
|
|
|
11468
11893
|
}];
|
|
11469
11894
|
})];
|
|
11470
11895
|
};
|
|
11896
|
+
|
|
11471
11897
|
const getComposerTextAreaDom = () => {
|
|
11472
11898
|
return {
|
|
11473
11899
|
childCount: 0,
|
|
@@ -11482,7 +11908,8 @@ const getComposerTextAreaDom = () => {
|
|
|
11482
11908
|
type: TextArea
|
|
11483
11909
|
};
|
|
11484
11910
|
};
|
|
11485
|
-
|
|
11911
|
+
|
|
11912
|
+
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, isSessionInProgress = false, scrollDownButtonEnabled = false, messagesAutoScrollEnabled = true) => {
|
|
11486
11913
|
const isSendDisabled = composerValue.trim() === '';
|
|
11487
11914
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
11488
11915
|
const showGitBranchPicker = gitBranchPickerVisible || Boolean(fallbackBranchName);
|
|
@@ -11512,7 +11939,7 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
|
|
|
11512
11939
|
className: ChatSendAreaPrimaryControls,
|
|
11513
11940
|
role: 'toolbar',
|
|
11514
11941
|
type: Div
|
|
11515
|
-
}, ...(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)];
|
|
11942
|
+
}, ...(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, isSessionInProgress)];
|
|
11516
11943
|
};
|
|
11517
11944
|
|
|
11518
11945
|
const authContainerStyle = 'align-items:center;display:flex;gap:8px;min-width:0;';
|
|
@@ -11570,26 +11997,57 @@ const getChatHeaderAuthDom = (authEnabled = false, userState = 'loggedOut', user
|
|
|
11570
11997
|
}, text(buttonLabel)];
|
|
11571
11998
|
};
|
|
11572
11999
|
|
|
12000
|
+
const getHeaderActionClassName = disabled => {
|
|
12001
|
+
return mergeClassNames(IconButton, disabled ? IconButtonDisabled : '');
|
|
12002
|
+
};
|
|
12003
|
+
const getHeaderActionVirtualDom = item => {
|
|
12004
|
+
return [{
|
|
12005
|
+
childCount: 1,
|
|
12006
|
+
className: getHeaderActionClassName(item.disabled),
|
|
12007
|
+
disabled: item.disabled,
|
|
12008
|
+
name: item.name,
|
|
12009
|
+
onClick: item.onClick,
|
|
12010
|
+
title: item.title,
|
|
12011
|
+
type: Button$1
|
|
12012
|
+
}, {
|
|
12013
|
+
childCount: 0,
|
|
12014
|
+
className: item.icon,
|
|
12015
|
+
type: Div
|
|
12016
|
+
}];
|
|
12017
|
+
};
|
|
12018
|
+
|
|
11573
12019
|
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;';
|
|
11574
12020
|
const focusHeaderMetaStyle = 'align-items:baseline;display:flex;gap:8px;min-width:0;overflow:hidden;';
|
|
11575
12021
|
const focusHeaderTitleStyle = 'margin:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11576
12022
|
const focusHeaderProjectStyle = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11577
12023
|
const focusHeaderActionsStyle = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;';
|
|
11578
|
-
const focusHeaderButtonStyle = 'white-space:nowrap;';
|
|
11579
|
-
const getFocusHeaderActionButtonDom = (label, name) => {
|
|
11580
|
-
return [{
|
|
11581
|
-
childCount: 1,
|
|
11582
|
-
className: mergeClassNames(Button, ButtonSecondary),
|
|
11583
|
-
inputType: 'button',
|
|
11584
|
-
name,
|
|
11585
|
-
onClick: HandleClick,
|
|
11586
|
-
style: focusHeaderButtonStyle,
|
|
11587
|
-
title: label,
|
|
11588
|
-
type: Button$1
|
|
11589
|
-
}, text(label)];
|
|
11590
|
-
};
|
|
11591
12024
|
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
11592
|
-
const items = [
|
|
12025
|
+
const items = [{
|
|
12026
|
+
icon: mergeClassNames(MaskIcon, MaskIconAdd),
|
|
12027
|
+
name: FocusAddAction,
|
|
12028
|
+
onClick: HandleClick,
|
|
12029
|
+
title: addAction()
|
|
12030
|
+
}, {
|
|
12031
|
+
icon: mergeClassNames(MaskIcon, MaskIconFolder),
|
|
12032
|
+
name: FocusOpenInVsCode,
|
|
12033
|
+
onClick: HandleClick,
|
|
12034
|
+
title: openInVsCode()
|
|
12035
|
+
}, {
|
|
12036
|
+
icon: mergeClassNames(MaskIcon, MaskIconGitCommit),
|
|
12037
|
+
name: FocusCommit,
|
|
12038
|
+
onClick: HandleClick,
|
|
12039
|
+
title: commit()
|
|
12040
|
+
}, {
|
|
12041
|
+
icon: mergeClassNames(MaskIcon, MaskIconTerminal),
|
|
12042
|
+
name: FocusOpenTerminal,
|
|
12043
|
+
onClick: HandleClick,
|
|
12044
|
+
title: openTerminal()
|
|
12045
|
+
}, {
|
|
12046
|
+
icon: mergeClassNames(MaskIcon, MaskIconDiff),
|
|
12047
|
+
name: FocusShowDiff,
|
|
12048
|
+
onClick: HandleClick,
|
|
12049
|
+
title: showDiff()
|
|
12050
|
+
}];
|
|
11593
12051
|
const hasProjectName = !!selectedProjectName;
|
|
11594
12052
|
return [{
|
|
11595
12053
|
childCount: 2 + (authEnabled ? 1 : 0),
|
|
@@ -11618,7 +12076,7 @@ const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, au
|
|
|
11618
12076
|
role: ToolBar,
|
|
11619
12077
|
style: focusHeaderActionsStyle,
|
|
11620
12078
|
type: Div
|
|
11621
|
-
}, ...items.flatMap(
|
|
12079
|
+
}, ...items.flatMap(getHeaderActionVirtualDom)];
|
|
11622
12080
|
};
|
|
11623
12081
|
|
|
11624
12082
|
const getAgentModeOptionsVirtualDom = selectedAgentMode => {
|
|
@@ -11654,10 +12112,6 @@ const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
|
|
|
11654
12112
|
return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
|
|
11655
12113
|
};
|
|
11656
12114
|
|
|
11657
|
-
const getUsageCostLabel = model => {
|
|
11658
|
-
return `${model.usageCost ?? 1}x`;
|
|
11659
|
-
};
|
|
11660
|
-
|
|
11661
12115
|
const getUsageCostDom = detail => {
|
|
11662
12116
|
if (detail === '') {
|
|
11663
12117
|
return [];
|
|
@@ -11668,6 +12122,11 @@ const getUsageCostDom = detail => {
|
|
|
11668
12122
|
type: Span
|
|
11669
12123
|
}, text(detail)];
|
|
11670
12124
|
};
|
|
12125
|
+
|
|
12126
|
+
const getUsageCostLabel = model => {
|
|
12127
|
+
return `${model.usageCost ?? 1}x`;
|
|
12128
|
+
};
|
|
12129
|
+
|
|
11671
12130
|
const getChatModelListItemVirtualDom = (model, selectedModelId) => {
|
|
11672
12131
|
const detail = getUsageCostLabel(model);
|
|
11673
12132
|
const hasDetail = detail !== '';
|
|
@@ -11733,6 +12192,7 @@ const getModelPickerHeaderDom = modelPickerSearchValue => {
|
|
|
11733
12192
|
value: modelPickerSearchValue
|
|
11734
12193
|
}];
|
|
11735
12194
|
};
|
|
12195
|
+
|
|
11736
12196
|
const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPickerSearchValue) => {
|
|
11737
12197
|
const visibleModels = getVisibleModels(models, modelPickerSearchValue);
|
|
11738
12198
|
return [{
|
|
@@ -11787,15 +12247,6 @@ const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, atta
|
|
|
11787
12247
|
}])];
|
|
11788
12248
|
};
|
|
11789
12249
|
|
|
11790
|
-
const runModes = ['local', 'background', 'cloud'];
|
|
11791
|
-
const runModePickerHeight = runModes.length * 28;
|
|
11792
|
-
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
11793
|
-
return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
|
|
11794
|
-
};
|
|
11795
|
-
const getRunModePickerPopOverVirtualDom = selectedRunMode => {
|
|
11796
|
-
return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver, false);
|
|
11797
|
-
};
|
|
11798
|
-
|
|
11799
12250
|
const getDropOverlayVirtualDom = () => {
|
|
11800
12251
|
return [{
|
|
11801
12252
|
childCount: 1,
|
|
@@ -11810,6 +12261,16 @@ const getDropOverlayVirtualDom = () => {
|
|
|
11810
12261
|
type: Text
|
|
11811
12262
|
}];
|
|
11812
12263
|
};
|
|
12264
|
+
|
|
12265
|
+
const runModes = ['local', 'background', 'cloud'];
|
|
12266
|
+
const runModePickerHeight = runModes.length * 28;
|
|
12267
|
+
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
12268
|
+
return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
|
|
12269
|
+
};
|
|
12270
|
+
const getRunModePickerPopOverVirtualDom = selectedRunMode => {
|
|
12271
|
+
return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver, false);
|
|
12272
|
+
};
|
|
12273
|
+
|
|
11813
12274
|
const getChatOverlaysVirtualDom = ({
|
|
11814
12275
|
agentMode,
|
|
11815
12276
|
agentModePickerVisible,
|
|
@@ -12448,14 +12909,16 @@ const getReadFileTarget = rawArguments => {
|
|
|
12448
12909
|
}
|
|
12449
12910
|
const uri = Reflect.get(parsed, 'uri');
|
|
12450
12911
|
const path = Reflect.get(parsed, 'path');
|
|
12912
|
+
const baseUri = Reflect.get(parsed, 'baseUri');
|
|
12451
12913
|
const uriValue = typeof uri === 'string' ? uri : '';
|
|
12452
12914
|
const pathValue = typeof path === 'string' ? path : '';
|
|
12453
|
-
const
|
|
12915
|
+
const baseUriValue = typeof baseUri === 'string' ? baseUri : '';
|
|
12916
|
+
const title = uriValue || pathValue || baseUriValue;
|
|
12454
12917
|
if (!title) {
|
|
12455
12918
|
return undefined;
|
|
12456
12919
|
}
|
|
12457
|
-
//
|
|
12458
|
-
const clickableUri = uriValue || pathValue;
|
|
12920
|
+
// File-like tool calls use absolute `uri` where available; keep `path` as a legacy fallback.
|
|
12921
|
+
const clickableUri = uriValue || pathValue || baseUriValue;
|
|
12459
12922
|
return {
|
|
12460
12923
|
clickableUri,
|
|
12461
12924
|
title
|
|
@@ -12466,11 +12929,12 @@ const getToolCallFileNameDom = (fileName, {
|
|
|
12466
12929
|
clickableProps = {},
|
|
12467
12930
|
title
|
|
12468
12931
|
} = {}) => {
|
|
12932
|
+
const resolvedTitle = title ?? clickableProps['data-uri'];
|
|
12469
12933
|
return [{
|
|
12470
12934
|
childCount: 1,
|
|
12471
12935
|
className: ChatToolCallReadFileLink,
|
|
12472
|
-
...(
|
|
12473
|
-
title
|
|
12936
|
+
...(resolvedTitle === undefined ? {} : {
|
|
12937
|
+
title: resolvedTitle
|
|
12474
12938
|
}),
|
|
12475
12939
|
...clickableProps,
|
|
12476
12940
|
type: Span
|
|
@@ -12496,7 +12960,6 @@ const getToolCallCreateDirectoryVirtualDom = toolCall => {
|
|
|
12496
12960
|
return [{
|
|
12497
12961
|
childCount: statusLabel ? 4 : 3,
|
|
12498
12962
|
className: ChatOrderedListItem,
|
|
12499
|
-
title: target.title,
|
|
12500
12963
|
type: Li
|
|
12501
12964
|
}, {
|
|
12502
12965
|
childCount: 0,
|
|
@@ -12574,7 +13037,7 @@ const getToolCallLabel = toolCall => {
|
|
|
12574
13037
|
if (toolCall.name === 'write_file' && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12575
13038
|
return `${displayName} (in progress)`;
|
|
12576
13039
|
}
|
|
12577
|
-
if ((toolCall.name === 'list_files' || toolCall.name === 'grep_search') && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
13040
|
+
if ((toolCall.name === 'list_files' || toolCall.name === 'grep_search' || toolCall.name === 'glob') && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12578
13041
|
return displayName;
|
|
12579
13042
|
}
|
|
12580
13043
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
@@ -12620,7 +13083,6 @@ const getToolCallEditFileVirtualDom = toolCall => {
|
|
|
12620
13083
|
return [{
|
|
12621
13084
|
childCount: 3,
|
|
12622
13085
|
className: ChatOrderedListItem,
|
|
12623
|
-
title: target.title,
|
|
12624
13086
|
type: Li
|
|
12625
13087
|
}, {
|
|
12626
13088
|
childCount: 0,
|
|
@@ -12649,7 +13111,6 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12649
13111
|
return [{
|
|
12650
13112
|
childCount: statusLabel ? 4 : 3,
|
|
12651
13113
|
className: ChatOrderedListItem,
|
|
12652
|
-
title: toolCall.result,
|
|
12653
13114
|
type: Li
|
|
12654
13115
|
}, {
|
|
12655
13116
|
childCount: 0,
|
|
@@ -12664,6 +13125,21 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12664
13125
|
}), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12665
13126
|
};
|
|
12666
13127
|
|
|
13128
|
+
const getGlobPatternLabel = toolCall => {
|
|
13129
|
+
if (toolCall.name !== 'glob') {
|
|
13130
|
+
return '';
|
|
13131
|
+
}
|
|
13132
|
+
try {
|
|
13133
|
+
const parsed = JSON.parse(toolCall.arguments);
|
|
13134
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
13135
|
+
return '';
|
|
13136
|
+
}
|
|
13137
|
+
const pattern = Reflect.get(parsed, 'pattern');
|
|
13138
|
+
return typeof pattern === 'string' && pattern ? ` "${pattern}"` : '';
|
|
13139
|
+
} catch {
|
|
13140
|
+
return '';
|
|
13141
|
+
}
|
|
13142
|
+
};
|
|
12667
13143
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
12668
13144
|
const target = getReadFileTarget(toolCall.arguments);
|
|
12669
13145
|
if (!target) {
|
|
@@ -12672,14 +13148,16 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12672
13148
|
const fileName = getFileNameFromUri(target.title);
|
|
12673
13149
|
const toolNameLabel = `${toolCall.name} `;
|
|
12674
13150
|
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
13151
|
+
const globPatternLabel = getGlobPatternLabel(toolCall);
|
|
13152
|
+
const globMatchCount = toolCall.name === 'glob' && toolCall.status === 'success' ? getGlobMatchCount(toolCall.result) : undefined;
|
|
13153
|
+
const globMatchLabel = typeof globMatchCount === 'number' ? `, ${globMatchCount} ${globMatchCount === 1 ? 'match' : 'matches'}` : '';
|
|
12675
13154
|
const fileNameClickableProps = target.clickableUri ? {
|
|
12676
13155
|
'data-uri': target.clickableUri,
|
|
12677
13156
|
onClick: HandleClickFileName
|
|
12678
13157
|
} : {};
|
|
12679
13158
|
return [{
|
|
12680
|
-
childCount: statusLabel ?
|
|
13159
|
+
childCount: 3 + (globPatternLabel ? 1 : 0) + (globMatchLabel ? 1 : 0) + (statusLabel ? 1 : 0),
|
|
12681
13160
|
className: ChatOrderedListItem,
|
|
12682
|
-
title: target.title,
|
|
12683
13161
|
type: Li
|
|
12684
13162
|
}, {
|
|
12685
13163
|
childCount: 0,
|
|
@@ -12690,8 +13168,9 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12690
13168
|
className: ToolCallName,
|
|
12691
13169
|
type: Span
|
|
12692
13170
|
}, text(toolNameLabel), ...getToolCallFileNameDom(fileName, {
|
|
12693
|
-
clickableProps: fileNameClickableProps
|
|
12694
|
-
|
|
13171
|
+
clickableProps: fileNameClickableProps,
|
|
13172
|
+
title: target.title
|
|
13173
|
+
}), ...(globPatternLabel ? [text(globPatternLabel)] : []), ...(globMatchLabel ? [text(globMatchLabel)] : []), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12695
13174
|
};
|
|
12696
13175
|
|
|
12697
13176
|
const maxHtmlLength = 40_000;
|
|
@@ -13058,7 +13537,6 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
13058
13537
|
return [{
|
|
13059
13538
|
childCount: showDiffStats ? statusLabel ? 6 : 5 : statusLabel ? 4 : 3,
|
|
13060
13539
|
className: ChatOrderedListItem,
|
|
13061
|
-
title: target.title,
|
|
13062
13540
|
type: Li
|
|
13063
13541
|
}, {
|
|
13064
13542
|
childCount: 0,
|
|
@@ -13088,7 +13566,7 @@ const getToolCallDom = toolCall => {
|
|
|
13088
13566
|
return virtualDom;
|
|
13089
13567
|
}
|
|
13090
13568
|
}
|
|
13091
|
-
if (toolCall.name === 'read_file' || toolCall.name === 'list_files' || toolCall.name === 'list_file') {
|
|
13569
|
+
if (toolCall.name === 'read_file' || toolCall.name === 'list_files' || toolCall.name === 'list_file' || toolCall.name === 'glob') {
|
|
13092
13570
|
const virtualDom = getToolCallReadFileVirtualDom(toolCall);
|
|
13093
13571
|
if (virtualDom.length > 0) {
|
|
13094
13572
|
return virtualDom;
|
|
@@ -13577,17 +14055,27 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13577
14055
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13578
14056
|
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13579
14057
|
const chatRootChildCount = 2 + (hasVisibleOverlays ? 1 : 0);
|
|
14058
|
+
const isSelectedSessionInProgress = selectedSession ? getChatSessionStatus(selectedSession) === 'in-progress' : false;
|
|
13580
14059
|
return [{
|
|
13581
|
-
childCount: chatRootChildCount,
|
|
14060
|
+
childCount: chatRootChildCount + 1,
|
|
13582
14061
|
className: mergeClassNames(Viewlet, Chat, ChatFocus),
|
|
13583
14062
|
onDragEnter: HandleDragEnterChatView,
|
|
13584
14063
|
onDragOver: HandleDragOverChatView,
|
|
14064
|
+
onPointerMove: HandlePointerMoveProjectSidebarSash,
|
|
14065
|
+
onPointerUp: HandlePointerUpProjectSidebarSash,
|
|
13585
14066
|
type: Div
|
|
13586
14067
|
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), {
|
|
14068
|
+
'aria-orientation': 'vertical',
|
|
14069
|
+
childCount: 0,
|
|
14070
|
+
className: mergeClassNames(Sash, SashVertical),
|
|
14071
|
+
onPointerDown: HandlePointerDownProjectSidebarSash,
|
|
14072
|
+
role: 'separator',
|
|
14073
|
+
type: Div
|
|
14074
|
+
}, {
|
|
13587
14075
|
childCount: 3,
|
|
13588
14076
|
className: ChatFocusMainArea,
|
|
13589
14077
|
type: Div
|
|
13590
|
-
}, ...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({
|
|
14078
|
+
}, ...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, isSelectedSessionInProgress, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
13591
14079
|
agentMode,
|
|
13592
14080
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13593
14081
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -13621,25 +14109,6 @@ const getBackButtonVirtualDom = () => {
|
|
|
13621
14109
|
}, arrowLeft];
|
|
13622
14110
|
};
|
|
13623
14111
|
|
|
13624
|
-
const getHeaderActionClassName = disabled => {
|
|
13625
|
-
return mergeClassNames(IconButton, disabled ? IconButtonDisabled : '');
|
|
13626
|
-
};
|
|
13627
|
-
const getHeaderActionVirtualDom = item => {
|
|
13628
|
-
return [{
|
|
13629
|
-
childCount: 1,
|
|
13630
|
-
className: getHeaderActionClassName(item.disabled),
|
|
13631
|
-
disabled: item.disabled,
|
|
13632
|
-
name: item.name,
|
|
13633
|
-
onClick: item.onClick,
|
|
13634
|
-
title: item.title,
|
|
13635
|
-
type: Button$1
|
|
13636
|
-
}, {
|
|
13637
|
-
childCount: 0,
|
|
13638
|
-
className: item.icon,
|
|
13639
|
-
type: Div
|
|
13640
|
-
}];
|
|
13641
|
-
};
|
|
13642
|
-
|
|
13643
14112
|
const getChatHeaderActionsDom = (viewMode, searchEnabled = false) => {
|
|
13644
14113
|
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
13645
14114
|
const items = [{
|
|
@@ -13762,6 +14231,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13762
14231
|
voiceDictationEnabled = false
|
|
13763
14232
|
}) => {
|
|
13764
14233
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
14234
|
+
const isSelectedSessionInProgress = selectedSession ? getChatSessionStatus(selectedSession) === 'in-progress' : false;
|
|
13765
14235
|
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
13766
14236
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
13767
14237
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
@@ -13778,7 +14248,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13778
14248
|
onDragEnter: HandleDragEnterChatView,
|
|
13779
14249
|
onDragOver: HandleDragOverChatView,
|
|
13780
14250
|
type: Div
|
|
13781
|
-
}, ...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({
|
|
14251
|
+
}, ...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, isSelectedSessionInProgress, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
13782
14252
|
agentMode,
|
|
13783
14253
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13784
14254
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -13814,6 +14284,7 @@ const getChatSearchDom = (hasSearchField, searchValue) => {
|
|
|
13814
14284
|
value: searchValue
|
|
13815
14285
|
}];
|
|
13816
14286
|
};
|
|
14287
|
+
|
|
13817
14288
|
const getChatHeaderListModeDom = (authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
|
|
13818
14289
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
13819
14290
|
const hasSearchField = searchEnabled && searchFieldVisible;
|
|
@@ -13849,12 +14320,11 @@ const getEmptyChatSessionsDom = () => {
|
|
|
13849
14320
|
};
|
|
13850
14321
|
|
|
13851
14322
|
const getSessionStatusClassName = session => {
|
|
13852
|
-
const
|
|
13853
|
-
if (
|
|
14323
|
+
const status = getChatSessionStatus(session);
|
|
14324
|
+
if (status === 'in-progress') {
|
|
13854
14325
|
return ChatListItemStatusInProgress;
|
|
13855
14326
|
}
|
|
13856
|
-
|
|
13857
|
-
if (hasAssistantMessage) {
|
|
14327
|
+
if (status === 'finished') {
|
|
13858
14328
|
return ChatListItemStatusFinished;
|
|
13859
14329
|
}
|
|
13860
14330
|
return ChatListItemStatusStopped;
|
|
@@ -13981,7 +14451,7 @@ const getChatModeListVirtualDom = ({
|
|
|
13981
14451
|
onDragEnter: HandleDragEnterChatView,
|
|
13982
14452
|
onDragOver: HandleDragOverChatView,
|
|
13983
14453
|
type: Div
|
|
13984
|
-
}, ...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({
|
|
14454
|
+
}, ...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, false), ...getChatOverlaysVirtualDom({
|
|
13985
14455
|
agentMode,
|
|
13986
14456
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13987
14457
|
composerAttachmentPreviewOverlayAttachmentId,
|
|
@@ -14714,6 +15184,17 @@ const renderEventListeners = () => {
|
|
|
14714
15184
|
name: HandlePointerDownModelPickerList,
|
|
14715
15185
|
params: ['handlePointerDownModelPickerList'],
|
|
14716
15186
|
preventDefault: true
|
|
15187
|
+
}, {
|
|
15188
|
+
name: HandlePointerDownProjectSidebarSash,
|
|
15189
|
+
params: ['handlePointerDownProjectSidebarSash'],
|
|
15190
|
+
preventDefault: true
|
|
15191
|
+
}, {
|
|
15192
|
+
name: HandlePointerMoveProjectSidebarSash,
|
|
15193
|
+
params: ['handlePointerMoveProjectSidebarSash', ClientX]
|
|
15194
|
+
}, {
|
|
15195
|
+
name: HandlePointerUpProjectSidebarSash,
|
|
15196
|
+
params: ['handlePointerUpProjectSidebarSash', ClientX],
|
|
15197
|
+
preventDefault: true
|
|
14717
15198
|
}, {
|
|
14718
15199
|
name: HandlePointerUpModelPickerList,
|
|
14719
15200
|
params: ['handlePointerUpModelPickerList', ClientY],
|
|
@@ -14827,6 +15308,7 @@ const saveState = state => {
|
|
|
14827
15308
|
projectExpandedIds,
|
|
14828
15309
|
projectListScrollTop,
|
|
14829
15310
|
projects,
|
|
15311
|
+
projectSidebarWidth,
|
|
14830
15312
|
reasoningEffort,
|
|
14831
15313
|
renamingSessionId,
|
|
14832
15314
|
searchFieldVisible,
|
|
@@ -14849,6 +15331,7 @@ const saveState = state => {
|
|
|
14849
15331
|
projectExpandedIds,
|
|
14850
15332
|
projectListScrollTop,
|
|
14851
15333
|
projects,
|
|
15334
|
+
projectSidebarWidth,
|
|
14852
15335
|
reasoningEffort,
|
|
14853
15336
|
renamingSessionId,
|
|
14854
15337
|
searchFieldVisible,
|
|
@@ -15119,7 +15602,10 @@ const commandMap = {
|
|
|
15119
15602
|
'Chat.handleMouseOut': wrapCommand(handleMouseOut),
|
|
15120
15603
|
'Chat.handleMouseOver': wrapCommand(handleMouseOver),
|
|
15121
15604
|
'Chat.handlePointerDownModelPickerList': wrapCommand(handlePointerDownModelPickerList),
|
|
15605
|
+
'Chat.handlePointerDownProjectSidebarSash': wrapCommand(handlePointerDownProjectSidebarSash),
|
|
15606
|
+
'Chat.handlePointerMoveProjectSidebarSash': wrapCommand(handlePointerMoveProjectSidebarSash),
|
|
15122
15607
|
'Chat.handlePointerUpModelPickerList': wrapCommand(handlePointerUpModelPickerList),
|
|
15608
|
+
'Chat.handlePointerUpProjectSidebarSash': wrapCommand(handlePointerUpProjectSidebarSash),
|
|
15123
15609
|
'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
|
|
15124
15610
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
15125
15611
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|