generated from silverbulletmd/silverbullet-plug-template
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsilverbullet-ai.plug.js
80 lines (63 loc) · 52 KB
/
silverbullet-ai.plug.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var Pt=Object.defineProperty;var v=(e,t)=>{for(var r in t)Pt(e,r,{get:t[r],enumerable:!0})};var me=typeof window>"u"&&typeof globalThis.WebSocketPair>"u";typeof Deno>"u"&&(self.Deno={args:[],build:{arch:"x86_64"},env:{get(){}}});var ce=new Map,ae=0;function G(e){self.postMessage(e)}me&&(globalThis.syscall=async(e,...t)=>await new Promise((r,n)=>{ae++,ce.set(ae,{resolve:r,reject:n}),G({type:"sys",id:ae,name:e,args:t})}));function ve(e,t){me&&(self.addEventListener("message",r=>{(async()=>{let n=r.data;switch(n.type){case"inv":{let o=e[n.name];if(!o)throw new Error(`Function not loaded: ${n.name}`);try{let i=await Promise.resolve(o(...n.args||[]));G({type:"invr",id:n.id,result:i})}catch(i){console.error("An exception was thrown as a result of invoking function",n.name,"error:",i.message),G({type:"invr",id:n.id,error:i.message})}}break;case"sysr":{let o=n.id,i=ce.get(o);if(!i)throw Error("Invalid request id");ce.delete(o),n.error?i.reject(new Error(n.error)):i.resolve(n.result)}break}})().catch(console.error)}),G({type:"manifest",manifest:t}))}function Et(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o<r;o++)n[o]=t.charCodeAt(o);return n}function Ce(e){typeof e=="string"&&(e=new TextEncoder().encode(e));let t="",r=e.byteLength;for(let n=0;n<r;n++)t+=String.fromCharCode(e[n]);return btoa(t)}async function St(e,t){if(typeof e!="string"){let r=new Uint8Array(await e.arrayBuffer()),n=r.length>0?Ce(r):void 0;t={method:e.method,headers:Object.fromEntries(e.headers.entries()),base64Body:n},e=e.url}return syscall("sandboxFetch.fetch",e,t)}globalThis.nativeFetch=globalThis.fetch;function At(){globalThis.fetch=async function(e,t){let r=t&&t.body?Ce(new Uint8Array(await new Response(t.body).arrayBuffer())):void 0,n=await St(e,t&&{method:t.method,headers:t.headers,base64Body:r});return new Response(n.base64Body?Et(n.base64Body):null,{status:n.status,headers:n.headers})}}me&&At();function de(e){if(e.children)for(let t of e.children){if(t.parent)return;t.parent=e,de(t)}}function vt(e,t){return W(e,r=>r.type===t)}function W(e,t){if(t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...W(n,t)];return r}async function Te(e,t){if(await t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...await Te(n,t)];return r}function le(e,t){if(e.children){let r=e.children.slice();for(let n of r){let o=t(n);if(o!==void 0){let i=e.children.indexOf(n);o?e.children.splice(i,1,o):e.children.splice(i,1)}else le(n,t)}}}async function pe(e,t){if(e.children){let r=e.children.slice();for(let n of r){let o=await t(n);if(o!==void 0){let i=e.children.indexOf(n);o?e.children.splice(i,1,o):e.children.splice(i,1)}else await pe(n,t)}}}function M(e,t){return W(e,r=>r.type===t)[0]}function ue(e,t){W(e,t)}async function Me(e,t){await Te(e,t)}function E(e){if(!e)return"";let t=[];if(e.text!==void 0)return e.text;for(let r of e.children)t.push(E(r));return t.join("")}function ge(e,t=!0){if(vt(e,"\u26A0").length>0)throw new Error(`Parse error in: ${E(e)}`);if(e.text!==void 0)return e.text;let n=[e.type];for(let o of e.children)o.type&&!o.type.endsWith("Mark")&&n.push(ge(o,t)),o.text&&(t&&o.text.trim()||!t)&&n.push(o.text);return n}function Ct(e){return e.getUTCHours()===0&&e.getUTCMinutes()===0&&e.getUTCSeconds()===0?e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0"):e.toISOString()}function D(e){if(!e||typeof e!="object")return e;if(Array.isArray(e))return e.map(D);if(e instanceof Date)return Ct(e);let t={};for(let r of Object.keys(e)){let n=r.split("."),o=t;for(let i=0;i<n.length-1;i++){let s=n[i];o[s]||(o[s]={}),o=o[s]}o[n[n.length-1]]=D(e[r])}return t}var m={};v(m,{confirm:()=>tr,copyToClipboard:()=>ur,deleteLine:()=>gr,dispatch:()=>Xt,downloadFile:()=>Dt,filterBox:()=>Ht,flashNotification:()=>_t,fold:()=>ir,foldAll:()=>cr,getCurrentPage:()=>Tt,getCursor:()=>Ot,getSelection:()=>kt,getText:()=>It,getUiOption:()=>rr,goHistory:()=>Wt,hidePanel:()=>zt,insertAtCursor:()=>Zt,insertAtPos:()=>Yt,moveCursor:()=>Jt,navigate:()=>Ut,openCommandPalette:()=>Lt,openPageNavigator:()=>Rt,openSearchPanel:()=>pr,openUrl:()=>Gt,prompt:()=>er,redo:()=>lr,reloadPage:()=>jt,reloadSettingsAndCommands:()=>qt,reloadUI:()=>Kt,replaceRange:()=>Qt,save:()=>$t,setPage:()=>Mt,setSelection:()=>Ft,setText:()=>Nt,setUiOption:()=>nr,showPanel:()=>Vt,toggleFold:()=>ar,undo:()=>dr,unfold:()=>sr,unfoldAll:()=>mr,uploadFile:()=>Bt,vimEx:()=>or});typeof self>"u"&&(self={syscall:()=>{throw new Error("Not implemented here")}});var a=globalThis.syscall;function Tt(){return a("editor.getCurrentPage")}function Mt(e){return a("editor.setPage",e)}function It(){return a("editor.getText")}function Nt(e){return a("editor.setText",e)}function Ot(){return a("editor.getCursor")}function kt(){return a("editor.getSelection")}function Ft(e,t){return a("editor.setSelection",e,t)}function $t(){return a("editor.save")}function Ut(e,t=!1,r=!1){return a("editor.navigate",e,t,r)}function Rt(e="page"){return a("editor.openPageNavigator",e)}function Lt(){return a("editor.openCommandPalette")}function jt(){return a("editor.reloadPage")}function Kt(){return a("editor.reloadUI")}function qt(){return a("editor.reloadSettingsAndCommands")}function Gt(e,t=!1){return a("editor.openUrl",e,t)}function Wt(e){return a("editor.goHistory",e)}function Dt(e,t){return a("editor.downloadFile",e,t)}function Bt(e,t){return a("editor.uploadFile",e,t)}function _t(e,t="info"){return a("editor.flashNotification",e,t)}function Ht(e,t,r="",n=""){return a("editor.filterBox",e,t,r,n)}function Vt(e,t,r,n=""){return a("editor.showPanel",e,t,r,n)}function zt(e){return a("editor.hidePanel",e)}function Yt(e,t){return a("editor.insertAtPos",e,t)}function Qt(e,t,r){return a("editor.replaceRange",e,t,r)}function Jt(e,t=!1){return a("editor.moveCursor",e,t)}function Zt(e){return a("editor.insertAtCursor",e)}function Xt(e){return a("editor.dispatch",e)}function er(e,t=""){return a("editor.prompt",e,t)}function tr(e){return a("editor.confirm",e)}function rr(e){return a("editor.getUiOption",e)}function nr(e,t){return a("editor.setUiOption",e,t)}function or(e){return a("editor.vimEx",e)}function ir(){return a("editor.fold")}function sr(){return a("editor.unfold")}function ar(){return a("editor.toggleFold")}function cr(){return a("editor.foldAll")}function mr(){return a("editor.unfoldAll")}function dr(){return a("editor.undo")}function lr(){return a("editor.redo")}function pr(){return a("editor.openSearchPanel")}function ur(e){return a("editor.copyToClipboard",e)}function gr(){return a("editor.deleteLine")}var S={};v(S,{parseMarkdown:()=>fr});function fr(e){return a("markdown.parseMarkdown",e)}var w={};v(w,{deleteAttachment:()=>Cr,deleteFile:()=>Or,deletePage:()=>wr,getAttachmentMeta:()=>Sr,getFileMeta:()=>Ir,getPageMeta:()=>yr,listAttachments:()=>Er,listFiles:()=>Tr,listPages:()=>hr,listPlugs:()=>Pr,readAttachment:()=>Ar,readFile:()=>Mr,readPage:()=>xr,writeAttachment:()=>vr,writeFile:()=>Nr,writePage:()=>br});function hr(e=!1){return a("space.listPages",e)}function yr(e){return a("space.getPageMeta",e)}function xr(e){return a("space.readPage",e)}function br(e,t){return a("space.writePage",e,t)}function wr(e){return a("space.deletePage",e)}function Pr(){return a("space.listPlugs")}function Er(){return a("space.listAttachments")}function Sr(e){return a("space.getAttachmentMeta",e)}function Ar(e){return a("space.readAttachment",e)}function vr(e,t){return a("space.writeAttachment",e,t)}function Cr(e){return a("space.deleteAttachment",e)}function Tr(){return a("space.listFiles")}function Mr(e){return a("space.readFile",e)}function Ir(e){return a("space.getFileMeta",e)}function Nr(e,t){return a("space.writeFile",e,t)}function Or(e){return a("space.deleteFile",e)}var f={};v(f,{applyAttributeExtractors:()=>Lr,getEnv:()=>Kr,getMode:()=>qr,getVersion:()=>Gr,invokeCommand:()=>Fr,invokeFunction:()=>kr,invokeSpaceFunction:()=>Rr,listCommands:()=>$r,listSyscalls:()=>Ur,reloadPlugs:()=>jr});function kr(e,...t){return a("system.invokeFunction",e,...t)}function Fr(e,t){return a("system.invokeCommand",e,t)}function $r(){return a("system.listCommands")}function Ur(){return a("system.listSyscalls")}function Rr(e,...t){return a("system.invokeSpaceFunction",e,...t)}function Lr(e,t,r){return a("system.applyAttributeExtractors",e,t,r)}function jr(){return a("system.reloadPlugs")}function Kr(){return a("system.getEnv")}function qr(){return a("system.getMode")}function Gr(){return a("system.getVersion")}var C={};v(C,{del:()=>Br,get:()=>Dr,set:()=>Wr});function Wr(e,t){return a("clientStore.set",e,t)}function Dr(e){return a("clientStore.get",e)}function Br(e){return a("clientStore.delete",e)}var B={};v(B,{listLanguages:()=>zr,parseLanguage:()=>Vr});function Vr(e,t){return a("language.parseLanguage",e,t)}function zr(){return a("language.listLanguages")}var F={};v(F,{parseTemplate:()=>Qr,renderTemplate:()=>Yr});function Yr(e,t,r={}){return a("template.renderTemplate",e,t,r)}function Qr(e){return a("template.parseTemplate",e)}var O={};v(O,{dispatchEvent:()=>Xr,listEvents:()=>en});function Xr(e,t,r){return new Promise((n,o)=>{let i=-1;r&&(i=setTimeout(()=>{console.log("Timeout!"),o("timeout")},r)),a("event.dispatch",e,t).then(s=>{i!==-1&&clearTimeout(i),n(s)}).catch(o)})}function en(){return a("event.list")}var A={};v(A,{parse:()=>rn,stringify:()=>nn});function rn(e){return a("yaml.parse",e)}function nn(e){return a("yaml.stringify",e)}async function $(e,t={}){let r={tags:[]},n=[];de(e),await pe(e,async o=>{if(o.type==="Paragraph"&&o.parent?.type==="Document"){let i=!0,s=new Set;for(let c of o.children)if(c.text){if(c.text.startsWith(`
`)&&c.text!==`
`)break;if(c.text.trim()){i=!1;break}}else if(c.type==="Hashtag"){let d=c.children[0].text.substring(1);s.add(d),(t.removeTags===!0||t.removeTags?.includes(d))&&(c.children[0].text="")}else if(c.type){i=!1;break}i&&n.push(...s)}if(o.type==="FrontMatter"){let i=o.children[1].children[0],s=E(i);try{let c=await A.parse(s),d={...c};if(r={...r,...c},r.tags||(r.tags=[]),typeof r.tags=="string"&&n.push(...r.tags.split(/,\s*|\s+/)),Array.isArray(r.tags)&&n.push(...r.tags),t.removeKeys&&t.removeKeys.length>0){let p=!1;for(let u of t.removeKeys)u in d&&(delete d[u],p=!0);p&&(i.text=await A.stringify(d))}if(Object.keys(d).length===0||t.removeFrontmatterSection)return null}catch(c){console.warn("Could not parse frontmatter",c.message)}}});try{r.tags=[...new Set([...n.map(o=>String(o).replace(/^#/,""))])]}catch(o){console.error("Error while processing tags",o)}return r=D(r),r}async function Ie(e,t){let r=null;if(await Me(e,async n=>{if(n.type==="FrontMatter"){let o=n.children[1].children[0],i=E(o);try{let s="";if(typeof t=="string")s=i+t+`
`;else{let d={...await A.parse(i),...t};s=await A.stringify(d)}r={changes:{from:o.from,to:o.to,insert:s}}}catch(s){console.error("Error parsing YAML",s)}return!0}return!1}),!r){let n="";typeof t=="string"?n=t+`
`:n=await A.stringify(t),r={changes:{from:0,to:0,insert:`---
`+n+`---
`}}}return r}var _=class{constructor(t,r={}){this.maxSize=t;this.map=new Map(Object.entries(r))}map;set(t,r,n){let o={value:r,la:Date.now()};if(n){let i=this.map.get(t);i?.expTimer&&clearTimeout(i.expTimer),o.expTimer=setTimeout(()=>{this.map.delete(t)},n)}if(this.map.size>=this.maxSize){let i=this.getOldestKey();this.map.delete(i)}this.map.set(t,o)}get(t){let r=this.map.get(t);if(r)return r.la=Date.now(),r.value}remove(t){this.map.delete(t)}toJSON(){return Object.fromEntries(this.map.entries())}getOldestKey(){let t,r;for(let[n,o]of this.map.entries())(!r||o.la<r)&&(t=n,r=o.la);return t}};var Ne=new _(50);async function Oe(e,t,r){if(!r)return t(e);let n=JSON.stringify(e),o=Ne.get(n);if(o)return o;let i=await t(e);return Ne.set(n,i,r*1e3),i}function fe(e,t){return f.invokeFunction("index.indexObjects",e,t)}function U(e,t,r){return Oe(t,()=>f.invokeFunction("index.queryObjects",e,t),r)}async function ke(e,t={},r={}){try{let n=await S.parseMarkdown(e),o=await $(n,{removeFrontmatterSection:!0,removeTags:["template"]});e=E(n).trimStart();let i;return o.frontmatter&&(typeof o.frontmatter=="string"?i=o.frontmatter:i=await A.stringify(o.frontmatter),i=await F.renderTemplate(i,t,r)),{frontmatter:o,renderedFrontmatter:i,text:await F.renderTemplate(e,t,r)}}catch(n){throw console.error("Error rendering template",n),n}}async function an(){let e=await m.getSelection(),t="";return e.from===e.to?t="":t=(await m.getText()).slice(e.from,e.to),{from:e.from,to:e.to,text:t}}async function H(){let e=await an(),t=await m.getText();if(e.text==="")return{from:0,to:t.length,text:t,isWholeNote:!0};let r=e.from===0&&e.to===t.length;return{...e,isWholeNote:r}}async function R(){return(await m.getText()).length}async function cn(e,t){let r=await w.readPage(e),n=await S.parseMarkdown(r),o;return ue(n,i=>{if(i.type!=="FencedCode")return!1;let s=M(i,"CodeInfo");if(t&&!s||t&&!t.includes(s.children[0].text))return!1;let c=M(i,"CodeText");return c?(o=c.children[0].text,!0):!1}),o}async function V(e,t=["yaml"]){let r=await cn(e,t);if(r!==void 0)try{return A.parse(r)}catch(n){throw console.error("YAML Page parser error",n),new Error(`YAML Error: ${n.message}`)}}async function z(e){try{let r=(await V("SECRETS",["yaml","secrets"]))[e];if(r===void 0)throw new Error(`No such secret: ${e}`);return r}catch(t){throw t.message==="Not found"?new Error(`No such secret: ${e}`):t}}var mn="SETTINGS";async function Fe(e,t){try{let n=(await V(mn,["yaml"])||{})[e];return n===void 0?t:n}catch(r){if(r.message==="Not found")return t;throw r}}var Y=class{apiKey;baseUrl;name;modelName;requireAuth;constructor(t,r,n,o,i=!0){this.apiKey=t,this.baseUrl=r,this.name=n,this.modelName=o,this.requireAuth=i}};var Q=class extends Y{constructor(t,r,n){super(t,n,"DALL-E",r)}async generateImage(t){try{y||await I();let r=await nativeFetch(`${this.baseUrl}/images/generations`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({model:this.modelName,prompt:t.prompt,n:t.numImages,size:t.size,quality:t.quality,response_format:"b64_json"})});if(!r.ok)throw new Error(`HTTP error, status: ${r.status}`);let n=await r.json();if(!n||n.length===0)throw new Error("Invalid response from DALL-E.");return n}catch(r){throw console.error("Error calling DALL\xB7E image generation endpoint:",r),r}}};var k=function(e,t){if(!(this instanceof k))return new k(e,t);this.INITIALIZING=-1,this.CONNECTING=0,this.OPEN=1,this.CLOSED=2,this.url=e,t=t||{},this.headers=t.headers||{},this.payload=t.payload!==void 0?t.payload:"",this.method=t.method||this.payload&&"POST"||"GET",this.withCredentials=!!t.withCredentials,this.debug=!!t.debug,this.FIELD_SEPARATOR=":",this.listeners={},this.xhr=null,this.readyState=this.INITIALIZING,this.progress=0,this.chunk="",this.addEventListener=function(r,n){this.listeners[r]===void 0&&(this.listeners[r]=[]),this.listeners[r].indexOf(n)===-1&&this.listeners[r].push(n)},this.removeEventListener=function(r,n){if(this.listeners[r]!==void 0){var o=[];this.listeners[r].forEach(function(i){i!==n&&o.push(i)}),o.length===0?delete this.listeners[r]:this.listeners[r]=o}},this.dispatchEvent=function(r){if(!r)return!0;this.debug&&console.debug(r),r.source=this;var n="on"+r.type;return this.hasOwnProperty(n)&&(this[n].call(this,r),r.defaultPrevented)?!1:this.listeners[r.type]?this.listeners[r.type].every(function(o){return o(r),!r.defaultPrevented}):!0},this._setReadyState=function(r){var n=new CustomEvent("readystatechange");n.readyState=r,this.readyState=r,this.dispatchEvent(n)},this._onStreamFailure=function(r){var n=new CustomEvent("error");n.data=r.currentTarget.response,this.dispatchEvent(n),this.close()},this._onStreamAbort=function(r){this.dispatchEvent(new CustomEvent("abort")),this.close()},this._onStreamProgress=function(r){if(this.xhr){if(this.xhr.status!==200){this._onStreamFailure(r);return}this.readyState==this.CONNECTING&&(this.dispatchEvent(new CustomEvent("open")),this._setReadyState(this.OPEN));var n=this.xhr.responseText.substring(this.progress);this.progress+=n.length;var o=(this.chunk+n).split(/(\r\n\r\n|\r\r|\n\n)/g),i=o.pop();o.forEach(function(s){s.trim().length>0&&this.dispatchEvent(this._parseEventChunk(s))}.bind(this)),this.chunk=i}},this._onStreamLoaded=function(r){this._onStreamProgress(r),this.dispatchEvent(this._parseEventChunk(this.chunk)),this.chunk=""},this._parseEventChunk=function(r){if(!r||r.length===0)return null;this.debug&&console.debug(r);var n={id:null,retry:null,data:null,event:null};r.split(/\n|\r\n|\r/).forEach(function(i){var s=i.indexOf(this.FIELD_SEPARATOR),c,d;if(s>0){var p=i[s+1]===" "?2:1;c=i.substring(0,s),d=i.substring(s+p)}else if(s<0)c=i,d="";else return;c in n&&(c==="data"&&n[c]!==null?n.data+=`
`+d:n[c]=d)}.bind(this));var o=new CustomEvent(n.event||"message");return o.data=n.data||"",o.id=n.id,o},this._checkStreamClosed=function(){this.xhr&&this.xhr.readyState===XMLHttpRequest.DONE&&this._setReadyState(this.CLOSED)},this.stream=function(){if(!this.xhr){this._setReadyState(this.CONNECTING),this.xhr=new XMLHttpRequest,this.xhr.addEventListener("progress",this._onStreamProgress.bind(this)),this.xhr.addEventListener("load",this._onStreamLoaded.bind(this)),this.xhr.addEventListener("readystatechange",this._checkStreamClosed.bind(this)),this.xhr.addEventListener("error",this._onStreamFailure.bind(this)),this.xhr.addEventListener("abort",this._onStreamAbort.bind(this)),this.xhr.open(this.method,this.url);for(var r in this.headers)this.xhr.setRequestHeader(r,this.headers[r]);this.xhr.withCredentials=this.withCredentials,this.xhr.send(this.payload)}},this.close=function(){this.readyState!==this.CLOSED&&(this.xhr.abort(),this.xhr=null,this._setReadyState(this.CLOSED))},(t.start===void 0||t.start)&&this.stream()};typeof exports<"u"&&(exports.SSE=k);var $e={};function J(e,t){$e[e]=t}function Z(e){return $e[e]}async function X(...e){let t=e.join(""),r=new TextEncoder().encode(t),n=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(n)).map(s=>s.toString(16).padStart(2,"0")).join("")}var N=class{apiKey;baseUrl;name;modelName;requireAuth;constructor(t,r,n,o,i=!0){this.apiKey=t,this.baseUrl=r,this.name=n,this.modelName=o,this.requireAuth=i}async generateEmbeddings(t){let r=await X(this.modelName,t.text),n=Z(r);if(n)return n;let o=await this._generateEmbeddings(t);return J(r,o),o}};var L=class{name;apiKey;baseUrl;modelName;constructor(t,r,n,o){this.name=t,this.apiKey=r,this.baseUrl=n,this.modelName=o}async streamChatIntoEditor(t,r){let{onDataReceived:n}=t,o="\u{1F914} Thinking \u2026 ",i=r??await R();await m.insertAtPos(o,i);let s=!0,c=d=>{try{if(!d){console.log("No data received from LLM");return}s?(["`","-","*"].includes(d.charAt(0))&&(console.log("First character of response is:",d.charAt(0)),d=`
`+d),m.replaceRange(i,i+o.length,d),s=!1):m.insertAtPos(d,i),i+=d.length,n&&n(d)}catch(p){console.error("Error handling chat stream data:",p),m.flashNotification("An error occurred while processing chat data.","error")}};await this.chatWithAI({...t,onDataReceived:c})}async singleMessageChat(t,r){let n=[{role:"user",content:t}];return r&&n.unshift({role:"system",content:r}),await this.chatWithAI({messages:n,stream:!1})}};var ee=class extends L{name="Gemini";constructor(t,r){super("Gemini",t,"https://generativelanguage.googleapis.com",r)}async listModels(){let t=`${this.baseUrl}/v1beta/models?key=${this.apiKey}`;try{let r=await fetch(t);if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return(await r.json()).models||[]}catch(r){throw console.error("Failed to fetch models:",r),r}}async chatWithAI({messages:t,stream:r,onDataReceived:n}){return r?await this.streamChat({messages:t,stream:r,onDataReceived:n}):await this.nonStreamingChat(t)}mapRolesForGemini(t){let r=[],n="";return t.forEach(o=>{let i="user";o.role==="system"||o.role==="user"?i="user":o.role==="assistant"&&(i="model"),i==="model"&&(r.length===0||n==="model")||(i==="user"&&n==="user"?r[r.length-1].parts[0].text+=" "+o.content:r.push({role:i,parts:[{text:o.content}]})),n=i}),r}streamChat(t){let{messages:r,onDataReceived:n}=t;try{let o=`${this.baseUrl}/v1beta/models/${this.modelName}:streamGenerateContent?key=${this.apiKey}&alt=sse`,i={"Content-Type":"application/json"},s=this.mapRolesForGemini(r),c={method:"POST",headers:i,payload:JSON.stringify({contents:s}),withCredentials:!1},d=new k(o,c),p="";d.addEventListener("message",u=>{try{if(u.data=="[DONE]")return d.close(),p;if(!u.data)console.error("Received empty message from Gemini"),console.log("source: ",d);else{let g=JSON.parse(u.data),Ae=g.candidates[0].content.parts[0].text||g.text||"";p+=Ae,n&&n(Ae)}}catch(g){console.error("Error processing message event:",g,u.data)}}),d.addEventListener("end",()=>(d.close(),p)),d.addEventListener("error",u=>{console.error("SSE error:",u),d.close()}),d.stream()}catch(o){throw console.error("Error streaming from Gemini chat endpoint:",o),o}}async nonStreamingChat(t){let r=this.mapRolesForGemini(t),n=await nativeFetch(`${this.baseUrl}/v1beta/models/${this.modelName}:generateContent?key=${this.apiKey}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contents:r})});if(!n.ok)throw new Error(`HTTP error! status: ${n.status}`);return(await n.json()).candidates[0].content.parts[0].text}},te=class extends N{constructor(t,r,n="https://generativelanguage.googleapis.com",o=!0){super(t,n,"Gemini",r,o)}async _generateEmbeddings(t){let r=JSON.stringify({model:this.modelName,content:{parts:[{text:t.text}]}}),n={"Content-Type":"application/json"};this.requireAuth&&(n.Authorization=`Bearer ${this.apiKey}`);let o=await nativeFetch(`${this.baseUrl}/v1beta/models/${this.modelName}:embedContent?key=${this.apiKey}`,{method:"POST",headers:n,body:r});if(!o.ok)throw console.error("HTTP response: ",o),console.error("HTTP response body: ",await o.json()),new Error(`HTTP error, status: ${o.status}`);let i=await o.json();if(!i||!i.embedding||!i.embedding.values)throw new Error("Invalid response from Gemini.");return i.embedding.values}};var re=class extends L{name="OpenAI";requireAuth;constructor(t,r,n,o){super("OpenAI",t,n,r),this.requireAuth=o}async chatWithAI({messages:t,stream:r,onDataReceived:n}){return r?await this.streamChat({messages:t,onDataReceived:n}):await this.nonStreamingChat(t)}async streamChat(t){let{messages:r,onDataReceived:n}=t;try{let o=`${this.baseUrl}/chat/completions`,i={"Content-Type":"application/json"};this.requireAuth&&(i.Authorization=`Bearer ${this.apiKey}`);let s={method:"POST",headers:i,payload:JSON.stringify({model:this.modelName,stream:!0,messages:r}),withCredentials:!1},c=new k(o,s),d="";c.addEventListener("message",function(p){try{if(p.data=="[DONE]")return c.close(),d;{let g=JSON.parse(p.data).choices[0]?.delta?.content||"";d+=g,n&&n(g)}}catch(u){console.error("Error processing message event:",u,p.data)}}),c.addEventListener("end",function(){return c.close(),d}),c.addEventListener("error",p=>{console.error("SSE error:",p),c.close()}),c.stream()}catch(o){throw console.error("Error streaming from OpenAI chat endpoint:",o),await m.flashNotification("Error streaming from OpenAI chat endpoint.","error"),o}return""}async nonStreamingChat(t){try{let r=JSON.stringify({model:this.modelName,messages:t}),n={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},o=await nativeFetch(this.baseUrl+"/chat/completions",{method:"POST",headers:n,body:r});if(!o.ok)throw console.error("http response: ",o),console.error("http response body: ",await o.json()),new Error(`HTTP error, status: ${o.status}`);let i=await o.json();if(!i||!i.choices||i.choices.length===0)throw new Error("Invalid response from OpenAI.");return i.choices[0].message.content}catch(r){throw console.error("Error calling OpenAI chat endpoint:",r),await m.flashNotification("Error calling OpenAI chat endpoint.","error"),r}}},ne=class extends N{constructor(t,r,n,o=!0){super(t,n,"OpenAI",r,o)}async _generateEmbeddings(t){let r=JSON.stringify({model:this.modelName,input:t.text,encoding_format:"float"}),n={"Content-Type":"application/json"};this.requireAuth&&(n.Authorization=`Bearer ${this.apiKey}`);let o=await nativeFetch(`${this.baseUrl}/embeddings`,{method:"POST",headers:n,body:r});if(!o.ok)throw console.error("HTTP response: ",o),console.error("HTTP response body: ",await o.json()),new Error(`HTTP error, status: ${o.status}`);let i=await o.json();if(!i||!i.data||i.data.length===0)throw new Error("Invalid response from OpenAI.");return i.data[0].embedding}};var oe=class extends N{constructor(t,r,n,o=!1){super(t,n,"Ollama",r,o)}async _generateEmbeddings(t){let r=JSON.stringify({model:this.modelName,prompt:t.text}),n={"Content-Type":"application/json"};this.requireAuth&&(n.Authorization=`Bearer ${this.apiKey}`);let o=await nativeFetch(`${this.baseUrl}/api/embeddings`,{method:"POST",headers:n,body:r});if(!o.ok)throw console.error("HTTP response: ",o),console.error("HTTP response body: ",await o.json()),new Error(`HTTP error, status: ${o.status}`);let i=await o.json();if(!i||!i.embedding||i.embedding.length===0)throw new Error("Invalid response from Ollama.");return i.embedding}};var Re=/@(\d+)$/,Le=/\$([a-zA-Z\.\-\/]+[\w\.\-\/]*)$/,je=/#([^#]*)$/;function Ke(e){e.startsWith("[[")&&e.endsWith("]]")&&(e=e.slice(2,-2));let t={page:e},r=t.page.match(Re);r&&(t.pos=parseInt(r[1]),t.page=t.page.replace(Re,""));let n=t.page.match(Le);n&&(t.anchor=n[1],t.page=t.page.replace(Le,""));let o=t.page.match(je);return o&&(t.header=o[1],t.page=t.page.replace(je,"")),t}function qe(e){return le(e,t=>{switch(t.type){case"FrontMatter":return null;case"WikiLink":{let r=M(t,"WikiLinkPage").children[0].text,n=r.split("/").pop(),o=M(t,"WikiLinkAlias");o&&(n=o.children[0].text);let i=Ke(r);return{text:`[${n}](${typeof location<"u"?location.origin:""}/${encodeURI(i.page)})`}}case"NamedAnchor":return null;case"CommandLink":{let n=t.children[1].children[0].text,o=M(t,"CommandLinkAlias");return o&&(n=o.children[0].text),{text:"`"+n+"`"}}case"Attribute":return null}}),e}async function We({name:e,tree:t}){if(await f.getEnv()!=="server")return;await b();let r=["SETTINGS","SECRETS",...l.indexEmbeddingsExcludePages];if(!l.indexEmbeddings||r.includes(e)||e.startsWith("_")||/\.conflicted\.\d+$/.test(e)||!t.children)return;let n=t.children.filter(i=>i.type==="Paragraph"),o=[];for(let i of n){let s=E(i).trim();if(!s||s.length<10||l.indexEmbeddingsExcludeStrings.some(u=>s.includes(u)))continue;let c=await T.generateEmbeddings({text:s}),d=i.from??0,p={ref:`${e}@${d}`,page:e,pos:d,embedding:c,text:s,tag:"embedding"};o.push(p)}await fe(e,o),x("any",`AI: Indexed ${o.length} embedding objects for page ${e}`)}async function De({name:e,tree:t}){if(await f.getEnv()!=="server")return;await b();let r=["SETTINGS","SECRETS",...l.indexEmbeddingsExcludePages];if(!l.indexEmbeddings||!l.indexSummary||r.includes(e)||e.startsWith("_")||!t.children)return;let n=E(t),o=l.textModels.find(g=>g.name===l.indexSummaryModelName);if(!o)throw new Error(`Could not find summary model ${l.indexSummaryModelName}`);let i=await j(o),s;l.promptInstructions.indexSummaryPrompt!==""?s=l.promptInstructions.indexSummaryPrompt:s=`Provide a concise and informative summary of the above page. The summary should capture the key points and be useful for search purposes. Avoid any formatting or extraneous text. No more than one paragraph. Summary:
`;let c=await X(o.name,n,s),d=Z(c);d||(d=await i.singleMessageChat("Contents of "+e+`:
`+n+`
`+s),J(c,d));let p=await T.generateEmbeddings({text:d}),u={ref:`${e}@0`,page:e,embedding:p,text:d,tag:"aiSummary"};await fe(e,[u]),x("any",`AI: Indexed summary for page ${e}`)}async function dn(){return await U("embedding",{})}async function ln(){return await U("aiSummary",{})}function Ge(e,t){let r=e.reduce((i,s,c)=>i+s*t[c],0),n=Math.sqrt(e.reduce((i,s)=>i+s*s,0)),o=Math.sqrt(t.reduce((i,s)=>i+s*s,0));return r/(n*o)}async function pn(e,t=10){await b();let r=await T.generateEmbeddings({text:e}),o=(await dn()).map(i=>({page:i.page,ref:i.ref,text:i.text,similarity:Ge(r,i.embedding)}));if(l.indexSummary){let s=(await ln()).map(c=>({page:c.page,ref:c.ref,text:`Page Summary: ${c.text}`,similarity:Ge(r,c.embedding)}));o.push(...s)}return o.sort((i,s)=>s.similarity-i.similarity).slice(0,t)}async function ie(e,t=10,r=.15){let n=await pn(e,-1),o={};for(let s of n)s.similarity<r||(o[s.page]?(o[s.page].score+=s.similarity,o[s.page].children.push(s)):o[s.page]={page:s.page,score:s.similarity,children:[s]});for(let s in o)o[s].children=o[s].children.sort((c,d)=>d.similarity-c.similarity).slice(0,t);return Object.values(o).sort((s,c)=>c.score-s.score).slice(0,t)}async function Be(){let e=await m.prompt("Enter some text to search for:");if(!e){await m.flashNotification("No text entered.","error");return}let t=await ie(e);await m.flashNotification(`Found ${t.length} results`),x("any","AI: Search results",t)}var _e="\u{1F916} ";async function se(e){let t=e.substring(_e.length,e.length-3),r=await ie(t);x("client","AI: Embedding search results",r);let n=`# Embedding search results for "${t}"
`;l.indexEmbeddings||(n+=`> **warning** Embeddings generation is disabled.
`,n+=`> You can enable it in the AI settings.
`);for(let o of r){n+=`* [[${o.page}]] (score ${o.score})
`;for(let i of o.children)n+=` * [[${i.ref}]] (similarity ${i.similarity})
`,n+=` > ${i.text}
`}return{data:new TextEncoder().encode(n),meta:{name:e,contentType:"text/markdown",size:n.length,created:0,lastModified:0,perm:"ro"}}}function He(e){return{name:e,contentType:"text/markdown",size:-1,created:0,lastModified:0,perm:"ro"}}async function Ve(){let e=await m.prompt("Search for: ");e&&await m.navigate({page:`${_e}${e}`})}function ze(e){return e.split("/").slice(0,-1).join("/")}async function x(e,...t){(await f.getEnv()===e||e==="any")&&console.log(...t)}async function Ye(){let t=(await m.getText()).split(`
`),r=[],n="user",o="";return t.forEach(i=>{if(i.trim()==="")return;let s=i.match(/^\*\*(\w+)\*\*:/);if(s){let c=s[1].toLowerCase();n&&n!==c&&o.trim()!==""&&(r.push({role:n,content:o.trim()}),o=""),n=c,o+=i.replace(/^\*\*(\w+)\*\*:/,"").trim()+`
`}else n&&(o+=i.trim()+`
`)}),o&&n&&r.push({role:n,content:o.trim()}),r}async function Qe(){try{let e=await syscall("system.getVersion"),[t,r,n]=e.split(".").map(Number),[o,i,s]="0.7.2".split(".").map(Number);return t>o||t===o&&r>i||t===o&&r===i&&n>=s}catch{return!1}}async function he(e){let t=[];for(let r of e){let n=r.content;if(r.role==="assistant"){t.push(r);continue}if(l.chat.searchEmbeddings&&l.indexEmbeddings){let c=await ie(n);if(c.length>0){n+=`
The following pages were found to be relevant to the question. You can use them as context to answer the question.
`;for(let d of c)n+=`* [[${d.page}]] (similarity score ${d.score})
`}}if(l.chat.parseWikiLinks&&(n=await un(n)),l.chat.bakeMessages){let c=await S.parseMarkdown(n),d=await f.invokeFunction("markdown.expandCodeWidgets",c,"");n=E(qe(d)).trim()}let i=(await O.dispatchEvent("ai:enrichMessage",{enrichedContent:n,message:r})).flat().concat(l.chat.customEnrichFunctions),s=[...new Set(i)];console.log("Received custom enrich message functions",s);for(let c of s)n=await f.invokeSpaceFunction(c,n);t.push({...r,content:n})}return t}async function un(e){let t=[],r=e,n=/\[\[([^\]]+)\]\]/g,o,i=!1;for(;(o=n.exec(e))!==null;){let s=o[1];if(!t.includes(s)){i||(r+=`
Base your answer on the content of the following referenced pages (referenced above using the >>page name<< format). In these listings ~~~ is used to mark the page's content start and end. If context is missing, always ask me to link directly to a page mentioned in the context.`,i=!0);try{let c=await w.readPage(s);t.push(s),r+=`
Content of the [[${s}]] page:
~~~
${c}
~~~
`}catch(c){console.error(`Error fetching page '${s}':`,c)}}}return r=r.replace(n,">>$1<<"),r}var y,l,K,P,xe,T,ye,gn,fn;async function b(){let e=await Je();(!y||!P||!l||!ye||JSON.stringify(e)!==JSON.stringify(ye))&&await I(!0)}async function Je(){if(await f.getEnv()=="client")try{return await C.get("ai.selectedTextModel")}catch{return}}async function hn(){if(await f.getEnv()=="client")try{return await C.get("ai.selectedImageModel")}catch{return}}async function yn(){if(await f.getEnv()=="client")try{return await C.get("ai.selectedEmbeddingModel")}catch{return}}async function be(e){await f.getEnv()=="client"&&await C.set("ai.selectedImageModel",e)}async function we(e){await f.getEnv()=="client"&&await C.set("ai.selectedTextModel",e)}async function Pe(e){await f.getEnv()=="client"&&await C.set("ai.selectedEmbeddingModel",e)}async function xn(){let e=await Je()||l.textModels[0];if(!e)throw new Error("No text model selected or available as default.");await j(e)}async function bn(){let e=await hn()||l.imageModels[0];if(!e)throw new Error("No image model selected or available as default.");await Ee(e)}async function wn(){let e=await yn()||l.embeddingModels[0];if(!e)throw new Error("No embedding model selected or available as default.");await Se(e)}function Pn(e){let t=e.provider.toLowerCase();switch(x("client","Provider name",t),t){case"dalle":xe=new Q(y,e.modelName,e.baseUrl||l.dallEBaseUrl);break;default:throw new Error(`Unsupported image provider: ${e.provider}. Please configure a supported provider.`)}}function En(e){switch(e.provider.toLowerCase()){case"openai":P=new re(y,e.modelName,e.baseUrl||l.openAIBaseUrl,e.requireAuth||l.requireAuth);break;case"gemini":P=new ee(y,e.modelName);break;default:throw new Error(`Unsupported AI provider: ${e.provider}. Please configure a supported provider.`)}return P}function Sn(e){switch(e.provider.toLowerCase()){case"openai":T=new ne(y,e.modelName,e.baseUrl||l.openAIBaseUrl);break;case"gemini":T=new te(y,e.modelName);break;case"ollama":T=new oe(y,e.modelName,e.baseUrl||"http://localhost:11434",e.requireAuth);break;default:throw new Error(`Unsupported embedding provider: ${e.provider}. Please configure a supported provider.`)}}async function j(e){if(x("client","configureSelectedModel called with:",e),!e)throw new Error("No model provided to configure");if(e.requireAuth=e.requireAuth??l.requireAuth,e.requireAuth){let t=await z(e.secretName||"OPENAI_API_KEY");t!==y&&(y=t,x("client","API key updated"))}if(e.requireAuth&&!y)throw new Error("AI API key is missing. Please set it in the secrets page.");return ye=e,En(e)}async function Ee(e){if(x("client","configureSelectedImageModel called with:",e),!e)throw new Error("No image model provided to configure");if(e.requireAuth){let t=await z(e.secretName||"OPENAI_API_KEY");t!==y&&(y=t,x("client","API key updated for image model"))}if(e.requireAuth&&!y)throw new Error("AI API key is missing for image model. Please set it in the secrets page.");gn=e,Pn(e)}async function Se(e){if(x("client","configureSelectedEmbeddingModel called with:",e),!e)throw new Error("No embedding model provided to configure");if(e.requireAuth){let t=await z(e.secretName||"OPENAI_API_KEY");t!==y&&(y=t,x("client","API key updated for embedding model"))}if(e.requireAuth&&!y)throw new Error("AI API key is missing for embedding model. Please set it in the secrets page.");fn=e,Sn(e)}async function An(){let e={openAIBaseUrl:"https://api.openai.com/v1",dallEBaseUrl:"https://api.openai.com/v1",requireAuth:!0,secretName:"OPENAI_API_KEY",provider:"OpenAI",chat:{},promptInstructions:{},imageModels:[],embeddingModels:[],textModels:[],indexEmbeddings:!1,indexSummary:!1,indexSummaryModelName:"",indexEmbeddingsExcludePages:[],indexEmbeddingsExcludeStrings:["**user**:"]},t={userInformation:"",userInstructions:"",parseWikiLinks:!0,bakeMessages:!0,customEnrichFunctions:[],searchEmbeddings:!0},r={pageRenameSystem:"",pageRenameRules:"",tagRules:"",indexSummaryPrompt:""},n=await Fe("ai",{}),o={...e,...n};return o.chat={...t,...n.chat||{}},o.promptInstructions={...r,...n.promptInstructions||{}},o}async function I(e=!0){let t=await An();!l||JSON.stringify(l)!==JSON.stringify(t)?(x("client","aiSettings updating from",l),l=t,x("client","aiSettings updated to",l)):x("client","aiSettings unchanged",l),l.textModels.length===1&&await we(l.textModels[0]),l.imageModels.length===1&&await be(l.imageModels[0]),l.embeddingModels.length===1&&await Pe(l.embeddingModels[0]),e&&(l.textModels.length>0&&await xn(),l.imageModels.length>0&&await bn(),l.embeddingModels.length>0&&await wn()),K={role:"system",content:"This is an interactive chat session with a user in a markdown-based note-taking tool called SilverBullet."},l.chat.userInformation&&(K.content+=`
The user has provided the following information about themselves: ${l.chat.userInformation}`),l.chat.userInstructions&&(K.content+=`
The user has provided the following instructions for the chat, follow them as closely as possible: ${l.chat.userInstructions}`)}async function Ze(e){return Qe()?{options:(await U("template",{filter:["attr",["attr","aiprompt"],"slashCommand"]},5)).map(r=>{let n=r.aiprompt;return console.log("ai prompt template: ",n),{label:n.slashCommand,detail:n.description||r.description,order:n.order||0,templatePage:r.ref,pageName:e.pageName,invoke:"silverbullet-ai.insertAiPromptFromTemplate"}})}:void 0}async function Xe(e){let t;if(!e||!e.templatePage){let p=await U("template",{filter:["attr",["attr","aiprompt"],"description"]});t=await m.filterBox("Prompt Template",p.map(u=>{let g=u.ref.split("/").pop();return{...u,description:u.aiprompt.description||u.ref,name:u.aiprompt.displayName||g,systemPrompt:u.aiprompt.systemPrompt||"You are an AI note assistant. Please follow the prompt instructions.",insertAt:u.aiprompt.insertAt||"cursor"}}),"Select the template to use as the prompt. The prompt will be rendered and sent to the LLM model.")}else{console.log("selectedTemplate from slash completion: ",e);let p=await w.readPage(e.templatePage),u=await S.parseMarkdown(p),{aiprompt:g}=await $(u);console.log("templatePage from slash completion: ",p),t={ref:e.templatePage,systemPrompt:g.systemPrompt||g.system||"You are an AI note assistant. Please follow the prompt instructions.",insertAt:g.insertAt||"cursor"}}if(!t){await m.flashNotification("No template selected");return}console.log("User selected prompt template: ",t);let r=["cursor","page-start","page-end"];if(!r.includes(t.insertAt)){console.error(`Invalid insertAt value: ${t.insertAt}. It must be one of ${r.join(", ")}`),await m.flashNotification(`Invalid insertAt value: ${t.insertAt}. Please select a valid option.`,"error");return}await b();let n,o,i;try{n=await w.readPage(t.ref),o=await m.getCurrentPage(),i=await w.getPageMeta(o)}catch(p){console.error("Error fetching template details or page metadata",p),await m.flashNotification("Error fetching template details or page metadata","error");return}let s;switch(t.insertAt){case"page-start":s=0;break;case"page-end":s=await R();break;case"frontmatter":await m.flashNotification("rendering in frontmatter not supported yet","error");break;case"modal":break;case"replace":break;case"cursor":default:s=await m.getCursor()}console.log("templatetext: ",n);let c=await ke(n,i,{page:i});console.log("Rendered template:",c);let d=[{role:"user",content:c.text}];t.systemPrompt&&d.unshift({role:"system",content:t.systemPrompt}),await P.streamChatIntoEditor({messages:d,stream:!0},s)}function et(e){let t={querySource:""},[r,n,...o]=e;if(r!=="Query")throw new Error(`Expected query type, got ${r}`);t.querySource=n[1];for(let i of o){let[s]=i;switch(s){case"WhereClause":{t.filter?t.filter=["and",t.filter,h(i[2])]:t.filter=h(i[2]);break}case"OrderClause":{t.orderBy||(t.orderBy=[]);for(let c of i.slice(2))if(c[0]==="OrderBy"){let d=c[1][1];c[2]?t.orderBy.push({expr:h(d),desc:c[2][1][1]==="desc"}):t.orderBy.push({expr:h(d),desc:!1})}break}case"LimitClause":{t.limit=h(i[2][1]);break}case"SelectClause":{for(let c of i.slice(2))c[0]==="Select"&&(t.select||(t.select=[]),c.length===2?t.select.push({name:q(c[1][1])}):t.select.push({name:q(c[3][1]),expr:h(c[1])}));break}case"RenderClause":{let c=i.find(d=>d[0]==="PageRef");t.render=c[1].slice(2,-2),t.renderAll=!!i.find(d=>d[0]==="all");break}default:throw new Error(`Unknown clause type: ${s}`)}}return t}function q(e){return e.startsWith("`")&&e.endsWith("`")?e.slice(1,-1):e}function h(e){if(["LVal","Expression","Value"].includes(e[0]))return h(e[1]);switch(e[0]){case"Attribute":return["attr",h(e[1]),q(e[3][1])];case"Identifier":return["attr",q(e[1])];case"String":return["string",e[1].slice(1,-1)];case"Number":return["number",+e[1]];case"Bool":return["boolean",e[1][1]==="true"];case"null":return["null"];case"Regex":return["regexp",e[1].slice(1,-1),"i"];case"List":{let t=[];for(let r of e.slice(2))r[0]==="Expression"&&t.push(r);return["array",t.map(h)]}case"Object":{let t=[];for(let r of e.slice(2)){if(typeof r=="string")continue;let[n,o,i,s]=r;t.push([o[1].slice(1,-1),h(s)])}return["object",t]}case"BinExpression":{let t=h(e[1]),r=e[2][0]==="InKW"?"in":e[2].trim(),n=h(e[3]);return[r,t,n]}case"LogicalExpression":{let t=h(e[1]),r=e[2],n=h(e[3]);return[r[1],t,n]}case"ParenthesizedExpression":return h(e[2]);case"Call":{let t=q(e[1][1]),r=[];for(let n of e.slice(2))n[0]==="Expression"&&r.push(n);return["call",t,r.map(h)]}case"UnaryExpression":{if(e[1][0]==="NotKW"||e[1][0]==="!")return["not",h(e[2])];if(e[1][0]==="-")return["-",h(e[2])];throw new Error(`Unknown unary expression: ${e[1][0]}`)}case"TopLevelVal":return["attr"];case"GlobalIdentifier":return["global",e[1].substring(1)];case"TernaryExpression":{let[t,r,n,o,i,s]=e;return["?",h(r),h(o),h(s)]}case"QueryExpression":return["query",et(e[2])];case"PageRef":return["pageref",e[1].slice(2,-2)];default:throw new Error(`Not supported: ${e[0]}`)}}async function tt(e){let t=ge(await B.parseLanguage("query",e));return et(t[1])}async function rt(e,t){let r=await tt(e);return vn(r,t)}async function vn(e,t){e.limit||(e.limit=["number",1e3]);let r=`query:${e.querySource}`,n={query:e};t&&(n.variables=t);let o=await O.dispatchEvent(r,n,30*1e3);if(o.length===0)throw new Error(`Unsupported query source '${e.querySource}'`);return o.flat()}var Qi=new TextEncoder;function nt(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o<r;o++)n[o]=t.charCodeAt(o);return n}async function ot(e){(e==="SETTINGS"||e==="SECRETS")&&await I(!0)}async function it(){(!l||!l.textModels)&&await I(!1);let e=l.textModels.map(n=>({...n,name:n.name,description:n.description||`${n.modelName} on ${n.provider}`})),t=await m.filterBox("Select a model",e);if(!t){await m.flashNotification("No model selected.","error");return}let r=t.name;await we(t),await j(t),await m.flashNotification(`Selected model: ${r}`),console.log("Selected model:",t)}async function st(){(!l||!l.imageModels)&&await I(!1);let e=l.imageModels.map(n=>({...n,name:n.name,description:n.description||`${n.modelName} on ${n.provider}`})),t=await m.filterBox("Select an image model",e);if(!t){await m.flashNotification("No image model selected.","error");return}let r=t.name;await be(t),await Ee(t),await m.flashNotification(`Selected image model: ${r}`),console.log("Selected image model:",t)}async function at(){(!l||!l.embeddingModels)&&await I(!1);let e=l.embeddingModels.map(n=>({...n,name:n.name,description:n.description||`${n.modelName} on ${n.provider}`})),t=await m.filterBox("Select an embedding model",e);if(!t){await m.flashNotification("No embedding model selected.","error");return}let r=t.name;await Pe(t),await Se(t),await m.flashNotification(`Selected embedding model: ${r}`),console.log("Selected embedding model:",t)}async function ct(){await b();let e=await H(),t=await m.prompt("Please enter a prompt to send to the LLM. Selected text or the entire note will also be sent as context."),r=await m.getCurrentPage(),n=new Date,o=n.toISOString().split("T")[0],i=n.toLocaleDateString("en-US",{weekday:"long"});await P.streamChatIntoEditor({messages:[{role:"system",content:"You are an AI note assistant. Follow all user instructions and use the note context and note content to help follow those instructions. Use Markdown for any formatting."},{role:"user",content:`Note Context: Today is ${i}, ${o}. The current note name is "${r}".
User Prompt: ${t}
Note Content:
${e.text}`}],stream:!0},e.to)}async function mt(){await b();let e=await H();if(console.log("selectedTextInfo",e),e.text.length>0){let t=await m.getCurrentPage(),r=await P.chatWithAI({messages:[{role:"user",content:`Please summarize this note using markdown for any formatting. Your summary will be appended to the end of this note, do not include any of the note contents yourself. Keep the summary brief. The note name is ${t}.
${e.text}`}],stream:!1});return console.log("OpenAI response:",r),{summary:r,selectedTextInfo:e}}return{summary:"",selectedTextInfo:null}}async function dt(){let{summary:e,selectedTextInfo:t}=await mt();e&&t&&await m.insertAtPos(`
`+e,t.to)}async function lt(){let{summary:e}=await mt();e?await m.showPanel("rhs",2,e):await m.flashNotification("No summary available.")}async function pt(){await b();let e=await m.getText(),t=await m.getCurrentPage(),r=(await rt("tag select name where parent = 'page' order by name")).map(p=>p.name);console.log("All tags:",r);let o=(await P.chatWithAI({messages:[{role:"system",content:`You are an AI tagging assistant. Please provide a short list of tags, separated by spaces. Follow these guidelines:
- Only return tags and no other content.
- Tags must be one word only and in lowercase.
- Use existing tags as a starting point.
- Suggest tags sparingly, treating them as thematic descriptors rather than keywords.
The following tags are currently being used by other notes:
${r.join(", ")}
Always follow the below rules, if any, given by the user:
${l.promptInstructions.tagRules}`},{role:"user",content:`Page Title: ${t}
Page Content:
${e}`}],stream:!1})).trim().replace(/,/g,"").split(/\s+/),i=await S.parseMarkdown(e),s=await $(i),c=[...new Set([...s.tags||[],...o])];s.tags=c,console.log("Current frontmatter:",s);let d=await Ie(i,s);console.log("updatedNoteContent",d),await m.dispatch(d),await m.flashNotification("Note tagged successfully.")}async function ut(){await b();let e=await m.getText(),t=await m.getCurrentPage(),r=[{name:"Generating suggestions...",description:""}];m.filterBox("Loading...",r,"Retrieving suggestions from LLM provider.").then(g=>{console.log("Selected option (initial):",g)});let o="";l.promptInstructions.pageRenameSystem?o=l.promptInstructions.pageRenameSystem:o=`You are an AI note-naming assistant. Your task is to suggest three to five possible names for the provided note content. Please adhere to the following guidelines:
- Provide each name on a new line.
- Use only spaces, forward slashes (as folder separators), and hyphens as special characters.
- Ensure the names are concise, descriptive, and relevant to the content.
- Avoid suggesting the same name as the current note.
- Include as much detail as possible within 3 to 10 words.
- Start names with ASCII characters only.
- Do not use markdown or any other formatting in your response.`;let i=[{role:"system",content:`${o}
Always follow the below rules, if any, given by the user:
${l.promptInstructions.pageRenameRules}`},{role:"user",content:`Current Page Title: ${t}
Page Content:
${e}`}],s=await he(i);console.log("enrichedMessages",s);let d=(await P.chatWithAI({messages:s,stream:!1})).trim().split(`
`).filter(g=>g.trim()!=="").map(g=>g.replace(/^[*-]\s*/,"").trim());d.length===0&&await m.flashNotification("No suggestions available.");let p=await m.filterBox("New page name",d.map(g=>({name:g})),"Select a new page name from one of the suggestions below.");if(!p){await m.flashNotification("No page name selected.","error");return}console.log("selectedSuggestion",p);let u=await f.invokeFunction("index.renamePageCommand",{oldPage:t,page:p.name});console.log("renamedPage",u),u||await m.flashNotification("Error renaming page.","error")}async function gt(){let e=await H(),t=e.to;await P.streamChatIntoEditor({messages:[{role:"system",content:"You are an AI note assistant in a markdown-based note tool."},{role:"user",content:e.text}],stream:!0},t)}async function ft(){await b();let e=await Ye();if(e.length===0){await m.flashNotification("Error: The page does not match the required format for a chat.");return}e.unshift(K);let t=await he(e);console.log("enrichedMessages",t);let r=await R();await m.insertAtPos(`
**assistant**: `,r),r+=17,await m.insertAtPos(`
**user**: `,r),await m.moveCursor(r+12);try{await P.streamChatIntoEditor({messages:t,stream:!0},r)}catch(n){console.error("Error streaming chat on page:",n),await m.flashNotification("Error streaming chat on page.","error")}}async function ht(){if(await b(),!l.imageModels||l.imageModels.length===0){await m.flashNotification("No image models available.","error");return}try{let e=await m.prompt("Enter a prompt for DALL\xB7E:");if(!e||!e.trim()){await m.flashNotification("No prompt entered. Operation cancelled.","error");return}let t={prompt:e,numImages:1,size:"1024x1024",quality:"hd"},r=await xe.generateImage(t);if(r&&r.data&&r.data.length>0){let n=r.data[0].b64_json,o=r.data[0].revised_prompt,i=new Uint8Array(nt(n)),s=`dall-e-${Date.now()}.png`,c=ze(await m.getCurrentPage())+"/";c==="/"&&(c=""),await w.writeAttachment(c+s,i);let d=`
*${o}*`;await m.insertAtCursor(d),await m.flashNotification("Image generated and inserted with caption successfully.")}else await m.flashNotification("Failed to generate image.","error")}catch(e){console.error("Error generating image with DALL\xB7E:",e),await m.flashNotification("Error generating image.","error")}}async function yt(e,t){try{return await b(),await P.singleMessageChat(e,t||"You are an AI note assistant helping to render content for a note. Please follow user instructions and keep your response short and concise.")}catch(r){throw console.error("Error querying OpenAI:",r),r}}async function xt(){await b();let e=await m.prompt("Enter some text to embed:");if(!e){await m.flashNotification("No text entered.","error");return}let t=await T.generateEmbeddings({text:e});await m.insertAtCursor(`
Embedding: ${t}`)}var bt={aiPromptSlashCommplete:Ze,queryAI:yt,reloadConfig:ot,summarizeNote:lt,insertSummary:dt,callOpenAI:ct,tagNoteWithAI:pt,promptAndGenerateImage:ht,streamOpenAIWithSelectionAsPrompt:gt,streamChatOnPage:ft,insertAiPromptFromTemplate:Xe,suggestPageName:ut,selectTextModel:it,selectImageModel:st,selectEmbeddingModel:at,testEmbeddingGeneration:xt,indexEmbeddings:We,indexSummaryEmbeddings:De,debugSearchEmbeddings:Be,readPageSearchEmbeddings:se,writePageSearchEmbeddings:se,getPageMetaSearchEmbeddings:He,searchCommand:Ve},wt={name:"silverbullet-ai",requiredPermissions:["fetch"],functions:{aiPromptSlashCommplete:{path:"src/prompts.ts:aiPromptSlashComplete",events:["slash:complete"]},queryAI:{path:"sbai.ts:queryAI"},reloadConfig:{path:"sbai.ts:reloadConfig",events:["page:saved"]},summarizeNote:{path:"sbai.ts:openSummaryPanel",command:{name:"AI: Summarize Note and open summary"}},insertSummary:{path:"sbai.ts:insertSummary",command:{name:"AI: Insert Summary"}},callOpenAI:{path:"sbai.ts:callOpenAIwithNote",command:{name:"AI: Call OpenAI with Note as context"}},tagNoteWithAI:{path:"sbai.ts:tagNoteWithAI",command:{name:"AI: Generate tags for note"}},promptAndGenerateImage:{path:"sbai.ts:promptAndGenerateImage",command:{name:"AI: Generate and insert image using DallE"}},streamOpenAIWithSelectionAsPrompt:{path:"sbai.ts:streamOpenAIWithSelectionAsPrompt",command:{name:"AI: Stream response with selection or note as prompt"}},streamChatOnPage:{path:"sbai.ts:streamChatOnPage",command:{name:"AI: Chat on current page",key:"Ctrl-Shift-Enter",mac:"Cmd-Shift-Enter"}},insertAiPromptFromTemplate:{path:"src/prompts.ts:insertAiPromptFromTemplate",command:{name:"AI: Execute AI Prompt from Custom Template"}},suggestPageName:{path:"sbai.ts:suggestPageName",command:{name:"AI: Suggest Page Name"}},selectTextModel:{path:"sbai.ts:selectModelFromConfig",command:{name:"AI: Select Text Model from Config"}},selectImageModel:{path:"sbai.ts:selectImageModelFromConfig",command:{name:"AI: Select Image Model from Config"}},selectEmbeddingModel:{path:"sbai.ts:selectEmbeddingModelFromConfig",command:{name:"AI: Select Embedding Model from Config"}},testEmbeddingGeneration:{path:"sbai.ts:testEmbeddingGeneration",command:{name:"AI: Test Embedding Generation"}},indexEmbeddings:{path:"src/embeddings.ts:indexEmbeddings",env:"server",events:["page:index"]},indexSummaryEmbeddings:{path:"src/embeddings.ts:indexSummary",env:"server",events:["page:index"]},debugSearchEmbeddings:{path:"src/embeddings.ts:debugSearchEmbeddings",command:{name:"AI: Debug Search Embeddings"}},readPageSearchEmbeddings:{path:"src/embeddings.ts:readFileEmbeddings",env:"server",pageNamespace:{pattern:"\u{1F916} .+",operation:"readFile"}},writePageSearchEmbeddings:{path:"src/embeddings.ts:readFileEmbeddings",env:"server",pageNamespace:{pattern:"\u{1F916} .+",operation:"readFile"}},getPageMetaSearchEmbeddings:{path:"src/embeddings.ts:getFileMetaEmbeddings",env:"server",pageNamespace:{pattern:"\u{1F916} .+",operation:"getFileMeta"}},searchCommand:{path:"src/embeddings.ts:searchCommand",env:"server",command:{name:"AI: Search"}}},assets:{}},Fs={manifest:wt,functionMapping:bt};ve(bt,wt);export{Fs as plug};