@storvia/sdk 0.8.1 → 0.8.3
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 +9 -9
- package/dist/index.d.mts +22 -2
- package/dist/index.esm.js +9 -9
- package/dist/index.umd.js +9 -9
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
#${
|
|
1
|
+
"use strict";var re=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var Oe=Object.prototype.hasOwnProperty;var Me=(i,e)=>{for(var t in e)re(i,t,{get:e[t],enumerable:!0})},Ae=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of _e(e))!Oe.call(i,r)&&r!==t&&re(i,r,{get:()=>e[r],enumerable:!(n=xe(e,r))||n.enumerable});return i};var De=i=>Ae(re({},"__esModule",{value:!0}),i);var je={};Me(je,{PROTOCOL_VERSION:()=>A,StorviaBus:()=>O,StorviaError:()=>u,StorviaSDK:()=>Y,createStorviaSDK:()=>Pe,envelope:()=>R,extractFieldValue:()=>ke,isProtocolEnvelope:()=>W,isRichFieldValue:()=>le,setToastEnabled:()=>Ie,showToast:()=>se});module.exports=De(je);var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var A=1;function W(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function R(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var O=class{constructor(e){this.handlers=new Map;this.pendingAcks=new Map;this.listener=null;this.incoming=e.incoming,this.getOutgoing=e.outgoing,this.verifySource=e.verifySource??(()=>!0),this.validate=e.validate,this.debug=!!e.debug,this.getTransferables=e.transfer??(()=>{}),this.customSend=e.customSend,this.attach()}attach(){this.listener=e=>{if((this.incoming instanceof Window||this.incoming===window)&&!this.verifySource(e))return;let t=e.data;if(!W(t))return;if(t.protocol!==1){this.debug&&console.warn("[StorviaBus] protocol mismatch",{expected:1,got:t.protocol,type:t.type});return}if(this.validate&&!this.validate(t)){this.debug&&console.warn("[StorviaBus] validation failed",t);return}if(t.ackId){let r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(t);return}}let n=this.handlers.get(t.type);if(!n||n.size===0){this.debug&&console.debug("[StorviaBus] no handler for",t.type);return}n.forEach(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},this.incoming.addEventListener("message",this.listener),this.incoming instanceof MessagePort&&this.incoming.start()}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:R(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??Ne(),s=R(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 Ne(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var oe=null;function fe(i){oe=i}var ee="storvia-sdk-toast-style",te="storvia-sdk-toast-stack",ye=`
|
|
2
|
+
#${te} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
5
5
|
right: max(20px, env(safe-area-inset-right, 0px) + 20px);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
@media (max-width: 768px) {
|
|
15
|
-
#${
|
|
15
|
+
#${te} {
|
|
16
16
|
top: max(10px, env(safe-area-inset-top, 0px) + 10px);
|
|
17
17
|
left: 10px;
|
|
18
18
|
right: 10px;
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
.storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
|
|
220
220
|
.storvia-sheet-btn { height: 40px; font-size: 13px; }
|
|
221
221
|
}
|
|
222
|
-
`,
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,Ue={success:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',error:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',warning:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',info:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>'},ie={UNAUTHORIZED:"\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55",INSUFFICIENT_CREDITS:"\u82B1\u56ED\u5E01\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u518D\u7EE7\u7EED\u6E38\u620F",VIOLATION_WORD_DETECTED:"\u5185\u5BB9\u542B\u6709\u8FDD\u7981\u8BCD\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5",CONTENT_FILTERED:"\u5185\u5BB9\u88AB\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u8BF7\u8C03\u6574\u540E\u91CD\u8BD5",MODEL_REFUSAL:"\u6A21\u578B\u62D2\u7EDD\u54CD\u5E94\uFF0C\u6362\u4E2A\u8BF4\u6CD5\u8BD5\u8BD5",STREAM_INTERRUPTED:"\u56DE\u590D\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",RATE_LIMITED:"\u64CD\u4F5C\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",MODEL_NOT_FOUND:"\u6240\u9009\u6A21\u578B\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5207\u6362\u5176\u4ED6\u6A21\u578B",GAME_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u6E38\u620F",INVALID_REQUEST:"\u8BF7\u6C42\u65E0\u6548\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",INTERNAL_ERROR:"\u670D\u52A1\u51FA\u4E86\u70B9\u5C0F\u95EE\u9898\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",NOT_INITIALIZED:"SDK \u5C1A\u672A\u521D\u59CB\u5316",NOT_SUPPORTED_IN_PREVIEW:"\u5F53\u524D\u63A5\u53E3\u5728\u9884\u89C8\u6A21\u5F0F\u4E0B\u4E0D\u53EF\u7528",NETWORK_ERROR:"\u7F51\u7EDC\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5",REQUEST_TIMEOUT:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",MODEL_LOADING_TIMEOUT:"\u6A21\u578B\u54CD\u5E94\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",STREAM_INACTIVITY:"\u8FDE\u63A5\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},we=!0;function Ie(i){we=i}function $e(){if(typeof document>"u")return null;let i=document.getElementById(te);if(!i){if(!document.getElementById(ee)){let e=document.createElement("style");e.id=ee,e.textContent=ye,document.head.appendChild(e)}i=document.createElement("div"),i.id=te,document.body.appendChild(i)}return i}function se(i,e="info",t=3500,n){if(!we)return;let r=$e();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${Ue[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(
|
|
225
|
+
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(o){let a=document.createElement("button");a.type="button",a.className="storvia-toast-close",a.setAttribute("aria-label","\u5173\u95ED"),a.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',a.addEventListener("click",d),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function k(i,e){if(i==="INSUFFICIENT_CREDITS"){ve({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||ie.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){ve({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||ie.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=ie[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";se(t,i==="RATE_LIMITED"?"warning":"error")}var X=null;function ve(i){if(typeof document>"u"||X)return;if(!document.getElementById(ee)){let s=document.createElement("style");s.id=ee,s.textContent=ye,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=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(),
|
|
238
|
-
`);
|
|
239
|
-
`)){if(l.startsWith("id: ")){o=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var H=f;var A=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:W(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[]};this.previewConfig?t.prompt_config=this.previewConfig:t.game_id=this.getGameId();let n=this.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{o=a,s=h,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function W(i){if(i)return(e,t)=>i(e,t)}var de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}let n=t?{group:t}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,n)}async update(e,t,n){if(this.isPreview){let r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},M=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ye)),this.state=new de(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Ie):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Ie(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(r=>r.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};function ye(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function Ie(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}setInitial(e){this.mem=e?e.map(t=>({...t})):[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(r=>r.from===e&&r.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};function Ce(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ce(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=Ce(s);e[t]=r}return e}function $e(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Ce(n);return e}var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ce(r))}setInitial(e){this.mem=e?ce(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return $e(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ce(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let d={count:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=e;if(this.isPreview){let d=this.mem[t];if(!d||!(n in d))throw new Error(`Item "${t}/${n}" not found`);let a=d[n];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var U=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var le=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},$=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new le(e,t,n,o)}setInitial(e,t){this.memPersona=e?{...e}:{name:""},this.state.setInitial(t)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};function L(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=Re(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Re(e):{},this.memInject=t?{...t}:{}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{inject:t})}getInject(){return{...this.memInject}}async delete(e){if(this.isPreview){delete this.mem[e],delete this.memInject[e];return}await this.http.delete(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Re(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function Te(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var G=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var K=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var V=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=null}async get(){return this.isPreview?this.mem?{...this.mem}:null:(await this.http.get(`/conversations/${this.getConversationId()}/summary`)).ai_summary}async update(e){let t=(e??"").trim();if(this.isPreview){let r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ee="/functions/v1/world-engine/v1",Le="https://api.storvia.ai";function Fe(){return window.__STORVIA__||{}}function Ge(i,e=3e4){let t=Fe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let h=window;h.__STORVIA__=a,n(a)}i.send(C("ready",{}))})}var q=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=window.flutter_inappwebview,t=typeof e?.callHandler=="function";this.bus=new _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),ge(l=>this.bus.send(l));let n=await Ge(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ee}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new H(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,R=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new A(this.http,p,g,b,!0,this.previewConfig,R),this.characters=new M(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new D(this.http,g,!0,m?.relationships),this.inventory=new N(this.http,g,!0,m?.inventory),this.world=new U(this.http,g,!0,m?.world),this.player=new $(this.http,g,!0,m?.player,m?.playerState),this.custom=new F(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new G(this.http,g,p,!0,m?.save_data),this.state=new K(this.http,g,!0),this.memory=new V(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new A(this.http,c,d,a,!1,void 0,h),this.characters=new M(this.http,d),this.relationships=new D(this.http,d),this.inventory=new N(this.http,d),this.world=new U(this.http,d),this.player=new $(this.http,d),this.custom=new F(this.http,d,c),this.save=new G(this.http,d,c),this.state=new K(this.http,d),this.memory=new V(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("config-update",e=>{this.previewConfig=e.payload.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig),this.refreshPreviewSnapshot().catch(t=>{console.warn("[Storvia SDK] refreshPreviewSnapshot failed:",t)})})}async fetchPreviewSnapshot(){try{let e={game_id:this.gameId};return this.previewConfig&&("game_config"in this.previewConfig&&(e.game_config=this.previewConfig.game_config),"game_state"in this.previewConfig&&(e.game_state_override=this.previewConfig.game_state)),await this.http.post("/preview/initial-snapshot",e)}catch(e){return console.warn("[Storvia SDK] fetchPreviewSnapshot failed:",e),null}}async refreshPreviewSnapshot(){let e=await this.fetchPreviewSnapshot();e&&(this.characters?.setInitial(e.characters,e.characterStates),this.player?.setInitial(e.player,e.playerState),this.inventory?.setInitial(e.inventory),this.relationships?.setInitial(e.relationships),this.world?.setInitial(e.world),this.custom?.setInitial(e.custom,e.custom_inject),this.save?.setInitial(e.save_data))}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Le}${Ee}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new H(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new A(this.http,o,s,c,!0,void 0,d),this.characters=new M(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new D(this.http,s,!0,n?.relationships),this.inventory=new N(this.http,s,!0,n?.inventory),this.world=new U(this.http,s,!0,n?.world),this.player=new $(this.http,s,!0,n?.player,n?.playerState),this.custom=new F(this.http,s,o,!0,n?.custom),this.save=new G(this.http,s,o,!0,n?.save_data),this.memory=new V(this.http,s,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Se(i){let e=new q;return i?.dev?await e.initDev(i.dev):await e.init(),e}function he(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function be(i){return he(i)?i.value:i}0&&(module.exports={PROTOCOL_VERSION,StorviaBus,StorviaError,StorviaSDK,createStorviaSDK,envelope,extractFieldValue,isProtocolEnvelope,isRichFieldValue,setToastEnabled,showToast});
|
|
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(),X===e&&(X=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(oe)try{oe(R("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),X=e,requestAnimationFrame(()=>e.classList.add("show"))}var I=class I{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof u||k("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return k("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",g=a!==void 0?` (${a}ms)`:"",m=o!==void 0?` [${o}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${p} %c${t} ${n}${m}${w}${g} %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}${m}${w}${g} %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){let p=Date.now(),h=o?.modelName?` [model: ${o.modelName}]`:"",g=[],m=f=>{this.debug&&g.push({t:Date.now()-p,event:f})},w=new AbortController,T=null,S=null,E=null,C=null,x=()=>{T!==null&&(clearTimeout(T),T=null),S!==null&&(clearTimeout(S),S=null),E!==null&&(clearTimeout(E),E=null)},Q=f=>{C=f,x(),w.abort()};T=setTimeout(()=>Q("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let b;try{b=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:w.signal})}catch(f){if(x(),C){let y=new u(C,"Request timed out");throw k(C),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-p,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(f),f}if(T!==null&&(clearTimeout(T),T=null),!b.ok){x();let f=await b.text().catch(()=>""),y={};try{y=JSON.parse(f)}catch{}let P=y.code||"INTERNAL_ERROR",v=new u(P,y.message||`HTTP ${b.status}`);throw k(P,y.message),this.log({method:"STREAM",path:e,body:t,status:b.status,rawResponse:f,error:v,durationMs:Date.now()-p,modelName:o?.modelName}),v}let he=b.body?.getReader();if(!he)throw x(),new u("INTERNAL_ERROR","No response body for stream");S=setTimeout(()=>Q("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let ue=new TextDecoder,H="",_="",pe=!1,ne,Z,M="",J=!1,me=f=>{if(J)return;let y=f.endsWith("\r")?f.slice(0,-1):f;if(y.startsWith("id: ")){Z=y.slice(4);return}if(!y.startsWith("data: "))return;let P=y.slice(6);if(P==="[DONE]"){m("[DONE]"),J=!0;return}try{let v=JSON.parse(P);m(v),v.type==="done"&&v.id?H=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(pe?(E!==null&&clearTimeout(E),E=setTimeout(()=>Q("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(pe=!0,S!==null&&(clearTimeout(S),S=null),E=setTimeout(()=>Q("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),_+=v.content,n(v.content))}catch{m({raw:P})}Z!==void 0&&(ne=Z,Z=void 0)},ge=()=>{x(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log("Message ID:",H),console.log(`SSE events (${g.length}):`,g),console.groupEnd()),r(H)};try{for(;;){let{done:f,value:y}=await he.read();if(f)break;M+=ue.decode(y,{stream:!0});let P=M.split(`
|
|
238
|
+
`);M=P.pop()??"";for(let v of P)me(v);if(J){ge();return}}if(M+=ue.decode(),M&&me(M),J){ge();return}}catch(f){if(x(),C){let y=new u(C,C==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw k(C),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2717 ${C}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Stream error:",f),console.groupEnd()),a){await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0});return}throw f}if(x(),H){r(H);return}a&&await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0})}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"){n.onDone(a.messageId);return}if(l==="inactive"){(a.messageId||r?.finalize)&&n.onDone(a.messageId);return}}let s=new u("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw k("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let r={messageId:""},o;try{o=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(o==="done"){n.onDone(r.messageId);return}if(o==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,o){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),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 u("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 g=h.slice(6);if(g==="[DONE]"){a=!0;return}try{let m=JSON.parse(g);m.type==="done"&&m.id?t.messageId=m.id:m.type==="state"?(n.onState?.(m.delta,m.full??null),Array.isArray(m.createdNames)&&m.createdNames.length&&n.onCreatedCharacters?.(m.createdNames)):m.type==="thinking"?(m.status==="start"||m.status==="end")&&n.onThinking?.(m.status):m.content&&n.onChunk(m.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 g=d.split(`
|
|
239
|
+
`);d=g.pop()??"";for(let m of g)l(m);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 u(s,r.message||`HTTP ${e.status}`);throw k(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};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 K=I;var D=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.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?.()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:q(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],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(),q(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,l)=>{o=a,s=l,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function q(i){if(i)return(e,t)=>i(e,t)}var ae=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})}},N=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(Ce)),this.state=new ae(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(Ce):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Re):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Re(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 Ce(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 Re(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 U=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 Te(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 de(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]=Te(s);e[t]=r}return e}function Le(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Te(n);return e}var $=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=de(r))}setInitial(e){this.mem=e?de(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 Le(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return de(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 L=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 ce=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})}},F=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 ce(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 G(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var V=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=Se(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Se(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(G(`/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(G(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(G(`/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(G(`/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(G(`/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(G(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Se(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 Ee(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var j=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(Ee(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ee(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var z=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var B=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 be="/functions/v1/world-engine/v1",Fe="https://api.storvia.ai";function Ge(){return window.__STORVIA__||{}}function Ve(i,e=3e4){let t=Ge();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,storyMode:a.payload.storyMode,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(R("ready",{}))})}var Y=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 O({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}),fe(h=>this.bus.send(h));let n=await Ve(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${be}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new K(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,g]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(C=>C.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.storyMode=n.storyMode===!0;let m=()=>this.gameId,w=()=>this.conversationId,T=()=>this.modelId,S=()=>this.models.find(C=>C.id===this.modelId)?.name,E=()=>this.storyMode;this.chat=new D(this.http,m,w,T,!0,this.previewConfig,S,E),this.characters=new N(this.http,w,!0,g?.characters,g?.characterStates),this.relationships=new U(this.http,w,!0,g?.relationships),this.inventory=new $(this.http,w,!0,g?.inventory),this.world=new L(this.http,w,!0,g?.world),this.player=new F(this.http,w,!0,g?.player,g?.playerState),this.custom=new V(this.http,w,m,!0,g?.custom,g?.custom_inject),this.save=new j(this.http,w,m,!0,g?.save_data),this.state=new z(this.http,w,!0),this.memory=new B(this.http,w,!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.storyMode=n.storyMode===!0;let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name,p=()=>this.storyMode;this.chat=new D(this.http,c,d,a,!1,void 0,l,p),this.characters=new N(this.http,d),this.relationships=new U(this.http,d),this.inventory=new $(this.http,d),this.world=new L(this.http,d),this.player=new F(this.http,d),this.custom=new V(this.http,d,c),this.save=new j(this.http,d,c),this.state=new z(this.http,d),this.memory=new B(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 u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Fe}${be}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new K(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 D(this.http,o,s,c,!0,void 0,d),this.characters=new N(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new U(this.http,s,!0,n?.relationships),this.inventory=new $(this.http,s,!0,n?.inventory),this.world=new L(this.http,s,!0,n?.world),this.player=new F(this.http,s,!0,n?.player,n?.playerState),this.custom=new V(this.http,s,o,!0,n?.custom),this.save=new j(this.http,s,o,!0,n?.save_data),this.memory=new B(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 Pe(i){let e=new Y;return i?.dev?await e.initDev(i.dev):await e.init(),e}function le(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function ke(i){return le(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
|
@@ -54,6 +54,11 @@ declare class HttpClient {
|
|
|
54
54
|
/**
|
|
55
55
|
* 重连循环:退避 → GET 续读 → 直到拿到终止事件 / 服务端报无在途 / 次数耗尽。
|
|
56
56
|
* 每次重连前回调 onReconnect 供 UI 提示「正在重新连接 n/10」。
|
|
57
|
+
*
|
|
58
|
+
* opts.finalize:发起方链路(send/generate/retry 的断线续读)传 true —— 即使
|
|
59
|
+
* done 事件彻底丢失(messageId 为空)也必须触发 onDone 给调用方一个确定结局,
|
|
60
|
+
* 否则上层等回调等不到(「send 未返回」)。resume() 接管链路保持旧语义
|
|
61
|
+
* (无在途生成时静默返回)。
|
|
57
62
|
*/
|
|
58
63
|
private resumeLoop;
|
|
59
64
|
/**
|
|
@@ -453,7 +458,8 @@ declare class ChatModule {
|
|
|
453
458
|
private isPreview;
|
|
454
459
|
private previewConfig?;
|
|
455
460
|
private getModelName?;
|
|
456
|
-
|
|
461
|
+
private getStoryMode?;
|
|
462
|
+
constructor(http: HttpClient, getGameId: () => string, getConversationId: () => string, getModelId: () => string, isPreview?: boolean, previewConfig?: Record<string, unknown>, getModelName?: () => string | undefined, getStoryMode?: () => boolean);
|
|
457
463
|
/** 构造 http 层的元信息(用于 debug 日志标题显示) */
|
|
458
464
|
private reqMeta;
|
|
459
465
|
/** 更新预览配置(由父页面 postMessage 触发) */
|
|
@@ -760,6 +766,8 @@ declare class StorviaSDK {
|
|
|
760
766
|
private conversationId;
|
|
761
767
|
private modelId;
|
|
762
768
|
private models;
|
|
769
|
+
/** 剧情模式开关;由宿主经 init / 'set-story-mode' 下发,每次生成请求自动带上 */
|
|
770
|
+
private storyMode;
|
|
763
771
|
private accessToken;
|
|
764
772
|
private initialized;
|
|
765
773
|
private isPreview;
|
|
@@ -854,6 +862,13 @@ interface InitPayload {
|
|
|
854
862
|
* 在 SDK 注册监听前到达而丢失的竞态。运行时切换仍走 envelope 'set-model'。
|
|
855
863
|
*/
|
|
856
864
|
selectedModelId?: string;
|
|
865
|
+
/**
|
|
866
|
+
* 宿主(主站/App)当前的「剧情模式」开关状态。跟 selectedModelId 完全同一套机制:
|
|
867
|
+
* 随 init 一起下发初始值,避免竞态;运行时切换走 envelope 'set-story-mode'。
|
|
868
|
+
* SDK 把它存成内部状态,每次生成请求自动带上 story_mode,游戏作者零适配。
|
|
869
|
+
* 纯文风选择,不是信任边界——服务端仍用 isUnrestricted 兜底内容分级。
|
|
870
|
+
*/
|
|
871
|
+
storyMode?: boolean;
|
|
857
872
|
debug?: boolean;
|
|
858
873
|
}
|
|
859
874
|
interface PreviewConfig {
|
|
@@ -877,6 +892,8 @@ interface PreviewInitPayload {
|
|
|
877
892
|
provider?: string;
|
|
878
893
|
}>;
|
|
879
894
|
selectedModelId?: string;
|
|
895
|
+
/** 预览模式下宿主(创作台)当前的剧情模式开关初始值;运行时切换走 'set-story-mode' */
|
|
896
|
+
storyMode?: boolean;
|
|
880
897
|
debug?: boolean;
|
|
881
898
|
}
|
|
882
899
|
interface TokenUpdatePayload {
|
|
@@ -888,6 +905,9 @@ interface ConfigUpdatePayload {
|
|
|
888
905
|
interface SetModelPayload {
|
|
889
906
|
modelId: string;
|
|
890
907
|
}
|
|
908
|
+
interface SetStoryModePayload {
|
|
909
|
+
storyMode: boolean;
|
|
910
|
+
}
|
|
891
911
|
interface OrientationPayload {
|
|
892
912
|
mode: 'landscape' | 'portrait';
|
|
893
913
|
}
|
|
@@ -911,7 +931,7 @@ interface AckPayload {
|
|
|
911
931
|
ok: boolean;
|
|
912
932
|
error?: string;
|
|
913
933
|
}
|
|
914
|
-
type DownstreamMsg = ProtocolEnvelope<'init', InitPayload> | ProtocolEnvelope<'preview-init', PreviewInitPayload> | ProtocolEnvelope<'token-update', TokenUpdatePayload> | ProtocolEnvelope<'config-update', ConfigUpdatePayload> | ProtocolEnvelope<'set-model', SetModelPayload> | ProtocolEnvelope<'orientation', OrientationPayload> | ProtocolEnvelope<'ack', AckPayload>;
|
|
934
|
+
type DownstreamMsg = ProtocolEnvelope<'init', InitPayload> | ProtocolEnvelope<'preview-init', PreviewInitPayload> | ProtocolEnvelope<'token-update', TokenUpdatePayload> | ProtocolEnvelope<'config-update', ConfigUpdatePayload> | ProtocolEnvelope<'set-model', SetModelPayload> | ProtocolEnvelope<'set-story-mode', SetStoryModePayload> | ProtocolEnvelope<'orientation', OrientationPayload> | ProtocolEnvelope<'ack', AckPayload>;
|
|
915
935
|
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>;
|
|
916
936
|
declare function isProtocolEnvelope(data: unknown): data is ProtocolEnvelope<string, unknown>;
|
|
917
937
|
declare function envelope<T extends string, P>(type: T, payload: P, opts?: {
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var
|
|
2
|
-
#${
|
|
1
|
+
var m=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var H=1;function Z(o){if(!o||typeof o!="object")return!1;let e=o;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function P(o,e,t){return{protocol:1,type:o,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var M=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(!Z(t))return;if(t.protocol!==1){this.debug&&console.warn("[StorviaBus] protocol mismatch",{expected:1,got:t.protocol,type:t.type});return}if(this.validate&&!this.validate(t)){this.debug&&console.warn("[StorviaBus] validation failed",t);return}if(t.ackId){let r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(t);return}}let n=this.handlers.get(t.type);if(!n||n.size===0){this.debug&&console.debug("[StorviaBus] no handler for",t.type);return}n.forEach(r=>{try{r(t)}catch(i){console.error(`[StorviaBus] handler '${t.type}' threw:`,i)}})},this.incoming.addEventListener("message",this.listener),this.incoming instanceof MessagePort&&this.incoming.start()}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:P(e.type,e.payload,{id:e.id,ackId:e.ackId});if(this.customSend){try{this.customSend(t)}catch(i){console.error("[StorviaBus] customSend failed:",i,{type:e.type})}return}let n=this.getOutgoing();if(!n){this.debug&&console.warn("[StorviaBus] outgoing target unavailable, drop:",e.type);return}let r=this.getTransferables(t);try{n instanceof MessagePort?n.postMessage(t,r??[]):n.postMessage(t,"*",r??[])}catch(i){console.error("[StorviaBus] postMessage failed:",i,{type:e.type})}}request(e,t=1e4){return new Promise((n,r)=>{let i=e.id??Ee(),s=P(e.type,e.payload,{id:i}),c=setTimeout(()=>{this.pendingAcks.delete(i),r(new Error(`[StorviaBus] request '${e.type}' timed out after ${t}ms`))},t);this.pendingAcks.set(i,d=>{clearTimeout(c),n(d)}),this.send(s)})}destroy(){if(this.listener&&(this.incoming.removeEventListener("message",this.listener),this.listener=null),this.incoming instanceof MessagePort)try{this.incoming.close()}catch{}this.handlers.clear(),this.pendingAcks.clear()}};function Ee(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var ie=null;function me(o){ie=o}var X="storvia-sdk-toast-style",ee="storvia-sdk-toast-stack",ge=`
|
|
2
|
+
#${ee} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
5
5
|
right: max(20px, env(safe-area-inset-right, 0px) + 20px);
|
|
@@ -12,7 +12,7 @@ var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",thi
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
@media (max-width: 768px) {
|
|
15
|
-
#${
|
|
15
|
+
#${ee} {
|
|
16
16
|
top: max(10px, env(safe-area-inset-top, 0px) + 10px);
|
|
17
17
|
left: 10px;
|
|
18
18
|
right: 10px;
|
|
@@ -219,10 +219,10 @@ var u=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
|
+
`,be={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>'},re={UNAUTHORIZED:"\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55",INSUFFICIENT_CREDITS:"\u82B1\u56ED\u5E01\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u518D\u7EE7\u7EED\u6E38\u620F",VIOLATION_WORD_DETECTED:"\u5185\u5BB9\u542B\u6709\u8FDD\u7981\u8BCD\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5",CONTENT_FILTERED:"\u5185\u5BB9\u88AB\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u8BF7\u8C03\u6574\u540E\u91CD\u8BD5",MODEL_REFUSAL:"\u6A21\u578B\u62D2\u7EDD\u54CD\u5E94\uFF0C\u6362\u4E2A\u8BF4\u6CD5\u8BD5\u8BD5",STREAM_INTERRUPTED:"\u56DE\u590D\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",RATE_LIMITED:"\u64CD\u4F5C\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",MODEL_NOT_FOUND:"\u6240\u9009\u6A21\u578B\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5207\u6362\u5176\u4ED6\u6A21\u578B",GAME_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u6E38\u620F",INVALID_REQUEST:"\u8BF7\u6C42\u65E0\u6548\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",INTERNAL_ERROR:"\u670D\u52A1\u51FA\u4E86\u70B9\u5C0F\u95EE\u9898\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",NOT_INITIALIZED:"SDK \u5C1A\u672A\u521D\u59CB\u5316",NOT_SUPPORTED_IN_PREVIEW:"\u5F53\u524D\u63A5\u53E3\u5728\u9884\u89C8\u6A21\u5F0F\u4E0B\u4E0D\u53EF\u7528",NETWORK_ERROR:"\u7F51\u7EDC\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5",REQUEST_TIMEOUT:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",MODEL_LOADING_TIMEOUT:"\u6A21\u578B\u54CD\u5E94\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",STREAM_INACTIVITY:"\u8FDE\u63A5\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},ve=!0;function Pe(o){ve=o}function ke(){if(typeof document>"u")return null;let o=document.getElementById(ee);if(!o){if(!document.getElementById(X)){let e=document.createElement("style");e.id=X,e.textContent=ge,document.head.appendChild(e)}o=document.createElement("div"),o.id=ee,document.body.appendChild(o)}return o}function fe(o,e="info",t=3500,n){if(!ve)return;let r=ke();if(!r)return;let i=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${be[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=o);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(
|
|
225
|
+
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=o);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(i){let a=document.createElement("button");a.type="button",a.className="storvia-toast-close",a.setAttribute("aria-label","\u5173\u95ED"),a.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',a.addEventListener("click",d),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),i||setTimeout(d,t)}function k(o,e){if(o==="INSUFFICIENT_CREDITS"){pe({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||re.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(o==="DAISY_CARD_REQUIRED"){pe({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||re.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=re[o]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";fe(t,o==="RATE_LIMITED"?"warning":"error")}var J=null;function pe(o){if(typeof document>"u"||J)return;if(!document.getElementById(X)){let s=document.createElement("style");s.id=X,s.textContent=ge,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 u=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=o.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=o.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=o.primaryLabel);let i=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),
|
|
238
|
-
`);
|
|
239
|
-
`)){if(l.startsWith("id: ")){i=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}i!==void 0&&(t.lastId=i,i=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},i={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||i[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var B=f;var O=class{constructor(e,t,n,r,i=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=i;this.previewConfig=s,this.getModelName=c}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),H(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:H(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[]};this.previewConfig?t.prompt_config=this.previewConfig:t.game_id=this.getGameId();let n=this.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),H(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",i=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{i=a,s=h,e.onState&&e.onState(i,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function H(o){if(o)return(e,t)=>o(e,t)}var se=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}let n=t?{group:t}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,n)}async update(e,t,n){if(this.isPreview){let r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},A=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ve)),this.state=new se(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(ve):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(fe):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?fe(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(r=>r.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};function ve(o){return{name:o.name,description:o.description,avatar:o.avatar,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.gender?{gender:o.gender}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}function fe(o){return{name:o.name,avatar:o.avatar,description:o.description,...o.introduction!==void 0?{introduction:o.introduction}:{},...o.visibleAtStart!==void 0?{visibleAtStart:o.visibleAtStart}:{},...o.userDescription!==void 0?{userDescription:o.userDescription}:{},...o.gender?{gender:o.gender}:{},...o.isPreset!==void 0?{isPreset:o.isPreset}:{}}}var M=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(i=>({...i})))}setInitial(e){this.mem=e?e.map(t=>({...t})):[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(r=>r.from===e&&r.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let r=this.mem.find(i=>i.from===e&&i.to===t);r?Object.assign(r,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};function we(o){let e={count:o.count};return o.desc!==void 0&&(e.desc=o.desc),o.icon_url!==void 0&&(e.iconUrl=o.icon_url),e}function ae(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o)){let r={};for(let[i,s]of Object.entries(n))r[i]=we(s);e[t]=r}return e}function ke(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=we(n);return e}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ae(r))}setInitial(e){this.mem=e?ae(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,i]of Object.entries(this.mem))n[r]={...i};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return ke(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ae(t)}async add(e){let{group:t,name:n,count:r=1,desc:i,iconUrl:s}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let d={count:r};i!==void 0&&(d.desc=i),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};i!==void 0&&(c.desc=i),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:i,iconUrl:s}=e;if(this.isPreview){let d=this.mem[t];if(!d||!(n in d))throw new Error(`Item "${t}/${n}" not found`);let a=d[n];r!==void 0&&(a.count=r),i!==void 0&&(a.desc=i),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),i!==void 0&&(c.desc=i),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:r,newName:i}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=i||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:i})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let i=this.mem[e];if(i&&Object.keys(i).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},U=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new de(e,t,n,i)}setInitial(e,t){this.memPersona=e?{...e}:{name:""},this.state.setInitial(t)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};function $(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var L=class{constructor(e,t,n,r=!1,i,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};i&&(this.mem=ye(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?ye(e):{},this.memInject=t?{...t}:{}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get($(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,i]of Object.entries(e))typeof i=="object"&&i!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...i}:this.mem[r]=i,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch($(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch($(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{inject:t})}getInject(){return{...this.memInject}}async delete(e){if(this.isPreview){delete this.mem[e],delete this.memInject[e];return}await this.http.delete($(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch($(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete($(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function ye(o){let e={};for(let[t,n]of Object.entries(o))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function Ie(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,i){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};i&&(this.mem={...i})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Ie(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ie(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var W=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var G=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=null}async get(){return this.isPreview?this.mem?{...this.mem}:null:(await this.http.get(`/conversations/${this.getConversationId()}/summary`)).ai_summary}async update(e){let t=(e??"").trim();if(this.isPreview){let r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ce="/functions/v1/world-engine/v1",xe="https://api.storvia.ai";function _e(){return window.__STORVIA__||{}}function Oe(o,e=3e4){let t=_e();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let i=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=o.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=o.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(i),s(),c();let h=window;h.__STORVIA__=a,n(a)}o.send(E("ready",{}))})}var ee=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=window.flutter_inappwebview,t=typeof e?.callHandler=="function";this.bus=new _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),pe(l=>this.bus.send(l));let n=await Oe(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ce}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new B(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,C=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new O(this.http,p,g,b,!0,this.previewConfig,C),this.characters=new A(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new M(this.http,g,!0,m?.relationships),this.inventory=new D(this.http,g,!0,m?.inventory),this.world=new N(this.http,g,!0,m?.world),this.player=new U(this.http,g,!0,m?.player,m?.playerState),this.custom=new L(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new F(this.http,g,p,!0,m?.save_data),this.state=new W(this.http,g,!0),this.memory=new G(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[i,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=i.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new O(this.http,c,d,a,!1,void 0,h),this.characters=new A(this.http,d),this.relationships=new M(this.http,d),this.inventory=new D(this.http,d),this.world=new N(this.http,d),this.player=new U(this.http,d),this.custom=new L(this.http,d,c),this.save=new F(this.http,d,c),this.state=new W(this.http,d),this.memory=new G(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("config-update",e=>{this.previewConfig=e.payload.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig),this.refreshPreviewSnapshot().catch(t=>{console.warn("[Storvia SDK] refreshPreviewSnapshot failed:",t)})})}async fetchPreviewSnapshot(){try{let e={game_id:this.gameId};return this.previewConfig&&("game_config"in this.previewConfig&&(e.game_config=this.previewConfig.game_config),"game_state"in this.previewConfig&&(e.game_state_override=this.previewConfig.game_state)),await this.http.post("/preview/initial-snapshot",e)}catch(e){return console.warn("[Storvia SDK] fetchPreviewSnapshot failed:",e),null}}async refreshPreviewSnapshot(){let e=await this.fetchPreviewSnapshot();e&&(this.characters?.setInitial(e.characters,e.characterStates),this.player?.setInitial(e.player,e.playerState),this.inventory?.setInitial(e.inventory),this.relationships?.setInitial(e.relationships),this.world?.setInitial(e.world),this.custom?.setInitial(e.custom,e.custom_inject),this.save?.setInitial(e.save_data))}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${xe}${Ce}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new B(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let i=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new O(this.http,i,s,c,!0,void 0,d),this.characters=new A(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new M(this.http,s,!0,n?.relationships),this.inventory=new D(this.http,s,!0,n?.inventory),this.world=new N(this.http,s,!0,n?.world),this.player=new U(this.http,s,!0,n?.player,n?.playerState),this.custom=new L(this.http,s,i,!0,n?.custom),this.save=new F(this.http,s,i,!0,n?.save_data),this.memory=new G(this.http,s,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(i=>({id:i.id,name:i.name,url:i.url,assetType:i.asset_type,category:i.category}))}};async function Ae(o){let e=new ee;return o?.dev?await e.initDev(o.dev):await e.init(),e}function Re(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function Me(o){return Re(o)?o.value:o}export{j as PROTOCOL_VERSION,_ as StorviaBus,u as StorviaError,ee as StorviaSDK,Ae as createStorviaSDK,E as envelope,Me as extractFieldValue,Q as isProtocolEnvelope,Re as isRichFieldValue,be as setToastEnabled,ge as showToast};
|
|
237
|
+
`;let t=e.querySelector(".storvia-sheet-title");t&&(t.textContent=o.title);let n=e.querySelector(".storvia-sheet-msg");n&&(n.textContent=o.msg);let r=e.querySelector('[data-role="navigate"]');r&&(r.textContent=o.primaryLabel);let i=()=>{e.isConnected&&(e.classList.add("leaving"),e.classList.remove("show"),setTimeout(()=>{e.remove(),J===e&&(J=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",i),e.addEventListener("click",s=>{s.target===e&&i()}),r?.addEventListener("click",()=>{if(ie)try{ie(P("navigate",{target:"wallet"})),console.log("[Storvia] navigate \u2192 wallet\uFF1A\u5DF2\u901A\u8FC7 bus \u901A\u77E5\u5BBF\u4E3B\u8DF3\u8F6C\u94B1\u5305\u9875")}catch(s){console.error("[Storvia] navigate \u2192 wallet \u901A\u8FC7 bus \u53D1\u9001\u5931\u8D25:",s)}else console.warn("[Storvia] navigate \u2192 wallet\uFF1A\u5F53\u524D\u672A\u68C0\u6D4B\u5230\u5BBF\u4E3B\uFF08dev \u6A21\u5F0F\uFF09\uFF0C\u6309\u94AE\u5DF2\u70B9\u4F46\u65E0\u4EBA\u63A5\u6536\u3002\u751F\u4EA7\u73AF\u5883\u4F1A\u81EA\u52A8\u8DF3\u5230\u4E3B\u7AD9 /wallet \u6216 App \u94B1\u5305\u9875\u3002");i()}),document.body.appendChild(e),J=e,requestAnimationFrame(()=>e.classList.add("show"))}var I=class I{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof m||k("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new m("REQUEST_TIMEOUT","Request timed out");return k("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:i,rawResponse:s,parsedData:c,error:d,durationMs:a,modelName:l}=e,u="%c[Storvia SDK]",h="color: #6366f1; font-weight: bold",g=a!==void 0?` (${a}ms)`:"",p=i!==void 0?` [${i}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${u} %c${t} ${n}${p}${w}${g} %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(`${u} %c${t} ${n}${p}${w}${g} %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(),i,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(n.toString(),{method:"GET",headers:this.buildHeaders(),signal:c.signal});d(),i=a.status;let{raw:l,data:u}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"GET",path:e,body:t,status:i,rawResponse:s,parsedData:u,durationMs:Date.now()-r}),u}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"GET",path:e,body:t,status:i,rawResponse:s,error:l,durationMs:Date.now()-r}),l===a&&this.maybeShowNetworkToast(a),l}}async post(e,t,n){let r=Date.now(),i,s,{controller:c,clear:d}=this.createTimeoutController();try{let a=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:c.signal});d(),i=a.status;let{raw:l,data:u}=await this.handleResponseWithRaw(a);return s=l,this.log({method:"POST",path:e,body:t,status:i,rawResponse:s,parsedData:u,durationMs:Date.now()-r,modelName:n?.modelName}),u}catch(a){d();let l=this.wrapAbortError(a);throw this.log({method:"POST",path:e,body:t,status:i,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,i,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PATCH",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return i=a,this.log({method:"PATCH",path:e,body:t,status:r,rawResponse:i,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:i,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async put(e,t){let n=Date.now(),r,i,{controller:s,clear:c}=this.createTimeoutController();try{let d=await fetch(`${this.baseUrl}${e}`,{method:"PUT",headers:this.buildHeaders(),body:t?JSON.stringify(t):void 0,signal:s.signal});c(),r=d.status;let{raw:a,data:l}=await this.handleResponseWithRaw(d);return i=a,this.log({method:"PUT",path:e,body:t,status:r,rawResponse:i,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:i,error:a,durationMs:Date.now()-n}),a===d&&this.maybeShowNetworkToast(d),a}}async delete(e){let t=Date.now(),n,r,{controller:i,clear:s}=this.createTimeoutController();try{let c=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.buildHeaders(),signal:i.signal});s(),n=c.status;let{raw:d,data:a}=await this.handleResponseWithRaw(c);return r=d,this.log({method:"DELETE",path:e,status:n,rawResponse:r,parsedData:a,durationMs:Date.now()-t}),a}catch(c){s();let d=this.wrapAbortError(c);throw this.log({method:"DELETE",path:e,status:n,rawResponse:r,error:d,durationMs:Date.now()-t}),d===c&&this.maybeShowNetworkToast(c),d}}async stream(e,t,n,r,i,s,c,d,a,l){let u=Date.now(),h=i?.modelName?` [model: ${i.modelName}]`:"",g=[],p=f=>{this.debug&&g.push({t:Date.now()-u,event:f})},w=new AbortController,R=null,T=null,S=null,C=null,x=()=>{R!==null&&(clearTimeout(R),R=null),T!==null&&(clearTimeout(T),T=null),S!==null&&(clearTimeout(S),S=null)},z=f=>{C=f,x(),w.abort()};R=setTimeout(()=>z("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let E;try{E=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:w.signal})}catch(f){if(x(),C){let y=new m(C,"Request timed out");throw k(C),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-u,modelName:i?.modelName}),y}throw this.maybeShowNetworkToast(f),f}if(R!==null&&(clearTimeout(R),R=null),!E.ok){x();let f=await E.text().catch(()=>""),y={};try{y=JSON.parse(f)}catch{}let b=y.code||"INTERNAL_ERROR",v=new m(b,y.message||`HTTP ${E.status}`);throw k(b,y.message),this.log({method:"STREAM",path:e,body:t,status:E.status,rawResponse:f,error:v,durationMs:Date.now()-u,modelName:i?.modelName}),v}let de=E.body?.getReader();if(!de)throw x(),new m("INTERNAL_ERROR","No response body for stream");T=setTimeout(()=>z("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let ce=new TextDecoder,B="",_="",le=!1,ne,Y,O="",Q=!1,he=f=>{if(Q)return;let y=f.endsWith("\r")?f.slice(0,-1):f;if(y.startsWith("id: ")){Y=y.slice(4);return}if(!y.startsWith("data: "))return;let b=y.slice(6);if(b==="[DONE]"){p("[DONE]"),Q=!0;return}try{let v=JSON.parse(b);p(v),v.type==="done"&&v.id?B=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(le?(S!==null&&clearTimeout(S),S=setTimeout(()=>z("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(le=!0,T!==null&&(clearTimeout(T),T=null),S=setTimeout(()=>z("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),_+=v.content,n(v.content))}catch{p({raw:b})}Y!==void 0&&(ne=Y,Y=void 0)},ue=()=>{x(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${h} (${Date.now()-u}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log("Message ID:",B),console.log(`SSE events (${g.length}):`,g),console.groupEnd()),r(B)};try{for(;;){let{done:f,value:y}=await de.read();if(f)break;O+=ce.decode(y,{stream:!0});let b=O.split(`
|
|
238
|
+
`);O=b.pop()??"";for(let v of b)he(v);if(Q){ue();return}}if(O+=ce.decode(),O&&he(O),Q){ue();return}}catch(f){if(x(),C){let y=new m(C,C==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw k(C),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${h} (${Date.now()-u}ms) %c\u2717 ${C}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${E.status}]${h} (${Date.now()-u}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Stream error:",f),console.groupEnd()),a){await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0});return}throw f}if(x(),B){r(B);return}a&&await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0})}async resumeLoop(e,t,n,r){let i=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(u=>setTimeout(u,d)),n.onReconnect?.({attempt:c});let a={messageId:"",lastId:i},l;try{l=await this.pumpGetStream(e.conversationId,e.topic,i,a,n)}catch{continue}if(i=a.lastId??i,l==="done"){n.onDone(a.messageId);return}if(l==="inactive"){(a.messageId||r?.finalize)&&n.onDone(a.messageId);return}}let s=new m("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw k("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let r={messageId:""},i;try{i=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(i==="done"){n.onDone(r.messageId);return}if(i==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,i){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),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 u=a.body?.getReader();return u?await this.pumpReader(u,r,i):"inactive"}async pumpReader(e,t,n){let r=new TextDecoder,i,s=null,c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{e.cancel().catch(()=>{})},I.STREAM_INACTIVITY_TIMEOUT)};c();let d="",a=!1,l=u=>{if(a)return;let h=u.endsWith("\r")?u.slice(0,-1):u;if(h.startsWith("id: ")){i=h.slice(4);return}if(!h.startsWith("data: "))return;let g=h.slice(6);if(g==="[DONE]"){a=!0;return}try{let p=JSON.parse(g);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}i!==void 0&&(t.lastId=i,i=void 0)};try{for(;;){let{done:u,value:h}=await e.read();if(u)break;c(),d+=r.decode(h,{stream:!0});let g=d.split(`
|
|
239
|
+
`);d=g.pop()??"";for(let p of g)l(p);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 k(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 W=I;var A=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?.()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),K(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),K(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new 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(),K(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new 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:K(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],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(),K(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};return i&&(d.delta=i,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function K(o){if(o)return(e,t)=>o(e,t)}var oe=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,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})}},D=class{constructor(e,t,n=!1,r,i){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ye)),this.state=new oe(e,t,n,i)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(we):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?we(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(r=>r.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};function ye(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 we(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 N=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 Ie(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 se(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]=Ie(s);e[t]=r}return e}function xe(o){let e={};if(!o)return e;for(let[t,n]of Object.entries(o))e[t]=Ie(n);return e}var U=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=se(r))}setInitial(e){this.mem=e?se(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 xe(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return se(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 $=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 ae=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})}},L=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 ae(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 F(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var G=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=Ce(i)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Ce(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(F(`/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(F(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(F(`/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(F(`/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(F(`/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(F(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Ce(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 Re(o,e){if(!e)return o;let t=o.includes("?")?"&":"?";return`${o}${t}game_id=${encodeURIComponent(e)}`}var V=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(Re(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Re(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var q=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 j=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 Te="/functions/v1/world-engine/v1",_e="https://api.storvia.ai";function Oe(){return window.__STORVIA__||{}}function Me(o,e=3e4){let t=Oe();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(P("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 M({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}),me(h=>this.bus.send(h));let n=await Me(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}${Te}`,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 W(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,g]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(C=>C.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.storyMode=n.storyMode===!0;let p=()=>this.gameId,w=()=>this.conversationId,R=()=>this.modelId,T=()=>this.models.find(C=>C.id===this.modelId)?.name,S=()=>this.storyMode;this.chat=new A(this.http,p,w,R,!0,this.previewConfig,T,S),this.characters=new D(this.http,w,!0,g?.characters,g?.characterStates),this.relationships=new N(this.http,w,!0,g?.relationships),this.inventory=new U(this.http,w,!0,g?.inventory),this.world=new $(this.http,w,!0,g?.world),this.player=new L(this.http,w,!0,g?.player,g?.playerState),this.custom=new G(this.http,w,p,!0,g?.custom,g?.custom_inject),this.save=new V(this.http,w,p,!0,g?.save_data),this.state=new q(this.http,w,!0),this.memory=new j(this.http,w,!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(h=>h.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(h=>h.id===this.modelId)?.name,u=()=>this.storyMode;this.chat=new A(this.http,c,d,a,!1,void 0,l,u),this.characters=new D(this.http,d),this.relationships=new N(this.http,d),this.inventory=new U(this.http,d),this.world=new $(this.http,d),this.player=new L(this.http,d),this.custom=new G(this.http,d,c),this.save=new V(this.http,d,c),this.state=new q(this.http,d),this.memory=new j(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=`${_e}${Te}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new W(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 A(this.http,i,s,c,!0,void 0,d),this.characters=new D(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new N(this.http,s,!0,n?.relationships),this.inventory=new U(this.http,s,!0,n?.inventory),this.world=new $(this.http,s,!0,n?.world),this.player=new L(this.http,s,!0,n?.player,n?.playerState),this.custom=new G(this.http,s,i,!0,n?.custom),this.save=new V(this.http,s,i,!0,n?.save_data),this.memory=new j(this.http,s,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(i=>({id:i.id,name:i.name,url:i.url,assetType:i.asset_type,category:i.category}))}};async function Ae(o){let e=new te;return o?.dev?await e.initDev(o.dev):await e.init(),e}function Se(o){return typeof o=="object"&&o!==null&&"value"in o&&"type"in o&&(o.type==="number"||o.type==="text")}function De(o){return Se(o)?o.value:o}export{H as PROTOCOL_VERSION,M as StorviaBus,m as StorviaError,te as StorviaSDK,Ae as createStorviaSDK,P as envelope,De as extractFieldValue,Z as isProtocolEnvelope,Se as isRichFieldValue,Pe as setToastEnabled,fe as showToast};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var StorviaSDK=(()=>{var
|
|
2
|
-
#${
|
|
1
|
+
"use strict";var StorviaSDK=(()=>{var re=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var Oe=Object.prototype.hasOwnProperty;var Me=(i,e)=>{for(var t in e)re(i,t,{get:e[t],enumerable:!0})},Ae=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of _e(e))!Oe.call(i,r)&&r!==t&&re(i,r,{get:()=>e[r],enumerable:!(n=xe(e,r))||n.enumerable});return i};var De=i=>Ae(re({},"__esModule",{value:!0}),i);var je={};Me(je,{PROTOCOL_VERSION:()=>A,StorviaBus:()=>O,StorviaError:()=>u,StorviaSDK:()=>Y,createStorviaSDK:()=>Pe,envelope:()=>R,extractFieldValue:()=>ke,isProtocolEnvelope:()=>W,isRichFieldValue:()=>le,setToastEnabled:()=>Ie,showToast:()=>se});var u=class extends Error{constructor(e,t){super(t),this.name="StorviaError",this.code=e}};var A=1;function W(i){if(!i||typeof i!="object")return!1;let e=i;return typeof e.protocol=="number"&&typeof e.type=="string"&&"payload"in e}function R(i,e,t){return{protocol:1,type:i,payload:e,...t?.id?{id:t.id}:{},...t?.ackId?{ackId:t.ackId}:{}}}var O=class{constructor(e){this.handlers=new Map;this.pendingAcks=new Map;this.listener=null;this.incoming=e.incoming,this.getOutgoing=e.outgoing,this.verifySource=e.verifySource??(()=>!0),this.validate=e.validate,this.debug=!!e.debug,this.getTransferables=e.transfer??(()=>{}),this.customSend=e.customSend,this.attach()}attach(){this.listener=e=>{if((this.incoming instanceof Window||this.incoming===window)&&!this.verifySource(e))return;let t=e.data;if(!W(t))return;if(t.protocol!==1){this.debug&&console.warn("[StorviaBus] protocol mismatch",{expected:1,got:t.protocol,type:t.type});return}if(this.validate&&!this.validate(t)){this.debug&&console.warn("[StorviaBus] validation failed",t);return}if(t.ackId){let r=this.pendingAcks.get(t.ackId);if(r){this.pendingAcks.delete(t.ackId),r(t);return}}let n=this.handlers.get(t.type);if(!n||n.size===0){this.debug&&console.debug("[StorviaBus] no handler for",t.type);return}n.forEach(r=>{try{r(t)}catch(o){console.error(`[StorviaBus] handler '${t.type}' threw:`,o)}})},this.incoming.addEventListener("message",this.listener),this.incoming instanceof MessagePort&&this.incoming.start()}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let r=t;return n.add(r),()=>n.delete(r)}send(e){let t=e.protocol?e:R(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??Ne(),s=R(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 Ne(){return`bus-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var oe=null;function fe(i){oe=i}var ee="storvia-sdk-toast-style",te="storvia-sdk-toast-stack",ye=`
|
|
2
|
+
#${te} {
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: max(20px, env(safe-area-inset-top, 0px) + 20px);
|
|
5
5
|
right: max(20px, env(safe-area-inset-right, 0px) + 20px);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
@media (max-width: 768px) {
|
|
15
|
-
#${
|
|
15
|
+
#${te} {
|
|
16
16
|
top: max(10px, env(safe-area-inset-top, 0px) + 10px);
|
|
17
17
|
left: 10px;
|
|
18
18
|
right: 10px;
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
.storvia-sheet-msg { font-size: 13px; margin-bottom: 22px; }
|
|
220
220
|
.storvia-sheet-btn { height: 40px; font-size: 13px; }
|
|
221
221
|
}
|
|
222
|
-
`,
|
|
223
|
-
<span class="storvia-toast-icon">${
|
|
222
|
+
`,Ue={success:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',error:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',warning:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',info:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>'},ie={UNAUTHORIZED:"\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55",INSUFFICIENT_CREDITS:"\u82B1\u56ED\u5E01\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u518D\u7EE7\u7EED\u6E38\u620F",VIOLATION_WORD_DETECTED:"\u5185\u5BB9\u542B\u6709\u8FDD\u7981\u8BCD\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5",CONTENT_FILTERED:"\u5185\u5BB9\u88AB\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u8BF7\u8C03\u6574\u540E\u91CD\u8BD5",MODEL_REFUSAL:"\u6A21\u578B\u62D2\u7EDD\u54CD\u5E94\uFF0C\u6362\u4E2A\u8BF4\u6CD5\u8BD5\u8BD5",STREAM_INTERRUPTED:"\u56DE\u590D\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",RATE_LIMITED:"\u64CD\u4F5C\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",MODEL_NOT_FOUND:"\u6240\u9009\u6A21\u578B\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5207\u6362\u5176\u4ED6\u6A21\u578B",GAME_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u6E38\u620F",INVALID_REQUEST:"\u8BF7\u6C42\u65E0\u6548\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",INTERNAL_ERROR:"\u670D\u52A1\u51FA\u4E86\u70B9\u5C0F\u95EE\u9898\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",NOT_INITIALIZED:"SDK \u5C1A\u672A\u521D\u59CB\u5316",NOT_SUPPORTED_IN_PREVIEW:"\u5F53\u524D\u63A5\u53E3\u5728\u9884\u89C8\u6A21\u5F0F\u4E0B\u4E0D\u53EF\u7528",NETWORK_ERROR:"\u7F51\u7EDC\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5",REQUEST_TIMEOUT:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",MODEL_LOADING_TIMEOUT:"\u6A21\u578B\u54CD\u5E94\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",STREAM_INACTIVITY:"\u8FDE\u63A5\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u8BD5",DAISY_CARD_REQUIRED:"\u56DE\u6EAF\u6D88\u606F\u9700\u8981\u6709\u6548\u7684\u96CF\u83CA\u5361\u8BA2\u9605",MESSAGE_NOT_FOUND:"\u6D88\u606F\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C",MESSAGE_TOO_OLD:"\u4EC5\u53EF\u56DE\u6EAF 30 \u5929\u5185\u7684\u6D88\u606F",NO_MESSAGES_TO_DELETE:"\u8BE5\u6D88\u606F\u4E4B\u540E\u6CA1\u6709\u53EF\u56DE\u6EAF\u7684\u6D88\u606F",GENERATION_TIMEOUT:"\u751F\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5",REPETITION_LOOP:"\u56DE\u590D\u51FA\u73B0\u91CD\u590D\uFF0C\u8BF7\u91CD\u8BD5\u6216\u6362\u4E2A\u8BF4\u6CD5",SAVE_FAILED:"\u6D88\u606F\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4E0D\u6263\u8D39\uFF0C\u8BF7\u91CD\u8BD5",FINALIZE_FAILED:"\u56DE\u590D\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",CONVERSATION_NOT_FOUND:"\u672A\u627E\u5230\u5BF9\u5E94\u4F1A\u8BDD",EMPTY_MESSAGE:"\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A",CONTINUE_MODEL_NOT_AVAILABLE:"\u7EED\u5199\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528",CONTINUE_PROMPT_MISSING:"\u7EED\u5199\u914D\u7F6E\u7F3A\u5931"},we=!0;function Ie(i){we=i}function $e(){if(typeof document>"u")return null;let i=document.getElementById(te);if(!i){if(!document.getElementById(ee)){let e=document.createElement("style");e.id=ee,e.textContent=ye,document.head.appendChild(e)}i=document.createElement("div"),i.id=te,document.body.appendChild(i)}return i}function se(i,e="info",t=3500,n){if(!we)return;let r=$e();if(!r)return;let o=t<=0,s=document.createElement("div");s.className=`storvia-toast ${e}`,s.innerHTML=`
|
|
223
|
+
<span class="storvia-toast-icon">${Ue[e]}</span>
|
|
224
224
|
<span class="storvia-toast-msg"></span>
|
|
225
|
-
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(
|
|
225
|
+
`;let c=s.querySelector(".storvia-toast-msg");c&&(c.textContent=i);let d=()=>{s.isConnected&&(s.classList.add("leaving"),s.classList.remove("show"),setTimeout(()=>s.remove(),320))};if(n){let a=document.createElement("button");a.type="button",a.className="storvia-toast-action",a.textContent=n.label,a.addEventListener("click",()=>{try{n.onClick()}catch(l){console.error("[Storvia toast] action error:",l)}d()}),s.appendChild(a)}if(o){let a=document.createElement("button");a.type="button",a.className="storvia-toast-close",a.setAttribute("aria-label","\u5173\u95ED"),a.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',a.addEventListener("click",d),s.appendChild(a)}r.appendChild(s),requestAnimationFrame(()=>s.classList.add("show")),o||setTimeout(d,t)}function k(i,e){if(i==="INSUFFICIENT_CREDITS"){ve({title:"\u82B1\u56ED\u5E01\u4E0D\u8DB3",msg:e||ie.INSUFFICIENT_CREDITS,primaryLabel:"\u53BB\u5145\u503C"});return}if(i==="DAISY_CARD_REQUIRED"){ve({title:"\u9700\u8981\u96CF\u83CA\u5361",msg:e||ie.DAISY_CARD_REQUIRED,primaryLabel:"\u53BB\u5F00\u901A"});return}let t=ie[i]||e||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";se(t,i==="RATE_LIMITED"?"warning":"error")}var X=null;function ve(i){if(typeof document>"u"||X)return;if(!document.getElementById(ee)){let s=document.createElement("style");s.id=ee,s.textContent=ye,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=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(),
|
|
238
|
-
`);
|
|
239
|
-
`)){if(l.startsWith("id: ")){o=l.slice(4);continue}if(!l.startsWith("data: "))continue;let m=l.slice(6);if(m==="[DONE]")return s&&clearTimeout(s),"done";try{let p=JSON.parse(m);p.type==="done"&&p.id?t.messageId=p.id:p.type==="state"?(n.onState?.(p.delta,p.full??null),Array.isArray(p.createdNames)&&p.createdNames.length&&n.onCreatedCharacters?.(p.createdNames)):p.type==="thinking"?(p.status==="start"||p.status==="end")&&n.onThinking?.(p.status):p.content&&n.onChunk(p.content)}catch{}o!==void 0&&(t.lastId=o,o=void 0)}}}catch{}finally{s&&clearTimeout(s)}return"eof"}async handleResponseWithRaw(e){let t=await e.text(),n;try{n=t?JSON.parse(t):null}catch{n=t}if(!e.ok){let r=n&&typeof n=="object"?n:{},o={401:"UNAUTHORIZED",402:"INSUFFICIENT_CREDITS",429:"RATE_LIMITED"},s=r.code||o[e.status]||"INTERNAL_ERROR",c=new u(s,r.message||`HTTP ${e.status}`);throw S(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};f.REQUEST_TIMEOUT=6e4,f.MODEL_LOADING_TIMEOUT=18e4,f.STREAM_INACTIVITY_TIMEOUT=6e4,f.RECONNECT_MAX_ATTEMPTS=10,f.RECONNECT_BACKOFF_CAP=15e3;var H=f;var A=class{constructor(e,t,n,r,o=!1,s,c){this.http=e;this.getGameId=t;this.getConversationId=n;this.getModelId=r;this.isPreview=o;this.previewConfig=s,this.getModelName=c}reqMeta(){let e=this.getModelName?.();return e?{modelName:e}:void 0}updatePreviewConfig(e){this.previewConfig=e}async send(e){if(this.isPreview)return this.sendPreview(e);let t={game_id:this.getGameId(),conversation_id:this.getConversationId(),model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:W(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[]};this.previewConfig?t.prompt_config=this.previewConfig:t.game_id=this.getGameId();let n=this.previewConfig;if(n?.reply_length&&(t.reply_length=n.reply_length),n?.reply_language&&(t.reply_language=n.reply_language),e.stream){await this.http.stream("/preview",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),W(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,h)=>{o=a,s=h,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function W(i){if(i)return(e,t)=>i(e,t)}var de=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e,t){if(this.isPreview){let r=this.mem[e]||{};return t?{...r[t]||{}}:{...r}}let n=t?{group:t}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,n)}async update(e,t,n){if(this.isPreview){let r=this.mem[e]||(this.mem[e]={});r[t]={...r[t]||{},...n};return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{group:t,values:n})}},M=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(ye)),this.state=new de(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(ye):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Ie):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Ie(t):{name:e}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async add(e){if(this.isPreview){this.mem.push({...e,isPreset:!1});return}await this.http.post(`/conversations/${this.getConversationId()}/characters`,e)}async update(e,t){if(this.isPreview){let n=this.mem.find(r=>r.name===e);n&&Object.assign(n,t);return}await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`,t)}async remove(e){if(this.isPreview){this.mem=this.mem.filter(t=>t.name!==e);return}await this.http.delete(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}`)}async detail(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return{name:e,avatar:t?.avatar,description:t?.description,...t?.introduction!==void 0?{introduction:t.introduction}:{},...t?.visibleAtStart!==void 0?{visibleAtStart:t.visibleAtStart}:{},userDescription:t?.userDescription,...t?.gender?{gender:t.gender}:{},...t?.isPreset!==void 0?{isPreset:t.isPreset}:{},state:await this.state.get(e)}}return this.http.get(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/detail`)}async setPriority(e,t){let n=Math.max(0,Math.min(100,Math.round(t)));this.isPreview||await this.http.patch(`/conversations/${this.getConversationId()}/characters/${encodeURIComponent(e)}/state`,{priority:n})}};function ye(i){return{name:i.name,description:i.description,avatar:i.avatar,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.gender?{gender:i.gender}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}function Ie(i){return{name:i.name,avatar:i.avatar,description:i.description,...i.introduction!==void 0?{introduction:i.introduction}:{},...i.visibleAtStart!==void 0?{visibleAtStart:i.visibleAtStart}:{},...i.userDescription!==void 0?{userDescription:i.userDescription}:{},...i.gender?{gender:i.gender}:{},...i.isPreset!==void 0?{isPreset:i.isPreset}:{}}}var D=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(o=>({...o})))}setInitial(e){this.mem=e?e.map(t=>({...t})):[]}async list(){return this.isPreview?[...this.mem]:this.http.get(`/conversations/${this.getConversationId()}/relationships`)}async get(e,t){if(this.isPreview){let n=this.mem.find(r=>r.from===e&&r.to===t);if(n)return{...n};throw new Error("Relationship not found")}return this.http.get(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async add(e){if(this.isPreview){this.mem.push({...e});return}await this.http.post(`/conversations/${this.getConversationId()}/relationships`,e)}async update(e,t,n){if(this.isPreview){let r=this.mem.find(o=>o.from===e&&o.to===t);r?Object.assign(r,n):this.mem.push({from:e,to:t,...n});return}await this.http.patch(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,n)}async remove(e,t){if(this.isPreview){this.mem=this.mem.filter(n=>!(n.from===e&&n.to===t));return}await this.http.delete(`/conversations/${this.getConversationId()}/relationships/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}};function Ce(i){let e={count:i.count};return i.desc!==void 0&&(e.desc=i.desc),i.icon_url!==void 0&&(e.iconUrl=i.icon_url),e}function ce(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i)){let r={};for(let[o,s]of Object.entries(n))r[o]=Ce(s);e[t]=r}return e}function $e(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Ce(n);return e}var N=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=ce(r))}setInitial(e){this.mem=e?ce(e):{}}async list(e){if(this.isPreview){if(e!==void 0)return{...this.mem[e]||{}};let n={};for(let[r,o]of Object.entries(this.mem))n[r]={...o};return n}if(e!==void 0){let n=await this.http.get(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(e)}`);return $e(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return ce(t)}async add(e){let{group:t,name:n,count:r=1,desc:o,iconUrl:s}=e;if(this.isPreview){if(!this.mem[t])throw new Error(`Group "${t}" does not exist`);if(n in this.mem[t])throw new Error(`Item "${n}" already exists in group "${t}"`);let d={count:r};o!==void 0&&(d.desc=o),s!==void 0&&(d.iconUrl=s),this.mem[t][n]=d;return}let c={group:t,name:n,count:r};o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.post(`/conversations/${this.getConversationId()}/inventory`,c)}async update(e){let{group:t,name:n,count:r,desc:o,iconUrl:s}=e;if(this.isPreview){let d=this.mem[t];if(!d||!(n in d))throw new Error(`Item "${t}/${n}" not found`);let a=d[n];r!==void 0&&(a.count=r),o!==void 0&&(a.desc=o),s!==void 0&&(a.iconUrl=s);return}let c={};r!==void 0&&(c.count=r),o!==void 0&&(c.desc=o),s!==void 0&&(c.icon_url=s),await this.http.patch(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,c)}async remove(e){let{group:t,name:n}=e;if(this.isPreview){this.mem[t]&&delete this.mem[t][n];return}await this.http.delete(`/conversations/${this.getConversationId()}/inventory/${encodeURIComponent(t)}/${encodeURIComponent(n)}`)}async move(e){let{fromGroup:t,toGroup:n,name:r,newName:o}=e;if(this.isPreview){let s=this.mem[t];if(!s||!(r in s))throw new Error(`Source item "${t}/${r}" not found`);if(!this.mem[n])throw new Error(`Target group "${n}" does not exist`);let c=o||r;if(t===n&&c===r)return;if(c in this.mem[n])throw new Error(`Item "${c}" already exists in target group`);this.mem[n][c]=s[r],delete s[r];return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/move`,{fromGroup:t,toGroup:n,name:r,newName:o})}async ensureGroup(e){if(this.isPreview){this.mem[e]||(this.mem[e]={});return}await this.http.post(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}`,{})}async removeGroup(e,t){let n=t?.cascade??!1;if(this.isPreview){let o=this.mem[e];if(o&&Object.keys(o).length>0&&!n)throw new Error(`Group "${e}" is not empty, pass cascade: true to force delete`);delete this.mem[e];return}let r=n?"?cascade=true":"";await this.http.delete(`/conversations/${this.getConversationId()}/inventory/groups/${encodeURIComponent(e)}${r}`)}};var U=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:this.http.get(`/conversations/${this.getConversationId()}/world`)}async update(e){if(this.isPreview){Object.assign(this.mem,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/world`,e)}};var le=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem={...r})}setInitial(e){this.mem=e?{...e}:{}}async get(e){if(this.isPreview)return e?{...this.mem[e]||{}}:{...this.mem};let t=e?{group:e}:void 0;return this.http.get(`/conversations/${this.getConversationId()}/player/state`,t)}async update(e,t){if(this.isPreview){this.mem[e]={...this.mem[e]||{},...t};return}await this.http.patch(`/conversations/${this.getConversationId()}/player/state`,{group:e,values:t})}},$=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.memPersona={name:""};r&&(this.memPersona={...r}),this.state=new le(e,t,n,o)}setInitial(e,t){this.memPersona=e?{...e}:{name:""},this.state.setInitial(t)}async get(){return this.isPreview?{...this.memPersona}:this.http.get(`/conversations/${this.getConversationId()}/player`)}async update(e){if(this.isPreview){Object.assign(this.memPersona,e);return}await this.http.patch(`/conversations/${this.getConversationId()}/player`,e)}};function L(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var F=class{constructor(e,t,n,r=!1,o,s){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};this.memInject={};o&&(this.mem=Re(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Re(e):{},this.memInject=t?{...t}:{}}async get(e){if(this.isPreview)return e!==void 0?this.mem[e]:{...this.mem};let t=await this.http.get(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()));return e!==void 0?t[e]:t}async set(e,t){if(this.isPreview){for(let[r,o]of Object.entries(e))typeof o=="object"&&o!==null&&typeof this.mem[r]=="object"&&this.mem[r]!==null?this.mem[r]={...this.mem[r],...o}:this.mem[r]=o,t?.inject!==void 0&&(this.memInject[r]=t.inject);return}let n=t?.inject!==void 0?{data:e,inject:t.inject}:e;await this.http.patch(L(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/inject/${encodeURIComponent(e)}`,this.getGameId()),{inject:t})}getInject(){return{...this.memInject}}async delete(e){if(this.isPreview){delete this.mem[e],delete this.memInject[e];return}await this.http.delete(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}`,this.getGameId()))}async setGroupField(e,t,n){if(this.isPreview){(!this.mem[e]||typeof this.mem[e]!="object")&&(this.mem[e]={}),this.mem[e][t]=n;return}await this.http.patch(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()),{value:n})}async deleteGroupField(e,t){if(this.isPreview){if(typeof this.mem[e]=="object"&&this.mem[e]!==null){let n=this.mem[e];delete n[t]}return}await this.http.delete(L(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Re(i){let e={};for(let[t,n]of Object.entries(i))typeof n=="object"&&n!==null&&!Array.isArray(n)?e[t]={...n}:e[t]=n;return e}function Te(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var G=class{constructor(e,t,n,r=!1,o){this.http=e;this.getConversationId=t;this.getGameId=n;this.isPreview=r;this.mem={};o&&(this.mem={...o})}setInitial(e){this.mem=e?{...e}:{}}async get(){return this.isPreview?{...this.mem}:await this.http.get(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Te(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var K=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var V=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=null}async get(){return this.isPreview?this.mem?{...this.mem}:null:(await this.http.get(`/conversations/${this.getConversationId()}/summary`)).ai_summary}async update(e){let t=(e??"").trim();if(this.isPreview){let r={content:t,updated_at:new Date().toISOString()};return this.mem=r,{...r}}return(await this.http.patch(`/conversations/${this.getConversationId()}/summary`,{content:t})).ai_summary}};var Ee="/functions/v1/world-engine/v1",Le="https://api.storvia.ai";function Fe(){return window.__STORVIA__||{}}function Ge(i,e=3e4){let t=Fe();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,debug:a.payload.debug})}),c=i.on("preview-init",a=>{a.payload?.apiBase&&d(a.payload)});function d(a){clearTimeout(o),s(),c();let h=window;h.__STORVIA__=a,n(a)}i.send(C("ready",{}))})}var q=class{constructor(){this.baseUrl="";this.gameId="";this.conversationId="";this.modelId="";this.models=[];this.accessToken="";this.initialized=!1;this.isPreview=!1;this.previewConfig=void 0}async init(){if(this.initialized)return;let e=window.flutter_inappwebview,t=typeof e?.callHandler=="function";this.bus=new _({incoming:window,outgoing:()=>t?null:window.parent,verifySource:t?l=>l.source===null||l.source===window:l=>l.source===window.parent,customSend:t?l=>e.callHandler("storviaBus",l):void 0}),ge(l=>this.bus.send(l));let n=await Ge(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${Ee}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new H(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[l,m]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=l,this.modelId=(n.selectedModelId&&l.some(I=>I.id===n.selectedModelId)?n.selectedModelId:"")||l[0]?.id||"";let p=()=>this.gameId,g=()=>this.conversationId,b=()=>this.modelId,R=()=>this.models.find(I=>I.id===this.modelId)?.name;this.chat=new A(this.http,p,g,b,!0,this.previewConfig,R),this.characters=new M(this.http,g,!0,m?.characters,m?.characterStates),this.relationships=new D(this.http,g,!0,m?.relationships),this.inventory=new N(this.http,g,!0,m?.inventory),this.world=new U(this.http,g,!0,m?.world),this.player=new $(this.http,g,!0,m?.player,m?.playerState),this.custom=new F(this.http,g,p,!0,m?.custom,m?.custom_inject),this.save=new G(this.http,g,p,!0,m?.save_data),this.state=new K(this.http,g,!0),this.memory=new V(this.http,g,!0),this.initialized=!0,this.listenForPreviewMessages(),this.listenForTokenUpdate();return}this.conversationId=n.conversationId??"";let[o,s]=await Promise.all([this.authenticate(),this.fetchModels()]);this.conversationId=o.conversationId,this.models=s,this.modelId=(n.selectedModelId&&s.some(l=>l.id===n.selectedModelId)?n.selectedModelId:"")||s[0]?.id||"";let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,h=()=>this.models.find(l=>l.id===this.modelId)?.name;this.chat=new A(this.http,c,d,a,!1,void 0,h),this.characters=new M(this.http,d),this.relationships=new D(this.http,d),this.inventory=new N(this.http,d),this.world=new U(this.http,d),this.player=new $(this.http,d),this.custom=new F(this.http,d,c),this.save=new G(this.http,d,c),this.state=new K(this.http,d),this.memory=new V(this.http,d),this.listenForTokenUpdate(),this.listenForModelChange(),this.initialized=!0}listenForModelChange(){this.bus.on("set-model",e=>{let t=e.payload?.modelId||"";t&&(this.modelId=t)})}listenForTokenUpdate(){this.bus.on("token-update",e=>{let t=e.payload?.accessToken;typeof t!="string"||!t||(this.accessToken=t,this.http?.setToken(t))})}listenForPreviewMessages(){this.bus.on("set-model",e=>{this.modelId=e.payload.modelId||""}),this.bus.on("config-update",e=>{this.previewConfig=e.payload.previewConfig,this.chat&&this.chat.updatePreviewConfig(this.previewConfig),this.refreshPreviewSnapshot().catch(t=>{console.warn("[Storvia SDK] refreshPreviewSnapshot failed:",t)})})}async fetchPreviewSnapshot(){try{let e={game_id:this.gameId};return this.previewConfig&&("game_config"in this.previewConfig&&(e.game_config=this.previewConfig.game_config),"game_state"in this.previewConfig&&(e.game_state_override=this.previewConfig.game_state)),await this.http.post("/preview/initial-snapshot",e)}catch(e){return console.warn("[Storvia SDK] fetchPreviewSnapshot failed:",e),null}}async refreshPreviewSnapshot(){let e=await this.fetchPreviewSnapshot();e&&(this.characters?.setInitial(e.characters,e.characterStates),this.player?.setInitial(e.player,e.playerState),this.inventory?.setInitial(e.inventory),this.relationships?.setInitial(e.relationships),this.world?.setInitial(e.world),this.custom?.setInitial(e.custom,e.custom_inject),this.save?.setInitial(e.save_data))}async fetchModels(){try{return await this.http.get("/models")}catch{}return[]}async authenticate(){let e={game_id:this.gameId};this.conversationId&&(e.conversation_id=this.conversationId);let t=await fetch(`${this.baseUrl}/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`},body:JSON.stringify(e)});if(!t.ok)throw t.status===401?new u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Le}${Ee}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new H(this.baseUrl,"",!1,e.apiKey);let[t,n]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=t;let r=e.model?t.find(a=>a.name===e.model)?.id??"":"";this.modelId=r||t[0]?.id||"",this.conversationId="00000000-0000-0000-0000-000000000000";let o=()=>this.gameId,s=()=>this.conversationId,c=()=>this.modelId,d=()=>this.models.find(a=>a.id===this.modelId)?.name;this.chat=new A(this.http,o,s,c,!0,void 0,d),this.characters=new M(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new D(this.http,s,!0,n?.relationships),this.inventory=new N(this.http,s,!0,n?.inventory),this.world=new U(this.http,s,!0,n?.world),this.player=new $(this.http,s,!0,n?.player,n?.playerState),this.custom=new F(this.http,s,o,!0,n?.custom),this.save=new G(this.http,s,o,!0,n?.save_data),this.memory=new V(this.http,s,!0),this.initialized=!0}async getAssets(e,t){let n={asset_type:e};return t&&(n.category=t),(await this.http.get("/assets",n)).map(o=>({id:o.id,name:o.name,url:o.url,assetType:o.asset_type,category:o.category}))}};async function Se(i){let e=new q;return i?.dev?await e.initDev(i.dev):await e.init(),e}function he(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function be(i){return he(i)?i.value:i}return Me(Ve);})();
|
|
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(),X===e&&(X=null)},240))};e.querySelector('[data-role="cancel"]')?.addEventListener("click",o),e.addEventListener("click",s=>{s.target===e&&o()}),r?.addEventListener("click",()=>{if(oe)try{oe(R("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),X=e,requestAnimationFrame(()=>e.classList.add("show"))}var I=class I{constructor(e,t,n=!1,r=""){this.baseUrl=e,this.token=t,this.debug=n,this.devApiKey=r}setToken(e){this.token=e}setDebug(e){this.debug=e}maybeShowNetworkToast(e){e instanceof u||k("NETWORK_ERROR")}wrapAbortError(e){if(e instanceof DOMException&&e.name==="AbortError"){let t=new u("REQUEST_TIMEOUT","Request timed out");return k("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",g=a!==void 0?` (${a}ms)`:"",m=o!==void 0?` [${o}]`:"",w=l?` [model: ${l}]`:"";d?(console.groupCollapsed(`${p} %c${t} ${n}${m}${w}${g} %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}${m}${w}${g} %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){let p=Date.now(),h=o?.modelName?` [model: ${o.modelName}]`:"",g=[],m=f=>{this.debug&&g.push({t:Date.now()-p,event:f})},w=new AbortController,T=null,S=null,E=null,C=null,x=()=>{T!==null&&(clearTimeout(T),T=null),S!==null&&(clearTimeout(S),S=null),E!==null&&(clearTimeout(E),E=null)},Q=f=>{C=f,x(),w.abort()};T=setTimeout(()=>Q("REQUEST_TIMEOUT"),I.REQUEST_TIMEOUT);let b;try{b=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(t),signal:w.signal})}catch(f){if(x(),C){let y=new u(C,"Request timed out");throw k(C),this.log({method:"STREAM",path:e,body:t,error:y,durationMs:Date.now()-p,modelName:o?.modelName}),y}throw this.maybeShowNetworkToast(f),f}if(T!==null&&(clearTimeout(T),T=null),!b.ok){x();let f=await b.text().catch(()=>""),y={};try{y=JSON.parse(f)}catch{}let P=y.code||"INTERNAL_ERROR",v=new u(P,y.message||`HTTP ${b.status}`);throw k(P,y.message),this.log({method:"STREAM",path:e,body:t,status:b.status,rawResponse:f,error:v,durationMs:Date.now()-p,modelName:o?.modelName}),v}let he=b.body?.getReader();if(!he)throw x(),new u("INTERNAL_ERROR","No response body for stream");S=setTimeout(()=>Q("MODEL_LOADING_TIMEOUT"),I.MODEL_LOADING_TIMEOUT);let ue=new TextDecoder,H="",_="",pe=!1,ne,Z,M="",J=!1,me=f=>{if(J)return;let y=f.endsWith("\r")?f.slice(0,-1):f;if(y.startsWith("id: ")){Z=y.slice(4);return}if(!y.startsWith("data: "))return;let P=y.slice(6);if(P==="[DONE]"){m("[DONE]"),J=!0;return}try{let v=JSON.parse(P);m(v),v.type==="done"&&v.id?H=v.id:v.type==="state"?(s&&s(v.delta,v.full??null),d&&Array.isArray(v.createdNames)&&v.createdNames.length&&d(v.createdNames)):v.type==="thinking"?c&&(v.status==="start"||v.status==="end")&&c(v.status):v.content&&(pe?(E!==null&&clearTimeout(E),E=setTimeout(()=>Q("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)):(pe=!0,S!==null&&(clearTimeout(S),S=null),E=setTimeout(()=>Q("STREAM_INACTIVITY"),I.STREAM_INACTIVITY_TIMEOUT)),_+=v.content,n(v.content))}catch{m({raw:P})}Z!==void 0&&(ne=Z,Z=void 0)},ge=()=>{x(),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2713`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #22c55e"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log("Message ID:",H),console.log(`SSE events (${g.length}):`,g),console.groupEnd()),r(H)};try{for(;;){let{done:f,value:y}=await he.read();if(f)break;M+=ue.decode(y,{stream:!0});let P=M.split(`
|
|
238
|
+
`);M=P.pop()??"";for(let v of P)me(v);if(J){ge();return}}if(M+=ue.decode(),M&&me(M),J){ge();return}}catch(f){if(x(),C){let y=new u(C,C==="MODEL_LOADING_TIMEOUT"?"Model loading timed out":"Stream inactivity timed out");throw k(C),this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2717 ${C}`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Timeout:",y),console.groupEnd()),y}if(this.debug&&(console.groupCollapsed(`%c[Storvia SDK] %cSTREAM ${e} [${b.status}]${h} (${Date.now()-p}ms) %c\u2717`,"color: #6366f1; font-weight: bold","color: #e0e0e0","color: #ef4444"),console.log("Request:",t),console.log(`Accumulated content (${_.length} chars):`,_),console.log(`SSE events (${g.length}):`,g),console.error("Stream error:",f),console.groupEnd()),a){await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0});return}throw f}if(x(),H){r(H);return}a&&await this.resumeLoop(a,ne,{onChunk:n,onDone:r,onState:s,onThinking:c,onCreatedCharacters:d,onReconnect:l},{finalize:!0})}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"){n.onDone(a.messageId);return}if(l==="inactive"){(a.messageId||r?.finalize)&&n.onDone(a.messageId);return}}let s=new u("STREAM_INTERRUPTED","Stream reconnection failed after maximum attempts");throw k("STREAM_INTERRUPTED"),s}async resumeStream(e,t,n){let r={messageId:""},o;try{o=await this.pumpGetStream(e,t,void 0,r,n)}catch{await this.resumeLoop({conversationId:e,topic:t},r.lastId,n);return}if(o==="done"){n.onDone(r.messageId);return}if(o==="inactive"){r.messageId&&n.onDone(r.messageId);return}await this.resumeLoop({conversationId:e,topic:t},r.lastId,n)}async pumpGetStream(e,t,n,r,o){let s=new URL(`${this.baseUrl}/conversations/${encodeURIComponent(e)}/stream`);n&&s.searchParams.set("from",n),t&&s.searchParams.set("topic",t);let c=new AbortController,d=setTimeout(()=>c.abort(),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 u("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 g=h.slice(6);if(g==="[DONE]"){a=!0;return}try{let m=JSON.parse(g);m.type==="done"&&m.id?t.messageId=m.id:m.type==="state"?(n.onState?.(m.delta,m.full??null),Array.isArray(m.createdNames)&&m.createdNames.length&&n.onCreatedCharacters?.(m.createdNames)):m.type==="thinking"?(m.status==="start"||m.status==="end")&&n.onThinking?.(m.status):m.content&&n.onChunk(m.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 g=d.split(`
|
|
239
|
+
`);d=g.pop()??"";for(let m of g)l(m);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 u(s,r.message||`HTTP ${e.status}`);throw k(s,r.message),c}return n&&typeof n=="object"&&"data"in n?{raw:n,data:n.data}:{raw:n,data:n}}};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 K=I;var D=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.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?.()};if(e.stream){await this.http.stream("/chat",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/chat",t,this.reqMeta())}async save(e){return this.isPreview?{id:`preview-${Date.now()}`}:this.http.post("/messages/save",{conversation_id:this.getConversationId(),role:e.role,content:e.content,topic:e.topic})}async generate(e){if(this.isPreview)return this.sendPreview({message:"",topic:e.topic,sceneKey:e.sceneKey,stream:e.stream,onChunk:e.onChunk,onDone:e.onDone,onState:e.onState,onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters});let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/generate",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/generate",t,this.reqMeta())}async retry(e={}){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.retry() is not available in preview mode. Publish the game and test on the Storvia platform.");let t={conversation_id:this.getConversationId(),model_id:this.getModelId(),topic:e.topic,scene_key:e.sceneKey,extract:e.extract,stream:e.stream??!1,story_mode:this.getStoryMode?.()};if(e.stream){await this.http.stream("/retry",t,e.onChunk??(()=>{}),e.onDone??(()=>{}),this.reqMeta(),q(e.onState),e.onThinking,e.onCreatedCharacters,{conversationId:this.getConversationId(),topic:e.topic},e.onReconnecting);return}return this.http.post("/retry",t,this.reqMeta())}async messages(e){if(this.isPreview)return{data:[],hasMore:!1,nextCursor:null};let t={conversation_id:this.getConversationId(),order:e.order,limit:String(e.limit??20)};e.topic&&(t.topic=e.topic),e.cursor&&(t.cursor_uuid=e.cursor.uuid,t.cursor_created_at=e.cursor.createdAt);let n=await this.http.get("/messages",t);return{data:n.messages.map(r=>({uuid:r.uuid,role:r.role,content:r.content,topic:r.topic,status:r.status,model:r.model,createdAt:r.created_at})),hasMore:n.has_more,nextCursor:n.next_cursor?{uuid:n.next_cursor.cursor_uuid,createdAt:n.next_cursor.cursor_created_at}:null}}async edit(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.edit() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.patch(`/messages/${encodeURIComponent(e.uuid)}`,{content:e.content});return{uuid:t.uuid,role:t.role,content:t.content,updatedAt:t.updated_at}}async delete(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.delete() is not available in preview mode. Publish the game and test on the Storvia platform.");return{uuid:(await this.http.delete(`/messages/${encodeURIComponent(e.uuid)}`)).uuid}}async rollback(e){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.chat.rollback() is not available in preview mode. Publish the game and test on the Storvia platform.");let t=await this.http.post(`/messages/${encodeURIComponent(e.uuid)}/rollback`,{});return{deletedCount:t.deleted_count,deletedUuids:t.deleted_uuids,restoredGameState:t.restored_game_state}}async resume(e={}){this.isPreview||await this.http.resumeStream(this.getConversationId(),e.topic,{onChunk:e.onChunk??(()=>{}),onDone:e.onDone??(()=>{}),onState:q(e.onState),onThinking:e.onThinking,onCreatedCharacters:e.onCreatedCharacters,onReconnect:e.onReconnecting})}async sendPreview(e){let t={model_id:this.getModelId(),message:e.message,topic:e.topic,scene_key:e.sceneKey,history_messages:[],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(),q(e.onState),e.onThinking,e.onCreatedCharacters);return}let r="",o=null,s=null,c=[];await this.http.stream("/preview",t,a=>{r+=a},()=>{},this.reqMeta(),(a,l)=>{o=a,s=l,e.onState&&e.onState(o,s)},void 0,a=>{c=a,e.onCreatedCharacters&&e.onCreatedCharacters(a)});let d={id:"",content:r};return o&&(d.delta=o,s&&(d.full=s)),c.length&&(d.createdNames=c),d}};function q(i){if(i)return(e,t)=>i(e,t)}var ae=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})}},N=class{constructor(e,t,n=!1,r,o){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem=[];r&&(this.mem=r.map(Ce)),this.state=new ae(e,t,n,o)}setInitial(e,t){this.mem=e?e.map(Ce):[],this.state.setInitial(t)}async list(){return this.isPreview?this.mem.map(Re):this.http.get(`/conversations/${this.getConversationId()}/characters`)}async get(e){if(this.isPreview){let t=this.mem.find(n=>n.name===e);return t?Re(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 Ce(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 Re(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 U=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 Te(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 de(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]=Te(s);e[t]=r}return e}function Le(i){let e={};if(!i)return e;for(let[t,n]of Object.entries(i))e[t]=Te(n);return e}var $=class{constructor(e,t,n=!1,r){this.http=e;this.getConversationId=t;this.isPreview=n;this.mem={};r&&(this.mem=de(r))}setInitial(e){this.mem=e?de(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 Le(n)}let t=await this.http.get(`/conversations/${this.getConversationId()}/inventory`);return de(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 L=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 ce=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})}},F=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 ce(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 G(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var V=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=Se(o)),s&&(this.memInject={...s})}setInitial(e,t){this.mem=e?Se(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(G(`/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(G(`/conversations/${this.getConversationId()}/custom`,this.getGameId()),n)}async setInject(e,t){if(this.isPreview){this.memInject[e]=t;return}await this.http.patch(G(`/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(G(`/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(G(`/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(G(`/conversations/${this.getConversationId()}/custom/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,this.getGameId()))}};function Se(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 Ee(i,e){if(!e)return i;let t=i.includes("?")?"&":"?";return`${i}${t}game_id=${encodeURIComponent(e)}`}var j=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(Ee(`/conversations/${this.getConversationId()}/save`,this.getGameId()))}async set(e){if(this.isPreview){this.mem={...e};return}await this.http.put(Ee(`/conversations/${this.getConversationId()}/save`,this.getGameId()),e)}};var z=class{constructor(e,t,n=!1){this.http=e;this.getConversationId=t;this.isPreview=n}async get(){if(this.isPreview)throw new u("NOT_SUPPORTED_IN_PREVIEW","storvia.state.get() is not available in preview mode. Publish the game and test on the Storvia platform. (Use per-module get() like storvia.world.get() if you need to inspect state during preview.)");return this.http.get(`/conversations/${this.getConversationId()}/state`)}};var B=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 be="/functions/v1/world-engine/v1",Fe="https://api.storvia.ai";function Ge(){return window.__STORVIA__||{}}function Ve(i,e=3e4){let t=Ge();return t.apiBase?Promise.resolve(t):new Promise((n,r)=>{let o=setTimeout(()=>{s(),c(),r(new u("NOT_INITIALIZED","Timed out waiting for __STORVIA__ config from parent frame."))},e),s=i.on("init",a=>{a.payload?.apiBase&&d({apiBase:a.payload.apiBase,gameId:a.payload.gameId,conversationId:a.payload.conversationId,accessToken:a.payload.accessToken,selectedModelId:a.payload.selectedModelId,storyMode:a.payload.storyMode,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(R("ready",{}))})}var Y=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 O({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}),fe(h=>this.bus.send(h));let n=await Ve(this.bus),r=n.apiBase;if(!r)throw new u("NOT_INITIALIZED","window.__STORVIA__.apiBase is not set. The platform must inject it before SDK init.");if(this.baseUrl=`${r}${be}`,this.isPreview=!!n.preview,this.previewConfig=n.previewConfig,!n.gameId)throw new u("GAME_NOT_FOUND","window.__STORVIA__.gameId is not set. The platform must inject it before SDK init.");if(this.gameId=n.gameId,!n.accessToken)throw new u("UNAUTHORIZED","window.__STORVIA__.accessToken is not set. The platform must inject the user token before SDK init.");if(this.accessToken=n.accessToken,this.http=new K(this.baseUrl,this.accessToken,!!n.debug),this.isPreview){this.conversationId="00000000-0000-0000-0000-000000000000";let[h,g]=await Promise.all([this.fetchModels(),this.fetchPreviewSnapshot()]);this.models=h,this.modelId=(n.selectedModelId&&h.some(C=>C.id===n.selectedModelId)?n.selectedModelId:"")||h[0]?.id||"",this.storyMode=n.storyMode===!0;let m=()=>this.gameId,w=()=>this.conversationId,T=()=>this.modelId,S=()=>this.models.find(C=>C.id===this.modelId)?.name,E=()=>this.storyMode;this.chat=new D(this.http,m,w,T,!0,this.previewConfig,S,E),this.characters=new N(this.http,w,!0,g?.characters,g?.characterStates),this.relationships=new U(this.http,w,!0,g?.relationships),this.inventory=new $(this.http,w,!0,g?.inventory),this.world=new L(this.http,w,!0,g?.world),this.player=new F(this.http,w,!0,g?.player,g?.playerState),this.custom=new V(this.http,w,m,!0,g?.custom,g?.custom_inject),this.save=new j(this.http,w,m,!0,g?.save_data),this.state=new z(this.http,w,!0),this.memory=new B(this.http,w,!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.storyMode=n.storyMode===!0;let c=()=>this.gameId,d=()=>this.conversationId,a=()=>this.modelId,l=()=>this.models.find(h=>h.id===this.modelId)?.name,p=()=>this.storyMode;this.chat=new D(this.http,c,d,a,!1,void 0,l,p),this.characters=new N(this.http,d),this.relationships=new U(this.http,d),this.inventory=new $(this.http,d),this.world=new L(this.http,d),this.player=new F(this.http,d),this.custom=new V(this.http,d,c),this.save=new j(this.http,d,c),this.state=new z(this.http,d),this.memory=new B(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 u("UNAUTHORIZED","User not authenticated"):t.status===404?new u("GAME_NOT_FOUND","Game not found or not published"):new u("INTERNAL_ERROR",`Auth failed: HTTP ${t.status}`);let n=await t.json();return n.data??n}async initDev(e){if(this.initialized)return;this.baseUrl=`${Fe}${be}`,this.gameId=e.gameId,this.isPreview=!0,this.http=new K(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 D(this.http,o,s,c,!0,void 0,d),this.characters=new N(this.http,s,!0,n?.characters,n?.characterStates),this.relationships=new U(this.http,s,!0,n?.relationships),this.inventory=new $(this.http,s,!0,n?.inventory),this.world=new L(this.http,s,!0,n?.world),this.player=new F(this.http,s,!0,n?.player,n?.playerState),this.custom=new V(this.http,s,o,!0,n?.custom),this.save=new j(this.http,s,o,!0,n?.save_data),this.memory=new B(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 Pe(i){let e=new Y;return i?.dev?await e.initDev(i.dev):await e.init(),e}function le(i){return typeof i=="object"&&i!==null&&"value"in i&&"type"in i&&(i.type==="number"||i.type==="text")}function ke(i){return le(i)?i.value:i}return De(je);})();
|
|
240
240
|
if(typeof window!=="undefined"){window.createStorviaSDK=StorviaSDK.createStorviaSDK;}
|