mirror of
https://github.com/ollama/ollama.git
synced 2025-07-12 22:53:02 +02:00
some more menu options...
This commit is contained in:
@ -44,10 +44,12 @@ func run() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var options ServerOptions
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
var done chan int
|
var done chan int
|
||||||
|
|
||||||
done, err = SpawnServer(ctx, filepath.Join(filepath.Dir(exe), "..", "Resources", "ollama"))
|
done, err = SpawnServer(ctx, filepath.Join(filepath.Dir(exe), "..", "Resources", "ollama"), options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
|
slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
|
||||||
done = make(chan int, 1)
|
done = make(chan int, 1)
|
||||||
|
@ -16,7 +16,38 @@
|
|||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
// show status menu
|
// show status menu
|
||||||
NSMenu *menu = [[NSMenu alloc] init];
|
NSMenu *menu = [[NSMenu alloc] init];
|
||||||
|
|
||||||
|
NSMenuItem *aboutMenuItem = [[NSMenuItem alloc] initWithTitle:@"About Ollama" action:@selector(aboutOllama) keyEquivalent:@""];
|
||||||
|
[aboutMenuItem setTarget:self];
|
||||||
|
[menu addItem:aboutMenuItem];
|
||||||
|
|
||||||
|
// Settings submenu
|
||||||
|
NSMenu *settingsMenu = [[NSMenu alloc] initWithTitle:@"Settings"];
|
||||||
|
|
||||||
|
// Submenu items
|
||||||
|
NSMenuItem *chooseModelDirectoryItem = [[NSMenuItem alloc] initWithTitle:@"Choose model directory..." action:@selector(chooseModelDirectory) keyEquivalent:@""];
|
||||||
|
[chooseModelDirectoryItem setTarget:self];
|
||||||
|
[chooseModelDirectoryItem setEnabled:YES];
|
||||||
|
[settingsMenu addItem:chooseModelDirectoryItem];
|
||||||
|
|
||||||
|
NSMenuItem *exposeExternallyItem = [[NSMenuItem alloc] initWithTitle:@"Allow external connections" action:@selector(toggleExposeExternally:) keyEquivalent:@""];
|
||||||
|
[exposeExternallyItem setTarget:self];
|
||||||
|
[exposeExternallyItem setState:NSOffState]; // Set initial state to off
|
||||||
|
[exposeExternallyItem setEnabled:YES];
|
||||||
|
[settingsMenu addItem:exposeExternallyItem];
|
||||||
|
|
||||||
|
NSMenuItem *allowCrossOriginItem = [[NSMenuItem alloc] initWithTitle:@"Allow browser requests" action:@selector(toggleCrossOrigin:) keyEquivalent:@""];
|
||||||
|
[allowCrossOriginItem setTarget:self];
|
||||||
|
[allowCrossOriginItem setState:NSOffState]; // Set initial state to off
|
||||||
|
[allowCrossOriginItem setEnabled:YES];
|
||||||
|
[settingsMenu addItem:allowCrossOriginItem];
|
||||||
|
|
||||||
|
NSMenuItem *settingsMenuItem = [[NSMenuItem alloc] initWithTitle:@"Settings" action:nil keyEquivalent:@""];
|
||||||
|
[settingsMenuItem setSubmenu:settingsMenu];
|
||||||
|
[menu addItem:settingsMenuItem];
|
||||||
|
|
||||||
[menu addItemWithTitle:@"Quit Ollama" action:@selector(quit) keyEquivalent:@"q"];
|
[menu addItemWithTitle:@"Quit Ollama" action:@selector(quit) keyEquivalent:@"q"];
|
||||||
|
|
||||||
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
|
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
|
||||||
[self.statusItem addObserver:self forKeyPath:@"button.effectiveAppearance" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil];
|
[self.statusItem addObserver:self forKeyPath:@"button.effectiveAppearance" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil];
|
||||||
|
|
||||||
@ -24,6 +55,45 @@
|
|||||||
[self showIcon];
|
[self showIcon];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)aboutOllama {
|
||||||
|
[[NSApplication sharedApplication] orderFrontStandardAboutPanel:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)toggleCrossOrigin:(id)sender {
|
||||||
|
NSMenuItem *item = (NSMenuItem *)sender;
|
||||||
|
if ([item state] == NSOffState) {
|
||||||
|
// Do something when cross-origin requests are allowed
|
||||||
|
[item setState:NSOnState];
|
||||||
|
} else {
|
||||||
|
// Do something when cross-origin requests are disallowed
|
||||||
|
[item setState:NSOffState];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)toggleExposeExternally:(id)sender {
|
||||||
|
NSMenuItem *item = (NSMenuItem *)sender;
|
||||||
|
if ([item state] == NSOffState) {
|
||||||
|
// Do something when Ollama is exposed externally
|
||||||
|
[item setState:NSOnState];
|
||||||
|
} else {
|
||||||
|
// Do something when Ollama is not exposed externally
|
||||||
|
[item setState:NSOffState];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)chooseModelDirectory {
|
||||||
|
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||||
|
[openPanel setCanChooseFiles:NO];
|
||||||
|
[openPanel setCanChooseDirectories:YES];
|
||||||
|
[openPanel setAllowsMultipleSelection:NO];
|
||||||
|
|
||||||
|
NSInteger result = [openPanel runModal];
|
||||||
|
if (result == NSModalResponseOK) {
|
||||||
|
NSURL *selectedDirectoryURL = [openPanel URLs].firstObject;
|
||||||
|
// Do something with the selected directory URL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
-(void) showIcon {
|
-(void) showIcon {
|
||||||
NSAppearance* appearance = self.statusItem.button.effectiveAppearance;
|
NSAppearance* appearance = self.statusItem.button.effectiveAppearance;
|
||||||
NSString* appearanceName = (NSString*)(appearance.name);
|
NSString* appearanceName = (NSString*)(appearance.name);
|
||||||
|
@ -14,8 +14,28 @@ import (
|
|||||||
"github.com/ollama/ollama/api"
|
"github.com/ollama/ollama/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func start(ctx context.Context, command string) (*exec.Cmd, error) {
|
type ServerOptions struct {
|
||||||
|
Cors bool
|
||||||
|
Expose bool
|
||||||
|
ModelsPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func start(ctx context.Context, command string, options ServerOptions) (*exec.Cmd, error) {
|
||||||
cmd := getCmd(ctx, command)
|
cmd := getCmd(ctx, command)
|
||||||
|
|
||||||
|
// set environment variables
|
||||||
|
if options.ModelsPath != "" {
|
||||||
|
cmd.Env = append(cmd.Env, fmt.Sprintf("OLLAMA_MODELS=%s", options.ModelsPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Cors {
|
||||||
|
cmd.Env = append(cmd.Env, "OLLAMA_ORIGINS=*")
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Expose {
|
||||||
|
cmd.Env = append(cmd.Env, "OLLAMA_HOST=0.0.0.0")
|
||||||
|
}
|
||||||
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to spawn server stdout pipe: %w", err)
|
return nil, fmt.Errorf("failed to spawn server stdout pipe: %w", err)
|
||||||
@ -83,7 +103,7 @@ func start(ctx context.Context, command string) (*exec.Cmd, error) {
|
|||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SpawnServer(ctx context.Context, command string) (chan int, error) {
|
func SpawnServer(ctx context.Context, command string, options ServerOptions) (chan int, error) {
|
||||||
logDir := filepath.Dir(ServerLogFile)
|
logDir := filepath.Dir(ServerLogFile)
|
||||||
_, err := os.Stat(logDir)
|
_, err := os.Stat(logDir)
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
@ -99,7 +119,7 @@ func SpawnServer(ctx context.Context, command string) (chan int, error) {
|
|||||||
crashCount := 0
|
crashCount := 0
|
||||||
for {
|
for {
|
||||||
slog.Info(fmt.Sprintf("starting server..."))
|
slog.Info(fmt.Sprintf("starting server..."))
|
||||||
cmd, err := start(ctx, command)
|
cmd, err := start(ctx, command, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("failed to start server %s", err))
|
slog.Error(fmt.Sprintf("failed to start server %s", err))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user