@storvia/sdk 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +7 -7
- package/dist/index.d.mts +19 -16
- package/dist/index.esm.js +7 -7
- package/dist/index.umd.js +7 -7
- package/package.json +44 -44
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var le=Object.defineProperty;var
|
|
1
|
+
"use strict";var le=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var Be=(i,e)=>{for(var t in e)le(i,t,{get:e[t],enumerable:!0})},je=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ve(e))!He.call(i,r)&&r!==t&&le(i,r,{get:()=>e[r],enumerable:!(n=Ge(e,r))||n.enumerable});return i};var We=i=>je(le({},"__esModule",{value:!0}),i);var tt={};Be(tt,{PROTOCOL_VERSION:()=>L,StorviaBus:()=>N,StorviaError:()=>m,StorviaSDK:()=>te,createStorviaSDK:()=>Le,envelope:()=>E,extractFieldValue:()=>Fe,isProtocolEnvelope:()=>J,isRichFieldValue:()=>ye,setToastEnabled:()=>xe,showToast:()=>pe});module.exports=We(tt);var m=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var L=1;function J(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function E(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var N=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(!J(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:E(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??qe(),s=E(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 qe(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var ue=null;function Se(i){ue=i}var se="storvia-sdk-toast-style",ae="storvia-sdk-toast-stack",Pe=`
|
|
2
2
|
#${ae} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
.storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
|
|
220
220
|
.storvia-sheet-btn { height: 40px; font-size: 13px; }
|
|
221
221
|
}
|
|
222
|
-
`,
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,Ke={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>'},he={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",INVALID_EXTRACT_RULE:"\u56DE\u590D\u63D0\u53D6\u914D\u7F6E\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",GENERATION_LOST:"\u751F\u6210\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5\uFF1B\u82E5\u5185\u5BB9\u5DF2\u751F\u6210\uFF0C\u5237\u65B0\u540E\u53EF\u89C1",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",GENERATION_ABORTED:"\u751F\u6210\u5DF2\u505C\u6B62"},ke=!0;function xe(i){ke=i}function ze(){if(typeof document>"u")return null;let i=document.getElementById(ae);if(!i){if(!document.getElementById(se)){let e=document.createElement("style");e.id=se,e.textContent=Pe,document.head.appendChild(e)}i=document.createElement("div"),i.id=ae,document.body.appendChild(i)}return i}function pe(i,e="info",t=3500,n){if(!ke)return;let r=ze();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${Ke[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=
|
|
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 S(i,e){if(i==="GENERATION_ABORTED")return;if(i==="INSUFFICIENT_CREDITS"){Ee({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||he.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){Ee({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||he.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=he[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";pe(t,i==="RATE_LIMITED"?"warning":"error")}var oe=null;function Ee(i){if(typeof document>"u"||oe)return;if(!document.getElementById(se)){let s=document.createElement("style");s.id=se,s.textContent=Pe,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,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=
|
|
238
|
-
`);U=x.pop()??"";for(let
|
|
239
|
-
`);d=v.pop()??"";for(let h of v)l(h);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 p(s,r.message||`HTTP ${e.status}`);throw E(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,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var X=I;function ze(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let o=new Uint8Array(16);crypto.getRandomValues(o),o[6]=o[6]&15|64,o[8]=o[8]&63|128;let e=Array.from(o,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var V=class{constructor(e,t,n,r,i=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=i;this.previewConfig=s,this.getModelName=c,this.getStoryMode=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.(),client_message_uuid:ze()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),story_mode:this.getStoryMode?.()===!0,extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:G(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],story_mode:this.getStoryMode?.()};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(),G(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,l)=>{i=a,s=l,e.onState&&e.onState(i,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r,truncated:!1};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function G(o){if(o)return(e,t)=>o(e,t)}var ge=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})}},B=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(_e)),this.state=new ge(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(_e):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Oe):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Oe(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 _e(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 Oe(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 j=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 Ae(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 ve(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]=Ae(s);e[t]=r}return e}function Ye(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=Ae(n);return e}var H=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ve(r))}setInitial(e){this.mem=e?ve(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 Ye(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ve(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 W=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 fe=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})}},q=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 fe(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 K(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var z=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=Me(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Me(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(K(`/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(K(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(K(`/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(K(`/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(K(`/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(K(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Me(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 De(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var Y=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(De(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(De(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var ee=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 Q=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 Ne="/functions/v1/world-engine/v1",Qe="https://api.storvia.ai";function Ze(){return window.__STORVIA__||{}}function Je(o,e=3e4){let t=Ze();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let i=setTimeout(()=>{s(),c(),r(new p("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,storyMode:a.payload.storyMode,debug:a.payload.debug})}),c=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(i),s(),c();let l=window;l.__STORVIA__=a,n(a)}o.send(S("ready",{}))})}var te=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.storyMode=!1;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 N({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?u=>u.source===null||u.source===window:u=>u.source===window.parent,customSend:t?u=>e.callHandler("storviaBus",u):void 0}),Ee(u=>this.bus.send(u));let n=await Je(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}${Ne}`,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 X(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[u,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=u,this.modelId=(n.selectedModelId&&u.some(R=>R.id===n.selectedModelId)?n.selectedModelId:"")||u[0]?.id||"",this.storyMode=n.storyMode===!0;let h=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,b=()=>this.models.find(R=>R.id===this.modelId)?.name,T=()=>this.storyMode;this.chat=new V(this.http,h,y,f,!0,this.previewConfig,b,T),this.characters=new B(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new j(this.http,y,!0,v?.relationships),this.inventory=new H(this.http,y,!0,v?.inventory),this.world=new W(this.http,y,!0,v?.world),this.player=new q(this.http,y,!0,v?.player,v?.playerState),this.custom=new z(this.http,y,h,!0,v?.custom,v?.custom_inject),this.save=new Y(this.http,y,h,!0,v?.save_data),this.state=new ee(this.http,y,!0),this.memory=new Q(this.http,y,!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(u=>u.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"",this.storyMode=n.storyMode===!0;let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(u=>u.id===this.modelId)?.name,g=()=>this.storyMode;this.chat=new V(this.http,c,d,a,!1,void 0,l,g),this.characters=new B(this.http,d),this.relationships=new j(this.http,d),this.inventory=new H(this.http,d),this.world=new W(this.http,d),this.player=new q(this.http,d),this.custom=new z(this.http,d,c),this.save=new Y(this.http,d,c),this.state=new ee(this.http,d),this.memory=new Q(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)}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0}),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=`${Qe}${Ne}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new X(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 V(this.http,i,s,c,!0,void 0,d),this.characters=new B(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new j(this.http,s,!0,n?.relationships),this.inventory=new H(this.http,s,!0,n?.inventory),this.world=new W(this.http,s,!0,n?.world),this.player=new q(this.http,s,!0,n?.player,n?.playerState),this.custom=new z(this.http,s,i,!0,n?.custom),this.save=new Y(this.http,s,i,!0,n?.save_data),this.memory=new Q(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 Ue(o){let e=new te;return o?.dev?await e.initDev(o.dev):await e.init(),e}function ye(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function $e(o){return ye(o)?o.value:o}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(),oe===e&&(oe=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(ue)try{ue(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");o()}),document.body.appendChild(e),oe=e,requestAnimationFrame(()=>e.classList.add("show"))}function Ye(i,e){let t=e?.tickMs??100,n=e?.baseLagMs??1e3,r=e?.maxLagMs??2500,o=e?.minCharsPerTick??2,s="",c=null,d=0,a=0,l=()=>Math.min(r,Math.max(n,d*1.35)),p=()=>{let f=Math.max(o,Math.ceil(s.length*t/l()));if(f>=s.length)f=s.length;else{let T=s.charCodeAt(f-1);T>=55296&&T<=56319&&f++}let R=s.slice(0,f);s=s.slice(f),R&&i(R)},h=()=>{c=null,p(),s&&(c=setTimeout(h,t))};return{push:f=>{let R=Date.now();if(a>0){let T=Math.min(R-a,r);d=d>0?d*.7+T*.3:T}a=R,s+=f,c===null&&h()},flush:()=>{c!==null&&(clearTimeout(c),c=null),s&&(i(s),s="")},cancel:()=>{c!==null&&(clearTimeout(c),c=null),s=""}}}function me(i){let e=Ye(i.onChunk);return{cbs:{onChunk:n=>e.push(n),onDone:(n,r)=>{e.flush(),i.onDone(n,r)},onAborted:i.onAborted?n=>{e.flush(),i.onAborted(n)}:void 0,onState:i.onState?(n,r)=>{e.flush(),i.onState(n,r)}:void 0,onThinking:i.onThinking?n=>{e.flush(),i.onThinking(n)}:void 0,onCreatedCharacters:i.onCreatedCharacters?n=>{e.flush(),i.onCreatedCharacters(n)}:void 0,onReconnect:i.onReconnect},flush:()=>e.flush()}}function F(i,e){if(e.aborted){if(i.onAborted){i.onAborted(e.aborted);return}i.onDone(e.aborted.id,{truncated:!1});return}i.onDone(e.messageId,e.truncated===void 0?void 0:{truncated:e.truncated})}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 m||S("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new m("REQUEST_TIMEOUT","Request timed out");return S("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,p="%c[Storvia SDK]",h="color: #6366f1; font-weight: bold",v=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",y=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${p} %c${t} ${n}${u}${y}${v} %c\u2717`,h,"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(`${p} %c${t} ${n}${u}${y}${v} %c\u2713`,h,"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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r}),p}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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r,modelName:n?.modelName}),p}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,a,l,p){let h=Date.now(),v=o?.modelName?` [model: ${o.modelName}]`:"",u=[],y=w=>{this.debug&&u.push({t:Date.now()-h,event:w})},{cbs:f,flush:R}=me({onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l,onAborted:p}),T=new AbortController,b=null,O=null,A=null,P=null,M=()=>{b!==null&&(clearTimeout(b),b=null),O!==null&&(clearTimeout(O),O=null),A!==null&&(clearTimeout(A),A=null)},ne=w=>{P=w,M(),T.abort()};b=setTimeout(()=>ne("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let k;try{k=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:T.signal})}catch(w){if(M(),P){let C=new m(P,"Request timed out");throw S(P),this.log({method:"STREAM",path:e,body:t,error:C,durationMs:Date.now()-h,modelName:o?.modelName}),C}throw this.maybeShowNetworkToast(w),w}if(b!==null&&(clearTimeout(b),b=null),!k.ok){M();let w=await k.text().catch(()=>""),C={};try{C=JSON.parse(w)}catch{}let x=C.code||"INTERNAL_ERROR",g=C.message||C.error||C.details,Te=new m(x,g||`HTTP ${k.status}`);throw S(x,g),this.log({method:"STREAM",path:e,body:t,status:k.status,rawResponse:w,error:Te,durationMs:Date.now()-h,modelName:o?.modelName}),Te}let we=k.body?.getReader();if(!we)throw M(),new m("INTERNAL_ERROR","No response body for stream");O=setTimeout(()=>ne("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let Ce=new TextDecoder,Z="",de,re,D="",Ie=!1,ce,ie,U="",$=!1,_=null,Re=w=>{if($)return;let C=w.endsWith("\r")?w.slice(0,-1):w;if(C.startsWith("id: ")){ie=C.slice(4);return}if(!C.startsWith("data: "))return;let x=C.slice(6);if(x==="[DONE]"){y("[DONE]"),$=!0;return}try{let g=JSON.parse(x);y(g),g.type==="done"&&g.id?(Z=g.id,de=g.truncated===!0):g.type==="aborted"?(re={id:typeof g.id=="string"?g.id:"",persisted:g.persisted===!0},$=!0):g.type==="error"?(_=new m(g.code||"INTERNAL_ERROR",g.message||"Generation failed"),$=!0):g.type==="state"?(f.onState?.(g.delta,g.full??null),Array.isArray(g.createdNames)&&g.createdNames.length&&f.onCreatedCharacters?.(g.createdNames)):g.type==="thinking"?(g.status==="start"||g.status==="end")&&f.onThinking?.(g.status):g.content&&(Ie?(A!==null&&clearTimeout(A),A=setTimeout(()=>ne("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(Ie=!0,O!==null&&(clearTimeout(O),O=null),A=setTimeout(()=>ne("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),D+=g.content,f.onChunk(g.content))}catch{y({raw:x})}ie!==void 0&&(ce=ie,ie=void 0)},be=()=>{if(M(),_)throw R(),S(_.code,_.message),this.log({method:"STREAM",path:e,body:t,error:_,durationMs:Date.now()-h,modelName:o?.modelName}),_;this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log("Message ID:",Z),re&&console.log("Aborted:",re),console.log(`SSE events (${u.length}):`,u),console.groupEnd()),F(f,{messageId:Z,truncated:de,aborted:re})};try{for(;;){let{done:w,value:C}=await we.read();if(w)break;U+=Ce.decode(C,{stream:!0});let x=U.split(`
|
|
238
|
+
`);U=x.pop()??"";for(let g of x)Re(g);if($){be();return}}if(U+=Ce.decode(),U&&Re(U),$){be();return}}catch(w){if(M(),_)throw _;if(P){let C=new m(P,P==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw S(P),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2717 ${P}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Timeout:",C),console.groupEnd()),R(),C}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,ce,f,{finalize:!0});return}throw R(),w}if(M(),Z){F(f,{messageId:Z,truncated:de});return}if(a){await this.resumeLoop(a,ce,f,{finalize:!0});return}R()}async resumeLoop(e,t,n,r){let o=t;for(let c=1;c<=I.RECONNECT_MAX_ATTEMPTS;c++){let d=Math.min(I.RECONNECT_BACKOFF_CAP,1e3*2**(c-1));await new Promise(p=>setTimeout(p,d)),n.onReconnect?.({attempt:c});let a={messageId:"",lastId:o},l;try{l=await this.pumpGetStream(e.conversationId,e.topic,o,a,n)}catch{continue}if(o=a.lastId??o,l==="done"){if(a.errorCode)throw this.terminalError(a);F(n,a);return}if(l==="inactive"){(a.messageId||r?.finalize)&&F(n,a);return}}let s=new m("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw S("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let{cbs:r}=me(n),o={messageId:""},s;try{s=await this.pumpGetStream(e,t,void 0,o,r)}catch{await this.resumeLoop({conversationId:e,topic:t},o.lastId,r);return}if(s==="done"){if(o.errorCode)throw this.terminalError(o);F(r,o);return}if(s==="inactive"){o.messageId&&F(r,o);return}await this.resumeLoop({conversationId:e,topic:t},o.lastId,r)}terminalError(e){let t=new m(e.errorCode??"INTERNAL_ERROR",e.errorMessage||"Generation failed");return S(t.code,t.message),t}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(),I.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 m("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let p=a.body?.getReader();return p?await this.pumpReader(p,r,o):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,o,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},I.STREAM_INACTIVITY_TIMEOUT)};c();let d="",a=!1,l=p=>{if(a)return;let h=p.endsWith("\r")?p.slice(0,-1):p;if(h.startsWith("id: ")){o=h.slice(4);return}if(!h.startsWith("data: "))return;let v=h.slice(6);if(v==="[DONE]"){a=!0;return}try{let u=JSON.parse(v);u.type==="done"&&u.id?(t.messageId=u.id,t.truncated=u.truncated===!0):u.type==="aborted"?(t.aborted={id:typeof u.id=="string"?u.id:"",persisted:u.persisted===!0},a=!0):u.type==="error"?(t.errorCode=u.code||"INTERNAL_ERROR",t.errorMessage=u.message||"Generation failed",a=!0):u.type==="state"?(n.onState?.(u.delta,u.full??null),Array.isArray(u.createdNames)&&u.createdNames.length&&n.onCreatedCharacters?.(u.createdNames)):u.type==="thinking"?(u.status==="start"||u.status==="end")&&n.onThinking?.(u.status):u.content&&n.onChunk(u.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)};try{for(;;){let{done:p,value:h}=await e.read();if(p)break;c(),d+=r.decode(h,{stream:!0});let v=d.split(`
|
|
239
|
+
`);d=v.pop()??"";for(let u of v)l(u);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 m(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}}};I.REQUEST_TIMEOUT=6e4,I.MODEL_LOADING_TIMEOUT=18e4,I.STREAM_INACTIVITY_TIMEOUT=6e4,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var X=I;function Qe(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let i=new Uint8Array(16);crypto.getRandomValues(i),i[6]=i[6]&15|64,i[8]=i[8]&63|128;let e=Array.from(i,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var _e=20,Oe=40,V=class{constructor(e,t,n,r,o=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewHistory=[];this.previewConfig=s,this.getModelName=c,this.getPreset=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,preset:this.getPreset?.(),client_message_uuid:Qe()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new m("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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),preset:this.getPreset?.(),extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 m("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 m("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 m("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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:G(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t=e.message.trim().length>0,n=this.previewHistory.slice(t?-(_e-1):-_e);t&&this.pushPreviewHistory({role:"user",content:e.message});let r={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:n,preset:this.getPreset?.()};this.previewConfig?r.prompt_config=this.previewConfig:r.game_id=this.getGameId();let o=this.previewConfig;if(o?.reply_length&&(r.reply_length=o.reply_length),o?.reply_language&&(r.reply_language=o.reply_language),e.stream){let p="";await this.http.stream("/preview",r,h=>{p+=h,e.onChunk?.(h)},(h,v)=>{p&&this.pushPreviewHistory({role:"assistant",content:p}),e.onDone?.(h,v)},this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters);return}let s="",c=null,d=null,a=[];await this.http.stream("/preview",r,p=>{s+=p},()=>{},this.reqMeta(),(p,h)=>{c=p,d=h,e.onState&&e.onState(c,d)},void 0,p=>{a=p,e.onCreatedCharacters&&e.onCreatedCharacters(p)}),s&&this.pushPreviewHistory({role:"assistant",content:s});let l={id:"",content:s,truncated:!1};return c&&(l.delta=c,d&&(l.full=d)),a.length&&(l.createdNames=a),l}pushPreviewHistory(e){this.previewHistory.push(e),this.previewHistory.length>Oe&&this.previewHistory.splice(0,this.previewHistory.length-Oe)}};function G(i){if(i)return(e,t)=>i(e,t)}var ge=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})}},H=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(Ae)),this.state=new ge(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(Ae):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Me):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Me(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 Ae(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 Me(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 B=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 De(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 ve(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]=De(s);e[t]=r}return e}function Ze(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=De(n);return e}var j=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ve(r))}setInitial(e){this.mem=e?ve(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 Ze(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ve(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 W=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 fe=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})}},q=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 fe(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 K(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var z=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=Ne(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Ne(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(K(`/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(K(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(K(`/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(K(`/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(K(`/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(K(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Ne(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 Ue(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var Y=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(Ue(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ue(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var ee=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new m("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 Q=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 $e="/functions/v1/world-engine/v1",Je="https://api.storvia.ai";function Xe(){return window.__STORVIA__||{}}function et(i,e=3e4){let t=Xe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new m("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(E("ready",{}))})}var te=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.presetId="";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 N({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}),Se(h=>this.bus.send(h));let n=await et(this.bus),r=n.apiBase;if(!r)throw new m("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${$e}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new m("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 m("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 X(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(b=>b.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.presetId=n.presetId||"";let u=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,R=()=>this.models.find(b=>b.id===this.modelId)?.name,T=()=>this.presetId||void 0;this.chat=new V(this.http,u,y,f,!0,this.previewConfig,R,T),this.characters=new H(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new B(this.http,y,!0,v?.relationships),this.inventory=new j(this.http,y,!0,v?.inventory),this.world=new W(this.http,y,!0,v?.world),this.player=new q(this.http,y,!0,v?.player,v?.playerState),this.custom=new z(this.http,y,u,!0,v?.custom,v?.custom_inject),this.save=new Y(this.http,y,u,!0,v?.save_data),this.state=new ee(this.http,y,!0),this.memory=new Q(this.http,y,!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||"",this.presetId=n.presetId||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name,p=()=>this.presetId||void 0;this.chat=new V(this.http,c,d,a,!1,void 0,l,p),this.characters=new H(this.http,d),this.relationships=new B(this.http,d),this.inventory=new j(this.http,d),this.world=new W(this.http,d),this.player=new q(this.http,d),this.custom=new z(this.http,d,c),this.save=new Y(this.http,d,c),this.state=new ee(this.http,d),this.memory=new Q(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)}),this.bus.on("set-preset",e=>{this.presetId=e.payload?.presetId||""})}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("set-preset",e=>{this.presetId=e.payload?.presetId||""}),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 m("UNAUTHORIZED","User not authenticated"):t.status===404?new m("GAME_NOT_FOUND","Game not found or not published"):new m("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=`${Je}${$e}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new X(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 V(this.http,o,s,c,!0,void 0,d),this.characters=new H(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new B(this.http,s,!0,n?.relationships),this.inventory=new j(this.http,s,!0,n?.inventory),this.world=new W(this.http,s,!0,n?.world),this.player=new q(this.http,s,!0,n?.player,n?.playerState),this.custom=new z(this.http,s,o,!0,n?.custom),this.save=new Y(this.http,s,o,!0,n?.save_data),this.memory=new Q(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 Le(i){let e=new te;return i?.dev?await e.initDev(i.dev):await e.init(),e}function ye(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function Fe(i){return ye(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
|
@@ -11,7 +11,7 @@ interface AssetItem {
|
|
|
11
11
|
assetType: 'avatar' | 'icon';
|
|
12
12
|
category: string;
|
|
13
13
|
}
|
|
14
|
-
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' | 'GENERATION_LOST' | 'REPETITION_LOOP' | 'SAVE_FAILED' | 'FINALIZE_FAILED' | 'CONVERSATION_NOT_FOUND' | 'EMPTY_MESSAGE' | 'CONTINUE_MODEL_NOT_AVAILABLE' | 'CONTINUE_PROMPT_MISSING' | 'GENERATION_ABORTED';
|
|
14
|
+
type StorviaErrorCode = 'UNAUTHORIZED' | 'INSUFFICIENT_CREDITS' | 'VIOLATION_WORD_DETECTED' | 'CONTENT_FILTERED' | 'MODEL_REFUSAL' | 'STREAM_INTERRUPTED' | 'RATE_LIMITED' | 'MODEL_NOT_FOUND' | 'GAME_NOT_FOUND' | 'INVALID_REQUEST' | 'INVALID_EXTRACT_RULE' | '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' | 'GENERATION_LOST' | 'REPETITION_LOOP' | 'SAVE_FAILED' | 'FINALIZE_FAILED' | 'CONVERSATION_NOT_FOUND' | 'EMPTY_MESSAGE' | 'CONTINUE_MODEL_NOT_AVAILABLE' | 'CONTINUE_PROMPT_MISSING' | 'GENERATION_ABORTED';
|
|
15
15
|
/** AI 本轮的属性变更(仅包含发生改变的字段) */
|
|
16
16
|
interface StateChanges {
|
|
17
17
|
/** 世界状态变更(扁平 KV) */
|
|
@@ -203,7 +203,7 @@ interface ChatResponse {
|
|
|
203
203
|
* **始终流式**,无非流式分支。
|
|
204
204
|
*/
|
|
205
205
|
interface ChatContinueOptions {
|
|
206
|
-
/** 续写哪条支线的最后一条 AI 消息;缺省 =
|
|
206
|
+
/** 续写哪条支线的最后一条 AI 消息;缺省 = 整个会话最新的 AI 消息(不限 topic) */
|
|
207
207
|
topic?: string;
|
|
208
208
|
/**
|
|
209
209
|
* 内容过滤规则;与 send/generate/retry 的 extract 语义一致,流式与入库都只保留 start..end 范围。
|
|
@@ -552,8 +552,9 @@ declare class ChatModule {
|
|
|
552
552
|
private isPreview;
|
|
553
553
|
private previewConfig?;
|
|
554
554
|
private getModelName?;
|
|
555
|
-
private
|
|
556
|
-
|
|
555
|
+
private getPreset?;
|
|
556
|
+
private previewHistory;
|
|
557
|
+
constructor(http: HttpClient, getGameId: () => string, getConversationId: () => string, getModelId: () => string, isPreview?: boolean, previewConfig?: Record<string, unknown>, getModelName?: () => string | undefined, getPreset?: () => string | undefined);
|
|
557
558
|
/** 构造 http 层的元信息(用于 debug 日志标题显示) */
|
|
558
559
|
private reqMeta;
|
|
559
560
|
/** 更新预览配置(由父页面 postMessage 触发) */
|
|
@@ -635,6 +636,8 @@ declare class ChatModule {
|
|
|
635
636
|
* - 本地预览 / dev:无 previewConfig,请求体塞 game_id,服务端按 hash_id 查 prompts
|
|
636
637
|
*/
|
|
637
638
|
private sendPreview;
|
|
639
|
+
/** 预览历史入缓冲 + 截断到上限(保留最近 PREVIEW_HISTORY_CAP 条) */
|
|
640
|
+
private pushPreviewHistory;
|
|
638
641
|
}
|
|
639
642
|
|
|
640
643
|
/**
|
|
@@ -879,8 +882,8 @@ declare class StorviaSDK {
|
|
|
879
882
|
private conversationId;
|
|
880
883
|
private modelId;
|
|
881
884
|
private models;
|
|
882
|
-
/**
|
|
883
|
-
private
|
|
885
|
+
/** 预设 id(per-model);由宿主经 init / 'set-preset' 下发,每次生成请求自动带上 preset */
|
|
886
|
+
private presetId;
|
|
884
887
|
private accessToken;
|
|
885
888
|
private initialized;
|
|
886
889
|
private isPreview;
|
|
@@ -976,12 +979,12 @@ interface InitPayload {
|
|
|
976
979
|
*/
|
|
977
980
|
selectedModelId?: string;
|
|
978
981
|
/**
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
982
|
-
*
|
|
982
|
+
* 宿主当前选中的「预设」id(per-model)。跟 selectedModelId 同一套机制:随 init 下发初始值,
|
|
983
|
+
* 避免竞态;运行时切换走 envelope 'set-preset'。SDK 存内部状态,每次生成请求带上 preset。
|
|
984
|
+
* 剧情已并入预设(剧情=一个预设项)。纯文风/内容分级选择,不是信任边界——服务端仍据
|
|
985
|
+
* metadata.presets + isUnrestricted 兜底。
|
|
983
986
|
*/
|
|
984
|
-
|
|
987
|
+
presetId?: string;
|
|
985
988
|
debug?: boolean;
|
|
986
989
|
}
|
|
987
990
|
interface PreviewConfig {
|
|
@@ -1005,8 +1008,8 @@ interface PreviewInitPayload {
|
|
|
1005
1008
|
provider?: string;
|
|
1006
1009
|
}>;
|
|
1007
1010
|
selectedModelId?: string;
|
|
1008
|
-
/**
|
|
1009
|
-
|
|
1011
|
+
/** 预览模式下宿主当前选中的预设 id 初始值;运行时切换走 'set-preset' */
|
|
1012
|
+
presetId?: string;
|
|
1010
1013
|
debug?: boolean;
|
|
1011
1014
|
}
|
|
1012
1015
|
interface TokenUpdatePayload {
|
|
@@ -1018,8 +1021,8 @@ interface ConfigUpdatePayload {
|
|
|
1018
1021
|
interface SetModelPayload {
|
|
1019
1022
|
modelId: string;
|
|
1020
1023
|
}
|
|
1021
|
-
interface
|
|
1022
|
-
|
|
1024
|
+
interface SetPresetPayload {
|
|
1025
|
+
presetId: string;
|
|
1023
1026
|
}
|
|
1024
1027
|
interface OrientationPayload {
|
|
1025
1028
|
mode: 'landscape' | 'portrait';
|
|
@@ -1044,7 +1047,7 @@ interface AckPayload {
|
|
|
1044
1047
|
ok: boolean;
|
|
1045
1048
|
error?: string;
|
|
1046
1049
|
}
|
|
1047
|
-
type DownstreamMsg = ProtocolEnvelope<'init', InitPayload> | ProtocolEnvelope<'preview-init', PreviewInitPayload> | ProtocolEnvelope<'token-update', TokenUpdatePayload> | ProtocolEnvelope<'config-update', ConfigUpdatePayload> | ProtocolEnvelope<'set-model', SetModelPayload> | ProtocolEnvelope<'set-
|
|
1050
|
+
type DownstreamMsg = ProtocolEnvelope<'init', InitPayload> | ProtocolEnvelope<'preview-init', PreviewInitPayload> | ProtocolEnvelope<'token-update', TokenUpdatePayload> | ProtocolEnvelope<'config-update', ConfigUpdatePayload> | ProtocolEnvelope<'set-model', SetModelPayload> | ProtocolEnvelope<'set-preset', SetPresetPayload> | ProtocolEnvelope<'orientation', OrientationPayload> | ProtocolEnvelope<'ack', AckPayload>;
|
|
1048
1051
|
type UpstreamMsg = ProtocolEnvelope<'ready', ReadyPayload> | ProtocolEnvelope<'exit', Record<string, never>> | ProtocolEnvelope<'request-orientation', OrientationPayload> | ProtocolEnvelope<'error', SdkErrorPayload> | ProtocolEnvelope<'navigate', NavigatePayload> | ProtocolEnvelope<'model-change', SetModelPayload> | ProtocolEnvelope<'ack', AckPayload>;
|
|
1049
1052
|
declare function isProtocolEnvelope(data: unknown): data is ProtocolEnvelope<string, unknown>;
|
|
1050
1053
|
declare function envelope<T extends string, P>(type: T, payload: P, opts?: {
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var g=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var Z=1;function re(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function x(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(!re(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:x(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??Ue(),s=x(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 Ue(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var he=null;function be(i){he=i}var oe="storvia-sdk-toast-style",se="storvia-sdk-toast-stack",Te=`
|
|
2
2
|
#${se} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
@@ -219,10 +219,10 @@ var m=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
|
-
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,$e={success:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',error:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',warning:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',info:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>'},le={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",INVALID_EXTRACT_RULE:"\u56DE\u590D\u63D0\u53D6\u914D\u7F6E\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",GENERATION_LOST:"\u751F\u6210\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5\uFF1B\u82E5\u5185\u5BB9\u5DF2\u751F\u6210\uFF0C\u5237\u65B0\u540E\u53EF\u89C1",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",GENERATION_ABORTED:"\u751F\u6210\u5DF2\u505C\u6B62"},Ee=!0;function Le(i){Ee=i}function Fe(){if(typeof document>"u")return null;let i=document.getElementById(se);if(!i){if(!document.getElementById(oe)){let e=document.createElement("style");e.id=oe,e.textContent=Te,document.head.appendChild(e)}i=document.createElement("div"),i.id=se,document.body.appendChild(i)}return i}function Se(i,e="info",t=3500,n){if(!Ee)return;let r=Fe();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${$e[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=
|
|
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 E(i,e){if(i==="GENERATION_ABORTED")return;if(i==="INSUFFICIENT_CREDITS"){Re({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||le.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){Re({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||le.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=le[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";Se(t,i==="RATE_LIMITED"?"warning":"error")}var ie=null;function Re(i){if(typeof document>"u"||ie)return;if(!document.getElementById(oe)){let s=document.createElement("style");s.id=oe,s.textContent=Te,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,6 @@ var m=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=
|
|
238
|
-
`);N=k.pop()??"";for(let
|
|
239
|
-
`);d=v.pop()??"";for(let h of v)l(h);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 m(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}}};I.REQUEST_TIMEOUT=6e4,I.MODEL_LOADING_TIMEOUT=18e4,I.STREAM_INACTIVITY_TIMEOUT=6e4,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var J=I;function Fe(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let o=new Uint8Array(16);crypto.getRandomValues(o),o[6]=o[6]&15|64,o[8]=o[8]&63|128;let e=Array.from(o,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var G=class{constructor(e,t,n,r,i=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=i;this.previewConfig=s,this.getModelName=c,this.getStoryMode=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.(),client_message_uuid:Fe()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new m("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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),story_mode:this.getStoryMode?.()===!0,extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 m("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 m("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 m("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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:F(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],story_mode:this.getStoryMode?.()};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(),F(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,l)=>{i=a,s=l,e.onState&&e.onState(i,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r,truncated:!1};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function F(o){if(o)return(e,t)=>o(e,t)}var pe=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})}},V=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(Pe)),this.state=new pe(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(Pe):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(ke):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?ke(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(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 ke(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 B=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 xe(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 me(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]=xe(s);e[t]=r}return e}function Ge(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=xe(n);return e}var j=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=me(r))}setInitial(e){this.mem=e?me(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 Ge(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return me(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 H=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 ge=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})}},W=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 ge(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 q(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var K=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=_e(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?_e(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(q(`/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(q(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(q(`/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(q(`/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(q(`/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(q(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function _e(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 Oe(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var z=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(Oe(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Oe(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var X=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new m("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 Y=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 Ae="/functions/v1/world-engine/v1",Ve="https://api.storvia.ai";function Be(){return window.__STORVIA__||{}}function je(o,e=3e4){let t=Be();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let i=setTimeout(()=>{s(),c(),r(new m("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,storyMode:a.payload.storyMode,debug:a.payload.debug})}),c=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(i),s(),c();let l=window;l.__STORVIA__=a,n(a)}o.send(x("ready",{}))})}var ae=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.storyMode=!1;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?u=>u.source===null||u.source===window:u=>u.source===window.parent,customSend:t?u=>e.callHandler("storviaBus",u):void 0}),Re(u=>this.bus.send(u));let n=await je(this.bus),r=n.apiBase;if(!r)throw new m("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ae}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new m("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 m("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[u,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=u,this.modelId=(n.selectedModelId&&u.some(R=>R.id===n.selectedModelId)?n.selectedModelId:"")||u[0]?.id||"",this.storyMode=n.storyMode===!0;let h=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,b=()=>this.models.find(R=>R.id===this.modelId)?.name,T=()=>this.storyMode;this.chat=new G(this.http,h,y,f,!0,this.previewConfig,b,T),this.characters=new V(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new B(this.http,y,!0,v?.relationships),this.inventory=new j(this.http,y,!0,v?.inventory),this.world=new H(this.http,y,!0,v?.world),this.player=new W(this.http,y,!0,v?.player,v?.playerState),this.custom=new K(this.http,y,h,!0,v?.custom,v?.custom_inject),this.save=new z(this.http,y,h,!0,v?.save_data),this.state=new X(this.http,y,!0),this.memory=new Y(this.http,y,!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(u=>u.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"",this.storyMode=n.storyMode===!0;let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(u=>u.id===this.modelId)?.name,g=()=>this.storyMode;this.chat=new G(this.http,c,d,a,!1,void 0,l,g),this.characters=new V(this.http,d),this.relationships=new B(this.http,d),this.inventory=new j(this.http,d),this.world=new H(this.http,d),this.player=new W(this.http,d),this.custom=new K(this.http,d,c),this.save=new z(this.http,d,c),this.state=new X(this.http,d),this.memory=new Y(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)}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0}),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 m("UNAUTHORIZED","User not authenticated"):t.status===404?new m("GAME_NOT_FOUND","Game not found or not published"):new m("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=`${Ve}${Ae}`,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 i=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new G(this.http,i,s,c,!0,void 0,d),this.characters=new V(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new B(this.http,s,!0,n?.relationships),this.inventory=new j(this.http,s,!0,n?.inventory),this.world=new H(this.http,s,!0,n?.world),this.player=new W(this.http,s,!0,n?.player,n?.playerState),this.custom=new K(this.http,s,i,!0,n?.custom),this.save=new z(this.http,s,i,!0,n?.save_data),this.memory=new Y(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 He(o){let e=new ae;return o?.dev?await e.initDev(o.dev):await e.init(),e}function Me(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function We(o){return Me(o)?o.value:o}export{Z as PROTOCOL_VERSION,$ as StorviaBus,m as StorviaError,ae as StorviaSDK,He as createStorviaSDK,x as envelope,We as extractFieldValue,re as isProtocolEnvelope,Me as isRichFieldValue,Ue as setToastEnabled,Ee as 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(),ie===e&&(ie=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(he)try{he(x("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),ie=e,requestAnimationFrame(()=>e.classList.add("show"))}function Ge(i,e){let t=e?.tickMs??100,n=e?.baseLagMs??1e3,r=e?.maxLagMs??2500,o=e?.minCharsPerTick??2,s="",c=null,d=0,a=0,l=()=>Math.min(r,Math.max(n,d*1.35)),p=()=>{let f=Math.max(o,Math.ceil(s.length*t/l()));if(f>=s.length)f=s.length;else{let T=s.charCodeAt(f-1);T>=55296&&T<=56319&&f++}let R=s.slice(0,f);s=s.slice(f),R&&i(R)},h=()=>{c=null,p(),s&&(c=setTimeout(h,t))};return{push:f=>{let R=Date.now();if(a>0){let T=Math.min(R-a,r);d=d>0?d*.7+T*.3:T}a=R,s+=f,c===null&&h()},flush:()=>{c!==null&&(clearTimeout(c),c=null),s&&(i(s),s="")},cancel:()=>{c!==null&&(clearTimeout(c),c=null),s=""}}}function ue(i){let e=Ge(i.onChunk);return{cbs:{onChunk:n=>e.push(n),onDone:(n,r)=>{e.flush(),i.onDone(n,r)},onAborted:i.onAborted?n=>{e.flush(),i.onAborted(n)}:void 0,onState:i.onState?(n,r)=>{e.flush(),i.onState(n,r)}:void 0,onThinking:i.onThinking?n=>{e.flush(),i.onThinking(n)}:void 0,onCreatedCharacters:i.onCreatedCharacters?n=>{e.flush(),i.onCreatedCharacters(n)}:void 0,onReconnect:i.onReconnect},flush:()=>e.flush()}}function L(i,e){if(e.aborted){if(i.onAborted){i.onAborted(e.aborted);return}i.onDone(e.aborted.id,{truncated:!1});return}i.onDone(e.messageId,e.truncated===void 0?void 0:{truncated:e.truncated})}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 g||E("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new g("REQUEST_TIMEOUT","Request timed out");return E("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,p="%c[Storvia SDK]",h="color: #6366f1; font-weight: bold",v=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",y=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${p} %c${t} ${n}${u}${y}${v} %c\u2717`,h,"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(`${p} %c${t} ${n}${u}${y}${v} %c\u2713`,h,"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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r}),p}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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r,modelName:n?.modelName}),p}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,a,l,p){let h=Date.now(),v=o?.modelName?` [model: ${o.modelName}]`:"",u=[],y=w=>{this.debug&&u.push({t:Date.now()-h,event:w})},{cbs:f,flush:R}=ue({onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l,onAborted:p}),T=new AbortController,b=null,O=null,A=null,S=null,M=()=>{b!==null&&(clearTimeout(b),b=null),O!==null&&(clearTimeout(O),O=null),A!==null&&(clearTimeout(A),A=null)},ee=w=>{S=w,M(),T.abort()};b=setTimeout(()=>ee("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let P;try{P=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:T.signal})}catch(w){if(M(),S){let C=new g(S,"Request timed out");throw E(S),this.log({method:"STREAM",path:e,body:t,error:C,durationMs:Date.now()-h,modelName:o?.modelName}),C}throw this.maybeShowNetworkToast(w),w}if(b!==null&&(clearTimeout(b),b=null),!P.ok){M();let w=await P.text().catch(()=>""),C={};try{C=JSON.parse(w)}catch{}let k=C.code||"INTERNAL_ERROR",m=C.message||C.error||C.details,Ie=new g(k,m||`HTTP ${P.status}`);throw E(k,m),this.log({method:"STREAM",path:e,body:t,status:P.status,rawResponse:w,error:Ie,durationMs:Date.now()-h,modelName:o?.modelName}),Ie}let ve=P.body?.getReader();if(!ve)throw M(),new g("INTERNAL_ERROR","No response body for stream");O=setTimeout(()=>ee("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let fe=new TextDecoder,Q="",de,te,D="",ye=!1,ce,ne,N="",U=!1,_=null,we=w=>{if(U)return;let C=w.endsWith("\r")?w.slice(0,-1):w;if(C.startsWith("id: ")){ne=C.slice(4);return}if(!C.startsWith("data: "))return;let k=C.slice(6);if(k==="[DONE]"){y("[DONE]"),U=!0;return}try{let m=JSON.parse(k);y(m),m.type==="done"&&m.id?(Q=m.id,de=m.truncated===!0):m.type==="aborted"?(te={id:typeof m.id=="string"?m.id:"",persisted:m.persisted===!0},U=!0):m.type==="error"?(_=new g(m.code||"INTERNAL_ERROR",m.message||"Generation failed"),U=!0):m.type==="state"?(f.onState?.(m.delta,m.full??null),Array.isArray(m.createdNames)&&m.createdNames.length&&f.onCreatedCharacters?.(m.createdNames)):m.type==="thinking"?(m.status==="start"||m.status==="end")&&f.onThinking?.(m.status):m.content&&(ye?(A!==null&&clearTimeout(A),A=setTimeout(()=>ee("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(ye=!0,O!==null&&(clearTimeout(O),O=null),A=setTimeout(()=>ee("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),D+=m.content,f.onChunk(m.content))}catch{y({raw:k})}ne!==void 0&&(ce=ne,ne=void 0)},Ce=()=>{if(M(),_)throw R(),E(_.code,_.message),this.log({method:"STREAM",path:e,body:t,error:_,durationMs:Date.now()-h,modelName:o?.modelName}),_;this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${P.status}]${v} (${Date.now()-h}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log("Message ID:",Q),te&&console.log("Aborted:",te),console.log(`SSE events (${u.length}):`,u),console.groupEnd()),L(f,{messageId:Q,truncated:de,aborted:te})};try{for(;;){let{done:w,value:C}=await ve.read();if(w)break;N+=fe.decode(C,{stream:!0});let k=N.split(`
|
|
238
|
+
`);N=k.pop()??"";for(let m of k)we(m);if(U){Ce();return}}if(N+=fe.decode(),N&&we(N),U){Ce();return}}catch(w){if(M(),_)throw _;if(S){let C=new g(S,S==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw E(S),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${P.status}]${v} (${Date.now()-h}ms) %c\u2717 ${S}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Timeout:",C),console.groupEnd()),R(),C}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${P.status}]${v} (${Date.now()-h}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,ce,f,{finalize:!0});return}throw R(),w}if(M(),Q){L(f,{messageId:Q,truncated:de});return}if(a){await this.resumeLoop(a,ce,f,{finalize:!0});return}R()}async resumeLoop(e,t,n,r){let o=t;for(let c=1;c<=I.RECONNECT_MAX_ATTEMPTS;c++){let d=Math.min(I.RECONNECT_BACKOFF_CAP,1e3*2**(c-1));await new Promise(p=>setTimeout(p,d)),n.onReconnect?.({attempt:c});let a={messageId:"",lastId:o},l;try{l=await this.pumpGetStream(e.conversationId,e.topic,o,a,n)}catch{continue}if(o=a.lastId??o,l==="done"){if(a.errorCode)throw this.terminalError(a);L(n,a);return}if(l==="inactive"){(a.messageId||r?.finalize)&&L(n,a);return}}let s=new g("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw E("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let{cbs:r}=ue(n),o={messageId:""},s;try{s=await this.pumpGetStream(e,t,void 0,o,r)}catch{await this.resumeLoop({conversationId:e,topic:t},o.lastId,r);return}if(s==="done"){if(o.errorCode)throw this.terminalError(o);L(r,o);return}if(s==="inactive"){o.messageId&&L(r,o);return}await this.resumeLoop({conversationId:e,topic:t},o.lastId,r)}terminalError(e){let t=new g(e.errorCode??"INTERNAL_ERROR",e.errorMessage||"Generation failed");return E(t.code,t.message),t}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(),I.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 g("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let p=a.body?.getReader();return p?await this.pumpReader(p,r,o):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,o,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},I.STREAM_INACTIVITY_TIMEOUT)};c();let d="",a=!1,l=p=>{if(a)return;let h=p.endsWith("\r")?p.slice(0,-1):p;if(h.startsWith("id: ")){o=h.slice(4);return}if(!h.startsWith("data: "))return;let v=h.slice(6);if(v==="[DONE]"){a=!0;return}try{let u=JSON.parse(v);u.type==="done"&&u.id?(t.messageId=u.id,t.truncated=u.truncated===!0):u.type==="aborted"?(t.aborted={id:typeof u.id=="string"?u.id:"",persisted:u.persisted===!0},a=!0):u.type==="error"?(t.errorCode=u.code||"INTERNAL_ERROR",t.errorMessage=u.message||"Generation failed",a=!0):u.type==="state"?(n.onState?.(u.delta,u.full??null),Array.isArray(u.createdNames)&&u.createdNames.length&&n.onCreatedCharacters?.(u.createdNames)):u.type==="thinking"?(u.status==="start"||u.status==="end")&&n.onThinking?.(u.status):u.content&&n.onChunk(u.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)};try{for(;;){let{done:p,value:h}=await e.read();if(p)break;c(),d+=r.decode(h,{stream:!0});let v=d.split(`
|
|
239
|
+
`);d=v.pop()??"";for(let u of v)l(u);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 g(s,r.message||`HTTP ${e.status}`);throw E(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,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var J=I;function Ve(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let i=new Uint8Array(16);crypto.getRandomValues(i),i[6]=i[6]&15|64,i[8]=i[8]&63|128;let e=Array.from(i,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var Pe=20,ke=40,G=class{constructor(e,t,n,r,o=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewHistory=[];this.previewConfig=s,this.getModelName=c,this.getPreset=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,preset:this.getPreset?.(),client_message_uuid:Ve()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new g("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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),preset:this.getPreset?.(),extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 g("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 g("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 g("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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:F(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t=e.message.trim().length>0,n=this.previewHistory.slice(t?-(Pe-1):-Pe);t&&this.pushPreviewHistory({role:"user",content:e.message});let r={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:n,preset:this.getPreset?.()};this.previewConfig?r.prompt_config=this.previewConfig:r.game_id=this.getGameId();let o=this.previewConfig;if(o?.reply_length&&(r.reply_length=o.reply_length),o?.reply_language&&(r.reply_language=o.reply_language),e.stream){let p="";await this.http.stream("/preview",r,h=>{p+=h,e.onChunk?.(h)},(h,v)=>{p&&this.pushPreviewHistory({role:"assistant",content:p}),e.onDone?.(h,v)},this.reqMeta(),F(e.onState),e.onThinking,e.onCreatedCharacters);return}let s="",c=null,d=null,a=[];await this.http.stream("/preview",r,p=>{s+=p},()=>{},this.reqMeta(),(p,h)=>{c=p,d=h,e.onState&&e.onState(c,d)},void 0,p=>{a=p,e.onCreatedCharacters&&e.onCreatedCharacters(p)}),s&&this.pushPreviewHistory({role:"assistant",content:s});let l={id:"",content:s,truncated:!1};return c&&(l.delta=c,d&&(l.full=d)),a.length&&(l.createdNames=a),l}pushPreviewHistory(e){this.previewHistory.push(e),this.previewHistory.length>ke&&this.previewHistory.splice(0,this.previewHistory.length-ke)}};function F(i){if(i)return(e,t)=>i(e,t)}var pe=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})}},V=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(xe)),this.state=new pe(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(xe):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(_e):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?_e(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 xe(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 _e(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 H=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 Oe(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 me(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]=Oe(s);e[t]=r}return e}function He(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Oe(n);return e}var B=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=me(r))}setInitial(e){this.mem=e?me(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 He(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return me(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 j=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 ge=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})}},W=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 ge(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 q(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var K=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=Ae(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Ae(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(q(`/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(q(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(q(`/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(q(`/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(q(`/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(q(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Ae(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 Me(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var z=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(Me(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Me(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var X=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new g("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 Y=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 De="/functions/v1/world-engine/v1",Be="https://api.storvia.ai";function je(){return window.__STORVIA__||{}}function We(i,e=3e4){let t=je();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new g("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(x("ready",{}))})}var ae=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.presetId="";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?h=>h.source===null||h.source===window:h=>h.source===window.parent,customSend:t?h=>e.callHandler("storviaBus",h):void 0}),be(h=>this.bus.send(h));let n=await We(this.bus),r=n.apiBase;if(!r)throw new g("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${De}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new g("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 g("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,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(b=>b.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.presetId=n.presetId||"";let u=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,R=()=>this.models.find(b=>b.id===this.modelId)?.name,T=()=>this.presetId||void 0;this.chat=new G(this.http,u,y,f,!0,this.previewConfig,R,T),this.characters=new V(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new H(this.http,y,!0,v?.relationships),this.inventory=new B(this.http,y,!0,v?.inventory),this.world=new j(this.http,y,!0,v?.world),this.player=new W(this.http,y,!0,v?.player,v?.playerState),this.custom=new K(this.http,y,u,!0,v?.custom,v?.custom_inject),this.save=new z(this.http,y,u,!0,v?.save_data),this.state=new X(this.http,y,!0),this.memory=new Y(this.http,y,!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||"",this.presetId=n.presetId||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name,p=()=>this.presetId||void 0;this.chat=new G(this.http,c,d,a,!1,void 0,l,p),this.characters=new V(this.http,d),this.relationships=new H(this.http,d),this.inventory=new B(this.http,d),this.world=new j(this.http,d),this.player=new W(this.http,d),this.custom=new K(this.http,d,c),this.save=new z(this.http,d,c),this.state=new X(this.http,d),this.memory=new Y(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)}),this.bus.on("set-preset",e=>{this.presetId=e.payload?.presetId||""})}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("set-preset",e=>{this.presetId=e.payload?.presetId||""}),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 g("UNAUTHORIZED","User not authenticated"):t.status===404?new g("GAME_NOT_FOUND","Game not found or not published"):new g("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=`${Be}${De}`,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 G(this.http,o,s,c,!0,void 0,d),this.characters=new V(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new H(this.http,s,!0,n?.relationships),this.inventory=new B(this.http,s,!0,n?.inventory),this.world=new j(this.http,s,!0,n?.world),this.player=new W(this.http,s,!0,n?.player,n?.playerState),this.custom=new K(this.http,s,o,!0,n?.custom),this.save=new z(this.http,s,o,!0,n?.save_data),this.memory=new Y(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 qe(i){let e=new ae;return i?.dev?await e.initDev(i.dev):await e.init(),e}function Ne(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function Ke(i){return Ne(i)?i.value:i}export{Z as PROTOCOL_VERSION,$ as StorviaBus,g as StorviaError,ae as StorviaSDK,qe as createStorviaSDK,x as envelope,Ke as extractFieldValue,re as isProtocolEnvelope,Ne as isRichFieldValue,Le as setToastEnabled,Se as showToast};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var StorviaSDK=(()=>{var le=Object.defineProperty;var
|
|
1
|
+
"use strict";var StorviaSDK=(()=>{var le=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var Be=(i,e)=>{for(var t in e)le(i,t,{get:e[t],enumerable:!0})},je=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ve(e))!He.call(i,r)&&r!==t&&le(i,r,{get:()=>e[r],enumerable:!(n=Ge(e,r))||n.enumerable});return i};var We=i=>je(le({},"__esModule",{value:!0}),i);var tt={};Be(tt,{PROTOCOL_VERSION:()=>L,StorviaBus:()=>N,StorviaError:()=>m,StorviaSDK:()=>te,createStorviaSDK:()=>Le,envelope:()=>E,extractFieldValue:()=>Fe,isProtocolEnvelope:()=>J,isRichFieldValue:()=>ye,setToastEnabled:()=>xe,showToast:()=>pe});var m=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var L=1;function J(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function E(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var N=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(!J(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:E(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??qe(),s=E(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 qe(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var ue=null;function Se(i){ue=i}var se="storvia-sdk-toast-style",ae="storvia-sdk-toast-stack",Pe=`
|
|
2
2
|
#${ae} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
.storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
|
|
220
220
|
.storvia-sheet-btn { height: 40px; font-size: 13px; }
|
|
221
221
|
}
|
|
222
|
-
`,
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,Ke={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>'},he={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",INVALID_EXTRACT_RULE:"\u56DE\u590D\u63D0\u53D6\u914D\u7F6E\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",GENERATION_LOST:"\u751F\u6210\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5\uFF1B\u82E5\u5185\u5BB9\u5DF2\u751F\u6210\uFF0C\u5237\u65B0\u540E\u53EF\u89C1",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",GENERATION_ABORTED:"\u751F\u6210\u5DF2\u505C\u6B62"},ke=!0;function xe(i){ke=i}function ze(){if(typeof document>"u")return null;let i=document.getElementById(ae);if(!i){if(!document.getElementById(se)){let e=document.createElement("style");e.id=se,e.textContent=Pe,document.head.appendChild(e)}i=document.createElement("div"),i.id=ae,document.body.appendChild(i)}return i}function pe(i,e="info",t=3500,n){if(!ke)return;let r=ze();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${Ke[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=
|
|
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 S(i,e){if(i==="GENERATION_ABORTED")return;if(i==="INSUFFICIENT_CREDITS"){Ee({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||he.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){Ee({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||he.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=he[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";pe(t,i==="RATE_LIMITED"?"warning":"error")}var oe=null;function Ee(i){if(typeof document>"u"||oe)return;if(!document.getElementById(se)){let s=document.createElement("style");s.id=se,s.textContent=Pe,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,7 +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=
|
|
238
|
-
`);U=x.pop()??"";for(let
|
|
239
|
-
`);d=v.pop()??"";for(let h of v)l(h);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 p(s,r.message||`HTTP ${e.status}`);throw E(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,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var X=I;function ze(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let o=new Uint8Array(16);crypto.getRandomValues(o),o[6]=o[6]&15|64,o[8]=o[8]&63|128;let e=Array.from(o,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var V=class{constructor(e,t,n,r,i=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=i;this.previewConfig=s,this.getModelName=c,this.getStoryMode=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.(),client_message_uuid:ze()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),story_mode:this.getStoryMode?.()===!0,extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:G(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],story_mode:this.getStoryMode?.()};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(),G(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,l)=>{i=a,s=l,e.onState&&e.onState(i,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r,truncated:!1};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function G(o){if(o)return(e,t)=>o(e,t)}var ge=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})}},B=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(_e)),this.state=new ge(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(_e):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Oe):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Oe(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 _e(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 Oe(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 j=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 Ae(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 ve(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]=Ae(s);e[t]=r}return e}function Ye(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=Ae(n);return e}var H=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ve(r))}setInitial(e){this.mem=e?ve(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 Ye(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ve(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 W=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 fe=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})}},q=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 fe(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 K(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var z=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=Me(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Me(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(K(`/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(K(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(K(`/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(K(`/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(K(`/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(K(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Me(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 De(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var Y=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(De(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(De(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var ee=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 Q=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 Ne="/functions/v1/world-engine/v1",Qe="https://api.storvia.ai";function Ze(){return window.__STORVIA__||{}}function Je(o,e=3e4){let t=Ze();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let i=setTimeout(()=>{s(),c(),r(new p("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,storyMode:a.payload.storyMode,debug:a.payload.debug})}),c=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(i),s(),c();let l=window;l.__STORVIA__=a,n(a)}o.send(S("ready",{}))})}var te=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.storyMode=!1;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 N({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?u=>u.source===null||u.source===window:u=>u.source===window.parent,customSend:t?u=>e.callHandler("storviaBus",u):void 0}),Ee(u=>this.bus.send(u));let n=await Je(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}${Ne}`,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 X(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[u,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=u,this.modelId=(n.selectedModelId&&u.some(R=>R.id===n.selectedModelId)?n.selectedModelId:"")||u[0]?.id||"",this.storyMode=n.storyMode===!0;let h=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,b=()=>this.models.find(R=>R.id===this.modelId)?.name,T=()=>this.storyMode;this.chat=new V(this.http,h,y,f,!0,this.previewConfig,b,T),this.characters=new B(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new j(this.http,y,!0,v?.relationships),this.inventory=new H(this.http,y,!0,v?.inventory),this.world=new W(this.http,y,!0,v?.world),this.player=new q(this.http,y,!0,v?.player,v?.playerState),this.custom=new z(this.http,y,h,!0,v?.custom,v?.custom_inject),this.save=new Y(this.http,y,h,!0,v?.save_data),this.state=new ee(this.http,y,!0),this.memory=new Q(this.http,y,!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(u=>u.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"",this.storyMode=n.storyMode===!0;let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(u=>u.id===this.modelId)?.name,g=()=>this.storyMode;this.chat=new V(this.http,c,d,a,!1,void 0,l,g),this.characters=new B(this.http,d),this.relationships=new j(this.http,d),this.inventory=new H(this.http,d),this.world=new W(this.http,d),this.player=new q(this.http,d),this.custom=new z(this.http,d,c),this.save=new Y(this.http,d,c),this.state=new ee(this.http,d),this.memory=new Q(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)}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("set-story-mode",e=>{this.storyMode=e.payload?.storyMode===!0}),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=`${Qe}${Ne}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new X(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 V(this.http,i,s,c,!0,void 0,d),this.characters=new B(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new j(this.http,s,!0,n?.relationships),this.inventory=new H(this.http,s,!0,n?.inventory),this.world=new W(this.http,s,!0,n?.world),this.player=new q(this.http,s,!0,n?.player,n?.playerState),this.custom=new z(this.http,s,i,!0,n?.custom),this.save=new Y(this.http,s,i,!0,n?.save_data),this.memory=new Q(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 Ue(o){let e=new te;return o?.dev?await e.initDev(o.dev):await e.init(),e}function ye(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function $e(o){return ye(o)?o.value:o}return je(Xe);})();
|
|
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(),oe===e&&(oe=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(ue)try{ue(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");o()}),document.body.appendChild(e),oe=e,requestAnimationFrame(()=>e.classList.add("show"))}function Ye(i,e){let t=e?.tickMs??100,n=e?.baseLagMs??1e3,r=e?.maxLagMs??2500,o=e?.minCharsPerTick??2,s="",c=null,d=0,a=0,l=()=>Math.min(r,Math.max(n,d*1.35)),p=()=>{let f=Math.max(o,Math.ceil(s.length*t/l()));if(f>=s.length)f=s.length;else{let T=s.charCodeAt(f-1);T>=55296&&T<=56319&&f++}let R=s.slice(0,f);s=s.slice(f),R&&i(R)},h=()=>{c=null,p(),s&&(c=setTimeout(h,t))};return{push:f=>{let R=Date.now();if(a>0){let T=Math.min(R-a,r);d=d>0?d*.7+T*.3:T}a=R,s+=f,c===null&&h()},flush:()=>{c!==null&&(clearTimeout(c),c=null),s&&(i(s),s="")},cancel:()=>{c!==null&&(clearTimeout(c),c=null),s=""}}}function me(i){let e=Ye(i.onChunk);return{cbs:{onChunk:n=>e.push(n),onDone:(n,r)=>{e.flush(),i.onDone(n,r)},onAborted:i.onAborted?n=>{e.flush(),i.onAborted(n)}:void 0,onState:i.onState?(n,r)=>{e.flush(),i.onState(n,r)}:void 0,onThinking:i.onThinking?n=>{e.flush(),i.onThinking(n)}:void 0,onCreatedCharacters:i.onCreatedCharacters?n=>{e.flush(),i.onCreatedCharacters(n)}:void 0,onReconnect:i.onReconnect},flush:()=>e.flush()}}function F(i,e){if(e.aborted){if(i.onAborted){i.onAborted(e.aborted);return}i.onDone(e.aborted.id,{truncated:!1});return}i.onDone(e.messageId,e.truncated===void 0?void 0:{truncated:e.truncated})}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 m||S("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new m("REQUEST_TIMEOUT","Request timed out");return S("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,p="%c[Storvia SDK]",h="color: #6366f1; font-weight: bold",v=a!==void 0?` (${a}ms)`:"",u=o!==void 0?` [${o}]`:"",y=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${p} %c${t} ${n}${u}${y}${v} %c\u2717`,h,"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(`${p} %c${t} ${n}${u}${y}${v} %c\u2713`,h,"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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r}),p}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:p}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:o,rawResponse:s,parsedData:p,durationMs:Date.now()-r,modelName:n?.modelName}),p}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,a,l,p){let h=Date.now(),v=o?.modelName?` [model: ${o.modelName}]`:"",u=[],y=w=>{this.debug&&u.push({t:Date.now()-h,event:w})},{cbs:f,flush:R}=me({onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l,onAborted:p}),T=new AbortController,b=null,O=null,A=null,P=null,M=()=>{b!==null&&(clearTimeout(b),b=null),O!==null&&(clearTimeout(O),O=null),A!==null&&(clearTimeout(A),A=null)},ne=w=>{P=w,M(),T.abort()};b=setTimeout(()=>ne("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let k;try{k=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:T.signal})}catch(w){if(M(),P){let C=new m(P,"Request timed out");throw S(P),this.log({method:"STREAM",path:e,body:t,error:C,durationMs:Date.now()-h,modelName:o?.modelName}),C}throw this.maybeShowNetworkToast(w),w}if(b!==null&&(clearTimeout(b),b=null),!k.ok){M();let w=await k.text().catch(()=>""),C={};try{C=JSON.parse(w)}catch{}let x=C.code||"INTERNAL_ERROR",g=C.message||C.error||C.details,Te=new m(x,g||`HTTP ${k.status}`);throw S(x,g),this.log({method:"STREAM",path:e,body:t,status:k.status,rawResponse:w,error:Te,durationMs:Date.now()-h,modelName:o?.modelName}),Te}let we=k.body?.getReader();if(!we)throw M(),new m("INTERNAL_ERROR","No response body for stream");O=setTimeout(()=>ne("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let Ce=new TextDecoder,Z="",de,re,D="",Ie=!1,ce,ie,U="",$=!1,_=null,Re=w=>{if($)return;let C=w.endsWith("\r")?w.slice(0,-1):w;if(C.startsWith("id: ")){ie=C.slice(4);return}if(!C.startsWith("data: "))return;let x=C.slice(6);if(x==="[DONE]"){y("[DONE]"),$=!0;return}try{let g=JSON.parse(x);y(g),g.type==="done"&&g.id?(Z=g.id,de=g.truncated===!0):g.type==="aborted"?(re={id:typeof g.id=="string"?g.id:"",persisted:g.persisted===!0},$=!0):g.type==="error"?(_=new m(g.code||"INTERNAL_ERROR",g.message||"Generation failed"),$=!0):g.type==="state"?(f.onState?.(g.delta,g.full??null),Array.isArray(g.createdNames)&&g.createdNames.length&&f.onCreatedCharacters?.(g.createdNames)):g.type==="thinking"?(g.status==="start"||g.status==="end")&&f.onThinking?.(g.status):g.content&&(Ie?(A!==null&&clearTimeout(A),A=setTimeout(()=>ne("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(Ie=!0,O!==null&&(clearTimeout(O),O=null),A=setTimeout(()=>ne("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),D+=g.content,f.onChunk(g.content))}catch{y({raw:x})}ie!==void 0&&(ce=ie,ie=void 0)},be=()=>{if(M(),_)throw R(),S(_.code,_.message),this.log({method:"STREAM",path:e,body:t,error:_,durationMs:Date.now()-h,modelName:o?.modelName}),_;this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log("Message ID:",Z),re&&console.log("Aborted:",re),console.log(`SSE events (${u.length}):`,u),console.groupEnd()),F(f,{messageId:Z,truncated:de,aborted:re})};try{for(;;){let{done:w,value:C}=await we.read();if(w)break;U+=Ce.decode(C,{stream:!0});let x=U.split(`
|
|
238
|
+
`);U=x.pop()??"";for(let g of x)Re(g);if($){be();return}}if(U+=Ce.decode(),U&&Re(U),$){be();return}}catch(w){if(M(),_)throw _;if(P){let C=new m(P,P==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw S(P),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2717 ${P}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Timeout:",C),console.groupEnd()),R(),C}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${k.status}]${v} (${Date.now()-h}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${D.length} chars):`,D),console.log(`SSE events (${u.length}):`,u),console.error("Stream error:",w),console.groupEnd()),a){await this.resumeLoop(a,ce,f,{finalize:!0});return}throw R(),w}if(M(),Z){F(f,{messageId:Z,truncated:de});return}if(a){await this.resumeLoop(a,ce,f,{finalize:!0});return}R()}async resumeLoop(e,t,n,r){let o=t;for(let c=1;c<=I.RECONNECT_MAX_ATTEMPTS;c++){let d=Math.min(I.RECONNECT_BACKOFF_CAP,1e3*2**(c-1));await new Promise(p=>setTimeout(p,d)),n.onReconnect?.({attempt:c});let a={messageId:"",lastId:o},l;try{l=await this.pumpGetStream(e.conversationId,e.topic,o,a,n)}catch{continue}if(o=a.lastId??o,l==="done"){if(a.errorCode)throw this.terminalError(a);F(n,a);return}if(l==="inactive"){(a.messageId||r?.finalize)&&F(n,a);return}}let s=new m("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw S("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let{cbs:r}=me(n),o={messageId:""},s;try{s=await this.pumpGetStream(e,t,void 0,o,r)}catch{await this.resumeLoop({conversationId:e,topic:t},o.lastId,r);return}if(s==="done"){if(o.errorCode)throw this.terminalError(o);F(r,o);return}if(s==="inactive"){o.messageId&&F(r,o);return}await this.resumeLoop({conversationId:e,topic:t},o.lastId,r)}terminalError(e){let t=new m(e.errorCode??"INTERNAL_ERROR",e.errorMessage||"Generation failed");return S(t.code,t.message),t}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(),I.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 m("STREAM_INTERRUPTED",`Resume HTTP ${a.status}`);if(!(a.headers.get("content-type")||"").includes("text/event-stream"))return"inactive";let p=a.body?.getReader();return p?await this.pumpReader(p,r,o):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,o,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},I.STREAM_INACTIVITY_TIMEOUT)};c();let d="",a=!1,l=p=>{if(a)return;let h=p.endsWith("\r")?p.slice(0,-1):p;if(h.startsWith("id: ")){o=h.slice(4);return}if(!h.startsWith("data: "))return;let v=h.slice(6);if(v==="[DONE]"){a=!0;return}try{let u=JSON.parse(v);u.type==="done"&&u.id?(t.messageId=u.id,t.truncated=u.truncated===!0):u.type==="aborted"?(t.aborted={id:typeof u.id=="string"?u.id:"",persisted:u.persisted===!0},a=!0):u.type==="error"?(t.errorCode=u.code||"INTERNAL_ERROR",t.errorMessage=u.message||"Generation failed",a=!0):u.type==="state"?(n.onState?.(u.delta,u.full??null),Array.isArray(u.createdNames)&&u.createdNames.length&&n.onCreatedCharacters?.(u.createdNames)):u.type==="thinking"?(u.status==="start"||u.status==="end")&&n.onThinking?.(u.status):u.content&&n.onChunk(u.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)};try{for(;;){let{done:p,value:h}=await e.read();if(p)break;c(),d+=r.decode(h,{stream:!0});let v=d.split(`
|
|
239
|
+
`);d=v.pop()??"";for(let u of v)l(u);if(a)return s&&clearTimeout(s),"done"}if(d+=r.decode(),d&&l(d),a)return s&&clearTimeout(s),"done"}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 m(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}}};I.REQUEST_TIMEOUT=6e4,I.MODEL_LOADING_TIMEOUT=18e4,I.STREAM_INACTIVITY_TIMEOUT=6e4,I.RECONNECT_MAX_ATTEMPTS=10,I.RECONNECT_BACKOFF_CAP=15e3;var X=I;function Qe(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let i=new Uint8Array(16);crypto.getRandomValues(i),i[6]=i[6]&15|64,i[8]=i[8]&63|128;let e=Array.from(i,t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}var _e=20,Oe=40,V=class{constructor(e,t,n,r,o=!1,s,c,d){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewHistory=[];this.previewConfig=s,this.getModelName=c,this.getPreset=d}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,preset:this.getPreset?.(),client_message_uuid:Qe()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new m("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,preset:this.getPreset?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted);return}return this.http.post("/retry",t,this.reqMeta())}async continue(e={}){if(this.isPreview)return;let t={conversation_id:this.getConversationId(),topic:e.topic??null,game_id:this.getGameId(),preset:this.getPreset?.(),extract:e.extract};await this.http.stream("/continue",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting,e.onAborted)}async cancel(e={}){if(this.isPreview)return{active:!1};let t=await this.http.post(`/conversations/${encodeURIComponent(this.getConversationId())}/cancel`,{topic:e.topic});return{active:t.active===!0,generationId:t.generation_id}}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,truncated:r.truncated===!0})),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 m("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 m("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 m("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 resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:G(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting,onAborted:e.onAborted})}async sendPreview(e){let t=e.message.trim().length>0,n=this.previewHistory.slice(t?-(_e-1):-_e);t&&this.pushPreviewHistory({role:"user",content:e.message});let r={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:n,preset:this.getPreset?.()};this.previewConfig?r.prompt_config=this.previewConfig:r.game_id=this.getGameId();let o=this.previewConfig;if(o?.reply_length&&(r.reply_length=o.reply_length),o?.reply_language&&(r.reply_language=o.reply_language),e.stream){let p="";await this.http.stream("/preview",r,h=>{p+=h,e.onChunk?.(h)},(h,v)=>{p&&this.pushPreviewHistory({role:"assistant",content:p}),e.onDone?.(h,v)},this.reqMeta(),G(e.onState),e.onThinking,e.onCreatedCharacters);return}let s="",c=null,d=null,a=[];await this.http.stream("/preview",r,p=>{s+=p},()=>{},this.reqMeta(),(p,h)=>{c=p,d=h,e.onState&&e.onState(c,d)},void 0,p=>{a=p,e.onCreatedCharacters&&e.onCreatedCharacters(p)}),s&&this.pushPreviewHistory({role:"assistant",content:s});let l={id:"",content:s,truncated:!1};return c&&(l.delta=c,d&&(l.full=d)),a.length&&(l.createdNames=a),l}pushPreviewHistory(e){this.previewHistory.push(e),this.previewHistory.length>Oe&&this.previewHistory.splice(0,this.previewHistory.length-Oe)}};function G(i){if(i)return(e,t)=>i(e,t)}var ge=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})}},H=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(Ae)),this.state=new ge(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(Ae):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Me):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Me(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 Ae(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 Me(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 B=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 De(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 ve(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]=De(s);e[t]=r}return e}function Ze(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=De(n);return e}var j=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ve(r))}setInitial(e){this.mem=e?ve(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 Ze(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ve(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 W=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 fe=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})}},q=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 fe(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 K(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var z=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=Ne(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Ne(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(K(`/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(K(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(K(`/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(K(`/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(K(`/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(K(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Ne(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 Ue(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var Y=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(Ue(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ue(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var ee=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new m("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 Q=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 $e="/functions/v1/world-engine/v1",Je="https://api.storvia.ai";function Xe(){return window.__STORVIA__||{}}function et(i,e=3e4){let t=Xe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new m("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(E("ready",{}))})}var te=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.presetId="";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 N({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}),Se(h=>this.bus.send(h));let n=await et(this.bus),r=n.apiBase;if(!r)throw new m("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${$e}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new m("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 m("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 X(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,v]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(b=>b.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.presetId=n.presetId||"";let u=()=>this.gameId,y=()=>this.conversationId,f=()=>this.modelId,R=()=>this.models.find(b=>b.id===this.modelId)?.name,T=()=>this.presetId||void 0;this.chat=new V(this.http,u,y,f,!0,this.previewConfig,R,T),this.characters=new H(this.http,y,!0,v?.characters,v?.characterStates),this.relationships=new B(this.http,y,!0,v?.relationships),this.inventory=new j(this.http,y,!0,v?.inventory),this.world=new W(this.http,y,!0,v?.world),this.player=new q(this.http,y,!0,v?.player,v?.playerState),this.custom=new z(this.http,y,u,!0,v?.custom,v?.custom_inject),this.save=new Y(this.http,y,u,!0,v?.save_data),this.state=new ee(this.http,y,!0),this.memory=new Q(this.http,y,!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||"",this.presetId=n.presetId||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name,p=()=>this.presetId||void 0;this.chat=new V(this.http,c,d,a,!1,void 0,l,p),this.characters=new H(this.http,d),this.relationships=new B(this.http,d),this.inventory=new j(this.http,d),this.world=new W(this.http,d),this.player=new q(this.http,d),this.custom=new z(this.http,d,c),this.save=new Y(this.http,d,c),this.state=new ee(this.http,d),this.memory=new Q(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)}),this.bus.on("set-preset",e=>{this.presetId=e.payload?.presetId||""})}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("set-preset",e=>{this.presetId=e.payload?.presetId||""}),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 m("UNAUTHORIZED","User not authenticated"):t.status===404?new m("GAME_NOT_FOUND","Game not found or not published"):new m("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=`${Je}${$e}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new X(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 V(this.http,o,s,c,!0,void 0,d),this.characters=new H(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new B(this.http,s,!0,n?.relationships),this.inventory=new j(this.http,s,!0,n?.inventory),this.world=new W(this.http,s,!0,n?.world),this.player=new q(this.http,s,!0,n?.player,n?.playerState),this.custom=new z(this.http,s,o,!0,n?.custom),this.save=new Y(this.http,s,o,!0,n?.save_data),this.memory=new Q(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 Le(i){let e=new te;return i?.dev?await e.initDev(i.dev):await e.init(),e}function ye(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function Fe(i){return ye(i)?i.value:i}return We(tt);})();
|
|
240
240
|
if(typeof window!=="undefined"){window.createStorviaSDK=StorviaSDK.createStorviaSDK;}
|
package/package.json
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"dist"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "tsup",
|
|
20
|
-
"dev": "tsup --watch",
|
|
21
|
-
"typecheck": "tsc --noEmit",
|
|
22
|
-
"prepublishOnly": "npm run build",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"test:memory": "vitest run test/memory",
|
|
26
|
-
"test:production": "vitest run test/production",
|
|
27
|
-
"test:preview-studio": "vitest run test/preview-studio",
|
|
28
|
-
"test:preview-dev": "vitest run test/preview-dev"
|
|
29
|
-
},
|
|
30
|
-
"keywords": [
|
|
31
|
-
"storvia",
|
|
32
|
-
"world",
|
|
33
|
-
"sdk",
|
|
34
|
-
"interactive",
|
|
35
|
-
"text-game"
|
|
36
|
-
],
|
|
37
|
-
"license": "UNLICENSED",
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@supabase/supabase-js": "^2.45.0",
|
|
40
|
-
"@vitest/coverage-v8": "^2.1.0",
|
|
41
|
-
"dotenv": "^16.4.5",
|
|
42
|
-
"jsdom": "^25.0.0",
|
|
43
|
-
"tsup": "^8.0.0",
|
|
44
|
-
"typescript": "^5.4.0",
|
|
45
|
-
"vitest": "^2.1.0"
|
|
2
|
+
"name": "@storvia/sdk",
|
|
3
|
+
"version": "0.9.2",
|
|
4
|
+
"description": "Storvia World SDK - Build interactive text games on the Storvia platform",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.mts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"import": "./dist/index.esm.js",
|
|
12
|
+
"require": "./dist/index.cjs.js"
|
|
46
13
|
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"test:memory": "vitest run test/memory",
|
|
26
|
+
"test:production": "vitest run test/production",
|
|
27
|
+
"test:preview-studio": "vitest run test/preview-studio",
|
|
28
|
+
"test:preview-dev": "vitest run test/preview-dev"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"storvia",
|
|
32
|
+
"world",
|
|
33
|
+
"sdk",
|
|
34
|
+
"interactive",
|
|
35
|
+
"text-game"
|
|
36
|
+
],
|
|
37
|
+
"license": "UNLICENSED",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@supabase/supabase-js": "^2.45.0",
|
|
40
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
41
|
+
"dotenv": "^16.4.5",
|
|
42
|
+
"jsdom": "^25.0.0",
|
|
43
|
+
"tsup": "^8.0.0",
|
|
44
|
+
"typescript": "^5.4.0",
|
|
45
|
+
"vitest": "^2.1.0"
|
|
46
|
+
}
|
|
47
47
|
}
|