Skip to content

Commit

Permalink
Add "Start Ollama" button (#158)
Browse files Browse the repository at this point in the history
If Ollama is detected as stopped, a "Start Ollama" button is displayed. When clicked, it'll attempt to start the Ollama service from the terminal:

- on Mac, opens the Ollama.app
- on Windows, runs "ollama app.exe"
- on Linux, runs the start_ollama.sh script, responsible for finding the proper service to start (or falls back to running ollama serve)

Signed-off-by: msivasubramaniaan <[email protected]>
Signed-off-by: Fred Bricon <[email protected]>
Co-authored-by: Fred Bricon <[email protected]>
  • Loading branch information
msivasubramaniaan and fbricon authored Jan 7, 2025
1 parent 887304e commit e5bcacd
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 30 deletions.
40 changes: 35 additions & 5 deletions src/ollama/ollamaServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,36 @@ export class OllamaServer implements IModelServer {
}

async startServer(): Promise<boolean> {
// await terminalCommandRunner.runInTerminal("ollama list", {
// name: "Granite Code Setup",
// show: true,
// });
return true;
let startCommand: string | undefined;
if (isWin()) {
startCommand = [
`$ErrorActionPreference = "Stop"`,
`& "ollama app.exe"`,
].join(' ; ');
} else if (isMac()) {
startCommand = [
'set -e', // Exit immediately if a command exits with a non-zero status
'open -a Ollama.app',
].join(' && ');
} else {//Linux
const start_ollama_sh = path.join(this.context.extensionPath, 'start_ollama.sh');
startCommand = [
'set -e', // Exit immediately if a command exits with a non-zero status
`chmod +x "${start_ollama_sh}"`, // Ensure the script is executable
`"${start_ollama_sh}"`, // Use quotes in case the path contains spaces
].join(' && ');
}
if (startCommand) {
await terminalCommandRunner.runInTerminal(
startCommand,
{
name: "Start Ollama",
show: true,
}
);
return true;
}
return false;
}

async installServer(mode: string): Promise<boolean> {
Expand Down Expand Up @@ -398,6 +423,11 @@ function isLinux(): boolean {
function isWin(): boolean {
return PLATFORM.startsWith("win");
}

function isMac(): boolean {
return PLATFORM === "darwin";
}

function isDevspaces() {
//sudo is not available on Red Hat DevSpaces
return process.env['DEVWORKSPACE_ID'] !== undefined;
Expand Down
3 changes: 3 additions & 0 deletions src/panels/setupGranitePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ export class SetupGranitePage {
},
});
break;
case "startOllama":
await this.server.startServer();
break;
case "installOllama":
await this.server.installServer(data.mode);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/terminal/terminalCommandRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TerminalCommandRunner implements Disposable {
public async runInTerminal(command: string, options: ITerminalOptions): Promise<Terminal> {

let terminal: Terminal | undefined;
const name = "Granite Models Setup";
const name = options.name;
if (window.terminals.length) {
terminal = window.terminals.find(t => name === t.name);
}
Expand Down
60 changes: 36 additions & 24 deletions webviews/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ function App() {
});
}

function handleStartOllama(): void {
vscode.postMessage({
command: "startOllama"
});
}

const REFETCH_MODELS_INTERVAL_MS = 1500;
let ollamaStatusChecker: NodeJS.Timeout | undefined;

Expand Down Expand Up @@ -313,30 +319,36 @@ function App() {
</label>

{/* New section for additional buttons */}
{serverStatus === ServerStatus.missing &&
installationModes.length > 0 && (
<div className="install-options">
{installationModes.some(
(mode) => mode.supportsRefresh === true
) && (
<p>
<span>
This page will refresh once Ollama is installed.
</span>
</p>
)}
{installationModes.map((mode) => (
<button
key={mode.id}
className="install-button"
onClick={() => handleInstallOllama(mode.id)}
disabled={!enabled}
>
{mode.label}
</button>
))}
</div>
)}
{serverStatus === ServerStatus.missing && installationModes.length > 0 && (
<div className="install-options">
{installationModes.some(mode => mode.supportsRefresh === true) && (
<p><span>This page will refresh once Ollama is installed.</span></p>
)}
{installationModes.map((mode) => (
<button
key={mode.id}
className="install-button"
onClick={() => handleInstallOllama(mode.id)}
disabled={!enabled}
>
{mode.label}
</button>
))}
</div>
)}

{
// show start ollama button when server stopped
serverStatus === ServerStatus.stopped && (
<button
className="install-button"
onClick={() => handleStartOllama()}
>
Start Ollama
</button>
)
}

</div>
</div>
{(diskSpaceCheck.warnings.length > 0 || diskSpaceCheck.errors.length > 0) && (
Expand Down

0 comments on commit e5bcacd

Please sign in to comment.