add system prompt and user message options, logging option for anthropic

This commit is contained in:
socketteer 2024-05-05 18:26:03 -04:00
parent 437ef9257f
commit 926724a881
6 changed files with 76 additions and 30 deletions

View file

@ -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<Provider>[];
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];

87
main.ts
View file

@ -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: "<cmd>cat untitled.txt</cmd>",
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<Response> 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": `<cmd>cat untitled.txt</cmd>`},
{"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 || "<no 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)
}
}

View file

@ -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",

4
package-lock.json generated
View file

@ -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",

View file

@ -1,6 +1,6 @@
{
"name": "obsidian-loom",
"version": "1.20.6",
"version": "1.20.7",
"description": "Loom in Obsidian",
"main": "main.js",
"scripts": {

View file

@ -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) {