@lvce-editor/chat-view 7.4.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 +532 -176
- 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);
|
|
@@ -2222,6 +2225,7 @@ Use available project context to provide accurate, practical coding help.
|
|
|
2222
2225
|
Prefer using available tools to inspect and modify files in the current workspace.
|
|
2223
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.
|
|
2224
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\`.
|
|
2225
2229
|
When displaying code blocks in responses, use markdown triple backticks (\`\`\`) fences.
|
|
2226
2230
|
When referencing workspace files in responses (including "files added/changed" lists), use markdown links so users can click them.
|
|
2227
2231
|
Prefer file links like [src/index.ts]({{workspaceUri}}/src/index.ts) and avoid plain text file paths when a link is appropriate.
|
|
@@ -2291,11 +2295,16 @@ const getReasoningEffortLabel = reasoningEffort => {
|
|
|
2291
2295
|
}
|
|
2292
2296
|
};
|
|
2293
2297
|
|
|
2298
|
+
const defaultToolEnablement = {
|
|
2299
|
+
run_in_terminal: false
|
|
2300
|
+
};
|
|
2294
2301
|
const parseToolEnablement = value => {
|
|
2295
2302
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
2296
|
-
return
|
|
2303
|
+
return defaultToolEnablement;
|
|
2297
2304
|
}
|
|
2298
|
-
const toolEnablement = {
|
|
2305
|
+
const toolEnablement = {
|
|
2306
|
+
...defaultToolEnablement
|
|
2307
|
+
};
|
|
2299
2308
|
for (const [key, enabled] of Object.entries(value)) {
|
|
2300
2309
|
if (typeof enabled === 'boolean') {
|
|
2301
2310
|
toolEnablement[key] = enabled;
|
|
@@ -2320,10 +2329,13 @@ const validateToolEnablement = value => {
|
|
|
2320
2329
|
};
|
|
2321
2330
|
const isToolEnabled = (toolEnablement, toolName) => {
|
|
2322
2331
|
if (!toolEnablement) {
|
|
2323
|
-
return true;
|
|
2332
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2324
2333
|
}
|
|
2325
2334
|
const enabled = toolEnablement[toolName];
|
|
2326
|
-
|
|
2335
|
+
if (typeof enabled === 'boolean') {
|
|
2336
|
+
return enabled;
|
|
2337
|
+
}
|
|
2338
|
+
return defaultToolEnablement[toolName] ?? true;
|
|
2327
2339
|
};
|
|
2328
2340
|
const filterEnabledTools = (tools, toolEnablement) => {
|
|
2329
2341
|
return tools.filter(tool => isToolEnabled(toolEnablement, tool.function.name));
|
|
@@ -2399,7 +2411,7 @@ const createDefaultState = () => {
|
|
|
2399
2411
|
maxToolCalls: defaultMaxToolCalls,
|
|
2400
2412
|
messagesAutoScrollEnabled: true,
|
|
2401
2413
|
messagesScrollTop: 0,
|
|
2402
|
-
mockAiResponseDelay:
|
|
2414
|
+
mockAiResponseDelay: 0,
|
|
2403
2415
|
mockApiCommandId: '',
|
|
2404
2416
|
mockOpenApiRequests: [],
|
|
2405
2417
|
modelPickerHeaderHeight,
|
|
@@ -2431,6 +2443,8 @@ const createDefaultState = () => {
|
|
|
2431
2443
|
name: '_blank',
|
|
2432
2444
|
uri: ''
|
|
2433
2445
|
}],
|
|
2446
|
+
projectSidebarResizing: false,
|
|
2447
|
+
projectSidebarWidth: 280,
|
|
2434
2448
|
questionToolEnabled: false,
|
|
2435
2449
|
reasoningEffort: defaultReasoningEffort,
|
|
2436
2450
|
reasoningEffortPickerOpen: false,
|
|
@@ -2835,7 +2849,7 @@ const getRenderHtmlCss = (sessions, selectedSessionId) => {
|
|
|
2835
2849
|
const isEqual$1 = (oldState, newState) => {
|
|
2836
2850
|
const oldRenderHtmlCss = getRenderHtmlCss(oldState.sessions, oldState.selectedSessionId);
|
|
2837
2851
|
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;
|
|
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;
|
|
2839
2853
|
};
|
|
2840
2854
|
|
|
2841
2855
|
const diffFocus = (oldState, newState) => {
|
|
@@ -3890,37 +3904,27 @@ const openFolder = async () => {
|
|
|
3890
3904
|
}
|
|
3891
3905
|
};
|
|
3892
3906
|
|
|
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;
|
|
3907
|
+
const parseEntries = value => {
|
|
3908
|
+
if (!Array.isArray(value)) {
|
|
3909
|
+
return [];
|
|
3921
3910
|
}
|
|
3922
|
-
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);
|
|
3923
3926
|
};
|
|
3927
|
+
|
|
3924
3928
|
const getRelativePath = (fromPath, toPath) => {
|
|
3925
3929
|
if (!fromPath.startsWith('/') || !toPath.startsWith('/')) {
|
|
3926
3930
|
return toPath;
|
|
@@ -3935,6 +3939,14 @@ const getRelativePath = (fromPath, toPath) => {
|
|
|
3935
3939
|
const childSegments = toParts.slice(commonPrefixLength);
|
|
3936
3940
|
return [...parentSegments, ...childSegments].join('/') || '.';
|
|
3937
3941
|
};
|
|
3942
|
+
|
|
3943
|
+
const toFileSystemPath = uri => {
|
|
3944
|
+
if (!uri.startsWith('file://')) {
|
|
3945
|
+
return uri;
|
|
3946
|
+
}
|
|
3947
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
3948
|
+
};
|
|
3949
|
+
|
|
3938
3950
|
const toFileSystemTarget = (workspaceUri, uri) => {
|
|
3939
3951
|
const workspacePath = toFileSystemPath(workspaceUri);
|
|
3940
3952
|
const fileSystemPath = toFileSystemPath(uri);
|
|
@@ -3943,34 +3955,56 @@ const toFileSystemTarget = (workspaceUri, uri) => {
|
|
|
3943
3955
|
}
|
|
3944
3956
|
return getRelativePath(workspacePath, fileSystemPath);
|
|
3945
3957
|
};
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
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('/')}`;
|
|
3949
3969
|
}
|
|
3950
|
-
return
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
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;
|
|
3956
3981
|
}
|
|
3957
|
-
if (entry
|
|
3958
|
-
|
|
3959
|
-
name: Reflect.get(entry, 'name'),
|
|
3960
|
-
type: Reflect.get(entry, 'type')
|
|
3961
|
-
};
|
|
3982
|
+
if (entry.type === FileTypeFile) {
|
|
3983
|
+
branches.add(`${prefix}${entry.name}`);
|
|
3962
3984
|
}
|
|
3963
|
-
|
|
3964
|
-
}).filter(entry => !!entry);
|
|
3985
|
+
}
|
|
3965
3986
|
};
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
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 '';
|
|
3969
3999
|
};
|
|
4000
|
+
|
|
3970
4001
|
const readTextFile = async (workspaceUri, uri) => {
|
|
3971
4002
|
const result = await invoke('FileSystem.readFile', toFileSystemTarget(workspaceUri, uri));
|
|
3972
4003
|
return decodeFileContent(result);
|
|
3973
4004
|
};
|
|
4005
|
+
|
|
4006
|
+
// cspell:ignore gitdir worktrees
|
|
4007
|
+
const gitDirPointerRegex = /^gitdir:\s*(.+)$/m;
|
|
3974
4008
|
const getGitDirUri = async workspaceUri => {
|
|
3975
4009
|
const gitUri = toGitUri(workspaceUri, '.git');
|
|
3976
4010
|
try {
|
|
@@ -3986,18 +4020,8 @@ const getGitDirUri = async workspaceUri => {
|
|
|
3986
4020
|
}
|
|
3987
4021
|
return new URL(match[1].trim(), workspaceUri.endsWith('/') ? workspaceUri : `${workspaceUri}/`).toString();
|
|
3988
4022
|
};
|
|
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
|
-
};
|
|
4023
|
+
|
|
4024
|
+
const headRefRegex = /^ref:\s+refs\/heads\/(.+)$/m;
|
|
4001
4025
|
const parseCurrentBranch = headContent => {
|
|
4002
4026
|
const match = headRefRegex.exec(headContent.trim());
|
|
4003
4027
|
if (match) {
|
|
@@ -4005,13 +4029,7 @@ const parseCurrentBranch = headContent => {
|
|
|
4005
4029
|
}
|
|
4006
4030
|
return '';
|
|
4007
4031
|
};
|
|
4008
|
-
|
|
4009
|
-
try {
|
|
4010
|
-
return Boolean(await getGitDirUri(workspaceUri));
|
|
4011
|
-
} catch {
|
|
4012
|
-
return false;
|
|
4013
|
-
}
|
|
4014
|
-
};
|
|
4032
|
+
|
|
4015
4033
|
const getGitBranches = async workspaceUri => {
|
|
4016
4034
|
const gitDirUri = await getGitDirUri(workspaceUri);
|
|
4017
4035
|
if (!gitDirUri) {
|
|
@@ -4044,6 +4062,14 @@ const getGitBranches = async workspaceUri => {
|
|
|
4044
4062
|
}));
|
|
4045
4063
|
};
|
|
4046
4064
|
|
|
4065
|
+
const hasGitRepository = async workspaceUri => {
|
|
4066
|
+
try {
|
|
4067
|
+
return Boolean(await getGitDirUri(workspaceUri));
|
|
4068
|
+
} catch {
|
|
4069
|
+
return false;
|
|
4070
|
+
}
|
|
4071
|
+
};
|
|
4072
|
+
|
|
4047
4073
|
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
4048
4074
|
return sessions.find(session => session.id === selectedSessionId);
|
|
4049
4075
|
};
|
|
@@ -4642,6 +4668,30 @@ const hasToolError = value => {
|
|
|
4642
4668
|
const error = Reflect.get(value, 'error');
|
|
4643
4669
|
return typeof error === 'string' && error.trim().length > 0;
|
|
4644
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
|
+
};
|
|
4645
4695
|
const parseWriteFileArguments = rawArguments => {
|
|
4646
4696
|
let parsed = rawArguments;
|
|
4647
4697
|
if (typeof rawArguments === 'string') {
|
|
@@ -4749,15 +4799,60 @@ const executeChatTool = async (name, rawArguments, options) => {
|
|
|
4749
4799
|
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
4750
4800
|
throw new Error('Chat tools must be executed in a web worker environment. Please set useChatToolWorker to true in the options.');
|
|
4751
4801
|
}
|
|
4752
|
-
const
|
|
4802
|
+
const executionOptions = {
|
|
4753
4803
|
assetDir: options.assetDir,
|
|
4754
4804
|
platform: options.platform,
|
|
4755
4805
|
...(options.workspaceUri ? {
|
|
4756
4806
|
workspaceUri: options.workspaceUri
|
|
4757
4807
|
} : {})
|
|
4758
|
-
}
|
|
4759
|
-
const
|
|
4760
|
-
|
|
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
|
+
}
|
|
4761
4856
|
};
|
|
4762
4857
|
|
|
4763
4858
|
const getAskQuestionTool = () => {
|
|
@@ -4839,6 +4934,7 @@ const getAttachmentTextPart = attachment => {
|
|
|
4839
4934
|
};
|
|
4840
4935
|
}
|
|
4841
4936
|
};
|
|
4937
|
+
|
|
4842
4938
|
const getChatMessageOpenAiContent = message => {
|
|
4843
4939
|
if (!message.attachments || message.attachments.length === 0) {
|
|
4844
4940
|
return message.text;
|
|
@@ -4870,7 +4966,9 @@ const getClientRequestIdHeader = () => {
|
|
|
4870
4966
|
};
|
|
4871
4967
|
|
|
4872
4968
|
const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
4873
|
-
|
|
4969
|
+
if (delayInMs > 0) {
|
|
4970
|
+
await delay(delayInMs);
|
|
4971
|
+
}
|
|
4874
4972
|
return `Mock AI response: I received "${userMessage}".`;
|
|
4875
4973
|
};
|
|
4876
4974
|
|
|
@@ -5354,6 +5452,51 @@ const makeStreamingApiRequest = async options => {
|
|
|
5354
5452
|
return invoke$6('ChatNetwork.makeStreamingApiRequest', options);
|
|
5355
5453
|
};
|
|
5356
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
|
+
|
|
5357
5500
|
const getTextContent = content => {
|
|
5358
5501
|
if (typeof content === 'string') {
|
|
5359
5502
|
return content;
|
|
@@ -5518,6 +5661,9 @@ const getToolCallResult = (name, content) => {
|
|
|
5518
5661
|
}
|
|
5519
5662
|
return content;
|
|
5520
5663
|
}
|
|
5664
|
+
if (name === 'glob') {
|
|
5665
|
+
return getGlobMatchCount(content) === undefined ? undefined : content;
|
|
5666
|
+
}
|
|
5521
5667
|
if (name !== 'getWorkspaceUri') {
|
|
5522
5668
|
return undefined;
|
|
5523
5669
|
}
|
|
@@ -6029,6 +6175,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6029
6175
|
onToolCallsChunk,
|
|
6030
6176
|
questionToolEnabled = false,
|
|
6031
6177
|
reasoningEffort,
|
|
6178
|
+
sessionId,
|
|
6032
6179
|
stream,
|
|
6033
6180
|
supportsReasoningEffort = false,
|
|
6034
6181
|
systemPrompt = '',
|
|
@@ -6145,6 +6292,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6145
6292
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6146
6293
|
assetDir,
|
|
6147
6294
|
platform,
|
|
6295
|
+
...(sessionId ? {
|
|
6296
|
+
sessionId
|
|
6297
|
+
} : {}),
|
|
6298
|
+
toolCallId: toolCall.callId,
|
|
6148
6299
|
...(toolEnablement ? {
|
|
6149
6300
|
toolEnablement
|
|
6150
6301
|
} : {}),
|
|
@@ -6298,6 +6449,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6298
6449
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
6299
6450
|
assetDir,
|
|
6300
6451
|
platform,
|
|
6452
|
+
...(sessionId ? {
|
|
6453
|
+
sessionId
|
|
6454
|
+
} : {}),
|
|
6455
|
+
toolCallId: toolCall.callId,
|
|
6301
6456
|
...(toolEnablement ? {
|
|
6302
6457
|
toolEnablement
|
|
6303
6458
|
} : {}),
|
|
@@ -6378,6 +6533,10 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
6378
6533
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6379
6534
|
assetDir,
|
|
6380
6535
|
platform,
|
|
6536
|
+
...(sessionId ? {
|
|
6537
|
+
sessionId
|
|
6538
|
+
} : {}),
|
|
6539
|
+
toolCallId: id,
|
|
6381
6540
|
useChatToolWorker,
|
|
6382
6541
|
workspaceUri
|
|
6383
6542
|
}) : '{}';
|
|
@@ -6653,7 +6812,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, us
|
|
|
6653
6812
|
}
|
|
6654
6813
|
return normalizedLimitInfo;
|
|
6655
6814
|
};
|
|
6656
|
-
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) => {
|
|
6657
6816
|
const effectiveAgentMode = typeof agentMode === 'boolean' ? defaultAgentMode : agentMode;
|
|
6658
6817
|
const completionMessages = [...(systemPrompt ? [{
|
|
6659
6818
|
content: systemPrompt,
|
|
@@ -6815,6 +6974,10 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
|
|
|
6815
6974
|
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
6816
6975
|
assetDir,
|
|
6817
6976
|
platform,
|
|
6977
|
+
...(sessionId ? {
|
|
6978
|
+
sessionId
|
|
6979
|
+
} : {}),
|
|
6980
|
+
toolCallId: id,
|
|
6818
6981
|
...(toolEnablement ? {
|
|
6819
6982
|
toolEnablement
|
|
6820
6983
|
} : {}),
|
|
@@ -6990,6 +7153,7 @@ const getAiResponse = async ({
|
|
|
6990
7153
|
questionToolEnabled = false,
|
|
6991
7154
|
reasoningEffort,
|
|
6992
7155
|
selectedModelId,
|
|
7156
|
+
sessionId,
|
|
6993
7157
|
streamingEnabled = true,
|
|
6994
7158
|
systemPrompt = '',
|
|
6995
7159
|
toolEnablement,
|
|
@@ -7001,6 +7165,7 @@ const getAiResponse = async ({
|
|
|
7001
7165
|
webSearchEnabled = false,
|
|
7002
7166
|
workspaceUri
|
|
7003
7167
|
}) => {
|
|
7168
|
+
useChatCoordinatorWorker = false; // TODO enable this
|
|
7004
7169
|
if (useChatCoordinatorWorker && !authEnabled) {
|
|
7005
7170
|
try {
|
|
7006
7171
|
const result = await getAiResponse$1({
|
|
@@ -7115,6 +7280,10 @@ const getAiResponse = async ({
|
|
|
7115
7280
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
7116
7281
|
assetDir,
|
|
7117
7282
|
platform,
|
|
7283
|
+
...(sessionId ? {
|
|
7284
|
+
sessionId
|
|
7285
|
+
} : {}),
|
|
7286
|
+
toolCallId: toolCall.callId,
|
|
7118
7287
|
...(toolEnablement ? {
|
|
7119
7288
|
toolEnablement
|
|
7120
7289
|
} : {}),
|
|
@@ -7173,6 +7342,9 @@ const getAiResponse = async ({
|
|
|
7173
7342
|
...(reasoningEffort ? {
|
|
7174
7343
|
reasoningEffort
|
|
7175
7344
|
} : {}),
|
|
7345
|
+
...(sessionId ? {
|
|
7346
|
+
sessionId
|
|
7347
|
+
} : {}),
|
|
7176
7348
|
stream: streamingEnabled,
|
|
7177
7349
|
supportsReasoningEffort,
|
|
7178
7350
|
systemPrompt,
|
|
@@ -7210,7 +7382,7 @@ const getAiResponse = async ({
|
|
|
7210
7382
|
text = getOpenRouterErrorMessage(result);
|
|
7211
7383
|
}
|
|
7212
7384
|
} else if (openRouterApiKey) {
|
|
7213
|
-
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);
|
|
7214
7386
|
if (result.type === 'success') {
|
|
7215
7387
|
const {
|
|
7216
7388
|
text: assistantText
|
|
@@ -7995,8 +8167,19 @@ const getWorkspaceUri = (state, session) => {
|
|
|
7995
8167
|
}
|
|
7996
8168
|
return getProjectUri(state, session?.projectId || state.selectedProjectId);
|
|
7997
8169
|
};
|
|
7998
|
-
const
|
|
7999
|
-
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');
|
|
8000
8183
|
const currentDateInstructions = `Current date: ${getCurrentDate()}.
|
|
8001
8184
|
|
|
8002
8185
|
Do not assume your knowledge cutoff is the same as the current date.`;
|
|
@@ -8204,8 +8387,8 @@ const handleSubmit = async state => {
|
|
|
8204
8387
|
mockOpenApiRequests
|
|
8205
8388
|
} = optimisticState;
|
|
8206
8389
|
const selectedOptimisticSession = optimisticState.sessions.find(session => session.id === optimisticState.selectedSessionId);
|
|
8207
|
-
const
|
|
8208
|
-
const
|
|
8390
|
+
const workspaceUri = useMockApi ? getWorkspaceUri(optimisticState, selectedOptimisticSession) : await resolveWorkspaceUri(optimisticState, selectedOptimisticSession);
|
|
8391
|
+
const systemPrompt = getEffectiveSystemPrompt(optimisticState, workspaceUri);
|
|
8209
8392
|
const messages = (selectedOptimisticSession?.messages ?? []).filter(message => !message.inProgress);
|
|
8210
8393
|
const mentionContextMessage = await getMentionContextMessage(userText);
|
|
8211
8394
|
const messagesWithMentionContext = mentionContextMessage ? [...messages, mentionContextMessage] : messages;
|
|
@@ -8265,6 +8448,7 @@ const handleSubmit = async state => {
|
|
|
8265
8448
|
} : {}),
|
|
8266
8449
|
reasoningEffort,
|
|
8267
8450
|
selectedModelId,
|
|
8451
|
+
sessionId: optimisticState.selectedSessionId,
|
|
8268
8452
|
streamingEnabled,
|
|
8269
8453
|
systemPrompt,
|
|
8270
8454
|
toolEnablement,
|
|
@@ -9412,10 +9596,57 @@ const handlePointerDownModelPickerList = async state => {
|
|
|
9412
9596
|
return state;
|
|
9413
9597
|
};
|
|
9414
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
|
+
|
|
9415
9635
|
const handlePointerUpModelPickerList = async (state, eventY = 0) => {
|
|
9416
9636
|
return state;
|
|
9417
9637
|
};
|
|
9418
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
|
+
|
|
9419
9650
|
const handleProjectAddButtonContextMenu = async (state, button, x, y) => {
|
|
9420
9651
|
const {
|
|
9421
9652
|
uid
|
|
@@ -9703,6 +9934,19 @@ const getSavedProjects = savedState => {
|
|
|
9703
9934
|
return validProjects;
|
|
9704
9935
|
};
|
|
9705
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
|
+
|
|
9706
9950
|
const getSavedReasoningEffort = savedState => {
|
|
9707
9951
|
if (!isObject$1(savedState)) {
|
|
9708
9952
|
return undefined;
|
|
@@ -9923,7 +10167,7 @@ const loadToolEnablement = async () => {
|
|
|
9923
10167
|
const savedToolEnablement = await get('chat.toolEnablement');
|
|
9924
10168
|
return parseToolEnablement(savedToolEnablement);
|
|
9925
10169
|
} catch {
|
|
9926
|
-
return
|
|
10170
|
+
return parseToolEnablement(undefined);
|
|
9927
10171
|
}
|
|
9928
10172
|
};
|
|
9929
10173
|
|
|
@@ -10099,6 +10343,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10099
10343
|
const chatListScrollTop = getSavedChatListScrollTop(savedState) ?? state.chatListScrollTop;
|
|
10100
10344
|
const messagesScrollTop = getSavedMessagesScrollTop(savedState) ?? state.messagesScrollTop;
|
|
10101
10345
|
const projectListScrollTop = getSavedProjectListScrollTop(savedState) ?? state.projectListScrollTop;
|
|
10346
|
+
const projectSidebarWidth = getSavedProjectSidebarWidth(savedState) ?? state.projectSidebarWidth;
|
|
10102
10347
|
const savedProjectExpandedIds = getSavedProjectExpandedIds(savedState);
|
|
10103
10348
|
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
10104
10349
|
const reasoningEffort = getSavedReasoningEffort(savedState) ?? state.reasoningEffort;
|
|
@@ -10153,6 +10398,8 @@ const loadContent = async (state, savedState) => {
|
|
|
10153
10398
|
projectExpandedIds,
|
|
10154
10399
|
projectListScrollTop,
|
|
10155
10400
|
projects,
|
|
10401
|
+
projectSidebarResizing: false,
|
|
10402
|
+
projectSidebarWidth,
|
|
10156
10403
|
reasoningEffort,
|
|
10157
10404
|
reasoningEffortPickerOpen: false,
|
|
10158
10405
|
reasoningPickerEnabled,
|
|
@@ -10341,7 +10588,7 @@ const removeComposerAttachment = async (state, attachmentId) => {
|
|
|
10341
10588
|
return handleRemoveComposerAttachment(state, attachmentId);
|
|
10342
10589
|
};
|
|
10343
10590
|
|
|
10344
|
-
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) => {
|
|
10345
10592
|
const buttonsHeight = 20;
|
|
10346
10593
|
const gap = 10;
|
|
10347
10594
|
const contentPadding = 10;
|
|
@@ -10366,6 +10613,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10366
10613
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
10367
10614
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
10368
10615
|
--ChatFocusContentMaxWidth: ${chatFocusContentMaxWidth}px;
|
|
10616
|
+
--ProjectSidebarWidth: ${projectSidebarWidth}px;
|
|
10369
10617
|
--RunModePickerHeight: ${runModePickerHeight}px;
|
|
10370
10618
|
}
|
|
10371
10619
|
|
|
@@ -10679,7 +10927,41 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10679
10927
|
.Viewlet.Chat.ChatFocus{
|
|
10680
10928
|
display: flex !important;
|
|
10681
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;
|
|
10682
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));
|
|
10963
|
+
}
|
|
10964
|
+
|
|
10683
10965
|
.ChatFocusMainArea{
|
|
10684
10966
|
display: flex;
|
|
10685
10967
|
flex: 1;
|
|
@@ -10794,6 +11076,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10794
11076
|
composerHeight,
|
|
10795
11077
|
listItemHeight,
|
|
10796
11078
|
modelPickerHeight,
|
|
11079
|
+
projectSidebarWidth,
|
|
10797
11080
|
selectedSessionId,
|
|
10798
11081
|
sessions,
|
|
10799
11082
|
textAreaPaddingBottom,
|
|
@@ -10803,7 +11086,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10803
11086
|
uid
|
|
10804
11087
|
} = newState;
|
|
10805
11088
|
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);
|
|
11089
|
+
const css = getCss(composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, projectSidebarWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
10807
11090
|
return [SetCss, uid, css];
|
|
10808
11091
|
};
|
|
10809
11092
|
|
|
@@ -10982,9 +11265,13 @@ const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
|
10982
11265
|
const MaskIconChevronUp = 'MaskIconChevronUp';
|
|
10983
11266
|
const MaskIconClose = 'MaskIconClose';
|
|
10984
11267
|
const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
11268
|
+
const MaskIconDiff = 'MaskIconDiff';
|
|
11269
|
+
const MaskIconFolder = 'MaskIconFolder';
|
|
11270
|
+
const MaskIconGitCommit = 'MaskIconGitCommit';
|
|
10985
11271
|
const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
|
|
10986
11272
|
const MaskIconSearch = 'MaskIconSearch';
|
|
10987
11273
|
const MaskIconSettingsGear = 'MaskIconSettingsGear';
|
|
11274
|
+
const MaskIconTerminal = 'MaskIconTerminal';
|
|
10988
11275
|
const Message = 'Message';
|
|
10989
11276
|
const MessageAssistant = 'MessageAssistant';
|
|
10990
11277
|
const MessageUser = 'MessageUser';
|
|
@@ -11003,6 +11290,8 @@ const ProjectSessionItem = 'ProjectSessionItem';
|
|
|
11003
11290
|
const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
|
|
11004
11291
|
const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
|
|
11005
11292
|
const ProjectSidebar = 'ProjectSidebar';
|
|
11293
|
+
const Sash = 'Sash';
|
|
11294
|
+
const SashVertical = 'SashVertical';
|
|
11006
11295
|
const SearchFieldContainer = 'SearchFieldContainer';
|
|
11007
11296
|
const RunModePickerContainer = 'RunModePickerContainer';
|
|
11008
11297
|
const RunModePickerPopOver = 'RunModePickerPopOver';
|
|
@@ -11071,6 +11360,9 @@ const HandleContextMenuChatImageAttachment = 58;
|
|
|
11071
11360
|
const HandleClickGitBranchPickerToggle = 59;
|
|
11072
11361
|
const HandleErrorComposerAttachmentPreviewOverlay = 60;
|
|
11073
11362
|
const HandleClickCustomSelectOverlay = 61;
|
|
11363
|
+
const HandlePointerDownProjectSidebarSash = 62;
|
|
11364
|
+
const HandlePointerMoveProjectSidebarSash = 63;
|
|
11365
|
+
const HandlePointerUpProjectSidebarSash = 64;
|
|
11074
11366
|
|
|
11075
11367
|
const getAddContextButtonDom = () => {
|
|
11076
11368
|
return [{
|
|
@@ -11380,34 +11672,51 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
11380
11672
|
}, text(usageLabel)];
|
|
11381
11673
|
};
|
|
11382
11674
|
|
|
11383
|
-
const
|
|
11675
|
+
const getComposerAttachmentClassName = displayType => {
|
|
11384
11676
|
switch (displayType) {
|
|
11385
11677
|
case 'file':
|
|
11386
|
-
return
|
|
11678
|
+
return ChatComposerAttachment;
|
|
11387
11679
|
case 'image':
|
|
11388
|
-
return
|
|
11680
|
+
return ChatComposerAttachmentImage;
|
|
11389
11681
|
case 'invalid-image':
|
|
11390
|
-
return
|
|
11682
|
+
return ChatComposerAttachmentInvalidImage;
|
|
11391
11683
|
case 'text-file':
|
|
11392
|
-
return
|
|
11684
|
+
return ChatComposerAttachmentTextFile;
|
|
11393
11685
|
default:
|
|
11394
|
-
return
|
|
11686
|
+
return ChatComposerAttachment;
|
|
11395
11687
|
}
|
|
11396
11688
|
};
|
|
11397
|
-
|
|
11689
|
+
|
|
11690
|
+
const getComposerAttachmentLabel = displayType => {
|
|
11398
11691
|
switch (displayType) {
|
|
11399
11692
|
case 'file':
|
|
11400
|
-
return
|
|
11693
|
+
return 'File';
|
|
11401
11694
|
case 'image':
|
|
11402
|
-
return
|
|
11695
|
+
return 'Image';
|
|
11403
11696
|
case 'invalid-image':
|
|
11404
|
-
return
|
|
11697
|
+
return 'Invalid image';
|
|
11405
11698
|
case 'text-file':
|
|
11406
|
-
return
|
|
11699
|
+
return 'Text file';
|
|
11407
11700
|
default:
|
|
11408
|
-
return
|
|
11701
|
+
return displayType;
|
|
11702
|
+
}
|
|
11703
|
+
};
|
|
11704
|
+
|
|
11705
|
+
const getComposerAttachmentPreviewDom = attachment => {
|
|
11706
|
+
if (!attachment.previewSrc) {
|
|
11707
|
+
return [];
|
|
11409
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
|
+
}];
|
|
11410
11718
|
};
|
|
11719
|
+
|
|
11411
11720
|
const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
11412
11721
|
return [{
|
|
11413
11722
|
'aria-label': removeAttachment(),
|
|
@@ -11423,20 +11732,7 @@ const getComposerAttachmentRemoveButtonDom = attachment => {
|
|
|
11423
11732
|
type: Text
|
|
11424
11733
|
}];
|
|
11425
11734
|
};
|
|
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
|
-
};
|
|
11735
|
+
|
|
11440
11736
|
const getComposerAttachmentsDom = composerAttachments => {
|
|
11441
11737
|
if (composerAttachments.length === 0) {
|
|
11442
11738
|
return [];
|
|
@@ -11468,6 +11764,7 @@ const getComposerAttachmentsDom = composerAttachments => {
|
|
|
11468
11764
|
}];
|
|
11469
11765
|
})];
|
|
11470
11766
|
};
|
|
11767
|
+
|
|
11471
11768
|
const getComposerTextAreaDom = () => {
|
|
11472
11769
|
return {
|
|
11473
11770
|
childCount: 0,
|
|
@@ -11482,6 +11779,7 @@ const getComposerTextAreaDom = () => {
|
|
|
11482
11779
|
type: TextArea
|
|
11483
11780
|
};
|
|
11484
11781
|
};
|
|
11782
|
+
|
|
11485
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) => {
|
|
11486
11784
|
const isSendDisabled = composerValue.trim() === '';
|
|
11487
11785
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
@@ -11570,26 +11868,57 @@ const getChatHeaderAuthDom = (authEnabled = false, userState = 'loggedOut', user
|
|
|
11570
11868
|
}, text(buttonLabel)];
|
|
11571
11869
|
};
|
|
11572
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
|
+
|
|
11573
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;';
|
|
11574
11891
|
const focusHeaderMetaStyle = 'align-items:baseline;display:flex;gap:8px;min-width:0;overflow:hidden;';
|
|
11575
11892
|
const focusHeaderTitleStyle = 'margin:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11576
11893
|
const focusHeaderProjectStyle = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11577
11894
|
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
11895
|
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, authEnabled = false, userState = 'loggedOut', userName = '') => {
|
|
11592
|
-
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
|
+
}];
|
|
11593
11922
|
const hasProjectName = !!selectedProjectName;
|
|
11594
11923
|
return [{
|
|
11595
11924
|
childCount: 2 + (authEnabled ? 1 : 0),
|
|
@@ -11618,7 +11947,7 @@ const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName, au
|
|
|
11618
11947
|
role: ToolBar,
|
|
11619
11948
|
style: focusHeaderActionsStyle,
|
|
11620
11949
|
type: Div
|
|
11621
|
-
}, ...items.flatMap(
|
|
11950
|
+
}, ...items.flatMap(getHeaderActionVirtualDom)];
|
|
11622
11951
|
};
|
|
11623
11952
|
|
|
11624
11953
|
const getAgentModeOptionsVirtualDom = selectedAgentMode => {
|
|
@@ -11654,10 +11983,6 @@ const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
|
|
|
11654
11983
|
return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
|
|
11655
11984
|
};
|
|
11656
11985
|
|
|
11657
|
-
const getUsageCostLabel = model => {
|
|
11658
|
-
return `${model.usageCost ?? 1}x`;
|
|
11659
|
-
};
|
|
11660
|
-
|
|
11661
11986
|
const getUsageCostDom = detail => {
|
|
11662
11987
|
if (detail === '') {
|
|
11663
11988
|
return [];
|
|
@@ -11668,6 +11993,11 @@ const getUsageCostDom = detail => {
|
|
|
11668
11993
|
type: Span
|
|
11669
11994
|
}, text(detail)];
|
|
11670
11995
|
};
|
|
11996
|
+
|
|
11997
|
+
const getUsageCostLabel = model => {
|
|
11998
|
+
return `${model.usageCost ?? 1}x`;
|
|
11999
|
+
};
|
|
12000
|
+
|
|
11671
12001
|
const getChatModelListItemVirtualDom = (model, selectedModelId) => {
|
|
11672
12002
|
const detail = getUsageCostLabel(model);
|
|
11673
12003
|
const hasDetail = detail !== '';
|
|
@@ -11733,6 +12063,7 @@ const getModelPickerHeaderDom = modelPickerSearchValue => {
|
|
|
11733
12063
|
value: modelPickerSearchValue
|
|
11734
12064
|
}];
|
|
11735
12065
|
};
|
|
12066
|
+
|
|
11736
12067
|
const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPickerSearchValue) => {
|
|
11737
12068
|
const visibleModels = getVisibleModels(models, modelPickerSearchValue);
|
|
11738
12069
|
return [{
|
|
@@ -11787,15 +12118,6 @@ const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, atta
|
|
|
11787
12118
|
}])];
|
|
11788
12119
|
};
|
|
11789
12120
|
|
|
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
12121
|
const getDropOverlayVirtualDom = () => {
|
|
11800
12122
|
return [{
|
|
11801
12123
|
childCount: 1,
|
|
@@ -11810,6 +12132,16 @@ const getDropOverlayVirtualDom = () => {
|
|
|
11810
12132
|
type: Text
|
|
11811
12133
|
}];
|
|
11812
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
|
+
|
|
11813
12145
|
const getChatOverlaysVirtualDom = ({
|
|
11814
12146
|
agentMode,
|
|
11815
12147
|
agentModePickerVisible,
|
|
@@ -12448,14 +12780,16 @@ const getReadFileTarget = rawArguments => {
|
|
|
12448
12780
|
}
|
|
12449
12781
|
const uri = Reflect.get(parsed, 'uri');
|
|
12450
12782
|
const path = Reflect.get(parsed, 'path');
|
|
12783
|
+
const baseUri = Reflect.get(parsed, 'baseUri');
|
|
12451
12784
|
const uriValue = typeof uri === 'string' ? uri : '';
|
|
12452
12785
|
const pathValue = typeof path === 'string' ? path : '';
|
|
12453
|
-
const
|
|
12786
|
+
const baseUriValue = typeof baseUri === 'string' ? baseUri : '';
|
|
12787
|
+
const title = uriValue || pathValue || baseUriValue;
|
|
12454
12788
|
if (!title) {
|
|
12455
12789
|
return undefined;
|
|
12456
12790
|
}
|
|
12457
|
-
//
|
|
12458
|
-
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;
|
|
12459
12793
|
return {
|
|
12460
12794
|
clickableUri,
|
|
12461
12795
|
title
|
|
@@ -12466,11 +12800,12 @@ const getToolCallFileNameDom = (fileName, {
|
|
|
12466
12800
|
clickableProps = {},
|
|
12467
12801
|
title
|
|
12468
12802
|
} = {}) => {
|
|
12803
|
+
const resolvedTitle = title ?? clickableProps['data-uri'];
|
|
12469
12804
|
return [{
|
|
12470
12805
|
childCount: 1,
|
|
12471
12806
|
className: ChatToolCallReadFileLink,
|
|
12472
|
-
...(
|
|
12473
|
-
title
|
|
12807
|
+
...(resolvedTitle === undefined ? {} : {
|
|
12808
|
+
title: resolvedTitle
|
|
12474
12809
|
}),
|
|
12475
12810
|
...clickableProps,
|
|
12476
12811
|
type: Span
|
|
@@ -12496,7 +12831,6 @@ const getToolCallCreateDirectoryVirtualDom = toolCall => {
|
|
|
12496
12831
|
return [{
|
|
12497
12832
|
childCount: statusLabel ? 4 : 3,
|
|
12498
12833
|
className: ChatOrderedListItem,
|
|
12499
|
-
title: target.title,
|
|
12500
12834
|
type: Li
|
|
12501
12835
|
}, {
|
|
12502
12836
|
childCount: 0,
|
|
@@ -12574,7 +12908,7 @@ const getToolCallLabel = toolCall => {
|
|
|
12574
12908
|
if (toolCall.name === 'write_file' && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
12575
12909
|
return `${displayName} (in progress)`;
|
|
12576
12910
|
}
|
|
12577
|
-
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)) {
|
|
12578
12912
|
return displayName;
|
|
12579
12913
|
}
|
|
12580
12914
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
@@ -12620,7 +12954,6 @@ const getToolCallEditFileVirtualDom = toolCall => {
|
|
|
12620
12954
|
return [{
|
|
12621
12955
|
childCount: 3,
|
|
12622
12956
|
className: ChatOrderedListItem,
|
|
12623
|
-
title: target.title,
|
|
12624
12957
|
type: Li
|
|
12625
12958
|
}, {
|
|
12626
12959
|
childCount: 0,
|
|
@@ -12649,7 +12982,6 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12649
12982
|
return [{
|
|
12650
12983
|
childCount: statusLabel ? 4 : 3,
|
|
12651
12984
|
className: ChatOrderedListItem,
|
|
12652
|
-
title: toolCall.result,
|
|
12653
12985
|
type: Li
|
|
12654
12986
|
}, {
|
|
12655
12987
|
childCount: 0,
|
|
@@ -12664,6 +12996,21 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
|
12664
12996
|
}), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12665
12997
|
};
|
|
12666
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
|
+
};
|
|
12667
13014
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
12668
13015
|
const target = getReadFileTarget(toolCall.arguments);
|
|
12669
13016
|
if (!target) {
|
|
@@ -12672,14 +13019,16 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12672
13019
|
const fileName = getFileNameFromUri(target.title);
|
|
12673
13020
|
const toolNameLabel = `${toolCall.name} `;
|
|
12674
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'}` : '';
|
|
12675
13025
|
const fileNameClickableProps = target.clickableUri ? {
|
|
12676
13026
|
'data-uri': target.clickableUri,
|
|
12677
13027
|
onClick: HandleClickFileName
|
|
12678
13028
|
} : {};
|
|
12679
13029
|
return [{
|
|
12680
|
-
childCount: statusLabel ?
|
|
13030
|
+
childCount: 3 + (globPatternLabel ? 1 : 0) + (globMatchLabel ? 1 : 0) + (statusLabel ? 1 : 0),
|
|
12681
13031
|
className: ChatOrderedListItem,
|
|
12682
|
-
title: target.title,
|
|
12683
13032
|
type: Li
|
|
12684
13033
|
}, {
|
|
12685
13034
|
childCount: 0,
|
|
@@ -12690,8 +13039,9 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
12690
13039
|
className: ToolCallName,
|
|
12691
13040
|
type: Span
|
|
12692
13041
|
}, text(toolNameLabel), ...getToolCallFileNameDom(fileName, {
|
|
12693
|
-
clickableProps: fileNameClickableProps
|
|
12694
|
-
|
|
13042
|
+
clickableProps: fileNameClickableProps,
|
|
13043
|
+
title: target.title
|
|
13044
|
+
}), ...(globPatternLabel ? [text(globPatternLabel)] : []), ...(globMatchLabel ? [text(globMatchLabel)] : []), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12695
13045
|
};
|
|
12696
13046
|
|
|
12697
13047
|
const maxHtmlLength = 40_000;
|
|
@@ -13058,7 +13408,6 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
13058
13408
|
return [{
|
|
13059
13409
|
childCount: showDiffStats ? statusLabel ? 6 : 5 : statusLabel ? 4 : 3,
|
|
13060
13410
|
className: ChatOrderedListItem,
|
|
13061
|
-
title: target.title,
|
|
13062
13411
|
type: Li
|
|
13063
13412
|
}, {
|
|
13064
13413
|
childCount: 0,
|
|
@@ -13088,7 +13437,7 @@ const getToolCallDom = toolCall => {
|
|
|
13088
13437
|
return virtualDom;
|
|
13089
13438
|
}
|
|
13090
13439
|
}
|
|
13091
|
-
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') {
|
|
13092
13441
|
const virtualDom = getToolCallReadFileVirtualDom(toolCall);
|
|
13093
13442
|
if (virtualDom.length > 0) {
|
|
13094
13443
|
return virtualDom;
|
|
@@ -13578,12 +13927,21 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13578
13927
|
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13579
13928
|
const chatRootChildCount = 2 + (hasVisibleOverlays ? 1 : 0);
|
|
13580
13929
|
return [{
|
|
13581
|
-
childCount: chatRootChildCount,
|
|
13930
|
+
childCount: chatRootChildCount + 1,
|
|
13582
13931
|
className: mergeClassNames(Viewlet, Chat, ChatFocus),
|
|
13583
13932
|
onDragEnter: HandleDragEnterChatView,
|
|
13584
13933
|
onDragOver: HandleDragOverChatView,
|
|
13934
|
+
onPointerMove: HandlePointerMoveProjectSidebarSash,
|
|
13935
|
+
onPointerUp: HandlePointerUpProjectSidebarSash,
|
|
13585
13936
|
type: Div
|
|
13586
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
|
+
}, {
|
|
13587
13945
|
childCount: 3,
|
|
13588
13946
|
className: ChatFocusMainArea,
|
|
13589
13947
|
type: Div
|
|
@@ -13621,25 +13979,6 @@ const getBackButtonVirtualDom = () => {
|
|
|
13621
13979
|
}, arrowLeft];
|
|
13622
13980
|
};
|
|
13623
13981
|
|
|
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
13982
|
const getChatHeaderActionsDom = (viewMode, searchEnabled = false) => {
|
|
13644
13983
|
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
13645
13984
|
const items = [{
|
|
@@ -13814,6 +14153,7 @@ const getChatSearchDom = (hasSearchField, searchValue) => {
|
|
|
13814
14153
|
value: searchValue
|
|
13815
14154
|
}];
|
|
13816
14155
|
};
|
|
14156
|
+
|
|
13817
14157
|
const getChatHeaderListModeDom = (authEnabled = false, userState = 'loggedOut', userName = '', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
|
|
13818
14158
|
const hasAuthError = authEnabled && !!authErrorMessage;
|
|
13819
14159
|
const hasSearchField = searchEnabled && searchFieldVisible;
|
|
@@ -14714,6 +15054,17 @@ const renderEventListeners = () => {
|
|
|
14714
15054
|
name: HandlePointerDownModelPickerList,
|
|
14715
15055
|
params: ['handlePointerDownModelPickerList'],
|
|
14716
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
|
|
14717
15068
|
}, {
|
|
14718
15069
|
name: HandlePointerUpModelPickerList,
|
|
14719
15070
|
params: ['handlePointerUpModelPickerList', ClientY],
|
|
@@ -14827,6 +15178,7 @@ const saveState = state => {
|
|
|
14827
15178
|
projectExpandedIds,
|
|
14828
15179
|
projectListScrollTop,
|
|
14829
15180
|
projects,
|
|
15181
|
+
projectSidebarWidth,
|
|
14830
15182
|
reasoningEffort,
|
|
14831
15183
|
renamingSessionId,
|
|
14832
15184
|
searchFieldVisible,
|
|
@@ -14849,6 +15201,7 @@ const saveState = state => {
|
|
|
14849
15201
|
projectExpandedIds,
|
|
14850
15202
|
projectListScrollTop,
|
|
14851
15203
|
projects,
|
|
15204
|
+
projectSidebarWidth,
|
|
14852
15205
|
reasoningEffort,
|
|
14853
15206
|
renamingSessionId,
|
|
14854
15207
|
searchFieldVisible,
|
|
@@ -15119,7 +15472,10 @@ const commandMap = {
|
|
|
15119
15472
|
'Chat.handleMouseOut': wrapCommand(handleMouseOut),
|
|
15120
15473
|
'Chat.handleMouseOver': wrapCommand(handleMouseOver),
|
|
15121
15474
|
'Chat.handlePointerDownModelPickerList': wrapCommand(handlePointerDownModelPickerList),
|
|
15475
|
+
'Chat.handlePointerDownProjectSidebarSash': wrapCommand(handlePointerDownProjectSidebarSash),
|
|
15476
|
+
'Chat.handlePointerMoveProjectSidebarSash': wrapCommand(handlePointerMoveProjectSidebarSash),
|
|
15122
15477
|
'Chat.handlePointerUpModelPickerList': wrapCommand(handlePointerUpModelPickerList),
|
|
15478
|
+
'Chat.handlePointerUpProjectSidebarSash': wrapCommand(handlePointerUpProjectSidebarSash),
|
|
15123
15479
|
'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
|
|
15124
15480
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
15125
15481
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|