diff --git a/common.ts b/common.ts index 0a905e0..c964b0d 100644 --- a/common.ts +++ b/common.ts @@ -7,7 +7,7 @@ type ProviderProps = { "ocp": { url: string }; "azure": { url: string }; "azure-chat": { url: string }; - "anthropic": { url: string }; + "anthropic": { url: string };//, systemPrompt: string, userMessage: string }; }; type SharedPresetSettings = { @@ -25,6 +25,8 @@ export interface LoomSettings { defaultPassageSeparator: string; defaultPassageFrontmatter: string; + logApiCalls: boolean; + modelPresets: ModelPreset[]; modelPreset: number; @@ -37,11 +39,14 @@ export interface LoomSettings { prepend: string; bestOf: number; n: number; + systemPrompt: string; + userMessage: string; showSettings: boolean; showSearchBar: boolean; showNodeBorders: boolean; showExport: boolean; + } export const getPreset = (settings: LoomSettings) => settings.modelPresets[settings.modelPreset]; diff --git a/main.ts b/main.ts index e4444c8..32a4ec8 100644 --- a/main.ts +++ b/main.ts @@ -56,6 +56,7 @@ const DEFAULT_SETTINGS: LoomSettings = { passageFolder: "", defaultPassageSeparator: "\\n\\n---\\n\\n", defaultPassageFrontmatter: "%r:\\n", + logApiCalls: false, modelPresets: [], modelPreset: -1, @@ -71,6 +72,8 @@ const DEFAULT_SETTINGS: LoomSettings = { "frequencyPenalty": false, "presencePenalty": false, "prepend": false, + "systemPrompt": false, + "userMessage": false, }, maxTokens: 60, temperature: 1, @@ -80,6 +83,8 @@ const DEFAULT_SETTINGS: LoomSettings = { prepend: "<|endoftext|>", bestOf: 0, n: 5, + systemPrompt: "The assistant is in CLI simulation mode, and responds to the user's CLI commands only with the output of the command.", + userMessage: "cat untitled.txt", showSettings: false, showSearchBar: false, @@ -173,9 +178,10 @@ export default class LoomPlugin extends Plugin { //If not provided, we use node-fetch on Node.js and otherwise expect that fetch is defined globally. // expects Promise as return value this.anthropicApiKey = preset.apiKey; + this.anthropic = new Anthropic({ apiKey: preset.apiKey, - // fetch: + // fetch: defaultHeaders: { 'anthropic-version': '2023-06-01', 'anthropic-beta': 'messages-2023-12-15', @@ -1257,6 +1263,7 @@ export default class LoomPlugin extends Plugin { this.renderLoomViews(); let prompt = `${this.settings.prepend}${this.fullText(file, rootNode)}`; + // remove a trailing space if there is one // store whether there was, so it can be added back post-completion @@ -1543,8 +1550,20 @@ export default class LoomPlugin extends Plugin { async getAnthropicResponse(prompt: string) { prompt = this.trimOpenAIPrompt(prompt); // let result: CompletionResult; + const body = JSON.stringify({ + model: getPreset(this.settings).model, + max_tokens: this.settings.maxTokens, + temperature: this.settings.temperature, + system: this.settings.systemPrompt, + messages: [ + {"role": "user", "content": `${this.settings.userMessage}`}, + {"role": "assistant", "content": `${prompt}`} + ], + }, null, 2); + if(this.settings.logApiCalls) { + console.log(`request body: ${body}`); + } try { - // console.log("prompt", prompt); const response = await requestUrl({ url: "https://api.anthropic.com/v1/messages", method: "POST", @@ -1553,16 +1572,7 @@ export default class LoomPlugin extends Plugin { "anthropic-version": "2023-06-01", 'x-api-key': this.anthropicApiKey, }, - body: JSON.stringify({ - model: getPreset(this.settings).model, - max_tokens: this.settings.maxTokens, - temperature: this.settings.temperature, - system: "The assistant is in CLI simulation mode, and responds to the user's CLI commands only with the output of the command.", - messages: [ - {"role": "user", "content": `cat untitled.txt`}, - {"role": "assistant", "content": `${prompt}`} - ], - }), + body, }); if(response.status !== 200) { @@ -1575,7 +1585,9 @@ export default class LoomPlugin extends Plugin { // ? { ok: true, completions: [response.json.content[0]?.text || ""] } // : { ok: false, status: response.status, message: "" }; - // console.log("response", result); + if(this.settings.logApiCalls) { + console.log(result); + } return result; } catch (e) { @@ -1799,6 +1811,10 @@ class LoomSettingTab extends PluginSettingTab { ...preset, // @ts-expect-error apiKey: this.plugin.settings.anthropicApiKey || "", + // // @ts-expect-error + // systemPrompt: this.plugin.settings.anthropicSystemPrompt || "", + // // @ts-expect-error + // userMessage: this.plugin.settings.anthropicUserMessage || "", }; break; } @@ -1930,7 +1946,7 @@ class LoomSettingTab extends PluginSettingTab { const passagesHeader = containerEl.createDiv({ cls: "setting-item setting-item-heading" }); passagesHeader.createDiv({ cls: "setting-item-name", text: "Passages" }); - const setting = ( + const setting = ( name: string, key: LoomSettingKey, toText: (value: any) => string, @@ -1945,20 +1961,41 @@ class LoomSettingTab extends PluginSettingTab { ); } - const idSetting = (name: string, key: LoomSettingKey) => - setting(name, key, (value) => value, (text) => text); + const idSetting = (name: string, key: LoomSettingKey) => + setting(name, key, (value) => value, (text) => text); - new Setting(containerEl) - .setName("Passage folder location") - .setDesc("Passages can be quickly combined into a multipart prompt") - .addText((text) => - text.setValue(this.plugin.settings.passageFolder).onChange(async (value) => { - this.plugin.settings.passageFolder = value; - await this.plugin.save(); - }) - ); + new Setting(containerEl) + .setName("Passage folder location") + .setDesc("Passages can be quickly combined into a multipart prompt") + .addText((text) => + text.setValue(this.plugin.settings.passageFolder).onChange(async (value) => { + this.plugin.settings.passageFolder = value; + await this.plugin.save(); + }) + ); idSetting("Default passage separator", "defaultPassageSeparator"); idSetting("Default passage frontmatter", "defaultPassageFrontmatter"); + + + const debugHeader = containerEl.createDiv({ cls: "setting-item setting-item-heading" }); + debugHeader.createDiv({ cls: "setting-item-name", text: "Debug" }); + + new Setting(containerEl) + .setName("Log API calls") + .setDesc("Log API calls to the console") + .addToggle((toggle) => + toggle.setValue(this.plugin.settings.logApiCalls).onChange(async (value) => { + this.plugin.settings.logApiCalls = value; + await this.plugin.save(); + }) + ); + + new Setting(containerEl) + } + + + + } diff --git a/manifest.json b/manifest.json index 6d12953..7e7f2cd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "loom", "name": "Loom", - "version": "1.20.6", + "version": "1.20.7", "minAppVersion": "0.15.0", "description": "Loom in Obsidian", "author": "celeste", diff --git a/package-lock.json b/package-lock.json index c81d8c2..e3bfda9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "obsidian-loom", - "version": "1.20.4", + "version": "1.20.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-loom", - "version": "1.20.4", + "version": "1.20.7", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.20.0", diff --git a/package.json b/package.json index dfcf574..4e8dfad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-loom", - "version": "1.20.6", + "version": "1.20.7", "description": "Loom in Obsidian", "main": "main.js", "scripts": { diff --git a/views.ts b/views.ts index ad6f8d6..f244bde 100644 --- a/views.ts +++ b/views.ts @@ -308,6 +308,8 @@ export class LoomView extends ItemView { createCheckbox("frequencyPenalty", "Frequency penalty"); createCheckbox("presencePenalty", "Presence penalty"); createCheckbox("prepend", "Prepend sequence"); + createCheckbox("systemPrompt", "System prompt"); + createCheckbox("userMessage", "User message"); } // preset dropdown @@ -371,6 +373,8 @@ export class LoomView extends ItemView { setting("Frequency penalty", "frequencyPenalty", String(settings.frequencyPenalty), "float"); setting("Presence penalty", "presencePenalty", String(settings.presencePenalty), "float"); setting("Prepend sequence", "prepend", settings.prepend, "string"); + setting("System prompt", "systemPrompt", settings.systemPrompt, "string"); + setting("User message", "userMessage", settings.userMessage, "string"); } renderBookmarks(container: HTMLElement, state: NoteState) {