diff --git a/LICENSE b/LICENSE index 72c29b3..0f0a7a6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Bjorn Melin +Copyright (c) 2025 shyamsridhar123 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/jest.config.js b/jest.config.js index d60ed5c..9207c7e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,12 +5,16 @@ export default { extensionsToTreatAsEsm: ['.ts'], moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', + '^node-fetch$': '/src/__mocks__/node-fetch.ts', }, transform: { '^.+\\.tsx?$': [ 'ts-jest', { useESM: true, + diagnostics: { + ignoreCodes: [151002], + }, }, ], }, diff --git a/src/__mocks__/node-fetch.ts b/src/__mocks__/node-fetch.ts new file mode 100644 index 0000000..8d11a53 --- /dev/null +++ b/src/__mocks__/node-fetch.ts @@ -0,0 +1,13 @@ +// Mock implementation of node-fetch for Jest tests +const mockFetch = jest.fn(() => + Promise.resolve({ + ok: true, + status: 200, + statusText: 'OK', + json: jest.fn(() => Promise.resolve({})), + text: jest.fn(() => Promise.resolve('')), + headers: new Map(), + }) +); + +export default mockFetch as unknown as typeof fetch; diff --git a/src/config/index.ts b/src/config/index.ts index ed83b85..cdd09c8 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,7 @@ import dotenv from 'dotenv'; import { z } from 'zod'; -import pkg from '../../package.json' with { type: 'json' }; +// @ts-expect-error - ts-jest doesn't support import attributes yet +import pkg from '../../package.json'; // Load environment variables dotenv.config(); diff --git a/src/services/copilot-service.ts b/src/services/copilot-service.ts index 91693dd..16e3211 100644 --- a/src/services/copilot-service.ts +++ b/src/services/copilot-service.ts @@ -20,32 +20,32 @@ export function convertMessagesToCopilotPrompt(messages: OpenAIMessage[]): strin return ''; } - let systemPrompt = ''; - let userPrompts = ''; - let assistantResponses = ''; + let prompt = ''; - // Process messages in order to construct a coherent prompt + // Process messages in order to maintain conversation flow for (const message of messages) { if (!message.role || !message.content) continue; switch (message.role) { case 'system': - systemPrompt += message.content + '\n\n'; + prompt += message.content + '\n\n'; break; case 'user': - userPrompts += 'User: ' + message.content + '\n\n'; + prompt += 'User: ' + message.content + '\n\n'; break; case 'assistant': - assistantResponses += 'Assistant: ' + message.content + '\n\n'; + prompt += 'Assistant: ' + message.content + '\n\n'; break; } } - // Ensure it ends with a user message to prompt a response + // Ensure it ends with a prompt for the assistant if the last message is from user const lastMessage = messages[messages.length - 1]; - const needsAssistantPrompt = lastMessage.role !== 'user'; + if (lastMessage.role === 'user') { + prompt += 'Assistant: '; + } - return systemPrompt + userPrompts + assistantResponses + (needsAssistantPrompt ? '' : 'Assistant: '); + return prompt; } /** @@ -73,7 +73,7 @@ export function detectLanguageFromMessages(messages: OpenAIMessage[]): string { } // Check for file extensions in the message - const fileExtensionMatch = content.match(/\.([a-zA-Z0-9]+)(?:\s|"|')/); + const fileExtensionMatch = content.match(/\.([a-zA-Z0-9]+)(?:\s|"|'|\?|$)/); if (fileExtensionMatch && fileExtensionMatch[1]) { const ext = fileExtensionMatch[1].toLowerCase(); const extToLang: Record = {