vault backup: 2026-01-30 10:38:04
This commit is contained in:
Vendored
+321
-42
@@ -40,18 +40,30 @@ var import_obsidian = require("obsidian");
|
||||
var defaultSettings = {
|
||||
serviceUrl: "http://127.0.0.1:4096"
|
||||
};
|
||||
var MODELS_CACHE_TTL = 5 * 60 * 1e3;
|
||||
|
||||
// src/service.ts
|
||||
var OpenCodeClient = class {
|
||||
constructor(serviceUrl) {
|
||||
var OpenCodeClient = class _OpenCodeClient {
|
||||
constructor(serviceUrl, defaultModelId, onModelUnavailable) {
|
||||
this.session = null;
|
||||
this.cachedProviders = null;
|
||||
this.providersCacheTime = 0;
|
||||
this.cachedDefaults = null;
|
||||
this.serviceUrl = serviceUrl;
|
||||
this.defaultModelId = defaultModelId;
|
||||
this.onModelUnavailable = onModelUnavailable;
|
||||
}
|
||||
async request(options) {
|
||||
static {
|
||||
this.DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
|
||||
}
|
||||
static {
|
||||
this.MESSAGE_REQUEST_TIMEOUT_MS = 6e4;
|
||||
}
|
||||
async request(options, timeoutMs = _OpenCodeClient.DEFAULT_REQUEST_TIMEOUT_MS) {
|
||||
return await Promise.race([
|
||||
(0, import_obsidian.requestUrl)(options),
|
||||
new Promise(
|
||||
(_, reject) => setTimeout(() => reject(new Error("Request timeout after 10 seconds")), 1e4)
|
||||
(_, reject) => setTimeout(() => reject(new Error(`Request timeout after ${timeoutMs / 1e3} seconds`)), timeoutMs)
|
||||
)
|
||||
]);
|
||||
}
|
||||
@@ -97,36 +109,79 @@ var OpenCodeClient = class {
|
||||
if (response.status === 200) {
|
||||
const data = response.json;
|
||||
return {
|
||||
sessionID: data.sessionID,
|
||||
createTime: data.createTime,
|
||||
sessionID: data.id,
|
||||
createTime: data.time.created,
|
||||
title: data.title
|
||||
};
|
||||
} else {
|
||||
throw new Error(`HTTP ${response.status}: ${response.text}`);
|
||||
}
|
||||
if (response.status === 400) {
|
||||
const details = this.formatBadRequest(response.json, response.text);
|
||||
throw new Error(details);
|
||||
}
|
||||
throw new Error(`HTTP ${response.status}: ${response.text}`);
|
||||
} catch (error) {
|
||||
const err = error;
|
||||
throw new Error(`Failed to create session: ${err.message}`);
|
||||
}
|
||||
}
|
||||
formatBadRequest(payload, fallbackText) {
|
||||
if (!payload || typeof payload !== "object") {
|
||||
return `Bad request: ${fallbackText || "Unknown error"}`;
|
||||
}
|
||||
const p = payload;
|
||||
const errText = typeof p.errors === "string" ? p.errors : p.errors ? JSON.stringify(p.errors) : "";
|
||||
const dataText = p.data ? JSON.stringify(p.data) : "";
|
||||
const msg = [errText, dataText].filter(Boolean).join(" ");
|
||||
return msg ? `Bad request: ${msg}` : `Bad request: ${fallbackText || "Unknown error"}`;
|
||||
}
|
||||
formatNotFound(payload, fallbackText) {
|
||||
if (!payload || typeof payload !== "object") {
|
||||
return fallbackText || "Not found";
|
||||
}
|
||||
const p = payload;
|
||||
const name = typeof p.name === "string" ? p.name : "";
|
||||
const data = p.data ? JSON.stringify(p.data) : "";
|
||||
return [name, data].filter(Boolean).join(" ") || fallbackText || "Not found";
|
||||
}
|
||||
async sendMessageInternal(sessionID, message) {
|
||||
const url = `${this.serviceUrl}/session/${sessionID}/message`;
|
||||
try {
|
||||
const response = await this.request({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
const response = await this.request(
|
||||
{
|
||||
url,
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(message)
|
||||
},
|
||||
body: JSON.stringify(message)
|
||||
});
|
||||
_OpenCodeClient.MESSAGE_REQUEST_TIMEOUT_MS
|
||||
);
|
||||
if (response.status === 200) {
|
||||
return response.json;
|
||||
} else if (response.status === 404) {
|
||||
throw new Error("Session not found");
|
||||
} else {
|
||||
throw new Error(`HTTP ${response.status}: ${response.text}`);
|
||||
const raw = (response.text ?? "").trim();
|
||||
if (!raw) {
|
||||
throw new Error("Server returned empty response");
|
||||
}
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(raw);
|
||||
} catch {
|
||||
throw new Error(`Invalid JSON response: ${raw.slice(0, 50)}${raw.length > 50 ? "..." : ""}`);
|
||||
}
|
||||
if (!data || typeof data !== "object" || !Array.isArray(data.parts)) {
|
||||
throw new Error("Invalid response shape (expected {info, parts[]})");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
if (response.status === 400) {
|
||||
const payload = response.json;
|
||||
throw new Error(this.formatBadRequest(payload, response.text));
|
||||
}
|
||||
if (response.status === 404) {
|
||||
const payload = response.json;
|
||||
throw new Error(`Session not found: ${this.formatNotFound(payload, response.text)}`);
|
||||
}
|
||||
throw new Error(`HTTP ${response.status}: ${response.text}`);
|
||||
} catch (error) {
|
||||
const err = error;
|
||||
throw new Error(`Failed to send message: ${err.message}`);
|
||||
@@ -137,16 +192,99 @@ var OpenCodeClient = class {
|
||||
this.session = await this.createSession();
|
||||
}
|
||||
const message = {
|
||||
parts: [{ text: input, role: "user" }]
|
||||
parts: [{ type: "text", text: input }]
|
||||
};
|
||||
const response = await this.sendMessageInternal(this.session.sessionID, message);
|
||||
const assistantParts = response.parts.filter((part) => part.role === "assistant");
|
||||
const assistantText = assistantParts.map((part) => part.text).join("\n");
|
||||
if (this.defaultModelId) {
|
||||
const parts = this.defaultModelId.split("/");
|
||||
if (parts.length === 2) {
|
||||
message.model = {
|
||||
providerID: parts[0],
|
||||
modelID: parts[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
let response;
|
||||
try {
|
||||
response = await this.sendMessageInternal(this.session.sessionID, message);
|
||||
} catch (error) {
|
||||
const err = error;
|
||||
if (message.model && this.isLikelyModelError(err)) {
|
||||
console.log("[NoteBuddy] Selected model unavailable, falling back to server default");
|
||||
if (this.onModelUnavailable) {
|
||||
this.onModelUnavailable();
|
||||
}
|
||||
const fallbackMessage = {
|
||||
parts: message.parts
|
||||
};
|
||||
response = await this.sendMessageInternal(this.session.sessionID, fallbackMessage);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const assistantText = response.parts.filter((part) => part.type === "text").map((part) => part.type === "text" ? part.text : "").filter(Boolean).join("\n");
|
||||
return assistantText;
|
||||
}
|
||||
async sendMessageToSession(sessionID, message) {
|
||||
return await this.sendMessageInternal(sessionID, message);
|
||||
}
|
||||
isModelsCacheValid() {
|
||||
if (!this.cachedProviders) {
|
||||
return false;
|
||||
}
|
||||
const now = Date.now();
|
||||
return now - this.providersCacheTime < MODELS_CACHE_TTL;
|
||||
}
|
||||
clearModelsCache() {
|
||||
this.cachedProviders = null;
|
||||
this.providersCacheTime = 0;
|
||||
this.cachedDefaults = null;
|
||||
}
|
||||
async getCapabilities(forceRefresh = false) {
|
||||
const now = Date.now();
|
||||
if (!forceRefresh && this.cachedProviders && now - this.providersCacheTime < MODELS_CACHE_TTL) {
|
||||
return this.cachedProviders;
|
||||
}
|
||||
const url = `${this.serviceUrl}/config/providers`;
|
||||
try {
|
||||
const response = await this.request({
|
||||
url,
|
||||
method: "GET"
|
||||
});
|
||||
if (response.status === 200) {
|
||||
let data;
|
||||
try {
|
||||
data = response.json;
|
||||
} catch {
|
||||
const preview = (response.text || "").trim().slice(0, 50);
|
||||
if (preview.toLowerCase().startsWith("<!")) {
|
||||
throw new Error(
|
||||
"Server returned HTML instead of JSON. Check the Service URL and ensure the server exposes /config/providers."
|
||||
);
|
||||
}
|
||||
throw new Error(`Invalid JSON response: ${preview}...`);
|
||||
}
|
||||
const raw = data.providers || [];
|
||||
this.cachedDefaults = data.default || {};
|
||||
const providers = raw.map((p) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
models: Object.entries(p.models || {}).map(([id, m]) => ({ id, name: m?.name ?? id }))
|
||||
}));
|
||||
this.cachedProviders = providers;
|
||||
this.providersCacheTime = now;
|
||||
return providers;
|
||||
} else {
|
||||
throw new Error(`HTTP ${response.status}: ${response.text}`);
|
||||
}
|
||||
} catch (error) {
|
||||
const err = error;
|
||||
throw new Error(`Failed to get capabilities: ${err.message}`);
|
||||
}
|
||||
}
|
||||
isLikelyModelError(err) {
|
||||
const msg = (err.message || "").toLowerCase();
|
||||
return msg.includes("model") && (msg.includes("not found") || msg.includes("invalid") || msg.includes("unknown"));
|
||||
}
|
||||
};
|
||||
|
||||
// src/chat-view.ts
|
||||
@@ -156,7 +294,11 @@ var ChatView = class extends import_obsidian2.ItemView {
|
||||
super(leaf);
|
||||
this.plugin = plugin;
|
||||
this.messages = [];
|
||||
this.client = new OpenCodeClient(plugin.settings.serviceUrl);
|
||||
this.client = new OpenCodeClient(
|
||||
plugin.settings.serviceUrl,
|
||||
plugin.settings.defaultModelId,
|
||||
plugin.onModelUnavailable?.bind(plugin)
|
||||
);
|
||||
}
|
||||
getViewType() {
|
||||
return VIEW_TYPE_CHAT;
|
||||
@@ -233,7 +375,7 @@ var ChatView = class extends import_obsidian2.ItemView {
|
||||
const sendMessage = async () => {
|
||||
const message = textarea.value.trim();
|
||||
if (!message) return;
|
||||
this.messages.push({ text: message, role: "user" });
|
||||
this.messages.push({ kind: "userText", text: message });
|
||||
this.renderMessages();
|
||||
textarea.value = "";
|
||||
try {
|
||||
@@ -241,25 +383,32 @@ var ChatView = class extends import_obsidian2.ItemView {
|
||||
this.plugin.sessionState = await this.client.createSession();
|
||||
}
|
||||
const sendData = {
|
||||
parts: [{ text: message, role: "user" }],
|
||||
model: {
|
||||
providerID: "anthropic",
|
||||
modelID: "claude-3-5-sonnet-20241022"
|
||||
}
|
||||
parts: [{ type: "text", text: message }]
|
||||
};
|
||||
if (this.plugin.settings.defaultModelId) {
|
||||
const parts = this.plugin.settings.defaultModelId.split("/");
|
||||
if (parts.length === 2) {
|
||||
sendData.model = {
|
||||
providerID: parts[0],
|
||||
modelID: parts[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
let response;
|
||||
try {
|
||||
response = await this.client.sendMessageToSession(this.plugin.sessionState.sessionID, sendData);
|
||||
} catch (sendError) {
|
||||
const err = sendError;
|
||||
if (err.message.includes("Session not found") || err.message.includes("404")) {
|
||||
if (err.message.includes("Session not found")) {
|
||||
this.plugin.sessionState = await this.client.createSession();
|
||||
response = await this.client.sendMessageToSession(this.plugin.sessionState.sessionID, sendData);
|
||||
} else {
|
||||
throw sendError;
|
||||
}
|
||||
}
|
||||
this.messages.push(...response.parts);
|
||||
for (const part of response.parts) {
|
||||
this.messages.push({ kind: "assistantPart", part });
|
||||
}
|
||||
this.renderMessages();
|
||||
this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight;
|
||||
} catch (error) {
|
||||
@@ -292,19 +441,78 @@ var ChatView = class extends import_obsidian2.ItemView {
|
||||
`;
|
||||
return;
|
||||
}
|
||||
for (const message of this.messages) {
|
||||
const messageEl = this.messagesContainer.createDiv({
|
||||
cls: `nb-message nb-message-${message.role}`
|
||||
});
|
||||
messageEl.createSpan({ text: message.text });
|
||||
for (const item of this.messages) {
|
||||
if (item.kind === "userText") {
|
||||
const messageEl2 = this.messagesContainer.createDiv({ cls: "nb-message nb-message-user" });
|
||||
messageEl2.createSpan({ text: item.text });
|
||||
messageEl2.style.cssText = `
|
||||
padding: 0.75rem;
|
||||
background-color: var(--background-modifier-accent);
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
align-self: flex-end;
|
||||
max-width: 70%;
|
||||
`;
|
||||
continue;
|
||||
}
|
||||
const part = item.part;
|
||||
const messageEl = this.messagesContainer.createDiv({ cls: "nb-message nb-message-assistant" });
|
||||
messageEl.style.cssText = `
|
||||
padding: 0.75rem;
|
||||
background-color: ${message.role === "user" ? "var(--background-modifier-accent)" : "var(--background-secondary)"};
|
||||
background-color: var(--background-secondary);
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
align-self: ${message.role === "user" ? "flex-end" : "flex-start"};
|
||||
align-self: flex-start;
|
||||
max-width: 70%;
|
||||
`;
|
||||
switch (part.type) {
|
||||
case "text":
|
||||
messageEl.createSpan({ text: part.text });
|
||||
break;
|
||||
case "reasoning":
|
||||
messageEl.createSpan({ text: part.text });
|
||||
break;
|
||||
case "tool":
|
||||
messageEl.createEl("strong", { text: `Tool: ${part.tool}` });
|
||||
messageEl.createEl("pre", { text: JSON.stringify(part.state ?? {}, null, 2) });
|
||||
break;
|
||||
case "patch":
|
||||
messageEl.createEl("strong", { text: `Patch: ${part.hash}` });
|
||||
messageEl.createEl("pre", { text: (part.files || []).join("\n") });
|
||||
break;
|
||||
case "file":
|
||||
messageEl.createEl("strong", { text: `File: ${part.filename ?? part.url}` });
|
||||
messageEl.createEl("div", { text: `mime: ${part.mime}` });
|
||||
messageEl.createEl("div", { text: `url: ${part.url}` });
|
||||
break;
|
||||
case "agent":
|
||||
messageEl.createEl("strong", { text: `Agent: ${part.name}` });
|
||||
break;
|
||||
case "step_start":
|
||||
messageEl.createEl("strong", { text: `Step start${part.title ? `: ${part.title}` : ""}` });
|
||||
break;
|
||||
case "step_finish":
|
||||
messageEl.createEl("strong", { text: `Step finish${part.title ? `: ${part.title}` : ""}` });
|
||||
break;
|
||||
case "snapshot":
|
||||
messageEl.createEl("strong", { text: "Snapshot" });
|
||||
messageEl.createEl("pre", { text: JSON.stringify(part, null, 2) });
|
||||
break;
|
||||
case "retry":
|
||||
messageEl.createEl("strong", { text: "Retry" });
|
||||
messageEl.createEl("pre", { text: JSON.stringify(part, null, 2) });
|
||||
break;
|
||||
case "compaction":
|
||||
messageEl.createEl("strong", { text: "Compaction" });
|
||||
messageEl.createEl("pre", { text: JSON.stringify(part, null, 2) });
|
||||
break;
|
||||
case "unknown":
|
||||
messageEl.createEl("strong", {
|
||||
text: `Unsupported part type: ${part.originalType}`
|
||||
});
|
||||
messageEl.createEl("pre", { text: JSON.stringify(part, null, 2) });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -314,12 +522,20 @@ var import_obsidian3 = require("obsidian");
|
||||
var NoteBuddySettingTab = class extends import_obsidian3.PluginSettingTab {
|
||||
constructor(app, plugin) {
|
||||
super(app, plugin);
|
||||
this.providers = [];
|
||||
this.isLoadingModels = false;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
display() {
|
||||
async display(useCachedProviders) {
|
||||
const { containerEl } = this;
|
||||
containerEl.empty();
|
||||
containerEl.createEl("h2", { text: "NoteBuddy Settings" });
|
||||
if (!useCachedProviders) {
|
||||
try {
|
||||
await this.loadProviders();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
new import_obsidian3.Setting(containerEl).setName("Service URL").setDesc("The URL of the OpenCode service (must include protocol, hostname, and port)").addText(
|
||||
(text) => text.setPlaceholder("http://127.0.0.1:4096").setValue(this.plugin.settings.serviceUrl).onChange(async (value) => {
|
||||
if (!value.startsWith("http://") && !value.startsWith("https://")) {
|
||||
@@ -346,7 +562,7 @@ var NoteBuddySettingTab = class extends import_obsidian3.PluginSettingTab {
|
||||
);
|
||||
new import_obsidian3.Setting(containerEl).setName("Test Connection").setDesc("Test the connection to the service").addButton(
|
||||
(button) => button.setButtonText("Test").setCta().onClick(async () => {
|
||||
const client = new OpenCodeClient(this.plugin.settings.serviceUrl);
|
||||
const client = new OpenCodeClient(this.plugin.settings.serviceUrl, this.plugin.settings.defaultModelId);
|
||||
const result = await client.healthCheck();
|
||||
if (result.status === "connected") {
|
||||
new import_obsidian3.Notice("Connection successful!");
|
||||
@@ -355,6 +571,65 @@ var NoteBuddySettingTab = class extends import_obsidian3.PluginSettingTab {
|
||||
}
|
||||
})
|
||||
);
|
||||
this.displayModelSelection(containerEl);
|
||||
this.displayRefreshButton(containerEl);
|
||||
}
|
||||
async loadProviders(client, forceRefresh) {
|
||||
if (this.isLoadingModels) {
|
||||
return;
|
||||
}
|
||||
this.isLoadingModels = true;
|
||||
try {
|
||||
const c = client ?? new OpenCodeClient(this.plugin.settings.serviceUrl, this.plugin.settings.defaultModelId);
|
||||
this.providers = await c.getCapabilities(forceRefresh ?? false);
|
||||
} catch (error) {
|
||||
this.providers = [];
|
||||
console.error("[NoteBuddy] Failed to load providers:", error);
|
||||
throw error;
|
||||
} finally {
|
||||
this.isLoadingModels = false;
|
||||
}
|
||||
}
|
||||
displayModelSelection(containerEl) {
|
||||
const modelOptions = {};
|
||||
modelOptions[""] = "Use server default";
|
||||
for (const provider of this.providers) {
|
||||
for (const model of provider.models) {
|
||||
const value = `${provider.id}/${model.id}`;
|
||||
modelOptions[value] = `${provider.name} - ${model.name}`;
|
||||
}
|
||||
}
|
||||
const currentValue = this.getCurrentModelSelection();
|
||||
new import_obsidian3.Setting(containerEl).setName("Default Model").setDesc("Select the default AI model to use for conversations").addDropdown(
|
||||
(dropdown) => dropdown.addOptions(modelOptions).setValue(currentValue).onChange(async (value) => {
|
||||
if (value) {
|
||||
this.plugin.settings.defaultModelId = value;
|
||||
} else {
|
||||
this.plugin.settings.defaultModelId = void 0;
|
||||
}
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
getCurrentModelSelection() {
|
||||
return this.plugin.settings.defaultModelId || "";
|
||||
}
|
||||
displayRefreshButton(container) {
|
||||
new import_obsidian3.Setting(container).setName("Refresh Models").setDesc("Reload the list of available models from the service").addButton(
|
||||
(button) => button.setButtonText("Refresh").onClick(async () => {
|
||||
const client = new OpenCodeClient(this.plugin.settings.serviceUrl, this.plugin.settings.defaultModelId);
|
||||
client.clearModelsCache();
|
||||
try {
|
||||
await this.loadProviders(client, true);
|
||||
new import_obsidian3.Notice("Models refreshed");
|
||||
await this.display(true);
|
||||
} catch (error) {
|
||||
console.error("[NoteBuddy] Failed to load providers:", error);
|
||||
new import_obsidian3.Notice(`Failed to refresh models: ${error.message}`);
|
||||
await this.display(true);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -407,6 +682,10 @@ var NoteBuddyPlugin = class extends import_obsidian4.Plugin {
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
// Callback for when selected model is unavailable
|
||||
onModelUnavailable() {
|
||||
new import_obsidian4.Notice("Selected model is unavailable. Using server default instead.");
|
||||
}
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
|
||||
+6
-6
File diff suppressed because one or more lines are too long
+1
-1
@@ -5,7 +5,7 @@
|
||||
"isDesktopOnly": false,
|
||||
"js": "main.js",
|
||||
"fundingUrl": "https://ko-fi.com/vinzent",
|
||||
"version": "1.46.0",
|
||||
"version": "1.46.1",
|
||||
"author": "Vinzent",
|
||||
"authorUrl": "https://github.com/Vinzent03"
|
||||
}
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@
|
||||
"mdBorderColor": "Black",
|
||||
"mdCSS": "",
|
||||
"scriptEngineSettings": {},
|
||||
"previousRelease": "2.19.2",
|
||||
"previousRelease": "2.20.0",
|
||||
"showReleaseNotes": true,
|
||||
"compareManifestToPluginVersion": true,
|
||||
"showNewVersionNotification": true,
|
||||
|
||||
+3
-3
File diff suppressed because one or more lines are too long
+11
-11
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.19.2",
|
||||
"minAppVersion": "1.5.7",
|
||||
"description": "Sketch Your Mind. An Obsidian plugin to edit and view Excalidraw drawings. Enter the world of 4D Visual PKM.",
|
||||
"author": "Zsolt Viczian",
|
||||
"authorUrl": "https://excalidraw-obsidian.online",
|
||||
"fundingUrl": "https://ko-fi.com/zsolt",
|
||||
"helpUrl": "https://github.com/zsviczian/obsidian-excalidraw-plugin#readme",
|
||||
"isDesktopOnly": false
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.20.0",
|
||||
"minAppVersion": "1.5.7",
|
||||
"description": "Sketch Your Mind. An Obsidian plugin to edit and view Excalidraw drawings. Enter the world of 4D Visual PKM.",
|
||||
"author": "Zsolt Viczian",
|
||||
"authorUrl": "https://excalidraw-obsidian.online",
|
||||
"fundingUrl": "https://ko-fi.com/zsolt",
|
||||
"helpUrl": "https://github.com/zsviczian/obsidian-excalidraw-plugin#readme",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+3
-1
@@ -65,7 +65,9 @@
|
||||
"generalSettings": {},
|
||||
"headingOpened": {
|
||||
"核心状态": true,
|
||||
"自定义状态": true
|
||||
"自定义状态": true,
|
||||
"Core Statuses": true,
|
||||
"Custom Statuses": true
|
||||
},
|
||||
"debugSettings": {
|
||||
"ignoreSortInstructions": false,
|
||||
|
||||
Vendored
+17
-2
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"choices": [],
|
||||
"inputPrompt": "single-line",
|
||||
"persistInputPromptDrafts": true,
|
||||
"useSelectionAsCaptureValue": true,
|
||||
"devMode": false,
|
||||
"templateFolderPath": "06_Metadata/Templates",
|
||||
"announceUpdates": "all",
|
||||
"version": "2.9.4",
|
||||
"version": "2.10.0",
|
||||
"globalVariables": {},
|
||||
"onePageInputEnabled": false,
|
||||
"disableOnlineFeatures": true,
|
||||
@@ -12,6 +14,17 @@
|
||||
"showCaptureNotification": true,
|
||||
"showInputCancellationNotification": false,
|
||||
"enableTemplatePropertyTypes": true,
|
||||
"dateAliases": {
|
||||
"t": "today",
|
||||
"tm": "tomorrow",
|
||||
"yd": "yesterday",
|
||||
"nw": "next week",
|
||||
"nm": "next month",
|
||||
"ny": "next year",
|
||||
"lw": "last week",
|
||||
"lm": "last month",
|
||||
"ly": "last year"
|
||||
},
|
||||
"ai": {
|
||||
"defaultModel": "Ask me",
|
||||
"defaultSystemPrompt": "As an AI assistant within Obsidian, your primary goal is to help users manage their ideas and knowledge more effectively. Format your responses using Markdown syntax. Please use the [[Obsidian]] link format. You can write aliases for the links by writing [[Obsidian|the alias after the pipe symbol]]. To use mathematical notation, use LaTeX syntax. LaTeX syntax for larger equations should be on separate lines, surrounded with double dollar signs ($$). You can also inline math expressions by wrapping it in $ symbols. For example, use $$w_{ij}^{\text{new}}:=w_{ij}^{\text{current}}+etacdotdelta_jcdot x_{ij}$$ on a separate line, but you can write \"($eta$ = learning rate, $delta_j$ = error term, $x_{ij}$ = input)\" inline.",
|
||||
@@ -99,6 +112,8 @@
|
||||
"addDefaultAIProviders": true,
|
||||
"removeMacroIndirection": true,
|
||||
"migrateFileOpeningSettings": true,
|
||||
"setProviderModelDiscoveryMode": true
|
||||
"setProviderModelDiscoveryMode": true,
|
||||
"backfillFileOpeningDefaults": true,
|
||||
"migrateProviderApiKeysToSecretStorage": true
|
||||
}
|
||||
}
|
||||
Vendored
+78
-73
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "quickadd",
|
||||
"name": "QuickAdd",
|
||||
"version": "2.9.4",
|
||||
"minAppVersion": "1.6.0",
|
||||
"version": "2.10.0",
|
||||
"minAppVersion": "1.11.4",
|
||||
"description": "Quickly add new pages or content to your vault.",
|
||||
"author": "Christian B. B. Houmann",
|
||||
"authorUrl": "https://bagerbach.com",
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+14
-14
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "templater-obsidian",
|
||||
"name": "Templater",
|
||||
"version": "2.17.0",
|
||||
"version": "2.18.1",
|
||||
"description": "Create and use templates",
|
||||
"minAppVersion": "1.5.0",
|
||||
"author": "SilentVoid",
|
||||
|
||||
Reference in New Issue
Block a user