mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
feat: add active file context to chat requests
- Include user's current active file path in chat requests - Move conversation save after attachments are added - Extract formattedRequest in suggest handler - Add WorkSpaceService.getActiveFile() method - Remove premature chatArea layout update - Update unit tests
This commit is contained in:
parent
ea9cd211fc
commit
8efbfef63e
8 changed files with 170 additions and 36 deletions
|
|
@ -94,8 +94,8 @@
|
|||
if (userRequest.trim() === "" || !diffOpen) {
|
||||
return;
|
||||
}
|
||||
const suggestion = requestFromInput().formattedRequest;
|
||||
diffService.onSuggest(suggestion);
|
||||
const suggestion = requestFromInput();
|
||||
diffService.onSuggest(suggestion.formattedRequest);
|
||||
}
|
||||
|
||||
function requestFromInput() {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@
|
|||
|
||||
await chatService.submit(conversation, editModeActive, currentRequest, formattedRequest, attachments, {
|
||||
onSubmit: () => {
|
||||
chatArea.updateChatAreaLayout("smooth");
|
||||
isSubmitting = true;
|
||||
attachments = [];
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { Exception } from "Helpers/Exception";
|
|||
import { Copy } from "Enums/Copy";
|
||||
import type { Attachment } from "Conversations/Attachment";
|
||||
import { Reference } from "Conversations/Reference";
|
||||
import type { WorkSpaceService } from "./WorkSpaceService";
|
||||
|
||||
export interface IChatServiceCallbacks {
|
||||
onSubmit: () => void;
|
||||
|
|
@ -31,6 +32,7 @@ export class ChatService {
|
|||
private conversationService: ConversationFileSystemService;
|
||||
private aiFunctionService: AIFunctionService;
|
||||
private namingService: ConversationNamingService;
|
||||
private workSpaceService: WorkSpaceService;
|
||||
private eventService: EventService;
|
||||
private abortService: AbortService;
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ export class ChatService {
|
|||
this.conversationService = Resolve<ConversationFileSystemService>(Services.ConversationFileSystemService);
|
||||
this.aiFunctionService = Resolve<AIFunctionService>(Services.AIFunctionService);
|
||||
this.namingService = Resolve<ConversationNamingService>(Services.ConversationNamingService);
|
||||
this.workSpaceService = Resolve<WorkSpaceService>(Services.WorkSpaceService);
|
||||
this.eventService = Resolve<EventService>(Services.EventService);
|
||||
this.abortService = Resolve<AbortService>(Services.AbortService);
|
||||
this.semaphore = new Semaphore(1, false);
|
||||
|
|
@ -71,11 +74,10 @@ export class ChatService {
|
|||
|
||||
const conversationContent = new ConversationContent({
|
||||
role: Role.User,
|
||||
content: formattedRequest,
|
||||
content: this.requestWithContext(formattedRequest),
|
||||
displayContent: userRequest
|
||||
});
|
||||
conversation.contents.push(conversationContent);
|
||||
await this.saveConversation(conversation);
|
||||
|
||||
if (attachments.length > 0) {
|
||||
// Add any attachments that came from paste / drop
|
||||
|
|
@ -88,6 +90,7 @@ export class ChatService {
|
|||
conversationContent.references = attachments.map(attachment =>
|
||||
new Reference(attachment.fileName, attachment.approximateFileSizeMB()));
|
||||
}
|
||||
await this.saveConversation(conversation);
|
||||
|
||||
callbacks.onSubmit();
|
||||
callbacks.onStreamingUpdate(null);
|
||||
|
|
@ -282,4 +285,9 @@ export class ChatService {
|
|||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
private requestWithContext(request: string) {
|
||||
const activeFile = this.workSpaceService.getActiveFile();
|
||||
return activeFile ? `${request}\nUser current active file: "${activeFile.path}"` : request;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,8 @@ export class WorkSpaceService {
|
|||
await leaf.openFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
public getActiveFile(): TFile | null {
|
||||
return this.plugin.app.workspace.getActiveFile();
|
||||
}
|
||||
}
|
||||
|
|
@ -737,7 +737,7 @@ describe('Claude', () => {
|
|||
expect(result[0].content.length).toBeGreaterThan(1);
|
||||
|
||||
// Should have filename text block from formatBinaryFiles
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'test-image.png');
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'Binary data for test-image.png follows in next message');
|
||||
expect(filenameBlock).toBeDefined();
|
||||
|
||||
// Should have image content blocks from formatBinaryFiles
|
||||
|
|
@ -769,7 +769,7 @@ describe('Claude', () => {
|
|||
expect(result[0].content.length).toBeGreaterThan(1);
|
||||
|
||||
// Should have filename text block from formatBinaryFiles
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'document.pdf');
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'Binary data for document.pdf follows in next message');
|
||||
expect(filenameBlock).toBeDefined();
|
||||
|
||||
// Should have document content blocks from formatBinaryFiles
|
||||
|
|
@ -903,7 +903,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'report.pdf'
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document',
|
||||
|
|
@ -930,7 +930,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'photo.jpg'
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'image',
|
||||
|
|
@ -1064,7 +1064,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(6);
|
||||
|
||||
// PDF file
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: 'doc.pdf' });
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document',
|
||||
source: {
|
||||
|
|
@ -1074,7 +1074,7 @@ describe('Claude', () => {
|
|||
});
|
||||
|
||||
// JPEG image
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: 'image.jpg' });
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: 'Binary data for image.jpg follows in next message' });
|
||||
expect(parsed[3]).toEqual({
|
||||
type: 'image',
|
||||
source: {
|
||||
|
|
@ -1084,7 +1084,7 @@ describe('Claude', () => {
|
|||
});
|
||||
|
||||
// PNG image
|
||||
expect(parsed[4]).toEqual({ type: 'text', text: 'screenshot.png' });
|
||||
expect(parsed[4]).toEqual({ type: 'text', text: 'Binary data for screenshot.png follows in next message' });
|
||||
expect(parsed[5]).toEqual({
|
||||
type: 'image',
|
||||
source: {
|
||||
|
|
@ -1128,14 +1128,14 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(5);
|
||||
|
||||
expect(parsed[0].type).toBe('text');
|
||||
expect(parsed[0].text).toBe('good.jpg');
|
||||
expect(parsed[0].text).toBe('Binary data for good.jpg follows in next message');
|
||||
expect(parsed[1].type).toBe('image');
|
||||
expect(parsed[2]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Unsupported mime type \'image/bmp\': bad.bmp'
|
||||
});
|
||||
expect(parsed[3].type).toBe('text');
|
||||
expect(parsed[3].text).toBe('doc.pdf');
|
||||
expect(parsed[3].text).toBe('Binary data for doc.pdf follows in next message');
|
||||
expect(parsed[4].type).toBe('document');
|
||||
});
|
||||
|
||||
|
|
@ -1180,9 +1180,9 @@ describe('Claude', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(4);
|
||||
expect(parsed[0].text).toBe('document.PDF');
|
||||
expect(parsed[0].text).toBe('Binary data for document.PDF follows in next message');
|
||||
expect(parsed[1].type).toBe('document');
|
||||
expect(parsed[2].text).toBe('photo.JPG');
|
||||
expect(parsed[2].text).toBe('Binary data for photo.JPG follows in next message');
|
||||
expect(parsed[3].type).toBe('image');
|
||||
});
|
||||
|
||||
|
|
@ -1208,7 +1208,7 @@ describe('Claude', () => {
|
|||
const result = claude.formatBinaryFiles([attachment as any]);
|
||||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed[0].text).toBe('report (final) v2.pdf');
|
||||
expect(parsed[0].text).toBe('Binary data for report (final) v2.pdf follows in next message');
|
||||
});
|
||||
|
||||
it('should handle JPEG files with .jpeg extension', () => {
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,7 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
text: 'report.pdf'
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
|
|
@ -1114,7 +1114,7 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
text: 'photo.jpg'
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
|
|
@ -1218,7 +1218,7 @@ describe('Gemini', () => {
|
|||
expect(parsed).toHaveLength(6);
|
||||
|
||||
// PDF file
|
||||
expect(parsed[0]).toEqual({ text: 'doc.pdf' });
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'application/pdf',
|
||||
|
|
@ -1227,7 +1227,7 @@ describe('Gemini', () => {
|
|||
});
|
||||
|
||||
// JPEG image
|
||||
expect(parsed[2]).toEqual({ text: 'image.jpg' });
|
||||
expect(parsed[2]).toEqual({ text: 'Binary data for image.jpg follows in next message' });
|
||||
expect(parsed[3]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'image/jpeg',
|
||||
|
|
@ -1236,7 +1236,7 @@ describe('Gemini', () => {
|
|||
});
|
||||
|
||||
// PNG image
|
||||
expect(parsed[4]).toEqual({ text: 'screenshot.png' });
|
||||
expect(parsed[4]).toEqual({ text: 'Binary data for screenshot.png follows in next message' });
|
||||
expect(parsed[5]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'image/png',
|
||||
|
|
@ -1278,12 +1278,12 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(5);
|
||||
|
||||
expect(parsed[0]).toEqual({ text: 'good.jpg' });
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for good.jpg follows in next message' });
|
||||
expect(parsed[1]).toHaveProperty('fileData');
|
||||
expect(parsed[2]).toEqual({
|
||||
text: 'Unsupported mime type \'image/bmp\': bad.bmp'
|
||||
});
|
||||
expect(parsed[3]).toEqual({ text: 'doc.pdf' });
|
||||
expect(parsed[3]).toEqual({ text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[4]).toHaveProperty('fileData');
|
||||
});
|
||||
|
||||
|
|
@ -1311,7 +1311,7 @@ describe('Gemini', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(2); // Only successful upload
|
||||
expect(parsed[0]).toEqual({ text: 'success.pdf' });
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for success.pdf follows in next message' });
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'application/pdf',
|
||||
|
|
@ -1340,7 +1340,7 @@ describe('Gemini', () => {
|
|||
const result = gemini.formatBinaryFiles([attachment as any]);
|
||||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed[0].text).toBe('report (final) v2.pdf');
|
||||
expect(parsed[0].text).toBe('Binary data for report (final) v2.pdf follows in next message');
|
||||
});
|
||||
|
||||
it('should handle JPEG files with .jpeg extension', () => {
|
||||
|
|
|
|||
|
|
@ -975,8 +975,12 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].role).toBe('user');
|
||||
expect(parsed[0].content).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
file_id: 'file-123'
|
||||
});
|
||||
|
|
@ -997,8 +1001,12 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].role).toBe('user');
|
||||
expect(parsed[0].content).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
file_id: 'file-456'
|
||||
});
|
||||
|
|
@ -1018,7 +1026,12 @@ describe('OpenAI', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for diagram.png follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
file_id: 'file-789'
|
||||
});
|
||||
|
|
@ -1038,7 +1051,12 @@ describe('OpenAI', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for modern.webp follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
file_id: 'file-webp'
|
||||
});
|
||||
|
|
@ -1116,19 +1134,31 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].role).toBe('user');
|
||||
expect(parsed[0].content).toHaveLength(3);
|
||||
expect(parsed[0].content).toHaveLength(6);
|
||||
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for doc.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
file_id: 'file-pdf'
|
||||
});
|
||||
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
expect(parsed[0].content[2]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for image.jpg follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[3]).toEqual({
|
||||
type: 'input_image',
|
||||
file_id: 'file-jpg'
|
||||
});
|
||||
|
||||
expect(parsed[0].content[2]).toEqual({
|
||||
expect(parsed[0].content[4]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for screenshot.png follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[5]).toEqual({
|
||||
type: 'input_image',
|
||||
file_id: 'file-png'
|
||||
});
|
||||
|
|
@ -1166,14 +1196,22 @@ describe('OpenAI', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(3);
|
||||
expect(parsed[0].content).toHaveLength(5);
|
||||
|
||||
expect(parsed[0].content[0].type).toBe('input_image');
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for good.jpg follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1].type).toBe('input_image');
|
||||
expect(parsed[0].content[2]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Unsupported mime type \'image/bmp\': bad.bmp'
|
||||
});
|
||||
expect(parsed[0].content[2].type).toBe('input_file');
|
||||
expect(parsed[0].content[3]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for doc.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[4].type).toBe('input_file');
|
||||
});
|
||||
|
||||
it('should handle mixed successful and failed uploads', () => {
|
||||
|
|
@ -1200,8 +1238,12 @@ describe('OpenAI', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(1);
|
||||
expect(parsed[0].content).toHaveLength(1); // Only successful upload
|
||||
expect(parsed[0].content).toHaveLength(2); // Text + file reference
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for success.pdf follows in next message'
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
file_id: 'file-success'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ describe('ChatService - Integration Tests (Sync Methods Only)', () => {
|
|||
let mockPrompt: any;
|
||||
let mockStatusBarService: any;
|
||||
let mockEventService: any;
|
||||
let mockWorkSpaceService: any;
|
||||
let abortService: AbortService;
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -59,6 +60,12 @@ describe('ChatService - Integration Tests (Sync Methods Only)', () => {
|
|||
off: vi.fn()
|
||||
};
|
||||
|
||||
// Mock WorkSpaceService
|
||||
mockWorkSpaceService = {
|
||||
openNote: vi.fn(),
|
||||
getActiveFile: vi.fn().mockReturnValue(null)
|
||||
};
|
||||
|
||||
// Create real AbortService instance
|
||||
abortService = new AbortService();
|
||||
|
||||
|
|
@ -68,6 +75,7 @@ describe('ChatService - Integration Tests (Sync Methods Only)', () => {
|
|||
RegisterSingleton(Services.ConversationNamingService, mockNamingService);
|
||||
RegisterSingleton(Services.IPrompt, mockPrompt);
|
||||
RegisterSingleton(Services.EventService, mockEventService);
|
||||
RegisterSingleton(Services.WorkSpaceService, mockWorkSpaceService);
|
||||
RegisterSingleton(Services.AbortService, abortService);
|
||||
|
||||
// Create service
|
||||
|
|
@ -542,4 +550,77 @@ describe('ChatService - Integration Tests (Sync Methods Only)', () => {
|
|||
expect(() => fromString('')).toThrow('Unknown function name: ');
|
||||
});
|
||||
});
|
||||
|
||||
describe('requestWithContext (private method tests via reflection)', () => {
|
||||
// Access private method for testing
|
||||
const getRequestWithContextMethod = (service: ChatService) => {
|
||||
return (service as any).requestWithContext.bind(service);
|
||||
};
|
||||
|
||||
it('should return request unchanged when no active file exists', () => {
|
||||
mockWorkSpaceService.getActiveFile.mockReturnValue(null);
|
||||
const requestWithContext = getRequestWithContextMethod(service);
|
||||
const request = 'Please help me with this task';
|
||||
|
||||
const result = requestWithContext(request);
|
||||
|
||||
expect(result).toBe(request);
|
||||
expect(mockWorkSpaceService.getActiveFile).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should append active file path when active file exists', () => {
|
||||
const mockFile = {
|
||||
path: 'notes/my-note.md',
|
||||
name: 'my-note.md',
|
||||
basename: 'my-note'
|
||||
};
|
||||
mockWorkSpaceService.getActiveFile.mockReturnValue(mockFile);
|
||||
const requestWithContext = getRequestWithContextMethod(service);
|
||||
const request = 'Please help me with this task';
|
||||
|
||||
const result = requestWithContext(request);
|
||||
|
||||
expect(result).toBe('Please help me with this task\nUser current active file: "notes/my-note.md"');
|
||||
expect(mockWorkSpaceService.getActiveFile).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle empty request with active file', () => {
|
||||
const mockFile = {
|
||||
path: 'test.md'
|
||||
};
|
||||
mockWorkSpaceService.getActiveFile.mockReturnValue(mockFile);
|
||||
const requestWithContext = getRequestWithContextMethod(service);
|
||||
const request = '';
|
||||
|
||||
const result = requestWithContext(request);
|
||||
|
||||
expect(result).toBe('\nUser current active file: "test.md"');
|
||||
});
|
||||
|
||||
it('should handle request with special characters in file path', () => {
|
||||
const mockFile = {
|
||||
path: 'folder/my file (v2).md'
|
||||
};
|
||||
mockWorkSpaceService.getActiveFile.mockReturnValue(mockFile);
|
||||
const requestWithContext = getRequestWithContextMethod(service);
|
||||
const request = 'Update this file';
|
||||
|
||||
const result = requestWithContext(request);
|
||||
|
||||
expect(result).toBe('Update this file\nUser current active file: "folder/my file (v2).md"');
|
||||
});
|
||||
|
||||
it('should handle multiline requests with active file', () => {
|
||||
const mockFile = {
|
||||
path: 'docs/readme.md'
|
||||
};
|
||||
mockWorkSpaceService.getActiveFile.mockReturnValue(mockFile);
|
||||
const requestWithContext = getRequestWithContextMethod(service);
|
||||
const request = 'Please help me:\n1. First task\n2. Second task';
|
||||
|
||||
const result = requestWithContext(request);
|
||||
|
||||
expect(result).toBe('Please help me:\n1. First task\n2. Second task\nUser current active file: "docs/readme.md"');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue