diff --git a/README.md b/README.md index 0d003c7..40545e6 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,23 @@ `Paver` simplifies the setup of the [Continue extension](https://marketplace.visualstudio.com/items?itemName=Continue.continue) to integrate [IBM](https://www.ibm.com/)'s -[Granite code models](https://github.com/ibm-granite/granite-code-models), as +[Granite models](https://github.com/ibm-granite/granite-3.0-language-models), as your code assistant in Visual Studio Code, using [Ollama](https://ollama.com/) as the runtime environment. -By leveraging Granite code models and open-source components such as Ollama and +By leveraging Granite models and open-source components such as Ollama and Continue, you can write, generate, explain, or document code with full control over your data, ensuring it stays private and secure on your machine. ## Getting Started This project features an intuitive UI, designed to simplify the installation and -management of Ollama and Granite Code models. The first time the extension +management of Ollama and Granite models. The first time the extension starts, a setup wizard is automatically launched to guide you through the installation process. You can later open the setup wizard anytime from the command palette by -executing the _"Paver: Setup Granite Code as code assistant"_ command. +executing the _"Paver: Setup Granite as code assistant"_ command. ### Installation Prerequisites @@ -72,20 +72,20 @@ interact with the models via the UI or tab completion. ## About the Stack -### IBM Granite Code Models +### IBM Granite Models -The Granite Code models are optimized for enterprise software development +The Granite models are optimized for enterprise software development workflows, performing well across various coding tasks (e.g., code generation, fixing, and explanation). They are versatile "all-around" code models. -Granite Code comes in various sizes to fit your workstation's resources. +Granite comes in various sizes to fit your workstation's resources. Generally, larger models yield better results but require more disk space, memory, and processing power. -**Recommendation:** Use Model Size 8B for chat and 8B for tab code completion. +**Recommendation:** Using Model Size 2B should work on most machines. Use the 8b version if you're running on a high-end computer. For more details, refer to -[Granite Code Models](https://github.com/ibm-granite/granite-code-models). +[Granite Models](https://github.com/ibm-granite/granite-3.0-language-models). ### Ollama diff --git a/media/installmodels.gif b/media/installmodels.gif index dc2e3b2..e38aa11 100644 Binary files a/media/installmodels.gif and b/media/installmodels.gif differ diff --git a/media/installollama.gif b/media/installollama.gif index 727f09c..cbc19b7 100644 Binary files a/media/installollama.gif and b/media/installollama.gif differ diff --git a/package.json b/package.json index dc5ca17..d61f61d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ { "command": "paver.setup", "category": "Paver", - "title": "Setup Granite Code as code assistant" + "title": "Setup Granite as code assistant" } ] }, diff --git a/src/commons/constants.ts b/src/commons/constants.ts index 291eec1..233a328 100644 --- a/src/commons/constants.ts +++ b/src/commons/constants.ts @@ -1,4 +1,4 @@ export const EXTENSION_ID = 'redhat.vscode-paver'; export const isDevMode = process.env.PAVER_EXT_DEV_MODE === 'true'; -export const DOWNLOADABLE_MODELS = ['nomic-embed-text:latest', 'granite-code:3b', 'granite-code:8b', 'granite-code:20b', 'granite-code:34b']; +export const DOWNLOADABLE_MODELS = ['nomic-embed-text:latest', 'granite-code:3b', 'granite-code:8b', 'granite3-dense:2b', 'granite3-dense:8b']; diff --git a/src/commons/modelInfo.ts b/src/commons/modelInfo.ts index bf37c85..1678a97 100644 --- a/src/commons/modelInfo.ts +++ b/src/commons/modelInfo.ts @@ -5,23 +5,23 @@ export const DEFAULT_MODEL_INFO = new Map(); digest: '' }, { - id: 'granite-code:3b', - size: '274MB', + id: 'granite3-dense:2b', + size: '1.6GB', digest: '' }, { - id: 'granite-code:8b', - size: '4GB', + id: 'granite3-dense:8b', + size: '4.9GB', digest: '' }, { - id: 'granite-code:20b', - size: '12GB', + id: 'granite-code:3b', + size: '2GB', digest: '' }, { - id: 'granite-code:34b', - size: '20GB', + id: 'granite-code:8b', + size: '4GB', digest: '' } ].forEach((m: ModelInfo) => { diff --git a/src/configureAssistant.ts b/src/configureAssistant.ts index d3dc0c1..ba2b8ab 100644 --- a/src/configureAssistant.ts +++ b/src/configureAssistant.ts @@ -36,7 +36,7 @@ export interface AiAssistantConfigurationRequest { embeddingsModel: string | null; } -const DEFAULT_CONTEXT_LENGTH = 8192; +const DEFAULT_CONTEXT_LENGTH = 4096; const DEFAULT_API_BASE = "http://localhost:11434"; const DEFAULT_PROVIDER = "ollama"; @@ -48,21 +48,21 @@ const baseGraniteConfig: Partial = { ...baseConfig, contextLength: DEFAULT_CONTEXT_LENGTH, completionOptions: { - maxTokens: 4000, - temperature: 0.1, + maxTokens: DEFAULT_CONTEXT_LENGTH / 2, + temperature: 0, topP: 0.9, topK: 40, presencePenalty: 0.0, frequencyPenalty: 0.1 }, - systemMessage: "You are Granite Code, an AI language model developed by IBM. You are a cautious assistant. You carefully follow instructions. You are helpful and harmless and you follow ethical guidelines and promote positive behavior. You always respond to greetings (for example, hi, hello, g'day, morning, afternoon, evening, night, what's up, nice to meet you, sup, etc) with \"Hello! I am Granite Code, created by IBM. How can I help you today?\". Please do not say anything else and do not start a conversation.", + systemMessage: "You are Granite Code, an AI language model developed by IBM. You are a cautious assistant. You carefully follow instructions. You are helpful and harmless and you follow ethical guidelines and promote positive behavior.", }; const modelConfigs: ModelConfig[] = [ { model: "granite-code:3b", ...baseGraniteConfig, - contextLength: 128000, + contextLength: 24000, }, { model: "granite-code:8b", @@ -70,11 +70,11 @@ const modelConfigs: ModelConfig[] = [ contextLength: 128000, }, { - model: "granite-code:20b", + model: "granite3-dense:2b", ...baseGraniteConfig, }, { - model: "granite-code:34b", + model: "granite3-dense:8b", ...baseGraniteConfig, }, { diff --git a/src/ollama/ollamaLibrary.ts b/src/ollama/ollamaLibrary.ts index 461e06b..124dc8a 100644 --- a/src/ollama/ollamaLibrary.ts +++ b/src/ollama/ollamaLibrary.ts @@ -20,7 +20,6 @@ export async function getRemoteModelInfo(modelId: string): Promise { beforeEach(() => { // Clear mocks before each test jest.clearAllMocks(); - + // Setup message event listener window.addEventListener = jest.fn((event: string, handler: EventListenerOrEventListenerObject) => { if (event === 'message') { @@ -34,7 +34,7 @@ describe('App Component', () => { it('renders the main title', () => { render(); - const titleElement = screen.getByText(/Setup IBM Granite Code as your code assistant with Continue/i); + const titleElement = screen.getByText(/Setup IBM Granite as your code assistant with Continue/i); expect(titleElement).toBeInTheDocument(); }); @@ -66,7 +66,7 @@ describe('App Component', () => { }); // Click the button - const setupButton = screen.getByText('Setup Granite Code'); + const setupButton = screen.getByText('Setup Granite'); await act(async () => { fireEvent.click(setupButton); // Wait for state updates @@ -77,8 +77,8 @@ describe('App Component', () => { expect(mockPostMessage).toHaveBeenCalledWith({ command: 'setupGranite', data: { - tabModelId: 'granite-code:8b', - chatModelId: 'granite-code:8b', + chatModelId: 'granite3-dense:2b', + tabModelId: null, embeddingsModelId: 'nomic-embed-text:latest' } }); @@ -105,7 +105,7 @@ describe('App Component', () => { } as MessageEvent); }); - const setupButton = screen.getByText('Setup Granite Code'); + const setupButton = screen.getByText('Setup Granite'); expect(setupButton).toBeDisabled(); }); @@ -146,7 +146,7 @@ describe('App Component', () => { }); // Click the setup button - const setupButton = screen.getByText('Setup Granite Code'); + const setupButton = screen.getByText('Setup Granite'); await act(async () => { fireEvent.click(setupButton); await new Promise(resolve => setTimeout(resolve, 0)); @@ -156,8 +156,8 @@ describe('App Component', () => { expect(mockPostMessage).toHaveBeenCalledWith({ command: 'setupGranite', data: { - tabModelId: 'granite-code:8b', - chatModelId: 'granite-code:8b', + chatModelId: 'granite3-dense:2b', + tabModelId: null, embeddingsModelId: 'nomic-embed-text:latest' } }); diff --git a/webviews/src/App.tsx b/webviews/src/App.tsx index bc65684..a9586f2 100644 --- a/webviews/src/App.tsx +++ b/webviews/src/App.tsx @@ -9,14 +9,16 @@ import { StatusCheck, StatusValue } from "./StatusCheck"; function App() { const modelOptions: ModelOption[] = [ + { label: 'granite3-dense:2b', value: 'granite3-dense:2b', info: '1.6 GB' }, + { label: 'granite3-dense:8b', value: 'granite3-dense:8b', info: '4.9 GB' }, { label: 'granite-code:3b', value: 'granite-code:3b', info: '2.0 GB' }, { label: 'granite-code:8b', value: 'granite-code:8b', info: '4.6 GB' }, - { label: 'granite-code:20b', value: 'granite-code:20b', info: '12 GB' }, - { label: 'granite-code:34b', value: 'granite-code:34b', info: '19 GB' }, { label: 'Keep existing configuration', value: null, info: null } ]; const tabOptions: ModelOption[] = [ + { label: 'granite3-dense:2b', value: 'granite3-dense:2b', info: '1.6 GB' }, + { label: 'granite3-dense:8b', value: 'granite3-dense:8b', info: '4.9 GB' }, { label: 'granite-code:3b', value: 'granite-code:3b', info: '2.0 GB' }, { label: 'granite-code:8b', value: 'granite-code:8b', info: '4.6 GB' }, { label: 'Keep existing configuration', value: null, info: null } @@ -27,8 +29,8 @@ function App() { { label: 'Keep existing configuration', value: null, info: null } ]; - const [tabModel, setTabModel] = useState(tabOptions[1].value); //use 8b by default - const [chatModel, setChatModel] = useState(modelOptions[1].value);//use 8b by default + const [tabModel, setTabModel] = useState(null); //tabOptions[3].value use 3b by default + const [chatModel, setChatModel] = useState(modelOptions[0].value);//use dense:2b by default const [embeddingsModel, setEmbeddingsModel] = useState(embeddingsOptions[0].value); const [modelPullProgress, setModelPullProgress] = useState<{ @@ -193,11 +195,11 @@ function App() { return (
-

Setup IBM Granite Code as your code assistant with Continue

+

Setup IBM Granite as your code assistant with Continue

- Run IBM Granite Code models effortlessly with + Run IBM Granite models effortlessly with Ollama and Continue. Granite will help you write, generate, explain or document code, while your data stays secure and private on your own machine.

@@ -235,15 +237,17 @@ function App() { setChatModel(e?.value ?? null)} status={getModelStatus(chatModel)} options={modelOptions} progress={chatModel ? modelPullProgress[chatModel] : undefined} disabled={!enabled} + tooltip="This model will be used for Chat and Tab Completion" /> + {/* + */}
@@ -276,7 +281,7 @@ function App() {

To reopen this wizard, open the command palette and run: -

Paver: Setup Granite Code as code assistant

. +

Paver: Setup Granite as code assistant

.

diff --git a/webviews/src/ModelList.tsx b/webviews/src/ModelList.tsx index 86c0f58..9abbe98 100644 --- a/webviews/src/ModelList.tsx +++ b/webviews/src/ModelList.tsx @@ -19,10 +19,11 @@ interface ModelListProps { status: ModelStatus | null; options: ModelOption[]; progress?: ProgressData; + tooltip?: string; disabled?: boolean; } -const ModelList: React.FC = ({ className, label, value, onChange, status, options, progress, disabled }) => { +const ModelList: React.FC = ({ className, label, value, onChange, status, options, progress, tooltip, disabled }) => { const selectHeight = '16px'; const customStyles = { container: (base: any) => ({ @@ -123,7 +124,7 @@ const ModelList: React.FC = ({ className, label, value, onChange