소스 검색

some more menu options...

jmorganca 1 년 전
부모
커밋
201a987ff9
3개의 변경된 파일96개의 추가작업 그리고 4개의 파일을 삭제
  1. 3 1
      app/app_darwin.go
  2. 70 0
      app/app_darwin.m
  3. 23 3
      app/server.go

+ 3 - 1
app/app_darwin.go

@@ -44,10 +44,12 @@ func run() {
 		panic(err)
 	}
 
+	var options ServerOptions
+
 	ctx, cancel := context.WithCancel(context.Background())
 	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 {
 		slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
 		done = make(chan int, 1)

+ 70 - 0
app/app_darwin.m

@@ -16,7 +16,38 @@
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
     // show status menu
     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"];
+
     self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
     [self.statusItem addObserver:self forKeyPath:@"button.effectiveAppearance" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil];
 
@@ -24,6 +55,45 @@
     [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 {
     NSAppearance* appearance = self.statusItem.button.effectiveAppearance;
     NSString* appearanceName = (NSString*)(appearance.name);

+ 23 - 3
app/server.go

@@ -14,8 +14,28 @@ import (
 	"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)
+
+	// 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()
 	if err != nil {
 		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
 }
 
-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)
 	_, err := os.Stat(logDir)
 	if errors.Is(err, os.ErrNotExist) {
@@ -99,7 +119,7 @@ func SpawnServer(ctx context.Context, command string) (chan int, error) {
 		crashCount := 0
 		for {
 			slog.Info(fmt.Sprintf("starting server..."))
-			cmd, err := start(ctx, command)
+			cmd, err := start(ctx, command, options)
 			if err != nil {
 				slog.Error(fmt.Sprintf("failed to start server %s", err))
 			}