@storvia/sdk 0.6.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,15 @@
1
+ /** 续读/重连共用的回调集合(与 stream() 的散参一一对应)。 */
2
+ interface SSECallbacks {
3
+ onChunk: (text: string) => void;
4
+ onDone: (id: string) => void;
5
+ onState?: (delta: unknown, full: unknown) => void;
6
+ onThinking?: (status: 'start' | 'end') => void;
7
+ onCreatedCharacters?: (names: string[]) => void;
8
+ /** 每次发起重连前触发(attempt 从 1 递增),供 UI 提示「正在重新连接」。 */
9
+ onReconnect?: (info: {
10
+ attempt: number;
11
+ }) => void;
12
+ }
1
13
  declare class HttpClient {
2
14
  private baseUrl;
3
15
  private token;
@@ -31,7 +43,28 @@ declare class HttpClient {
31
43
  delete<T>(path: string): Promise<T>;
32
44
  stream(path: string, body: unknown, onChunk: (text: string) => void, onDone: (id: string) => void, meta?: {
33
45
  modelName?: string;
34
- }, onState?: (delta: unknown, full: unknown) => void, onThinking?: (status: 'start' | 'end') => void, onCreatedCharacters?: (names: string[]) => void): Promise<void>;
46
+ }, onState?: (delta: unknown, full: unknown) => void, onThinking?: (status: 'start' | 'end') => void, onCreatedCharacters?: (names: string[]) => void, resume?: {
47
+ conversationId: string;
48
+ topic?: string;
49
+ }, onReconnect?: (info: {
50
+ attempt: number;
51
+ }) => void): Promise<void>;
52
+ private static readonly RECONNECT_MAX_ATTEMPTS;
53
+ private static readonly RECONNECT_BACKOFF_CAP;
54
+ /**
55
+ * 重连循环:退避 → GET 续读 → 直到拿到终止事件 / 服务端报无在途 / 次数耗尽。
56
+ * 每次重连前回调 onReconnect 供 UI 提示「正在重新连接 n/10」。
57
+ */
58
+ private resumeLoop;
59
+ /**
60
+ * 公开续读入口:接管某会话/ topic 的在途生成(刷新 / 换设备 / 多端接力时用)。
61
+ * 无在途生成则静默返回。供 ChatModule.resume() 调用。
62
+ */
63
+ resumeStream(conversationId: string, topic: string | undefined, cb: SSECallbacks): Promise<void>;
64
+ /** 单次 GET 续读:拉一段 SSE 并分发。无在途生成(服务端回 JSON)返回 'inactive';HTTP/网络失败抛出供上层退避。 */
65
+ private pumpGetStream;
66
+ /** 共享 SSE 读循环:解析 id:/data:,分发 content/state/thinking/done,跟踪 lastId。带无活动超时(cancel 后返回 'eof' 供重连)。 */
67
+ private pumpReader;
35
68
  /**
36
69
  * 读取完整响应文本,解析为 JSON 并返回 `{ raw, data }`:
37
70
  * - `raw` 是后端返回的整体(用于 debug 完整打印,含 success/code/message 等包装字段)
@@ -53,7 +86,7 @@ interface AssetItem {
53
86
  assetType: 'avatar' | 'icon';
54
87
  category: string;
55
88
  }
56
- type StorviaErrorCode = 'UNAUTHORIZED' | 'INSUFFICIENT_CREDITS' | 'VIOLATION_WORD_DETECTED' | 'CONTENT_FILTERED' | 'MODEL_REFUSAL' | 'STREAM_INTERRUPTED' | 'RATE_LIMITED' | 'MODEL_NOT_FOUND' | 'GAME_NOT_FOUND' | 'INVALID_REQUEST' | 'INTERNAL_ERROR' | 'NOT_INITIALIZED' | 'NOT_SUPPORTED_IN_PREVIEW' | 'NETWORK_ERROR' | 'REQUEST_TIMEOUT' | 'MODEL_LOADING_TIMEOUT' | 'STREAM_INACTIVITY' | 'DAISY_CARD_REQUIRED' | 'MESSAGE_NOT_FOUND' | 'MESSAGE_TOO_OLD' | 'NO_MESSAGES_TO_DELETE';
89
+ type StorviaErrorCode = 'UNAUTHORIZED' | 'INSUFFICIENT_CREDITS' | 'VIOLATION_WORD_DETECTED' | 'CONTENT_FILTERED' | 'MODEL_REFUSAL' | 'STREAM_INTERRUPTED' | 'RATE_LIMITED' | 'MODEL_NOT_FOUND' | 'GAME_NOT_FOUND' | 'INVALID_REQUEST' | 'INTERNAL_ERROR' | 'NOT_INITIALIZED' | 'NOT_SUPPORTED_IN_PREVIEW' | 'NETWORK_ERROR' | 'REQUEST_TIMEOUT' | 'MODEL_LOADING_TIMEOUT' | 'STREAM_INACTIVITY' | 'DAISY_CARD_REQUIRED' | 'MESSAGE_NOT_FOUND' | 'MESSAGE_TOO_OLD' | 'NO_MESSAGES_TO_DELETE' | 'GENERATION_TIMEOUT' | 'REPETITION_LOOP' | 'SAVE_FAILED' | 'FINALIZE_FAILED' | 'CONVERSATION_NOT_FOUND' | 'EMPTY_MESSAGE' | 'CONTINUE_MODEL_NOT_AVAILABLE' | 'CONTINUE_PROMPT_MISSING';
57
90
  /** AI 本轮的属性变更(仅包含发生改变的字段) */
58
91
  interface StateChanges {
59
92
  /** 世界状态变更(扁平 KV) */
@@ -104,6 +137,14 @@ type ChatThinkingCallback = (status: 'start' | 'end') => void;
104
137
  * 非流式调用通过 ChatResponse.createdNames 获取,无需此回调。
105
138
  */
106
139
  type ChatCreatedCharactersCallback = (names: string[]) => void;
140
+ /**
141
+ * 断线重连回调:流式生成中途断开(刷新/切后台/断网/弱网)后,SDK 自动经
142
+ * GET /conversations/:id/stream 续读,每次发起重连前触发。
143
+ * @param info.attempt 第几次重连尝试(从 1 递增,最多 10 次)
144
+ */
145
+ type ChatReconnectingCallback = (info: {
146
+ attempt: number;
147
+ }) => void;
107
148
  /**
108
149
  * 流式 + 入库内容过滤规则。提供后,服务端只保留 AI 回复中
109
150
  * `start..end` 之间的内容(多段会自动拼接),其余被丢弃。
@@ -135,6 +176,8 @@ interface ChatSendOptions {
135
176
  onThinking?: ChatThinkingCallback;
136
177
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
137
178
  onCreatedCharacters?: ChatCreatedCharactersCallback;
179
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
180
+ onReconnecting?: ChatReconnectingCallback;
138
181
  }
139
182
  interface ChatSaveOptions {
140
183
  role: 'user' | 'assistant';
@@ -155,6 +198,8 @@ interface ChatGenerateOptions {
155
198
  onThinking?: ChatThinkingCallback;
156
199
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
157
200
  onCreatedCharacters?: ChatCreatedCharactersCallback;
201
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
202
+ onReconnecting?: ChatReconnectingCallback;
158
203
  }
159
204
  interface ChatRetryOptions {
160
205
  topic?: string;
@@ -170,6 +215,8 @@ interface ChatRetryOptions {
170
215
  onThinking?: ChatThinkingCallback;
171
216
  /** 本轮出现「真·新角色」时触发;非流式调用通过 ChatResponse.createdNames 获取,无需此回调 */
172
217
  onCreatedCharacters?: ChatCreatedCharactersCallback;
218
+ /** 仅流式:生成中途断开后 SDK 自动续读,每次重连前触发,供 UI 提示「正在重新连接」 */
219
+ onReconnecting?: ChatReconnectingCallback;
173
220
  }
174
221
  interface ChatResponse {
175
222
  id: string;
@@ -181,6 +228,26 @@ interface ChatResponse {
181
228
  /** 本轮出现的「真·新角色」名字数组,仅在有新角色时出现 */
182
229
  createdNames?: string[];
183
230
  }
231
+ /** chat.active() 返回:该会话/ topic 当前是否有在途生成。 */
232
+ interface ChatActiveResult {
233
+ /** 是否有正在进行的生成 */
234
+ active: boolean;
235
+ /** 在途生成的 id(active 为 true 时存在) */
236
+ generationId?: string;
237
+ }
238
+ /**
239
+ * chat.resume() 选项:接管会话/ topic 的在途生成(刷新 / 换设备 / 多端接力)。
240
+ * 流式回调与 send 一致;无在途生成时静默返回。
241
+ */
242
+ interface ChatResumeOptions {
243
+ topic?: string;
244
+ onChunk?: (text: string) => void;
245
+ onDone?: (id: string) => void;
246
+ onState?: ChatStateCallback;
247
+ onThinking?: ChatThinkingCallback;
248
+ onCreatedCharacters?: ChatCreatedCharactersCallback;
249
+ onReconnecting?: ChatReconnectingCallback;
250
+ }
184
251
  interface ChatMessageCursor {
185
252
  uuid: string;
186
253
  createdAt: string;
@@ -385,13 +452,6 @@ interface State {
385
452
  dormant: DormantState;
386
453
  }
387
454
 
388
- interface GameSettings {
389
- temperature: number;
390
- replyLength: string;
391
- replyLanguage: string;
392
- playerNote: string;
393
- }
394
-
395
455
  declare class ChatModule {
396
456
  private http;
397
457
  private getGameId;
@@ -399,9 +459,8 @@ declare class ChatModule {
399
459
  private getModelId;
400
460
  private isPreview;
401
461
  private previewConfig?;
402
- private getSettings?;
403
462
  private getModelName?;
404
- constructor(http: HttpClient, getGameId: () => string, getConversationId: () => string, getModelId: () => string, isPreview?: boolean, previewConfig?: Record<string, unknown>, getSettings?: () => GameSettings | null | undefined, getModelName?: () => string | undefined);
463
+ constructor(http: HttpClient, getGameId: () => string, getConversationId: () => string, getModelId: () => string, isPreview?: boolean, previewConfig?: Record<string, unknown>, getModelName?: () => string | undefined);
405
464
  /** 构造 http 层的元信息(用于 debug 日志标题显示) */
406
465
  private reqMeta;
407
466
  /** 更新预览配置(由父页面 postMessage 触发) */
@@ -452,6 +511,21 @@ declare class ChatModule {
452
511
  * - 该消息本身不会被删除;它之后的所有消息会被删除
453
512
  */
454
513
  rollback(options: ChatRollbackOptions): Promise<ChatRollbackResponse>;
514
+ /**
515
+ * 查询当前会话(可按 topic)是否有正在进行的生成。
516
+ * 进入对话 / 刷新 / 换设备后先调它,命中再用 resume() 接管在途流。
517
+ * 预览模式无在途生成,恒返回 { active: false }。
518
+ */
519
+ active(options?: {
520
+ topic?: string;
521
+ }): Promise<ChatActiveResult>;
522
+ /**
523
+ * 接管会话/ topic 的在途生成并续读(刷新、换设备、多端接力时用)。
524
+ * - 生成跑在 chat-worker、产物在 Redis 流,与发起请求的连接解耦;从头实时接上正在输出的内容。
525
+ * - 续读中途再断会自动重连续读;服务端已无在途生成(已跑完)则静默返回。
526
+ * 预览模式无在途生成,直接返回。
527
+ */
528
+ resume(options?: ChatResumeOptions): Promise<void>;
455
529
  /** 预览模式:发到 /preview 端点
456
530
  * - 创作台预览:父页面已注入 previewConfig,请求体塞 prompt_config,服务端不查库
457
531
  * - 本地预览 / dev:无 previewConfig,请求体塞 game_id,服务端按 hash_id 查 prompts
@@ -691,10 +765,11 @@ declare class MemoryModule {
691
765
  interface DevConfig {
692
766
  apiKey: string;
693
767
  gameId: string;
768
+ /** 本地预览/dev:指定初始模型的展示名(display name)。不传则用第一个可用模型。 */
769
+ model?: string;
694
770
  }
695
771
  declare class StorviaSDK {
696
772
  private http;
697
- private settingsSheet;
698
773
  private baseUrl;
699
774
  private gameId;
700
775
  private conversationId;
@@ -716,18 +791,18 @@ declare class StorviaSDK {
716
791
  state: StateModule;
717
792
  memory: MemoryModule;
718
793
  init(): Promise<void>;
794
+ /**
795
+ * 监听宿主运行时下发的模型切换(envelope 'set-model')。
796
+ * 正式模式用:宿主已接管模型选择,用户在宿主 FAB 改模型时实时同步到 SDK。
797
+ * (预览模式的 set-model 在 listenForPreviewMessages 内单独处理。)
798
+ */
799
+ private listenForModelChange;
719
800
  /**
720
801
  * 监听父页面 token 刷新(envelope 'token-update')。
721
802
  * Supabase JWT 默认 1h 过期,父页面 session 自动刷新后转发新 token 进来,
722
803
  * 否则 SDK 会一直用旧 token 请求被服务端 401。
723
804
  */
724
805
  private listenForTokenUpdate;
725
- /**
726
- * 用户在 SDK 内置选择器里切换模型时统一入口:
727
- * 更新内部 modelId,并把选择回传给宿主(主站/App),实现双向同步与持久化。
728
- * dev 模式没有 bus(无父页面),此时仅更新本地。
729
- */
730
- private handleLocalModelChange;
731
806
  /** 监听父页面发来的预览模式动态更新(envelope 'config-update' / 'set-model') */
732
807
  private listenForPreviewMessages;
733
808
  /**
@@ -739,13 +814,8 @@ declare class StorviaSDK {
739
814
  private fetchPreviewSnapshot;
740
815
  /** 重新拉 snapshot 并把结果灌进每个 module 的 mem(用于 update-config 后同步) */
741
816
  private refreshPreviewSnapshot;
742
- /** 保存设置到后端 */
743
- private saveSettings;
744
- /** 同步最新游戏设定到当前存档 */
745
- syncSettings(): Promise<void>;
746
817
  private fetchModels;
747
818
  private authenticate;
748
- private getSavedModelId;
749
819
  initDev(devConfig: DevConfig): Promise<void>;
750
820
  getAssets(type: 'avatar' | 'icon', category?: string): Promise<AssetItem[]>;
751
821
  }
@@ -793,6 +863,12 @@ interface InitPayload {
793
863
  * 待主站 / App 全部升级后改为必填,以彻底消除 /auth 端选错存档的漂移。
794
864
  */
795
865
  conversationId?: string;
866
+ /**
867
+ * 宿主(主站/App)已选中的模型 UUID。宿主已接管模型选择 → 正式模式优先用它,
868
+ * 盖过 SDK 自己的 localStorage / 列表首项。随 init 一起下发,避免「init 后单独发 set-model」
869
+ * 在 SDK 注册监听前到达而丢失的竞态。运行时切换仍走 envelope 'set-model'。
870
+ */
871
+ selectedModelId?: string;
796
872
  debug?: boolean;
797
873
  }
798
874
  interface PreviewConfig {
@@ -943,4 +1019,4 @@ interface ToastAction {
943
1019
  */
944
1020
  declare function showToast(message: string, type?: ToastType, duration?: number, action?: ToastAction): void;
945
1021
 
946
- export { type AISummary, type AckPayload, type AssetItem, type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatGenerateOptions, type ChatMessage, type ChatMessageCursor, type ChatMessagesOptions, type ChatMessagesResponse, type ChatResponse, type ChatRetryOptions, type ChatSaveOptions, type ChatSendOptions, type ChatStateCallback, type ConfigUpdatePayload, type CurrentState, type DormantState, type DownstreamMsg, type FieldValue, type Gender, type InitPayload, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type OrientationPayload, PROTOCOL_VERSION, type PlayerPersona, type PreviewConfig, type PreviewInitPayload, type ProtocolEnvelope, type ReadyPayload, type Relationship, type RichFieldValue, type SdkErrorPayload, type SetModelPayload, type State, type StateChanges, StorviaBus, type StorviaBusOptions, StorviaError, type StorviaErrorCode, StorviaSDK, type TokenUpdatePayload, type UpstreamMsg, createStorviaSDK, envelope, extractFieldValue, isProtocolEnvelope, isRichFieldValue, setToastEnabled, showToast };
1022
+ export { type AISummary, type AckPayload, type AssetItem, type CharacterAddOptions, type CharacterDetail, type CharacterPersona, type CharacterUpdateOptions, type ChatActiveResult, type ChatGenerateOptions, type ChatMessage, type ChatMessageCursor, type ChatMessagesOptions, type ChatMessagesResponse, type ChatReconnectingCallback, type ChatResponse, type ChatResumeOptions, type ChatRetryOptions, type ChatSaveOptions, type ChatSendOptions, type ChatStateCallback, type ConfigUpdatePayload, type CurrentState, type DormantState, type DownstreamMsg, type FieldValue, type Gender, type InitPayload, type InventoryAddOptions, type InventoryMoveOptions, type InventoryRemoveGroupOptions, type InventoryRemoveOptions, type InventoryState, type InventoryUpdateOptions, type ItemData, type OrientationPayload, PROTOCOL_VERSION, type PlayerPersona, type PreviewConfig, type PreviewInitPayload, type ProtocolEnvelope, type ReadyPayload, type Relationship, type RichFieldValue, type SdkErrorPayload, type SetModelPayload, type State, type StateChanges, StorviaBus, type StorviaBusOptions, StorviaError, type StorviaErrorCode, StorviaSDK, type TokenUpdatePayload, type UpstreamMsg, createStorviaSDK, envelope, extractFieldValue, isProtocolEnvelope, isRichFieldValue, setToastEnabled, showToast };