Storvia

SDK 初始化

Storvia SDK 的安装、引入、初始化和基本使用

已有项目接入

纯 HTML 项目(无构建工具)

直接通过 CDN 引入,无需 npm 或构建工具:

<script src="https://cdn.jsdelivr.net/npm/@storvia/sdk/dist/index.umd.js"></script>
<script type="module">
    const storvia = await window.createStorviaSDK();
</script>

npm 项目(Vue / React 等)

安装 SDK:

npm install @storvia/sdk

在入口文件中导入:

import { createStorviaSDK } from "@storvia/sdk";

const storvia = await createStorviaSDK();

使用构建工具(Vite 等)时,需在 vite.config.js 中设置 base: './',确保打包后资源使用相对路径。详见 快速开始。

初始化

createStorviaSDK() 是异步工厂函数,会自动完成以下步骤:

  1. 从 Storvia 平台接收配置(API 地址、游戏 ID、用户身份、当前模型)
  2. 鉴权并获取或创建用户存档
  3. 加载模型列表,并应用平台下发的当前模型
  4. 准备各功能模块(对话、角色、属性等)

模型选择与游戏设置由平台提供:模型切换、回复长度、温度等由 Storvia 平台(网页端 / App)的界面负责。SDK 不再渲染内置的模型 / 设置悬浮按钮——玩家在平台 切换模型后,SDK 会自动应用到后续对话,游戏侧无需处理。

建议用 try/catch 包裹:

try {
    const storvia = await createStorviaSDK();
    // 初始化成功,开始游戏
} catch (err) {
    console.error("SDK 初始化失败:", err.message);
}

本地调试

本地开发时 SDK 无法从平台获取配置,可通过 API Key 进入 dev 模式:

  1. 在创作台将游戏发布为私有
  2. 获取 gameId:进入游戏详情页,点击右上角「⋯」菜单,选择「复制游戏 ID」
  3. 在创作台「API 密钥」页面生成一个 API Key
  4. 本地代码传入 dev 配置:
const storvia = await createStorviaSDK({
    dev: {
        apiKey: "sk-storvia-xxxxxx",
        gameId: "your-game-id",
        model: "超速DS · 4 · 直连", // 可选,本地测试用的初始模型(界面上显示的模型名,任一语言都行);不传则用第一个可用模型
    },
});

dev 模式走预览模式:AI 对话正常工作(消耗创作者花园币),游戏状态不持久化。API Key 不要提交到 git,上传 ZIP 时平台会自动扫描并拦截。

SDK 模块一览

初始化成功后,可以通过以下模块访问平台能力:

模块访问方式功能
对话storvia.chatAI 对话(发送/保存/生成)
角色storvia.characters角色列表 + 角色属性读写 + 重复角色合并
玩家storvia.player玩家信息 + 玩家属性读写
关系storvia.relationships角色间关系 CRUD
物品storvia.inventory物品栏 CRUD(上限 200)
世界storvia.world世界状态读写
扩展属性storvia.custom文本/数值字段读写(上限 100,AI 追踪可在创作台或者SDK控制)
存档storvia.save游戏运行状态持久化(任意 JSON,独立配额,不注入 AI)
完整状态storvia.state一次性返回所有模块的合并快照(含休眠区)
永久记忆storvia.memory永久记忆读取 / 覆写(不过期、不被覆盖,每轮注入提示词)
素材库storvia.getAssets()获取官方素材库的头像 / 物品图标(平台级方法)
主线联动storvia.host仅小组件:给主线弹通知 / 刷新主线游戏面板(0.9.8 起)

每个模块的详细 API 见 聊天 和 属性;storvia.host 只在小组件里有意义,见 小组件 · 通知主线 / 刷新主线面板。

调试

SDK 不开放 debug 日志开关。window.__STORVIA__ 是平台侧初始化通信用的对象,由平台自动注入并整体覆盖,往里写 debug: true 不会生效(dev 模式不读这个对象,平台模式下宿主也不会下发 debug 配置)。

排查问题请直接用浏览器开发者工具的 Network 面板查看 SDK 的请求与响应,SSE 流可以在响应的 EventStream 里逐条看。更多本地调试细节见 沉浸创作本地测试。

错误处理

SDK 会自动捕获常见错误(余额不足、频率限制、登录失效等)并以 Toast 通知的形式展示给用户,无需在业务代码中逐一处理。

内置提示会跟随玩家的界面语言(简体 / 繁体 / English / 日本語 / 한국어),平台会把当前语言下发给 SDK,你不需要做任何事。本地 dev 调试时没有平台下发,SDK 按浏览器语言判断。

花园币不足 / 需要雏菊卡

这两种情况由平台接管,不走 Toast:SDK 会通知平台,平台弹出自己的充值引导(网页端在游戏上方弹充值弹窗,玩家不用离开游戏;App 跳到钱包页)。

你不需要为它们写任何处理代码。注意即使调用了 setToastEnabled(false),这两种情况依然会触发平台引导——这是平台级统一行为,不受该开关影响。

关闭内置 Toast

如果你想完全自己接管错误提示 UI(例如用自己的 toast 组件、对话框,或者直接静默处理),可以调用 setToastEnabled(false) 关闭 SDK 内置的 toast:

import { setToastEnabled } from "@storvia/sdk";

// 关闭所有内置 toast(包括错误、成功、信息提示)
setToastEnabled(false);

// 需要时可以再开回来
setToastEnabled(true);

这是一个全局开关,会同时关闭所有类型的 toast(error / success / warning / info),无法只静默某一类。关闭后请务必通过 try/catch 自己处理错误,否则用户将完全得不到反馈。

如果需要在特定操作出错时执行自定义逻辑(如跳转页面、记录日志),可以用 try/catch 捕获:

try {
    await storvia.chat.send({ message: "你好", topic: "main" });
} catch (err) {
    // err.code 是错误码,err.message 是可读的错误描述
    console.error("发送失败:", err.code, err.message);
}

命中违禁词时拿到具体的词(SDK 0.9.7 起)

VIOLATION_WORD_DETECTED 抛出的错误上会多带一个 matchedWords 字段(string[]),列出这次命中的违禁词,方便你在自己的 UI 里精确提示玩家改哪儿:

try {
    await storvia.chat.send({ message: text, topic: "main" });
} catch (err) {
    if (err.code === "VIOLATION_WORD_DETECTED") {
        highlightInInput(err.matchedWords); // ['词A', '词B']
        return;
    }
    throw err;
}

发消息、预览、保存消息、编辑消息、修改角色人设、修改玩家人设都会带上这个字段。SDK 内置 toast 也会自动把词拼进文案(「内容包含不符合社区规范的用词「词A」「词B」,请修改后重试」),所以不接管错误 UI 的话什么都不用做。

只有 VIOLATION_WORD_DETECTED 有 matchedWords,其它错误码上该字段为 undefined。

以下是 SDK 可能抛出的全部错误码(与 StorviaErrorCode 类型一一对应)。

鉴权与配额

错误码含义
UNAUTHORIZED用户未登录或 token 过期
NOT_INITIALIZEDSDK 尚未初始化(在 createStorviaSDK() 完成前调用了方法)
INSUFFICIENT_CREDITS花园币不足(由平台弹充值引导,不走 Toast)
DAISY_CARD_REQUIRED需要雏菊卡订阅(如 rollback();由平台引导,不走 Toast)
RATE_LIMITED请求频率过高
GENERATING_IN_PROGRESS该会话该 topic 已有生成在跑(409),见生成的并发规则
CONCURRENT_GENERATION_LIMIT该用户同时进行的生成已达上限(429)

资源与请求

错误码含义
GAME_NOT_FOUND游戏或存档不存在
CONVERSATION_NOT_FOUND会话不存在
MESSAGE_NOT_FOUND消息不存在或无权操作
MESSAGE_TOO_OLD仅可回溯 30 天内的消息
NO_MESSAGES_TO_DELETE该消息之后没有可回溯的消息
EMPTY_MESSAGE消息内容为空
INVALID_REQUEST请求参数无效
INVALID_EXTRACT_RULEextract 提取规则非法(缺失 / 相同 / 超长)
INVENTORY_LIMIT物品栏已满(上限 200)
CUSTOM_FIELDS_LIMIT扩展属性字段已满(上限 100)
NOT_SUPPORTED_IN_PREVIEW该方法在预览模式下不可用

生成过程

错误码含义
MODEL_NOT_FOUND所选模型不可用
VIOLATION_WORD_DETECTED内容命中违禁词
CONTENT_FILTERED内容被安全策略拦截
MODEL_REFUSAL模型拒绝响应
REPETITION_LOOP模型陷入重复循环被中断
GENERATION_TIMEOUT生成超时
GENERATION_LOST生成进程失联(内容可能已落库,刷新后用 messages() 取回)
GENERATION_ABORTED被用户主动中断(不是失败,SDK 不弹错误提示)
SAVE_FAILED消息入库失败(本次不扣费)
FINALIZE_FAILED回复收尾处理失败
CONTINUE_MODEL_NOT_AVAILABLE续写模型不可用
CONTINUE_PROMPT_MISSING续写配置缺失

网络与超时

错误码含义
NETWORK_ERROR网络层失败(fetch 抛错、断网)
REQUEST_TIMEOUT请求超时(60 秒内未收到服务器响应)
MODEL_LOADING_TIMEOUT模型响应超时(180 秒内未收到第一个 token)
STREAM_INACTIVITY流式连接静默(60 秒内未收到任何数据)
STREAM_INTERRUPTED流式输出中途断开(自动重连 10 次耗尽后抛出)
INTERNAL_ERROR服务器内部错误

本页目录