@storvia/sdk 0.7.0 → 0.8.0

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 CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var X=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var Pe=(i,e)=>{for(var t in e)X(i,t,{get:e[t],enumerable:!0})},ke=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Se(e))!Ee.call(i,r)&&r!==t&&X(i,r,{get:()=>e[r],enumerable:!(n=Te(e,r))||n.enumerable});return i};var xe=i=>ke(X({},"__esModule",{value:!0}),i);var $e={};Pe($e,{PROTOCOL_VERSION:()=>x,StorviaBus:()=>P,StorviaError:()=>p,StorviaSDK:()=>B,createStorviaSDK:()=>Ce,envelope:()=>I,extractFieldValue:()=>Re,isProtocolEnvelope:()=>V,isRichFieldValue:()=>se,setToastEnabled:()=>me,showToast:()=>ne});module.exports=xe($e);var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var x=1;function V(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function I(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var P=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(!V(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},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 r=t;return n.add(r),()=>n.delete(r)}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(o){console.error("[StorviaBus] customSend failed:",o,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(o){console.error("[StorviaBus] postMessage failed:",o,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let o=e.id??_e(),s=I(e.type,e.payload,{id:o}),c=setTimeout(()=>{this.pendingAcks.delete(o),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(o,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 _e(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var te=null;function he(i){te=i}var z="storvia-sdk-toast-style",Q="storvia-sdk-toast-stack",pe=`
2
- #${Q} {
1
+ "use strict";var ie=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var _e=Object.prototype.hasOwnProperty;var Oe=(i,e)=>{for(var t in e)ie(i,t,{get:e[t],enumerable:!0})},Ae=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of xe(e))!_e.call(i,r)&&r!==t&&ie(i,r,{get:()=>e[r],enumerable:!(n=ke(e,r))||n.enumerable});return i};var Me=i=>Ae(ie({},"__esModule",{value:!0}),i);var Ve={};Oe(Ve,{PROTOCOL_VERSION:()=>O,StorviaBus:()=>_,StorviaError:()=>u,StorviaSDK:()=>q,createStorviaSDK:()=>Se,envelope:()=>C,extractFieldValue:()=>be,isProtocolEnvelope:()=>B,isRichFieldValue:()=>he,setToastEnabled:()=>we,showToast:()=>ae});module.exports=Me(Ve);var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var O=1;function B(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function C(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var _=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(!B(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},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 r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:C(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(o){console.error("[StorviaBus] customSend failed:",o,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(o){console.error("[StorviaBus] postMessage failed:",o,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let o=e.id??De(),s=C(e.type,e.payload,{id:o}),c=setTimeout(()=>{this.pendingAcks.delete(o),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(o,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 De(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var se=null;function ge(i){se=i}var X="storvia-sdk-toast-style",ee="storvia-sdk-toast-stack",ve=`
2
+ #${ee} {
3
3
  position: fixed;
4
4
  top: max(20px, env(safe-area-inset-top, 0px) + 20px);
5
5
  right: max(20px, env(safe-area-inset-right, 0px) + 20px);
@@ -12,7 +12,7 @@
12
12
  }
13
13
 
14
14
  @media (max-width: 768px) {
15
- #${Q} {
15
+ #${ee} {
16
16
  top: max(10px, env(safe-area-inset-top, 0px) + 10px);
17
17
  left: 10px;
18
18
  right: 10px;
@@ -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
- `,Oe={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>'},ee={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F"},ue=!0;function me(i){ue=i}function Me(){if(typeof document>"u")return null;let i=document.getElementById(Q);if(!i){if(!document.getElementById(z)){let e=document.createElement("style");e.id=z,e.textContent=pe,document.head.appendChild(e)}i=document.createElement("div"),i.id=Q,document.body.appendChild(i)}return i}function ne(i,e="info",t=3500,n){if(!ue)return;let r=Me();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
- <span class="storvia-toast-icon">${Oe[e]}</span>
222
+ `,Ne={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>'},oe={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},fe=!0;function we(i){fe=i}function Ue(){if(typeof document>"u")return null;let i=document.getElementById(ee);if(!i){if(!document.getElementById(X)){let e=document.createElement("style");e.id=X,e.textContent=ve,document.head.appendChild(e)}i=document.createElement("div"),i.id=ee,document.body.appendChild(i)}return i}function ae(i,e="info",t=3500,n){if(!fe)return;let r=Ue();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
+ <span class="storvia-toast-icon">${Ne[e]}</span>
224
224
  <span class="storvia-toast-msg"></span>
225
- `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(o){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function k(i,e){if(i==="INSUFFICIENT_CREDITS"){le({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||ee.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){le({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||ee.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=ee[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";ne(t,i==="RATE_LIMITED"?"warning":"error")}var K=null;function le(i){if(typeof document>"u"||K)return;if(!document.getElementById(z)){let s=document.createElement("style");s.id=z,s.textContent=pe,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.innerHTML=`
225
+ `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(h){console.error("[Storvia toast] action error:",h)}d()}),s.appendChild(a)}if(o){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function S(i,e){if(i==="INSUFFICIENT_CREDITS"){me({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||oe.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){me({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||oe.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=oe[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";ae(t,i==="RATE_LIMITED"?"warning":"error")}var J=null;function me(i){if(typeof document>"u"||J)return;if(!document.getElementById(X)){let s=document.createElement("style");s.id=X,s.textContent=ve,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.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,5 +234,6 @@
234
234
  <button type="button" class="storvia-sheet-btn storvia-sheet-btn-primary" data-role="navigate"></button>
235
235
  </div>
236
236
  </div>
237
- `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=i.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=i.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=i.primaryLabel);let o=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),K===e&&(K=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(te)try{te(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");o()}),document.body.appendChild(e),K=e,requestAnimationFrame(()=>e.classList.add("show"))}var C=class C{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof p||k("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new p("REQUEST_TIMEOUT","Request timed out");return k("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),C.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:r,status:o,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:l}=e,h="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",R=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${R} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${R} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,l])=>n.searchParams.set(a,l));let r=Date.now(),o,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r}),l===a&&this.maybeShowNetworkToast(a),l}}async post(e,t,n){let r=Date.now(),o,s,{controller:c,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:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r,modelName:n?.modelName}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r,modelName:n?.modelName}),l===a&&this.maybeShowNetworkToast(a),l}}async patch(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:o,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:o.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,o,s,c,d){let a=Date.now(),l=o?.modelName?` [model: ${o.modelName}]`:"",h=[],m=v=>{this.debug&&h.push({t:Date.now()-a,event:v})},R=new AbortController,u=null,w=null,b=null,f=null,S=()=>{u!==null&&(clearTimeout(u),u=null),w!==null&&(clearTimeout(w),w=null),b!==null&&(clearTimeout(b),b=null)},W=v=>{f=v,S(),R.abort()};u=setTimeout(()=>W("REQUEST_TIMEOUT"),C.REQUEST_TIMEOUT);let T;try{T=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:R.signal})}catch(v){if(S(),f){let y=new p(f,"Request timed out");throw k(f),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-a,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(v),v}if(u!==null&&(clearTimeout(u),u=null),!T.ok){S();let v=await T.text().catch(()=>""),y={};try{y=JSON.parse(v)}catch{}let Z=y.code||"INTERNAL_ERROR",q=new p(Z,y.message||`HTTP ${T.status}`);throw k(Z,y.message),this.log({method:"STREAM",path:e,body:t,status:T.status,rawResponse:v,error:q,durationMs:Date.now()-a,modelName:o?.modelName}),q}let ae=T.body?.getReader();if(!ae)throw S(),new p("INTERNAL_ERROR","No response body for stream");w=setTimeout(()=>W("MODEL_LOADING_TIMEOUT"),C.MODEL_LOADING_TIMEOUT);let be=new TextDecoder,G="",E="",de=!1;try{for(;;){let{done:v,value:y}=await ae.read();if(v)break;let q=be.decode(y,{stream:!0}).split(`
238
- `);for(let ce of q){if(!ce.startsWith("data: "))continue;let J=ce.slice(6);if(J==="[DONE]"){m("[DONE]"),S(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log("Message ID:",G),console.log(`SSE events (${h.length}):`,h),console.groupEnd()),r(G);return}try{let g=JSON.parse(J);m(g),g.type==="done"&&g.id?G=g.id:g.type==="state"?(s&&s(g.delta,g.full??null),d&&Array.isArray(g.createdNames)&&g.createdNames.length&&d(g.createdNames)):g.type==="thinking"?c&&(g.status==="start"||g.status==="end")&&c(g.status):g.content&&(de?(b!==null&&clearTimeout(b),b=setTimeout(()=>W("STREAM_INACTIVITY"),C.STREAM_INACTIVITY_TIMEOUT)):(de=!0,w!==null&&(clearTimeout(w),w=null),b=setTimeout(()=>W("STREAM_INACTIVITY"),C.STREAM_INACTIVITY_TIMEOUT)),E+=g.content,n(g.content))}catch{m({raw:J})}}}}catch(v){if(S(),f){let y=new p(f,f==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw k(f),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2717 ${f}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Timeout:",y),console.groupEnd()),y}throw this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Stream error:",v),console.groupEnd()),v}S(),G&&r(G)}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new p(s,r.message||`HTTP ${e.status}`);throw k(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};C.REQUEST_TIMEOUT=6e4,C.MODEL_LOADING_TIMEOUT=18e4,C.STREAM_INACTIVITY_TIMEOUT=6e4;var j=C;var _=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new p("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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 p("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 delete(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Y(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,l)=>{o=a,s=l,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function Y(i){if(i)return(e,t)=>i(e,t)}var re=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},O=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ge)),this.state=new re(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ge):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(ve):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?ve(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(r=>r.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 ge(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function ve(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var M=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}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(r=>r.from===e&&r.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 r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,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 fe(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ie(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=fe(s);e[t]=r}return e}function Ae(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=fe(n);return e}var A=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ie(r))}setInitial(e){this.mem=e?ie(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return Ae(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ie(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=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:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=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];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}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 o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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 oe=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new oe(e,t,n,o)}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)}};function N(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var $=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=we(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?we(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(N(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(N(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(N(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function we(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function ye(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var L=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(ye(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(ye(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var H=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new p("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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ie="/functions/v1/world-engine/v1",De="https://api.storvia.ai";function Ue(){return window.__STORVIA__||{}}function Ne(i,e=3e4){let t=Ue();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new p("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let l=window;l.__STORVIA__=a,n(a)}i.send(I("ready",{}))})}var B=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 P({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?h=>h.source===null||h.source===window:h=>h.source===window.parent,customSend:t?h=>e.callHandler("storviaBus",h):void 0}),he(h=>this.bus.send(h));let n=await Ne(this.bus),r=n.apiBase;if(!r)throw new p("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ie}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new p("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 p("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[h,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(f=>f.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"";let R=()=>this.gameId,u=()=>this.conversationId,w=()=>this.modelId,b=()=>this.models.find(f=>f.id===this.modelId)?.name;this.chat=new _(this.http,R,u,w,!0,this.previewConfig,b),this.characters=new O(this.http,u,!0,m?.characters,m?.characterStates),this.relationships=new M(this.http,u,!0,m?.relationships),this.inventory=new A(this.http,u,!0,m?.inventory),this.world=new D(this.http,u,!0,m?.world),this.player=new U(this.http,u,!0,m?.player,m?.playerState),this.custom=new $(this.http,u,R,!0,m?.custom,m?.custom_inject),this.save=new L(this.http,u,R,!0,m?.save_data),this.state=new H(this.http,u,!0),this.memory=new F(this.http,u,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(h=>h.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name;this.chat=new _(this.http,c,d,a,!1,void 0,l),this.characters=new O(this.http,d),this.relationships=new M(this.http,d),this.inventory=new A(this.http,d),this.world=new D(this.http,d),this.player=new U(this.http,d),this.custom=new $(this.http,d,c),this.save=new L(this.http,d,c),this.state=new H(this.http,d),this.memory=new F(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new p("UNAUTHORIZED","User not authenticated"):t.status===404?new p("GAME_NOT_FOUND","Game not found or not published"):new p("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${De}${Ie}`,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 r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new _(this.http,o,s,c,!0,void 0,d),this.characters=new O(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new M(this.http,s,!0,n?.relationships),this.inventory=new A(this.http,s,!0,n?.inventory),this.world=new D(this.http,s,!0,n?.world),this.player=new U(this.http,s,!0,n?.player,n?.playerState),this.custom=new $(this.http,s,o,!0,n?.custom),this.save=new L(this.http,s,o,!0,n?.save_data),this.memory=new F(this.http,s,!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(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Ce(i){let e=new B;return i?.dev?await e.initDev(i.dev):await e.init(),e}function se(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function Re(i){return se(i)?i.value:i}0&&(module.exports={PROTOCOL_VERSION,StorviaBus,StorviaError,StorviaSDK,createStorviaSDK,envelope,extractFieldValue,isProtocolEnvelope,isRichFieldValue,setToastEnabled,showToast});
237
+ `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=i.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=i.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=i.primaryLabel);let o=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),J===e&&(J=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(se)try{se(C("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");o()}),document.body.appendChild(e),J=e,requestAnimationFrame(()=>e.classList.add("show"))}var f=class f{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof u||S("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return S("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),f.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:r,status:o,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:h}=e,l="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",p=a!==void 0?` (${a}ms)`:"",g=o!==void 0?` [${o}]`:"",b=h?` [model: ${h}]`:"";d?(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,h])=>n.searchParams.set(a,h));let r=Date.now(),o,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),o=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:l,durationMs:Date.now()-r}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,error:h,durationMs:Date.now()-r}),h===a&&this.maybeShowNetworkToast(a),h}}async post(e,t,n){let r=Date.now(),o,s,{controller:c,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:c.signal});d(),o=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:l,durationMs:Date.now()-r,modelName:n?.modelName}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,error:h,durationMs:Date.now()-r,modelName:n?.modelName}),h===a&&this.maybeShowNetworkToast(a),h}}async patch(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:o,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:o.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,o,s,c,d,a,h){let l=Date.now(),m=o?.modelName?` [model: ${o.modelName}]`:"",p=[],g=w=>{this.debug&&p.push({t:Date.now()-l,event:w})},b=new AbortController,R=null,I=null,P=null,T=null,k=()=>{R!==null&&(clearTimeout(R),R=null),I!==null&&(clearTimeout(I),I=null),P!==null&&(clearTimeout(P),P=null)},z=w=>{T=w,k(),b.abort()};R=setTimeout(()=>z("REQUEST_TIMEOUT"),f.REQUEST_TIMEOUT);let E;try{E=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:b.signal})}catch(w){if(k(),T){let y=new u(T,"Request timed out");throw S(T),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-l,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(w),w}if(R!==null&&(clearTimeout(R),R=null),!E.ok){k();let w=await E.text().catch(()=>""),y={};try{y=JSON.parse(w)}catch{}let ne=y.code||"INTERNAL_ERROR",Q=new u(ne,y.message||`HTTP ${E.status}`);throw S(ne,y.message),this.log({method:"STREAM",path:e,body:t,status:E.status,rawResponse:w,error:Q,durationMs:Date.now()-l,modelName:o?.modelName}),Q}let pe=E.body?.getReader();if(!pe)throw k(),new u("INTERNAL_ERROR","No response body for stream");I=setTimeout(()=>z("MODEL_LOADING_TIMEOUT"),f.MODEL_LOADING_TIMEOUT);let Pe=new TextDecoder,j="",x="",ue=!1,te,Y;try{for(;;){let{done:w,value:y}=await pe.read();if(w)break;let Q=Pe.decode(y,{stream:!0}).split(`
238
+ `);for(let Z of Q){if(Z.startsWith("id: ")){Y=Z.slice(4);continue}if(!Z.startsWith("data: "))continue;let re=Z.slice(6);if(re==="[DONE]"){g("[DONE]"),k(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log("Message ID:",j),console.log(`SSE events (${p.length}):`,p),console.groupEnd()),r(j);return}try{let v=JSON.parse(re);g(v),v.type==="done"&&v.id?j=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(ue?(P!==null&&clearTimeout(P),P=setTimeout(()=>z("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)):(ue=!0,I!==null&&(clearTimeout(I),I=null),P=setTimeout(()=>z("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)),x+=v.content,n(v.content))}catch{g({raw:re})}Y!==void 0&&(te=Y,Y=void 0)}}}catch(w){if(k(),T){let y=new u(T,T==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw S(T),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2717 ${T}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h});return}throw w}if(k(),j){r(j);return}a&&await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h})}async resumeLoop(e,t,n){let r=t;for(let s=1;s<=f.RECONNECT_MAX_ATTEMPTS;s++){let c=Math.min(f.RECONNECT_BACKOFF_CAP,1e3*2**(s-1));await new Promise(h=>setTimeout(h,c)),n.onReconnect?.({attempt:s});let d={messageId:"",lastId:r},a;try{a=await this.pumpGetStream(e.conversationId,e.topic,r,d,n)}catch{continue}if(r=d.lastId??r,a==="done"){n.onDone(d.messageId);return}if(a==="inactive"){d.messageId&&n.onDone(d.messageId);return}}let o=new u("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw S("STREAM_INTERRUPTED"),o}async resumeStream(e,t,n){let r={messageId:""},o;try{o=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(o==="done"){n.onDone(r.messageId);return}if(o==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,o){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),f.REQUEST_TIMEOUT),a;try{a=await fetch(s.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal})}finally{clearTimeout(d)}if(!a.ok)throw new u("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let l=a.body?.getReader();return l?await this.pumpReader(l,r,o):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,o,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},f.STREAM_INACTIVITY_TIMEOUT)};c();try{for(;;){let{done:d,value:a}=await e.read();if(d)break;c();let h=r.decode(a,{stream:!0});for(let l of h.split(`
239
+ `)){if(l.startsWith("id: ")){o=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var H=f;var A=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async active(e={}){if(this.isPreview)return{active:!1};let t={};return e.topic&&(t.topic=e.topic),this.http.get(`/conversations/${encodeURIComponent(this.getConversationId())}/active`,t)}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:W(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{o=a,s=h,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function W(i){if(i)return(e,t)=>i(e,t)}var de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},M=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ye)),this.state=new de(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Ie):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Ie(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(r=>r.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(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function Ie(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}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(r=>r.from===e&&r.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 r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,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 Ce(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ce(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=Ce(s);e[t]=r}return e}function $e(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Ce(n);return e}var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ce(r))}setInitial(e){this.mem=e?ce(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return $e(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ce(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=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:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=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];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}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 o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var U=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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})}},$=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new le(e,t,n,o)}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)}};function L(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=Re(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Re(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(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Re(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function Te(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var G=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var K=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 V=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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ee="/functions/v1/world-engine/v1",Le="https://api.storvia.ai";function Fe(){return window.__STORVIA__||{}}function Ge(i,e=3e4){let t=Fe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let h=window;h.__STORVIA__=a,n(a)}i.send(C("ready",{}))})}var q=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 _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),ge(l=>this.bus.send(l));let n=await Ge(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${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 H(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,R=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new A(this.http,p,g,b,!0,this.previewConfig,R),this.characters=new M(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new D(this.http,g,!0,m?.relationships),this.inventory=new N(this.http,g,!0,m?.inventory),this.world=new U(this.http,g,!0,m?.world),this.player=new $(this.http,g,!0,m?.player,m?.playerState),this.custom=new F(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new G(this.http,g,p,!0,m?.save_data),this.state=new K(this.http,g,!0),this.memory=new V(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new A(this.http,c,d,a,!1,void 0,h),this.characters=new M(this.http,d),this.relationships=new D(this.http,d),this.inventory=new N(this.http,d),this.world=new U(this.http,d),this.player=new $(this.http,d),this.custom=new F(this.http,d,c),this.save=new G(this.http,d,c),this.state=new K(this.http,d),this.memory=new V(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Le}${Ee}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new H(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new A(this.http,o,s,c,!0,void 0,d),this.characters=new M(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new D(this.http,s,!0,n?.relationships),this.inventory=new N(this.http,s,!0,n?.inventory),this.world=new U(this.http,s,!0,n?.world),this.player=new $(this.http,s,!0,n?.player,n?.playerState),this.custom=new F(this.http,s,o,!0,n?.custom),this.save=new G(this.http,s,o,!0,n?.save_data),this.memory=new V(this.http,s,!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(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Se(i){let e=new q;return i?.dev?await e.initDev(i.dev):await e.init(),e}function he(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function be(i){return he(i)?i.value:i}0&&(module.exports={PROTOCOL_VERSION,StorviaBus,StorviaError,StorviaSDK,createStorviaSDK,envelope,extractFieldValue,isProtocolEnvelope,isRichFieldValue,setToastEnabled,showToast});
package/dist/index.d.mts CHANGED
@@ -1,3 +1,15 @@
1
+ /** 续读/重连共用的回调集合(与 stream() 的散参一一对应)。 */
2
+ interface SSECallbacks {
3
+ onChunk: (text: string) => void;
4
+ onDone: (id: string) => void;
5
+ onState?: (delta: unknown, full: unknown) => void;
6
+ onThinking?: (status: 'start' | 'end') => void;
7
+ onCreatedCharacters?: (names: string[]) => void;
8
+ /** 每次发起重连前触发(attempt 从 1 递增),供 UI 提示「正在重新连接」。 */
9
+ onReconnect?: (info: {
10
+ attempt: number;
11
+ }) => void;
12
+ }
1
13
  declare class HttpClient {
2
14
  private baseUrl;
3
15
  private token;
@@ -31,7 +43,28 @@ declare class HttpClient {
31
43
  delete<T>(path: string): Promise<T>;
32
44
  stream(path: string, body: unknown, onChunk: (text: string) => void, onDone: (id: string) => void, meta?: {
33
45
  modelName?: string;
34
- }, onState?: (delta: unknown, full: unknown) => void, onThinking?: (status: 'start' | 'end') => void, onCreatedCharacters?: (names: string[]) => void): Promise<void>;
46
+ }, onState?: (delta: unknown, full: unknown) => void, onThinking?: (status: 'start' | 'end') => void, onCreatedCharacters?: (names: string[]) => void, resume?: {
47
+ conversationId: string;
48
+ topic?: string;
49
+ }, onReconnect?: (info: {
50
+ attempt: number;
51
+ }) => void): Promise<void>;
52
+ private static readonly RECONNECT_MAX_ATTEMPTS;
53
+ private static readonly RECONNECT_BACKOFF_CAP;
54
+ /**
55
+ * 重连循环:退避 → GET 续读 → 直到拿到终止事件 / 服务端报无在途 / 次数耗尽。
56
+ * 每次重连前回调 onReconnect 供 UI 提示「正在重新连接 n/10」。
57
+ */
58
+ private resumeLoop;
59
+ /**
60
+ * 公开续读入口:接管某会话/ topic 的在途生成(刷新 / 换设备 / 多端接力时用)。
61
+ * 无在途生成则静默返回。供 ChatModule.resume() 调用。
62
+ */
63
+ resumeStream(conversationId: string, topic: string | undefined, cb: SSECallbacks): Promise<void>;
64
+ /** 单次 GET 续读:拉一段 SSE 并分发。无在途生成(服务端回 JSON)返回 'inactive';HTTP/网络失败抛出供上层退避。 */
65
+ private pumpGetStream;
66
+ /** 共享 SSE 读循环:解析 id:/data:,分发 content/state/thinking/done,跟踪 lastId。带无活动超时(cancel 后返回 'eof' 供重连)。 */
67
+ private pumpReader;
35
68
  /**
36
69
  * 读取完整响应文本,解析为 JSON 并返回 `{ raw, data }`:
37
70
  * - `raw` 是后端返回的整体(用于 debug 完整打印,含 success/code/message 等包装字段)
@@ -53,7 +86,7 @@ interface AssetItem {
53
86
  assetType: 'avatar' | 'icon';
54
87
  category: string;
55
88
  }
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' | 'DAISY_CARD_REQUIRED' | 'MESSAGE_NOT_FOUND' | 'MESSAGE_TOO_OLD' | 'NO_MESSAGES_TO_DELETE';
89
+ 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' | 'DAISY_CARD_REQUIRED' | 'MESSAGE_NOT_FOUND' | 'MESSAGE_TOO_OLD' | 'NO_MESSAGES_TO_DELETE' | 'GENERATION_TIMEOUT' | 'REPETITION_LOOP' | 'SAVE_FAILED' | 'FINALIZE_FAILED' | 'CONVERSATION_NOT_FOUND' | 'EMPTY_MESSAGE' | 'CONTINUE_MODEL_NOT_AVAILABLE' | 'CONTINUE_PROMPT_MISSING';
57
90
  /** AI 本轮的属性变更(仅包含发生改变的字段) */
58
91
  interface StateChanges {
59
92
  /** 世界状态变更(扁平 KV) */
@@ -104,6 +137,14 @@ type ChatThinkingCallback = (status: 'start' | 'end') => void;
104
137
  * 非流式调用通过 ChatResponse.createdNames 获取,无需此回调。
105
138
  */
106
139
  type ChatCreatedCharactersCallback = (names: string[]) => void;
140
+ /**
141
+ * 断线重连回调:流式生成中途断开(刷新/切后台/断网/弱网)后,SDK 自动经
142
+ * GET /conversations/:id/stream 续读,每次发起重连前触发。
143
+ * @param info.attempt 第几次重连尝试(从 1 递增,最多 10 次)
144
+ */
145
+ type ChatReconnectingCallback = (info: {
146
+ attempt: number;
147
+ }) => void;
107
148
  /**
108
149
  * 流式 + 入库内容过滤规则。提供后,服务端只保留 AI 回复中
109
150
  * `start..end` 之间的内容(多段会自动拼接),其余被丢弃。
@@ -135,6 +176,8 @@ interface ChatSendOptions {
135
176
  onThinking?: ChatThinkingCallback;
136
177
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
137
178
  onCreatedCharacters?: ChatCreatedCharactersCallback;
179
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
180
+ onReconnecting?: ChatReconnectingCallback;
138
181
  }
139
182
  interface ChatSaveOptions {
140
183
  role: 'user' | 'assistant';
@@ -155,6 +198,8 @@ interface ChatGenerateOptions {
155
198
  onThinking?: ChatThinkingCallback;
156
199
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
157
200
  onCreatedCharacters?: ChatCreatedCharactersCallback;
201
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
202
+ onReconnecting?: ChatReconnectingCallback;
158
203
  }
159
204
  interface ChatRetryOptions {
160
205
  topic?: string;
@@ -170,6 +215,8 @@ interface ChatRetryOptions {
170
215
  onThinking?: ChatThinkingCallback;
171
216
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
172
217
  onCreatedCharacters?: ChatCreatedCharactersCallback;
218
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
219
+ onReconnecting?: ChatReconnectingCallback;
173
220
  }
174
221
  interface ChatResponse {
175
222
  id: string;
@@ -181,6 +228,26 @@ interface ChatResponse {
181
228
  /** 本轮出现的「真·新角色」名字数组,仅在有新角色时出现 */
182
229
  createdNames?: string[];
183
230
  }
231
+ /** chat.active() 返回:该会话/ topic 当前是否有在途生成。 */
232
+ interface ChatActiveResult {
233
+ /** 是否有正在进行的生成 */
234
+ active: boolean;
235
+ /** 在途生成的 id(active 为 true 时存在) */
236
+ generationId?: string;
237
+ }
238
+ /**
239
+ * chat.resume() 选项:接管会话/ topic 的在途生成(刷新 / 换设备 / 多端接力)。
240
+ * 流式回调与 send 一致;无在途生成时静默返回。
241
+ */
242
+ interface ChatResumeOptions {
243
+ topic?: string;
244
+ onChunk?: (text: string) => void;
245
+ onDone?: (id: string) => void;
246
+ onState?: ChatStateCallback;
247
+ onThinking?: ChatThinkingCallback;
248
+ onCreatedCharacters?: ChatCreatedCharactersCallback;
249
+ onReconnecting?: ChatReconnectingCallback;
250
+ }
184
251
  interface ChatMessageCursor {
185
252
  uuid: string;
186
253
  createdAt: string;
@@ -444,6 +511,21 @@ declare class ChatModule {
444
511
  * - 该消息本身不会被删除;它之后的所有消息会被删除
445
512
  */
446
513
  rollback(options: ChatRollbackOptions): Promise<ChatRollbackResponse>;
514
+ /**
515
+ * 查询当前会话(可按 topic)是否有正在进行的生成。
516
+ * 进入对话 / 刷新 / 换设备后先调它,命中再用 resume() 接管在途流。
517
+ * 预览模式无在途生成,恒返回 { active: false }。
518
+ */
519
+ active(options?: {
520
+ topic?: string;
521
+ }): Promise<ChatActiveResult>;
522
+ /**
523
+ * 接管会话/ topic 的在途生成并续读(刷新、换设备、多端接力时用)。
524
+ * - 生成跑在 chat-worker、产物在 Redis 流,与发起请求的连接解耦;从头实时接上正在输出的内容。
525
+ * - 续读中途再断会自动重连续读;服务端已无在途生成(已跑完)则静默返回。
526
+ * 预览模式无在途生成,直接返回。
527
+ */
528
+ resume(options?: ChatResumeOptions): Promise<void>;
447
529
  /** 预览模式:发到 /preview 端点
448
530
  * - 创作台预览:父页面已注入 previewConfig,请求体塞 prompt_config,服务端不查库
449
531
  * - 本地预览 / dev:无 previewConfig,请求体塞 game_id,服务端按 hash_id 查 prompts
@@ -937,4 +1019,4 @@ interface ToastAction {
937
1019
  */
938
1020
  declare function showToast(message: string, type?: ToastType, duration?: number, action?: ToastAction): void;
939
1021
 
940
- 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 };
1022
+ export { type AISummary, type AckPayload, type AssetItem, type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatActiveResult, type ChatGenerateOptions, type ChatMessage, type ChatMessageCursor, type ChatMessagesOptions, type ChatMessagesResponse, type ChatReconnectingCallback, type ChatResponse, type ChatResumeOptions, 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 };
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
- var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var G=1;function W(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function T(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var k=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(!W(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},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 r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:T(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(o){console.error("[StorviaBus] customSend failed:",o,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(o){console.error("[StorviaBus] postMessage failed:",o,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let o=e.id??Ie(),s=T(e.type,e.payload,{id:o}),c=setTimeout(()=>{this.pendingAcks.delete(o),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(o,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 Ie(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var ee=null;function de(i){ee=i}var K="storvia-sdk-toast-style",z="storvia-sdk-toast-stack",ce=`
2
- #${z} {
1
+ var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var j=1;function Q(o){if(!o||typeof o!="object")return!1;let e=o;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function E(o,e,t){return{protocol:1,type:o,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var _=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(!Q(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(i){console.error(`[StorviaBus] handler '${t.type}' threw:`,i)}})},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 r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:E(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(i){console.error("[StorviaBus] customSend failed:",i,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(i){console.error("[StorviaBus] postMessage failed:",i,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let i=e.id??Ee(),s=E(e.type,e.payload,{id:i}),c=setTimeout(()=>{this.pendingAcks.delete(i),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(i,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 Ee(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var oe=null;function pe(o){oe=o}var J="storvia-sdk-toast-style",X="storvia-sdk-toast-stack",ue=`
2
+ #${X} {
3
3
  position: fixed;
4
4
  top: max(20px, env(safe-area-inset-top, 0px) + 20px);
5
5
  right: max(20px, env(safe-area-inset-right, 0px) + 20px);
@@ -12,7 +12,7 @@ var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",thi
12
12
  }
13
13
 
14
14
  @media (max-width: 768px) {
15
- #${z} {
15
+ #${X} {
16
16
  top: max(10px, env(safe-area-inset-top, 0px) + 10px);
17
17
  left: 10px;
18
18
  right: 10px;
@@ -219,10 +219,10 @@ var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",thi
219
219
  .storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
220
220
  .storvia-sheet-btn { height: 40px; font-size: 13px; }
221
221
  }
222
- `,Ce={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>'},X={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F"},le=!0;function Re(i){le=i}function be(){if(typeof document>"u")return null;let i=document.getElementById(z);if(!i){if(!document.getElementById(K)){let e=document.createElement("style");e.id=K,e.textContent=ce,document.head.appendChild(e)}i=document.createElement("div"),i.id=z,document.body.appendChild(i)}return i}function he(i,e="info",t=3500,n){if(!le)return;let r=be();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
- <span class="storvia-toast-icon">${Ce[e]}</span>
222
+ `,Se={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>'},ie={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},me=!0;function be(o){me=o}function Pe(){if(typeof document>"u")return null;let o=document.getElementById(X);if(!o){if(!document.getElementById(J)){let e=document.createElement("style");e.id=J,e.textContent=ue,document.head.appendChild(e)}o=document.createElement("div"),o.id=X,document.body.appendChild(o)}return o}function ge(o,e="info",t=3500,n){if(!me)return;let r=Pe();if(!r)return;let i=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
+ <span class="storvia-toast-icon">${Se[e]}</span>
224
224
  <span class="storvia-toast-msg"></span>
225
- `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(o){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function P(i,e){if(i==="INSUFFICIENT_CREDITS"){ae({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||X.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){ae({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||X.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=X[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";he(t,i==="RATE_LIMITED"?"warning":"error")}var q=null;function ae(i){if(typeof document>"u"||q)return;if(!document.getElementById(K)){let s=document.createElement("style");s.id=K,s.textContent=ce,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.innerHTML=`
225
+ `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=o);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(h){console.error("[Storvia toast] action error:",h)}d()}),s.appendChild(a)}if(i){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),i||setTimeout(d,t)}function S(o,e){if(o==="INSUFFICIENT_CREDITS"){he({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||ie.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(o==="DAISY_CARD_REQUIRED"){he({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||ie.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=ie[o]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";ge(t,o==="RATE_LIMITED"?"warning":"error")}var Z=null;function he(o){if(typeof document>"u"||Z)return;if(!document.getElementById(J)){let s=document.createElement("style");s.id=J,s.textContent=ue,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.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,5 +234,6 @@ var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",thi
234
234
  <button type="button" class="storvia-sheet-btn storvia-sheet-btn-primary" data-role="navigate"></button>
235
235
  </div>
236
236
  </div>
237
- `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=i.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=i.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=i.primaryLabel);let o=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),q===e&&(q=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(ee)try{ee(T("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");o()}),document.body.appendChild(e),q=e,requestAnimationFrame(()=>e.classList.add("show"))}var I=class I{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof p||P("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new p("REQUEST_TIMEOUT","Request timed out");return P("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),I.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:r,status:o,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:l}=e,h="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",C=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${C} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${C} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,l])=>n.searchParams.set(a,l));let r=Date.now(),o,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r}),l===a&&this.maybeShowNetworkToast(a),l}}async post(e,t,n){let r=Date.now(),o,s,{controller:c,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:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r,modelName:n?.modelName}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r,modelName:n?.modelName}),l===a&&this.maybeShowNetworkToast(a),l}}async patch(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:o,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:o.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,o,s,c,d){let a=Date.now(),l=o?.modelName?` [model: ${o.modelName}]`:"",h=[],m=v=>{this.debug&&h.push({t:Date.now()-a,event:v})},C=new AbortController,u=null,w=null,R=null,f=null,S=()=>{u!==null&&(clearTimeout(u),u=null),w!==null&&(clearTimeout(w),w=null),R!==null&&(clearTimeout(R),R=null)},H=v=>{f=v,S(),C.abort()};u=setTimeout(()=>H("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let b;try{b=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:C.signal})}catch(v){if(S(),f){let y=new p(f,"Request timed out");throw P(f),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-a,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(v),v}if(u!==null&&(clearTimeout(u),u=null),!b.ok){S();let v=await b.text().catch(()=>""),y={};try{y=JSON.parse(v)}catch{}let Z=y.code||"INTERNAL_ERROR",B=new p(Z,y.message||`HTTP ${b.status}`);throw P(Z,y.message),this.log({method:"STREAM",path:e,body:t,status:b.status,rawResponse:v,error:B,durationMs:Date.now()-a,modelName:o?.modelName}),B}let ie=b.body?.getReader();if(!ie)throw S(),new p("INTERNAL_ERROR","No response body for stream");w=setTimeout(()=>H("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let ye=new TextDecoder,F="",E="",oe=!1;try{for(;;){let{done:v,value:y}=await ie.read();if(v)break;let B=ye.decode(y,{stream:!0}).split(`
238
- `);for(let se of B){if(!se.startsWith("data: "))continue;let J=se.slice(6);if(J==="[DONE]"){m("[DONE]"),S(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${l} (${Date.now()-a}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log("Message ID:",F),console.log(`SSE events (${h.length}):`,h),console.groupEnd()),r(F);return}try{let g=JSON.parse(J);m(g),g.type==="done"&&g.id?F=g.id:g.type==="state"?(s&&s(g.delta,g.full??null),d&&Array.isArray(g.createdNames)&&g.createdNames.length&&d(g.createdNames)):g.type==="thinking"?c&&(g.status==="start"||g.status==="end")&&c(g.status):g.content&&(oe?(R!==null&&clearTimeout(R),R=setTimeout(()=>H("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(oe=!0,w!==null&&(clearTimeout(w),w=null),R=setTimeout(()=>H("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),E+=g.content,n(g.content))}catch{m({raw:J})}}}}catch(v){if(S(),f){let y=new p(f,f==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw P(f),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${l} (${Date.now()-a}ms) %c\u2717 ${f}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Timeout:",y),console.groupEnd()),y}throw this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${l} (${Date.now()-a}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Stream error:",v),console.groupEnd()),v}S(),F&&r(F)}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new p(s,r.message||`HTTP ${e.status}`);throw P(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};I.REQUEST_TIMEOUT=6e4,I.MODEL_LOADING_TIMEOUT=18e4,I.STREAM_INACTIVITY_TIMEOUT=6e4;var V=I;var x=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}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(),Q(e.onState),e.onThinking,e.onCreatedCharacters);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),Q(e.onState),e.onThinking,e.onCreatedCharacters);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new p("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(),Q(e.onState),e.onThinking,e.onCreatedCharacters);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 p("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 delete(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Q(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,l)=>{o=a,s=l,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function Q(i){if(i)return(e,t)=>i(e,t)}var te=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},_=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(pe)),this.state=new te(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(pe):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(ue):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?ue(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(r=>r.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 pe(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function ue(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var O=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}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(r=>r.from===e&&r.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 r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,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 me(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ne(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=me(s);e[t]=r}return e}function Te(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=me(n);return e}var M=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ne(r))}setInitial(e){this.mem=e?ne(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return Te(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ne(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=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:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=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];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}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 o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var A=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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 re=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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})}},D=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new re(e,t,n,o)}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)}};function U(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var N=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=ge(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?ge(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(U(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(U(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(U(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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(U(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}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(U(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{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(U(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function ge(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function ve(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var $=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(ve(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(ve(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var j=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new p("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 L=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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var fe="/functions/v1/world-engine/v1",Se="https://api.storvia.ai";function Ee(){return window.__STORVIA__||{}}function Pe(i,e=3e4){let t=Ee();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new p("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let l=window;l.__STORVIA__=a,n(a)}i.send(T("ready",{}))})}var Y=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 k({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?h=>h.source===null||h.source===window:h=>h.source===window.parent,customSend:t?h=>e.callHandler("storviaBus",h):void 0}),de(h=>this.bus.send(h));let n=await Pe(this.bus),r=n.apiBase;if(!r)throw new p("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${fe}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new p("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 p("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 V(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(f=>f.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"";let C=()=>this.gameId,u=()=>this.conversationId,w=()=>this.modelId,R=()=>this.models.find(f=>f.id===this.modelId)?.name;this.chat=new x(this.http,C,u,w,!0,this.previewConfig,R),this.characters=new _(this.http,u,!0,m?.characters,m?.characterStates),this.relationships=new O(this.http,u,!0,m?.relationships),this.inventory=new M(this.http,u,!0,m?.inventory),this.world=new A(this.http,u,!0,m?.world),this.player=new D(this.http,u,!0,m?.player,m?.playerState),this.custom=new N(this.http,u,C,!0,m?.custom,m?.custom_inject),this.save=new $(this.http,u,C,!0,m?.save_data),this.state=new j(this.http,u,!0),this.memory=new L(this.http,u,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(h=>h.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name;this.chat=new x(this.http,c,d,a,!1,void 0,l),this.characters=new _(this.http,d),this.relationships=new O(this.http,d),this.inventory=new M(this.http,d),this.world=new A(this.http,d),this.player=new D(this.http,d),this.custom=new N(this.http,d,c),this.save=new $(this.http,d,c),this.state=new j(this.http,d),this.memory=new L(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new p("UNAUTHORIZED","User not authenticated"):t.status===404?new p("GAME_NOT_FOUND","Game not found or not published"):new p("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Se}${fe}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new V(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new x(this.http,o,s,c,!0,void 0,d),this.characters=new _(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new O(this.http,s,!0,n?.relationships),this.inventory=new M(this.http,s,!0,n?.inventory),this.world=new A(this.http,s,!0,n?.world),this.player=new D(this.http,s,!0,n?.player,n?.playerState),this.custom=new N(this.http,s,o,!0,n?.custom),this.save=new $(this.http,s,o,!0,n?.save_data),this.memory=new L(this.http,s,!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(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function ke(i){let e=new Y;return i?.dev?await e.initDev(i.dev):await e.init(),e}function we(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function xe(i){return we(i)?i.value:i}export{G as PROTOCOL_VERSION,k as StorviaBus,p as StorviaError,Y as StorviaSDK,ke as createStorviaSDK,T as envelope,xe as extractFieldValue,W as isProtocolEnvelope,we as isRichFieldValue,Re as setToastEnabled,he as showToast};
237
+ `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=o.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=o.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=o.primaryLabel);let i=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),Z===e&&(Z=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",i),e.addEventListener("click",s=>{s.target===e&&i()}),r?.addEventListener("click",()=>{if(oe)try{oe(E("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(e),Z=e,requestAnimationFrame(()=>e.classList.add("show"))}var f=class f{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof u||S("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return S("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),f.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:r,status:i,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:h}=e,l="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",p=a!==void 0?` (${a}ms)`:"",g=i!==void 0?` [${i}]`:"",b=h?` [model: ${h}]`:"";d?(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,h])=>n.searchParams.set(a,h));let r=Date.now(),i,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),i=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"GET",path:e,body:t,status:i,rawResponse:s,parsedData:l,durationMs:Date.now()-r}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:i,rawResponse:s,error:h,durationMs:Date.now()-r}),h===a&&this.maybeShowNetworkToast(a),h}}async post(e,t,n){let r=Date.now(),i,s,{controller:c,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:c.signal});d(),i=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"POST",path:e,body:t,status:i,rawResponse:s,parsedData:l,durationMs:Date.now()-r,modelName:n?.modelName}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:i,rawResponse:s,error:h,durationMs:Date.now()-r,modelName:n?.modelName}),h===a&&this.maybeShowNetworkToast(a),h}}async patch(e,t){let n=Date.now(),r,i,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return i=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:i,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:i,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,i,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return i=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:i,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:i,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:i,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:i.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,i,s,c,d,a,h){let l=Date.now(),m=i?.modelName?` [model: ${i.modelName}]`:"",p=[],g=w=>{this.debug&&p.push({t:Date.now()-l,event:w})},b=new AbortController,C=null,I=null,P=null,R=null,k=()=>{C!==null&&(clearTimeout(C),C=null),I!==null&&(clearTimeout(I),I=null),P!==null&&(clearTimeout(P),P=null)},K=w=>{R=w,k(),b.abort()};C=setTimeout(()=>K("REQUEST_TIMEOUT"),f.REQUEST_TIMEOUT);let T;try{T=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:b.signal})}catch(w){if(k(),R){let y=new u(R,"Request timed out");throw S(R),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-l,modelName:i?.modelName}),y}throw this.maybeShowNetworkToast(w),w}if(C!==null&&(clearTimeout(C),C=null),!T.ok){k();let w=await T.text().catch(()=>""),y={};try{y=JSON.parse(w)}catch{}let ne=y.code||"INTERNAL_ERROR",z=new u(ne,y.message||`HTTP ${T.status}`);throw S(ne,y.message),this.log({method:"STREAM",path:e,body:t,status:T.status,rawResponse:w,error:z,durationMs:Date.now()-l,modelName:i?.modelName}),z}let ce=T.body?.getReader();if(!ce)throw k(),new u("INTERNAL_ERROR","No response body for stream");I=setTimeout(()=>K("MODEL_LOADING_TIMEOUT"),f.MODEL_LOADING_TIMEOUT);let Te=new TextDecoder,V="",x="",le=!1,te,q;try{for(;;){let{done:w,value:y}=await ce.read();if(w)break;let z=Te.decode(y,{stream:!0}).split(`
238
+ `);for(let Y of z){if(Y.startsWith("id: ")){q=Y.slice(4);continue}if(!Y.startsWith("data: "))continue;let re=Y.slice(6);if(re==="[DONE]"){g("[DONE]"),k(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${m} (${Date.now()-l}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log("Message ID:",V),console.log(`SSE events (${p.length}):`,p),console.groupEnd()),r(V);return}try{let v=JSON.parse(re);g(v),v.type==="done"&&v.id?V=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(le?(P!==null&&clearTimeout(P),P=setTimeout(()=>K("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)):(le=!0,I!==null&&(clearTimeout(I),I=null),P=setTimeout(()=>K("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)),x+=v.content,n(v.content))}catch{g({raw:re})}q!==void 0&&(te=q,q=void 0)}}}catch(w){if(k(),R){let y=new u(R,R==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw S(R),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${m} (${Date.now()-l}ms) %c\u2717 ${R}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${m} (${Date.now()-l}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h});return}throw w}if(k(),V){r(V);return}a&&await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h})}async resumeLoop(e,t,n){let r=t;for(let s=1;s<=f.RECONNECT_MAX_ATTEMPTS;s++){let c=Math.min(f.RECONNECT_BACKOFF_CAP,1e3*2**(s-1));await new Promise(h=>setTimeout(h,c)),n.onReconnect?.({attempt:s});let d={messageId:"",lastId:r},a;try{a=await this.pumpGetStream(e.conversationId,e.topic,r,d,n)}catch{continue}if(r=d.lastId??r,a==="done"){n.onDone(d.messageId);return}if(a==="inactive"){d.messageId&&n.onDone(d.messageId);return}}let i=new u("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw S("STREAM_INTERRUPTED"),i}async resumeStream(e,t,n){let r={messageId:""},i;try{i=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(i==="done"){n.onDone(r.messageId);return}if(i==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,i){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),f.REQUEST_TIMEOUT),a;try{a=await fetch(s.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal})}finally{clearTimeout(d)}if(!a.ok)throw new u("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let l=a.body?.getReader();return l?await this.pumpReader(l,r,i):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,i,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},f.STREAM_INACTIVITY_TIMEOUT)};c();try{for(;;){let{done:d,value:a}=await e.read();if(d)break;c();let h=r.decode(a,{stream:!0});for(let l of h.split(`
239
+ `)){if(l.startsWith("id: ")){i=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}i!==void 0&&(t.lastId=i,i=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},i={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||i[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var B=f;var O=class{constructor(e,t,n,r,i=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=i;this.previewConfig=s,this.getModelName=c}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(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async active(e={}){if(this.isPreview)return{active:!1};let t={};return e.topic&&(t.topic=e.topic),this.http.get(`/conversations/${encodeURIComponent(this.getConversationId())}/active`,t)}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:H(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),H(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",i=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{i=a,s=h,e.onState&&e.onState(i,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function H(o){if(o)return(e,t)=>o(e,t)}var se=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},A=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ve)),this.state=new se(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(ve):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(fe):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?fe(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(r=>r.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 ve(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 fe(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 M=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(i=>({...i})))}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(r=>r.from===e&&r.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 r=this.mem.find(i=>i.from===e&&i.to===t);r?Object.assign(r,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 ae(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o)){let r={};for(let[i,s]of Object.entries(n))r[i]=we(s);e[t]=r}return e}function ke(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=we(n);return e}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ae(r))}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[r,i]of Object.entries(this.mem))n[r]={...i};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return ke(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ae(t)}async add(e){let{group:t,name:n,count:r=1,desc:i,iconUrl:s}=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:r};i!==void 0&&(d.desc=i),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};i!==void 0&&(c.desc=i),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:i,iconUrl:s}=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];r!==void 0&&(a.count=r),i!==void 0&&(a.desc=i),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),i!==void 0&&(c.desc=i),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=i||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:i})}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 i=this.mem[e];if(i&&Object.keys(i).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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 de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new de(e,t,n,i)}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)}};function $(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var L=class{constructor(e,t,n,r=!1,i,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};i&&(this.mem=ye(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?ye(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`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,i]of Object.entries(e))typeof i=="object"&&i!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...i}:this.mem[r]=i,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch($(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch($(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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)}`,this.getGameId()))}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)}`,this.getGameId()),{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)}`,this.getGameId()))}};function ye(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}function Ie(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,i){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Ie(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ie(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var W=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 G=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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ce="/functions/v1/world-engine/v1",xe="https://api.storvia.ai";function _e(){return window.__STORVIA__||{}}function Oe(o,e=3e4){let t=_e();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let i=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=o.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(i),s(),c();let h=window;h.__STORVIA__=a,n(a)}o.send(E("ready",{}))})}var ee=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 _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),pe(l=>this.bus.send(l));let n=await Oe(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${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 B(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,C=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new O(this.http,p,g,b,!0,this.previewConfig,C),this.characters=new A(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new M(this.http,g,!0,m?.relationships),this.inventory=new D(this.http,g,!0,m?.inventory),this.world=new N(this.http,g,!0,m?.world),this.player=new U(this.http,g,!0,m?.player,m?.playerState),this.custom=new L(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new F(this.http,g,p,!0,m?.save_data),this.state=new W(this.http,g,!0),this.memory=new G(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[i,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=i.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new O(this.http,c,d,a,!1,void 0,h),this.characters=new A(this.http,d),this.relationships=new M(this.http,d),this.inventory=new D(this.http,d),this.world=new N(this.http,d),this.player=new U(this.http,d),this.custom=new L(this.http,d,c),this.save=new F(this.http,d,c),this.state=new W(this.http,d),this.memory=new G(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${xe}${Ce}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new B(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let i=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new O(this.http,i,s,c,!0,void 0,d),this.characters=new A(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new M(this.http,s,!0,n?.relationships),this.inventory=new D(this.http,s,!0,n?.inventory),this.world=new N(this.http,s,!0,n?.world),this.player=new U(this.http,s,!0,n?.player,n?.playerState),this.custom=new L(this.http,s,i,!0,n?.custom),this.save=new F(this.http,s,i,!0,n?.save_data),this.memory=new G(this.http,s,!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(i=>({id:i.id,name:i.name,url:i.url,assetType:i.asset_type,category:i.category}))}};async function Ae(o){let e=new ee;return o?.dev?await e.initDev(o.dev):await e.init(),e}function Re(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function Me(o){return Re(o)?o.value:o}export{j as PROTOCOL_VERSION,_ as StorviaBus,u as StorviaError,ee as StorviaSDK,Ae as createStorviaSDK,E as envelope,Me as extractFieldValue,Q as isProtocolEnvelope,Re as isRichFieldValue,be as setToastEnabled,ge as showToast};
package/dist/index.umd.js CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var StorviaSDK=(()=>{var X=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var Pe=(i,e)=>{for(var t in e)X(i,t,{get:e[t],enumerable:!0})},ke=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Se(e))!Ee.call(i,r)&&r!==t&&X(i,r,{get:()=>e[r],enumerable:!(n=Te(e,r))||n.enumerable});return i};var xe=i=>ke(X({},"__esModule",{value:!0}),i);var $e={};Pe($e,{PROTOCOL_VERSION:()=>x,StorviaBus:()=>P,StorviaError:()=>p,StorviaSDK:()=>B,createStorviaSDK:()=>Ce,envelope:()=>I,extractFieldValue:()=>Re,isProtocolEnvelope:()=>V,isRichFieldValue:()=>se,setToastEnabled:()=>me,showToast:()=>ne});var p=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var x=1;function V(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function I(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var P=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(!V(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},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 r=t;return n.add(r),()=>n.delete(r)}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(o){console.error("[StorviaBus] customSend failed:",o,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(o){console.error("[StorviaBus] postMessage failed:",o,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let o=e.id??_e(),s=I(e.type,e.payload,{id:o}),c=setTimeout(()=>{this.pendingAcks.delete(o),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(o,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 _e(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var te=null;function he(i){te=i}var z="storvia-sdk-toast-style",Q="storvia-sdk-toast-stack",pe=`
2
- #${Q} {
1
+ "use strict";var StorviaSDK=(()=>{var ie=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var _e=Object.prototype.hasOwnProperty;var Oe=(i,e)=>{for(var t in e)ie(i,t,{get:e[t],enumerable:!0})},Ae=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of xe(e))!_e.call(i,r)&&r!==t&&ie(i,r,{get:()=>e[r],enumerable:!(n=ke(e,r))||n.enumerable});return i};var Me=i=>Ae(ie({},"__esModule",{value:!0}),i);var Ve={};Oe(Ve,{PROTOCOL_VERSION:()=>O,StorviaBus:()=>_,StorviaError:()=>u,StorviaSDK:()=>q,createStorviaSDK:()=>Se,envelope:()=>C,extractFieldValue:()=>be,isProtocolEnvelope:()=>B,isRichFieldValue:()=>he,setToastEnabled:()=>we,showToast:()=>ae});var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var O=1;function B(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function C(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var _=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(!B(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 r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(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(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},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 r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:C(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(o){console.error("[StorviaBus] customSend failed:",o,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(o){console.error("[StorviaBus] postMessage failed:",o,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let o=e.id??De(),s=C(e.type,e.payload,{id:o}),c=setTimeout(()=>{this.pendingAcks.delete(o),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(o,d=>{clearTimeout(c),n(d)}),this.send(s)})}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 De(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var se=null;function ge(i){se=i}var X="storvia-sdk-toast-style",ee="storvia-sdk-toast-stack",ve=`
2
+ #${ee} {
3
3
  position: fixed;
4
4
  top: max(20px, env(safe-area-inset-top, 0px) + 20px);
5
5
  right: max(20px, env(safe-area-inset-right, 0px) + 20px);
@@ -12,7 +12,7 @@
12
12
  }
13
13
 
14
14
  @media (max-width: 768px) {
15
- #${Q} {
15
+ #${ee} {
16
16
  top: max(10px, env(safe-area-inset-top, 0px) + 10px);
17
17
  left: 10px;
18
18
  right: 10px;
@@ -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
- `,Oe={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>'},ee={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F"},ue=!0;function me(i){ue=i}function Me(){if(typeof document>"u")return null;let i=document.getElementById(Q);if(!i){if(!document.getElementById(z)){let e=document.createElement("style");e.id=z,e.textContent=pe,document.head.appendChild(e)}i=document.createElement("div"),i.id=Q,document.body.appendChild(i)}return i}function ne(i,e="info",t=3500,n){if(!ue)return;let r=Me();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
- <span class="storvia-toast-icon">${Oe[e]}</span>
222
+ `,Ne={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>'},oe={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",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},fe=!0;function we(i){fe=i}function Ue(){if(typeof document>"u")return null;let i=document.getElementById(ee);if(!i){if(!document.getElementById(X)){let e=document.createElement("style");e.id=X,e.textContent=ve,document.head.appendChild(e)}i=document.createElement("div"),i.id=ee,document.body.appendChild(i)}return i}function ae(i,e="info",t=3500,n){if(!fe)return;let r=Ue();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
223
+ <span class="storvia-toast-icon">${Ne[e]}</span>
224
224
  <span class="storvia-toast-msg"></span>
225
- `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(o){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function k(i,e){if(i==="INSUFFICIENT_CREDITS"){le({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||ee.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){le({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||ee.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=ee[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";ne(t,i==="RATE_LIMITED"?"warning":"error")}var K=null;function le(i){if(typeof document>"u"||K)return;if(!document.getElementById(z)){let s=document.createElement("style");s.id=z,s.textContent=pe,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.innerHTML=`
225
+ `;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.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(h){console.error("[Storvia toast] action error:",h)}d()}),s.appendChild(a)}if(o){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),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function S(i,e){if(i==="INSUFFICIENT_CREDITS"){me({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||oe.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){me({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||oe.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=oe[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";ae(t,i==="RATE_LIMITED"?"warning":"error")}var J=null;function me(i){if(typeof document>"u"||J)return;if(!document.getElementById(X)){let s=document.createElement("style");s.id=X,s.textContent=ve,document.head.appendChild(s)}let e=document.createElement("div");e.className="storvia-sheet-backdrop",e.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,6 +234,7 @@
234
234
  <button type="button" class="storvia-sheet-btn storvia-sheet-btn-primary" data-role="navigate"></button>
235
235
  </div>
236
236
  </div>
237
- `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=i.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=i.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=i.primaryLabel);let o=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),K===e&&(K=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(te)try{te(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");o()}),document.body.appendChild(e),K=e,requestAnimationFrame(()=>e.classList.add("show"))}var C=class C{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof p||k("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new p("REQUEST_TIMEOUT","Request timed out");return k("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),C.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:r,status:o,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:l}=e,h="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",R=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${R} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${h} %c${t} ${n}${u}${w}${R} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,l])=>n.searchParams.set(a,l));let r=Date.now(),o,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r}),l===a&&this.maybeShowNetworkToast(a),l}}async post(e,t,n){let r=Date.now(),o,s,{controller:c,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:c.signal});d(),o=a.status;let{raw:l,data:h}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:h,durationMs:Date.now()-r,modelName:n?.modelName}),h}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,error:l,durationMs:Date.now()-r,modelName:n?.modelName}),l===a&&this.maybeShowNetworkToast(a),l}}async patch(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,parsedData:l,durationMs:Date.now()-n}),l}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:o,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:o.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,o,s,c,d){let a=Date.now(),l=o?.modelName?` [model: ${o.modelName}]`:"",h=[],m=v=>{this.debug&&h.push({t:Date.now()-a,event:v})},R=new AbortController,u=null,w=null,b=null,f=null,S=()=>{u!==null&&(clearTimeout(u),u=null),w!==null&&(clearTimeout(w),w=null),b!==null&&(clearTimeout(b),b=null)},W=v=>{f=v,S(),R.abort()};u=setTimeout(()=>W("REQUEST_TIMEOUT"),C.REQUEST_TIMEOUT);let T;try{T=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:R.signal})}catch(v){if(S(),f){let y=new p(f,"Request timed out");throw k(f),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-a,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(v),v}if(u!==null&&(clearTimeout(u),u=null),!T.ok){S();let v=await T.text().catch(()=>""),y={};try{y=JSON.parse(v)}catch{}let Z=y.code||"INTERNAL_ERROR",q=new p(Z,y.message||`HTTP ${T.status}`);throw k(Z,y.message),this.log({method:"STREAM",path:e,body:t,status:T.status,rawResponse:v,error:q,durationMs:Date.now()-a,modelName:o?.modelName}),q}let ae=T.body?.getReader();if(!ae)throw S(),new p("INTERNAL_ERROR","No response body for stream");w=setTimeout(()=>W("MODEL_LOADING_TIMEOUT"),C.MODEL_LOADING_TIMEOUT);let be=new TextDecoder,G="",E="",de=!1;try{for(;;){let{done:v,value:y}=await ae.read();if(v)break;let q=be.decode(y,{stream:!0}).split(`
238
- `);for(let ce of q){if(!ce.startsWith("data: "))continue;let J=ce.slice(6);if(J==="[DONE]"){m("[DONE]"),S(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log("Message ID:",G),console.log(`SSE events (${h.length}):`,h),console.groupEnd()),r(G);return}try{let g=JSON.parse(J);m(g),g.type==="done"&&g.id?G=g.id:g.type==="state"?(s&&s(g.delta,g.full??null),d&&Array.isArray(g.createdNames)&&g.createdNames.length&&d(g.createdNames)):g.type==="thinking"?c&&(g.status==="start"||g.status==="end")&&c(g.status):g.content&&(de?(b!==null&&clearTimeout(b),b=setTimeout(()=>W("STREAM_INACTIVITY"),C.STREAM_INACTIVITY_TIMEOUT)):(de=!0,w!==null&&(clearTimeout(w),w=null),b=setTimeout(()=>W("STREAM_INACTIVITY"),C.STREAM_INACTIVITY_TIMEOUT)),E+=g.content,n(g.content))}catch{m({raw:J})}}}}catch(v){if(S(),f){let y=new p(f,f==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw k(f),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2717 ${f}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Timeout:",y),console.groupEnd()),y}throw this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${T.status}]${l} (${Date.now()-a}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${E.length} chars):`,E),console.log(`SSE events (${h.length}):`,h),console.error("Stream error:",v),console.groupEnd()),v}S(),G&&r(G)}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new p(s,r.message||`HTTP ${e.status}`);throw k(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};C.REQUEST_TIMEOUT=6e4,C.MODEL_LOADING_TIMEOUT=18e4,C.STREAM_INACTIVITY_TIMEOUT=6e4;var j=C;var _=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new p("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(),Y(e.onState),e.onThinking,e.onCreatedCharacters);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 p("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 delete(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new p("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),Y(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,l)=>{o=a,s=l,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function Y(i){if(i)return(e,t)=>i(e,t)}var re=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},O=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ge)),this.state=new re(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ge):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(ve):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?ve(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(r=>r.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 ge(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function ve(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var M=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}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(r=>r.from===e&&r.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 r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,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 fe(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ie(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=fe(s);e[t]=r}return e}function Ae(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=fe(n);return e}var A=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ie(r))}setInitial(e){this.mem=e?ie(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return Ae(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ie(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=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:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=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];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}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 o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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 oe=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new oe(e,t,n,o)}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)}};function N(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var $=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=we(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?we(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(N(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(N(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(N(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{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(N(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function we(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function ye(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var L=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(ye(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(ye(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var H=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new p("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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ie="/functions/v1/world-engine/v1",De="https://api.storvia.ai";function Ue(){return window.__STORVIA__||{}}function Ne(i,e=3e4){let t=Ue();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new p("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let l=window;l.__STORVIA__=a,n(a)}i.send(I("ready",{}))})}var B=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 P({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?h=>h.source===null||h.source===window:h=>h.source===window.parent,customSend:t?h=>e.callHandler("storviaBus",h):void 0}),he(h=>this.bus.send(h));let n=await Ne(this.bus),r=n.apiBase;if(!r)throw new p("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ie}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new p("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 p("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[h,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(f=>f.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"";let R=()=>this.gameId,u=()=>this.conversationId,w=()=>this.modelId,b=()=>this.models.find(f=>f.id===this.modelId)?.name;this.chat=new _(this.http,R,u,w,!0,this.previewConfig,b),this.characters=new O(this.http,u,!0,m?.characters,m?.characterStates),this.relationships=new M(this.http,u,!0,m?.relationships),this.inventory=new A(this.http,u,!0,m?.inventory),this.world=new D(this.http,u,!0,m?.world),this.player=new U(this.http,u,!0,m?.player,m?.playerState),this.custom=new $(this.http,u,R,!0,m?.custom,m?.custom_inject),this.save=new L(this.http,u,R,!0,m?.save_data),this.state=new H(this.http,u,!0),this.memory=new F(this.http,u,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(h=>h.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name;this.chat=new _(this.http,c,d,a,!1,void 0,l),this.characters=new O(this.http,d),this.relationships=new M(this.http,d),this.inventory=new A(this.http,d),this.world=new D(this.http,d),this.player=new U(this.http,d),this.custom=new $(this.http,d,c),this.save=new L(this.http,d,c),this.state=new H(this.http,d),this.memory=new F(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new p("UNAUTHORIZED","User not authenticated"):t.status===404?new p("GAME_NOT_FOUND","Game not found or not published"):new p("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${De}${Ie}`,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 r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new _(this.http,o,s,c,!0,void 0,d),this.characters=new O(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new M(this.http,s,!0,n?.relationships),this.inventory=new A(this.http,s,!0,n?.inventory),this.world=new D(this.http,s,!0,n?.world),this.player=new U(this.http,s,!0,n?.player,n?.playerState),this.custom=new $(this.http,s,o,!0,n?.custom),this.save=new L(this.http,s,o,!0,n?.save_data),this.memory=new F(this.http,s,!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(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Ce(i){let e=new B;return i?.dev?await e.initDev(i.dev):await e.init(),e}function se(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function Re(i){return se(i)?i.value:i}return xe($e);})();
237
+ `;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=i.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=i.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=i.primaryLabel);let o=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),J===e&&(J=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(se)try{se(C("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");o()}),document.body.appendChild(e),J=e,requestAnimationFrame(()=>e.classList.add("show"))}var f=class f{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof u||S("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return S("REQUEST_TIMEOUT"),t}return e}createTimeoutController(){let e=new AbortController,t=setTimeout(()=>e.abort(),f.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:r,status:o,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:h}=e,l="%c[Storvia SDK]",m="color: #6366f1; font-weight: bold",p=a!==void 0?` (${a}ms)`:"",g=o!==void 0?` [${o}]`:"",b=h?` [model: ${h}]`:"";d?(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2717`,m,"color: #e0e0e0","color: #ef4444"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),console.error("Error:",d),console.groupEnd()):(console.groupCollapsed(`${l} %c${t} ${n}${g}${b}${p} %c\u2713`,m,"color: #e0e0e0","color: #22c55e"),r!==void 0&&console.log("Request:",r),s!==void 0&&console.log("Response (raw):",s),c!==void 0&&c!==s&&console.log("Response (data):",c),console.groupEnd())}async get(e,t){let n=new URL(`${this.baseUrl}${e}`);t&&Object.entries(t).forEach(([a,h])=>n.searchParams.set(a,h));let r=Date.now(),o,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),o=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:l,durationMs:Date.now()-r}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,error:h,durationMs:Date.now()-r}),h===a&&this.maybeShowNetworkToast(a),h}}async post(e,t,n){let r=Date.now(),o,s,{controller:c,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:c.signal});d(),o=a.status;let{raw:h,data:l}=await this.handleResponseWithRaw(a);return s=h,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:l,durationMs:Date.now()-r,modelName:n?.modelName}),l}catch(a){d();let h=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,error:h,durationMs:Date.now()-r,modelName:n?.modelName}),h===a&&this.maybeShowNetworkToast(a),h}}async patch(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,o,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:h}=await this.handleResponseWithRaw(d);return o=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,parsedData:h,durationMs:Date.now()-n}),h}catch(d){c();let a=this.wrapAbortError(d);throw this.log({method:"PUT",path:e,body:t,status:r,rawResponse:o,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:o,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:o.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,o,s,c,d,a,h){let l=Date.now(),m=o?.modelName?` [model: ${o.modelName}]`:"",p=[],g=w=>{this.debug&&p.push({t:Date.now()-l,event:w})},b=new AbortController,R=null,I=null,P=null,T=null,k=()=>{R!==null&&(clearTimeout(R),R=null),I!==null&&(clearTimeout(I),I=null),P!==null&&(clearTimeout(P),P=null)},z=w=>{T=w,k(),b.abort()};R=setTimeout(()=>z("REQUEST_TIMEOUT"),f.REQUEST_TIMEOUT);let E;try{E=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:b.signal})}catch(w){if(k(),T){let y=new u(T,"Request timed out");throw S(T),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-l,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(w),w}if(R!==null&&(clearTimeout(R),R=null),!E.ok){k();let w=await E.text().catch(()=>""),y={};try{y=JSON.parse(w)}catch{}let ne=y.code||"INTERNAL_ERROR",Q=new u(ne,y.message||`HTTP ${E.status}`);throw S(ne,y.message),this.log({method:"STREAM",path:e,body:t,status:E.status,rawResponse:w,error:Q,durationMs:Date.now()-l,modelName:o?.modelName}),Q}let pe=E.body?.getReader();if(!pe)throw k(),new u("INTERNAL_ERROR","No response body for stream");I=setTimeout(()=>z("MODEL_LOADING_TIMEOUT"),f.MODEL_LOADING_TIMEOUT);let Pe=new TextDecoder,j="",x="",ue=!1,te,Y;try{for(;;){let{done:w,value:y}=await pe.read();if(w)break;let Q=Pe.decode(y,{stream:!0}).split(`
238
+ `);for(let Z of Q){if(Z.startsWith("id: ")){Y=Z.slice(4);continue}if(!Z.startsWith("data: "))continue;let re=Z.slice(6);if(re==="[DONE]"){g("[DONE]"),k(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log("Message ID:",j),console.log(`SSE events (${p.length}):`,p),console.groupEnd()),r(j);return}try{let v=JSON.parse(re);g(v),v.type==="done"&&v.id?j=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(ue?(P!==null&&clearTimeout(P),P=setTimeout(()=>z("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)):(ue=!0,I!==null&&(clearTimeout(I),I=null),P=setTimeout(()=>z("STREAM_INACTIVITY"),f.STREAM_INACTIVITY_TIMEOUT)),x+=v.content,n(v.content))}catch{g({raw:re})}Y!==void 0&&(te=Y,Y=void 0)}}}catch(w){if(k(),T){let y=new u(T,T==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw S(T),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2717 ${T}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${m} (${Date.now()-l}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${x.length} chars):`,x),console.log(`SSE events (${p.length}):`,p),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h});return}throw w}if(k(),j){r(j);return}a&&await this.resumeLoop(a,te,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:h})}async resumeLoop(e,t,n){let r=t;for(let s=1;s<=f.RECONNECT_MAX_ATTEMPTS;s++){let c=Math.min(f.RECONNECT_BACKOFF_CAP,1e3*2**(s-1));await new Promise(h=>setTimeout(h,c)),n.onReconnect?.({attempt:s});let d={messageId:"",lastId:r},a;try{a=await this.pumpGetStream(e.conversationId,e.topic,r,d,n)}catch{continue}if(r=d.lastId??r,a==="done"){n.onDone(d.messageId);return}if(a==="inactive"){d.messageId&&n.onDone(d.messageId);return}}let o=new u("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw S("STREAM_INTERRUPTED"),o}async resumeStream(e,t,n){let r={messageId:""},o;try{o=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(o==="done"){n.onDone(r.messageId);return}if(o==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,o){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),f.REQUEST_TIMEOUT),a;try{a=await fetch(s.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal})}finally{clearTimeout(d)}if(!a.ok)throw new u("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let l=a.body?.getReader();return l?await this.pumpReader(l,r,o):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,o,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},f.STREAM_INACTIVITY_TIMEOUT)};c();try{for(;;){let{done:d,value:a}=await e.read();if(d)break;c();let h=r.decode(a,{stream:!0});for(let l of h.split(`
239
+ `)){if(l.startsWith("id: ")){o=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var H=f;var A=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);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(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.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 delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async active(e={}){if(this.isPreview)return{active:!1};let t={};return e.topic&&(t.topic=e.topic),this.http.get(`/conversations/${encodeURIComponent(this.getConversationId())}/active`,t)}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:W(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}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.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{o=a,s=h,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function W(i){if(i)return(e,t)=>i(e,t)}var de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}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 r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},M=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ye)),this.state=new de(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Ie):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Ie(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(r=>r.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(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function Ie(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}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(r=>r.from===e&&r.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 r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,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 Ce(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ce(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=Ce(s);e[t]=r}return e}function $e(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Ce(n);return e}var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ce(r))}setInitial(e){this.mem=e?ce(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return $e(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ce(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=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:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=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];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}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:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}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 o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var U=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}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})}},$=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new le(e,t,n,o)}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)}};function L(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=Re(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Re(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(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{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(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Re(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function Te(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var G=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var K=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 V=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 r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ee="/functions/v1/world-engine/v1",Le="https://api.storvia.ai";function Fe(){return window.__STORVIA__||{}}function Ge(i,e=3e4){let t=Fe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let h=window;h.__STORVIA__=a,n(a)}i.send(C("ready",{}))})}var q=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 _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),ge(l=>this.bus.send(l));let n=await Ge(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${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 H(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,R=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new A(this.http,p,g,b,!0,this.previewConfig,R),this.characters=new M(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new D(this.http,g,!0,m?.relationships),this.inventory=new N(this.http,g,!0,m?.inventory),this.world=new U(this.http,g,!0,m?.world),this.player=new $(this.http,g,!0,m?.player,m?.playerState),this.custom=new F(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new G(this.http,g,p,!0,m?.save_data),this.state=new K(this.http,g,!0),this.memory=new V(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new A(this.http,c,d,a,!1,void 0,h),this.characters=new M(this.http,d),this.relationships=new D(this.http,d),this.inventory=new N(this.http,d),this.world=new U(this.http,d),this.player=new $(this.http,d),this.custom=new F(this.http,d,c),this.save=new G(this.http,d,c),this.state=new K(this.http,d),this.memory=new V(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}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 fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Le}${Ee}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new H(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new A(this.http,o,s,c,!0,void 0,d),this.characters=new M(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new D(this.http,s,!0,n?.relationships),this.inventory=new N(this.http,s,!0,n?.inventory),this.world=new U(this.http,s,!0,n?.world),this.player=new $(this.http,s,!0,n?.player,n?.playerState),this.custom=new F(this.http,s,o,!0,n?.custom),this.save=new G(this.http,s,o,!0,n?.save_data),this.memory=new V(this.http,s,!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(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Se(i){let e=new q;return i?.dev?await e.initDev(i.dev):await e.init(),e}function he(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function be(i){return he(i)?i.value:i}return Me(Ve);})();
239
240
  if(typeof window!=="undefined"){window.createStorviaSDK=StorviaSDK.createStorviaSDK;}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storvia/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Storvia World SDK - Build interactive text games on the Storvia platform",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",