@storvia/sdk 0.5.25 → 0.5.27
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 +12 -12
- package/dist/index.d.mts +5 -8
- package/dist/index.esm.js +11 -11
- package/dist/index.umd.js +12 -12
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var ne=Object.defineProperty;var
|
|
1
|
+
"use strict";var ne=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var ke=Object.prototype.hasOwnProperty;var Re=(o,e)=>{for(var t in e)ne(o,t,{get:e[t],enumerable:!0})},Pe=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Te(e))!ke.call(o,i)&&i!==t&&ne(o,i,{get:()=>e[i],enumerable:!(n=Ee(e,i))||n.enumerable});return o};var Me=o=>Pe(ne({},"__esModule",{value:!0}),o);var qe={};Re(qe,{PROTOCOL_VERSION:()=>O,StorviaBus:()=>R,StorviaError:()=>u,StorviaSDK:()=>W,createStorviaSDK:()=>Se,envelope:()=>I,extractFieldValue:()=>Ie,isProtocolEnvelope:()=>G,isRichFieldValue:()=>le,setToastEnabled:()=>me,showToast:()=>se});module.exports=Me(qe);var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var O=1;function G(o){if(!o||typeof o!="object")return!1;let e=o;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function I(o,e,t){return{protocol:1,type:o,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var R=class{constructor(e){this.handlers=new Map;this.pendingAcks=new Map;this.listener=null;this.incoming=e.incoming,this.getOutgoing=e.outgoing,this.verifySource=e.verifySource??(()=>!0),this.validate=e.validate,this.debug=!!e.debug,this.getTransferables=e.transfer??(()=>{}),this.customSend=e.customSend,this.attach()}attach(){this.listener=e=>{if((this.incoming instanceof Window||this.incoming===window)&&!this.verifySource(e))return;let t=e.data;if(!G(t))return;if(t.protocol!==1){this.debug&&console.warn("[StorviaBus] protocol mismatch",{expected:1,got:t.protocol,type:t.type});return}if(this.validate&&!this.validate(t)){this.debug&&console.warn("[StorviaBus] validation failed",t);return}if(t.ackId){let i=this.pendingAcks.get(t.ackId);if(i){this.pendingAcks.delete(t.ackId),i(t);return}}let n=this.handlers.get(t.type);if(!n||n.size===0){this.debug&&console.debug("[StorviaBus] no handler for",t.type);return}n.forEach(i=>{try{i(t)}catch(s){console.error(`[StorviaBus] handler '${t.type}' threw:`,s)}})},this.incoming.addEventListener("message",this.listener),this.incoming instanceof MessagePort&&this.incoming.start()}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let i=t;return n.add(i),()=>n.delete(i)}send(e){let t=e.protocol?e:I(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(s){console.error("[StorviaBus] customSend failed:",s,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let i=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,i??[]):n.postMessage(t,"*",i??[])}catch(s){console.error("[StorviaBus] postMessage failed:",s,{type:e.type})}}request(e,t=1e4){return new Promise((n,i)=>{let s=e.id??Oe(),r=I(e.type,e.payload,{id:s}),l=setTimeout(()=>{this.pendingAcks.delete(s),i(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(s,d=>{clearTimeout(l),n(d)}),this.send(r)})}destroy(){if(this.listener&&(this.incoming.removeEventListener("message",this.listener),this.listener=null),this.incoming instanceof MessagePort)try{this.incoming.close()}catch{}this.handlers.clear(),this.pendingAcks.clear()}};function Oe(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var ie=null;function pe(o){ie=o}var X="storvia-sdk-toast-style",Q="storvia-sdk-toast-stack",he=`
|
|
2
2
|
#${Q} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
.storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
|
|
220
220
|
.storvia-sheet-btn { height: 40px; font-size: 13px; }
|
|
221
221
|
}
|
|
222
|
-
`,
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,_e={success:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',error:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" 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>',warning:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',info:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>'},ue={UNAUTHORIZED:"\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55",INSUFFICIENT_CREDITS:"\u82B1\u56ED\u5E01\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u518D\u7EE7\u7EED\u6E38\u620F",VIOLATION_WORD_DETECTED:"\u5185\u5BB9\u542B\u6709\u8FDD\u7981\u8BCD\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5",CONTENT_FILTERED:"\u5185\u5BB9\u88AB\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u8BF7\u8C03\u6574\u540E\u91CD\u8BD5",MODEL_REFUSAL:"\u6A21\u578B\u62D2\u7EDD\u54CD\u5E94\uFF0C\u6362\u4E2A\u8BF4\u6CD5\u8BD5\u8BD5",STREAM_INTERRUPTED:"\u56DE\u590D\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",RATE_LIMITED:"\u64CD\u4F5C\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",MODEL_NOT_FOUND:"\u6240\u9009\u6A21\u578B\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5207\u6362\u5176\u4ED6\u6A21\u578B",GAME_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u6E38\u620F",INVALID_REQUEST:"\u8BF7\u6C42\u65E0\u6548\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",INTERNAL_ERROR:"\u670D\u52A1\u51FA\u4E86\u70B9\u5C0F\u95EE\u9898\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",NOT_INITIALIZED:"SDK \u5C1A\u672A\u521D\u59CB\u5316",NOT_SUPPORTED_IN_PREVIEW:"\u5F53\u524D\u63A5\u53E3\u5728\u9884\u89C8\u6A21\u5F0F\u4E0B\u4E0D\u53EF\u7528",NETWORK_ERROR:"\u7F51\u7EDC\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5",REQUEST_TIMEOUT:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",MODEL_LOADING_TIMEOUT:"\u6A21\u578B\u54CD\u5E94\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",STREAM_INACTIVITY:"\u8FDE\u63A5\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5"},ge=!0;function me(o){ge=o}function De(){if(typeof document>"u")return null;let o=document.getElementById(Q);if(!o){if(!document.getElementById(X)){let e=document.createElement("style");e.id=X,e.textContent=he,document.head.appendChild(e)}o=document.createElement("div"),o.id=Q,document.body.appendChild(o)}return o}function se(o,e="info",t=3500,n){if(!ge)return;let i=De();if(!i)return;let s=t<=0,r=document.createElement("div");r.className=`storvia-toast ${e}`,r.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${_e[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let l=r.querySelector(".storvia-toast-msg");l&&(l.textContent=o);let d=()=>{r.isConnected&&(r.classList.add("leaving"),r.classList.remove("show"),setTimeout(()=>r.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(c){console.error("[Storvia toast] action error:",c)}d()}),r.appendChild(a)}if(s){let a=document.createElement("button");a.type="button",a.className="storvia-toast-close",a.setAttribute("aria-label","\u5173\u95ED"),a.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',a.addEventListener("click",d),r.appendChild(a)}i.appendChild(r),requestAnimationFrame(()=>r.classList.add("show")),s||setTimeout(d,t)}function P(o,e){if(o==="INSUFFICIENT_CREDITS"){
|
|
225
|
+
`;let l=r.querySelector(".storvia-toast-msg");l&&(l.textContent=o);let d=()=>{r.isConnected&&(r.classList.add("leaving"),r.classList.remove("show"),setTimeout(()=>r.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(c){console.error("[Storvia toast] action error:",c)}d()}),r.appendChild(a)}if(s){let a=document.createElement("button");a.type="button",a.className="storvia-toast-close",a.setAttribute("aria-label","\u5173\u95ED"),a.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',a.addEventListener("click",d),r.appendChild(a)}i.appendChild(r),requestAnimationFrame(()=>r.classList.add("show")),s||setTimeout(d,t)}function P(o,e){if(o==="INSUFFICIENT_CREDITS"){Ne(e);return}let t=ue[o]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";se(t,o==="RATE_LIMITED"?"warning":"error")}var K=null;function Ne(o){if(typeof document>"u"||K)return;if(!document.getElementById(X)){let s=document.createElement("style");s.id=X,s.textContent=he,document.head.appendChild(s)}let e=o||ue.INSUFFICIENT_CREDITS,t=document.createElement("div");t.className="storvia-sheet-backdrop",t.innerHTML=`
|
|
226
226
|
<div class="storvia-sheet" role="dialog" aria-modal="true" aria-labelledby="storvia-sheet-title">
|
|
227
227
|
<div class="storvia-sheet-icon">
|
|
228
228
|
<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>
|
|
@@ -234,8 +234,8 @@
|
|
|
234
234
|
<button type="button" class="storvia-sheet-btn storvia-sheet-btn-primary" data-role="recharge">\u53BB\u5145\u503C</button>
|
|
235
235
|
</div>
|
|
236
236
|
</div>
|
|
237
|
-
`;let n=t.querySelector(".storvia-sheet-msg");n&&(n.textContent=e);let i=()=>{t.isConnected&&(t.classList.add("leaving"),t.classList.remove("show"),setTimeout(()=>{t.remove(),K===t&&(K=null)},240))};t.querySelector('[data-role="cancel"]')?.addEventListener("click",i),t.addEventListener("click",s=>{s.target===t&&i()}),t.querySelector('[data-role="recharge"]')?.addEventListener("click",()=>{if(ie)try{ie(I("navigate",{target:"wallet"})),console.log("[Storvia] navigate \u2192 wallet\uFF1A\u5DF2\u901A\u8FC7 bus \u901A\u77E5\u5BBF\u4E3B\u8DF3\u8F6C\u94B1\u5305\u9875")}catch(s){console.error("[Storvia] navigate \u2192 wallet \u901A\u8FC7 bus \u53D1\u9001\u5931\u8D25:",s)}else console.warn("[Storvia] navigate \u2192 wallet\uFF1A\u5F53\u524D\u672A\u68C0\u6D4B\u5230\u5BBF\u4E3B\uFF08dev \u6A21\u5F0F\uFF09\uFF0C\u6309\u94AE\u5DF2\u70B9\u4F46\u65E0\u4EBA\u63A5\u6536\u3002\u751F\u4EA7\u73AF\u5883\u4F1A\u81EA\u52A8\u8DF3\u5230\u4E3B\u7AD9 /wallet \u6216 App \u94B1\u5305\u9875\u3002");i()}),document.body.appendChild(t),K=t,requestAnimationFrame(()=>t.classList.add("show"))}var E=class E{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}maybeShowNetworkToast(e){e instanceof u||P("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return P("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),E.REQUEST_TIMEOUT);return{controller:e,clear:()=>clearTimeout(t)}}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){if(!this.debug)return;let{method:t,path:n,body:i,status:s,rawResponse:r,parsedData:l,error:d,durationMs:a,modelName:c}=e,h="%c[Storvia SDK]",v="color: #6366f1; font-weight: bold",g=a!==void 0?` (${a}ms)`:"",p=s!==void 0?` [${s}]`:"",m=c?` [model: ${c}]`:"";d?(console.groupCollapsed(`${h} %c${t} ${n}${p}${m}${g} %c\u2717`,v,"color: #e0e0e0","color: #ef4444"),i!==void 0&&console.log("Request:",i),r!==void 0&&console.log("Response (raw):",r),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${h} %c${t} ${n}${p}${m}${g} %c\u2713`,v,"color: #e0e0e0","color: #22c55e"),i!==void 0&&console.log("Request:",i),r!==void 0&&console.log("Response (raw):",r),l!==void 0&&l!==r&&console.log("Response (data):",l),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,c])=>n.searchParams.set(a,c));let i=Date.now(),s,r,{controller:l,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:l.signal});d(),s=a.status;let{raw:c,data:h}=await this.handleResponseWithRaw(a);return r=c,this.log({method:"GET",path:e,body:t,status:s,rawResponse:r,parsedData:h,durationMs:Date.now()-i}),h}catch(a){d();let c=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:s,rawResponse:r,error:c,durationMs:Date.now()-i}),c===a&&this.maybeShowNetworkToast(a),c}}async post(e,t,n){let i=Date.now(),s,r,{controller:l,clear:d}=this.createTimeoutController();try{let a=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:l.signal});d(),s=a.status;let{raw:c,data:h}=await this.handleResponseWithRaw(a);return r=c,this.log({method:"POST",path:e,body:t,status:s,rawResponse:r,parsedData:h,durationMs:Date.now()-i,modelName:n?.modelName}),h}catch(a){d();let c=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:s,rawResponse:r,error:c,durationMs:Date.now()-i,modelName:n?.modelName}),c===a&&this.maybeShowNetworkToast(a),c}}async patch(e,t){let n=Date.now(),i,s,{controller:r,clear:l}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:r.signal});l(),i=d.status;let{raw:a,data:c}=await this.handleResponseWithRaw(d);return s=a,this.log({method:"PATCH",path:e,body:t,status:i,rawResponse:s,parsedData:c,durationMs:Date.now()-n}),c}catch(d){l();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:i,rawResponse:s,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),i,s,{controller:r,clear:l}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:r.signal});l(),i=d.status;let{raw:a,data:c}=await this.handleResponseWithRaw(d);return s=a,this.log({method:"PUT",path:e,body:t,status:i,rawResponse:s,parsedData:c,durationMs:Date.now()-n}),c}catch(d){l();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:i,rawResponse:s,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,i,{controller:s,clear:r}=this.createTimeoutController();try{let l=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:s.signal});r(),n=l.status;let{raw:d,data:a}=await this.handleResponseWithRaw(l);return i=d,this.log({method:"DELETE",path:e,status:n,rawResponse:i,parsedData:a,durationMs:Date.now()-t}),a}catch(l){r();let d=this.wrapAbortError(l);throw this.log({method:"DELETE",path:e,status:n,rawResponse:i,error:d,durationMs:Date.now()-t}),d===l&&this.maybeShowNetworkToast(l),d}}async stream(e,t,n,i,s,r){let l=Date.now(),d=s?.modelName?` [model: ${s.modelName}]`:"",a=[],c=y=>{this.debug&&a.push({t:Date.now()-l,event:y})},h=new AbortController,v=null,g=null,p=null,m=null,w=()=>{v!==null&&(clearTimeout(v),v=null),g!==null&&(clearTimeout(g),g=null),p!==null&&(clearTimeout(p),p=null)},M=y=>{m=y,w(),h.abort()};v=setTimeout(()=>M("REQUEST_TIMEOUT"),E.REQUEST_TIMEOUT);let f;try{f=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:h.signal})}catch(y){if(w(),m){let b=new u(m,"Request timed out");throw P(m),this.log({method:"STREAM",path:e,body:t,error:b,durationMs:Date.now()-l,modelName:s?.modelName}),b}throw this.maybeShowNetworkToast(y),y}if(v!==null&&(clearTimeout(v),v=null),!f.ok){w();let y=await f.text().catch(()=>""),b={};try{b=JSON.parse(y)}catch{}let ee=b.code||"INTERNAL_ERROR",q=new u(ee,b.message||`HTTP ${f.status}`);throw P(ee,b.message),this.log({method:"STREAM",path:e,body:t,status:f.status,rawResponse:y,error:q,durationMs:Date.now()-l,modelName:s?.modelName}),q}let Y=f.body?.getReader();if(!Y)throw w(),new u("INTERNAL_ERROR","No response body for stream");g=setTimeout(()=>M("MODEL_LOADING_TIMEOUT"),E.MODEL_LOADING_TIMEOUT);let J=new TextDecoder,x="",k="",
|
|
238
|
-
`);for(let
|
|
237
|
+
`;let n=t.querySelector(".storvia-sheet-msg");n&&(n.textContent=e);let i=()=>{t.isConnected&&(t.classList.add("leaving"),t.classList.remove("show"),setTimeout(()=>{t.remove(),K===t&&(K=null)},240))};t.querySelector('[data-role="cancel"]')?.addEventListener("click",i),t.addEventListener("click",s=>{s.target===t&&i()}),t.querySelector('[data-role="recharge"]')?.addEventListener("click",()=>{if(ie)try{ie(I("navigate",{target:"wallet"})),console.log("[Storvia] navigate \u2192 wallet\uFF1A\u5DF2\u901A\u8FC7 bus \u901A\u77E5\u5BBF\u4E3B\u8DF3\u8F6C\u94B1\u5305\u9875")}catch(s){console.error("[Storvia] navigate \u2192 wallet \u901A\u8FC7 bus \u53D1\u9001\u5931\u8D25:",s)}else console.warn("[Storvia] navigate \u2192 wallet\uFF1A\u5F53\u524D\u672A\u68C0\u6D4B\u5230\u5BBF\u4E3B\uFF08dev \u6A21\u5F0F\uFF09\uFF0C\u6309\u94AE\u5DF2\u70B9\u4F46\u65E0\u4EBA\u63A5\u6536\u3002\u751F\u4EA7\u73AF\u5883\u4F1A\u81EA\u52A8\u8DF3\u5230\u4E3B\u7AD9 /wallet \u6216 App \u94B1\u5305\u9875\u3002");i()}),document.body.appendChild(t),K=t,requestAnimationFrame(()=>t.classList.add("show"))}var E=class E{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}maybeShowNetworkToast(e){e instanceof u||P("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return P("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),E.REQUEST_TIMEOUT);return{controller:e,clear:()=>clearTimeout(t)}}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){if(!this.debug)return;let{method:t,path:n,body:i,status:s,rawResponse:r,parsedData:l,error:d,durationMs:a,modelName:c}=e,h="%c[Storvia SDK]",v="color: #6366f1; font-weight: bold",g=a!==void 0?` (${a}ms)`:"",p=s!==void 0?` [${s}]`:"",m=c?` [model: ${c}]`:"";d?(console.groupCollapsed(`${h} %c${t} ${n}${p}${m}${g} %c\u2717`,v,"color: #e0e0e0","color: #ef4444"),i!==void 0&&console.log("Request:",i),r!==void 0&&console.log("Response (raw):",r),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${h} %c${t} ${n}${p}${m}${g} %c\u2713`,v,"color: #e0e0e0","color: #22c55e"),i!==void 0&&console.log("Request:",i),r!==void 0&&console.log("Response (raw):",r),l!==void 0&&l!==r&&console.log("Response (data):",l),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,c])=>n.searchParams.set(a,c));let i=Date.now(),s,r,{controller:l,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:l.signal});d(),s=a.status;let{raw:c,data:h}=await this.handleResponseWithRaw(a);return r=c,this.log({method:"GET",path:e,body:t,status:s,rawResponse:r,parsedData:h,durationMs:Date.now()-i}),h}catch(a){d();let c=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:s,rawResponse:r,error:c,durationMs:Date.now()-i}),c===a&&this.maybeShowNetworkToast(a),c}}async post(e,t,n){let i=Date.now(),s,r,{controller:l,clear:d}=this.createTimeoutController();try{let a=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:l.signal});d(),s=a.status;let{raw:c,data:h}=await this.handleResponseWithRaw(a);return r=c,this.log({method:"POST",path:e,body:t,status:s,rawResponse:r,parsedData:h,durationMs:Date.now()-i,modelName:n?.modelName}),h}catch(a){d();let c=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:s,rawResponse:r,error:c,durationMs:Date.now()-i,modelName:n?.modelName}),c===a&&this.maybeShowNetworkToast(a),c}}async patch(e,t){let n=Date.now(),i,s,{controller:r,clear:l}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:r.signal});l(),i=d.status;let{raw:a,data:c}=await this.handleResponseWithRaw(d);return s=a,this.log({method:"PATCH",path:e,body:t,status:i,rawResponse:s,parsedData:c,durationMs:Date.now()-n}),c}catch(d){l();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:i,rawResponse:s,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),i,s,{controller:r,clear:l}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:r.signal});l(),i=d.status;let{raw:a,data:c}=await this.handleResponseWithRaw(d);return s=a,this.log({method:"PUT",path:e,body:t,status:i,rawResponse:s,parsedData:c,durationMs:Date.now()-n}),c}catch(d){l();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:i,rawResponse:s,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,i,{controller:s,clear:r}=this.createTimeoutController();try{let l=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:s.signal});r(),n=l.status;let{raw:d,data:a}=await this.handleResponseWithRaw(l);return i=d,this.log({method:"DELETE",path:e,status:n,rawResponse:i,parsedData:a,durationMs:Date.now()-t}),a}catch(l){r();let d=this.wrapAbortError(l);throw this.log({method:"DELETE",path:e,status:n,rawResponse:i,error:d,durationMs:Date.now()-t}),d===l&&this.maybeShowNetworkToast(l),d}}async stream(e,t,n,i,s,r){let l=Date.now(),d=s?.modelName?` [model: ${s.modelName}]`:"",a=[],c=y=>{this.debug&&a.push({t:Date.now()-l,event:y})},h=new AbortController,v=null,g=null,p=null,m=null,w=()=>{v!==null&&(clearTimeout(v),v=null),g!==null&&(clearTimeout(g),g=null),p!==null&&(clearTimeout(p),p=null)},M=y=>{m=y,w(),h.abort()};v=setTimeout(()=>M("REQUEST_TIMEOUT"),E.REQUEST_TIMEOUT);let f;try{f=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:h.signal})}catch(y){if(w(),m){let b=new u(m,"Request timed out");throw P(m),this.log({method:"STREAM",path:e,body:t,error:b,durationMs:Date.now()-l,modelName:s?.modelName}),b}throw this.maybeShowNetworkToast(y),y}if(v!==null&&(clearTimeout(v),v=null),!f.ok){w();let y=await f.text().catch(()=>""),b={};try{b=JSON.parse(y)}catch{}let ee=b.code||"INTERNAL_ERROR",q=new u(ee,b.message||`HTTP ${f.status}`);throw P(ee,b.message),this.log({method:"STREAM",path:e,body:t,status:f.status,rawResponse:y,error:q,durationMs:Date.now()-l,modelName:s?.modelName}),q}let Y=f.body?.getReader();if(!Y)throw w(),new u("INTERNAL_ERROR","No response body for stream");g=setTimeout(()=>M("MODEL_LOADING_TIMEOUT"),E.MODEL_LOADING_TIMEOUT);let J=new TextDecoder,x="",k="",de=!1;try{for(;;){let{done:y,value:b}=await Y.read();if(y)break;let q=J.decode(b,{stream:!0}).split(`
|
|
238
|
+
`);for(let ce of q){if(!ce.startsWith("data: "))continue;let te=ce.slice(6);if(te==="[DONE]"){c("[DONE]"),w(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${f.status}]${d} (${Date.now()-l}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${k.length} chars):`,k),console.log("Message ID:",x),console.log(`SSE events (${a.length}):`,a),console.groupEnd()),i(x);return}try{let S=JSON.parse(te);c(S),S.type==="done"&&S.id?x=S.id:S.type==="state"?r&&r(S.delta,S.full??null):S.content&&(de?(p!==null&&clearTimeout(p),p=setTimeout(()=>M("STREAM_INACTIVITY"),E.STREAM_INACTIVITY_TIMEOUT)):(de=!0,g!==null&&(clearTimeout(g),g=null),p=setTimeout(()=>M("STREAM_INACTIVITY"),E.STREAM_INACTIVITY_TIMEOUT)),k+=S.content,n(S.content))}catch{c({raw:te})}}}}catch(y){if(w(),m){let b=new u(m,m==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw P(m),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${f.status}]${d} (${Date.now()-l}ms) %c\u2717 ${m}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${k.length} chars):`,k),console.log(`SSE events (${a.length}):`,a),console.error("Timeout:",b),console.groupEnd()),b}throw this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${f.status}]${d} (${Date.now()-l}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${k.length} chars):`,k),console.log(`SSE events (${a.length}):`,a),console.error("Stream error:",y),console.groupEnd()),y}w(),x&&i(x)}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let i=n&&typeof n=="object"?n:{},s={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",404:"GAME_NOT_FOUND",429:"RATE_LIMITED"},r=i.code||s[e.status]||"INTERNAL_ERROR",l=new u(r,i.message||`HTTP ${e.status}`);throw P(r,i.message),l}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};E.REQUEST_TIMEOUT=6e4,E.MODEL_LOADING_TIMEOUT=18e4,E.STREAM_INACTIVITY_TIMEOUT=6e4;var j=E;var V=[{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"}],fe=[{value:"low",label:"\u7B80\u77ED"},{value:"medium",label:"\u9002\u4E2D"},{value:"high",label:"\u8BE6\u7EC6"}],Le="https://cdn.storvia.ai/default/logo.png",Ae="https://api.storvia.ai/storage/v1/object/public/storvia/default/credits.png",$e=`
|
|
239
239
|
:host {
|
|
240
240
|
position: fixed;
|
|
241
241
|
z-index: 2147483647;
|
|
@@ -1020,16 +1020,16 @@
|
|
|
1020
1020
|
padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
|
|
1021
1021
|
}
|
|
1022
1022
|
}
|
|
1023
|
-
`,
|
|
1023
|
+
`,Ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>',Be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6M3 12a9 9 0 0 1 15-6.7L21 8M3 22v-6h6M21 12a9 9 0 0 1-15 6.7L3 16"/></svg>',He='<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>',Fe='<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>',Ge='<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>',ve='<svg class="check" viewBox="0 0 24 24" fill="none" stroke="#8246FF" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',C=48,T=16,je=5,_=class{constructor(e){this.selectedModelId="";this.pendingModelId="";this.fabWrap=null;this.models=[];this.settings={temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""};this.activeTab="model";this.selectedCategory=null;this.hasWorldUpdate=!1;this.fabDot=null;this.syncHint=null;this.syncDot=null;this.fabX=0;this.fabY=0;this.fab=null;this.panel=null;this.modelTabBtn=null;this.settingsTabBtn=null;this.modelBody=null;this.settingsBody=null;this.footer=null;this.modelGrid=null;this.modelDetail=null;this.tempValueEl=null;this.segmentBtns=[];this.langDropdown=null;this.langOptions=[];this.langArrow=null;this.langDropdownOpen=!1;this.noteCounter=null;this.saveBtn=null;this.syncBtn=null;this.syncState="idle";this.dragStartX=0;this.dragStartY=0;this.dragOffsetX=0;this.dragOffsetY=0;this.dragMoved=!1;this.dragging=!1;this.updateDialogOpen=!1;this.handlePointerDown=e=>{this.fab&&(e.preventDefault(),this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.dragOffsetX=e.clientX-this.fabX,this.dragOffsetY=e.clientY-this.fabY,this.dragMoved=!1,this.dragging=!0,this.fab.setPointerCapture(e.pointerId),this.fab.addEventListener("pointermove",this.handlePointerMove),this.fab.addEventListener("pointerup",this.handlePointerUp),this.fab.addEventListener("pointercancel",this.handlePointerUp))};this.handlePointerMove=e=>{if(!this.dragging)return;let t=e.clientX-this.dragStartX,n=e.clientY-this.dragStartY;!this.dragMoved&&Math.hypot(t,n)>je&&(this.dragMoved=!0,this.fab?.classList.add("dragging"),this.closePanel()),this.dragMoved&&(this.fabX=e.clientX-this.dragOffsetX,this.fabY=e.clientY-this.dragOffsetY,this.applyHostPosition())};this.handlePointerUp=e=>{if(!this.fab)return;this.fab.removeEventListener("pointermove",this.handlePointerMove),this.fab.removeEventListener("pointerup",this.handlePointerUp),this.fab.removeEventListener("pointercancel",this.handlePointerUp);try{this.fab.releasePointerCapture(e.pointerId)}catch{}if(this.dragging=!1,!this.dragMoved){this.togglePanel();return}this.fab.classList.remove("dragging");let n=this.fabX+C/2<window.innerWidth/2;this.fabX=n?T:window.innerWidth-C-T,this.fabY=Math.max(T,Math.min(window.innerHeight-C-T,this.fabY)),this.fab&&(this.fab.style.transition="left 0.25s cubic-bezier(0.32, 0.72, 0, 1), top 0.25s cubic-bezier(0.32, 0.72, 0, 1), transform 0.2s, box-shadow 0.2s"),this.applyHostPosition(),setTimeout(()=>{this.fab&&(this.fab.style.transition="")},260)};this.handleResize=()=>{this.fabX=Math.max(T,Math.min(window.innerWidth-C-T,this.fabX)),this.fabY=Math.max(T,Math.min(window.innerHeight-C-T,this.fabY)),this.applyHostPosition()};this.handleDocClick=e=>{this.host.contains(e.target)||(this.closePanel(),this.closeLangDropdown())};this.savedBodyOverflow=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.pendingModelId=t,this.settings={...n},this.hasWorldUpdate=i,this.fabX=window.innerWidth-C-T,this.fabY=window.innerHeight-C-T,document.body.appendChild(this.host),this.render(),this.applyHostPosition(),window.addEventListener("resize",this.handleResize),document.addEventListener("click",this.handleDocClick),i&&setTimeout(()=>this.showUpdateDialog("prompt"),600)}unmount(){window.removeEventListener("resize",this.handleResize),document.removeEventListener("click",this.handleDocClick),this.host.remove()}getSelectedModelId(){return this.selectedModelId}getSettings(){return{...this.settings}}render(){let e=document.createElement("style");e.textContent=$e;let t=document.createElement("div");t.className="fab-wrap",this.fabWrap=t;let n=document.createElement("div");n.className="fab",n.title="\u6E38\u620F\u8BBE\u7F6E";let i=document.createElement("img");i.src=Le,i.alt="Storvia",n.appendChild(i),this.fab=n;let s=document.createElement("div");s.className=`fab-dot${this.hasWorldUpdate?" visible":""}`,this.fabDot=s,t.appendChild(n),t.appendChild(s);let r=document.createElement("div");r.className="panel",this.panel=r;let l=document.createElement("div");l.className="panel-header";let d=document.createElement("h2");d.className="panel-title",d.textContent="\u6E38\u620F\u8BBE\u7F6E";let a=document.createElement("button");a.className="close-btn",a.innerHTML=Ue,a.addEventListener("click",()=>this.closePanel()),l.appendChild(d),l.appendChild(a),r.appendChild(l);let c=document.createElement("div");c.className="tabs",this.modelTabBtn=this.createTabBtn("model","\u6A21\u578B\u9009\u62E9"),this.settingsTabBtn=this.createTabBtn("settings","\u6E38\u620F\u8BBE\u7F6E"),this.models.length===0&&(this.activeTab="settings",this.modelTabBtn.style.display="none"),c.appendChild(this.modelTabBtn),c.appendChild(this.settingsTabBtn),r.appendChild(c);let h=document.createElement("div");h.className="panel-body",this.modelBody=this.buildModelTab(),this.settingsBody=this.buildSettingsTab(),h.appendChild(this.modelBody),h.appendChild(this.settingsBody),r.appendChild(h);let v=document.createElement("div");v.className="panel-footer";let g=document.createElement("button");g.className="btn btn-save",g.textContent="\u4FDD\u5B58",this.saveBtn=g,g.addEventListener("click",()=>this.handleSave()),v.appendChild(g),this.footer=v,r.appendChild(v),n.addEventListener("pointerdown",this.handlePointerDown);let p=document.createElement("div");p.appendChild(r),p.appendChild(t),this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(p),this.applyTab()}createTabBtn(e,t){let n=document.createElement("button");return n.className=`tab-btn${this.activeTab===e?" active":""}`,n.textContent=t,n.addEventListener("click",()=>{this.activeTab=e,this.applyTab()}),n}applyTab(){this.modelTabBtn&&this.modelTabBtn.classList.toggle("active",this.activeTab==="model"),this.settingsTabBtn&&this.settingsTabBtn.classList.toggle("active",this.activeTab==="settings"),this.modelBody&&(this.modelBody.style.display=this.activeTab==="model"?"block":"none"),this.settingsBody&&(this.settingsBody.style.display=this.activeTab==="settings"?"block":"none"),this.footer&&(this.footer.style.display="flex")}buildModelTab(){let e=document.createElement("div"),t=this.getCategories();if(t.length>0){let s=document.createElement("div");s.className="category-tabs";let r=(l,d)=>{let a=document.createElement("button");return a.className=`category-tab${this.selectedCategory===d?" active":""}`,a.textContent=l,a.addEventListener("click",()=>{this.selectedCategory=d,s.querySelectorAll(".category-tab").forEach(c=>c.classList.remove("active")),a.classList.add("active"),this.renderModelGrid()}),a};s.appendChild(r("\u5168\u90E8",null)),t.forEach(l=>s.appendChild(r(l,l))),e.appendChild(s)}let n=document.createElement("div");n.className="models-grid",this.modelGrid=n,e.appendChild(n);let i=document.createElement("div");return i.className="model-detail",i.style.display="none",this.modelDetail=i,e.appendChild(i),this.renderModelGrid(),this.renderModelDetail(),e}getCategories(){let e=new Set;return this.models.forEach(t=>{t.category&&e.add(t.category)}),Array.from(e)}getFilteredModels(){return this.selectedCategory?this.models.filter(e=>e.category===this.selectedCategory):this.models}renderModelGrid(){this.modelGrid&&(this.modelGrid.innerHTML="",this.getFilteredModels().forEach(e=>{let t=document.createElement("button"),n=e.is_active!==!1;t.className=`model-card${e.id===this.pendingModelId?" selected":""}${n?"":" disabled"}`;let i=this.getStatusDotColor(e);t.innerHTML=`<span class="status-dot" style="background:${i}"></span><span class="model-name">${this.escapeHtml(e.name)}</span>`,t.addEventListener("click",()=>this.handleSelectModel(e)),this.modelGrid.appendChild(t)}))}handleSelectModel(e){this.pendingModelId=e.id;let t=this.getFilteredModels();this.modelGrid&&this.modelGrid.querySelectorAll(".model-card").forEach((n,i)=>{n.classList.toggle("selected",t[i].id===this.pendingModelId)}),this.renderModelDetail()}renderModelDetail(){if(!this.modelDetail)return;let e=this.models.find(l=>l.id===this.pendingModelId);if(!e){this.modelDetail.style.display="none";return}this.modelDetail.style.display="block";let t=this.getStatusClass(e),n=this.getStatusText(e),i=this.getCreditsValue(e),s=this.getCreditsUnit(e),r=e.description||"";this.modelDetail.innerHTML=`
|
|
1024
1024
|
<div class="detail-header">
|
|
1025
1025
|
<span class="detail-title">${this.escapeHtml(e.name)}</span>
|
|
1026
1026
|
<span class="detail-status ${t}">${n}</span>
|
|
1027
1027
|
</div>
|
|
1028
|
-
${i?`<div class="detail-credits">
|
|
1028
|
+
${i!==null?`<div class="detail-credits">
|
|
1029
1029
|
<span class="credits-label">\u6D88\u8017</span>
|
|
1030
1030
|
<span class="credits-value">${i}</span>
|
|
1031
|
-
<img class="credits-icon" src="${
|
|
1032
|
-
<span class="credits-unit"
|
|
1031
|
+
<img class="credits-icon" src="${Ae}" alt="credits" />
|
|
1032
|
+
<span class="credits-unit">${s}</span>
|
|
1033
1033
|
</div>`:""}
|
|
1034
|
-
${
|
|
1035
|
-
`}getStatusDotColor(e){if(e.is_active===!1)return"#6b7280";let t=e.success_rate??100;return t>=90?"#10b981":t>=80?"#3b82f6":t>=60?"#eab308":"#f97316"}getStatusClass(e){if(e.is_active===!1)return"inactive";let t=e.success_rate??100;return t>=90?"excellent":t>=80?"good":t>=60?"normal":"crowded"}getStatusText(e){if(e.is_active===!1)return"\u505C\u7528";let t=e.success_rate??100;return t>=90?"\u6D41\u7545":t>=80?"\u826F\u597D":t>=60?"\u4E00\u822C":"\u62E5\u6324"}getCreditsRange(e){let t=e.credits_config?.min??0,n=e.credits_config?.max??0;return t===0&&n===0?"":t===n?`${t}`:`${t}\uFF5E${n}`}buildSettingsTab(){let e=document.createElement("div"),t=document.createElement("div");return t.className="form-stack",t.appendChild(this.buildTemperatureSection()),t.appendChild(this.buildReplyLengthSection()),t.appendChild(this.buildReplyLanguageSection()),t.appendChild(this.buildNoteSection()),t.appendChild(this.buildSyncSection()),e.appendChild(t),e}buildTemperatureSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="temperature-value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className="form-hint",s.textContent="\u66F4\u4F4E\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u7406\u667A\uFF0C\u66F4\u9AD8\u8BA9\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027",e.appendChild(s);let r=document.createElement("input");r.type="range",r.className="slider",r.min="0",r.max="1",r.step="0.1",r.value=String(this.settings.temperature),r.addEventListener("input",()=>{let d=parseFloat(r.value);this.settings.temperature=d,this.tempValueEl&&(this.tempValueEl.textContent=d.toFixed(1))}),e.appendChild(r);let l=document.createElement("div");return l.className="slider-labels",l.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",e.appendChild(l),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment-control",this.segmentBtns=[],be.forEach(i=>{let s=document.createElement("button");s.className=`segment-button${i.value===this.settings.replyLength?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.replyLength=i.value,this.segmentBtns.forEach((r,l)=>{r.classList.toggle("active",be[l].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="custom-select";let i=document.createElement("button");i.className="select-trigger";let s=document.createElement("span");s.textContent=V.find(d=>d.value===this.settings.replyLanguage)?.label||"";let r=document.createElement("span");r.className="select-arrow",r.textContent="\u25BE",this.langArrow=r,i.appendChild(s),i.appendChild(r),i.addEventListener("click",d=>{d.stopPropagation(),this.toggleLangDropdown()}),n.appendChild(i);let l=document.createElement("div");return l.className="select-dropdown",this.langDropdown=l,this.langOptions=[],V.forEach(d=>{let a=document.createElement("button");a.className=`select-option${d.value===this.settings.replyLanguage?" active":""}`,a.innerHTML=`<span>${d.label}</span>${d.value===this.settings.replyLanguage?we:""}`,a.addEventListener("click",()=>{this.settings.replyLanguage=d.value,s.textContent=d.label,this.langOptions.forEach((c,h)=>{c.classList.toggle("active",V[h].value===d.value),c.innerHTML=`<span>${V[h].label}</span>${V[h].value===d.value?we:""}`}),this.closeLangDropdown()}),this.langOptions.push(a),l.appendChild(a)}),n.appendChild(l),e.appendChild(n),e}toggleLangDropdown(){this.langDropdownOpen?this.closeLangDropdown():this.openLangDropdown()}openLangDropdown(){this.langDropdownOpen=!0,this.langDropdown?.classList.add("open"),this.langArrow&&(this.langArrow.textContent="\u25B4")}closeLangDropdown(){this.langDropdownOpen=!1,this.langDropdown?.classList.remove("open"),this.langArrow&&(this.langArrow.textContent="\u25BE")}buildNoteSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.className="char-count",i.textContent=`${this.settings.playerNote.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className="form-hint",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("textarea");return r.className="player-note-input",r.placeholder="\u5907\u6CE8",r.maxLength=50,r.rows=2,r.value=this.settings.playerNote,r.addEventListener("input",()=>{this.settings.playerNote=r.value,this.noteCounter&&(this.noteCounter.textContent=`${r.value.length}/50`)}),e.appendChild(r),e}buildSyncSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label sync-label-wrap";let n=document.createElement("span");n.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A";let i=document.createElement("span");i.className=`sync-label-dot${this.hasWorldUpdate?" visible":""}`,this.syncDot=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,s.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=s,e.appendChild(s);let r=document.createElement("p");r.className="form-hint",r.textContent="\u5C06\u6700\u65B0\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(r);let l=document.createElement("button");return l.className="btn btn-sync",this.syncBtn=l,this.renderSyncBtn(),l.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.syncDot&&this.syncDot.classList.remove("visible"),this.syncHint&&(this.syncHint.textContent="\u2705 \u540C\u6B65\u6210\u529F\uFF0C\u8BF7\u9000\u51FA\u6E38\u620F\u540E\u91CD\u65B0\u6253\u5F00\uFF0C\u6700\u65B0\u8BBE\u5B9A\u5373\u53EF\u751F\u6548",this.syncHint.classList.add("visible")),setTimeout(()=>this.setSyncState("idle"),3e3),this.showUpdateDialog("success")}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(l),e}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:Fe,loading:Ge,success:je,error:Ve},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`btn btn-sync${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}showUpdateDialog(e="prompt"){if(this.updateDialogOpen)return;this.updateDialogOpen=!0;let t=document.createElement("div");t.className="confirm-overlay";let n=document.createElement("div");n.className="confirm-dialog";let i=document.createElement("h3");i.className="confirm-title";let s=document.createElement("p");s.className="confirm-message";let r=document.createElement("div");r.className="confirm-actions",n.appendChild(i),n.appendChild(s),n.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(t);let l=()=>{this.updateDialogOpen=!1,t.classList.remove("visible"),setTimeout(()=>t.remove(),200)},d=(c,h,v)=>{let g=document.createElement("button");return g.className=`btn ${h}`,g.textContent=c,g.addEventListener("click",v),g},a=c=>{r.innerHTML="",c==="prompt"?(i.textContent="\u68C0\u6D4B\u5230\u65B0\u7248\u672C",s.textContent="\u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u662F\u5426\u7ACB\u5373\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A\uFF1F",r.appendChild(d("\u7A0D\u540E","btn-confirm-cancel",l)),r.appendChild(d("\u7ACB\u5373\u66F4\u65B0","btn-confirm-ok",async()=>{a("syncing");try{await this.callbacks.onSync(),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncDot&&this.syncDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),this.setSyncState("success"),setTimeout(()=>this.setSyncState("idle"),3e3),a("success")}catch{a("error")}}))):c==="syncing"?(i.textContent="\u6B63\u5728\u540C\u6B65",s.innerHTML='<span class="spinner"></span><span>\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A\u4E2D\uFF0C\u8BF7\u7A0D\u5019...</span>'):c==="success"?(i.textContent="\u540C\u6B65\u6210\u529F",s.textContent="\u9700\u8981\u91CD\u65B0\u542F\u52A8\u6E38\u620F\u624D\u80FD\u5E94\u7528\u6700\u65B0\u8BBE\u5B9A\u3002",r.appendChild(d("\u91CD\u65B0\u542F\u52A8","btn-confirm-ok",()=>{l();try{window.parent.postMessage({type:"storvia-exit"},"*")}catch{}}))):(i.textContent="\u540C\u6B65\u5931\u8D25",s.textContent="\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF0C\u6216\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u3002",r.appendChild(d("\u5173\u95ED","btn-confirm-cancel",l)))};t.addEventListener("click",c=>{c.target===t&&e==="prompt"&&l()}),a(e),requestAnimationFrame(()=>t.classList.add("visible"))}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.innerHTML='<span class="spinner"></span>\u4FDD\u5B58\u4E2D...';try{if(this.pendingModelId&&this.pendingModelId!==this.selectedModelId){let e=this.models.find(t=>t.id===this.pendingModelId);if(e&&e.is_active!==!1){this.selectedModelId=this.pendingModelId,this.callbacks.onModelChange(this.pendingModelId);try{localStorage.setItem("storvia_model_id",this.pendingModelId)}catch{}}else this.pendingModelId=this.selectedModelId}await this.callbacks.onSettingsChange({temperature:this.settings.temperature,replyLength:this.settings.replyLength,replyLanguage:this.settings.replyLanguage,playerNote:this.settings.playerNote}),this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1),this.closePanel()}catch{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3))}}}escapeHtml(e){return e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}applyHostPosition(){this.host.style.left=`${this.fabX}px`,this.host.style.top=`${this.fabY}px`,this.host.style.right="auto",this.host.style.bottom="auto",this.applyPanelPosition()}isMobile(){return window.innerWidth<=768}applyPanelPosition(){if(!this.panel)return;if(this.isMobile()){this.panel.style.left="",this.panel.style.right="",this.panel.style.top="",this.panel.style.bottom="";return}let e=this.fabX+C/2<window.innerWidth/2,t=380;e?(this.panel.style.left="0",this.panel.style.right="auto"):(this.panel.style.left=`${C-t}px`,this.panel.style.right="auto"),this.fabY>500?(this.panel.style.bottom=`${C+8}px`,this.panel.style.top="auto"):(this.panel.style.top=`${C+8}px`,this.panel.style.bottom="auto")}togglePanel(){this.panel&&(this.panel.classList.contains("open")?this.closePanel():(this.applyPanelPosition(),this.panel.classList.add("open"),requestAnimationFrame(()=>{this.panel?.classList.contains("open")&&(this.fab&&(this.fab.style.visibility="hidden"),this.fabDot&&(this.fabDot.style.visibility="hidden"),this.fabWrap&&(this.fabWrap.style.pointerEvents="none"))}),this.isMobile()&&this.lockBodyScroll()))}closePanel(){if(this.panel&&this.panel.classList.remove("open"),this.fab&&(this.fab.style.visibility="visible"),this.fabDot&&(this.fabDot.style.visibility="visible"),this.fabWrap&&(this.fabWrap.style.pointerEvents=""),this.unlockBodyScroll(),this.pendingModelId!==this.selectedModelId){if(this.pendingModelId=this.selectedModelId,this.modelGrid){let e=this.getFilteredModels();this.modelGrid.querySelectorAll(".model-card").forEach((t,n)=>{t.classList.toggle("selected",e[n].id===this.pendingModelId)})}this.renderModelDetail()}}lockBodyScroll(){this.savedBodyOverflow===null&&(this.savedBodyOverflow=document.body.style.overflow||"",document.body.style.overflow="hidden")}unlockBodyScroll(){this.savedBodyOverflow!==null&&(document.body.style.overflow=this.savedBodyOverflow,this.savedBodyOverflow=null)}};var D=class{constructor(e,t,n,i,s=!1,r,l,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r,this.getSettings=l,this.getModelName=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}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_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/chat",t,this.reqMeta())}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,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(i=>({uuid:i.uuid,role:i.role,content:i.content,topic:i.topic,status:i.status,model:i.model,createdAt:i.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[]};this.previewConfig?t.prompt_config=this.previewConfig:t.game_id=this.getGameId();let n=this.getSettings?.();if(n&&(typeof n.temperature=="number"&&(t.temperature=n.temperature),n.replyLength&&(t.reply_length=n.replyLength),n.replyLanguage&&(t.reply_language=n.replyLanguage)),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}let i="",s=null,r=null;await this.http.stream("/preview",t,d=>{i+=d},()=>{},this.reqMeta(),(d,a)=>{s=d,r=a,e.onState&&e.onState(s,r)});let l={id:"",content:i};return s&&(l.delta=s,r&&(l.full=r)),l}};function Z(o){if(o)return(e,t)=>o(e,t)}var oe=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let i=this.mem[e]||{};return t?{...i[t]||{}}:{...i}}let n=t?{group:t}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,n)}async update(e,t,n){if(this.isPreview){let i=this.mem[e]||(this.mem[e]={});i[t]={...i[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},N=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];i&&(this.mem=i.map(xe)),this.state=new oe(e,t,n,s)}setInitial(e,t){this.mem=e?e.map(xe):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Ce):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Ce(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});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,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},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})}};function xe(o){return{name:o.name,description:o.description,avatar:o.avatar,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.gender?{gender:o.gender}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}function Ce(o){return{name:o.name,avatar:o.avatar,description:o.description,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.gender?{gender:o.gender}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}var L=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];i&&(this.mem=i.map(s=>({...s})))}setInitial(e){this.mem=e?e.map(t=>({...t})):[]}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)}`)}};function Se(o){let e={count:o.count};return o.desc!==void 0&&(e.desc=o.desc),o.icon_url!==void 0&&(e.iconUrl=o.icon_url),e}function ae(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o)){let i={};for(let[s,r]of Object.entries(n))i[s]=Se(r);e[t]=i}return e}function We(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=Se(n);return e}var A=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem=ae(i))}setInitial(e){this.mem=e?ae(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[i,s]of Object.entries(this.mem))n[i]={...s};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return We(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ae(t)}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 d={count:i};s!==void 0&&(d.desc=s),r!==void 0&&(d.iconUrl=r),this.mem[t][n]=d;return}let l={group:t,name:n,count:i};s!==void 0&&(l.desc=s),r!==void 0&&(l.icon_url=r),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,l)}async update(e){let{group:t,name:n,count:i,desc:s,iconUrl:r}=e;if(this.isPreview){let d=this.mem[t];if(!d||!(n in d))throw new Error(`Item "${t}/${n}" not found`);let a=d[n];i!==void 0&&(a.count=i),s!==void 0&&(a.desc=s),r!==void 0&&(a.iconUrl=r);return}let l={};i!==void 0&&(l.count=i),s!==void 0&&(l.desc=s),r!==void 0&&(l.icon_url=r),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,l)}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 l=s||i;if(t===n&&l===i)return;if(l in this.mem[n])throw new Error(`Item "${l}" already exists in target group`);this.mem[n][l]=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 $=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}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 le=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}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})}},U=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};i&&(this.memPersona={...i}),this.state=new le(e,t,n,s)}setInitial(e,t){this.memPersona=e?{...e}:{name:""},this.state.setInitial(t)}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 B=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};this.memInject={};i&&(this.mem=Ie(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Ie(e):{},this.memInject=t?{...t}:{}}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,t){if(this.isPreview){for(let[i,s]of Object.entries(e))typeof s=="object"&&s!==null&&typeof this.mem[i]=="object"&&this.mem[i]!==null?this.mem[i]={...this.mem[i],...s}:this.mem[i]=s,t?.inject!==void 0&&(this.memInject[i]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(`/conversations/${this.getConversationId()}/custom`,n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,{inject:t})}getInject(){return{...this.memInject}}async delete(e){if(this.isPreview){delete this.mem[e],delete this.memInject[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)}`)}};function Ie(o){let e={};for(let[t,n]of Object.entries(o))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}var H=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(`/conversations/${this.getConversationId()}/save`)}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(`/conversations/${this.getConversationId()}/save`,e)}};var z=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var F=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=null}async get(){return this.isPreview?this.mem?{...this.mem}:null:(await this.http.get(`/conversations/${this.getConversationId()}/summary`)).ai_summary}async update(e){let t=(e??"").trim();if(this.isPreview){let i={content:t,updated_at:new Date().toISOString()};return this.mem=i,{...i}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ee="/functions/v1/world-engine/v1",Ye="https://api.storvia.ai";function qe(){return window.__STORVIA__||{}}function Ke(o,e=3e4){let t=qe();return t.apiBase?Promise.resolve(t):new Promise((n,i)=>{let s=setTimeout(()=>{r(),l(),i(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),r=o.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,accessToken:a.payload.accessToken,debug:a.payload.debug})}),l=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(s),r(),l();let c=window;c.__STORVIA__=a,n(a)}o.send(I("ready",{}))})}var W=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=window.flutter_inappwebview,t=typeof e?.callHandler=="function";this.bus=new R({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?p=>p.source===null||p.source===window:p=>p.source===window.parent,customSend:t?p=>e.callHandler("storviaBus",p):void 0}),he(p=>this.bus.send(p));let n=await Ke(this.bus),i=n.apiBase;if(!i)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${i}${Ee}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new j(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[p,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=p;let w=this.getSavedModelId();this.modelId=n.selectedModelId||(w&&p.some(x=>x.id===w)?w:"")||p[0]?.id||"",this.settingsSheet=new _({onModelChange:x=>{this.modelId=x},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),p.length>0&&this.settingsSheet.mount(p,this.modelId,{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""},!1);let M=()=>this.gameId,f=()=>this.conversationId,Y=()=>this.modelId,J=()=>this.models.find(x=>x.id===this.modelId)?.name;this.chat=new D(this.http,M,f,Y,!0,this.previewConfig,()=>this.settingsSheet?.getSettings()??null,J),this.characters=new N(this.http,f,!0,m?.characters,m?.characterStates),this.relationships=new L(this.http,f,!0,m?.relationships),this.inventory=new A(this.http,f,!0,m?.inventory),this.world=new $(this.http,f,!0,m?.world),this.player=new U(this.http,f,!0,m?.player,m?.playerState),this.custom=new B(this.http,f,!0,m?.custom,m?.custom_inject),this.save=new H(this.http,f,!0,m?.save_data),this.state=new z(this.http,f,!0),this.memory=new F(this.http,f,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}let[s,r]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=s.conversationId,this.models=r;let l=this.getSavedModelId();this.modelId=l&&r.some(p=>p.id===l)?l:r[0]?.id||"";let d=s.settings,a=d?{temperature:d.temperature??1,replyLength:d.reply_length??"medium",replyLanguage:d.reply_language??"zh-CN",playerNote:d.player_note??""}:{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""};this.settingsSheet=new _({onModelChange:p=>{this.modelId=p},onSettingsChange:p=>this.saveSettings(p),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(r,this.modelId,a,s.hasWorldUpdate??!1);let c=()=>this.gameId,h=()=>this.conversationId,v=()=>this.modelId,g=()=>this.models.find(p=>p.id===this.modelId)?.name;this.chat=new D(this.http,c,h,v,!1,void 0,void 0,g),this.characters=new N(this.http,h),this.relationships=new L(this.http,h),this.inventory=new A(this.http,h),this.world=new $(this.http,h),this.player=new U(this.http,h),this.custom=new B(this.http,h),this.save=new H(this.http,h),this.state=new z(this.http,h),this.memory=new F(this.http,h),this.listenForTokenUpdate(),this.initialized=!0}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("config-update",e=>{this.previewConfig=e.payload.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig),this.refreshPreviewSnapshot().catch(t=>{console.warn("[Storvia SDK] refreshPreviewSnapshot failed:",t)})})}async fetchPreviewSnapshot(){try{let e={game_id:this.gameId};return this.previewConfig&&("game_config"in this.previewConfig&&(e.game_config=this.previewConfig.game_config),"game_state"in this.previewConfig&&(e.game_state_override=this.previewConfig.game_state)),await this.http.post("/preview/initial-snapshot",e)}catch(e){return console.warn("[Storvia SDK] fetchPreviewSnapshot failed:",e),null}}async refreshPreviewSnapshot(){let e=await this.fetchPreviewSnapshot();e&&(this.characters?.setInitial(e.characters,e.characterStates),this.player?.setInitial(e.player,e.playerState),this.inventory?.setInitial(e.inventory),this.relationships?.setInitial(e.relationships),this.world?.setInitial(e.world),this.custom?.setInitial(e.custom,e.custom_inject),this.save?.setInitial(e.save_data))}async saveSettings(e){let t={conversation_id:this.conversationId};e.temperature!==void 0&&(t.temperature=e.temperature),e.replyLength!==void 0&&(t.reply_length=e.replyLength),e.replyLanguage!==void 0&&(t.reply_language=e.replyLanguage),e.playerNote!==void 0&&(t.player_note=e.playerNote),await this.http.patch("/settings",t)}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 u("UNAUTHORIZED","User not authenticated"):e.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("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=`${Ye}${Ee}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new j(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let i=this.getSavedModelId();this.modelId=(i&&t.some(a=>a.id===i)?i:"")||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new _({onModelChange:a=>{this.modelId=a},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""},!1);let s=()=>this.gameId,r=()=>this.conversationId,l=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new D(this.http,s,r,l,!0,void 0,()=>this.settingsSheet?.getSettings()??null,d),this.characters=new N(this.http,r,!0,n?.characters,n?.characterStates),this.relationships=new L(this.http,r,!0,n?.relationships),this.inventory=new A(this.http,r,!0,n?.inventory),this.world=new $(this.http,r,!0,n?.world),this.player=new U(this.http,r,!0,n?.player,n?.playerState),this.custom=new B(this.http,r,!0,n?.custom),this.save=new H(this.http,r,!0,n?.save_data),this.memory=new F(this.http,r,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(s=>({id:s.id,name:s.name,url:s.url,assetType:s.asset_type,category:s.category}))}};async function Te(o){let e=new W;return o?.dev?await e.initDev(o.dev):await e.init(),e}function de(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function ke(o){return de(o)?o.value:o}0&&(module.exports={PROTOCOL_VERSION,StorviaBus,StorviaError,StorviaSDK,createStorviaSDK,envelope,extractFieldValue,isProtocolEnvelope,isRichFieldValue,setInsufficientCreditsSheetEnabled,setToastEnabled,showInsufficientCreditsSheet,showToast});
|
|
1034
|
+
${r?`<div class="detail-description">${this.escapeHtml(r)}</div>`:""}
|
|
1035
|
+
`}getStatusDotColor(e){if(e.is_active===!1)return"#6b7280";let t=e.success_rate??100;return t>=90?"#10b981":t>=80?"#3b82f6":t>=60?"#eab308":"#f97316"}getStatusClass(e){if(e.is_active===!1)return"inactive";let t=e.success_rate??100;return t>=90?"excellent":t>=80?"good":t>=60?"normal":"crowded"}getStatusText(e){if(e.is_active===!1)return"\u505C\u7528";let t=e.success_rate??100;return t>=90?"\u6D41\u7545":t>=80?"\u826F\u597D":t>=60?"\u4E00\u822C":"\u62E5\u6324"}getCreditsValue(e){let t=e.credits_config;return t?.billing_mode==="per_10k"&&typeof t.per_10k_tokens=="number"?String(t.per_10k_tokens):t?.billing_mode==="flat"&&typeof t.flat=="number"?String(t.flat):null}getCreditsUnit(e){return e.credits_config?.billing_mode==="per_10k"?"/ 10000 token":"/ 1 \u6B21"}buildSettingsTab(){let e=document.createElement("div"),t=document.createElement("div");return t.className="form-stack",t.appendChild(this.buildTemperatureSection()),t.appendChild(this.buildReplyLengthSection()),t.appendChild(this.buildReplyLanguageSection()),t.appendChild(this.buildNoteSection()),t.appendChild(this.buildSyncSection()),e.appendChild(t),e}buildTemperatureSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label";let n=document.createElement("span");n.textContent="\u6E29\u5EA6";let i=document.createElement("span");i.className="temperature-value",i.textContent=this.settings.temperature.toFixed(1),this.tempValueEl=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className="form-hint",s.textContent="\u66F4\u4F4E\u8BA9 AI \u56DE\u590D\u66F4\u7A33\u5B9A\u7406\u667A\uFF0C\u66F4\u9AD8\u8BA9\u56DE\u590D\u66F4\u5177\u591A\u6837\u6027",e.appendChild(s);let r=document.createElement("input");r.type="range",r.className="slider",r.min="0",r.max="1",r.step="0.1",r.value=String(this.settings.temperature),r.addEventListener("input",()=>{let d=parseFloat(r.value);this.settings.temperature=d,this.tempValueEl&&(this.tempValueEl.textContent=d.toFixed(1))}),e.appendChild(r);let l=document.createElement("div");return l.className="slider-labels",l.innerHTML="<span>\u7CBE\u786E</span><span>\u521B\u610F</span>",e.appendChild(l),e}buildReplyLengthSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label",t.textContent="\u56DE\u590D\u957F\u5EA6",e.appendChild(t);let n=document.createElement("div");return n.className="segment-control",this.segmentBtns=[],fe.forEach(i=>{let s=document.createElement("button");s.className=`segment-button${i.value===this.settings.replyLength?" active":""}`,s.textContent=i.label,s.addEventListener("click",()=>{this.settings.replyLength=i.value,this.segmentBtns.forEach((r,l)=>{r.classList.toggle("active",fe[l].value===i.value)})}),this.segmentBtns.push(s),n.appendChild(s)}),e.appendChild(n),e}buildReplyLanguageSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label",t.textContent="\u56DE\u590D\u8BED\u8A00",e.appendChild(t);let n=document.createElement("div");n.className="custom-select";let i=document.createElement("button");i.className="select-trigger";let s=document.createElement("span");s.textContent=V.find(d=>d.value===this.settings.replyLanguage)?.label||"";let r=document.createElement("span");r.className="select-arrow",r.textContent="\u25BE",this.langArrow=r,i.appendChild(s),i.appendChild(r),i.addEventListener("click",d=>{d.stopPropagation(),this.toggleLangDropdown()}),n.appendChild(i);let l=document.createElement("div");return l.className="select-dropdown",this.langDropdown=l,this.langOptions=[],V.forEach(d=>{let a=document.createElement("button");a.className=`select-option${d.value===this.settings.replyLanguage?" active":""}`,a.innerHTML=`<span>${d.label}</span>${d.value===this.settings.replyLanguage?ve:""}`,a.addEventListener("click",()=>{this.settings.replyLanguage=d.value,s.textContent=d.label,this.langOptions.forEach((c,h)=>{c.classList.toggle("active",V[h].value===d.value),c.innerHTML=`<span>${V[h].label}</span>${V[h].value===d.value?ve:""}`}),this.closeLangDropdown()}),this.langOptions.push(a),l.appendChild(a)}),n.appendChild(l),e.appendChild(n),e}toggleLangDropdown(){this.langDropdownOpen?this.closeLangDropdown():this.openLangDropdown()}openLangDropdown(){this.langDropdownOpen=!0,this.langDropdown?.classList.add("open"),this.langArrow&&(this.langArrow.textContent="\u25B4")}closeLangDropdown(){this.langDropdownOpen=!1,this.langDropdown?.classList.remove("open"),this.langArrow&&(this.langArrow.textContent="\u25BE")}buildNoteSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label";let n=document.createElement("span");n.textContent="\u5907\u6CE8";let i=document.createElement("span");i.className="char-count",i.textContent=`${this.settings.playerNote.length}/50`,this.noteCounter=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className="form-hint",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("textarea");return r.className="player-note-input",r.placeholder="\u5907\u6CE8",r.maxLength=50,r.rows=2,r.value=this.settings.playerNote,r.addEventListener("input",()=>{this.settings.playerNote=r.value,this.noteCounter&&(this.noteCounter.textContent=`${r.value.length}/50`)}),e.appendChild(r),e}buildSyncSection(){let e=document.createElement("div");e.className="form-group";let t=document.createElement("label");t.className="form-label sync-label-wrap";let n=document.createElement("span");n.textContent="\u540C\u6B65\u6E38\u620F\u8BBE\u5B9A";let i=document.createElement("span");i.className=`sync-label-dot${this.hasWorldUpdate?" visible":""}`,this.syncDot=i,t.appendChild(n),t.appendChild(i),e.appendChild(t);let s=document.createElement("p");s.className=`sync-hint${this.hasWorldUpdate?" visible":""}`,s.textContent="\u26A0 \u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u5EFA\u8BAE\u70B9\u51FB\u540C\u6B65",this.syncHint=s,e.appendChild(s);let r=document.createElement("p");r.className="form-hint",r.textContent="\u5C06\u6700\u65B0\u6E38\u620F\u8BBE\u5B9A\u548C\u5F00\u5E55\u5C0F\u5267\u573A\u540C\u6B65\u5230\u5F53\u524D\u5BF9\u8BDD",e.appendChild(r);let l=document.createElement("button");return l.className="btn btn-sync",this.syncBtn=l,this.renderSyncBtn(),l.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.syncDot&&this.syncDot.classList.remove("visible"),this.syncHint&&(this.syncHint.textContent="\u2705 \u540C\u6B65\u6210\u529F\uFF0C\u8BF7\u9000\u51FA\u6E38\u620F\u540E\u91CD\u65B0\u6253\u5F00\uFF0C\u6700\u65B0\u8BBE\u5B9A\u5373\u53EF\u751F\u6548",this.syncHint.classList.add("visible")),setTimeout(()=>this.setSyncState("idle"),3e3),this.showUpdateDialog("success")}catch{this.setSyncState("error"),setTimeout(()=>this.setSyncState("idle"),4e3)}}}),e.appendChild(l),e}setSyncState(e){this.syncState=e,this.renderSyncBtn()}renderSyncBtn(){if(!this.syncBtn)return;let e=this.syncState,t={idle:Be,loading:He,success:Fe,error:Ge},n={idle:"\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A",loading:"\u540C\u6B65\u4E2D...",success:"\u5DF2\u540C\u6B65",error:"\u540C\u6B65\u5931\u8D25"};this.syncBtn.className=`btn btn-sync${e==="success"||e==="error"?` ${e}`:""}`,this.syncBtn.disabled=e==="loading",this.syncBtn.innerHTML=`${t[e]}<span>${n[e]}</span>`}showUpdateDialog(e="prompt"){if(this.updateDialogOpen)return;this.updateDialogOpen=!0;let t=document.createElement("div");t.className="confirm-overlay";let n=document.createElement("div");n.className="confirm-dialog";let i=document.createElement("h3");i.className="confirm-title";let s=document.createElement("p");s.className="confirm-message";let r=document.createElement("div");r.className="confirm-actions",n.appendChild(i),n.appendChild(s),n.appendChild(r),t.appendChild(n),this.shadowRoot.appendChild(t);let l=()=>{this.updateDialogOpen=!1,t.classList.remove("visible"),setTimeout(()=>t.remove(),200)},d=(c,h,v)=>{let g=document.createElement("button");return g.className=`btn ${h}`,g.textContent=c,g.addEventListener("click",v),g},a=c=>{r.innerHTML="",c==="prompt"?(i.textContent="\u68C0\u6D4B\u5230\u65B0\u7248\u672C",s.textContent="\u4F5C\u8005\u5DF2\u66F4\u65B0\u6E38\u620F\u5185\u5BB9\uFF0C\u662F\u5426\u7ACB\u5373\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A\uFF1F",r.appendChild(d("\u7A0D\u540E","btn-confirm-cancel",l)),r.appendChild(d("\u7ACB\u5373\u66F4\u65B0","btn-confirm-ok",async()=>{a("syncing");try{await this.callbacks.onSync(),this.hasWorldUpdate=!1,this.fabDot&&this.fabDot.classList.remove("visible"),this.syncDot&&this.syncDot.classList.remove("visible"),this.syncHint&&this.syncHint.classList.remove("visible"),this.setSyncState("success"),setTimeout(()=>this.setSyncState("idle"),3e3),a("success")}catch{a("error")}}))):c==="syncing"?(i.textContent="\u6B63\u5728\u540C\u6B65",s.innerHTML='<span class="spinner"></span><span>\u540C\u6B65\u6700\u65B0\u8BBE\u5B9A\u4E2D\uFF0C\u8BF7\u7A0D\u5019...</span>'):c==="success"?(i.textContent="\u540C\u6B65\u6210\u529F",s.textContent="\u9700\u8981\u91CD\u65B0\u542F\u52A8\u6E38\u620F\u624D\u80FD\u5E94\u7528\u6700\u65B0\u8BBE\u5B9A\u3002",r.appendChild(d("\u91CD\u65B0\u542F\u52A8","btn-confirm-ok",()=>{l();try{window.parent.postMessage({type:"storvia-exit"},"*")}catch{}}))):(i.textContent="\u540C\u6B65\u5931\u8D25",s.textContent="\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF0C\u6216\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u3002",r.appendChild(d("\u5173\u95ED","btn-confirm-cancel",l)))};t.addEventListener("click",c=>{c.target===t&&e==="prompt"&&l()}),a(e),requestAnimationFrame(()=>t.classList.add("visible"))}async handleSave(){if(!(!this.saveBtn||this.saveBtn.disabled)){this.saveBtn.disabled=!0,this.saveBtn.innerHTML='<span class="spinner"></span>\u4FDD\u5B58\u4E2D...';try{if(this.pendingModelId&&this.pendingModelId!==this.selectedModelId){let e=this.models.find(t=>t.id===this.pendingModelId);if(e&&e.is_active!==!1){this.selectedModelId=this.pendingModelId,this.callbacks.onModelChange(this.pendingModelId);try{localStorage.setItem("storvia_model_id",this.pendingModelId)}catch{}}else this.pendingModelId=this.selectedModelId}await this.callbacks.onSettingsChange({temperature:this.settings.temperature,replyLength:this.settings.replyLength,replyLanguage:this.settings.replyLanguage,playerNote:this.settings.playerNote}),this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1),this.closePanel()}catch{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58\u5931\u8D25",setTimeout(()=>{this.saveBtn&&(this.saveBtn.textContent="\u4FDD\u5B58",this.saveBtn.disabled=!1)},2e3))}}}escapeHtml(e){return e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}applyHostPosition(){this.host.style.left=`${this.fabX}px`,this.host.style.top=`${this.fabY}px`,this.host.style.right="auto",this.host.style.bottom="auto",this.applyPanelPosition()}isMobile(){return window.innerWidth<=768}applyPanelPosition(){if(!this.panel)return;if(this.isMobile()){this.panel.style.left="",this.panel.style.right="",this.panel.style.top="",this.panel.style.bottom="";return}let e=this.fabX+C/2<window.innerWidth/2,t=380;e?(this.panel.style.left="0",this.panel.style.right="auto"):(this.panel.style.left=`${C-t}px`,this.panel.style.right="auto"),this.fabY>500?(this.panel.style.bottom=`${C+8}px`,this.panel.style.top="auto"):(this.panel.style.top=`${C+8}px`,this.panel.style.bottom="auto")}togglePanel(){this.panel&&(this.panel.classList.contains("open")?this.closePanel():(this.applyPanelPosition(),this.panel.classList.add("open"),requestAnimationFrame(()=>{this.panel?.classList.contains("open")&&(this.fab&&(this.fab.style.visibility="hidden"),this.fabDot&&(this.fabDot.style.visibility="hidden"),this.fabWrap&&(this.fabWrap.style.pointerEvents="none"))}),this.isMobile()&&this.lockBodyScroll()))}closePanel(){if(this.panel&&this.panel.classList.remove("open"),this.fab&&(this.fab.style.visibility="visible"),this.fabDot&&(this.fabDot.style.visibility="visible"),this.fabWrap&&(this.fabWrap.style.pointerEvents=""),this.unlockBodyScroll(),this.pendingModelId!==this.selectedModelId){if(this.pendingModelId=this.selectedModelId,this.modelGrid){let e=this.getFilteredModels();this.modelGrid.querySelectorAll(".model-card").forEach((t,n)=>{t.classList.toggle("selected",e[n].id===this.pendingModelId)})}this.renderModelDetail()}}lockBodyScroll(){this.savedBodyOverflow===null&&(this.savedBodyOverflow=document.body.style.overflow||"",document.body.style.overflow="hidden")}unlockBodyScroll(){this.savedBodyOverflow!==null&&(document.body.style.overflow=this.savedBodyOverflow,this.savedBodyOverflow=null)}};var D=class{constructor(e,t,n,i,s=!1,r,l,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=i;this.isPreview=s;this.previewConfig=r,this.getSettings=l,this.getModelName=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}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_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/chat",t,this.reqMeta())}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,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(i=>({uuid:i.uuid,role:i.role,content:i.content,topic:i.topic,status:i.status,model:i.model,createdAt:i.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[]};this.previewConfig?t.prompt_config=this.previewConfig:t.game_id=this.getGameId();let n=this.getSettings?.();if(n&&(typeof n.temperature=="number"&&(t.temperature=n.temperature),n.replyLength&&(t.reply_length=n.replyLength),n.replyLanguage&&(t.reply_language=n.replyLanguage)),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Z(e.onState));return}let i="",s=null,r=null;await this.http.stream("/preview",t,d=>{i+=d},()=>{},this.reqMeta(),(d,a)=>{s=d,r=a,e.onState&&e.onState(s,r)});let l={id:"",content:i};return s&&(l.delta=s,r&&(l.full=r)),l}};function Z(o){if(o)return(e,t)=>o(e,t)}var re=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let i=this.mem[e]||{};return t?{...i[t]||{}}:{...i}}let n=t?{group:t}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,n)}async update(e,t,n){if(this.isPreview){let i=this.mem[e]||(this.mem[e]={});i[t]={...i[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},N=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];i&&(this.mem=i.map(ye)),this.state=new re(e,t,n,s)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(be):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?be(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});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,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},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})}};function ye(o){return{name:o.name,description:o.description,avatar:o.avatar,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.gender?{gender:o.gender}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}function be(o){return{name:o.name,avatar:o.avatar,description:o.description,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.gender?{gender:o.gender}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}var L=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];i&&(this.mem=i.map(s=>({...s})))}setInitial(e){this.mem=e?e.map(t=>({...t})):[]}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)}`)}};function we(o){let e={count:o.count};return o.desc!==void 0&&(e.desc=o.desc),o.icon_url!==void 0&&(e.iconUrl=o.icon_url),e}function oe(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o)){let i={};for(let[s,r]of Object.entries(n))i[s]=we(r);e[t]=i}return e}function Ve(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=we(n);return e}var A=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem=oe(i))}setInitial(e){this.mem=e?oe(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[i,s]of Object.entries(this.mem))n[i]={...s};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return Ve(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return oe(t)}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 d={count:i};s!==void 0&&(d.desc=s),r!==void 0&&(d.iconUrl=r),this.mem[t][n]=d;return}let l={group:t,name:n,count:i};s!==void 0&&(l.desc=s),r!==void 0&&(l.icon_url=r),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,l)}async update(e){let{group:t,name:n,count:i,desc:s,iconUrl:r}=e;if(this.isPreview){let d=this.mem[t];if(!d||!(n in d))throw new Error(`Item "${t}/${n}" not found`);let a=d[n];i!==void 0&&(a.count=i),s!==void 0&&(a.desc=s),r!==void 0&&(a.iconUrl=r);return}let l={};i!==void 0&&(l.count=i),s!==void 0&&(l.desc=s),r!==void 0&&(l.icon_url=r),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,l)}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 l=s||i;if(t===n&&l===i)return;if(l in this.mem[n])throw new Error(`Item "${l}" already exists in target group`);this.mem[n][l]=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 $=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}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 ae=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}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})}},U=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};i&&(this.memPersona={...i}),this.state=new ae(e,t,n,s)}setInitial(e,t){this.memPersona=e?{...e}:{name:""},this.state.setInitial(t)}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 B=class{constructor(e,t,n=!1,i,s){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};this.memInject={};i&&(this.mem=xe(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?xe(e):{},this.memInject=t?{...t}:{}}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,t){if(this.isPreview){for(let[i,s]of Object.entries(e))typeof s=="object"&&s!==null&&typeof this.mem[i]=="object"&&this.mem[i]!==null?this.mem[i]={...this.mem[i],...s}:this.mem[i]=s,t?.inject!==void 0&&(this.memInject[i]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(`/conversations/${this.getConversationId()}/custom`,n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,{inject:t})}getInject(){return{...this.memInject}}async delete(e){if(this.isPreview){delete this.mem[e],delete this.memInject[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)}`)}};function xe(o){let e={};for(let[t,n]of Object.entries(o))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}var H=class{constructor(e,t,n=!1,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(`/conversations/${this.getConversationId()}/save`)}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(`/conversations/${this.getConversationId()}/save`,e)}};var z=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var F=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=null}async get(){return this.isPreview?this.mem?{...this.mem}:null:(await this.http.get(`/conversations/${this.getConversationId()}/summary`)).ai_summary}async update(e){let t=(e??"").trim();if(this.isPreview){let i={content:t,updated_at:new Date().toISOString()};return this.mem=i,{...i}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ce="/functions/v1/world-engine/v1",ze="https://api.storvia.ai";function We(){return window.__STORVIA__||{}}function Ye(o,e=3e4){let t=We();return t.apiBase?Promise.resolve(t):new Promise((n,i)=>{let s=setTimeout(()=>{r(),l(),i(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),r=o.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,accessToken:a.payload.accessToken,debug:a.payload.debug})}),l=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(s),r(),l();let c=window;c.__STORVIA__=a,n(a)}o.send(I("ready",{}))})}var W=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=window.flutter_inappwebview,t=typeof e?.callHandler=="function";this.bus=new R({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?p=>p.source===null||p.source===window:p=>p.source===window.parent,customSend:t?p=>e.callHandler("storviaBus",p):void 0}),pe(p=>this.bus.send(p));let n=await Ye(this.bus),i=n.apiBase;if(!i)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${i}${Ce}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new j(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[p,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=p;let w=this.getSavedModelId();this.modelId=n.selectedModelId||(w&&p.some(x=>x.id===w)?w:"")||p[0]?.id||"",this.settingsSheet=new _({onModelChange:x=>{this.modelId=x},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),p.length>0&&this.settingsSheet.mount(p,this.modelId,{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""},!1);let M=()=>this.gameId,f=()=>this.conversationId,Y=()=>this.modelId,J=()=>this.models.find(x=>x.id===this.modelId)?.name;this.chat=new D(this.http,M,f,Y,!0,this.previewConfig,()=>this.settingsSheet?.getSettings()??null,J),this.characters=new N(this.http,f,!0,m?.characters,m?.characterStates),this.relationships=new L(this.http,f,!0,m?.relationships),this.inventory=new A(this.http,f,!0,m?.inventory),this.world=new $(this.http,f,!0,m?.world),this.player=new U(this.http,f,!0,m?.player,m?.playerState),this.custom=new B(this.http,f,!0,m?.custom,m?.custom_inject),this.save=new H(this.http,f,!0,m?.save_data),this.state=new z(this.http,f,!0),this.memory=new F(this.http,f,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}let[s,r]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=s.conversationId,this.models=r;let l=this.getSavedModelId();this.modelId=l&&r.some(p=>p.id===l)?l:r[0]?.id||"";let d=s.settings,a=d?{temperature:d.temperature??1,replyLength:d.reply_length??"medium",replyLanguage:d.reply_language??"zh-CN",playerNote:d.player_note??""}:{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""};this.settingsSheet=new _({onModelChange:p=>{this.modelId=p},onSettingsChange:p=>this.saveSettings(p),onSync:()=>this.syncSettings()}),this.settingsSheet.mount(r,this.modelId,a,s.hasWorldUpdate??!1);let c=()=>this.gameId,h=()=>this.conversationId,v=()=>this.modelId,g=()=>this.models.find(p=>p.id===this.modelId)?.name;this.chat=new D(this.http,c,h,v,!1,void 0,void 0,g),this.characters=new N(this.http,h),this.relationships=new L(this.http,h),this.inventory=new A(this.http,h),this.world=new $(this.http,h),this.player=new U(this.http,h),this.custom=new B(this.http,h),this.save=new H(this.http,h),this.state=new z(this.http,h),this.memory=new F(this.http,h),this.listenForTokenUpdate(),this.initialized=!0}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("config-update",e=>{this.previewConfig=e.payload.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig),this.refreshPreviewSnapshot().catch(t=>{console.warn("[Storvia SDK] refreshPreviewSnapshot failed:",t)})})}async fetchPreviewSnapshot(){try{let e={game_id:this.gameId};return this.previewConfig&&("game_config"in this.previewConfig&&(e.game_config=this.previewConfig.game_config),"game_state"in this.previewConfig&&(e.game_state_override=this.previewConfig.game_state)),await this.http.post("/preview/initial-snapshot",e)}catch(e){return console.warn("[Storvia SDK] fetchPreviewSnapshot failed:",e),null}}async refreshPreviewSnapshot(){let e=await this.fetchPreviewSnapshot();e&&(this.characters?.setInitial(e.characters,e.characterStates),this.player?.setInitial(e.player,e.playerState),this.inventory?.setInitial(e.inventory),this.relationships?.setInitial(e.relationships),this.world?.setInitial(e.world),this.custom?.setInitial(e.custom,e.custom_inject),this.save?.setInitial(e.save_data))}async saveSettings(e){let t={conversation_id:this.conversationId};e.temperature!==void 0&&(t.temperature=e.temperature),e.replyLength!==void 0&&(t.reply_length=e.replyLength),e.replyLanguage!==void 0&&(t.reply_language=e.replyLanguage),e.playerNote!==void 0&&(t.player_note=e.playerNote),await this.http.patch("/settings",t)}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 u("UNAUTHORIZED","User not authenticated"):e.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("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=`${ze}${Ce}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new j(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let i=this.getSavedModelId();this.modelId=(i&&t.some(a=>a.id===i)?i:"")||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000",this.settingsSheet=new _({onModelChange:a=>{this.modelId=a},onSettingsChange:()=>Promise.resolve(),onSync:()=>Promise.resolve()}),t.length>0&&this.settingsSheet.mount(t,this.modelId,{temperature:1,replyLength:"medium",replyLanguage:"zh-CN",playerNote:""},!1);let s=()=>this.gameId,r=()=>this.conversationId,l=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new D(this.http,s,r,l,!0,void 0,()=>this.settingsSheet?.getSettings()??null,d),this.characters=new N(this.http,r,!0,n?.characters,n?.characterStates),this.relationships=new L(this.http,r,!0,n?.relationships),this.inventory=new A(this.http,r,!0,n?.inventory),this.world=new $(this.http,r,!0,n?.world),this.player=new U(this.http,r,!0,n?.player,n?.playerState),this.custom=new B(this.http,r,!0,n?.custom),this.save=new H(this.http,r,!0,n?.save_data),this.memory=new F(this.http,r,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(s=>({id:s.id,name:s.name,url:s.url,assetType:s.asset_type,category:s.category}))}};async function Se(o){let e=new W;return o?.dev?await e.initDev(o.dev):await e.init(),e}function le(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function Ie(o){return le(o)?o.value:o}0&&(module.exports={PROTOCOL_VERSION,StorviaBus,StorviaError,StorviaSDK,createStorviaSDK,envelope,extractFieldValue,isProtocolEnvelope,isRichFieldValue,setToastEnabled,showToast});
|
package/dist/index.d.mts
CHANGED
|
@@ -41,7 +41,7 @@ declare class HttpClient {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
interface AISummary {
|
|
44
|
-
/**
|
|
44
|
+
/** 记忆内容 */
|
|
45
45
|
content: string;
|
|
46
46
|
/** ISO 时间戳 */
|
|
47
47
|
updated_at: string;
|
|
@@ -53,7 +53,7 @@ interface AssetItem {
|
|
|
53
53
|
assetType: 'avatar' | 'icon';
|
|
54
54
|
category: string;
|
|
55
55
|
}
|
|
56
|
-
type StorviaErrorCode = 'UNAUTHORIZED' | 'INSUFFICIENT_CREDITS' | 'VIOLATION_WORD_DETECTED' | '
|
|
56
|
+
type StorviaErrorCode = 'UNAUTHORIZED' | 'INSUFFICIENT_CREDITS' | 'VIOLATION_WORD_DETECTED' | 'CONTENT_FILTERED' | 'MODEL_REFUSAL' | 'STREAM_INTERRUPTED' | 'RATE_LIMITED' | 'MODEL_NOT_FOUND' | 'GAME_NOT_FOUND' | 'INVALID_REQUEST' | 'INTERNAL_ERROR' | 'NOT_INITIALIZED' | 'NOT_SUPPORTED_IN_PREVIEW' | 'NETWORK_ERROR' | 'REQUEST_TIMEOUT' | 'MODEL_LOADING_TIMEOUT' | 'STREAM_INACTIVITY';
|
|
57
57
|
/** AI 本轮的属性变更(仅包含发生改变的字段) */
|
|
58
58
|
interface StateChanges {
|
|
59
59
|
/** 世界状态变更(扁平 KV) */
|
|
@@ -185,7 +185,7 @@ interface ChatMessagesResponse {
|
|
|
185
185
|
interface ChatEditOptions {
|
|
186
186
|
/** 要编辑的消息 UUID(来自 chat.messages() 返回的 uuid) */
|
|
187
187
|
uuid: string;
|
|
188
|
-
/** 新内容;trim
|
|
188
|
+
/** 新内容;trim 后不能为空 */
|
|
189
189
|
content: string;
|
|
190
190
|
}
|
|
191
191
|
interface ChatEditResponse {
|
|
@@ -391,7 +391,6 @@ declare class ChatModule {
|
|
|
391
391
|
* 适用于修复 user 输入的错别字、修订 AI 回复中的不当措辞等场景
|
|
392
392
|
* - 仅文本字段会被更新;消息的 role / topic / status / 关联状态均不变
|
|
393
393
|
* - user 消息会再次触发违禁词检测,AI 消息不检测
|
|
394
|
-
* - 消息内容上限 6000 字符(与主站编辑一致)
|
|
395
394
|
*/
|
|
396
395
|
edit(options: ChatEditOptions): Promise<ChatEditResponse>;
|
|
397
396
|
/** 预览模式:发到 /preview 端点
|
|
@@ -613,7 +612,7 @@ declare class StateModule {
|
|
|
613
612
|
/**
|
|
614
613
|
* AI 记忆 / 总结
|
|
615
614
|
* - get:读取当前会话的 AI 记忆,未生成时返回 null
|
|
616
|
-
* - update:覆写记忆 content(自动 trim
|
|
615
|
+
* - update:覆写记忆 content(自动 trim)
|
|
617
616
|
*
|
|
618
617
|
* 预览模式下记忆保存在 SDK 内存中,不打后端。
|
|
619
618
|
*/
|
|
@@ -869,7 +868,5 @@ interface ToastAction {
|
|
|
869
868
|
* - duration === 0:常驻,必须用户点关闭按钮(× 自动加上)或 action 按钮才会关闭
|
|
870
869
|
*/
|
|
871
870
|
declare function showToast(message: string, type?: ToastType, duration?: number, action?: ToastAction): void;
|
|
872
|
-
declare function setInsufficientCreditsSheetEnabled(enabled: boolean): void;
|
|
873
|
-
declare function showInsufficientCreditsSheet(fallbackMsg?: string): void;
|
|
874
871
|
|
|
875
|
-
export { type AISummary, type AckPayload, type AssetItem, type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatGenerateOptions, type ChatMessage, type ChatMessageCursor, type ChatMessagesOptions, type ChatMessagesResponse, type ChatResponse, type ChatRetryOptions, type ChatSaveOptions, type ChatSendOptions, type ChatStateCallback, type ConfigUpdatePayload, type CurrentState, type DormantState, type DownstreamMsg, type FieldValue, type Gender, type InitPayload, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type OrientationPayload, PROTOCOL_VERSION, type PlayerPersona, type PreviewConfig, type PreviewInitPayload, type ProtocolEnvelope, type ReadyPayload, type Relationship, type RichFieldValue, type SdkErrorPayload, type SetModelPayload, type State, type StateChanges, StorviaBus, type StorviaBusOptions, StorviaError, type StorviaErrorCode, StorviaSDK, type TokenUpdatePayload, type UpstreamMsg, createStorviaSDK, envelope, extractFieldValue, isProtocolEnvelope, isRichFieldValue,
|
|
872
|
+
export { type AISummary, type AckPayload, type AssetItem, type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatGenerateOptions, type ChatMessage, type ChatMessageCursor, type ChatMessagesOptions, type ChatMessagesResponse, type ChatResponse, type ChatRetryOptions, type ChatSaveOptions, type ChatSendOptions, type ChatStateCallback, type ConfigUpdatePayload, type CurrentState, type DormantState, type DownstreamMsg, type FieldValue, type Gender, type InitPayload, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type OrientationPayload, PROTOCOL_VERSION, type PlayerPersona, type PreviewConfig, type PreviewInitPayload, type ProtocolEnvelope, type ReadyPayload, type Relationship, type RichFieldValue, type SdkErrorPayload, type SetModelPayload, type State, type StateChanges, StorviaBus, type StorviaBusOptions, StorviaError, type StorviaErrorCode, StorviaSDK, type TokenUpdatePayload, type UpstreamMsg, createStorviaSDK, envelope, extractFieldValue, isProtocolEnvelope, isRichFieldValue, setToastEnabled, showToast };
|