@lvce-editor/chat-view 7.3.0 → 7.5.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 +638 -219
- 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);
|
|
@@ -1485,10 +1488,6 @@ const terminate = () => {
|
|
|
1485
1488
|
globalThis.close();
|
|
1486
1489
|
};
|
|
1487
1490
|
|
|
1488
|
-
const getComposerWidth = width => {
|
|
1489
|
-
return Math.max(1, width - 32);
|
|
1490
|
-
};
|
|
1491
|
-
|
|
1492
1491
|
const composerAttachmentGap = 8;
|
|
1493
1492
|
const composerAttachmentMarginBottom = 8;
|
|
1494
1493
|
const composerAttachmentFontSize = 12;
|
|
@@ -1497,6 +1496,18 @@ const composerAttachmentBorderWidth = 2;
|
|
|
1497
1496
|
const composerAttachmentHeight = 26;
|
|
1498
1497
|
const averageCharacterWidth = composerAttachmentFontSize * 0.6;
|
|
1499
1498
|
const fallbackComposerWidth = 480;
|
|
1499
|
+
|
|
1500
|
+
const getComposerWidth = width => {
|
|
1501
|
+
return Math.max(1, width - 32);
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
const getAttachmentContainerWidth = width => {
|
|
1505
|
+
if (width <= 0) {
|
|
1506
|
+
return fallbackComposerWidth;
|
|
1507
|
+
}
|
|
1508
|
+
return Math.max(1, getComposerWidth(width));
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1500
1511
|
const getComposerAttachmentLabel$1 = displayType => {
|
|
1501
1512
|
switch (displayType) {
|
|
1502
1513
|
case 'file':
|
|
@@ -1511,17 +1522,13 @@ const getComposerAttachmentLabel$1 = displayType => {
|
|
|
1511
1522
|
return displayType;
|
|
1512
1523
|
}
|
|
1513
1524
|
};
|
|
1514
|
-
|
|
1515
|
-
if (width <= 0) {
|
|
1516
|
-
return fallbackComposerWidth;
|
|
1517
|
-
}
|
|
1518
|
-
return Math.max(1, getComposerWidth(width));
|
|
1519
|
-
};
|
|
1525
|
+
|
|
1520
1526
|
const getComposerAttachmentWidth = (attachment, containerWidth) => {
|
|
1521
1527
|
const label = `${getComposerAttachmentLabel$1(attachment.displayType)} · ${attachment.name}`;
|
|
1522
1528
|
const estimatedWidth = Math.ceil(label.length * averageCharacterWidth) + composerAttachmentHorizontalPadding + composerAttachmentBorderWidth;
|
|
1523
1529
|
return Math.min(containerWidth, estimatedWidth);
|
|
1524
1530
|
};
|
|
1531
|
+
|
|
1525
1532
|
const getComposerAttachmentsHeight = (composerAttachments, width) => {
|
|
1526
1533
|
if (composerAttachments.length === 0) {
|
|
1527
1534
|
return 0;
|
|
@@ -2218,6 +2225,7 @@ Use available project context to provide accurate, practical coding help.
|
|
|
2218
2225
|
Prefer using available tools to inspect and modify files in the current workspace.
|
|
2219
2226
|
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.
|
|
2220
2227
|
Only provide raw code snippets when explicitly requested or when file editing tools are unavailable.
|
|
2228
|
+
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\`.
|
|
2221
2229
|
When displaying code blocks in responses, use markdown triple backticks (\`\`\`) fences.
|
|
2222
2230
|
When referencing workspace files in responses (including "files added/changed" lists), use markdown links so users can click them.
|
|
2223
2231
|
Prefer file links like [src/index.ts]({{workspaceUri}}/src/index.ts) and avoid plain text file paths when a link is appropriate.
|
|
@@ -2287,11 +2295,16 @@ const getReasoningEffortLabel = reasoningEffort => {
|
|
|
2287
2295
|
}
|
|
2288
2296
|
};
|
|
2289
2297
|
|
|
2298
|
+
const defaultToolEnablement = {
|
|
2299
|
+
run_in_terminal: false
|
|
2300
|
+
};
|
|
2290
2301
|
const parseToolEnablement = value => {
|
|
2291
2302
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
2292
|
-
return
|
|
2303
|
+
return defaultToolEnablement;
|
|
2293
2304
|
}
|
|
2294
|
-
const toolEnablement = {
|
|
2305
|
+
const toolEnablement = {
|
|
2306
|
+
...defaultToolEnablement
|
|
2307
|
+
};
|
|
2295
2308
|
for (const [key, enabled] of Object.entries(value)) {
|
|
2296
2309
|
if (typeof enabled === 'boolean') {
|
|
2297
2310
|
toolEnablement[key] = enabled;
|
|
@@ -2316,10 +2329,13 @@ const validateToolEnablement = value => {
|
|
|
2316
2329
|
};
|
|
2317
2330
|
const isToolEnabled = (toolEnablement, toolName) => {
|
|
2318
2331
|
if (!toolEnablement) {
|
|
2319
|
-
return true;
|
|
2332
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2320
2333
|
}
|
|
2321
2334
|
const enabled = toolEnablement[toolName];
|
|
2322
|
-
|
|
2335
|
+
if (typeof enabled === 'boolean') {
|
|
2336
|
+
return enabled;
|
|
2337
|
+
}
|
|
2338
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2323
2339
|
};
|
|
2324
2340
|
const filterEnabledTools = (tools, toolEnablement) => {
|
|
2325
2341
|
return tools.filter(tool => isToolEnabled(toolEnablement, tool.function.name));
|
|
@@ -2395,7 +2411,7 @@ const createDefaultState = () => {
|
|
|
2395
2411
|
maxToolCalls: defaultMaxToolCalls,
|
|
2396
2412
|
messagesAutoScrollEnabled: true,
|
|
2397
2413
|
messagesScrollTop: 0,
|
|
2398
|
-
mockAiResponseDelay:
|
|
2414
|
+
mockAiResponseDelay: 0,
|
|
2399
2415
|
mockApiCommandId: '',
|
|
2400
2416
|
mockOpenApiRequests: [],
|
|
2401
2417
|
modelPickerHeaderHeight,
|
|
@@ -2427,6 +2443,8 @@ const createDefaultState = () => {
|
|
|
2427
2443
|
name: '_blank',
|
|
2428
2444
|
uri: ''
|
|
2429
2445
|
}],
|
|
2446
|
+
projectSidebarResizing: false,
|
|
2447
|
+
projectSidebarWidth: 280,
|
|
2430
2448
|
questionToolEnabled: false,
|
|
2431
2449
|
reasoningEffort: defaultReasoningEffort,
|
|
2432
2450
|
reasoningEffortPickerOpen: false,
|
|
@@ -2595,14 +2613,21 @@ const getChatViewEvents = async sessionId => {
|
|
|
2595
2613
|
return getEvents(sessionId);
|
|
2596
2614
|
};
|
|
2597
2615
|
|
|
2598
|
-
const textFileRegex = /\.txt$/i;
|
|
2599
|
-
const pngSignature = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
2600
2616
|
const isImageFile = mimeType => {
|
|
2601
2617
|
return mimeType.startsWith('image/');
|
|
2602
2618
|
};
|
|
2619
|
+
|
|
2620
|
+
const textFileRegex = /\.txt$/i;
|
|
2603
2621
|
const isTextFile = (name, mimeType) => {
|
|
2604
2622
|
return mimeType === 'text/plain' || textFileRegex.test(name);
|
|
2605
2623
|
};
|
|
2624
|
+
|
|
2625
|
+
const isValidJpeg = async blob => {
|
|
2626
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
2627
|
+
return bytes.length >= 4 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes.at(-2) === 0xff && bytes.at(-1) === 0xd9;
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
const pngSignature = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
2606
2631
|
const isValidPng = async blob => {
|
|
2607
2632
|
const header = new Uint8Array(await blob.slice(0, pngSignature.length).arrayBuffer());
|
|
2608
2633
|
if (header.length !== pngSignature.length) {
|
|
@@ -2610,10 +2635,7 @@ const isValidPng = async blob => {
|
|
|
2610
2635
|
}
|
|
2611
2636
|
return pngSignature.every((value, index) => header[index] === value);
|
|
2612
2637
|
};
|
|
2613
|
-
|
|
2614
|
-
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
2615
|
-
return bytes.length >= 4 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes.at(-2) === 0xff && bytes.at(-1) === 0xd9;
|
|
2616
|
-
};
|
|
2638
|
+
|
|
2617
2639
|
const isValidImage = async (blob, mimeType) => {
|
|
2618
2640
|
if (mimeType.startsWith('image/') && mimeType !== 'image/png' && mimeType !== 'image/jpeg') {
|
|
2619
2641
|
return true;
|
|
@@ -2635,6 +2657,7 @@ const isValidImage = async (blob, mimeType) => {
|
|
|
2635
2657
|
return false;
|
|
2636
2658
|
}
|
|
2637
2659
|
};
|
|
2660
|
+
|
|
2638
2661
|
const getComposerAttachmentDisplayType = async (blob, name, mimeType) => {
|
|
2639
2662
|
if (isImageFile(mimeType)) {
|
|
2640
2663
|
return (await isValidImage(blob, mimeType)) ? 'image' : 'invalid-image';
|
|
@@ -2694,8 +2717,7 @@ const getComposerAttachments = async sessionId => {
|
|
|
2694
2717
|
continue;
|
|
2695
2718
|
}
|
|
2696
2719
|
const displayType = await getComposerAttachmentDisplayType(event.blob, event.name, event.mimeType);
|
|
2697
|
-
const previewSrc = await getComposerAttachmentPreviewSrc(event.blob, displayType, event.mimeType);
|
|
2698
|
-
const textContent = await getComposerAttachmentTextContent(event.blob, displayType);
|
|
2720
|
+
const [previewSrc, textContent] = await Promise.all([getComposerAttachmentPreviewSrc(event.blob, displayType, event.mimeType), getComposerAttachmentTextContent(event.blob, displayType)]);
|
|
2699
2721
|
attachments.set(event.attachmentId, {
|
|
2700
2722
|
attachmentId: event.attachmentId,
|
|
2701
2723
|
displayType,
|
|
@@ -2827,7 +2849,7 @@ const getRenderHtmlCss = (sessions, selectedSessionId) => {
|
|
|
2827
2849
|
const isEqual$1 = (oldState, newState) => {
|
|
2828
2850
|
const oldRenderHtmlCss = getRenderHtmlCss(oldState.sessions, oldState.selectedSessionId);
|
|
2829
2851
|
const newRenderHtmlCss = getRenderHtmlCss(newState.sessions, newState.selectedSessionId);
|
|
2830
|
-
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;
|
|
2852
|
+
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;
|
|
2831
2853
|
};
|
|
2832
2854
|
|
|
2833
2855
|
const diffFocus = (oldState, newState) => {
|
|
@@ -3882,37 +3904,27 @@ const openFolder = async () => {
|
|
|
3882
3904
|
}
|
|
3883
3905
|
};
|
|
3884
3906
|
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
const slashAtEndRegex = /\/$/;
|
|
3889
|
-
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3890
|
-
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
3891
|
-
const toGitUri = (baseUri, ...segments) => {
|
|
3892
|
-
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3893
|
-
for (const segment of segments) {
|
|
3894
|
-
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3895
|
-
}
|
|
3896
|
-
return url.toString();
|
|
3897
|
-
};
|
|
3898
|
-
const decodeFileContent = content => {
|
|
3899
|
-
if (typeof content === 'string') {
|
|
3900
|
-
return content;
|
|
3901
|
-
}
|
|
3902
|
-
if (content instanceof Uint8Array) {
|
|
3903
|
-
return new TextDecoder().decode(content);
|
|
3904
|
-
}
|
|
3905
|
-
if (Array.isArray(content)) {
|
|
3906
|
-
return new TextDecoder().decode(new Uint8Array(content));
|
|
3907
|
-
}
|
|
3908
|
-
return '';
|
|
3909
|
-
};
|
|
3910
|
-
const toFileSystemPath = uri => {
|
|
3911
|
-
if (!uri.startsWith('file://')) {
|
|
3912
|
-
return uri;
|
|
3907
|
+
const parseEntries = value => {
|
|
3908
|
+
if (!Array.isArray(value)) {
|
|
3909
|
+
return [];
|
|
3913
3910
|
}
|
|
3914
|
-
return
|
|
3911
|
+
return value.map(entry => {
|
|
3912
|
+
if (Array.isArray(entry) && typeof entry[0] === 'string' && typeof entry[1] === 'number') {
|
|
3913
|
+
return {
|
|
3914
|
+
name: entry[0],
|
|
3915
|
+
type: entry[1]
|
|
3916
|
+
};
|
|
3917
|
+
}
|
|
3918
|
+
if (entry && typeof entry === 'object' && typeof Reflect.get(entry, 'name') === 'string' && typeof Reflect.get(entry, 'type') === 'number') {
|
|
3919
|
+
return {
|
|
3920
|
+
name: Reflect.get(entry, 'name'),
|
|
3921
|
+
type: Reflect.get(entry, 'type')
|
|
3922
|
+
};
|
|
3923
|
+
}
|
|
3924
|
+
return undefined;
|
|
3925
|
+
}).filter(entry => !!entry);
|
|
3915
3926
|
};
|
|
3927
|
+
|
|
3916
3928
|
const getRelativePath = (fromPath, toPath) => {
|
|
3917
3929
|
if (!fromPath.startsWith('/') || !toPath.startsWith('/')) {
|
|
3918
3930
|
return toPath;
|
|
@@ -3927,6 +3939,14 @@ const getRelativePath = (fromPath, toPath) => {
|
|
|
3927
3939
|
const childSegments = toParts.slice(commonPrefixLength);
|
|
3928
3940
|
return [...parentSegments, ...childSegments].join('/') || '.';
|
|
3929
3941
|
};
|
|
3942
|
+
|
|
3943
|
+
const toFileSystemPath = uri => {
|
|
3944
|
+
if (!uri.startsWith('file://')) {
|
|
3945
|
+
return uri;
|
|
3946
|
+
}
|
|
3947
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
3948
|
+
};
|
|
3949
|
+
|
|
3930
3950
|
const toFileSystemTarget = (workspaceUri, uri) => {
|
|
3931
3951
|
const workspacePath = toFileSystemPath(workspaceUri);
|
|
3932
3952
|
const fileSystemPath = toFileSystemPath(uri);
|
|
@@ -3935,34 +3955,56 @@ const toFileSystemTarget = (workspaceUri, uri) => {
|
|
|
3935
3955
|
}
|
|
3936
3956
|
return getRelativePath(workspacePath, fileSystemPath);
|
|
3937
3957
|
};
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3958
|
+
|
|
3959
|
+
const readDir = async (workspaceUri, uri) => {
|
|
3960
|
+
const result = await invoke('FileSystem.readDirWithFileTypes', toFileSystemTarget(workspaceUri, uri));
|
|
3961
|
+
return parseEntries(result);
|
|
3962
|
+
};
|
|
3963
|
+
|
|
3964
|
+
const slashAtEndRegex = /\/$/;
|
|
3965
|
+
const toGitUri = (baseUri, ...segments) => {
|
|
3966
|
+
const url = new URL(baseUri.endsWith('/') ? baseUri : `${baseUri}/`);
|
|
3967
|
+
for (const segment of segments) {
|
|
3968
|
+
url.pathname = `${url.pathname.replace(slashAtEndRegex, '')}/${segment.split('/').map(part => encodeURIComponent(part)).join('/')}`;
|
|
3941
3969
|
}
|
|
3942
|
-
return
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3970
|
+
return url.toString();
|
|
3971
|
+
};
|
|
3972
|
+
|
|
3973
|
+
const FileTypeFile = 1;
|
|
3974
|
+
const FileTypeDirectory = 2;
|
|
3975
|
+
const collectBranchNames = async (workspaceUri, refsHeadsUri, prefix, branches) => {
|
|
3976
|
+
const entries = await readDir(workspaceUri, refsHeadsUri);
|
|
3977
|
+
for (const entry of entries) {
|
|
3978
|
+
if (entry.type === FileTypeDirectory) {
|
|
3979
|
+
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
3980
|
+
continue;
|
|
3948
3981
|
}
|
|
3949
|
-
if (entry
|
|
3950
|
-
|
|
3951
|
-
name: Reflect.get(entry, 'name'),
|
|
3952
|
-
type: Reflect.get(entry, 'type')
|
|
3953
|
-
};
|
|
3982
|
+
if (entry.type === FileTypeFile) {
|
|
3983
|
+
branches.add(`${prefix}${entry.name}`);
|
|
3954
3984
|
}
|
|
3955
|
-
|
|
3956
|
-
}).filter(entry => !!entry);
|
|
3985
|
+
}
|
|
3957
3986
|
};
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3987
|
+
|
|
3988
|
+
const decodeFileContent = content => {
|
|
3989
|
+
if (typeof content === 'string') {
|
|
3990
|
+
return content;
|
|
3991
|
+
}
|
|
3992
|
+
if (content instanceof Uint8Array) {
|
|
3993
|
+
return new TextDecoder().decode(content);
|
|
3994
|
+
}
|
|
3995
|
+
if (Array.isArray(content)) {
|
|
3996
|
+
return new TextDecoder().decode(new Uint8Array(content));
|
|
3997
|
+
}
|
|
3998
|
+
return '';
|
|
3961
3999
|
};
|
|
4000
|
+
|
|
3962
4001
|
const readTextFile = async (workspaceUri, uri) => {
|
|
3963
4002
|
const result = await invoke('FileSystem.readFile', toFileSystemTarget(workspaceUri, uri));
|
|
3964
4003
|
return decodeFileContent(result);
|
|
3965
4004
|
};
|
|
4005
|
+
|
|
4006
|
+
// cspell:ignore gitdir worktrees
|
|
4007
|
+
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3966
4008
|
const getGitDirUri = async workspaceUri => {
|
|
3967
4009
|
const gitUri = toGitUri(workspaceUri, '.git');
|
|
3968
4010
|
try {
|
|
@@ -3978,18 +4020,8 @@ const getGitDirUri = async workspaceUri => {
|
|
|
3978
4020
|
}
|
|
3979
4021
|
return new URL(match[1].trim(), workspaceUri.endsWith('/') ? workspaceUri : `${workspaceUri}/`).toString();
|
|
3980
4022
|
};
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
for (const entry of entries) {
|
|
3984
|
-
if (entry.type === FileTypeDirectory) {
|
|
3985
|
-
await collectBranchNames(workspaceUri, toGitUri(refsHeadsUri, entry.name), `${prefix}${entry.name}/`, branches);
|
|
3986
|
-
continue;
|
|
3987
|
-
}
|
|
3988
|
-
if (entry.type === FileTypeFile) {
|
|
3989
|
-
branches.add(`${prefix}${entry.name}`);
|
|
3990
|
-
}
|
|
3991
|
-
}
|
|
3992
|
-
};
|
|
4023
|
+
|
|
4024
|
+
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
3993
4025
|
const parseCurrentBranch = headContent => {
|
|
3994
4026
|
const match = headRefRegex.exec(headContent.trim());
|
|
3995
4027
|
if (match) {
|
|
@@ -3997,13 +4029,7 @@ const parseCurrentBranch = headContent => {
|
|
|
3997
4029
|
}
|
|
3998
4030
|
return '';
|
|
3999
4031
|
};
|
|
4000
|
-
|
|
4001
|
-
try {
|
|
4002
|
-
return Boolean(await getGitDirUri(workspaceUri));
|
|
4003
|
-
} catch {
|
|
4004
|
-
return false;
|
|
4005
|
-
}
|
|
4006
|
-
};
|
|
4032
|
+
|
|
4007
4033
|
const getGitBranches = async workspaceUri => {
|
|
4008
4034
|
const gitDirUri = await getGitDirUri(workspaceUri);
|
|
4009
4035
|
if (!gitDirUri) {
|
|
@@ -4036,6 +4062,14 @@ const getGitBranches = async workspaceUri => {
|
|
|
4036
4062
|
}));
|
|
4037
4063
|
};
|
|
4038
4064
|
|
|
4065
|
+
const hasGitRepository = async workspaceUri => {
|
|
4066
|
+
try {
|
|
4067
|
+
return Boolean(await getGitDirUri(workspaceUri));
|
|
4068
|
+
} catch {
|
|
4069
|
+
return false;
|
|
4070
|
+
}
|
|
4071
|
+
};
|
|
4072
|
+
|
|
4039
4073
|
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
4040
4074
|
return sessions.find(session => session.id === selectedSessionId);
|
|
4041
4075
|
};
|
|
@@ -4634,6 +4668,30 @@ const hasToolError = value => {
|
|
|
4634
4668
|
const error = Reflect.get(value, 'error');
|
|
4635
4669
|
return typeof error === 'string' && error.trim().length > 0;
|
|
4636
4670
|
};
|
|
4671
|
+
const getTrackedToolExecutionValue = value => {
|
|
4672
|
+
if (typeof value !== 'string') {
|
|
4673
|
+
return value;
|
|
4674
|
+
}
|
|
4675
|
+
try {
|
|
4676
|
+
return JSON.parse(value);
|
|
4677
|
+
} catch {
|
|
4678
|
+
return value;
|
|
4679
|
+
}
|
|
4680
|
+
};
|
|
4681
|
+
const getStoredToolExecutionStatus = result => {
|
|
4682
|
+
let parsed = result;
|
|
4683
|
+
if (typeof result === 'string') {
|
|
4684
|
+
try {
|
|
4685
|
+
parsed = JSON.parse(result);
|
|
4686
|
+
} catch {
|
|
4687
|
+
return 'error';
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4691
|
+
return 'error';
|
|
4692
|
+
}
|
|
4693
|
+
return hasToolError(parsed) ? 'error' : 'success';
|
|
4694
|
+
};
|
|
4637
4695
|
const parseWriteFileArguments = rawArguments => {
|
|
4638
4696
|
let parsed = rawArguments;
|
|
4639
4697
|
if (typeof rawArguments === 'string') {
|
|
@@ -4741,15 +4799,60 @@ const executeChatTool = async (name, rawArguments, options) => {
|
|
|
4741
4799
|
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4742
4800
|
throw new Error('Chat tools must be executed in a web worker environment. Please set useChatToolWorker to true in the options.');
|
|
4743
4801
|
}
|
|
4744
|
-
const
|
|
4802
|
+
const executionOptions = {
|
|
4745
4803
|
assetDir: options.assetDir,
|
|
4746
4804
|
platform: options.platform,
|
|
4747
4805
|
...(options.workspaceUri ? {
|
|
4748
4806
|
workspaceUri: options.workspaceUri
|
|
4749
4807
|
} : {})
|
|
4750
|
-
}
|
|
4751
|
-
const
|
|
4752
|
-
|
|
4808
|
+
};
|
|
4809
|
+
const executionId = options.toolCallId || `${name}-${Date.now()}`;
|
|
4810
|
+
const startedAt = new Date().toISOString();
|
|
4811
|
+
if (options.sessionId) {
|
|
4812
|
+
await appendChatViewEvent({
|
|
4813
|
+
arguments: getTrackedToolExecutionValue(rawArguments),
|
|
4814
|
+
id: executionId,
|
|
4815
|
+
name,
|
|
4816
|
+
options: executionOptions,
|
|
4817
|
+
sessionId: options.sessionId,
|
|
4818
|
+
time: startedAt,
|
|
4819
|
+
timestamp: startedAt,
|
|
4820
|
+
type: 'tool-execution-started'
|
|
4821
|
+
});
|
|
4822
|
+
}
|
|
4823
|
+
try {
|
|
4824
|
+
const workerOutput = await execute(name, rawArguments, executionOptions);
|
|
4825
|
+
const outputWithLineCounts = name === 'write_file' ? await withWriteFileLineCounts(workerOutput, rawArguments) : workerOutput;
|
|
4826
|
+
const result = stringifyToolOutput(outputWithLineCounts);
|
|
4827
|
+
if (options.sessionId) {
|
|
4828
|
+
await appendChatViewEvent({
|
|
4829
|
+
id: executionId,
|
|
4830
|
+
name,
|
|
4831
|
+
result: outputWithLineCounts,
|
|
4832
|
+
sessionId: options.sessionId,
|
|
4833
|
+
status: getStoredToolExecutionStatus(outputWithLineCounts),
|
|
4834
|
+
timestamp: new Date().toISOString(),
|
|
4835
|
+
type: 'tool-execution-finished'
|
|
4836
|
+
});
|
|
4837
|
+
}
|
|
4838
|
+
return result;
|
|
4839
|
+
} catch (error) {
|
|
4840
|
+
const errorResult = {
|
|
4841
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4842
|
+
};
|
|
4843
|
+
if (options.sessionId) {
|
|
4844
|
+
await appendChatViewEvent({
|
|
4845
|
+
id: executionId,
|
|
4846
|
+
name,
|
|
4847
|
+
result: errorResult,
|
|
4848
|
+
sessionId: options.sessionId,
|
|
4849
|
+
status: 'error',
|
|
4850
|
+
timestamp: new Date().toISOString(),
|
|
4851
|
+
type: 'tool-execution-finished'
|
|
4852
|
+
});
|
|
4853
|
+
}
|
|
4854
|
+
throw error;
|
|
4855
|
+
}
|
|
4753
4856
|
};
|
|
4754
4857
|
|
|
4755
4858
|
const getAskQuestionTool = () => {
|
|
@@ -4831,6 +4934,7 @@ const getAttachmentTextPart = attachment => {
|
|
|
4831
4934
|
};
|
|
4832
4935
|
}
|
|
4833
4936
|
};
|
|
4937
|
+
|
|
4834
4938
|
const getChatMessageOpenAiContent = message => {
|
|
4835
4939
|
if (!message.attachments || message.attachments.length === 0) {
|
|
4836
4940
|
return message.text;
|
|
@@ -4862,7 +4966,9 @@ const getClientRequestIdHeader = () => {
|
|
|
4862
4966
|
};
|
|
4863
4967
|
|
|
4864
4968
|
const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
4865
|
-
|
|
4969
|
+
if (delayInMs > 0) {
|
|
4970
|
+
await delay(delayInMs);
|
|
4971
|
+
}
|
|
4866
4972
|
return `Mock AI response: I received "${userMessage}".`;
|
|
4867
4973
|
};
|
|
4868
4974
|
|
|
@@ -5346,6 +5452,51 @@ const makeStreamingApiRequest = async options => {
|
|
|
5346
5452
|
return invoke$6('ChatNetwork.makeStreamingApiRequest', options);
|
|
5347
5453
|
};
|
|
5348
5454
|
|
|
5455
|
+
const getNumericCount = parsed => {
|
|
5456
|
+
const count = Reflect.get(parsed, 'count');
|
|
5457
|
+
if (typeof count === 'number' && Number.isFinite(count)) {
|
|
5458
|
+
return count;
|
|
5459
|
+
}
|
|
5460
|
+
const matchCount = Reflect.get(parsed, 'matchCount');
|
|
5461
|
+
if (typeof matchCount === 'number' && Number.isFinite(matchCount)) {
|
|
5462
|
+
return matchCount;
|
|
5463
|
+
}
|
|
5464
|
+
return undefined;
|
|
5465
|
+
};
|
|
5466
|
+
const getArrayCount = parsed => {
|
|
5467
|
+
const matches = Reflect.get(parsed, 'matches');
|
|
5468
|
+
if (Array.isArray(matches)) {
|
|
5469
|
+
return matches.length;
|
|
5470
|
+
}
|
|
5471
|
+
const files = Reflect.get(parsed, 'files');
|
|
5472
|
+
if (Array.isArray(files)) {
|
|
5473
|
+
return files.length;
|
|
5474
|
+
}
|
|
5475
|
+
const results = Reflect.get(parsed, 'results');
|
|
5476
|
+
if (Array.isArray(results)) {
|
|
5477
|
+
return results.length;
|
|
5478
|
+
}
|
|
5479
|
+
return undefined;
|
|
5480
|
+
};
|
|
5481
|
+
const getGlobMatchCount = result => {
|
|
5482
|
+
if (!result) {
|
|
5483
|
+
return undefined;
|
|
5484
|
+
}
|
|
5485
|
+
let parsed;
|
|
5486
|
+
try {
|
|
5487
|
+
parsed = JSON.parse(result);
|
|
5488
|
+
} catch {
|
|
5489
|
+
return undefined;
|
|
5490
|
+
}
|
|
5491
|
+
if (Array.isArray(parsed)) {
|
|
5492
|
+
return parsed.length;
|
|
5493
|
+
}
|
|
5494
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
5495
|
+
return undefined;
|
|
5496
|
+
}
|
|
5497
|
+
return getNumericCount(parsed) ?? getArrayCount(parsed);
|
|
5498
|
+
};
|
|
5499
|
+
|
|
5349
5500
|
const getTextContent = content => {
|
|
5350
5501
|
if (typeof content === 'string') {
|
|
5351
5502
|
return content;
|
|
@@ -5510,6 +5661,9 @@ const getToolCallResult = (name, content) => {
|
|
|
5510
5661
|
}
|
|
5511
5662
|
return content;
|
|
5512
5663
|
}
|
|
5664
|
+
if (name === 'glob') {
|
|
5665
|
+
return getGlobMatchCount(content) === undefined ? undefined : content;
|
|
5666
|
+
}
|
|
5513
5667
|
if (name !== 'getWorkspaceUri') {
|
|
5514
5668
|
return undefined;
|
|
5515
5669
|
}
|
|
@@ -6021,6 +6175,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6021
6175
|
onToolCallsChunk,
|
|
6022
6176
|
questionToolEnabled = false,
|
|
6023
6177
|
reasoningEffort,
|
|
6178
|
+
sessionId,
|
|
6024
6179
|
stream,
|
|
6025
6180
|
supportsReasoningEffort = false,
|
|
6026
6181
|
systemPrompt = '',
|
|
@@ -6137,6 +6292,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6137
6292
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6138
6293
|
assetDir,
|
|
6139
6294
|
platform,
|
|
6295
|
+
...(sessionId ? {
|
|
6296
|
+
sessionId
|
|
6297
|
+
} : {}),
|
|
6298
|
+
toolCallId: toolCall.callId,
|
|
6140
6299
|
...(toolEnablement ? {
|
|
6141
6300
|
toolEnablement
|
|
6142
6301
|
} : {}),
|
|
@@ -6290,6 +6449,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6290
6449
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6291
6450
|
assetDir,
|
|
6292
6451
|
platform,
|
|
6452
|
+
...(sessionId ? {
|
|
6453
|
+
sessionId
|
|
6454
|
+
} : {}),
|
|
6455
|
+
toolCallId: toolCall.callId,
|
|
6293
6456
|
...(toolEnablement ? {
|
|
6294
6457
|
toolEnablement
|
|
6295
6458
|
} : {}),
|
|
@@ -6370,6 +6533,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6370
6533
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6371
6534
|
assetDir,
|
|
6372
6535
|
platform,
|
|
6536
|
+
...(sessionId ? {
|
|
6537
|
+
sessionId
|
|
6538
|
+
} : {}),
|
|
6539
|
+
toolCallId: id,
|
|
6373
6540
|
useChatToolWorker,
|
|
6374
6541
|
workspaceUri
|
|
6375
6542
|
}) : '{}';
|
|
@@ -6645,7 +6812,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, us
|
|
|
6645
6812
|
}
|
|
6646
6813
|
return normalizedLimitInfo;
|
|
6647
6814
|
};
|
|
6648
|
-
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = true, questionToolEnabled = false, systemPrompt = '', workspaceUri = '', agentMode = defaultAgentMode, toolEnablement) => {
|
|
6815
|
+
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = true, questionToolEnabled = false, systemPrompt = '', workspaceUri = '', agentMode = defaultAgentMode, toolEnablement, sessionId) => {
|
|
6649
6816
|
const effectiveAgentMode = typeof agentMode === 'boolean' ? defaultAgentMode : agentMode;
|
|
6650
6817
|
const completionMessages = [...(systemPrompt ? [{
|
|
6651
6818
|
content: systemPrompt,
|
|
@@ -6807,6 +6974,10 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
|
|
|
6807
6974
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6808
6975
|
assetDir,
|
|
6809
6976
|
platform,
|
|
6977
|
+
...(sessionId ? {
|
|
6978
|
+
sessionId
|
|
6979
|
+
} : {}),
|
|
6980
|
+
toolCallId: id,
|
|
6810
6981
|
...(toolEnablement ? {
|
|
6811
6982
|
toolEnablement
|
|
6812
6983
|
} : {}),
|
|
@@ -6982,6 +7153,7 @@ const getAiResponse = async ({
|
|
|
6982
7153
|
questionToolEnabled = false,
|
|
6983
7154
|
reasoningEffort,
|
|
6984
7155
|
selectedModelId,
|
|
7156
|
+
sessionId,
|
|
6985
7157
|
streamingEnabled = true,
|
|
6986
7158
|
systemPrompt = '',
|
|
6987
7159
|
toolEnablement,
|
|
@@ -6993,6 +7165,7 @@ const getAiResponse = async ({
|
|
|
6993
7165
|
webSearchEnabled = false,
|
|
6994
7166
|
workspaceUri
|
|
6995
7167
|
}) => {
|
|
7168
|
+
useChatCoordinatorWorker = false; // TODO enable this
|
|
6996
7169
|
if (useChatCoordinatorWorker && !authEnabled) {
|
|
6997
7170
|
try {
|
|
6998
7171
|
const result = await getAiResponse$1({
|
|
@@ -7107,6 +7280,10 @@ const getAiResponse = async ({
|
|
|
7107
7280
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
7108
7281
|
assetDir,
|
|
7109
7282
|
platform,
|
|
7283
|
+
...(sessionId ? {
|
|
7284
|
+
sessionId
|
|
7285
|
+
} : {}),
|
|
7286
|
+
toolCallId: toolCall.callId,
|
|
7110
7287
|
...(toolEnablement ? {
|
|
7111
7288
|
toolEnablement
|
|
7112
7289
|
} : {}),
|
|
@@ -7165,6 +7342,9 @@ const getAiResponse = async ({
|
|
|
7165
7342
|
...(reasoningEffort ? {
|
|
7166
7343
|
reasoningEffort
|
|
7167
7344
|
} : {}),
|
|
7345
|
+
...(sessionId ? {
|
|
7346
|
+
sessionId
|
|
7347
|
+
} : {}),
|
|
7168
7348
|
stream: streamingEnabled,
|
|
7169
7349
|
supportsReasoningEffort,
|
|
7170
7350
|
systemPrompt,
|
|
@@ -7202,7 +7382,7 @@ const getAiResponse = async ({
|
|
|
7202
7382
|
text = getOpenRouterErrorMessage(result);
|
|
7203
7383
|
}
|
|
7204
7384
|
} else if (openRouterApiKey) {
|
|
7205
|
-
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement);
|
|
7385
|
+
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement, sessionId);
|
|
7206
7386
|
if (result.type === 'success') {
|
|
7207
7387
|
const {
|
|
7208
7388
|
text: assistantText
|
|
@@ -7987,8 +8167,19 @@ const getWorkspaceUri = (state, session) => {
|
|
|
7987
8167
|
}
|
|
7988
8168
|
return getProjectUri(state, session?.projectId || state.selectedProjectId);
|
|
7989
8169
|
};
|
|
7990
|
-
const
|
|
7991
|
-
const
|
|
8170
|
+
const resolveWorkspaceUri = async (state, session) => {
|
|
8171
|
+
const workspaceUri = getWorkspaceUri(state, session);
|
|
8172
|
+
if (workspaceUri) {
|
|
8173
|
+
return workspaceUri;
|
|
8174
|
+
}
|
|
8175
|
+
try {
|
|
8176
|
+
return await getWorkspacePath();
|
|
8177
|
+
} catch {
|
|
8178
|
+
return '';
|
|
8179
|
+
}
|
|
8180
|
+
};
|
|
8181
|
+
const getEffectiveSystemPrompt = (state, workspaceUri) => {
|
|
8182
|
+
const resolvedSystemPrompt = state.systemPrompt.replaceAll(workspaceUriPlaceholder, workspaceUri || 'unknown');
|
|
7992
8183
|
const currentDateInstructions = `Current date: ${getCurrentDate()}.
|
|
7993
8184
|
|
|
7994
8185
|
Do not assume your knowledge cutoff is the same as the current date.`;
|
|
@@ -8196,8 +8387,8 @@ const handleSubmit = async state => {
|
|
|
8196
8387
|
mockOpenApiRequests
|
|
8197
8388
|
} = optimisticState;
|
|
8198
8389
|
const selectedOptimisticSession = optimisticState.sessions.find(session => session.id === optimisticState.selectedSessionId);
|
|
8199
|
-
const
|
|
8200
|
-
const
|
|
8390
|
+
const workspaceUri = useMockApi ? getWorkspaceUri(optimisticState, selectedOptimisticSession) : await resolveWorkspaceUri(optimisticState, selectedOptimisticSession);
|
|
8391
|
+
const systemPrompt = getEffectiveSystemPrompt(optimisticState, workspaceUri);
|
|
8201
8392
|
const messages = (selectedOptimisticSession?.messages ?? []).filter(message => !message.inProgress);
|
|
8202
8393
|
const mentionContextMessage = await getMentionContextMessage(userText);
|
|
8203
8394
|
const messagesWithMentionContext = mentionContextMessage ? [...messages, mentionContextMessage] : messages;
|
|
@@ -8257,6 +8448,7 @@ const handleSubmit = async state => {
|
|
|
8257
8448
|
} : {}),
|
|
8258
8449
|
reasoningEffort,
|
|
8259
8450
|
selectedModelId,
|
|
8451
|
+
sessionId: optimisticState.selectedSessionId,
|
|
8260
8452
|
streamingEnabled,
|
|
8261
8453
|
systemPrompt,
|
|
8262
8454
|
toolEnablement,
|
|
@@ -8800,6 +8992,18 @@ const handleClickClose = async () => {
|
|
|
8800
8992
|
await invoke('Layout.hideSecondarySideBar');
|
|
8801
8993
|
};
|
|
8802
8994
|
|
|
8995
|
+
const handleClickCustomSelectOverlay = async (state, defaultPrevented) => {
|
|
8996
|
+
if (defaultPrevented) {
|
|
8997
|
+
return state;
|
|
8998
|
+
}
|
|
8999
|
+
return closeGitBranchPicker({
|
|
9000
|
+
...state,
|
|
9001
|
+
agentModePickerOpen: false,
|
|
9002
|
+
reasoningEffortPickerOpen: false,
|
|
9003
|
+
runModePickerOpen: false
|
|
9004
|
+
});
|
|
9005
|
+
};
|
|
9006
|
+
|
|
8803
9007
|
const handleClickDelete = async (state, sessionId = '') => {
|
|
8804
9008
|
return deleteSession(state, sessionId);
|
|
8805
9009
|
};
|
|
@@ -9083,8 +9287,7 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9083
9287
|
const file = await droppedFileHandle.getFile();
|
|
9084
9288
|
const attachmentId = `attachment-${nextAttachmentId + nextAttachments.length}`;
|
|
9085
9289
|
const displayType = await getComposerAttachmentDisplayType(file, file.name, file.type);
|
|
9086
|
-
const previewSrc = await getComposerAttachmentPreviewSrc(file, displayType, file.type);
|
|
9087
|
-
const textContent = await getComposerAttachmentTextContent(file, displayType);
|
|
9290
|
+
const [previewSrc, textContent] = await Promise.all([getComposerAttachmentPreviewSrc(file, displayType, file.type), getComposerAttachmentTextContent(file, displayType)]);
|
|
9088
9291
|
await appendChatViewEvent({
|
|
9089
9292
|
attachmentId,
|
|
9090
9293
|
blob: file,
|
|
@@ -9152,11 +9355,13 @@ const handleInput = async (state, name, value, inputSource = 'user') => {
|
|
|
9152
9355
|
}
|
|
9153
9356
|
if (name === ModelPickerSearch) {
|
|
9154
9357
|
const visibleModels = getVisibleModels(state.models, value);
|
|
9358
|
+
const selectedModelId = visibleModels.some(model => model.id === state.selectedModelId) ? state.selectedModelId : visibleModels[0]?.id || state.selectedModelId;
|
|
9155
9359
|
return {
|
|
9156
9360
|
...state,
|
|
9157
9361
|
modelPickerHeight: getModelPickerHeight(state.modelPickerHeaderHeight, visibleModels.length),
|
|
9158
9362
|
modelPickerListScrollTop: 0,
|
|
9159
9363
|
modelPickerSearchValue: value,
|
|
9364
|
+
selectedModelId,
|
|
9160
9365
|
visibleModels
|
|
9161
9366
|
};
|
|
9162
9367
|
}
|
|
@@ -9391,10 +9596,57 @@ const handlePointerDownModelPickerList = async state => {
|
|
|
9391
9596
|
return state;
|
|
9392
9597
|
};
|
|
9393
9598
|
|
|
9599
|
+
const handlePointerDownProjectSidebarSash = async state => {
|
|
9600
|
+
if (state.projectSidebarResizing) {
|
|
9601
|
+
return state;
|
|
9602
|
+
}
|
|
9603
|
+
return {
|
|
9604
|
+
...state,
|
|
9605
|
+
projectSidebarResizing: true
|
|
9606
|
+
};
|
|
9607
|
+
};
|
|
9608
|
+
|
|
9609
|
+
const minimumProjectSidebarWidth = 180;
|
|
9610
|
+
const minimumChatAreaWidth = 320;
|
|
9611
|
+
const getProjectSidebarWidth = (state, clientX) => {
|
|
9612
|
+
const availableWidth = state.width > 0 ? state.width : state.projectSidebarWidth + minimumChatAreaWidth;
|
|
9613
|
+
const maximumProjectSidebarWidth = Math.max(minimumProjectSidebarWidth, availableWidth - minimumChatAreaWidth);
|
|
9614
|
+
const nextWidth = Math.round(clientX - state.x);
|
|
9615
|
+
return Math.min(Math.max(nextWidth, minimumProjectSidebarWidth), maximumProjectSidebarWidth);
|
|
9616
|
+
};
|
|
9617
|
+
const resizeProjectSidebar = (state, clientX) => {
|
|
9618
|
+
const projectSidebarWidth = getProjectSidebarWidth(state, clientX);
|
|
9619
|
+
if (projectSidebarWidth === state.projectSidebarWidth) {
|
|
9620
|
+
return state;
|
|
9621
|
+
}
|
|
9622
|
+
return {
|
|
9623
|
+
...state,
|
|
9624
|
+
projectSidebarWidth
|
|
9625
|
+
};
|
|
9626
|
+
};
|
|
9627
|
+
|
|
9628
|
+
const handlePointerMoveProjectSidebarSash = async (state, clientX) => {
|
|
9629
|
+
if (!state.projectSidebarResizing) {
|
|
9630
|
+
return state;
|
|
9631
|
+
}
|
|
9632
|
+
return resizeProjectSidebar(state, clientX);
|
|
9633
|
+
};
|
|
9634
|
+
|
|
9394
9635
|
const handlePointerUpModelPickerList = async (state, eventY = 0) => {
|
|
9395
9636
|
return state;
|
|
9396
9637
|
};
|
|
9397
9638
|
|
|
9639
|
+
const handlePointerUpProjectSidebarSash = async (state, clientX) => {
|
|
9640
|
+
if (!state.projectSidebarResizing) {
|
|
9641
|
+
return state;
|
|
9642
|
+
}
|
|
9643
|
+
const nextState = resizeProjectSidebar(state, clientX);
|
|
9644
|
+
return {
|
|
9645
|
+
...nextState,
|
|
9646
|
+
projectSidebarResizing: false
|
|
9647
|
+
};
|
|
9648
|
+
};
|
|
9649
|
+
|
|
9398
9650
|
const handleProjectAddButtonContextMenu = async (state, button, x, y) => {
|
|
9399
9651
|
const {
|
|
9400
9652
|
uid
|
|
@@ -9682,6 +9934,19 @@ const getSavedProjects = savedState => {
|
|
|
9682
9934
|
return validProjects;
|
|
9683
9935
|
};
|
|
9684
9936
|
|
|
9937
|
+
const getSavedProjectSidebarWidth = savedState => {
|
|
9938
|
+
if (!isObject$1(savedState)) {
|
|
9939
|
+
return undefined;
|
|
9940
|
+
}
|
|
9941
|
+
const {
|
|
9942
|
+
projectSidebarWidth
|
|
9943
|
+
} = savedState;
|
|
9944
|
+
if (typeof projectSidebarWidth !== 'number') {
|
|
9945
|
+
return undefined;
|
|
9946
|
+
}
|
|
9947
|
+
return projectSidebarWidth;
|
|
9948
|
+
};
|
|
9949
|
+
|
|
9685
9950
|
const getSavedReasoningEffort = savedState => {
|
|
9686
9951
|
if (!isObject$1(savedState)) {
|
|
9687
9952
|
return undefined;
|
|
@@ -9902,7 +10167,7 @@ const loadToolEnablement = async () => {
|
|
|
9902
10167
|
const savedToolEnablement = await get('chat.toolEnablement');
|
|
9903
10168
|
return parseToolEnablement(savedToolEnablement);
|
|
9904
10169
|
} catch {
|
|
9905
|
-
return
|
|
10170
|
+
return parseToolEnablement(undefined);
|
|
9906
10171
|
}
|
|
9907
10172
|
};
|
|
9908
10173
|
|
|
@@ -10078,6 +10343,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10078
10343
|
const chatListScrollTop = getSavedChatListScrollTop(savedState) ?? state.chatListScrollTop;
|
|
10079
10344
|
const messagesScrollTop = getSavedMessagesScrollTop(savedState) ?? state.messagesScrollTop;
|
|
10080
10345
|
const projectListScrollTop = getSavedProjectListScrollTop(savedState) ?? state.projectListScrollTop;
|
|
10346
|
+
const projectSidebarWidth = getSavedProjectSidebarWidth(savedState) ?? state.projectSidebarWidth;
|
|
10081
10347
|
const savedProjectExpandedIds = getSavedProjectExpandedIds(savedState);
|
|
10082
10348
|
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
10083
10349
|
const reasoningEffort = getSavedReasoningEffort(savedState) ?? state.reasoningEffort;
|
|
@@ -10132,6 +10398,8 @@ const loadContent = async (state, savedState) => {
|
|
|
10132
10398
|
projectExpandedIds,
|
|
10133
10399
|
projectListScrollTop,
|
|
10134
10400
|
projects,
|
|
10401
|
+
projectSidebarResizing: false,
|
|
10402
|
+
projectSidebarWidth,
|
|
10135
10403
|
reasoningEffort,
|
|
10136
10404
|
reasoningEffortPickerOpen: false,
|
|
10137
10405
|
reasoningPickerEnabled,
|
|
@@ -10320,10 +10588,11 @@ const removeComposerAttachment = async (state, attachmentId) => {
|
|
|
10320
10588
|
return handleRemoveComposerAttachment(state, attachmentId);
|
|
10321
10589
|
};
|
|
10322
10590
|
|
|
10323
|
-
const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
|
|
10591
|
+
const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, projectSidebarWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
|
|
10324
10592
|
const buttonsHeight = 20;
|
|
10325
10593
|
const gap = 10;
|
|
10326
10594
|
const contentPadding = 10;
|
|
10595
|
+
const runModePickerHeight = 84;
|
|
10327
10596
|
const chatSendAreaHeight = composerHeight + composerAttachmentsHeight + chatSendAreaPaddingTop + chatSendAreaPaddingBottom + buttonsHeight + gap + contentPadding * 2;
|
|
10328
10597
|
const baseCss = `:root {
|
|
10329
10598
|
--ChatInputBoxHeight: ${composerHeight}px;
|
|
@@ -10344,6 +10613,12 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10344
10613
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
10345
10614
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
10346
10615
|
--ChatFocusContentMaxWidth: ${chatFocusContentMaxWidth}px;
|
|
10616
|
+
--ProjectSidebarWidth: ${projectSidebarWidth}px;
|
|
10617
|
+
--RunModePickerHeight: ${runModePickerHeight}px;
|
|
10618
|
+
}
|
|
10619
|
+
|
|
10620
|
+
:root{
|
|
10621
|
+
--WidgetBorder: white;
|
|
10347
10622
|
}
|
|
10348
10623
|
|
|
10349
10624
|
.ChatSendAreaBottom{
|
|
@@ -10369,7 +10644,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10369
10644
|
min-width: 0;
|
|
10370
10645
|
overflow: hidden;
|
|
10371
10646
|
border-radius: 999px;
|
|
10372
|
-
border: 1px solid var(--
|
|
10647
|
+
border: 1px solid var(--WidgetBorder, white);
|
|
10373
10648
|
padding: 4px 10px;
|
|
10374
10649
|
background: var(--vscode-badge-background, color-mix(in srgb, var(--vscode-editor-background) 88%, white));
|
|
10375
10650
|
color: var(--vscode-badge-foreground, var(--vscode-foreground));
|
|
@@ -10419,7 +10694,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10419
10694
|
}
|
|
10420
10695
|
|
|
10421
10696
|
.ChatComposerAttachmentTextFile{
|
|
10422
|
-
border-color: var(--vscode-charts-green, var(--
|
|
10697
|
+
border-color: var(--vscode-charts-green, var(--WidgetBorder, white));
|
|
10423
10698
|
}
|
|
10424
10699
|
|
|
10425
10700
|
.ChatAttachments{
|
|
@@ -10437,7 +10712,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10437
10712
|
min-width: 0;
|
|
10438
10713
|
overflow: hidden;
|
|
10439
10714
|
border-radius: 999px;
|
|
10440
|
-
border: 1px solid var(--
|
|
10715
|
+
border: 1px solid var(--WidgetBorder, white);
|
|
10441
10716
|
padding: 4px 10px;
|
|
10442
10717
|
background: var(--vscode-badge-background, color-mix(in srgb, var(--vscode-editor-background) 88%, white));
|
|
10443
10718
|
color: var(--vscode-badge-foreground, var(--vscode-foreground));
|
|
@@ -10469,12 +10744,12 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10469
10744
|
}
|
|
10470
10745
|
|
|
10471
10746
|
.ChatAttachmentTextFile{
|
|
10472
|
-
border-color: var(--vscode-charts-green, var(--
|
|
10747
|
+
border-color: var(--vscode-charts-green, var(--WidgetBorder, white));
|
|
10473
10748
|
}
|
|
10474
10749
|
|
|
10475
10750
|
.ChatImageMessageContent{
|
|
10476
10751
|
padding: 6px;
|
|
10477
|
-
border: 1px solid var(--
|
|
10752
|
+
border: 1px solid var(--WidgetBorder, white);
|
|
10478
10753
|
border-radius: 12px;
|
|
10479
10754
|
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
10480
10755
|
overflow: hidden;
|
|
@@ -10505,7 +10780,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10505
10780
|
display: flex;
|
|
10506
10781
|
align-items: center;
|
|
10507
10782
|
justify-content: center;
|
|
10508
|
-
border: 1px solid var(--
|
|
10783
|
+
border: 1px solid var(--WidgetBorder, white);
|
|
10509
10784
|
border-radius: 12px;
|
|
10510
10785
|
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
10511
10786
|
box-shadow: 0 12px 28px color-mix(in srgb, var(--vscode-editor-background) 45%, black);
|
|
@@ -10564,8 +10839,9 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10564
10839
|
}
|
|
10565
10840
|
|
|
10566
10841
|
.RunModePickerPopOver{
|
|
10842
|
+
height: var(--RunModePickerHeight);
|
|
10567
10843
|
overflow: hidden;
|
|
10568
|
-
border: 1px solid var(--
|
|
10844
|
+
border: 1px solid var(--WidgetBorder, white);
|
|
10569
10845
|
border-radius: 8px;
|
|
10570
10846
|
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
10571
10847
|
box-shadow: 0 8px 24px color-mix(in srgb, var(--vscode-editor-background) 50%, black);
|
|
@@ -10651,7 +10927,41 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10651
10927
|
.Viewlet.Chat.ChatFocus{
|
|
10652
10928
|
display: flex !important;
|
|
10653
10929
|
min-width: 0;
|
|
10930
|
+
flex-direction: row !important;
|
|
10931
|
+
}
|
|
10932
|
+
|
|
10933
|
+
.ChatFocus > .ProjectSidebar{
|
|
10934
|
+
display: flex;
|
|
10935
|
+
flex: none;
|
|
10936
|
+
flex-direction: column;
|
|
10937
|
+
inline-size: var(--ProjectSidebarWidth);
|
|
10938
|
+
min-inline-size: 0;
|
|
10939
|
+
}
|
|
10940
|
+
|
|
10941
|
+
.ChatFocus > .ProjectSidebar > .ProjectList{
|
|
10942
|
+
flex: 1;
|
|
10943
|
+
min-height: 0;
|
|
10944
|
+
}
|
|
10945
|
+
|
|
10946
|
+
.ChatFocus > .Sash.SashVertical{
|
|
10947
|
+
position: relative;
|
|
10948
|
+
flex: none;
|
|
10949
|
+
inline-size: 4px;
|
|
10950
|
+
cursor: col-resize;
|
|
10951
|
+
touch-action: none;
|
|
10952
|
+
}
|
|
10953
|
+
|
|
10954
|
+
.ChatFocus > .Sash.SashVertical::before{
|
|
10955
|
+
content: '';
|
|
10956
|
+
position: absolute;
|
|
10957
|
+
inset: 0;
|
|
10958
|
+
background: color-mix(in srgb, var(--vscode-sideBar-border, var(--WidgetBorder, white)) 75%, transparent);
|
|
10959
|
+
}
|
|
10960
|
+
|
|
10961
|
+
.ChatFocus > .Sash.SashVertical:hover::before{
|
|
10962
|
+
background: var(--vscode-focusBorder, var(--vscode-button-background));
|
|
10654
10963
|
}
|
|
10964
|
+
|
|
10655
10965
|
.ChatFocusMainArea{
|
|
10656
10966
|
display: flex;
|
|
10657
10967
|
flex: 1;
|
|
@@ -10766,6 +11076,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10766
11076
|
composerHeight,
|
|
10767
11077
|
listItemHeight,
|
|
10768
11078
|
modelPickerHeight,
|
|
11079
|
+
projectSidebarWidth,
|
|
10769
11080
|
selectedSessionId,
|
|
10770
11081
|
sessions,
|
|
10771
11082
|
textAreaPaddingBottom,
|
|
@@ -10775,7 +11086,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10775
11086
|
uid
|
|
10776
11087
|
} = newState;
|
|
10777
11088
|
const renderHtmlCss = getRenderHtmlCss(sessions, selectedSessionId);
|
|
10778
|
-
const css = getCss(composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
11089
|
+
const css = getCss(composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, projectSidebarWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
10779
11090
|
return [SetCss, uid, css];
|
|
10780
11091
|
};
|
|
10781
11092
|
|
|
@@ -10954,9 +11265,13 @@ const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
|
10954
11265
|
const MaskIconChevronUp = 'MaskIconChevronUp';
|
|
10955
11266
|
const MaskIconClose = 'MaskIconClose';
|
|
10956
11267
|
const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
11268
|
+
const MaskIconDiff = 'MaskIconDiff';
|
|
11269
|
+
const MaskIconFolder = 'MaskIconFolder';
|
|
11270
|
+
const MaskIconGitCommit = 'MaskIconGitCommit';
|
|
10957
11271
|
const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
|
|
10958
11272
|
const MaskIconSearch = 'MaskIconSearch';
|
|
10959
11273
|
const MaskIconSettingsGear = 'MaskIconSettingsGear';
|
|
11274
|
+
const MaskIconTerminal = 'MaskIconTerminal';
|
|
10960
11275
|
const Message = 'Message';
|
|
10961
11276
|
const MessageAssistant = 'MessageAssistant';
|
|
10962
11277
|
const MessageUser = 'MessageUser';
|
|
@@ -10975,6 +11290,8 @@ const ProjectSessionItem = 'ProjectSessionItem';
|
|
|
10975
11290
|
const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
|
|
10976
11291
|
const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
|
|
10977
11292
|
const ProjectSidebar = 'ProjectSidebar';
|
|
11293
|
+
const Sash = 'Sash';
|
|
11294
|
+
const SashVertical = 'SashVertical';
|
|
10978
11295
|
const SearchFieldContainer = 'SearchFieldContainer';
|
|
10979
11296
|
const RunModePickerContainer = 'RunModePickerContainer';
|
|
10980
11297
|
const RunModePickerPopOver = 'RunModePickerPopOver';
|
|
@@ -11042,6 +11359,10 @@ const HandleClickAgentModePickerToggle = 57;
|
|
|
11042
11359
|
const HandleContextMenuChatImageAttachment = 58;
|
|
11043
11360
|
const HandleClickGitBranchPickerToggle = 59;
|
|
11044
11361
|
const HandleErrorComposerAttachmentPreviewOverlay = 60;
|
|
11362
|
+
const HandleClickCustomSelectOverlay = 61;
|
|
11363
|
+
const HandlePointerDownProjectSidebarSash = 62;
|
|
11364
|
+
const HandlePointerMoveProjectSidebarSash = 63;
|
|
11365
|
+
const HandlePointerUpProjectSidebarSash = 64;
|
|
11045
11366
|
|
|
11046
11367
|
const getAddContextButtonDom = () => {
|
|
11047
11368
|
return [{
|
|
@@ -11056,7 +11377,7 @@ const getAddContextButtonDom = () => {
|
|
|
11056
11377
|
}];
|
|
11057
11378
|
};
|
|
11058
11379
|
|
|
11059
|
-
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
|
|
11380
|
+
const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, ariaControls = '') => {
|
|
11060
11381
|
const getChevronDom = expanded => {
|
|
11061
11382
|
return {
|
|
11062
11383
|
childCount: 0,
|
|
@@ -11067,6 +11388,9 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
|
|
|
11067
11388
|
};
|
|
11068
11389
|
};
|
|
11069
11390
|
return [{
|
|
11391
|
+
...(ariaControls ? {
|
|
11392
|
+
'aria-controls': ariaControls
|
|
11393
|
+
} : {}),
|
|
11070
11394
|
'aria-expanded': open ? 'true' : 'false',
|
|
11071
11395
|
'aria-haspopup': 'true',
|
|
11072
11396
|
'aria-label': ariaLabel,
|
|
@@ -11087,8 +11411,8 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
|
|
|
11087
11411
|
}, text(label), getChevronDom(open)];
|
|
11088
11412
|
};
|
|
11089
11413
|
|
|
11090
|
-
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
|
|
11091
|
-
return getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel);
|
|
11414
|
+
const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, ariaControls = '') => {
|
|
11415
|
+
return getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel, ariaControls);
|
|
11092
11416
|
};
|
|
11093
11417
|
|
|
11094
11418
|
const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) => {
|
|
@@ -11099,7 +11423,7 @@ const getChatModelPickerToggleVirtualDom = (models, selectedModelId, modelPicker
|
|
|
11099
11423
|
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
11100
11424
|
const selectedModelLabel = selectedModel ? selectedModel.name : selectedModelId;
|
|
11101
11425
|
const pickModelLabel = pickModel(selectedModelLabel);
|
|
11102
|
-
return getCustomSelectPickerToggleVirtualDom(selectedModelLabel, ModelPickerToggle, modelPickerOpen, HandleClickModelPickerToggle, pickModelLabel, pickModelLabel);
|
|
11426
|
+
return getCustomSelectPickerToggleVirtualDom(selectedModelLabel, ModelPickerToggle, modelPickerOpen, HandleClickModelPickerToggle, pickModelLabel, pickModelLabel, ModelPickerList);
|
|
11103
11427
|
};
|
|
11104
11428
|
|
|
11105
11429
|
const getCreatePullRequestButtonDom = () => {
|
|
@@ -11181,6 +11505,11 @@ const getGitBranchPickerVirtualDom = (gitBranches, gitBranchPickerOpen, gitBranc
|
|
|
11181
11505
|
const showMessage = messageDom.length > 0;
|
|
11182
11506
|
const popOverHeight = gitBranches.length * itemHeight + (showMessage ? messageHeight : 0);
|
|
11183
11507
|
return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch'), ...(gitBranchPickerOpen ? [{
|
|
11508
|
+
childCount: 1,
|
|
11509
|
+
className: ChatModelPickerContainer,
|
|
11510
|
+
onClick: HandleClickCustomSelectOverlay,
|
|
11511
|
+
type: Div
|
|
11512
|
+
}, {
|
|
11184
11513
|
childCount: (showMessage ? 1 : 0) + 1,
|
|
11185
11514
|
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver, ChatGitBranchPicker),
|
|
11186
11515
|
style: `height: ${popOverHeight}px;`,
|
|
@@ -11202,6 +11531,11 @@ const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
|
|
|
11202
11531
|
};
|
|
11203
11532
|
const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEffortPickerOpen) => {
|
|
11204
11533
|
return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning'), ...(reasoningEffortPickerOpen ? [{
|
|
11534
|
+
childCount: 1,
|
|
11535
|
+
className: ChatModelPickerContainer,
|
|
11536
|
+
onClick: HandleClickCustomSelectOverlay,
|
|
11537
|
+
type: Div
|
|
11538
|
+
}, {
|
|
11205
11539
|
childCount: 1,
|
|
11206
11540
|
className: mergeClassNames(ChatModelPicker, CustomSelectPopOver),
|
|
11207
11541
|
style: `height: ${reasoningEffortPickerHeight}px;`,
|
|
@@ -11338,34 +11672,51 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
11338
11672
|
}, text(usageLabel)];
|
|
11339
11673
|
};
|
|
11340
11674
|
|
|
11341
|
-
const
|
|
11675
|
+
const getComposerAttachmentClassName = displayType => {
|
|
11342
11676
|
switch (displayType) {
|
|
11343
11677
|
case 'file':
|
|
11344
|
-
return
|
|
11678
|
+
return ChatComposerAttachment;
|
|
11345
11679
|
case 'image':
|
|
11346
|
-
return
|
|
11680
|
+
return ChatComposerAttachmentImage;
|
|
11347
11681
|
case 'invalid-image':
|
|
11348
|
-
return
|
|
11682
|
+
return ChatComposerAttachmentInvalidImage;
|
|
11349
11683
|
case 'text-file':
|
|
11350
|
-
return
|
|
11684
|
+
return ChatComposerAttachmentTextFile;
|
|
11351
11685
|
default:
|
|
11352
|
-
return
|
|
11686
|
+
return ChatComposerAttachment;
|
|
11353
11687
|
}
|
|
11354
11688
|
};
|
|
11355
|
-
|
|
11689
|
+
|
|
11690
|
+
const getComposerAttachmentLabel = displayType => {
|
|
11356
11691
|
switch (displayType) {
|
|
11357
11692
|
case 'file':
|
|
11358
|
-
return
|
|
11693
|
+
return 'File';
|
|
11359
11694
|
case 'image':
|
|
11360
|
-
return
|
|
11695
|
+
return 'Image';
|
|
11361
11696
|
case 'invalid-image':
|
|
11362
|
-
return
|
|
11697
|
+
return 'Invalid image';
|
|
11363
11698
|
case 'text-file':
|
|
11364
|
-
return
|
|
11699
|
+
return 'Text file';
|
|
11365
11700
|
default:
|
|
11366
|
-
return
|
|
11701
|
+
return displayType;
|
|
11367
11702
|
}
|
|
11368
11703
|
};
|
|
11704
|
+
|
|
11705
|
+
const getComposerAttachmentPreviewDom = attachment => {
|
|
11706
|
+
if (!attachment.previewSrc) {
|
|
11707
|
+
return [];
|
|
11708
|
+
}
|
|
11709
|
+
return [{
|
|
11710
|
+
alt: `Image preview for ${attachment.name}`,
|
|
11711
|
+
childCount: 0,
|
|
11712
|
+
className: ChatComposerAttachmentPreview,
|
|
11713
|
+
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11714
|
+
onContextMenu: HandleContextMenuChatImageAttachment,
|
|
11715
|
+
src: attachment.previewSrc,
|
|
11716
|
+
type: Img
|
|
11717
|
+
}];
|
|
11718
|
+
};
|
|
11719
|
+
|
|
11369
11720
|
const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
11370
11721
|
return [{
|
|
11371
11722
|
'aria-label': removeAttachment(),
|
|
@@ -11381,20 +11732,7 @@ const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
|
11381
11732
|
type: Text
|
|
11382
11733
|
}];
|
|
11383
11734
|
};
|
|
11384
|
-
|
|
11385
|
-
if (!attachment.previewSrc) {
|
|
11386
|
-
return [];
|
|
11387
|
-
}
|
|
11388
|
-
return [{
|
|
11389
|
-
alt: `Image preview for ${attachment.name}`,
|
|
11390
|
-
childCount: 0,
|
|
11391
|
-
className: ChatComposerAttachmentPreview,
|
|
11392
|
-
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11393
|
-
onContextMenu: HandleContextMenuChatImageAttachment,
|
|
11394
|
-
src: attachment.previewSrc,
|
|
11395
|
-
type: Img
|
|
11396
|
-
}];
|
|
11397
|
-
};
|
|
11735
|
+
|
|
11398
11736
|
const getComposerAttachmentsDom = composerAttachments => {
|
|
11399
11737
|
if (composerAttachments.length === 0) {
|
|
11400
11738
|
return [];
|
|
@@ -11426,6 +11764,7 @@ const getComposerAttachmentsDom = composerAttachments => {
|
|
|
11426
11764
|
}];
|
|
11427
11765
|
})];
|
|
11428
11766
|
};
|
|
11767
|
+
|
|
11429
11768
|
const getComposerTextAreaDom = () => {
|
|
11430
11769
|
return {
|
|
11431
11770
|
childCount: 0,
|
|
@@ -11440,6 +11779,7 @@ const getComposerTextAreaDom = () => {
|
|
|
11440
11779
|
type: TextArea
|
|
11441
11780
|
};
|
|
11442
11781
|
};
|
|
11782
|
+
|
|
11443
11783
|
const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agentModePickerOpen, gitBranchPickerVisible, gitBranchPickerOpen, gitBranchPickerErrorMessage, gitBranches, fallbackBranchName, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton = false, voiceDictationEnabled = false, scrollDownButtonEnabled = false, messagesAutoScrollEnabled = true) => {
|
|
11444
11784
|
const isSendDisabled = composerValue.trim() === '';
|
|
11445
11785
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
@@ -11528,26 +11868,57 @@ const getChatHeaderAuthDom = (authEnabled = false, userState = 'loggedOut', user
|
|
|
11528
11868
|
}, text(buttonLabel)];
|
|
11529
11869
|
};
|
|
11530
11870
|
|
|
11871
|
+
const getHeaderActionClassName = disabled => {
|
|
11872
|
+
return mergeClassNames(IconButton, disabled ? IconButtonDisabled : '');
|
|
11873
|
+
};
|
|
11874
|
+
const getHeaderActionVirtualDom = item => {
|
|
11875
|
+
return [{
|
|
11876
|
+
childCount: 1,
|
|
11877
|
+
className: getHeaderActionClassName(item.disabled),
|
|
11878
|
+
disabled: item.disabled,
|
|
11879
|
+
name: item.name,
|
|
11880
|
+
onClick: item.onClick,
|
|
11881
|
+
title: item.title,
|
|
11882
|
+
type: Button$1
|
|
11883
|
+
}, {
|
|
11884
|
+
childCount: 0,
|
|
11885
|
+
className: item.icon,
|
|
11886
|
+
type: Div
|
|
11887
|
+
}];
|
|
11888
|
+
};
|
|
11889
|
+
|
|
11531
11890
|
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;';
|
|
11532
11891
|
const focusHeaderMetaStyle = 'align-items:baseline;display:flex;gap:8px;min-width:0;overflow:hidden;';
|
|
11533
11892
|
const focusHeaderTitleStyle = 'margin:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11534
11893
|
const focusHeaderProjectStyle = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11535
11894
|
const focusHeaderActionsStyle = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;';
|
|
11536
|
-
const focusHeaderButtonStyle = 'white-space:nowrap;';
|
|
11537
|
-
const getFocusHeaderActionButtonDom = (label, name) => {
|
|
11538
|
-
return [{
|
|
11539
|
-
childCount: 1,
|
|
11540
|
-
className: mergeClassNames(Button, ButtonSecondary),
|
|
11541
|
-
inputType: 'button',
|
|
11542
|
-
name,
|
|
11543
|
-
onClick: HandleClick,
|
|
11544
|
-
style: focusHeaderButtonStyle,
|
|
11545
|
-
title: label,
|
|
11546
|
-
type: Button$1
|
|
11547
|
-
}, text(label)];
|
|
11548
|
-
};
|
|
11549
11895
|
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
11550
|
-
const items = [
|
|
11896
|
+
const items = [{
|
|
11897
|
+
icon: mergeClassNames(MaskIcon, MaskIconAdd),
|
|
11898
|
+
name: FocusAddAction,
|
|
11899
|
+
onClick: HandleClick,
|
|
11900
|
+
title: addAction()
|
|
11901
|
+
}, {
|
|
11902
|
+
icon: mergeClassNames(MaskIcon, MaskIconFolder),
|
|
11903
|
+
name: FocusOpenInVsCode,
|
|
11904
|
+
onClick: HandleClick,
|
|
11905
|
+
title: openInVsCode()
|
|
11906
|
+
}, {
|
|
11907
|
+
icon: mergeClassNames(MaskIcon, MaskIconGitCommit),
|
|
11908
|
+
name: FocusCommit,
|
|
11909
|
+
onClick: HandleClick,
|
|
11910
|
+
title: commit()
|
|
11911
|
+
}, {
|
|
11912
|
+
icon: mergeClassNames(MaskIcon, MaskIconTerminal),
|
|
11913
|
+
name: FocusOpenTerminal,
|
|
11914
|
+
onClick: HandleClick,
|
|
11915
|
+
title: openTerminal()
|
|
11916
|
+
}, {
|
|
11917
|
+
icon: mergeClassNames(MaskIcon, MaskIconDiff),
|
|
11918
|
+
name: FocusShowDiff,
|
|
11919
|
+
onClick: HandleClick,
|
|
11920
|
+
title: showDiff()
|
|
11921
|
+
}];
|
|
11551
11922
|
const hasProjectName = !!selectedProjectName;
|
|
11552
11923
|
return [{
|
|
11553
11924
|
childCount: 2 + (authEnabled ? 1 : 0),
|
|
@@ -11576,23 +11947,28 @@ const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, au
|
|
|
11576
11947
|
role: ToolBar,
|
|
11577
11948
|
style: focusHeaderActionsStyle,
|
|
11578
11949
|
type: Div
|
|
11579
|
-
}, ...items.flatMap(
|
|
11950
|
+
}, ...items.flatMap(getHeaderActionVirtualDom)];
|
|
11580
11951
|
};
|
|
11581
11952
|
|
|
11582
11953
|
const getAgentModeOptionsVirtualDom = selectedAgentMode => {
|
|
11583
11954
|
return agentModes.flatMap(agentMode => getCustomSelectOptionVirtualDom(getAgentModePickerItemInputName(agentMode), getAgentModeLabel(agentMode), agentMode === selectedAgentMode));
|
|
11584
11955
|
};
|
|
11585
11956
|
|
|
11586
|
-
const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '') => {
|
|
11957
|
+
const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '', useInlineHeight = true) => {
|
|
11587
11958
|
return [{
|
|
11588
11959
|
childCount: 1,
|
|
11589
11960
|
className: mergeClassNames(ChatModelPickerContainer, containerClassName),
|
|
11961
|
+
onClick: HandleClickCustomSelectOverlay,
|
|
11590
11962
|
type: Div
|
|
11591
|
-
}, {
|
|
11963
|
+
}, useInlineHeight ? {
|
|
11592
11964
|
childCount: 1,
|
|
11593
11965
|
className: mergeClassNames(ChatModelPicker, popOverClassName),
|
|
11594
11966
|
style: `height: ${height}px;`,
|
|
11595
11967
|
type: Div
|
|
11968
|
+
} : {
|
|
11969
|
+
childCount: 1,
|
|
11970
|
+
className: mergeClassNames(ChatModelPicker, popOverClassName),
|
|
11971
|
+
type: Div
|
|
11596
11972
|
}, {
|
|
11597
11973
|
childCount: optionCount,
|
|
11598
11974
|
className: ChatModelPickerList,
|
|
@@ -11607,6 +11983,17 @@ const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
|
|
|
11607
11983
|
return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
|
|
11608
11984
|
};
|
|
11609
11985
|
|
|
11986
|
+
const getUsageCostDom = detail => {
|
|
11987
|
+
if (detail === '') {
|
|
11988
|
+
return [];
|
|
11989
|
+
}
|
|
11990
|
+
return [{
|
|
11991
|
+
childCount: 1,
|
|
11992
|
+
className: ChatModelPickerItemUsageCost,
|
|
11993
|
+
type: Span
|
|
11994
|
+
}, text(detail)];
|
|
11995
|
+
};
|
|
11996
|
+
|
|
11610
11997
|
const getUsageCostLabel = model => {
|
|
11611
11998
|
return `${model.usageCost ?? 1}x`;
|
|
11612
11999
|
};
|
|
@@ -11614,9 +12001,11 @@ const getUsageCostLabel = model => {
|
|
|
11614
12001
|
const getChatModelListItemVirtualDom = (model, selectedModelId) => {
|
|
11615
12002
|
const detail = getUsageCostLabel(model);
|
|
11616
12003
|
const hasDetail = detail !== '';
|
|
12004
|
+
const usageCostDom = getUsageCostDom(detail);
|
|
11617
12005
|
const selected = model.id === selectedModelId;
|
|
11618
12006
|
const className = mergeClassNames(ChatModelPickerItem, selected ? ChatModelPickerItemSelected : '');
|
|
11619
12007
|
return [{
|
|
12008
|
+
'aria-selected': selected ? 'true' : 'false',
|
|
11620
12009
|
childCount: hasDetail ? 2 : 1,
|
|
11621
12010
|
className,
|
|
11622
12011
|
'data-id': model.id,
|
|
@@ -11626,11 +12015,7 @@ const getChatModelListItemVirtualDom = (model, selectedModelId) => {
|
|
|
11626
12015
|
childCount: 1,
|
|
11627
12016
|
className: ChatModelPickerItemLabel,
|
|
11628
12017
|
type: Span
|
|
11629
|
-
}, text(getModelLabel(model)), ...
|
|
11630
|
-
childCount: 1,
|
|
11631
|
-
className: ChatModelPickerItemUsageCost,
|
|
11632
|
-
type: Span
|
|
11633
|
-
}, text(detail)] : [])];
|
|
12018
|
+
}, text(getModelLabel(model)), ...usageCostDom];
|
|
11634
12019
|
};
|
|
11635
12020
|
|
|
11636
12021
|
const parentNode$2 = {
|
|
@@ -11649,6 +12034,7 @@ const getChatModelListVirtualDom = (visibleModels, selectedModelId) => {
|
|
|
11649
12034
|
return [{
|
|
11650
12035
|
childCount: visibleModels.length,
|
|
11651
12036
|
className: ChatModelPickerList,
|
|
12037
|
+
id: ModelPickerList,
|
|
11652
12038
|
onClick: HandleClickModelPickerList,
|
|
11653
12039
|
onPointerDown: HandlePointerDownModelPickerList,
|
|
11654
12040
|
onPointerUp: HandlePointerUpModelPickerList,
|
|
@@ -11677,6 +12063,7 @@ const getModelPickerHeaderDom = modelPickerSearchValue => {
|
|
|
11677
12063
|
value: modelPickerSearchValue
|
|
11678
12064
|
}];
|
|
11679
12065
|
};
|
|
12066
|
+
|
|
11680
12067
|
const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPickerSearchValue) => {
|
|
11681
12068
|
const visibleModels = getVisibleModels(models, modelPickerSearchValue);
|
|
11682
12069
|
return [{
|
|
@@ -11692,6 +12079,17 @@ const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPicke
|
|
|
11692
12079
|
}, ...getModelPickerHeaderDom(modelPickerSearchValue), ...getChatModelListVirtualDom(visibleModels, selectedModelId)];
|
|
11693
12080
|
};
|
|
11694
12081
|
|
|
12082
|
+
const getImageCouldNotBeLoadedDom = () => {
|
|
12083
|
+
return [{
|
|
12084
|
+
childCount: 1,
|
|
12085
|
+
className: mergeClassNames(ChatComposerAttachmentPreviewOverlayError, ImageErrorMessage),
|
|
12086
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
12087
|
+
type: Div
|
|
12088
|
+
}, {
|
|
12089
|
+
text: imageCouldNotBeLoaded(),
|
|
12090
|
+
type: Text
|
|
12091
|
+
}];
|
|
12092
|
+
};
|
|
11695
12093
|
const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, attachmentId, hasError) => {
|
|
11696
12094
|
if (!attachmentId) {
|
|
11697
12095
|
return [];
|
|
@@ -11709,15 +12107,7 @@ const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, atta
|
|
|
11709
12107
|
onPointerOut: HandleMouseOut,
|
|
11710
12108
|
onPointerOver: HandleMouseOver,
|
|
11711
12109
|
type: Div
|
|
11712
|
-
}, ...(hasError ? [{
|
|
11713
|
-
childCount: 1,
|
|
11714
|
-
className: mergeClassNames(ChatComposerAttachmentPreviewOverlayError, ImageErrorMessage),
|
|
11715
|
-
name: ComposerAttachmentPreviewOverlay,
|
|
11716
|
-
type: Div
|
|
11717
|
-
}, {
|
|
11718
|
-
text: imageCouldNotBeLoaded(),
|
|
11719
|
-
type: Text
|
|
11720
|
-
}] : [{
|
|
12110
|
+
}, ...(hasError ? getImageCouldNotBeLoadedDom() : [{
|
|
11721
12111
|
alt: `Large image preview for ${attachment.name}`,
|
|
11722
12112
|
childCount: 0,
|
|
11723
12113
|
className: ChatComposerAttachmentPreviewOverlayImage,
|
|
@@ -11728,15 +12118,6 @@ const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, atta
|
|
|
11728
12118
|
}])];
|
|
11729
12119
|
};
|
|
11730
12120
|
|
|
11731
|
-
const runModes = ['local', 'background', 'cloud'];
|
|
11732
|
-
const runModePickerHeight = runModes.length * 28;
|
|
11733
|
-
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
11734
|
-
return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
|
|
11735
|
-
};
|
|
11736
|
-
const getRunModePickerPopOverVirtualDom = selectedRunMode => {
|
|
11737
|
-
return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver);
|
|
11738
|
-
};
|
|
11739
|
-
|
|
11740
12121
|
const getDropOverlayVirtualDom = () => {
|
|
11741
12122
|
return [{
|
|
11742
12123
|
childCount: 1,
|
|
@@ -11751,6 +12132,16 @@ const getDropOverlayVirtualDom = () => {
|
|
|
11751
12132
|
type: Text
|
|
11752
12133
|
}];
|
|
11753
12134
|
};
|
|
12135
|
+
|
|
12136
|
+
const runModes = ['local', 'background', 'cloud'];
|
|
12137
|
+
const runModePickerHeight = runModes.length * 28;
|
|
12138
|
+
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
12139
|
+
return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
|
|
12140
|
+
};
|
|
12141
|
+
const getRunModePickerPopOverVirtualDom = selectedRunMode => {
|
|
12142
|
+
return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver, false);
|
|
12143
|
+
};
|
|
12144
|
+
|
|
11754
12145
|
const getChatOverlaysVirtualDom = ({
|
|
11755
12146
|
agentMode,
|
|
11756
12147
|
agentModePickerVisible,
|
|
@@ -12389,14 +12780,16 @@ const getReadFileTarget = rawArguments => {
|
|
|
12389
12780
|
}
|
|
12390
12781
|
const uri = Reflect.get(parsed, 'uri');
|
|
12391
12782
|
const path = Reflect.get(parsed, 'path');
|
|
12783
|
+
const baseUri = Reflect.get(parsed, 'baseUri');
|
|
12392
12784
|
const uriValue = typeof uri === 'string' ? uri : '';
|
|
12393
12785
|
const pathValue = typeof path === 'string' ? path : '';
|
|
12394
|
-
const
|
|
12786
|
+
const baseUriValue = typeof baseUri === 'string' ? baseUri : '';
|
|
12787
|
+
const title = uriValue || pathValue || baseUriValue;
|
|
12395
12788
|
if (!title) {
|
|
12396
12789
|
return undefined;
|
|
12397
12790
|
}
|
|
12398
|
-
//
|
|
12399
|
-
const clickableUri = uriValue || pathValue;
|
|
12791
|
+
// File-like tool calls use absolute `uri` where available; keep `path` as a legacy fallback.
|
|
12792
|
+
const clickableUri = uriValue || pathValue || baseUriValue;
|
|
12400
12793
|
return {
|
|
12401
12794
|
clickableUri,
|
|
12402
12795
|
title
|
|
@@ -12407,11 +12800,12 @@ const getToolCallFileNameDom = (fileName, {
|
|
|
12407
12800
|
clickableProps = {},
|
|
12408
12801
|
title
|
|
12409
12802
|
} = {}) => {
|
|
12803
|
+
const resolvedTitle = title ?? clickableProps['data-uri'];
|
|
12410
12804
|
return [{
|
|
12411
12805
|
childCount: 1,
|
|
12412
12806
|
className: ChatToolCallReadFileLink,
|
|
12413
|
-
...(
|
|
12414
|
-
title
|
|
12807
|
+
...(resolvedTitle === undefined ? {} : {
|
|
12808
|
+
title: resolvedTitle
|
|
12415
12809
|
}),
|
|
12416
12810
|
...clickableProps,
|
|
12417
12811
|
type: Span
|
|
@@ -12437,7 +12831,6 @@ const getToolCallCreateDirectoryVirtualDom = toolCall => {
|
|
|
12437
12831
|
return [{
|
|
12438
12832
|
childCount: statusLabel ? 4 : 3,
|
|
12439
12833
|
className: ChatOrderedListItem,
|
|
12440
|
-
title: target.title,
|
|
12441
12834
|
type: Li
|
|
12442
12835
|
}, {
|
|
12443
12836
|
childCount: 0,
|
|
@@ -12515,7 +12908,7 @@ const getToolCallLabel = toolCall => {
|
|
|
12515
12908
|
if (toolCall.name === 'write_file' && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12516
12909
|
return `${displayName} (in progress)`;
|
|
12517
12910
|
}
|
|
12518
|
-
if ((toolCall.name === 'list_files' || toolCall.name === 'grep_search') && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12911
|
+
if ((toolCall.name === 'list_files' || toolCall.name === 'grep_search' || toolCall.name === 'glob') && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12519
12912
|
return displayName;
|
|
12520
12913
|
}
|
|
12521
12914
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
@@ -12561,7 +12954,6 @@ const getToolCallEditFileVirtualDom = toolCall => {
|
|
|
12561
12954
|
return [{
|
|
12562
12955
|
childCount: 3,
|
|
12563
12956
|
className: ChatOrderedListItem,
|
|
12564
|
-
title: target.title,
|
|
12565
12957
|
type: Li
|
|
12566
12958
|
}, {
|
|
12567
12959
|
childCount: 0,
|
|
@@ -12590,7 +12982,6 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12590
12982
|
return [{
|
|
12591
12983
|
childCount: statusLabel ? 4 : 3,
|
|
12592
12984
|
className: ChatOrderedListItem,
|
|
12593
|
-
title: toolCall.result,
|
|
12594
12985
|
type: Li
|
|
12595
12986
|
}, {
|
|
12596
12987
|
childCount: 0,
|
|
@@ -12605,6 +12996,21 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12605
12996
|
}), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12606
12997
|
};
|
|
12607
12998
|
|
|
12999
|
+
const getGlobPatternLabel = toolCall => {
|
|
13000
|
+
if (toolCall.name !== 'glob') {
|
|
13001
|
+
return '';
|
|
13002
|
+
}
|
|
13003
|
+
try {
|
|
13004
|
+
const parsed = JSON.parse(toolCall.arguments);
|
|
13005
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
13006
|
+
return '';
|
|
13007
|
+
}
|
|
13008
|
+
const pattern = Reflect.get(parsed, 'pattern');
|
|
13009
|
+
return typeof pattern === 'string' && pattern ? ` "${pattern}"` : '';
|
|
13010
|
+
} catch {
|
|
13011
|
+
return '';
|
|
13012
|
+
}
|
|
13013
|
+
};
|
|
12608
13014
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
12609
13015
|
const target = getReadFileTarget(toolCall.arguments);
|
|
12610
13016
|
if (!target) {
|
|
@@ -12613,14 +13019,16 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12613
13019
|
const fileName = getFileNameFromUri(target.title);
|
|
12614
13020
|
const toolNameLabel = `${toolCall.name} `;
|
|
12615
13021
|
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
13022
|
+
const globPatternLabel = getGlobPatternLabel(toolCall);
|
|
13023
|
+
const globMatchCount = toolCall.name === 'glob' && toolCall.status === 'success' ? getGlobMatchCount(toolCall.result) : undefined;
|
|
13024
|
+
const globMatchLabel = typeof globMatchCount === 'number' ? `, ${globMatchCount} ${globMatchCount === 1 ? 'match' : 'matches'}` : '';
|
|
12616
13025
|
const fileNameClickableProps = target.clickableUri ? {
|
|
12617
13026
|
'data-uri': target.clickableUri,
|
|
12618
13027
|
onClick: HandleClickFileName
|
|
12619
13028
|
} : {};
|
|
12620
13029
|
return [{
|
|
12621
|
-
childCount: statusLabel ?
|
|
13030
|
+
childCount: 3 + (globPatternLabel ? 1 : 0) + (globMatchLabel ? 1 : 0) + (statusLabel ? 1 : 0),
|
|
12622
13031
|
className: ChatOrderedListItem,
|
|
12623
|
-
title: target.title,
|
|
12624
13032
|
type: Li
|
|
12625
13033
|
}, {
|
|
12626
13034
|
childCount: 0,
|
|
@@ -12631,8 +13039,9 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12631
13039
|
className: ToolCallName,
|
|
12632
13040
|
type: Span
|
|
12633
13041
|
}, text(toolNameLabel), ...getToolCallFileNameDom(fileName, {
|
|
12634
|
-
clickableProps: fileNameClickableProps
|
|
12635
|
-
|
|
13042
|
+
clickableProps: fileNameClickableProps,
|
|
13043
|
+
title: target.title
|
|
13044
|
+
}), ...(globPatternLabel ? [text(globPatternLabel)] : []), ...(globMatchLabel ? [text(globMatchLabel)] : []), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12636
13045
|
};
|
|
12637
13046
|
|
|
12638
13047
|
const maxHtmlLength = 40_000;
|
|
@@ -12999,7 +13408,6 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
12999
13408
|
return [{
|
|
13000
13409
|
childCount: showDiffStats ? statusLabel ? 6 : 5 : statusLabel ? 4 : 3,
|
|
13001
13410
|
className: ChatOrderedListItem,
|
|
13002
|
-
title: target.title,
|
|
13003
13411
|
type: Li
|
|
13004
13412
|
}, {
|
|
13005
13413
|
childCount: 0,
|
|
@@ -13029,7 +13437,7 @@ const getToolCallDom = toolCall => {
|
|
|
13029
13437
|
return virtualDom;
|
|
13030
13438
|
}
|
|
13031
13439
|
}
|
|
13032
|
-
if (toolCall.name === 'read_file' || toolCall.name === 'list_files' || toolCall.name === 'list_file') {
|
|
13440
|
+
if (toolCall.name === 'read_file' || toolCall.name === 'list_files' || toolCall.name === 'list_file' || toolCall.name === 'glob') {
|
|
13033
13441
|
const virtualDom = getToolCallReadFileVirtualDom(toolCall);
|
|
13034
13442
|
if (virtualDom.length > 0) {
|
|
13035
13443
|
return virtualDom;
|
|
@@ -13519,12 +13927,21 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13519
13927
|
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13520
13928
|
const chatRootChildCount = 2 + (hasVisibleOverlays ? 1 : 0);
|
|
13521
13929
|
return [{
|
|
13522
|
-
childCount: chatRootChildCount,
|
|
13930
|
+
childCount: chatRootChildCount + 1,
|
|
13523
13931
|
className: mergeClassNames(Viewlet, Chat, ChatFocus),
|
|
13524
13932
|
onDragEnter: HandleDragEnterChatView,
|
|
13525
13933
|
onDragOver: HandleDragOverChatView,
|
|
13934
|
+
onPointerMove: HandlePointerMoveProjectSidebarSash,
|
|
13935
|
+
onPointerUp: HandlePointerUpProjectSidebarSash,
|
|
13526
13936
|
type: Div
|
|
13527
13937
|
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), {
|
|
13938
|
+
'aria-orientation': 'vertical',
|
|
13939
|
+
childCount: 0,
|
|
13940
|
+
className: mergeClassNames(Sash, SashVertical),
|
|
13941
|
+
onPointerDown: HandlePointerDownProjectSidebarSash,
|
|
13942
|
+
role: 'separator',
|
|
13943
|
+
type: Div
|
|
13944
|
+
}, {
|
|
13528
13945
|
childCount: 3,
|
|
13529
13946
|
className: ChatFocusMainArea,
|
|
13530
13947
|
type: Div
|
|
@@ -13562,25 +13979,6 @@ const getBackButtonVirtualDom = () => {
|
|
|
13562
13979
|
}, arrowLeft];
|
|
13563
13980
|
};
|
|
13564
13981
|
|
|
13565
|
-
const getHeaderActionClassName = disabled => {
|
|
13566
|
-
return mergeClassNames(IconButton, disabled ? IconButtonDisabled : '');
|
|
13567
|
-
};
|
|
13568
|
-
const getHeaderActionVirtualDom = item => {
|
|
13569
|
-
return [{
|
|
13570
|
-
childCount: 1,
|
|
13571
|
-
className: getHeaderActionClassName(item.disabled),
|
|
13572
|
-
disabled: item.disabled,
|
|
13573
|
-
name: item.name,
|
|
13574
|
-
onClick: item.onClick,
|
|
13575
|
-
title: item.title,
|
|
13576
|
-
type: Button$1
|
|
13577
|
-
}, {
|
|
13578
|
-
childCount: 0,
|
|
13579
|
-
className: item.icon,
|
|
13580
|
-
type: Div
|
|
13581
|
-
}];
|
|
13582
|
-
};
|
|
13583
|
-
|
|
13584
13982
|
const getChatHeaderActionsDom = (viewMode, searchEnabled = false) => {
|
|
13585
13983
|
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
13586
13984
|
const items = [{
|
|
@@ -13755,6 +14153,7 @@ const getChatSearchDom = (hasSearchField, searchValue) => {
|
|
|
13755
14153
|
value: searchValue
|
|
13756
14154
|
}];
|
|
13757
14155
|
};
|
|
14156
|
+
|
|
13758
14157
|
const getChatHeaderListModeDom = (authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
|
|
13759
14158
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
13760
14159
|
const hasSearchField = searchEnabled && searchFieldVisible;
|
|
@@ -14531,6 +14930,9 @@ const renderEventListeners = () => {
|
|
|
14531
14930
|
}, {
|
|
14532
14931
|
name: HandleClickGitBranchPickerToggle,
|
|
14533
14932
|
params: ['handleClickGitBranchPickerToggle']
|
|
14933
|
+
}, {
|
|
14934
|
+
name: HandleClickCustomSelectOverlay,
|
|
14935
|
+
params: ['handleClickCustomSelectOverlay', DefaultPrevented]
|
|
14534
14936
|
}, {
|
|
14535
14937
|
name: HandleClickModelPickerOverlay,
|
|
14536
14938
|
params: ['handleClickModelPickerOverlay', DefaultPrevented]
|
|
@@ -14652,6 +15054,17 @@ const renderEventListeners = () => {
|
|
|
14652
15054
|
name: HandlePointerDownModelPickerList,
|
|
14653
15055
|
params: ['handlePointerDownModelPickerList'],
|
|
14654
15056
|
preventDefault: true
|
|
15057
|
+
}, {
|
|
15058
|
+
name: HandlePointerDownProjectSidebarSash,
|
|
15059
|
+
params: ['handlePointerDownProjectSidebarSash'],
|
|
15060
|
+
preventDefault: true
|
|
15061
|
+
}, {
|
|
15062
|
+
name: HandlePointerMoveProjectSidebarSash,
|
|
15063
|
+
params: ['handlePointerMoveProjectSidebarSash', ClientX]
|
|
15064
|
+
}, {
|
|
15065
|
+
name: HandlePointerUpProjectSidebarSash,
|
|
15066
|
+
params: ['handlePointerUpProjectSidebarSash', ClientX],
|
|
15067
|
+
preventDefault: true
|
|
14655
15068
|
}, {
|
|
14656
15069
|
name: HandlePointerUpModelPickerList,
|
|
14657
15070
|
params: ['handlePointerUpModelPickerList', ClientY],
|
|
@@ -14765,6 +15178,7 @@ const saveState = state => {
|
|
|
14765
15178
|
projectExpandedIds,
|
|
14766
15179
|
projectListScrollTop,
|
|
14767
15180
|
projects,
|
|
15181
|
+
projectSidebarWidth,
|
|
14768
15182
|
reasoningEffort,
|
|
14769
15183
|
renamingSessionId,
|
|
14770
15184
|
searchFieldVisible,
|
|
@@ -14787,6 +15201,7 @@ const saveState = state => {
|
|
|
14787
15201
|
projectExpandedIds,
|
|
14788
15202
|
projectListScrollTop,
|
|
14789
15203
|
projects,
|
|
15204
|
+
projectSidebarWidth,
|
|
14790
15205
|
reasoningEffort,
|
|
14791
15206
|
renamingSessionId,
|
|
14792
15207
|
searchFieldVisible,
|
|
@@ -15022,6 +15437,7 @@ const commandMap = {
|
|
|
15022
15437
|
'Chat.handleClickBack': wrapCommand(handleClickBack),
|
|
15023
15438
|
'Chat.handleClickClose': handleClickClose,
|
|
15024
15439
|
'Chat.handleClickCreatePullRequest': wrapCommand(handleClickCreatePullRequest),
|
|
15440
|
+
'Chat.handleClickCustomSelectOverlay': wrapCommand(handleClickCustomSelectOverlay),
|
|
15025
15441
|
'Chat.handleClickDelete': wrapCommand(handleClickDelete),
|
|
15026
15442
|
'Chat.handleClickDictationButton': wrapCommand(handleClickDictationButton),
|
|
15027
15443
|
'Chat.handleClickFileName': wrapCommand(handleClickFileName),
|
|
@@ -15056,7 +15472,10 @@ const commandMap = {
|
|
|
15056
15472
|
'Chat.handleMouseOut': wrapCommand(handleMouseOut),
|
|
15057
15473
|
'Chat.handleMouseOver': wrapCommand(handleMouseOver),
|
|
15058
15474
|
'Chat.handlePointerDownModelPickerList': wrapCommand(handlePointerDownModelPickerList),
|
|
15475
|
+
'Chat.handlePointerDownProjectSidebarSash': wrapCommand(handlePointerDownProjectSidebarSash),
|
|
15476
|
+
'Chat.handlePointerMoveProjectSidebarSash': wrapCommand(handlePointerMoveProjectSidebarSash),
|
|
15059
15477
|
'Chat.handlePointerUpModelPickerList': wrapCommand(handlePointerUpModelPickerList),
|
|
15478
|
+
'Chat.handlePointerUpProjectSidebarSash': wrapCommand(handlePointerUpProjectSidebarSash),
|
|
15060
15479
|
'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
|
|
15061
15480
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
15062
15481
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|