@storvia/sdk 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +2 -2
- package/dist/index.d.mts +26 -11
- package/dist/index.esm.js +3 -3
- package/dist/index.umd.js +2 -2
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var P=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var P=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var H=(a,e)=>{for(var t in e)P(a,t,{get:e[t],enumerable:!0})},B=(a,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of A(e))!D.call(a,i)&&i!==t&&P(a,i,{get:()=>e[i],enumerable:!(n=U(e,i))||n.enumerable});return a};var G=a=>B(P({},"__esModule",{value:!0}),a);var Q={};H(Q,{StorviaError:()=>l,StorviaSDK:()=>S,createStorviaSDK:()=>$,extractFieldValue:()=>L,isRichFieldValue:()=>_});module.exports=G(Q);var l=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var E=class{constructor(e,t,n=!1,i=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=i}setToken(e){this.token=e}setDebug(e){this.debug=e}buildHeaders(){let e={"Content-Type":"application/json"};return this.token&&(e.Authorization=`Bearer ${this.token}`),this.devApiKey&&(e["x-api-key"]=this.devApiKey),e}log(e,t,n,i,s){if(!this.debug)return;let r="%c[Storvia SDK]",o="color: #6366f1; font-weight: bold";s?(console.groupCollapsed(`${r} %c${e} ${t} %c\u2717`,o,"color: #e0e0e0","color: #ef4444"),n&&console.log("Request:",n),console.error("Error:",s),console.groupEnd()):(console.groupCollapsed(`${r} %c${e} ${t} %c\u2713`,o,"color: #e0e0e0","color: #22c55e"),n&&console.log("Request:",n),i!==void 0&&console.log("Response:",i),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([i,s])=>n.searchParams.set(i,s));try{let i=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders()}),s=await this.handleResponse(i);return this.log("GET",e,t,s),s}catch(i){throw this.log("GET",e,t,void 0,i),i}}async post(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("POST",e,t,i),i}catch(n){throw this.log("POST",e,t,void 0,n),n}}async patch(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("PATCH",e,t,i),i}catch(n){throw this.log("PATCH",e,t,void 0,n),n}}async delete(e){try{let t=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders()}),n=await this.handleResponse(t);return this.log("DELETE",e,void 0,n),n}catch(t){throw this.log("DELETE",e,void 0,void 0,t),t}}async stream(e,t,n,i){this.log("STREAM",e,t);let s=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t)});if(!s.ok){let d=await s.json().catch(()=>({})),m=new l(d.code||"INTERNAL_ERROR",d.message||`HTTP ${s.status}`);throw this.log("STREAM",e,t,void 0,m),m}let r=s.body?.getReader();if(!r)throw new l("INTERNAL_ERROR","No response body for stream");let o=new TextDecoder,c="",p="";for(;;){let{done:d,value:m}=await r.read();if(d)break;let I=o.decode(m,{stream:!0}).split(`
|
|
2
2
|
`);for(let R of I){if(!R.startsWith("data: "))continue;let N=R.slice(6);if(N==="[DONE]"){this.debug&&this.log("STREAM",e+" [done]",void 0,{id:c,contentLength:p.length}),i(c);return}try{let g=JSON.parse(N);g.type==="done"&&g.id?c=g.id:g.content&&(p+=g.content,n(g.content))}catch{}}}c&&i(c)}async handleResponse(e){if(!e.ok){let n={};try{n=await e.json()}catch{}let i={401:"UNAUTHORIZED",402:"INSUFFICIENT_BALANCE",404:"GAME_NOT_FOUND",429:"RATE_LIMITED"},s=n.code||i[e.status]||"INTERNAL_ERROR";throw new l(s,n.message||`HTTP ${e.status}`)}let t=await e.json();return t&&typeof t=="object"&&"data"in t?t.data:t}};var F=[{value:"zh-CN",label:"\u7B80\u4F53\u4E2D\u6587"},{value:"zh-TW",label:"\u7E41\u9AD4\u4E2D\u6587"},{value:"en",label:"English"},{value:"ja",label:"\u65E5\u672C\u8A9E"},{value:"ko",label:"\uD55C\uAD6D\uC5B4"}],M=[{value:"low",label:"\u7B80\u77ED"},{value:"medium",label:"\u9002\u4E2D"},{value:"high",label:"\u8BE6\u7EC6"}],j=`
|
|
3
3
|
:host {
|
|
4
4
|
position: fixed;
|
|
@@ -428,4 +428,4 @@
|
|
|
428
428
|
}
|
|
429
429
|
.spin { animation: spin 0.8s linear infinite; }
|
|
430
430
|
`,V='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',z='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',W='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>',Z='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',K='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',u=class{constructor(e){this.selectedModelId="";this.models=[];this.modelPanel=null;this.settings={temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.hasWorldUpdate=!1;this.fabDot=null;this.syncHint=null;this.displayMode="phone";this.displayModeBtns=[];this.tempValueEl=null;this.tempSlider=null;this.segmentBtns=[];this.langSelect=null;this.noteInput=null;this.noteCounter=null;this.saveBtn=null;this.syncBtn=null;this.syncState="idle";this.panel=null;this.callbacks=e,this.host=document.createElement("div"),this.host.id="storvia-settings",this.shadowRoot=this.host.attachShadow({mode:"closed"})}mount(e,t,n,i=!1){this.models=e,this.selectedModelId=t,this.settings={...n},this.hasWorldUpdate=i;try{let s=localStorage.getItem("storvia_display_mode");(s==="phone"||s==="desktop")&&(this.displayMode=s)}catch{}document.body.appendChild(this.host),this.render()}unmount(){this.host.remove()}getSelectedModelId(){return this.selectedModelId}getSettings(){return{...this.settings}}render(){let e=document.createElement("style");e.textContent=j;let t=document.createElement("div"),n=document.createElement("div");n.className="fab-wrap";let i=document.createElement("button");i.className="fab",i.innerHTML=V,i.title="\u6E38\u620F\u8BBE\u7F6E";let s=document.createElement("div");s.className=`fab-dot${this.hasWorldUpdate?" visible":""}`,this.fabDot=s,n.appendChild(i),n.appendChild(s);let r=document.createElement("div");r.className="panel",this.panel=r;let o=document.createElement("div");o.className="panel-header";let c=document.createElement("div");c.className="panel-title",c.textContent="\u6E38\u620F\u8BBE\u7F6E";let p=document.createElement("button");p.className="close-btn",p.innerHTML="\u2715",p.addEventListener("click",()=>r.classList.remove("open")),o.appendChild(c),o.appendChild(p),r.appendChild(o);let d=document.createElement("div");d.className="panel-body",this.models.length>0&&(d.appendChild(this.buildModelSection()),d.appendChild(this.makeDivider())),d.appendChild(this.buildTemperatureSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildReplyLengthSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildReplyLanguageSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildNoteSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildDisplayModeSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildSyncSection());let m=document.createElement("div");m.className="save-row";let h=document.createElement("button");h.className="save-btn",h.textContent="\u4FDD\u5B58",this.saveBtn=h,h.addEventListener("click",()=>this.handleSave()),m.appendChild(h),d.appendChild(m),r.appendChild(d),i.addEventListener("click",()=>r.classList.toggle("open")),document.addEventListener("click",I=>{this.host.contains(I.target)||r.classList.remove("open")}),t.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(t)}buildModelSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="AI \u6A21\u578B",e.appendChild(t);let n=document.createElement("div");return n.className="model-list",this.modelPanel=n,this.models.forEach(i=>{let s=document.createElement("button");s.className=`model-option${i.id===this.selectedModelId?" active":""}`,s.innerHTML=`<span class="dot"></span><span>${i.name}</span>`,s.addEventListener("click",()=>{this.selectedModelId=i.id,this.callbacks.onModelChange(i.id);try{localStorage.setItem("storvia_model_id",i.id)}catch{}this.updateModelActive()}),n.appendChild(s)}),e.appendChild(n),e}buildTemperatureSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u66F4\u4F4E\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u3001\u7406\u667A\uFF1B\u66F4\u9AD8\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u7684\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027\u548C\u968F\u673A\u6027",e.appendChild(s);let r=document.createElement("div");r.className="slider-wrap";let o=document.createElement("input");o.type="range",o.className="slider",o.min="0",o.max="2",o.step="0.1",o.value=String(this.settings.temperature),this.tempSlider=o,o.addEventListener("input",()=>{let p=parseFloat(o.value);this.settings.temperature=p,this.tempValueEl&&(this.tempValueEl.textContent=p.toFixed(1))}),r.appendChild(o);let c=document.createElement("div");return c.className="slider-labels",c.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",r.appendChild(c),e.appendChild(r),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment",this.segmentBtns=[],M.forEach(i=>{let s=document.createElement("button");s.className=`segment-btn${i.value===this.settings.reply_length?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.reply_length=i.value,this.segmentBtns.forEach((r,o)=>{r.classList.toggle("active",M[o].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="select-wrap";let i=document.createElement("select");i.className="select",this.langSelect=i,F.forEach(r=>{let o=document.createElement("option");o.value=r.value,o.textContent=r.label,r.value===this.settings.reply_language&&(o.selected=!0),i.appendChild(o)}),i.addEventListener("change",()=>{this.settings.reply_language=i.value});let s=document.createElement("span");return s.className="select-arrow",s.textContent="\u25BE",n.appendChild(i),n.appendChild(s),e.appendChild(n),e}buildNoteSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.textContent=`${this.settings.player_note.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u5199\u4E0B\u4F60\u5BF9\u8FD9\u4E2A\u6E38\u620F\u7684\u5907\u6CE8\uFF0C\u4F1A\u663E\u793A\u5728\u5B58\u6863\u5217\u8868",e.appendChild(s);let r=document.createElement("div");r.className="note-wrap";let o=document.createElement("textarea");return o.className="note-input",o.placeholder="\u5907\u6CE8",o.maxLength=50,o.value=this.settings.player_note,this.noteInput=o,o.addEventListener("input",()=>{this.settings.player_note=o.value,this.noteCounter&&(this.noteCounter.textContent=`${o.value.length}/50`)}),r.appendChild(o),e.appendChild(r),e}buildDisplayModeSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u663E\u793A\u6A21\u5F0F",e.appendChild(t);let n=document.createElement("div");n.className="section-desc",n.textContent="\u7535\u8111\u6A21\u5F0F\u4F1A\u81EA\u52A8\u6A2A\u5C4F\u663E\u793A",e.appendChild(n);let i=document.createElement("div");i.className="segment",this.displayModeBtns=[];let s=[{value:"phone",label:"\u624B\u673A"},{value:"desktop",label:"\u7535\u8111"}];return s.forEach(r=>{let o=document.createElement("button");o.className=`segment-btn${r.value===this.displayMode?" active":""}`,o.textContent=r.label,o.addEventListener("click",()=>{this.displayMode=r.value;try{localStorage.setItem("storvia_display_mode",r.value)}catch{}this.displayModeBtns.forEach((c,p)=>{c.classList.toggle("active",s[p].value===r.value)});try{window.parent.postMessage({type:"storvia-orientation",mode:r.value==="desktop"?"landscape":"portrait"},"*")}catch{}}),this.displayModeBtns.push(o),i.appendChild(o)}),e.appendChild(i),e}buildSyncSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A",e.appendChild(t);let n=document.createElement("div");n.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,n.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=n,e.appendChild(n);let i=document.createElement("div");i.className="sync-desc",i.textContent="\u5982\u679C\u6E38\u620F\u4F5C\u8005\u66F4\u65B0\u4E86\u5185\u5BB9\uFF0C\u70B9\u51FB\u6B64\u6309\u94AE\u53EF\u5C06\u6700\u65B0\u7684\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(i);let s=document.createElement("button");return s.className="sync-btn",this.syncBtn=s,this.renderSyncBtn(),s.addEventListener("click",async()=>{if(this.syncState!=="loading"){this.setSyncState("loading");try{await this.callbacks.onSync(),this.setSyncState("success"),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),setTimeout(()=>this.setSyncState("idle"),3e3)}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(s),e}makeDivider(){let e=document.createElement("div");return e.className="divider",e}updateModelActive(){this.modelPanel&&this.modelPanel.querySelectorAll(".model-option").forEach((e,t)=>{e.classList.toggle("active",this.models[t].id===this.selectedModelId)})}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:z,loading:W,success:Z,error:K},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`sync-btn${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.textContent="\u4FDD\u5B58\u4E2D...";try{await this.callbacks.onSettingsChange({temperature:this.settings.temperature,reply_length:this.settings.reply_length,reply_language:this.settings.reply_language,player_note:this.settings.player_note}),this.saveBtn.textContent="\u5DF2\u4FDD\u5B58",this.saveBtn.classList.add("saved"),setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.classList.remove("saved"),this.saveBtn.disabled=!1)},2e3)}catch{this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3)}}}};var v=class{constructor(e,t,n,i,s=!1,r){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/chat",t)}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,context:(e.context||"")+`
|
|
431
|
-
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new k(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var T=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new T(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var $="/functions/v1/world-engine/v1",J="https://api.storvia.ai";function Y(){return window.__STORVIA__||{}}function q(a=5e3){let e=Y();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},a);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var S=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await q(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${$}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let d=await this.fetchModels();this.modelId=e.selectedModelId||d[0]?.id||"",this.settingsSheet=new u({onModelChange:R=>{this.modelId=R},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),d.length>0&&this.settingsSheet.mount(d,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(d=>d.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:d=>{this.modelId=d},onSettingsChange:d=>this.saveSettings(d),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${J}${$}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function O(a){let e=new S;return a?.dev?await e.initDev(a.dev):await e.init(),e}function _(a){return typeof a=="object"&&a!==null&&"value"in a&&"type"in a&&(a.type==="number"||a.type==="text")}function L(a){return _(a)?a.value:a}0&&(module.exports={StorviaError,StorviaSDK,createStorviaSDK,extractFieldValue,isRichFieldValue});
|
|
431
|
+
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new k(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar,...e.gender?{gender:e.gender}:{}})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar,...t?.gender?{gender:t.gender}:{}}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var T=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new T(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var O="/functions/v1/world-engine/v1",J="https://api.storvia.ai";function Y(){return window.__STORVIA__||{}}function q(a=5e3){let e=Y();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},a);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var S=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await q(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${O}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let d=await this.fetchModels();this.modelId=e.selectedModelId||d[0]?.id||"",this.settingsSheet=new u({onModelChange:R=>{this.modelId=R},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),d.length>0&&this.settingsSheet.mount(d,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(d=>d.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:d=>{this.modelId=d},onSettingsChange:d=>this.saveSettings(d),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${J}${O}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function $(a){let e=new S;return a?.dev?await e.initDev(a.dev):await e.init(),e}function _(a){return typeof a=="object"&&a!==null&&"value"in a&&"type"in a&&(a.type==="number"||a.type==="text")}function L(a){return _(a)?a.value:a}0&&(module.exports={StorviaError,StorviaSDK,createStorviaSDK,extractFieldValue,isRichFieldValue});
|
package/dist/index.d.mts
CHANGED
|
@@ -62,11 +62,13 @@ type FieldValue = string | number | boolean | RichFieldValue;
|
|
|
62
62
|
declare function isRichFieldValue(v: unknown): v is RichFieldValue;
|
|
63
63
|
/** 从 FieldValue 中提取原始值 */
|
|
64
64
|
declare function extractFieldValue(v: FieldValue): string | number | boolean;
|
|
65
|
+
type Gender = 'male' | 'female' | 'other';
|
|
65
66
|
interface CharacterPersona {
|
|
66
67
|
name: string;
|
|
67
68
|
avatar?: string;
|
|
68
69
|
description?: string;
|
|
69
70
|
userDescription?: string;
|
|
71
|
+
gender?: Gender;
|
|
70
72
|
isPreset?: boolean;
|
|
71
73
|
}
|
|
72
74
|
interface CharacterDetail {
|
|
@@ -74,9 +76,22 @@ interface CharacterDetail {
|
|
|
74
76
|
avatar?: string;
|
|
75
77
|
description?: string;
|
|
76
78
|
userDescription?: string;
|
|
79
|
+
gender?: Gender;
|
|
77
80
|
isPreset?: boolean;
|
|
78
81
|
state: Record<string, FieldValue>;
|
|
79
82
|
}
|
|
83
|
+
interface CharacterAddOptions {
|
|
84
|
+
name: string;
|
|
85
|
+
description?: string;
|
|
86
|
+
avatar?: string;
|
|
87
|
+
gender: Gender;
|
|
88
|
+
}
|
|
89
|
+
interface CharacterUpdateOptions {
|
|
90
|
+
description?: string;
|
|
91
|
+
userDescription?: string;
|
|
92
|
+
avatar?: string;
|
|
93
|
+
gender?: Gender;
|
|
94
|
+
}
|
|
80
95
|
interface Relationship {
|
|
81
96
|
from: string;
|
|
82
97
|
to: string;
|
|
@@ -178,18 +193,18 @@ declare class CharactersModule {
|
|
|
178
193
|
constructor(http: HttpClient, getConversationId: () => string, isPreview?: boolean);
|
|
179
194
|
list(): Promise<CharacterPersona[]>;
|
|
180
195
|
get(name: string): Promise<CharacterPersona>;
|
|
181
|
-
add(character:
|
|
182
|
-
|
|
183
|
-
description?: string;
|
|
184
|
-
avatar?: string;
|
|
185
|
-
}): Promise<void>;
|
|
186
|
-
update(name: string, data: {
|
|
187
|
-
description?: string;
|
|
188
|
-
userDescription?: string;
|
|
189
|
-
avatar?: string;
|
|
190
|
-
}): Promise<void>;
|
|
196
|
+
add(character: CharacterAddOptions): Promise<void>;
|
|
197
|
+
update(name: string, data: CharacterUpdateOptions): Promise<void>;
|
|
191
198
|
remove(name: string): Promise<void>;
|
|
192
199
|
detail(name: string): Promise<CharacterDetail>;
|
|
200
|
+
/**
|
|
201
|
+
* 调整 NPC 的重要程度(0-100,越高越不容易被挤出场景)。
|
|
202
|
+
* 预设 NPC 不可修改(固定为 100),调用会抛错。
|
|
203
|
+
* 超出范围会自动钳位到 0 或 100。
|
|
204
|
+
*
|
|
205
|
+
* 等价写法:`state.update(name, { priority: value })`
|
|
206
|
+
*/
|
|
207
|
+
setPriority(name: string, value: number): Promise<void>;
|
|
193
208
|
}
|
|
194
209
|
|
|
195
210
|
declare class RelationshipsModule {
|
|
@@ -322,4 +337,4 @@ declare class StorviaError extends Error {
|
|
|
322
337
|
constructor(code: StorviaErrorCode, message: string);
|
|
323
338
|
}
|
|
324
339
|
|
|
325
|
-
export { type CharacterDetail, type CharacterPersona, type ChatGenerateOptions, type ChatResponse, type ChatSaveOptions, type ChatSendOptions, type FieldValue, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type PlayerPersona, type Relationship, type RichFieldValue, StorviaError, type StorviaErrorCode, StorviaSDK, createStorviaSDK, extractFieldValue, isRichFieldValue };
|
|
340
|
+
export { type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatGenerateOptions, type ChatResponse, type ChatSaveOptions, type ChatSendOptions, type FieldValue, type Gender, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type PlayerPersona, type Relationship, type RichFieldValue, StorviaError, type StorviaErrorCode, StorviaSDK, createStorviaSDK, extractFieldValue, isRichFieldValue };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var l=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var E=class{constructor(e,t,n=!1,i=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=i}setToken(e){this.token=e}setDebug(e){this.debug=e}buildHeaders(){let e={"Content-Type":"application/json"};return this.token&&(e.Authorization=`Bearer ${this.token}`),this.devApiKey&&(e["x-api-key"]=this.devApiKey),e}log(e,t,n,i,s){if(!this.debug)return;let r="%c[Storvia SDK]",o="color: #6366f1; font-weight: bold";s?(console.groupCollapsed(`${r} %c${e} ${t} %c\u2717`,o,"color: #e0e0e0","color: #ef4444"),n&&console.log("Request:",n),console.error("Error:",s),console.groupEnd()):(console.groupCollapsed(`${r} %c${e} ${t} %c\u2713`,o,"color: #e0e0e0","color: #22c55e"),n&&console.log("Request:",n),i!==void 0&&console.log("Response:",i),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([i,s])=>n.searchParams.set(i,s));try{let i=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders()}),s=await this.handleResponse(i);return this.log("GET",e,t,s),s}catch(i){throw this.log("GET",e,t,void 0,i),i}}async post(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("POST",e,t,i),i}catch(n){throw this.log("POST",e,t,void 0,n),n}}async patch(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("PATCH",e,t,i),i}catch(n){throw this.log("PATCH",e,t,void 0,n),n}}async delete(e){try{let t=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders()}),n=await this.handleResponse(t);return this.log("DELETE",e,void 0,n),n}catch(t){throw this.log("DELETE",e,void 0,void 0,t),t}}async stream(e,t,n,i){this.log("STREAM",e,t);let s=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t)});if(!s.ok){let a=await s.json().catch(()=>({})),m=new l(a.code||"INTERNAL_ERROR",a.message||`HTTP ${s.status}`);throw this.log("STREAM",e,t,void 0,m),m}let r=s.body?.getReader();if(!r)throw new l("INTERNAL_ERROR","No response body for stream");let o=new TextDecoder,c="",p="";for(;;){let{done:a,value:m}=await r.read();if(a)break;let I=o.decode(m,{stream:!0}).split(`
|
|
2
|
-
`);for(let S of I){if(!S.startsWith("data: "))continue;let T=S.slice(6);if(T==="[DONE]"){this.debug&&this.log("STREAM",e+" [done]",void 0,{id:c,contentLength:p.length}),i(c);return}try{let g=JSON.parse(T);g.type==="done"&&g.id?c=g.id:g.content&&(p+=g.content,n(g.content))}catch{}}}c&&i(c)}async handleResponse(e){if(!e.ok){let n={};try{n=await e.json()}catch{}let i={401:"UNAUTHORIZED",402:"INSUFFICIENT_BALANCE",404:"GAME_NOT_FOUND",429:"RATE_LIMITED"},s=n.code||i[e.status]||"INTERNAL_ERROR";throw new l(s,n.message||`HTTP ${e.status}`)}let t=await e.json();return t&&typeof t=="object"&&"data"in t?t.data:t}};var
|
|
2
|
+
`);for(let S of I){if(!S.startsWith("data: "))continue;let T=S.slice(6);if(T==="[DONE]"){this.debug&&this.log("STREAM",e+" [done]",void 0,{id:c,contentLength:p.length}),i(c);return}try{let g=JSON.parse(T);g.type==="done"&&g.id?c=g.id:g.content&&(p+=g.content,n(g.content))}catch{}}}c&&i(c)}async handleResponse(e){if(!e.ok){let n={};try{n=await e.json()}catch{}let i={401:"UNAUTHORIZED",402:"INSUFFICIENT_BALANCE",404:"GAME_NOT_FOUND",429:"RATE_LIMITED"},s=n.code||i[e.status]||"INTERNAL_ERROR";throw new l(s,n.message||`HTTP ${e.status}`)}let t=await e.json();return t&&typeof t=="object"&&"data"in t?t.data:t}};var O=[{value:"zh-CN",label:"\u7B80\u4F53\u4E2D\u6587"},{value:"zh-TW",label:"\u7E41\u9AD4\u4E2D\u6587"},{value:"en",label:"English"},{value:"ja",label:"\u65E5\u672C\u8A9E"},{value:"ko",label:"\uD55C\uAD6D\uC5B4"}],_=[{value:"low",label:"\u7B80\u77ED"},{value:"medium",label:"\u9002\u4E2D"},{value:"high",label:"\u8BE6\u7EC6"}],$=`
|
|
3
3
|
:host {
|
|
4
4
|
position: fixed;
|
|
5
5
|
bottom: 20px;
|
|
@@ -427,5 +427,5 @@ var l=class extends Error{constructor(e,t){super(t),this.name="StorviaError",thi
|
|
|
427
427
|
to { transform: rotate(360deg); }
|
|
428
428
|
}
|
|
429
429
|
.spin { animation: spin 0.8s linear infinite; }
|
|
430
|
-
`,L='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',U='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',D='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>',A='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',H='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',u=class{constructor(e){this.selectedModelId="";this.models=[];this.modelPanel=null;this.settings={temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.hasWorldUpdate=!1;this.fabDot=null;this.syncHint=null;this.displayMode="phone";this.displayModeBtns=[];this.tempValueEl=null;this.tempSlider=null;this.segmentBtns=[];this.langSelect=null;this.noteInput=null;this.noteCounter=null;this.saveBtn=null;this.syncBtn=null;this.syncState="idle";this.panel=null;this.callbacks=e,this.host=document.createElement("div"),this.host.id="storvia-settings",this.shadowRoot=this.host.attachShadow({mode:"closed"})}mount(e,t,n,i=!1){this.models=e,this.selectedModelId=t,this.settings={...n},this.hasWorldUpdate=i;try{let s=localStorage.getItem("storvia_display_mode");(s==="phone"||s==="desktop")&&(this.displayMode=s)}catch{}document.body.appendChild(this.host),this.render()}unmount(){this.host.remove()}getSelectedModelId(){return this.selectedModelId}getSettings(){return{...this.settings}}render(){let e=document.createElement("style");e.textContent=O;let t=document.createElement("div"),n=document.createElement("div");n.className="fab-wrap";let i=document.createElement("button");i.className="fab",i.innerHTML=L,i.title="\u6E38\u620F\u8BBE\u7F6E";let s=document.createElement("div");s.className=`fab-dot${this.hasWorldUpdate?" visible":""}`,this.fabDot=s,n.appendChild(i),n.appendChild(s);let r=document.createElement("div");r.className="panel",this.panel=r;let o=document.createElement("div");o.className="panel-header";let c=document.createElement("div");c.className="panel-title",c.textContent="\u6E38\u620F\u8BBE\u7F6E";let p=document.createElement("button");p.className="close-btn",p.innerHTML="\u2715",p.addEventListener("click",()=>r.classList.remove("open")),o.appendChild(c),o.appendChild(p),r.appendChild(o);let a=document.createElement("div");a.className="panel-body",this.models.length>0&&(a.appendChild(this.buildModelSection()),a.appendChild(this.makeDivider())),a.appendChild(this.buildTemperatureSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildReplyLengthSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildReplyLanguageSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildNoteSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildDisplayModeSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildSyncSection());let m=document.createElement("div");m.className="save-row";let h=document.createElement("button");h.className="save-btn",h.textContent="\u4FDD\u5B58",this.saveBtn=h,h.addEventListener("click",()=>this.handleSave()),m.appendChild(h),a.appendChild(m),r.appendChild(a),i.addEventListener("click",()=>r.classList.toggle("open")),document.addEventListener("click",I=>{this.host.contains(I.target)||r.classList.remove("open")}),t.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(t)}buildModelSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="AI \u6A21\u578B",e.appendChild(t);let n=document.createElement("div");return n.className="model-list",this.modelPanel=n,this.models.forEach(i=>{let s=document.createElement("button");s.className=`model-option${i.id===this.selectedModelId?" active":""}`,s.innerHTML=`<span class="dot"></span><span>${i.name}</span>`,s.addEventListener("click",()=>{this.selectedModelId=i.id,this.callbacks.onModelChange(i.id);try{localStorage.setItem("storvia_model_id",i.id)}catch{}this.updateModelActive()}),n.appendChild(s)}),e.appendChild(n),e}buildTemperatureSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u66F4\u4F4E\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u3001\u7406\u667A\uFF1B\u66F4\u9AD8\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u7684\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027\u548C\u968F\u673A\u6027",e.appendChild(s);let r=document.createElement("div");r.className="slider-wrap";let o=document.createElement("input");o.type="range",o.className="slider",o.min="0",o.max="2",o.step="0.1",o.value=String(this.settings.temperature),this.tempSlider=o,o.addEventListener("input",()=>{let p=parseFloat(o.value);this.settings.temperature=p,this.tempValueEl&&(this.tempValueEl.textContent=p.toFixed(1))}),r.appendChild(o);let c=document.createElement("div");return c.className="slider-labels",c.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",r.appendChild(c),e.appendChild(r),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment",this.segmentBtns=[],_.forEach(i=>{let s=document.createElement("button");s.className=`segment-btn${i.value===this.settings.reply_length?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.reply_length=i.value,this.segmentBtns.forEach((r,o)=>{r.classList.toggle("active",_[o].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="select-wrap";let i=document.createElement("select");i.className="select",this.langSelect=i,$.forEach(r=>{let o=document.createElement("option");o.value=r.value,o.textContent=r.label,r.value===this.settings.reply_language&&(o.selected=!0),i.appendChild(o)}),i.addEventListener("change",()=>{this.settings.reply_language=i.value});let s=document.createElement("span");return s.className="select-arrow",s.textContent="\u25BE",n.appendChild(i),n.appendChild(s),e.appendChild(n),e}buildNoteSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.textContent=`${this.settings.player_note.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u5199\u4E0B\u4F60\u5BF9\u8FD9\u4E2A\u6E38\u620F\u7684\u5907\u6CE8\uFF0C\u4F1A\u663E\u793A\u5728\u5B58\u6863\u5217\u8868",e.appendChild(s);let r=document.createElement("div");r.className="note-wrap";let o=document.createElement("textarea");return o.className="note-input",o.placeholder="\u5907\u6CE8",o.maxLength=50,o.value=this.settings.player_note,this.noteInput=o,o.addEventListener("input",()=>{this.settings.player_note=o.value,this.noteCounter&&(this.noteCounter.textContent=`${o.value.length}/50`)}),r.appendChild(o),e.appendChild(r),e}buildDisplayModeSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u663E\u793A\u6A21\u5F0F",e.appendChild(t);let n=document.createElement("div");n.className="section-desc",n.textContent="\u7535\u8111\u6A21\u5F0F\u4F1A\u81EA\u52A8\u6A2A\u5C4F\u663E\u793A",e.appendChild(n);let i=document.createElement("div");i.className="segment",this.displayModeBtns=[];let s=[{value:"phone",label:"\u624B\u673A"},{value:"desktop",label:"\u7535\u8111"}];return s.forEach(r=>{let o=document.createElement("button");o.className=`segment-btn${r.value===this.displayMode?" active":""}`,o.textContent=r.label,o.addEventListener("click",()=>{this.displayMode=r.value;try{localStorage.setItem("storvia_display_mode",r.value)}catch{}this.displayModeBtns.forEach((c,p)=>{c.classList.toggle("active",s[p].value===r.value)});try{window.parent.postMessage({type:"storvia-orientation",mode:r.value==="desktop"?"landscape":"portrait"},"*")}catch{}}),this.displayModeBtns.push(o),i.appendChild(o)}),e.appendChild(i),e}buildSyncSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A",e.appendChild(t);let n=document.createElement("div");n.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,n.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=n,e.appendChild(n);let i=document.createElement("div");i.className="sync-desc",i.textContent="\u5982\u679C\u6E38\u620F\u4F5C\u8005\u66F4\u65B0\u4E86\u5185\u5BB9\uFF0C\u70B9\u51FB\u6B64\u6309\u94AE\u53EF\u5C06\u6700\u65B0\u7684\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(i);let s=document.createElement("button");return s.className="sync-btn",this.syncBtn=s,this.renderSyncBtn(),s.addEventListener("click",async()=>{if(this.syncState!=="loading"){this.setSyncState("loading");try{await this.callbacks.onSync(),this.setSyncState("success"),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),setTimeout(()=>this.setSyncState("idle"),3e3)}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(s),e}makeDivider(){let e=document.createElement("div");return e.className="divider",e}updateModelActive(){this.modelPanel&&this.modelPanel.querySelectorAll(".model-option").forEach((e,t)=>{e.classList.toggle("active",this.models[t].id===this.selectedModelId)})}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:U,loading:D,success:A,error:H},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`sync-btn${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.textContent="\u4FDD\u5B58\u4E2D...";try{await this.callbacks.onSettingsChange({temperature:this.settings.temperature,reply_length:this.settings.reply_length,reply_language:this.settings.reply_language,player_note:this.settings.player_note}),this.saveBtn.textContent="\u5DF2\u4FDD\u5B58",this.saveBtn.classList.add("saved"),setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.classList.remove("saved"),this.saveBtn.disabled=!1)},2e3)}catch{this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3)}}}};var v=class{constructor(e,t,n,i,s=!1,r){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/chat",t)}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,context:(e.context||"")+`
|
|
431
|
-
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var P=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new P(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new k(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var N="/functions/v1/world-engine/v1",B="https://api.storvia.ai";function G(){return window.__STORVIA__||{}}function F(d=5e3){let e=G();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},d);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var R=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await F(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${N}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let a=await this.fetchModels();this.modelId=e.selectedModelId||a[0]?.id||"",this.settingsSheet=new u({onModelChange:S=>{this.modelId=S},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),a.length>0&&this.settingsSheet.mount(a,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(a=>a.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:a=>{this.modelId=a},onSettingsChange:a=>this.saveSettings(a),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${B}${N}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function j(d){let e=new R;return d?.dev?await e.initDev(d.dev):await e.init(),e}function M(d){return typeof d=="object"&&d!==null&&"value"in d&&"type"in d&&(d.type==="number"||d.type==="text")}function V(d){return M(d)?d.value:d}export{l as StorviaError,R as StorviaSDK,j as createStorviaSDK,V as extractFieldValue,M as isRichFieldValue};
|
|
430
|
+
`,L='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',U='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',A='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>',D='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',H='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',u=class{constructor(e){this.selectedModelId="";this.models=[];this.modelPanel=null;this.settings={temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.hasWorldUpdate=!1;this.fabDot=null;this.syncHint=null;this.displayMode="phone";this.displayModeBtns=[];this.tempValueEl=null;this.tempSlider=null;this.segmentBtns=[];this.langSelect=null;this.noteInput=null;this.noteCounter=null;this.saveBtn=null;this.syncBtn=null;this.syncState="idle";this.panel=null;this.callbacks=e,this.host=document.createElement("div"),this.host.id="storvia-settings",this.shadowRoot=this.host.attachShadow({mode:"closed"})}mount(e,t,n,i=!1){this.models=e,this.selectedModelId=t,this.settings={...n},this.hasWorldUpdate=i;try{let s=localStorage.getItem("storvia_display_mode");(s==="phone"||s==="desktop")&&(this.displayMode=s)}catch{}document.body.appendChild(this.host),this.render()}unmount(){this.host.remove()}getSelectedModelId(){return this.selectedModelId}getSettings(){return{...this.settings}}render(){let e=document.createElement("style");e.textContent=$;let t=document.createElement("div"),n=document.createElement("div");n.className="fab-wrap";let i=document.createElement("button");i.className="fab",i.innerHTML=L,i.title="\u6E38\u620F\u8BBE\u7F6E";let s=document.createElement("div");s.className=`fab-dot${this.hasWorldUpdate?" visible":""}`,this.fabDot=s,n.appendChild(i),n.appendChild(s);let r=document.createElement("div");r.className="panel",this.panel=r;let o=document.createElement("div");o.className="panel-header";let c=document.createElement("div");c.className="panel-title",c.textContent="\u6E38\u620F\u8BBE\u7F6E";let p=document.createElement("button");p.className="close-btn",p.innerHTML="\u2715",p.addEventListener("click",()=>r.classList.remove("open")),o.appendChild(c),o.appendChild(p),r.appendChild(o);let a=document.createElement("div");a.className="panel-body",this.models.length>0&&(a.appendChild(this.buildModelSection()),a.appendChild(this.makeDivider())),a.appendChild(this.buildTemperatureSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildReplyLengthSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildReplyLanguageSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildNoteSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildDisplayModeSection()),a.appendChild(this.makeDivider()),a.appendChild(this.buildSyncSection());let m=document.createElement("div");m.className="save-row";let h=document.createElement("button");h.className="save-btn",h.textContent="\u4FDD\u5B58",this.saveBtn=h,h.addEventListener("click",()=>this.handleSave()),m.appendChild(h),a.appendChild(m),r.appendChild(a),i.addEventListener("click",()=>r.classList.toggle("open")),document.addEventListener("click",I=>{this.host.contains(I.target)||r.classList.remove("open")}),t.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(t)}buildModelSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="AI \u6A21\u578B",e.appendChild(t);let n=document.createElement("div");return n.className="model-list",this.modelPanel=n,this.models.forEach(i=>{let s=document.createElement("button");s.className=`model-option${i.id===this.selectedModelId?" active":""}`,s.innerHTML=`<span class="dot"></span><span>${i.name}</span>`,s.addEventListener("click",()=>{this.selectedModelId=i.id,this.callbacks.onModelChange(i.id);try{localStorage.setItem("storvia_model_id",i.id)}catch{}this.updateModelActive()}),n.appendChild(s)}),e.appendChild(n),e}buildTemperatureSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u66F4\u4F4E\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u3001\u7406\u667A\uFF1B\u66F4\u9AD8\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u7684\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027\u548C\u968F\u673A\u6027",e.appendChild(s);let r=document.createElement("div");r.className="slider-wrap";let o=document.createElement("input");o.type="range",o.className="slider",o.min="0",o.max="2",o.step="0.1",o.value=String(this.settings.temperature),this.tempSlider=o,o.addEventListener("input",()=>{let p=parseFloat(o.value);this.settings.temperature=p,this.tempValueEl&&(this.tempValueEl.textContent=p.toFixed(1))}),r.appendChild(o);let c=document.createElement("div");return c.className="slider-labels",c.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",r.appendChild(c),e.appendChild(r),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment",this.segmentBtns=[],_.forEach(i=>{let s=document.createElement("button");s.className=`segment-btn${i.value===this.settings.reply_length?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.reply_length=i.value,this.segmentBtns.forEach((r,o)=>{r.classList.toggle("active",_[o].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="select-wrap";let i=document.createElement("select");i.className="select",this.langSelect=i,O.forEach(r=>{let o=document.createElement("option");o.value=r.value,o.textContent=r.label,r.value===this.settings.reply_language&&(o.selected=!0),i.appendChild(o)}),i.addEventListener("change",()=>{this.settings.reply_language=i.value});let s=document.createElement("span");return s.className="select-arrow",s.textContent="\u25BE",n.appendChild(i),n.appendChild(s),e.appendChild(n),e}buildNoteSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.textContent=`${this.settings.player_note.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u5199\u4E0B\u4F60\u5BF9\u8FD9\u4E2A\u6E38\u620F\u7684\u5907\u6CE8\uFF0C\u4F1A\u663E\u793A\u5728\u5B58\u6863\u5217\u8868",e.appendChild(s);let r=document.createElement("div");r.className="note-wrap";let o=document.createElement("textarea");return o.className="note-input",o.placeholder="\u5907\u6CE8",o.maxLength=50,o.value=this.settings.player_note,this.noteInput=o,o.addEventListener("input",()=>{this.settings.player_note=o.value,this.noteCounter&&(this.noteCounter.textContent=`${o.value.length}/50`)}),r.appendChild(o),e.appendChild(r),e}buildDisplayModeSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u663E\u793A\u6A21\u5F0F",e.appendChild(t);let n=document.createElement("div");n.className="section-desc",n.textContent="\u7535\u8111\u6A21\u5F0F\u4F1A\u81EA\u52A8\u6A2A\u5C4F\u663E\u793A",e.appendChild(n);let i=document.createElement("div");i.className="segment",this.displayModeBtns=[];let s=[{value:"phone",label:"\u624B\u673A"},{value:"desktop",label:"\u7535\u8111"}];return s.forEach(r=>{let o=document.createElement("button");o.className=`segment-btn${r.value===this.displayMode?" active":""}`,o.textContent=r.label,o.addEventListener("click",()=>{this.displayMode=r.value;try{localStorage.setItem("storvia_display_mode",r.value)}catch{}this.displayModeBtns.forEach((c,p)=>{c.classList.toggle("active",s[p].value===r.value)});try{window.parent.postMessage({type:"storvia-orientation",mode:r.value==="desktop"?"landscape":"portrait"},"*")}catch{}}),this.displayModeBtns.push(o),i.appendChild(o)}),e.appendChild(i),e}buildSyncSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A",e.appendChild(t);let n=document.createElement("div");n.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,n.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=n,e.appendChild(n);let i=document.createElement("div");i.className="sync-desc",i.textContent="\u5982\u679C\u6E38\u620F\u4F5C\u8005\u66F4\u65B0\u4E86\u5185\u5BB9\uFF0C\u70B9\u51FB\u6B64\u6309\u94AE\u53EF\u5C06\u6700\u65B0\u7684\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(i);let s=document.createElement("button");return s.className="sync-btn",this.syncBtn=s,this.renderSyncBtn(),s.addEventListener("click",async()=>{if(this.syncState!=="loading"){this.setSyncState("loading");try{await this.callbacks.onSync(),this.setSyncState("success"),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),setTimeout(()=>this.setSyncState("idle"),3e3)}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(s),e}makeDivider(){let e=document.createElement("div");return e.className="divider",e}updateModelActive(){this.modelPanel&&this.modelPanel.querySelectorAll(".model-option").forEach((e,t)=>{e.classList.toggle("active",this.models[t].id===this.selectedModelId)})}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:U,loading:A,success:D,error:H},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`sync-btn${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.textContent="\u4FDD\u5B58\u4E2D...";try{await this.callbacks.onSettingsChange({temperature:this.settings.temperature,reply_length:this.settings.reply_length,reply_language:this.settings.reply_language,player_note:this.settings.player_note}),this.saveBtn.textContent="\u5DF2\u4FDD\u5B58",this.saveBtn.classList.add("saved"),setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.classList.remove("saved"),this.saveBtn.disabled=!1)},2e3)}catch{this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3)}}}};var v=class{constructor(e,t,n,i,s=!1,r){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/chat",t)}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,context:(e.context||"")+`
|
|
431
|
+
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var P=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new P(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar,...e.gender?{gender:e.gender}:{}})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar,...t?.gender?{gender:t.gender}:{}}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new k(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var N="/functions/v1/world-engine/v1",B="https://api.storvia.ai";function G(){return window.__STORVIA__||{}}function F(d=5e3){let e=G();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},d);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var R=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await F(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${N}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let a=await this.fetchModels();this.modelId=e.selectedModelId||a[0]?.id||"",this.settingsSheet=new u({onModelChange:S=>{this.modelId=S},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),a.length>0&&this.settingsSheet.mount(a,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(a=>a.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:a=>{this.modelId=a},onSettingsChange:a=>this.saveSettings(a),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${B}${N}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function j(d){let e=new R;return d?.dev?await e.initDev(d.dev):await e.init(),e}function M(d){return typeof d=="object"&&d!==null&&"value"in d&&"type"in d&&(d.type==="number"||d.type==="text")}function V(d){return M(d)?d.value:d}export{l as StorviaError,R as StorviaSDK,j as createStorviaSDK,V as extractFieldValue,M as isRichFieldValue};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var StorviaSDK=(()=>{var P=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var StorviaSDK=(()=>{var P=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var H=(a,e)=>{for(var t in e)P(a,t,{get:e[t],enumerable:!0})},B=(a,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of A(e))!D.call(a,i)&&i!==t&&P(a,i,{get:()=>e[i],enumerable:!(n=U(e,i))||n.enumerable});return a};var G=a=>B(P({},"__esModule",{value:!0}),a);var Q={};H(Q,{StorviaError:()=>l,StorviaSDK:()=>S,createStorviaSDK:()=>$,extractFieldValue:()=>L,isRichFieldValue:()=>_});var l=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var E=class{constructor(e,t,n=!1,i=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=i}setToken(e){this.token=e}setDebug(e){this.debug=e}buildHeaders(){let e={"Content-Type":"application/json"};return this.token&&(e.Authorization=`Bearer ${this.token}`),this.devApiKey&&(e["x-api-key"]=this.devApiKey),e}log(e,t,n,i,s){if(!this.debug)return;let r="%c[Storvia SDK]",o="color: #6366f1; font-weight: bold";s?(console.groupCollapsed(`${r} %c${e} ${t} %c\u2717`,o,"color: #e0e0e0","color: #ef4444"),n&&console.log("Request:",n),console.error("Error:",s),console.groupEnd()):(console.groupCollapsed(`${r} %c${e} ${t} %c\u2713`,o,"color: #e0e0e0","color: #22c55e"),n&&console.log("Request:",n),i!==void 0&&console.log("Response:",i),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([i,s])=>n.searchParams.set(i,s));try{let i=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders()}),s=await this.handleResponse(i);return this.log("GET",e,t,s),s}catch(i){throw this.log("GET",e,t,void 0,i),i}}async post(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("POST",e,t,i),i}catch(n){throw this.log("POST",e,t,void 0,n),n}}async patch(e,t){try{let n=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0}),i=await this.handleResponse(n);return this.log("PATCH",e,t,i),i}catch(n){throw this.log("PATCH",e,t,void 0,n),n}}async delete(e){try{let t=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders()}),n=await this.handleResponse(t);return this.log("DELETE",e,void 0,n),n}catch(t){throw this.log("DELETE",e,void 0,void 0,t),t}}async stream(e,t,n,i){this.log("STREAM",e,t);let s=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t)});if(!s.ok){let d=await s.json().catch(()=>({})),m=new l(d.code||"INTERNAL_ERROR",d.message||`HTTP ${s.status}`);throw this.log("STREAM",e,t,void 0,m),m}let r=s.body?.getReader();if(!r)throw new l("INTERNAL_ERROR","No response body for stream");let o=new TextDecoder,c="",p="";for(;;){let{done:d,value:m}=await r.read();if(d)break;let I=o.decode(m,{stream:!0}).split(`
|
|
2
2
|
`);for(let R of I){if(!R.startsWith("data: "))continue;let N=R.slice(6);if(N==="[DONE]"){this.debug&&this.log("STREAM",e+" [done]",void 0,{id:c,contentLength:p.length}),i(c);return}try{let g=JSON.parse(N);g.type==="done"&&g.id?c=g.id:g.content&&(p+=g.content,n(g.content))}catch{}}}c&&i(c)}async handleResponse(e){if(!e.ok){let n={};try{n=await e.json()}catch{}let i={401:"UNAUTHORIZED",402:"INSUFFICIENT_BALANCE",404:"GAME_NOT_FOUND",429:"RATE_LIMITED"},s=n.code||i[e.status]||"INTERNAL_ERROR";throw new l(s,n.message||`HTTP ${e.status}`)}let t=await e.json();return t&&typeof t=="object"&&"data"in t?t.data:t}};var F=[{value:"zh-CN",label:"\u7B80\u4F53\u4E2D\u6587"},{value:"zh-TW",label:"\u7E41\u9AD4\u4E2D\u6587"},{value:"en",label:"English"},{value:"ja",label:"\u65E5\u672C\u8A9E"},{value:"ko",label:"\uD55C\uAD6D\uC5B4"}],M=[{value:"low",label:"\u7B80\u77ED"},{value:"medium",label:"\u9002\u4E2D"},{value:"high",label:"\u8BE6\u7EC6"}],j=`
|
|
3
3
|
:host {
|
|
4
4
|
position: fixed;
|
|
@@ -428,5 +428,5 @@
|
|
|
428
428
|
}
|
|
429
429
|
.spin { animation: spin 0.8s linear infinite; }
|
|
430
430
|
`,V='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',z='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',W='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>',Z='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',K='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',u=class{constructor(e){this.selectedModelId="";this.models=[];this.modelPanel=null;this.settings={temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.hasWorldUpdate=!1;this.fabDot=null;this.syncHint=null;this.displayMode="phone";this.displayModeBtns=[];this.tempValueEl=null;this.tempSlider=null;this.segmentBtns=[];this.langSelect=null;this.noteInput=null;this.noteCounter=null;this.saveBtn=null;this.syncBtn=null;this.syncState="idle";this.panel=null;this.callbacks=e,this.host=document.createElement("div"),this.host.id="storvia-settings",this.shadowRoot=this.host.attachShadow({mode:"closed"})}mount(e,t,n,i=!1){this.models=e,this.selectedModelId=t,this.settings={...n},this.hasWorldUpdate=i;try{let s=localStorage.getItem("storvia_display_mode");(s==="phone"||s==="desktop")&&(this.displayMode=s)}catch{}document.body.appendChild(this.host),this.render()}unmount(){this.host.remove()}getSelectedModelId(){return this.selectedModelId}getSettings(){return{...this.settings}}render(){let e=document.createElement("style");e.textContent=j;let t=document.createElement("div"),n=document.createElement("div");n.className="fab-wrap";let i=document.createElement("button");i.className="fab",i.innerHTML=V,i.title="\u6E38\u620F\u8BBE\u7F6E";let s=document.createElement("div");s.className=`fab-dot${this.hasWorldUpdate?" visible":""}`,this.fabDot=s,n.appendChild(i),n.appendChild(s);let r=document.createElement("div");r.className="panel",this.panel=r;let o=document.createElement("div");o.className="panel-header";let c=document.createElement("div");c.className="panel-title",c.textContent="\u6E38\u620F\u8BBE\u7F6E";let p=document.createElement("button");p.className="close-btn",p.innerHTML="\u2715",p.addEventListener("click",()=>r.classList.remove("open")),o.appendChild(c),o.appendChild(p),r.appendChild(o);let d=document.createElement("div");d.className="panel-body",this.models.length>0&&(d.appendChild(this.buildModelSection()),d.appendChild(this.makeDivider())),d.appendChild(this.buildTemperatureSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildReplyLengthSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildReplyLanguageSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildNoteSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildDisplayModeSection()),d.appendChild(this.makeDivider()),d.appendChild(this.buildSyncSection());let m=document.createElement("div");m.className="save-row";let h=document.createElement("button");h.className="save-btn",h.textContent="\u4FDD\u5B58",this.saveBtn=h,h.addEventListener("click",()=>this.handleSave()),m.appendChild(h),d.appendChild(m),r.appendChild(d),i.addEventListener("click",()=>r.classList.toggle("open")),document.addEventListener("click",I=>{this.host.contains(I.target)||r.classList.remove("open")}),t.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(t)}buildModelSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="AI \u6A21\u578B",e.appendChild(t);let n=document.createElement("div");return n.className="model-list",this.modelPanel=n,this.models.forEach(i=>{let s=document.createElement("button");s.className=`model-option${i.id===this.selectedModelId?" active":""}`,s.innerHTML=`<span class="dot"></span><span>${i.name}</span>`,s.addEventListener("click",()=>{this.selectedModelId=i.id,this.callbacks.onModelChange(i.id);try{localStorage.setItem("storvia_model_id",i.id)}catch{}this.updateModelActive()}),n.appendChild(s)}),e.appendChild(n),e}buildTemperatureSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u66F4\u4F4E\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u3001\u7406\u667A\uFF1B\u66F4\u9AD8\u7684\u6E29\u5EA6\u4F1A\u8BA9 AI \u7684\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027\u548C\u968F\u673A\u6027",e.appendChild(s);let r=document.createElement("div");r.className="slider-wrap";let o=document.createElement("input");o.type="range",o.className="slider",o.min="0",o.max="2",o.step="0.1",o.value=String(this.settings.temperature),this.tempSlider=o,o.addEventListener("input",()=>{let p=parseFloat(o.value);this.settings.temperature=p,this.tempValueEl&&(this.tempValueEl.textContent=p.toFixed(1))}),r.appendChild(o);let c=document.createElement("div");return c.className="slider-labels",c.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",r.appendChild(c),e.appendChild(r),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment",this.segmentBtns=[],M.forEach(i=>{let s=document.createElement("button");s.className=`segment-btn${i.value===this.settings.reply_length?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.reply_length=i.value,this.segmentBtns.forEach((r,o)=>{r.classList.toggle("active",M[o].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="select-wrap";let i=document.createElement("select");i.className="select",this.langSelect=i,F.forEach(r=>{let o=document.createElement("option");o.value=r.value,o.textContent=r.label,r.value===this.settings.reply_language&&(o.selected=!0),i.appendChild(o)}),i.addEventListener("change",()=>{this.settings.reply_language=i.value});let s=document.createElement("span");return s.className="select-arrow",s.textContent="\u25BE",n.appendChild(i),n.appendChild(s),e.appendChild(n),e}buildNoteSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.textContent=`${this.settings.player_note.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("div");s.className="section-desc",s.textContent="\u5199\u4E0B\u4F60\u5BF9\u8FD9\u4E2A\u6E38\u620F\u7684\u5907\u6CE8\uFF0C\u4F1A\u663E\u793A\u5728\u5B58\u6863\u5217\u8868",e.appendChild(s);let r=document.createElement("div");r.className="note-wrap";let o=document.createElement("textarea");return o.className="note-input",o.placeholder="\u5907\u6CE8",o.maxLength=50,o.value=this.settings.player_note,this.noteInput=o,o.addEventListener("input",()=>{this.settings.player_note=o.value,this.noteCounter&&(this.noteCounter.textContent=`${o.value.length}/50`)}),r.appendChild(o),e.appendChild(r),e}buildDisplayModeSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u663E\u793A\u6A21\u5F0F",e.appendChild(t);let n=document.createElement("div");n.className="section-desc",n.textContent="\u7535\u8111\u6A21\u5F0F\u4F1A\u81EA\u52A8\u6A2A\u5C4F\u663E\u793A",e.appendChild(n);let i=document.createElement("div");i.className="segment",this.displayModeBtns=[];let s=[{value:"phone",label:"\u624B\u673A"},{value:"desktop",label:"\u7535\u8111"}];return s.forEach(r=>{let o=document.createElement("button");o.className=`segment-btn${r.value===this.displayMode?" active":""}`,o.textContent=r.label,o.addEventListener("click",()=>{this.displayMode=r.value;try{localStorage.setItem("storvia_display_mode",r.value)}catch{}this.displayModeBtns.forEach((c,p)=>{c.classList.toggle("active",s[p].value===r.value)});try{window.parent.postMessage({type:"storvia-orientation",mode:r.value==="desktop"?"landscape":"portrait"},"*")}catch{}}),this.displayModeBtns.push(o),i.appendChild(o)}),e.appendChild(i),e}buildSyncSection(){let e=document.createElement("div");e.className="section";let t=document.createElement("div");t.className="section-label",t.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A",e.appendChild(t);let n=document.createElement("div");n.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,n.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=n,e.appendChild(n);let i=document.createElement("div");i.className="sync-desc",i.textContent="\u5982\u679C\u6E38\u620F\u4F5C\u8005\u66F4\u65B0\u4E86\u5185\u5BB9\uFF0C\u70B9\u51FB\u6B64\u6309\u94AE\u53EF\u5C06\u6700\u65B0\u7684\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(i);let s=document.createElement("button");return s.className="sync-btn",this.syncBtn=s,this.renderSyncBtn(),s.addEventListener("click",async()=>{if(this.syncState!=="loading"){this.setSyncState("loading");try{await this.callbacks.onSync(),this.setSyncState("success"),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),setTimeout(()=>this.setSyncState("idle"),3e3)}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(s),e}makeDivider(){let e=document.createElement("div");return e.className="divider",e}updateModelActive(){this.modelPanel&&this.modelPanel.querySelectorAll(".model-option").forEach((e,t)=>{e.classList.toggle("active",this.models[t].id===this.selectedModelId)})}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:z,loading:W,success:Z,error:K},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`sync-btn${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.textContent="\u4FDD\u5B58\u4E2D...";try{await this.callbacks.onSettingsChange({temperature:this.settings.temperature,reply_length:this.settings.reply_length,reply_language:this.settings.reply_language,player_note:this.settings.player_note}),this.saveBtn.textContent="\u5DF2\u4FDD\u5B58",this.saveBtn.classList.add("saved"),setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.classList.remove("saved"),this.saveBtn.disabled=!1)},2e3)}catch{this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3)}}}};var v=class{constructor(e,t,n,i,s=!1,r){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/chat",t)}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,context:(e.context||"")+`
|
|
431
|
-
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new k(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var T=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new T(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var $="/functions/v1/world-engine/v1",J="https://api.storvia.ai";function Y(){return window.__STORVIA__||{}}function q(a=5e3){let e=Y();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},a);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var S=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await q(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${$}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let d=await this.fetchModels();this.modelId=e.selectedModelId||d[0]?.id||"",this.settingsSheet=new u({onModelChange:R=>{this.modelId=R},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),d.length>0&&this.settingsSheet.mount(d,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(d=>d.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:d=>{this.modelId=d},onSettingsChange:d=>this.saveSettings(d),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${J}${$}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function O(a){let e=new S;return a?.dev?await e.initDev(a.dev):await e.init(),e}function _(a){return typeof a=="object"&&a!==null&&"value"in a&&"type"in a&&(a.type==="number"||a.type==="text")}function L(a){return _(a)?a.value:a}return G(Q);})();
|
|
431
|
+
[\u6307\u4EE4] \u8BF7\u76F4\u63A5\u751F\u6210\u56DE\u590D\uFF0C\u65E0\u9700\u7528\u6237\u8F93\u5165`,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1,save:e.save??!0};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/generate",t)}async retry(e={}){if(this.isPreview)throw new Error("Retry is not supported in preview mode");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_context:e.context,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}return this.http.post("/retry",t)}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,context:e.context,prompt_config:this.previewConfig||{},history_messages:[]};if(e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}));return}let n="";return await this.http.stream("/preview",t,i=>{n+=i},()=>{}),{id:"",content:n}}};var k=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){return this.isPreview?{...this.mem[e]||{}}:this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,t)}},f=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];this.state=new k(e,t,n)}async list(){return this.isPreview?this.mem.map(e=>({name:e.name,avatar:e.avatar,...e.gender?{gender:e.gender}:{}})):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:t?.name||e,avatar:t?.avatar,...t?.gender?{gender:t.gender}:{}}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push(e);return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(i=>i.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};var y=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(i=>i.from===e&&i.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let i=this.mem.find(s=>s.from===e&&s.to===t);i?Object.assign(i,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var w=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let t={};for(let[n,i]of Object.entries(this.mem))t[n]={...i};return t}return e!==void 0?this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`):this.http.get(`/conversations/${this.getConversationId()}/inventory`)}async add(e){let{group:t,name:n,count:i=1,desc:s,iconUrl:r}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let o={count:i};s!==void 0&&(o.desc=s),r!==void 0&&(o.iconUrl=r),this.mem[t][n]=o;return}await this.http.post(`/conversations/${this.getConversationId()}/inventory`,{group:t,name:n,count:i,desc:s,iconUrl:r})}async update(e){let{group:t,name:n,...i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(n in s))throw new Error(`Item "${t}/${n}" not found`);Object.assign(s[n],i);return}await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,i)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:i,newName:s}=e;if(this.isPreview){let r=this.mem[t];if(!r||!(i in r))throw new Error(`Source item "${t}/${i}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let o=s||i;if(t===n&&o===i)return;if(o in this.mem[n])throw new Error(`Item "${o}" already exists in target group`);this.mem[n][o]=r[i],delete r[i];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:i,newName:s})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let s=this.mem[e];if(s&&Object.keys(s).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let i=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${i}`)}};var b=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var T=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},C=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};this.state=new T(e,t,n)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};var x=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(`/conversations/${this.getConversationId()}/custom`);return e!==void 0?t[e]:t}async set(e){if(this.isPreview){for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null&&!Array.isArray(n)&&typeof this.mem[t]=="object"&&this.mem[t]!==null?this.mem[t]={...this.mem[t],...n}:this.mem[t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom`,e)}async delete(e){if(this.isPreview){delete this.mem[e];return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`)}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};var O="/functions/v1/world-engine/v1",J="https://api.storvia.ai";function Y(){return window.__STORVIA__||{}}function q(a=5e3){let e=Y();return e.apiBase?Promise.resolve(e):new Promise((t,n)=>{let i=setTimeout(()=>{window.removeEventListener("message",s),n(new l("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},a);function s(r){let o=null;if(r.data?.type==="storvia-init"&&r.data.apiBase?o={apiBase:r.data.apiBase,gameId:r.data.gameId,accessToken:r.data.accessToken}:r.data?.type==="storvia-preview-init"&&r.data.config&&(o=r.data.config),o&&o.apiBase){clearTimeout(i),window.removeEventListener("message",s);let c=window;c.__STORVIA__=o,t(o)}}window.addEventListener("message",s)})}var S=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=await q(),t=e.apiBase;if(!t)throw new l("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${t}${O}`,this.isPreview=!!e.preview,this.previewConfig=e.previewConfig,!e.gameId)throw new l("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=e.gameId,!e.accessToken)throw new l("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=e.accessToken,this.http=new E(this.baseUrl,this.accessToken,!!e.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let d=await this.fetchModels();this.modelId=e.selectedModelId||d[0]?.id||"",this.settingsSheet=new u({onModelChange:R=>{this.modelId=R},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),d.length>0&&this.settingsSheet.mount(d,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let m=()=>this.gameId,h=()=>this.conversationId,I=()=>this.modelId;this.chat=new v(this.http,m,h,I,!0,this.previewConfig),this.characters=new f(this.http,h,!0),this.relationships=new y(this.http,h,!0),this.inventory=new w(this.http,h,!0),this.world=new b(this.http,h,!0),this.player=new C(this.http,h,!0),this.custom=new x(this.http,h,!0),this.initialized=!0,this.listenForPreviewMessages();return}let[n,i]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=n.conversationId;let s=this.getSavedModelId();this.modelId=s&&i.some(d=>d.id===s)?s:i[0]?.id||"";let r=n.settings||{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""};this.settingsSheet=new u({onModelChange:d=>{this.modelId=d},onSettingsChange:d=>this.saveSettings(d),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(i,this.modelId,r,n.hasWorldUpdate??!1);let o=()=>this.gameId,c=()=>this.conversationId,p=()=>this.modelId;this.chat=new v(this.http,o,c,p),this.characters=new f(this.http,c),this.relationships=new y(this.http,c),this.inventory=new w(this.http,c),this.world=new b(this.http,c),this.player=new C(this.http,c),this.custom=new x(this.http,c),this.initialized=!0}listenForPreviewMessages(){window.addEventListener("message",e=>{!e.data||e.data.type!=="storvia-preview"||(e.data.action==="set-model"&&(this.modelId=e.data.modelId||""),e.data.action==="update-config"&&(this.previewConfig=e.data.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig)))})}async saveSettings(e){await this.http.patch("/settings",{conversation_id:this.conversationId,...e})}async syncSettings(){await this.http.post("/sync",{conversation_id:this.conversationId})}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify({game_id:this.gameId})});if(!e.ok)throw e.status===401?new l("UNAUTHORIZED","User not authenticated"):e.status===404?new l("GAME_NOT_FOUND","Game not found or not published"):new l("INTERNAL_ERROR",`Auth failed: HTTP ${e.status}`);let t=await e.json();return t.data??t}getSavedModelId(){try{return localStorage.getItem("storvia_model_id")||""}catch{return""}}async initDev(e){if(this.initialized)return;this.baseUrl=`${J}${O}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new E(this.baseUrl,"",!1,e.apiKey);let t=await this.fetchModels();this.modelId=t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new u({onModelChange:r=>{this.modelId=r},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,reply_length:"medium",reply_language:"zh-CN",player_note:""},!1);let n=()=>this.gameId,i=()=>this.conversationId,s=()=>this.modelId;this.chat=new v(this.http,n,i,s,!0,void 0),this.characters=new f(this.http,i,!0),this.relationships=new y(this.http,i,!0),this.inventory=new w(this.http,i,!0),this.world=new b(this.http,i,!0),this.player=new C(this.http,i,!0),this.custom=new x(this.http,i,!0),this.initialized=!0}};async function $(a){let e=new S;return a?.dev?await e.initDev(a.dev):await e.init(),e}function _(a){return typeof a=="object"&&a!==null&&"value"in a&&"type"in a&&(a.type==="number"||a.type==="text")}function L(a){return _(a)?a.value:a}return G(Q);})();
|
|
432
432
|
if(typeof window!=="undefined"){window.createStorviaSDK=StorviaSDK.createStorviaSDK;}
|