From 00257fba914972fea0ee212d1627b66d2f62fef7 Mon Sep 17 00:00:00 2001 From: Justyn Shull Date: Thu, 22 Feb 2024 02:07:59 -0600 Subject: [PATCH] Move cursor to follow streaming response, build 0.0.5 bundle --- silverbullet-ai.plug.js | 38 ++++++++++++++++++-------------------- src/openai.ts | 1 + 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/silverbullet-ai.plug.js b/silverbullet-ai.plug.js index bc8c537..8d3a52d 100644 --- a/silverbullet-ai.plug.js +++ b/silverbullet-ai.plug.js @@ -1,27 +1,25 @@ -var oe=Object.defineProperty;var P=(e,t)=>{for(var r in t)oe(e,r,{get:t[r],enumerable:!0})};var I=typeof window>"u"&&typeof globalThis.WebSocketPair>"u";typeof Deno>"u"&&(self.Deno={args:[],build:{arch:"x86_64"},env:{get(){}}});var C=new Map,E=0;function w(e){self.postMessage(e)}I&&(globalThis.syscall=async(e,...t)=>await new Promise((r,n)=>{E++,C.set(E,{resolve:r,reject:n}),w({type:"sys",id:E,name:e,args:t})}));function R(e,t){I&&(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||[]));w({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),w({type:"invr",id:n.id,error:i.message})}}break;case"sysr":{let o=n.id,i=C.get(o);if(!i)throw Error("Invalid request id");C.delete(o),n.error?i.reject(new Error(n.error)):i.resolve(n.result)}break}})().catch(console.error)}),w({type:"manifest",manifest:t}))}function se(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o0?W(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 ae(){globalThis.fetch=async function(e,t){let r=t&&t.body?W(new Uint8Array(await new Response(t.body).arrayBuffer())):void 0,n=await ie(e,t&&{method:t.method,headers:t.headers,base64Body:r});return new Response(n.base64Body?se(n.base64Body):null,{status:n.status,headers:n.headers})}}I&&ae();var Mt=new TextEncoder;function D(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o0&&this.dispatchEvent(this._parseEventChunk(a))}.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 a=i.indexOf(this.FIELD_SEPARATOR),l,u;if(a>0){var x=i[a+1]===" "?2:1;l=i.substring(0,a),u=i.substring(a+x)}else if(a<0)l=i,u="";else return;l in n&&(l==="data"&&n[l]!==null?n.data+=` -`+u:n[l]=u)}.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=y);function N(e){if(e.children)for(let t of e.children){if(t.parent)return;t.parent=e,N(t)}}function O(e,t){if(t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...O(n,t)];return r}async function $(e,t){if(await t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...await $(n,t)];return r}async function M(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 M(n,t)}}}function k(e,t){return O(e,r=>r.type===t)[0]}function B(e,t){O(e,t)}async function _(e,t){await $(e,t)}function A(e){if(!e)return"";let t=[];if(e.text!==void 0)return e.text;for(let r of e.children)t.push(A(r));return t.join("")}var c={};P(c,{confirm:()=>Re,dispatch:()=>Le,downloadFile:()=>ve,filterBox:()=>Ce,flashNotification:()=>Ee,fold:()=>Be,foldAll:()=>je,getCurrentPage:()=>ce,getCursor:()=>fe,getSelection:()=>me,getText:()=>ue,getUiOption:()=>We,goHistory:()=>Se,hidePanel:()=>Ne,insertAtCursor:()=>Fe,insertAtPos:()=>Oe,moveCursor:()=>ke,navigate:()=>ge,openCommandPalette:()=>xe,openPageNavigator:()=>ye,openSearchPanel:()=>Ye,openUrl:()=>Te,prompt:()=>Ue,reloadPage:()=>Pe,reloadSettingsAndCommands:()=>Ae,reloadUI:()=>we,replaceRange:()=>Me,save:()=>he,setPage:()=>le,setSelection:()=>pe,setText:()=>de,setUiOption:()=>De,showPanel:()=>Ie,toggleFold:()=>Ke,unfold:()=>_e,unfoldAll:()=>Ge,uploadFile:()=>be,vimEx:()=>$e});typeof self>"u"&&(self={syscall:()=>{throw new Error("Not implemented here")}});var s=self.syscall;function ce(){return s("editor.getCurrentPage")}function le(e){return s("editor.setPage",e)}function ue(){return s("editor.getText")}function de(e){return s("editor.setText",e)}function fe(){return s("editor.getCursor")}function me(){return s("editor.getSelection")}function pe(e,t){return s("editor.setSelection",e,t)}function he(){return s("editor.save")}function ge(e,t=!1,r=!1){return s("editor.navigate",e,t,r)}function ye(e="page"){return s("editor.openPageNavigator",e)}function xe(){return s("editor.openCommandPalette")}function Pe(){return s("editor.reloadPage")}function we(){return s("editor.reloadUI")}function Ae(){return s("editor.reloadSettingsAndCommands")}function Te(e,t=!1){return s("editor.openUrl",e,t)}function Se(e){return s("editor.goHistory",e)}function ve(e,t){return s("editor.downloadFile",e,t)}function be(e,t){return s("editor.uploadFile",e,t)}function Ee(e,t="info"){return s("editor.flashNotification",e,t)}function Ce(e,t,r="",n=""){return s("editor.filterBox",e,t,r,n)}function Ie(e,t,r,n=""){return s("editor.showPanel",e,t,r,n)}function Ne(e){return s("editor.hidePanel",e)}function Oe(e,t){return s("editor.insertAtPos",e,t)}function Me(e,t,r){return s("editor.replaceRange",e,t,r)}function ke(e,t=!1){return s("editor.moveCursor",e,t)}function Fe(e){return s("editor.insertAtCursor",e)}function Le(e){return s("editor.dispatch",e)}function Ue(e,t=""){return s("editor.prompt",e,t)}function Re(e){return s("editor.confirm",e)}function We(e){return s("editor.getUiOption",e)}function De(e,t){return s("editor.setUiOption",e,t)}function $e(e){return s("editor.vimEx",e)}function Be(){return s("editor.fold")}function _e(){return s("editor.unfold")}function Ke(){return s("editor.toggleFold")}function je(){return s("editor.foldAll")}function Ge(){return s("editor.unfoldAll")}function Ye(){return s("editor.openSearchPanel")}var g={};P(g,{parseMarkdown:()=>qe});function qe(e){return s("markdown.parseMarkdown",e)}var h={};P(h,{deleteAttachment:()=>nt,deleteFile:()=>ct,deletePage:()=>Ve,getAttachmentMeta:()=>et,getFileMeta:()=>it,getPageMeta:()=>He,listAttachments:()=>Ze,listFiles:()=>ot,listPages:()=>ze,listPlugs:()=>Xe,readAttachment:()=>tt,readFile:()=>st,readPage:()=>Qe,writeAttachment:()=>rt,writeFile:()=>at,writePage:()=>Je});function ze(e=!1){return s("space.listPages",e)}function He(e){return s("space.getPageMeta",e)}function Qe(e){return s("space.readPage",e)}function Je(e,t){return s("space.writePage",e,t)}function Ve(e){return s("space.deletePage",e)}function Xe(){return s("space.listPlugs")}function Ze(){return s("space.listAttachments")}function et(e){return s("space.getAttachmentMeta",e)}function tt(e){return s("space.readAttachment",e)}function rt(e,t){return s("space.writeAttachment",e,t)}function nt(e){return s("space.deleteAttachment",e)}function ot(){return s("space.listFiles")}function st(e){return s("space.readFile",e)}function it(e){return s("space.getFileMeta",e)}function at(e,t){return s("space.writeFile",e,t)}function ct(e){return s("space.deleteFile",e)}var m=globalThis.syscall;var d={};P(d,{parse:()=>Pt,stringify:()=>wt});function Pt(e){return m("yaml.parse",e)}function wt(e){return m("yaml.stringify",e)}async function St(e,t){let r=await h.readPage(e),n=await g.parseMarkdown(r),o;return B(n,i=>{if(i.type!=="FencedCode")return!1;let a=k(i,"CodeInfo");if(t&&!a||t&&!t.includes(a.children[0].text))return!1;let l=k(i,"CodeText");return l?(o=l.children[0].text,!0):!1}),o}async function T(e,t=["yaml"]){let r=await St(e,t);if(r!==void 0)try{return d.parse(r)}catch(n){throw console.error("YAML Page parser error",n),new Error(`YAML Error: ${n.message}`)}}var vt="SETTINGS";async function K(e,t){try{let n=(await T(vt,["yaml"])||{})[e];return n===void 0?t:n}catch(r){if(r.message==="Not found")return t;throw r}}async function j(e){try{let r=(await T("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}}function S(e){if(!e||typeof e!="object")return e;if(Array.isArray(e))return e.map(S);let t={};for(let r of Object.keys(e)){let n=r.split("."),o=t;for(let i=0;i{if(o.type==="Paragraph"&&o.parent?.type==="Document"){let i=!0,a=new Set;for(let l of o.children)if(l.text){if(l.text.startsWith(` -`)&&l.text!==` -`)break;if(l.text.trim()){i=!1;break}}else if(l.type==="Hashtag"){let u=l.children[0].text.substring(1);a.add(u),(t.removeTags===!0||t.removeTags?.includes(u))&&(l.children[0].text="")}else if(l.type){i=!1;break}i&&n.push(...a)}if(o.type==="FrontMatter"){let i=o.children[1].children[0],a=A(i);try{let l=await d.parse(a),u={...l};if(r={...r,...l},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 x=!1;for(let U of t.removeKeys)U in u&&(delete u[U],x=!0);x&&(i.text=await d.stringify(u))}if(Object.keys(u).length===0||t.removeFrontmatterSection)return null}catch(l){console.warn("Could not parse frontmatter",l.message)}}}),r.tags=[...new Set([...n.map(o=>o.replace(/^#/,""))])],r=S(r),r}async function Y(e,t){let r=null;if(await _(e,async n=>{if(n.type==="FrontMatter"){let o=n.children[1].children[0],i=A(o);try{let a="";if(typeof t=="string")a=i+t+` -`;else{let u={...await d.parse(i),...t};a=await d.stringify(u)}r={changes:{from:o.from,to:o.to,insert:a}}}catch(a){console.error("Error parsing YAML",a)}return!0}return!1}),!r){let n="";typeof t=="string"?n=t+` -`:n=await d.stringify(t),r={changes:{from:0,to:0,insert:`--- +var ce=Object.defineProperty;var A=(e,t)=>{for(var r in t)ce(e,r,{get:t[r],enumerable:!0})};var M=typeof window>"u"&&typeof globalThis.WebSocketPair>"u";typeof Deno>"u"&&(self.Deno={args:[],build:{arch:"x86_64"},env:{get(){}}});var O=new Map,I=0;function T(e){self.postMessage(e)}M&&(globalThis.syscall=async(e,...t)=>await new Promise((r,n)=>{I++,O.set(I,{resolve:r,reject:n}),T({type:"sys",id:I,name:e,args:t})}));function W(e,t){M&&(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||[]));T({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),T({type:"invr",id:n.id,error:i.message})}}break;case"sysr":{let o=n.id,i=O.get(o);if(!i)throw Error("Invalid request id");O.delete(o),n.error?i.reject(new Error(n.error)):i.resolve(n.result)}break}})().catch(console.error)}),T({type:"manifest",manifest:t}))}function le(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o0?B(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 de(){globalThis.fetch=async function(e,t){let r=t&&t.body?B(new Uint8Array(await new Response(t.body).arrayBuffer())):void 0,n=await ue(e,t&&{method:t.method,headers:t.headers,base64Body:r});return new Response(n.base64Body?le(n.base64Body):null,{status:n.status,headers:n.headers})}}M&&de();var g=globalThis.syscall;var f={};A(f,{parse:()=>ge,stringify:()=>he});function ge(e){return g("yaml.parse",e)}function he(e){return g("yaml.stringify",e)}function k(e){if(e.children)for(let t of e.children){if(t.parent)return;t.parent=e,k(t)}}function F(e,t){if(t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...F(n,t)];return r}async function $(e,t){if(await t(e))return[e];let r=[];if(e.children)for(let n of e.children)r=[...r,...await $(n,t)];return r}async function L(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 L(n,t)}}}function U(e,t){return F(e,r=>r.type===t)[0]}function K(e,t){F(e,t)}async function _(e,t){await $(e,t)}function v(e){if(!e)return"";let t=[];if(e.text!==void 0)return e.text;for(let r of e.children)t.push(v(r));return t.join("")}function S(e){if(!e||typeof e!="object")return e;if(Array.isArray(e))return e.map(S);let t={};for(let r of Object.keys(e)){let n=r.split("."),o=t;for(let i=0;i{if(o.type==="Paragraph"&&o.parent?.type==="Document"){let i=!0,l=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 u=c.children[0].text.substring(1);l.add(u),(t.removeTags===!0||t.removeTags?.includes(u))&&(c.children[0].text="")}else if(c.type){i=!1;break}i&&n.push(...l)}if(o.type==="FrontMatter"){let i=o.children[1].children[0],l=v(i);try{let c=await f.parse(l),u={...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 P of t.removeKeys)P in u&&(delete u[P],p=!0);p&&(i.text=await f.stringify(u))}if(Object.keys(u).length===0||t.removeFrontmatterSection)return null}catch(c){console.warn("Could not parse frontmatter",c.message)}}}),r.tags=[...new Set([...n.map(o=>o.replace(/^#/,""))])],r=S(r),r}async function q(e,t){let r=null;if(await _(e,async n=>{if(n.type==="FrontMatter"){let o=n.children[1].children[0],i=v(o);try{let l="";if(typeof t=="string")l=i+t+` +`;else{let u={...await f.parse(i),...t};l=await f.stringify(u)}r={changes:{from:o.from,to:o.to,insert:l}}}catch(l){console.error("Error parsing YAML",l)}return!0}return!1}),!r){let n="";typeof t=="string"?n=t+` +`:n=await f.stringify(t),r={changes:{from:0,to:0,insert:`--- `+n+`--- -`}}}return r}var p,f;async function F(){if(p=await j("OPENAI_API_KEY"),!p)throw new Error("OpenAI API key is missing. Please set it in the secrets page.");let e={defaultTextModel:"gpt-3.5-turbo",openAIBaseUrl:"https://api.openai.com/v1",dallEBaseUrl:"https://api.openai.com/v1"};f=await K("ai",{}),f={...e,...f},console.log("aiSettings",f)}async function bt(){let e=await c.getSelection(),t="";return e.from===e.to?t="":t=(await c.getText()).slice(e.from,e.to),{from:e.from,to:e.to,text:t}}async function v(){let e=await bt(),t=await c.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 L(){let e=await v();if(console.log("selectedTextInfo",e),e.text.length>0){let t=await c.getCurrentPage(),r=await b("You are an AI Note assistant here to help summarize your personal notes.",[{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}. +`}}}return r}var a={};A(a,{confirm:()=>ze,dispatch:()=>Ge,downloadFile:()=>Ue,filterBox:()=>We,flashNotification:()=>Re,fold:()=>Ve,foldAll:()=>et,getCurrentPage:()=>Pe,getCursor:()=>ve,getSelection:()=>Se,getText:()=>Ae,getUiOption:()=>He,goHistory:()=>Le,hidePanel:()=>$e,insertAtCursor:()=>qe,insertAtPos:()=>Ke,moveCursor:()=>je,navigate:()=>Ce,openCommandPalette:()=>Ie,openPageNavigator:()=>Ne,openSearchPanel:()=>rt,openUrl:()=>Fe,prompt:()=>Ye,reloadPage:()=>Oe,reloadSettingsAndCommands:()=>ke,reloadUI:()=>Me,replaceRange:()=>_e,save:()=>Ee,setPage:()=>we,setSelection:()=>be,setText:()=>Te,setUiOption:()=>Qe,showPanel:()=>Be,toggleFold:()=>Ze,unfold:()=>Xe,unfoldAll:()=>tt,uploadFile:()=>De,vimEx:()=>Je});typeof self>"u"&&(self={syscall:()=>{throw new Error("Not implemented here")}});var s=self.syscall;function Pe(){return s("editor.getCurrentPage")}function we(e){return s("editor.setPage",e)}function Ae(){return s("editor.getText")}function Te(e){return s("editor.setText",e)}function ve(){return s("editor.getCursor")}function Se(){return s("editor.getSelection")}function be(e,t){return s("editor.setSelection",e,t)}function Ee(){return s("editor.save")}function Ce(e,t=!1,r=!1){return s("editor.navigate",e,t,r)}function Ne(e="page"){return s("editor.openPageNavigator",e)}function Ie(){return s("editor.openCommandPalette")}function Oe(){return s("editor.reloadPage")}function Me(){return s("editor.reloadUI")}function ke(){return s("editor.reloadSettingsAndCommands")}function Fe(e,t=!1){return s("editor.openUrl",e,t)}function Le(e){return s("editor.goHistory",e)}function Ue(e,t){return s("editor.downloadFile",e,t)}function De(e,t){return s("editor.uploadFile",e,t)}function Re(e,t="info"){return s("editor.flashNotification",e,t)}function We(e,t,r="",n=""){return s("editor.filterBox",e,t,r,n)}function Be(e,t,r,n=""){return s("editor.showPanel",e,t,r,n)}function $e(e){return s("editor.hidePanel",e)}function Ke(e,t){return s("editor.insertAtPos",e,t)}function _e(e,t,r){return s("editor.replaceRange",e,t,r)}function je(e,t=!1){return s("editor.moveCursor",e,t)}function qe(e){return s("editor.insertAtCursor",e)}function Ge(e){return s("editor.dispatch",e)}function Ye(e,t=""){return s("editor.prompt",e,t)}function ze(e){return s("editor.confirm",e)}function He(e){return s("editor.getUiOption",e)}function Qe(e,t){return s("editor.setUiOption",e,t)}function Je(e){return s("editor.vimEx",e)}function Ve(){return s("editor.fold")}function Xe(){return s("editor.unfold")}function Ze(){return s("editor.toggleFold")}function et(){return s("editor.foldAll")}function tt(){return s("editor.unfoldAll")}function rt(){return s("editor.openSearchPanel")}var y={};A(y,{parseMarkdown:()=>nt});function nt(e){return s("markdown.parseMarkdown",e)}var h={};A(h,{deleteAttachment:()=>pt,deleteFile:()=>Pt,deletePage:()=>ct,getAttachmentMeta:()=>dt,getFileMeta:()=>yt,getPageMeta:()=>st,listAttachments:()=>ut,listFiles:()=>gt,listPages:()=>ot,listPlugs:()=>lt,readAttachment:()=>ft,readFile:()=>ht,readPage:()=>it,writeAttachment:()=>mt,writeFile:()=>xt,writePage:()=>at});function ot(e=!1){return s("space.listPages",e)}function st(e){return s("space.getPageMeta",e)}function it(e){return s("space.readPage",e)}function at(e,t){return s("space.writePage",e,t)}function ct(e){return s("space.deletePage",e)}function lt(){return s("space.listPlugs")}function ut(){return s("space.listAttachments")}function dt(e){return s("space.getAttachmentMeta",e)}function ft(e){return s("space.readAttachment",e)}function mt(e,t){return s("space.writeAttachment",e,t)}function pt(e){return s("space.deleteAttachment",e)}function gt(){return s("space.listFiles")}function ht(e){return s("space.readFile",e)}function yt(e){return s("space.getFileMeta",e)}function xt(e,t){return s("space.writeFile",e,t)}function Pt(e){return s("space.deleteFile",e)}var fr=new TextEncoder;function G(e){let t=atob(e),r=t.length,n=new Uint8Array(r);for(let o=0;o{if(i.type!=="FencedCode")return!1;let l=U(i,"CodeInfo");if(t&&!l||t&&!t.includes(l.children[0].text))return!1;let c=U(i,"CodeText");return c?(o=c.children[0].text,!0):!1}),o}async function C(e,t=["yaml"]){let r=await Nt(e,t);if(r!==void 0)try{return f.parse(r)}catch(n){throw console.error("YAML Page parser error",n),new Error(`YAML Error: ${n.message}`)}}var It="SETTINGS";async function Y(e,t){try{let n=(await C(It,["yaml"])||{})[e];return n===void 0?t:n}catch(r){if(r.message==="Not found")return t;throw r}}async function z(e){try{let r=(await C("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 m,d;async function x(){let e=await z("OPENAI_API_KEY");if(e!==m&&(m=e,await a.flashNotification("silverbullet-ai API key updated")),!m){let o="OpenAI API key is missing. Please set it in the secrets page.";throw await a.flashNotification(o,"error"),new Error(o)}let t={defaultTextModel:"gpt-3.5-turbo",openAIBaseUrl:"https://api.openai.com/v1",dallEBaseUrl:"https://api.openai.com/v1",requireAuth:!0},r=await Y("ai",{}),n={...t,...r};JSON.stringify(d)!==JSON.stringify(n)?(console.log("aiSettings updating from",d),d=n,console.log("aiSettings updated to",d),await a.flashNotification("silverbullet-ai settings updated")):console.log("aiSettings unchanged",d)}var w=function(e,t){if(!(this instanceof w))return new w(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(l){l.trim().length>0&&this.dispatchEvent(this._parseEventChunk(l))}.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 l=i.indexOf(this.FIELD_SEPARATOR),c,u;if(l>0){var p=i[l+1]===" "?2:1;c=i.substring(0,l),u=i.substring(l+p)}else if(l<0)c=i,u="";else return;c in n&&(c==="data"&&n[c]!==null?n.data+=` +`+u:n[c]=u)}.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=w);async function N(e,t=void 0){try{m||await x(),await a.flashNotification("Contacting LLM, please wait...");let n=`${d.openAIBaseUrl}/chat/completions`,o=!1,i;"systemMessage"in e&&"userMessage"in e?i=[{role:"system",content:e.systemMessage},{role:"user",content:e.userMessage}]:(i=e,o=!0);var r={"Content-Type":"application/json"};d.requireAuth&&(r.Authorization=`Bearer ${m}`);let l={method:"POST",headers:r,payload:JSON.stringify({model:d.defaultTextModel,stream:!0,messages:i}),withCredentials:!1},c=new w(n,l),u;t?u=t:u=await E(),console.log("cursorPos before addeventlistener",u),c.addEventListener("message",function(p){try{if(p.data=="[DONE]")c.close(),o&&a.insertAtPos(` -${e.text}`}]);return console.log("OpenAI response:",r),{summary:r.choices[0].message.content,selectedTextInfo:e}}return{summary:"",selectedTextInfo:null}}async function q(){let e=await v(),t=await c.prompt("Please enter a prompt to send to the LLM."),r=await c.getCurrentPage(),n=new Date,o=n.toISOString().split("T")[0],i=n.toLocaleDateString("en-US",{weekday:"long"}),a=await b("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**: `,u);else{let R=JSON.parse(p.data).choices[0]?.delta?.content||"";a.insertAtPos(R,u),u+=R.length}a.moveCursor(u,!0)}catch(P){console.error("Error processing message event:",P,p.data)}}),c.addEventListener("end",function(){c.close()}),c.stream()}catch(n){throw console.error("Error streaming from OpenAI chat endpoint:",n),await a.flashNotification("Error streaming from OpenAI chat endpoint.","error"),n}}async function D(e,t){try{if(m||await x(),!m||!d||!d.openAIBaseUrl)throw await a.flashNotification("API key or AI settings are not properly configured.","error"),new Error("API key or AI settings are not properly configured.");await a.flashNotification("Contacting LLM, please wait...");let r=await fetch(d.openAIBaseUrl+"/chat/completions",{method:"POST",headers:{Authorization:`Bearer ${m}`,"Content-Type":"application/json"},body:JSON.stringify({model:d.defaultTextModel,messages:[{role:"system",content:e},...t]})});if(!r.ok)throw new Error(`HTTP error, status: ${r.status}`);let n=await r.json();if(!n||!n.choices||n.choices.length===0)throw new Error("Invalid response from OpenAI.");return n}catch(r){throw console.error("Error calling OpenAI chat endpoint:",r),await a.flashNotification("Error calling OpenAI chat endpoint.","error"),r}}async function H(e,t,r="1024x1024",n="hd"){try{m||await x(),await a.flashNotification("Contacting DALL\xB7E, please wait...");let o=await fetch(d.dallEBaseUrl+"/images/generations",{method:"POST",headers:{Authorization:`Bearer ${m}`,"Content-Type":"application/json"},body:JSON.stringify({model:"dall-e-3",prompt:e,quality:n,n:t,size:r,response_format:"b64_json"})});if(!o.ok)throw new Error(`HTTP error, status: ${o.status}`);return await o.json()}catch(o){throw console.error("Error calling DALL\xB7E image generation endpoint:",o),o}}function Q(e){return e.split("/").slice(0,-1).join("/")}async function J(){let t=(await a.getText()).split(` +`),r=[],n="user",o="";return t.forEach(i=>{let l=i.match(/^\*\*(\w+)\*\*:/);if(l){let c=l[1].toLowerCase();n&&n!==c&&(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 V(e){(e==="SETTINGS"||e==="SECRETS")&&await x()}async function X(){let e=await b();if(console.log("selectedTextInfo",e),e.text.length>0){let t=await a.getCurrentPage(),r=await D("You are an AI Note assistant here to help summarize the user's personal notes.",[{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}`}]);return console.log("OpenAI response:",r),{summary:r.choices[0].message.content,selectedTextInfo:e}}return{summary:"",selectedTextInfo:null}}async function Z(){let e=await b(),t=await a.prompt("Please enter a prompt to send to the LLM. Selected text or the entire note will also be sent as context."),r=await a.getCurrentPage(),n=new Date,o=n.toISOString().split("T")[0],i=n.toLocaleDateString("en-US",{weekday:"long"});await N({systemMessage:"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.",userMessage:`Note Context: Today is ${i}, ${o}. The current note name is "${r}". User Prompt: ${t} Note Content: -${e.text}`}]);e.isWholeNote?await c.insertAtCursor(a.choices[0].message.content):await c.replaceRange(e.from,e.to,a.choices[0].message.content)}async function z(){let e=await v(),t=await b("You are an AI note assistant in a markdown-based note tool.",[{role:"user",content:`${e.text}`}]);e.isWholeNote?await c.insertAtCursor(t.choices[0].message.content):await c.replaceRange(e.from,e.to,t.choices[0].message.content)}async function H(){let{summary:e}=await L();e?await c.showPanel("rhs",2,e):await c.flashNotification("No summary available.")}async function Q(){let{summary:e,selectedTextInfo:t}=await L();e&&t&&await c.replaceRange(t.from,t.to,e)}async function J(){let{summary:e,selectedTextInfo:t}=await L();e&&t&&await c.insertAtPos(` - -`+e,t.to)}async function V(){let e=await c.getText(),t=await c.getCurrentPage(),n=(await b("You are an AI tagging assistant. Please provide a short list of tags, separated by spaces. Only return tags and no other content. Tags must be one word only and lowercase.",[{role:"user",content:`Given the note titled "${t}" with the content below, please provide tags. +${e.text}`},e.isWholeNote?void 0:e.to)}async function ee(){let{summary:e}=await X();e?await a.showPanel("rhs",2,e):await a.flashNotification("No summary available.")}async function te(){let{summary:e,selectedTextInfo:t}=await X();e&&t&&await a.insertAtPos(` -${e}`}])).choices[0].message.content.trim().replace(/,/g,"").split(/\s+/),o=await g.parseMarkdown(e),i=await G(o),a=[...new Set([...i.tags||[],...n])];i.tags=a,console.log("Current frontmatter:",i);let l=await Y(o,i);console.log("updatedNoteContent",l),await c.dispatch(l),await c.flashNotification("Note tagged successfully.")}async function X(){let e=await v();await ee({systemMessage:"You are an AI note assistant in a markdown-based note tool.",userMessage:e.text})}async function Z(){let e=await Et();if(e.length===0){await c.flashNotification("Error: The page does not match the required format for a chat.");return}await c.insertAtCursor(` - -**assistant**: `),await ee(e)}async function Et(){let t=(await c.getText()).split(` -`),r=[],n="",o="";return t.forEach(i=>{let a=i.match(/^\*\*(\w+)\*\*:/);if(a){let l=a[1].toLowerCase();n&&n!==l&&(r.push({role:n,content:o.trim()}),o=""),n=l,o+=i.replace(/^\*\*(\w+)\*\*:/,"").trim()+` -`}else n&&(o+=i.trim()+` -`)}),o&&n&&r.push({role:n,content:o.trim()}),r}async function ee(e){try{p||await F(),await c.flashNotification("Contacting LLM, please wait...");let t=`${f.openAIBaseUrl}/chat/completions`,r=!1,n;"systemMessage"in e&&"userMessage"in e?n=[{role:"system",content:e.systemMessage},{role:"user",content:e.userMessage}]:(n=e,r=!0);let o={method:"POST",headers:{Authorization:`Bearer ${p}`,"Content-Type":"application/json"},payload:JSON.stringify({model:f.defaultTextModel,stream:!0,messages:n}),withCredentials:!1},i=new y(t,o);i.addEventListener("message",function(a){try{if(a.data=="[DONE]")r&&c.insertAtCursor(` +`+e,t.to)}async function re(){let e=await a.getText(),t=await a.getCurrentPage(),n=(await D("You are an AI tagging assistant. Please provide a short list of tags, separated by spaces. Only return tags and no other content. Tags must be one word only and lowercase. Suggest tags sparringly, do not treat them as keywords.",[{role:"user",content:`Given the note titled "${t}" with the content below, please provide tags. -**user**: `),i.close();else{let l=JSON.parse(a.data);c.insertAtCursor(l.choices[0]?.delta?.content||"")}}catch(l){console.error("Error processing message event:",l,a.data)}}),i.addEventListener("end",function(){r&&c.insertAtCursor(` +${e}`}])).choices[0].message.content.trim().replace(/,/g,"").split(/\s+/),o=await y.parseMarkdown(e),i=await j(o),l=[...new Set([...i.tags||[],...n])];i.tags=l,console.log("Current frontmatter:",i);let c=await q(o,i);console.log("updatedNoteContent",c),await a.dispatch(c),await a.flashNotification("Note tagged successfully.")}async function ne(){let e=await b();await N({systemMessage:"You are an AI note assistant in a markdown-based note tool.",userMessage:e.text})}async function oe(){let e=await J();if(e.length===0){await a.flashNotification("Error: The page does not match the required format for a chat.");return}let t=await E();await a.insertAtPos(` -**user**: `),i.close()}),i.stream()}catch(t){throw console.error("Error streaming from OpenAI chat endpoint:",t),t}}async function b(e,t){try{p||await F(),await c.flashNotification("Contacting LLM, please wait...");let r=await fetch(f.openAIBaseUrl+"/chat/completions",{method:"POST",headers:{Authorization:`Bearer ${p}`,"Content-Type":"application/json"},body:JSON.stringify({model:f.defaultTextModel,messages:[{role:"system",content:e},...t]})});if(!r.ok)throw new Error(`HTTP error, status: ${r.status}`);return await r.json()}catch(r){throw console.error("Error calling OpenAI chat endpoint:",r),r}}function Ct(e){return e.split("/").slice(0,-1).join("/")}async function te(){try{let e=await c.prompt("Enter a prompt for DALL\xB7E:");if(!e){await c.flashNotification("No prompt entered. Operation cancelled.","error");return}let t=await It(e,1);if(t&&t.data&&t.data.length>0){let r=t.data[0].b64_json,n=t.data[0].revised_prompt,o=new Uint8Array(D(r)),i=`dall-e-${Date.now()}.png`,a=Ct(await c.getCurrentPage())+"/";a==="/"&&(a=""),await h.writeAttachment(a+i,o);let l=`![${e}](${i}) -*${n}*`;await c.insertAtCursor(l),await c.flashNotification("Image generated and inserted with caption successfully.")}else await c.flashNotification("Failed to generate image.","error")}catch(e){console.error("Error generating image with DALL\xB7E:",e),await c.flashNotification("Error generating image.","error")}}async function It(e,t,r="1024x1024",n="hd"){try{p||await F(),await c.flashNotification("Contacting DALL\xB7E, please wait...");let o=await fetch(f.dallEBaseUrl+"/images/generations",{method:"POST",headers:{Authorization:`Bearer ${p}`,"Content-Type":"application/json"},body:JSON.stringify({model:"dall-e-3",prompt:e,quality:n,n:t,size:r,response_format:"b64_json"})});if(!o.ok)throw new Error(`HTTP error, status: ${o.status}`);return await o.json()}catch(o){throw console.error("Error calling DALL\xB7E image generation endpoint:",o),o}}var re={summarizeNote:H,replaceWithSummary:Q,insertSummary:J,callOpenAI:q,tagNoteWithAI:V,promptAndGenerateImage:te,callOpenAIWithSelectionAsPrompt:z,streamOpenAIWithSelectionAsPrompt:X,streamChatOnPage:Z},ne={name:"silverbullet-ai",requiredPermissions:["fetch"],functions:{summarizeNote:{path:"sbai.ts:openSummaryPanel",command:{name:"AI: Summarize Note and open summary"}},replaceWithSummary:{path:"sbai.ts:replaceWithSummary",command:{name:"AI: Replace with Summary"}},insertSummary:{path:"sbai.ts:insertSummary",command:{name:"AI: Insert Summary"}},callOpenAI:{path:"sbai.ts:callOpenAIwithNote",command:{name:"AI: Call OpenAI with Note 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"}},callOpenAIWithSelectionAsPrompt:{path:"sbai.ts:callOpenAIWithSelectionAsPrompt",command:{name:"AI: Call OpenAI with selected text as prompt"}},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"}}},assets:{}},Gr={manifest:ne,functionMapping:re};R(re,ne);export{Gr as plug}; +**assistant**: `,t),await N(e)}async function se(){try{let e=await a.prompt("Enter a prompt for DALL\xB7E:");if(!e||!e.trim()){await a.flashNotification("No prompt entered. Operation cancelled.","error");return}let t=await H(e,1);if(t&&t.data&&t.data.length>0){let r=t.data[0].b64_json,n=t.data[0].revised_prompt,o=new Uint8Array(G(r)),i=`dall-e-${Date.now()}.png`,l=Q(await a.getCurrentPage())+"/";l==="/"&&(l=""),await h.writeAttachment(l+i,o);let c=`![${e}](${i}) +*${n}*`;await a.insertAtCursor(c),await a.flashNotification("Image generated and inserted with caption successfully.")}else await a.flashNotification("Failed to generate image.","error")}catch(e){console.error("Error generating image with DALL\xB7E:",e),await a.flashNotification("Error generating image.","error")}}var ie={reloadConfig:V,summarizeNote:ee,insertSummary:te,callOpenAI:Z,tagNoteWithAI:re,promptAndGenerateImage:se,streamOpenAIWithSelectionAsPrompt:ne,streamChatOnPage:oe},ae={name:"silverbullet-ai",requiredPermissions:["fetch"],functions:{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"}}},assets:{}},on={manifest:ae,functionMapping:ie};W(ie,ae);export{on as plug}; diff --git a/src/openai.ts b/src/openai.ts index dfcfbbd..5167976 100644 --- a/src/openai.ts +++ b/src/openai.ts @@ -68,6 +68,7 @@ export async function streamChatWithOpenAI( editor.insertAtPos(msg, cursorPos); cursorPos += msg.length; } + editor.moveCursor(cursorPos, true); } catch (error) { console.error("Error processing message event:", error, e.data); }