keepwork-sdk 1.0.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.
Files changed (146) hide show
  1. package/README.md +21 -0
  2. package/dist-npm/keepwork-sdk.js +37514 -0
  3. package/dist-npm/keepwork-sdk.js.map +1 -0
  4. package/dist-npm/md5-CZ0vz1_S.js +240 -0
  5. package/dist-npm/md5-CZ0vz1_S.js.map +1 -0
  6. package/dist-npm/types/index.d.ts +42 -0
  7. package/dist-npm/types/index.d.ts.map +1 -0
  8. package/dist-npm/types/src/ai-chat/AIChat.core.d.ts +218 -0
  9. package/dist-npm/types/src/ai-chat/AIChat.core.d.ts.map +1 -0
  10. package/dist-npm/types/src/ai-chat/AIChat.d.ts +18 -0
  11. package/dist-npm/types/src/ai-chat/AIChat.d.ts.map +1 -0
  12. package/dist-npm/types/src/ai-chat/AIChat.session.d.ts +201 -0
  13. package/dist-npm/types/src/ai-chat/AIChat.session.d.ts.map +1 -0
  14. package/dist-npm/types/src/ai-chat/AIGenerators.base.d.ts +297 -0
  15. package/dist-npm/types/src/ai-chat/AIGenerators.base.d.ts.map +1 -0
  16. package/dist-npm/types/src/ai-chat/AIGenerators.d.ts +15 -0
  17. package/dist-npm/types/src/ai-chat/AIGenerators.d.ts.map +1 -0
  18. package/dist-npm/types/src/ai-chat/AIGenerators.media.d.ts +208 -0
  19. package/dist-npm/types/src/ai-chat/AIGenerators.media.d.ts.map +1 -0
  20. package/dist-npm/types/src/ai-chat/ChildSessionMixin.d.ts +153 -0
  21. package/dist-npm/types/src/ai-chat/ChildSessionMixin.d.ts.map +1 -0
  22. package/dist-npm/types/src/ai-chat/CopilotTools.d.ts +150 -0
  23. package/dist-npm/types/src/ai-chat/CopilotTools.d.ts.map +1 -0
  24. package/dist-npm/types/src/ai-chat/MqttManager.d.ts +123 -0
  25. package/dist-npm/types/src/ai-chat/MqttManager.d.ts.map +1 -0
  26. package/dist-npm/types/src/ai-chat/SandboxToolEnv.d.ts +210 -0
  27. package/dist-npm/types/src/ai-chat/SandboxToolEnv.d.ts.map +1 -0
  28. package/dist-npm/types/src/audio/AudioEngine.d.ts +272 -0
  29. package/dist-npm/types/src/audio/AudioEngine.d.ts.map +1 -0
  30. package/dist-npm/types/src/audio/AudioEngine.utils.d.ts +72 -0
  31. package/dist-npm/types/src/audio/AudioEngine.utils.d.ts.map +1 -0
  32. package/dist-npm/types/src/audio/Speech.d.ts +247 -0
  33. package/dist-npm/types/src/audio/Speech.d.ts.map +1 -0
  34. package/dist-npm/types/src/core/AgentConfig.d.ts +104 -0
  35. package/dist-npm/types/src/core/AgentConfig.d.ts.map +1 -0
  36. package/dist-npm/types/src/core/AgentRouter.d.ts +342 -0
  37. package/dist-npm/types/src/core/AgentRouter.d.ts.map +1 -0
  38. package/dist-npm/types/src/core/NPL.d.ts +251 -0
  39. package/dist-npm/types/src/core/NPL.d.ts.map +1 -0
  40. package/dist-npm/types/src/core/RemoteLog.d.ts +132 -0
  41. package/dist-npm/types/src/core/RemoteLog.d.ts.map +1 -0
  42. package/dist-npm/types/src/core/keepworkSDK.core.d.ts +84 -0
  43. package/dist-npm/types/src/core/keepworkSDK.core.d.ts.map +1 -0
  44. package/dist-npm/types/src/core/keepworkSDK.d.ts +129 -0
  45. package/dist-npm/types/src/core/keepworkSDK.d.ts.map +1 -0
  46. package/dist-npm/types/src/core/keepworkSDK.pages.d.ts +101 -0
  47. package/dist-npm/types/src/core/keepworkSDK.pages.d.ts.map +1 -0
  48. package/dist-npm/types/src/core/keepworkSDK.utils.d.ts +40 -0
  49. package/dist-npm/types/src/core/keepworkSDK.utils.d.ts.map +1 -0
  50. package/dist-npm/types/src/digital-human/DigitalHuman.d.ts +1316 -0
  51. package/dist-npm/types/src/digital-human/DigitalHuman.d.ts.map +1 -0
  52. package/dist-npm/types/src/digital-human/DigitalHumanBridge.d.ts +54 -0
  53. package/dist-npm/types/src/digital-human/DigitalHumanBridge.d.ts.map +1 -0
  54. package/dist-npm/types/src/digital-human/DigitalHumanConfig.d.ts +104 -0
  55. package/dist-npm/types/src/digital-human/DigitalHumanConfig.d.ts.map +1 -0
  56. package/dist-npm/types/src/digital-human/DigitalHumanFrame.d.ts +390 -0
  57. package/dist-npm/types/src/digital-human/DigitalHumanFrame.d.ts.map +1 -0
  58. package/dist-npm/types/src/digital-human/DigitalHumanFrameMessages.d.ts +59 -0
  59. package/dist-npm/types/src/digital-human/DigitalHumanFrameMessages.d.ts.map +1 -0
  60. package/dist-npm/types/src/digital-human/DigitalHumanSubtitleOverlay.d.ts +114 -0
  61. package/dist-npm/types/src/digital-human/DigitalHumanSubtitleOverlay.d.ts.map +1 -0
  62. package/dist-npm/types/src/digital-human/DigitalHumanUtils.d.ts +53 -0
  63. package/dist-npm/types/src/digital-human/DigitalHumanUtils.d.ts.map +1 -0
  64. package/dist-npm/types/src/rtc/AIChatRTC.constants.d.ts +65 -0
  65. package/dist-npm/types/src/rtc/AIChatRTC.constants.d.ts.map +1 -0
  66. package/dist-npm/types/src/rtc/AIChatRTC.d.ts +91 -0
  67. package/dist-npm/types/src/rtc/AIChatRTC.d.ts.map +1 -0
  68. package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts +268 -0
  69. package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts.map +1 -0
  70. package/dist-npm/types/src/rtc/AIChatRTCLocal.backends.d.ts +232 -0
  71. package/dist-npm/types/src/rtc/AIChatRTCLocal.backends.d.ts.map +1 -0
  72. package/dist-npm/types/src/rtc/AIChatRTCLocal.core.d.ts +92 -0
  73. package/dist-npm/types/src/rtc/AIChatRTCLocal.core.d.ts.map +1 -0
  74. package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts +15 -0
  75. package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts.map +1 -0
  76. package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts +127 -0
  77. package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts.map +1 -0
  78. package/dist-npm/types/src/rtc/LocalRTC.d.ts +91 -0
  79. package/dist-npm/types/src/rtc/LocalRTC.d.ts.map +1 -0
  80. package/dist-npm/types/src/rtc/SpeechRTC.d.ts +156 -0
  81. package/dist-npm/types/src/rtc/SpeechRTC.d.ts.map +1 -0
  82. package/dist-npm/types/src/rtc/SpeechRTC.transport.d.ts +191 -0
  83. package/dist-npm/types/src/rtc/SpeechRTC.transport.d.ts.map +1 -0
  84. package/dist-npm/types/src/store/CloudDrive.d.ts +140 -0
  85. package/dist-npm/types/src/store/CloudDrive.d.ts.map +1 -0
  86. package/dist-npm/types/src/store/LocalStorageUtil.d.ts +136 -0
  87. package/dist-npm/types/src/store/LocalStorageUtil.d.ts.map +1 -0
  88. package/dist-npm/types/src/store/PersonalPageStore.base.d.ts +267 -0
  89. package/dist-npm/types/src/store/PersonalPageStore.base.d.ts.map +1 -0
  90. package/dist-npm/types/src/store/PersonalPageStore.d.ts +13 -0
  91. package/dist-npm/types/src/store/PersonalPageStore.d.ts.map +1 -0
  92. package/dist-npm/types/src/store/PersonalPageStore.data.d.ts +198 -0
  93. package/dist-npm/types/src/store/PersonalPageStore.data.d.ts.map +1 -0
  94. package/dist-npm/types/src/store/PersonalPageStore.sync.d.ts +171 -0
  95. package/dist-npm/types/src/store/PersonalPageStore.sync.d.ts.map +1 -0
  96. package/dist-npm/types/src/store/PersonalPageStore.types.d.ts +92 -0
  97. package/dist-npm/types/src/store/PersonalPageStore.types.d.ts.map +1 -0
  98. package/dist-npm/types/src/store/YMLParser.d.ts +96 -0
  99. package/dist-npm/types/src/store/YMLParser.d.ts.map +1 -0
  100. package/dist-npm/types/src/tools/AgentTool.d.ts +110 -0
  101. package/dist-npm/types/src/tools/AgentTool.d.ts.map +1 -0
  102. package/dist-npm/types/src/tools/AppTools.d.ts +122 -0
  103. package/dist-npm/types/src/tools/AppTools.d.ts.map +1 -0
  104. package/dist-npm/types/src/tools/ExecuteTool.d.ts +96 -0
  105. package/dist-npm/types/src/tools/ExecuteTool.d.ts.map +1 -0
  106. package/dist-npm/types/src/tools/FileTools.d.ts +77 -0
  107. package/dist-npm/types/src/tools/FileTools.d.ts.map +1 -0
  108. package/dist-npm/types/src/tools/MinigameTools.d.ts +234 -0
  109. package/dist-npm/types/src/tools/MinigameTools.d.ts.map +1 -0
  110. package/dist-npm/types/src/tools/MqttTool.d.ts +53 -0
  111. package/dist-npm/types/src/tools/MqttTool.d.ts.map +1 -0
  112. package/dist-npm/types/src/tools/PersonalPageTool.d.ts +57 -0
  113. package/dist-npm/types/src/tools/PersonalPageTool.d.ts.map +1 -0
  114. package/dist-npm/types/src/tools/SummarizeTool.d.ts +279 -0
  115. package/dist-npm/types/src/tools/SummarizeTool.d.ts.map +1 -0
  116. package/dist-npm/types/src/tools/WebTool.d.ts +106 -0
  117. package/dist-npm/types/src/tools/WebTool.d.ts.map +1 -0
  118. package/dist-npm/types/src/types/common.d.ts +164 -0
  119. package/dist-npm/types/src/types/common.d.ts.map +1 -0
  120. package/dist-npm/types/src/ui/LocalAPIKeySettings.d.ts +229 -0
  121. package/dist-npm/types/src/ui/LocalAPIKeySettings.d.ts.map +1 -0
  122. package/dist-npm/types/src/ui/LoginWindow.d.ts +163 -0
  123. package/dist-npm/types/src/ui/LoginWindow.d.ts.map +1 -0
  124. package/dist-npm/types/src/ui/ProfileWindow.d.ts +75 -0
  125. package/dist-npm/types/src/ui/ProfileWindow.d.ts.map +1 -0
  126. package/dist-npm/types/src/ui/VerifyHuman.d.ts +23 -0
  127. package/dist-npm/types/src/ui/VerifyHuman.d.ts.map +1 -0
  128. package/dist-npm/types/src/ui/WorkspaceViewer.d.ts +184 -0
  129. package/dist-npm/types/src/ui/WorkspaceViewer.d.ts.map +1 -0
  130. package/dist-npm/types/src/user/SocialFriends.d.ts +173 -0
  131. package/dist-npm/types/src/user/SocialFriends.d.ts.map +1 -0
  132. package/dist-npm/types/src/user/UserWorks.d.ts +187 -0
  133. package/dist-npm/types/src/user/UserWorks.d.ts.map +1 -0
  134. package/dist-npm/types/src/utils/ImageUtils.d.ts +107 -0
  135. package/dist-npm/types/src/utils/ImageUtils.d.ts.map +1 -0
  136. package/dist-npm/types/src/utils/SDKLogger.d.ts +111 -0
  137. package/dist-npm/types/src/utils/SDKLogger.d.ts.map +1 -0
  138. package/dist-npm/types/src/utils/translation.d.ts +95 -0
  139. package/dist-npm/types/src/utils/translation.d.ts.map +1 -0
  140. package/dist-npm/types/src/wechat/WxAuth.d.ts +126 -0
  141. package/dist-npm/types/src/wechat/WxAuth.d.ts.map +1 -0
  142. package/dist-npm/types/src/wechat/WxLaunchApp.d.ts +96 -0
  143. package/dist-npm/types/src/wechat/WxLaunchApp.d.ts.map +1 -0
  144. package/dist-npm/types/src/wechat/WxUtils.d.ts +145 -0
  145. package/dist-npm/types/src/wechat/WxUtils.d.ts.map +1 -0
  146. package/package.json +52 -0
@@ -0,0 +1,210 @@
1
+ /**
2
+ * SandboxToolEnv.ts — 工具沙箱执行环境(TypeScript 版)
3
+ *
4
+ * 为 AI 会话提供一个受控的工具执行上下文,包含:
5
+ * - `copilot` 代理对象:通过属性访问调用任意已注册工具
6
+ * - `processTemplate()`:展开 `${...}` 模板表达式
7
+ * - `registerAPI()`:注册自定义 API(优先于 CopilotTools)
8
+ * - 工具代理路由(toolProxy):将指定工具委托给远程 agent
9
+ * - 远程 agent 模式(remoteAgent):所有工具调用发往远程 agent
10
+ *
11
+ * ## 使用示例
12
+ * ```ts
13
+ * const sandbox = new SandboxToolEnv(sdk, {
14
+ * workspace: 'myApp',
15
+ * enabledCategories: ['fileOps', 'execute', 'agent'],
16
+ * });
17
+ * sandbox.registerAPI('get_weather', async (city) => fetchWeather(city));
18
+ * const expanded = await sandbox.processTemplate(
19
+ * 'Current time: ${new Date().toLocaleString()}'
20
+ * );
21
+ * ```
22
+ */
23
+ /**
24
+ * 由 `copilot.restartAgent()` 在 `processTemplate()` 内部抛出的哨兵错误。
25
+ * 调用方(如 DigitalHuman._sendViaText)捕获此信号后触发 agent 会话重启。
26
+ */
27
+ export declare class RestartAgentSignal {
28
+ readonly promptFile: string | null | undefined;
29
+ readonly tools: string[] | undefined;
30
+ readonly options: Record<string, unknown> | undefined;
31
+ /** 便于跨 iframe 传递时识别此信号类型 */
32
+ readonly isRestartAgentSignal = true;
33
+ /**
34
+ * @param promptFile - 新会话要加载的配置文件 URL 或路径(null/undefined 表示使用默认)
35
+ * @param tools - 新会话启用的工具分类列表(undefined 表示继承)
36
+ * @param options - 高级重启选项(minigameSlot / frameOptions 等)
37
+ */
38
+ constructor(promptFile?: string | null, tools?: string[], options?: Record<string, unknown>);
39
+ }
40
+ /** 工具代理路由配置 */
41
+ export interface ToolProxyRoute {
42
+ /** 目标 agent 名称 */
43
+ agent: string;
44
+ /** 可选:任务描述 */
45
+ task?: string;
46
+ }
47
+ /** SandboxToolEnv 构造选项 */
48
+ export interface SandboxToolEnvOptions {
49
+ /** 文件操作工作空间名(对应 personalPageStore 的 workspace 参数) */
50
+ workspace?: string;
51
+ /** 只读回退目录(挂载的外部公开文件夹) */
52
+ mountFolder?: unknown;
53
+ /** 启用的 CopilotTools 分类(默认 ['fileOps', 'execute']) */
54
+ enabledCategories?: string[];
55
+ /** 远程 agent 名称(设置后所有工具调用委托给该 agent) */
56
+ remoteAgent?: string;
57
+ /** 远程模式下授权的工具分类列表 */
58
+ categories?: string[];
59
+ /** 工具代理路由配置 */
60
+ toolProxy?: {
61
+ /** 按函数名代理:`{ 'read_file': { agent: 'fileAgent' } }` */
62
+ functions?: Record<string, ToolProxyRoute>;
63
+ /** 按分类代理:`{ 'fileOps': { agent: 'fileAgent' } }` */
64
+ categories?: Record<string, ToolProxyRoute>;
65
+ };
66
+ /** 关联的 ChatSession(允许工具通过 config._session 访问) */
67
+ session?: AgentSessionRef;
68
+ }
69
+ /** ChatSession 最小接口(避免循环引用) */
70
+ interface AgentSessionRef {
71
+ name?: string;
72
+ workspace?: string;
73
+ _restartSignal?: unknown;
74
+ sandbox?: unknown;
75
+ [key: string]: unknown;
76
+ }
77
+ /** SDK 最小接口 */
78
+ interface SDKRef {
79
+ copilotTools?: {
80
+ execute: (name: string, args: unknown, config: unknown) => Promise<unknown>;
81
+ getToolDefinitions: (categories: string[]) => unknown[];
82
+ _fnNameToCategory?: Record<string, string>;
83
+ _registry?: Record<string, {
84
+ disableAutoProxy?: boolean;
85
+ }>;
86
+ };
87
+ agentRouter?: {
88
+ hasAgent: (name: string) => boolean;
89
+ waitForAgent: (name: string) => Promise<void>;
90
+ submitTask: (name: string, payload: unknown) => Promise<unknown>;
91
+ };
92
+ }
93
+ declare class SandboxToolEnv {
94
+ readonly sdk: SDKRef;
95
+ workspace: string;
96
+ mountFolder: unknown;
97
+ enabledCategories: string[];
98
+ session: AgentSessionRef | null;
99
+ remoteAgent: string | null;
100
+ categories: string[];
101
+ _activePromptFile: string | null;
102
+ _templateSourceFile: string | null;
103
+ private _customAPIs;
104
+ private _copilotProxy;
105
+ private _toolProxy;
106
+ private _cachedDefinitions;
107
+ constructor(sdk: SDKRef, options?: SandboxToolEnvOptions);
108
+ /**
109
+ * copilot 代理对象:通过属性访问(如 `copilot.read_file(...)`)调用任意工具。
110
+ * 解析顺序:自定义 API → 工具代理(toolProxy)→ CopilotTools 内置工具。
111
+ */
112
+ get copilot(): Record<string, (...args: unknown[]) => Promise<string>>;
113
+ /**
114
+ * 注册自定义可调用 API(优先于同名 CopilotTools 工具)。
115
+ * 注册后 `copilot.myTool(args)` 将直接调用此函数。
116
+ *
117
+ * @param name - 工具/函数名称
118
+ * @param fn - 异步回调函数 `(...args) => result`
119
+ */
120
+ registerAPI(name: string, fn: (...args: unknown[]) => Promise<unknown>): void;
121
+ /**
122
+ * 执行指定工具。
123
+ * - 远程 agent 模式:委托给 remoteAgent
124
+ * - 自定义 API:直接调用
125
+ * - 工具代理:通过 AgentRouter 路由到远程 agent
126
+ * - 内置工具:调用 sdk.copilotTools.execute
127
+ *
128
+ * @param fnName - 工具/函数名称
129
+ * @param fnArgs - 参数对象
130
+ * @param extraConfig - 附加配置(如 { _session })
131
+ */
132
+ execute(fnName: string, fnArgs: unknown, extraConfig?: Record<string, unknown>): Promise<unknown>;
133
+ /**
134
+ * 获取已启用分类的 OpenAI 格式工具定义。
135
+ * 远程 agent 模式下从远端获取(带缓存)。
136
+ *
137
+ * @param forceRefresh - 是否强制刷新远程缓存(默认 false)
138
+ */
139
+ getToolDefinitions(forceRefresh?: boolean): Promise<unknown[]> | unknown[];
140
+ /** 检查沙箱是否可用(远程模式下检查 agent 是否已连接)。 */
141
+ isAvailable(): boolean;
142
+ /** 从远程 agent 获取所有可用工具分类列表。 */
143
+ getCategories(): Promise<unknown>;
144
+ /**
145
+ * 批量顺序执行工具调用,收集所有结果。
146
+ *
147
+ * @param calls - 工具调用列表 `[{ tool, args }]`
148
+ */
149
+ executeBatch(calls?: Array<{
150
+ tool: string;
151
+ args?: unknown;
152
+ }>): Promise<Array<{
153
+ tool: string;
154
+ success: boolean;
155
+ result?: unknown;
156
+ error?: string;
157
+ }>>;
158
+ /** 清除远程工具定义缓存。 */
159
+ clearCache(): void;
160
+ /**
161
+ * 在沙箱上下文中运行任意 async JavaScript 代码。
162
+ * 代码可访问 `copilot` 代理和 `context` 中的所有键。
163
+ *
164
+ * @param code - 要执行的 JavaScript 代码字符串
165
+ * @param context - 注入到执行上下文的变量映射
166
+ */
167
+ runCode(code: string, context?: Record<string, unknown>): Promise<unknown>;
168
+ /**
169
+ * 展开文本中的 `${...}` 模板表达式。
170
+ * 表达式可使用 `copilot` 代理和 `await`。
171
+ * 支持最多 3 层嵌套递归展开。
172
+ * 表达式执行出错时保留原始 `${...}` 标记不变。
173
+ *
174
+ * 示例:
175
+ * ```ts
176
+ * const result = await sandbox.processTemplate(
177
+ * 'Notes: ${await copilot.read_file("notes.md", 1, 50)}'
178
+ * );
179
+ * ```
180
+ *
181
+ * @param text - 包含 `${...}` 表达式的模板字符串
182
+ * @param _depth - 内部递归深度计数器(请勿手动传入)
183
+ */
184
+ processTemplate(text: string, _depth?: number): Promise<string>;
185
+ /** @private 解析函数名对应的工具代理路由。 */
186
+ private _resolveToolProxy;
187
+ /** @private 通过 AgentRouter 将工具调用代理给远程 agent(绕过 LLM)。 */
188
+ private _executeViaProxy;
189
+ /** @private 从远程 agent 获取工具定义(带缓存)。 */
190
+ private _getRemoteToolDefinitions;
191
+ /** @private 在远程 agent 模式下执行工具调用。 */
192
+ private _executeRemote;
193
+ /** @private 向远程 agent 提交任务(via AgentRouter.submitTask)。 */
194
+ private _submitRemoteTask;
195
+ /** @private 将任意工具执行结果规范化为字符串。 */
196
+ private _normalizeToolResult;
197
+ /** @private 构建 runCode 的执行上下文(注入 copilot 代理和 context 键)。 */
198
+ private _createRunCodeContext;
199
+ /** @private 将代码包装为 AsyncFunction(优先尝试表达式形式,回退语句形式)。 */
200
+ private _createCodeRunner;
201
+ /** @private 检查字符串是否为合法 JS 标识符(用于安全注入执行上下文)。 */
202
+ private _isValidIdentifier;
203
+ /**
204
+ * @private 构建 copilot Proxy——将属性访问映射到工具调用。
205
+ * 内置常用工具(read_file / list_dir 等)的位置参数自动转换为命名参数。
206
+ */
207
+ private _buildProxy;
208
+ }
209
+ export default SandboxToolEnv;
210
+ //# sourceMappingURL=SandboxToolEnv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SandboxToolEnv.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/SandboxToolEnv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,272 @@
1
+ /**
2
+ * AudioEngine — browser audio playback & caching with 3-tier storage.
3
+ *
4
+ * Cache tiers: Memory (Blob URL + AudioBuffer) → IndexedDB → Network TTS
5
+ *
6
+ * 工具函数(常量、IndexedDB、MIDI、超时估算、缓存键)已拆分至 AudioEngine.utils.js。
7
+ */
8
+ /** 播放回调集合(play / _playAudioBuffer / _playFromUrl / _playMidiSequence 共用) */
9
+ interface AEPlayCallbacks {
10
+ onEnd?: (() => void) | null;
11
+ onStart?: (() => void) | null;
12
+ onError?: ((err?: unknown) => void) | null;
13
+ generation: number;
14
+ text?: string;
15
+ refreshSafetyTimeoutFromMetadata?: boolean;
16
+ }
17
+ export default class AudioEngine {
18
+ options: Record<string, unknown>;
19
+ _audioContext: AudioContext | null;
20
+ _resumePromise: Promise<void> | null;
21
+ _outputGainNode: GainNode | null;
22
+ _outputGainContext: AudioContext | null;
23
+ _outputVolume: number;
24
+ _blobUrlCache: Map<string, string>;
25
+ _urlCache: Map<string, {
26
+ url: string | null;
27
+ status: string;
28
+ [key: string]: unknown;
29
+ }>;
30
+ _pendingLoads: Map<string, Promise<string | null>>;
31
+ _audioBufferCache: Map<string, AudioBuffer>;
32
+ _midiSequenceCache: Map<string, Record<string, unknown>>;
33
+ _sourceNode: AudioBufferSourceNode | null;
34
+ _audioElement: HTMLAudioElement | null;
35
+ _pooledAudio: HTMLAudioElement | null;
36
+ _urlPlaybackToken: number;
37
+ _playGeneration: number;
38
+ _safetyTimeoutId: ReturnType<typeof setTimeout> | null;
39
+ _midiNodes: Set<unknown>;
40
+ _midiEndTimerId: ReturnType<typeof setTimeout> | null;
41
+ _persistentQueue: Array<Record<string, unknown>>;
42
+ _persistentRunning: boolean;
43
+ _persistentCancelled: boolean;
44
+ _persistentTimerId: ReturnType<typeof setTimeout> | null;
45
+ [key: string]: unknown;
46
+ constructor(options?: Record<string, unknown>);
47
+ static getShared(options?: Record<string, unknown>): AudioEngine;
48
+ configure(options?: Record<string, unknown>): this;
49
+ setVolume(volume: unknown): this;
50
+ getVolume(): number;
51
+ isSupported(): boolean;
52
+ _getAudioContextCtor(): typeof AudioContext | null;
53
+ getContext(options?: Record<string, unknown>): AudioContext;
54
+ getOutputNode(options?: Record<string, unknown>): GainNode;
55
+ getDestination(options?: Record<string, unknown>): GainNode;
56
+ resume(options?: Record<string, unknown>): Promise<AudioContext>;
57
+ /**
58
+ * Check whether the AudioContext is in a usable (running) state.
59
+ * Returns false if context hasn't been created or is suspended/closed.
60
+ */
61
+ isContextRunning(): boolean;
62
+ bindUserGesture(target: (EventTarget & {
63
+ addEventListener?: unknown;
64
+ removeEventListener?: unknown;
65
+ }) | null, options?: Record<string, unknown>): () => void;
66
+ /**
67
+ * Build a deterministic cache key from text + speech params.
68
+ */
69
+ buildCacheKey(text: string, options?: Record<string, unknown>): string;
70
+ /**
71
+ * Get a cached Blob URL or CDN URL (synchronous, memory only).
72
+ * @param {string} text
73
+ * @param {object} [options] speech params
74
+ * @returns {string|null}
75
+ */
76
+ getCachedUrl(text: string, options?: Record<string, unknown>): string | null;
77
+ /**
78
+ * Get a pre-decoded AudioBuffer (synchronous, memory only).
79
+ */
80
+ getAudioBuffer(text: string, options?: Record<string, unknown>): AudioBuffer | null;
81
+ /**
82
+ * Get a normalized cached MIDI sequence (synchronous, memory only).
83
+ */
84
+ getMidiSequence(text: string, options?: Record<string, unknown>): Record<string, unknown> | null;
85
+ _cacheAudioBlob(cacheKey: string, blob: unknown, options?: Record<string, unknown>): string | null;
86
+ _cacheAudioUrl(cacheKey: string, url: string, options?: Record<string, unknown>): string | null;
87
+ _cacheAudioSource(cacheKey: string, source: unknown, options?: Record<string, unknown>): string | null;
88
+ _cacheMidiSequence(cacheKey: string, sequence: unknown, options?: Record<string, unknown>): Record<string, unknown> | null;
89
+ /**
90
+ * Store an externally-obtained audio URL in the cache and
91
+ * asynchronously download + persist its Blob to IndexedDB.
92
+ */
93
+ set(text: string, source: unknown, options?: Record<string, unknown>): unknown;
94
+ setUrl(text: string, url: string, options?: Record<string, unknown>): unknown;
95
+ setAudioFile(text: string, file: unknown, options?: Record<string, unknown>): unknown;
96
+ setAudioData(text: string, data: unknown, options?: Record<string, unknown>): unknown;
97
+ setMidiSequence(text: string, sequence: unknown, options?: Record<string, unknown>): unknown;
98
+ /**
99
+ * Preload a single text → audio entry through three tiers:
100
+ * memory Blob URL → IndexedDB → network TTS API
101
+ *
102
+ * @param {string} text
103
+ * @param {object} [options] speech params
104
+ * @param {function} [options.fetchAudioUrl] async (text, params) => url — custom TTS fetcher
105
+ * @returns {Promise<string|null>} playable URL
106
+ */
107
+ preload(text: string, options?: Record<string, unknown>): Promise<string | null>;
108
+ /**
109
+ * Batch-preload multiple items with concurrency control.
110
+ * @param {Array<string|{text:string, options?:object}>} items
111
+ * @param {number} [concurrency=3]
112
+ */
113
+ preloadBatch(items: Array<string | {
114
+ text: string;
115
+ options?: Record<string, unknown>;
116
+ }>, concurrency?: number): Promise<void>;
117
+ /**
118
+ * Background persistent preload queue with automatic retry.
119
+ */
120
+ preloadPersistent(items: Array<string | {
121
+ text: string;
122
+ options?: Record<string, unknown>;
123
+ }>, concurrency?: number, retryDelay?: number, batchDelay?: number): Promise<void>;
124
+ cancelPreload(): void;
125
+ /**
126
+ * Warm up memory caches from IndexedDB at app startup.
127
+ * @returns {Promise<Array<{text:string, options?:object}>>} items not found in IndexedDB
128
+ */
129
+ warmupFromDB(items: Array<string | {
130
+ text: string;
131
+ options?: Record<string, unknown>;
132
+ }>): Promise<Array<{
133
+ text: string;
134
+ options?: Record<string, unknown>;
135
+ }>>;
136
+ /**
137
+ * Decode a Blob into an AudioBuffer and cache it.
138
+ * On mobile the AudioContext may be suspended; decodeAudioData still works
139
+ * in most browsers but we guard against failures gracefully.
140
+ * @private
141
+ */
142
+ _decodeToBuffer(cacheKey: string, blob: Blob): Promise<void>;
143
+ /**
144
+ * Play audio for the given text, using the best available cached source.
145
+ *
146
+ * Resolution order: pre-decoded AudioBuffer → Blob/CDN URL → skip.
147
+ *
148
+ * On mobile, if the AudioContext is suspended (no user gesture), the method
149
+ * attempts `resume()` but does NOT block indefinitely. Instead it fires
150
+ * `onEnd` after a reasonable timeout derived from the AudioBuffer duration
151
+ * or estimated from text length.
152
+ *
153
+ * @param {string} text
154
+ * @param {object} [options]
155
+ * @param {function} [options.onEnd]
156
+ * @param {function} [options.onStart]
157
+ * @param {function} [options.onError]
158
+ * @param {number} [options.timeout] explicit safety timeout override (ms)
159
+ * @returns {{ type: string }|null} playback descriptor or null if nothing to play
160
+ */
161
+ play(text: string, options?: Record<string, unknown>): {
162
+ type: string;
163
+ } | null;
164
+ /**
165
+ * Play an AudioBuffer via Web Audio API.
166
+ * Attempts resume(); if the context stays suspended after a short wait,
167
+ * fires onEnd via the safety timeout rather than hanging forever.
168
+ * @private
169
+ */
170
+ _playAudioBuffer(audioBuffer: AudioBuffer, { onEnd, onStart, onError, generation }: AEPlayCallbacks): Promise<void>;
171
+ /**
172
+ * Get the shared pooled HTMLAudioElement used by `_playFromUrl`.
173
+ *
174
+ * WHY POOLED: On mobile WebViews (especially WeChat X5 / iOS Safari),
175
+ * each freshly-created `new Audio()` element requires its own user-gesture
176
+ * unlock. If we kept creating new elements, only the very first one
177
+ * (played during a user gesture) would be audible — subsequent cache-hit
178
+ * plays would silently fail while still resolving their promises,
179
+ * because browsers silently drop autoplay on a never-unlocked element.
180
+ *
181
+ * Reusing a single persistent element means only one unlock is required
182
+ * (via `bindUserGesture()` or the first natural play-during-gesture), and
183
+ * every later cache-hit play on the same element is permitted.
184
+ *
185
+ * The element is attached to `<body>` (hidden) because some mobile
186
+ * browsers require attachment for `.play()` to dispatch correctly.
187
+ *
188
+ * @private
189
+ */
190
+ _getPooledAudioElement(): HTMLAudioElement;
191
+ /**
192
+ * Play from a URL using a **pooled** HTMLAudioElement.
193
+ * On iOS/mobile, play() may reject if not called during a user gesture.
194
+ * In that case we fire onEnd immediately so callers are never left hanging.
195
+ * @private
196
+ */
197
+ _playFromUrl(url: string, { onEnd, onStart, onError, generation, text, refreshSafetyTimeoutFromMetadata }: AEPlayCallbacks): void;
198
+ /**
199
+ * Play a cached MIDI-like sequence using simple Web Audio oscillators.
200
+ * @private
201
+ */
202
+ _playMidiSequence(sequence: Record<string, unknown>, { onEnd, onStart, onError, generation }: AEPlayCallbacks): Promise<void>;
203
+ /**
204
+ * Stop any audio currently being played through this engine.
205
+ */
206
+ stopPlayback(): void;
207
+ /** @private — generation counter for speak(); independent of _playGeneration */
208
+ _speakGeneration: number;
209
+ /** @private — safety timeout for the SDK playKeepworkAudio fallback path */
210
+ _speakTimeoutId: ReturnType<typeof setTimeout> | null;
211
+ /** @private */
212
+ _clearSpeakTimeout(): void;
213
+ /**
214
+ * Play TTS audio for `text`, trying cached AudioEngine playback first,
215
+ * then falling back to the SDK `playKeepworkAudio` path.
216
+ *
217
+ * Handles generation-based cancellation so that calling `stopSpeak()` at
218
+ * any point safely invalidates in-flight async SDK callbacks.
219
+ *
220
+ * @param {string} text
221
+ * @param {object} [options]
222
+ * @param {function} [options.onEnd]
223
+ * @param {function} [options.onStart]
224
+ * @param {function} [options.onError]
225
+ * @returns {{ type: string }|null}
226
+ */
227
+ speak(text: string, options?: Record<string, unknown>): {
228
+ type: string;
229
+ } | null;
230
+ /**
231
+ * Stop all speech audio: engine playback, SDK-managed audio, and fallback keepwork-audio element.
232
+ * Also invalidates any in-flight speak() callbacks via generation counter.
233
+ */
234
+ stopSpeak(): void;
235
+ /** @private */
236
+ _stopCurrentAudio(): void;
237
+ /** @private */
238
+ _setSafetyTimeout(safeOnEnd: (() => void) | null | undefined, timeoutMs: number, text: string): void;
239
+ /** @private */
240
+ _clearSafetyTimeout(): void;
241
+ /** @private */
242
+ _clearMidiEndTimer(): void;
243
+ /**
244
+ * Estimate audio playback duration from text length (ms).
245
+ * Useful for setting timeouts when actual audio duration is unknown.
246
+ */
247
+ static estimateDuration(text: string): number;
248
+ /**
249
+ * Clear all in-memory caches (does NOT clear IndexedDB).
250
+ */
251
+ clearCache(): void;
252
+ /**
253
+ * Clear both in-memory caches and IndexedDB persistent cache.
254
+ */
255
+ clearAll(): Promise<void>;
256
+ /**
257
+ * Get cache statistics (for debugging).
258
+ */
259
+ getStats(): {
260
+ total: number;
261
+ ready: number;
262
+ loading: number;
263
+ error: number;
264
+ blobCached: number;
265
+ audioBufferDecoded: number;
266
+ midiCached: number;
267
+ persistentQueueSize: number;
268
+ persistentRunning: boolean;
269
+ };
270
+ }
271
+ export {};
272
+ //# sourceMappingURL=AudioEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioEngine.d.ts","sourceRoot":"","sources":["../../../../src/audio/AudioEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * AudioEngine.utils.js — AudioEngine 内部工具层
3
+ *
4
+ * 包含:
5
+ * - 常量(DB 名称、语音参数键、超时配置、音符映射等)
6
+ * - IndexedDB 辅助函数(_openDB / _getFromDB / _saveToDB / _clearDB)
7
+ * - Blob/ArrayBuffer 类型检查工具
8
+ * - MIDI 工具(_midiToFrequency / _noteNameToMidi / _normalizeMidiSequence 等)
9
+ * - 音频超时估算(_estimateDurationFromText / _timeoutFromBuffer 等)
10
+ * - 缓存键构建(_buildCacheKey / _extractSpeechParams)
11
+ *
12
+ * 供 AudioEngine.js 主类导入使用,不直接暴露给外部。
13
+ */
14
+ declare const DB_NAME = "keepwork-audio-cache";
15
+ declare const STORE_NAME = "audio-blobs";
16
+ declare const DB_VERSION = 1;
17
+ /** Speech parameter keys that affect audio output (sorted for deterministic serialization) */
18
+ declare const SPEECH_PARAM_KEYS: string[];
19
+ /** Estimated average reading speed: characters per second for CJK text */
20
+ declare const CJK_CHARS_PER_SECOND = 4.5;
21
+ /** Estimated average reading speed: words per second for Latin text */
22
+ declare const LATIN_WORDS_PER_SECOND = 2.5;
23
+ /** Minimum timeout in ms for text-length-based estimates */
24
+ declare const MIN_TEXT_TIMEOUT = 2000;
25
+ /** Maximum timeout in ms for text-length-based estimates */
26
+ declare const MAX_TEXT_TIMEOUT = 60000;
27
+ /** Extra padding added to estimated duration (ms) */
28
+ declare const TIMEOUT_PADDING = 1500;
29
+ /** Minimum timeout for URL/fallback playback when actual duration is unknown */
30
+ declare const MIN_UNKNOWN_AUDIO_TIMEOUT = 5000;
31
+ /** Conservative multiplier for estimated durations when metadata is unavailable */
32
+ declare const UNKNOWN_AUDIO_TIMEOUT_MULTIPLIER = 1.8;
33
+ /** Extra loading budget for SDK TTS fallback before audio playback begins */
34
+ declare const SPEAK_FALLBACK_LOAD_PADDING = 8000;
35
+ /** Maximum timeout for SDK TTS fallback including network loading */
36
+ declare const MAX_SPEAK_FALLBACK_TIMEOUT = 90000;
37
+ declare const AUDIO_RECORD_TYPE = "audioBlob";
38
+ declare const MIDI_RECORD_TYPE = "midiSequence";
39
+ declare const NOTE_NAME_TO_SEMITONE: Record<string, number>;
40
+ declare function _openDB(): Promise<IDBDatabase>;
41
+ declare function _getFromDB(cacheKey: string): Promise<unknown>;
42
+ declare function _saveToDB(cacheKey: string, blob: unknown): Promise<void>;
43
+ declare function _isBlob(value: unknown): value is Blob;
44
+ declare function _isArrayBuffer(value: unknown): value is ArrayBuffer;
45
+ declare function _isArrayBufferView(value: unknown): value is ArrayBufferView;
46
+ declare function _isAudioUrl(value: unknown): boolean;
47
+ declare function _createAudioBlobFromData(data: unknown, mimeType?: string): Blob | null;
48
+ declare function _getAudioSourceFromOptions(options: Record<string, unknown> | null | undefined): unknown;
49
+ declare function _getMidiSequenceFromOptions(options: Record<string, unknown> | null | undefined): unknown;
50
+ declare function _midiToFrequency(note: number): number;
51
+ declare function _noteNameToMidi(noteName: unknown): number | null;
52
+ declare function _normalizeMidiNoteValue(value: unknown): number | null;
53
+ declare function _normalizeMidiSequence(sequence: unknown, options?: Record<string, unknown>): Record<string, unknown> | null;
54
+ declare function _normalizeOutputVolume(value: unknown, fallback?: number): number;
55
+ declare function _clearDB(): Promise<void>;
56
+ declare function _extractSpeechParams(options: Record<string, unknown> | null | undefined): Record<string, unknown> | null;
57
+ declare function _buildCacheKey(text: string, options: Record<string, unknown> | null | undefined): string;
58
+ /**
59
+ * Estimate audio duration in ms from text content.
60
+ * Uses CJK character count or Latin word count as heuristic.
61
+ */
62
+ declare function _estimateDurationFromText(text: string): number;
63
+ /** Derive timeout from an AudioBuffer's actual duration. */
64
+ declare function _timeoutFromBuffer(audioBuffer: AudioBuffer | null | undefined): number | null;
65
+ /** Derive timeout from HTMLMediaElement metadata. */
66
+ declare function _timeoutFromMediaDuration(duration: number): number | null;
67
+ /** Conservative timeout when actual audio duration is not known. */
68
+ declare function _timeoutForUnknownAudio(text: string): number;
69
+ /** Conservative timeout for SDK-managed TTS playback (includes loading budget). */
70
+ declare function _timeoutForSpeakFallback(text: string): number;
71
+ export { DB_NAME, STORE_NAME, DB_VERSION, SPEECH_PARAM_KEYS, CJK_CHARS_PER_SECOND, LATIN_WORDS_PER_SECOND, MIN_TEXT_TIMEOUT, MAX_TEXT_TIMEOUT, TIMEOUT_PADDING, MIN_UNKNOWN_AUDIO_TIMEOUT, UNKNOWN_AUDIO_TIMEOUT_MULTIPLIER, SPEAK_FALLBACK_LOAD_PADDING, MAX_SPEAK_FALLBACK_TIMEOUT, AUDIO_RECORD_TYPE, MIDI_RECORD_TYPE, NOTE_NAME_TO_SEMITONE, _openDB, _getFromDB, _saveToDB, _clearDB, _isBlob, _isArrayBuffer, _isArrayBufferView, _isAudioUrl, _createAudioBlobFromData, _getAudioSourceFromOptions, _getMidiSequenceFromOptions, _midiToFrequency, _noteNameToMidi, _normalizeMidiNoteValue, _normalizeMidiSequence, _normalizeOutputVolume, _extractSpeechParams, _buildCacheKey, _estimateDurationFromText, _timeoutFromBuffer, _timeoutFromMediaDuration, _timeoutForUnknownAudio, _timeoutForSpeakFallback, };
72
+ //# sourceMappingURL=AudioEngine.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioEngine.utils.d.ts","sourceRoot":"","sources":["../../../../src/audio/AudioEngine.utils.ts"],"names":[],"mappings":"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"}