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() 是异步工厂函数,会自动完成以下步骤:
- 从 Storvia 平台接收配置(API 地址、游戏 ID、用户身份、当前模型)
- 鉴权并获取或创建用户存档
- 加载模型列表,并应用平台下发的当前模型
- 准备各功能模块(对话、角色、属性等)
模型选择与游戏设置由平台提供:模型切换、回复长度、温度等由 Storvia 平台(网页端 / App)的界面负责。SDK 不再渲染内置的模型 / 设置悬浮按钮——玩家在平台 切换模型后,SDK 会自动应用到后续对话,游戏侧无需处理。
建议用 try/catch 包裹:
try {
const storvia = await createStorviaSDK();
// 初始化成功,开始游戏
} catch (err) {
console.error("SDK 初始化失败:", err.message);
}本地调试
本地开发时 SDK 无法从平台获取配置,可通过 API Key 进入 dev 模式:
- 在创作台将游戏发布为私有
- 获取
gameId:进入游戏详情页,点击右上角「⋯」菜单,选择「复制游戏 ID」 - 在创作台「API 密钥」页面生成一个 API Key
- 本地代码传入 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.chat | AI 对话(发送/保存/生成) |
| 角色 | 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_INITIALIZED | SDK 尚未初始化(在 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_RULE | extract 提取规则非法(缺失 / 相同 / 超长) |
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 | 服务器内部错误 |