cc580889d2
Update coverage reports and add new validation utilities Add comprehensive validation utilities for Ollama URL and model name Add new API response types and client configuration interfaces Add Logger utility for consistent logging Add validation function for plugin settings Add unit tests for validation functions Update TypeScript configuration Update coverage reports to reflect new code additions ```
134 lines
4.0 KiB
TypeScript
134 lines
4.0 KiB
TypeScript
import { Plugin, WorkspaceLeaf, App, Setting, Notice, PluginSettingTab } from 'obsidian';
|
|
import { ChatView } from './src/chat-view';
|
|
import { PluginSettings } from './src/types';
|
|
import {
|
|
isValidHttpUrl,
|
|
validatePluginSettings,
|
|
validateOllamaUrl,
|
|
validateModelName,
|
|
Logger,
|
|
} from './src/utils';
|
|
|
|
export default class OllamaPlugin extends Plugin {
|
|
settings: PluginSettings = {
|
|
ollamaUrl: 'http://localhost:11434',
|
|
model: 'llama3',
|
|
lastIndexTime: 0,
|
|
};
|
|
|
|
async onload() {
|
|
// Initialize logging
|
|
Logger.info('Ollama Plugin loading...', 'plugin');
|
|
|
|
await this.loadSettings();
|
|
Logger.info('Plugin loaded successfully', 'plugin');
|
|
|
|
this.registerView(
|
|
'ollama-chat-view',
|
|
(leaf: WorkspaceLeaf) => new ChatView(leaf, this.settings)
|
|
);
|
|
|
|
this.addRibbonIcon('message-square', 'Ollama Chat', async () => {
|
|
const leaf = this.app.workspace.getLeaf();
|
|
await leaf.setViewState({
|
|
type: 'ollama-chat-view',
|
|
active: true,
|
|
});
|
|
this.app.workspace.revealLeaf(leaf);
|
|
});
|
|
|
|
this.addSettingTab(new OllamaSettingTab(this.app, this));
|
|
}
|
|
|
|
async loadSettings() {
|
|
try {
|
|
const data = await this.loadData();
|
|
if (data) {
|
|
Logger.debug('Loading saved settings', 'settings');
|
|
this.settings = Object.assign({}, this.settings, data);
|
|
}
|
|
} catch (error) {
|
|
// Use centralized error handling
|
|
const { ErrorHandler } = await import('./src/error-handler');
|
|
ErrorHandler.handleError(error, 'settings load');
|
|
}
|
|
}
|
|
|
|
async saveSettings() {
|
|
try {
|
|
// Validate settings before saving
|
|
const validationErrors = validatePluginSettings(this.settings);
|
|
if (validationErrors.length > 0) {
|
|
Logger.error(
|
|
'Validation errors prevented saving settings: ' + validationErrors.join('; '),
|
|
'settings'
|
|
);
|
|
new Notice(`Cannot save settings: ${validationErrors[0]}`);
|
|
return false;
|
|
}
|
|
|
|
Logger.debug('Saving settings: ' + JSON.stringify(this.settings), 'settings');
|
|
await this.saveData(this.settings);
|
|
Logger.info('Settings saved successfully', 'settings');
|
|
return true;
|
|
} catch (error) {
|
|
// Use centralized error handling
|
|
const { ErrorHandler } = await import('./src/error-handler');
|
|
ErrorHandler.handleError(error, 'settings save');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class OllamaSettingTab extends PluginSettingTab {
|
|
private plugin: OllamaPlugin;
|
|
|
|
constructor(app: App, plugin: OllamaPlugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
display(): void {
|
|
const container = this.containerEl.createDiv() as HTMLElement;
|
|
container.empty();
|
|
|
|
new Setting(container)
|
|
.setName('Ollama URL')
|
|
.setDesc('URL of your Ollama instance')
|
|
.addText((text) =>
|
|
text.setValue(this.plugin.settings.ollamaUrl).onChange(async (value) => {
|
|
const urlValidation = validateOllamaUrl(value);
|
|
if (urlValidation.valid) {
|
|
Logger.debug('URL changed to: ' + value, 'settings');
|
|
this.plugin.settings.ollamaUrl = value;
|
|
await this.plugin.saveSettings();
|
|
} else {
|
|
Logger.warn('Invalid URL format: ' + urlValidation.error, 'settings');
|
|
new Notice(urlValidation.error || 'Invalid Ollama URL format.');
|
|
}
|
|
})
|
|
);
|
|
|
|
new Setting(container)
|
|
.setName('Model')
|
|
.setDesc('Model to use for chat')
|
|
.addText((text) =>
|
|
text.setValue(this.plugin.settings.model).onChange(async (value) => {
|
|
const modelValidation = validateModelName(value);
|
|
if (modelValidation.valid) {
|
|
Logger.debug('Model changed to: ' + value, 'settings');
|
|
this.plugin.settings.model = value;
|
|
await this.plugin.saveSettings();
|
|
} else {
|
|
Logger.warn('Invalid model name format: ' + modelValidation.error, 'settings');
|
|
new Notice(modelValidation.error || 'Invalid model name format.');
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
hide(): void {
|
|
this.containerEl.empty();
|
|
}
|
|
}
|