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.
- package/README.md +21 -0
- package/dist-npm/keepwork-sdk.js +37514 -0
- package/dist-npm/keepwork-sdk.js.map +1 -0
- package/dist-npm/md5-CZ0vz1_S.js +240 -0
- package/dist-npm/md5-CZ0vz1_S.js.map +1 -0
- package/dist-npm/types/index.d.ts +42 -0
- package/dist-npm/types/index.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIChat.core.d.ts +218 -0
- package/dist-npm/types/src/ai-chat/AIChat.core.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIChat.d.ts +18 -0
- package/dist-npm/types/src/ai-chat/AIChat.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIChat.session.d.ts +201 -0
- package/dist-npm/types/src/ai-chat/AIChat.session.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.base.d.ts +297 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.base.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.d.ts +15 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.media.d.ts +208 -0
- package/dist-npm/types/src/ai-chat/AIGenerators.media.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/ChildSessionMixin.d.ts +153 -0
- package/dist-npm/types/src/ai-chat/ChildSessionMixin.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/CopilotTools.d.ts +150 -0
- package/dist-npm/types/src/ai-chat/CopilotTools.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/MqttManager.d.ts +123 -0
- package/dist-npm/types/src/ai-chat/MqttManager.d.ts.map +1 -0
- package/dist-npm/types/src/ai-chat/SandboxToolEnv.d.ts +210 -0
- package/dist-npm/types/src/ai-chat/SandboxToolEnv.d.ts.map +1 -0
- package/dist-npm/types/src/audio/AudioEngine.d.ts +272 -0
- package/dist-npm/types/src/audio/AudioEngine.d.ts.map +1 -0
- package/dist-npm/types/src/audio/AudioEngine.utils.d.ts +72 -0
- package/dist-npm/types/src/audio/AudioEngine.utils.d.ts.map +1 -0
- package/dist-npm/types/src/audio/Speech.d.ts +247 -0
- package/dist-npm/types/src/audio/Speech.d.ts.map +1 -0
- package/dist-npm/types/src/core/AgentConfig.d.ts +104 -0
- package/dist-npm/types/src/core/AgentConfig.d.ts.map +1 -0
- package/dist-npm/types/src/core/AgentRouter.d.ts +342 -0
- package/dist-npm/types/src/core/AgentRouter.d.ts.map +1 -0
- package/dist-npm/types/src/core/NPL.d.ts +251 -0
- package/dist-npm/types/src/core/NPL.d.ts.map +1 -0
- package/dist-npm/types/src/core/RemoteLog.d.ts +132 -0
- package/dist-npm/types/src/core/RemoteLog.d.ts.map +1 -0
- package/dist-npm/types/src/core/keepworkSDK.core.d.ts +84 -0
- package/dist-npm/types/src/core/keepworkSDK.core.d.ts.map +1 -0
- package/dist-npm/types/src/core/keepworkSDK.d.ts +129 -0
- package/dist-npm/types/src/core/keepworkSDK.d.ts.map +1 -0
- package/dist-npm/types/src/core/keepworkSDK.pages.d.ts +101 -0
- package/dist-npm/types/src/core/keepworkSDK.pages.d.ts.map +1 -0
- package/dist-npm/types/src/core/keepworkSDK.utils.d.ts +40 -0
- package/dist-npm/types/src/core/keepworkSDK.utils.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHuman.d.ts +1316 -0
- package/dist-npm/types/src/digital-human/DigitalHuman.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanBridge.d.ts +54 -0
- package/dist-npm/types/src/digital-human/DigitalHumanBridge.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanConfig.d.ts +104 -0
- package/dist-npm/types/src/digital-human/DigitalHumanConfig.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanFrame.d.ts +390 -0
- package/dist-npm/types/src/digital-human/DigitalHumanFrame.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanFrameMessages.d.ts +59 -0
- package/dist-npm/types/src/digital-human/DigitalHumanFrameMessages.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanSubtitleOverlay.d.ts +114 -0
- package/dist-npm/types/src/digital-human/DigitalHumanSubtitleOverlay.d.ts.map +1 -0
- package/dist-npm/types/src/digital-human/DigitalHumanUtils.d.ts +53 -0
- package/dist-npm/types/src/digital-human/DigitalHumanUtils.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTC.constants.d.ts +65 -0
- package/dist-npm/types/src/rtc/AIChatRTC.constants.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTC.d.ts +91 -0
- package/dist-npm/types/src/rtc/AIChatRTC.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts +268 -0
- package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.backends.d.ts +232 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.backends.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.core.d.ts +92 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.core.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts +15 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts +127 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/LocalRTC.d.ts +91 -0
- package/dist-npm/types/src/rtc/LocalRTC.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/SpeechRTC.d.ts +156 -0
- package/dist-npm/types/src/rtc/SpeechRTC.d.ts.map +1 -0
- package/dist-npm/types/src/rtc/SpeechRTC.transport.d.ts +191 -0
- package/dist-npm/types/src/rtc/SpeechRTC.transport.d.ts.map +1 -0
- package/dist-npm/types/src/store/CloudDrive.d.ts +140 -0
- package/dist-npm/types/src/store/CloudDrive.d.ts.map +1 -0
- package/dist-npm/types/src/store/LocalStorageUtil.d.ts +136 -0
- package/dist-npm/types/src/store/LocalStorageUtil.d.ts.map +1 -0
- package/dist-npm/types/src/store/PersonalPageStore.base.d.ts +267 -0
- package/dist-npm/types/src/store/PersonalPageStore.base.d.ts.map +1 -0
- package/dist-npm/types/src/store/PersonalPageStore.d.ts +13 -0
- package/dist-npm/types/src/store/PersonalPageStore.d.ts.map +1 -0
- package/dist-npm/types/src/store/PersonalPageStore.data.d.ts +198 -0
- package/dist-npm/types/src/store/PersonalPageStore.data.d.ts.map +1 -0
- package/dist-npm/types/src/store/PersonalPageStore.sync.d.ts +171 -0
- package/dist-npm/types/src/store/PersonalPageStore.sync.d.ts.map +1 -0
- package/dist-npm/types/src/store/PersonalPageStore.types.d.ts +92 -0
- package/dist-npm/types/src/store/PersonalPageStore.types.d.ts.map +1 -0
- package/dist-npm/types/src/store/YMLParser.d.ts +96 -0
- package/dist-npm/types/src/store/YMLParser.d.ts.map +1 -0
- package/dist-npm/types/src/tools/AgentTool.d.ts +110 -0
- package/dist-npm/types/src/tools/AgentTool.d.ts.map +1 -0
- package/dist-npm/types/src/tools/AppTools.d.ts +122 -0
- package/dist-npm/types/src/tools/AppTools.d.ts.map +1 -0
- package/dist-npm/types/src/tools/ExecuteTool.d.ts +96 -0
- package/dist-npm/types/src/tools/ExecuteTool.d.ts.map +1 -0
- package/dist-npm/types/src/tools/FileTools.d.ts +77 -0
- package/dist-npm/types/src/tools/FileTools.d.ts.map +1 -0
- package/dist-npm/types/src/tools/MinigameTools.d.ts +234 -0
- package/dist-npm/types/src/tools/MinigameTools.d.ts.map +1 -0
- package/dist-npm/types/src/tools/MqttTool.d.ts +53 -0
- package/dist-npm/types/src/tools/MqttTool.d.ts.map +1 -0
- package/dist-npm/types/src/tools/PersonalPageTool.d.ts +57 -0
- package/dist-npm/types/src/tools/PersonalPageTool.d.ts.map +1 -0
- package/dist-npm/types/src/tools/SummarizeTool.d.ts +279 -0
- package/dist-npm/types/src/tools/SummarizeTool.d.ts.map +1 -0
- package/dist-npm/types/src/tools/WebTool.d.ts +106 -0
- package/dist-npm/types/src/tools/WebTool.d.ts.map +1 -0
- package/dist-npm/types/src/types/common.d.ts +164 -0
- package/dist-npm/types/src/types/common.d.ts.map +1 -0
- package/dist-npm/types/src/ui/LocalAPIKeySettings.d.ts +229 -0
- package/dist-npm/types/src/ui/LocalAPIKeySettings.d.ts.map +1 -0
- package/dist-npm/types/src/ui/LoginWindow.d.ts +163 -0
- package/dist-npm/types/src/ui/LoginWindow.d.ts.map +1 -0
- package/dist-npm/types/src/ui/ProfileWindow.d.ts +75 -0
- package/dist-npm/types/src/ui/ProfileWindow.d.ts.map +1 -0
- package/dist-npm/types/src/ui/VerifyHuman.d.ts +23 -0
- package/dist-npm/types/src/ui/VerifyHuman.d.ts.map +1 -0
- package/dist-npm/types/src/ui/WorkspaceViewer.d.ts +184 -0
- package/dist-npm/types/src/ui/WorkspaceViewer.d.ts.map +1 -0
- package/dist-npm/types/src/user/SocialFriends.d.ts +173 -0
- package/dist-npm/types/src/user/SocialFriends.d.ts.map +1 -0
- package/dist-npm/types/src/user/UserWorks.d.ts +187 -0
- package/dist-npm/types/src/user/UserWorks.d.ts.map +1 -0
- package/dist-npm/types/src/utils/ImageUtils.d.ts +107 -0
- package/dist-npm/types/src/utils/ImageUtils.d.ts.map +1 -0
- package/dist-npm/types/src/utils/SDKLogger.d.ts +111 -0
- package/dist-npm/types/src/utils/SDKLogger.d.ts.map +1 -0
- package/dist-npm/types/src/utils/translation.d.ts +95 -0
- package/dist-npm/types/src/utils/translation.d.ts.map +1 -0
- package/dist-npm/types/src/wechat/WxAuth.d.ts +126 -0
- package/dist-npm/types/src/wechat/WxAuth.d.ts.map +1 -0
- package/dist-npm/types/src/wechat/WxLaunchApp.d.ts +96 -0
- package/dist-npm/types/src/wechat/WxLaunchApp.d.ts.map +1 -0
- package/dist-npm/types/src/wechat/WxUtils.d.ts +145 -0
- package/dist-npm/types/src/wechat/WxUtils.d.ts.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,1316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigitalHuman — Standalone ES module for virtual character rendering and AI session management.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Avatar rendering: Video / Live2D / WebP with lip sync
|
|
6
|
+
* 2. AI Chat Session: Full lifecycle via KeepworkSDK's aiChat.createSession()
|
|
7
|
+
* 3. Voice Chat: Real-time voice via AIChatRTC SDK class
|
|
8
|
+
*
|
|
9
|
+
* NOT responsible for: progress bar, game scoring, quick replies,
|
|
10
|
+
* history dropdown, AI toolbox sidebar, file upload UI, inner thoughts display.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import DigitalHuman from './libs/digitalhuman';
|
|
14
|
+
* const dh = new DigitalHuman({ sdk, container: document.getElementById('avatar-root') });
|
|
15
|
+
* await dh.initAvatar(videoActions);
|
|
16
|
+
* dh.on('message', ({ partialText }) => { ... });
|
|
17
|
+
* dh.on('bracketAction', ({ actionKey }) => dh.playAction(actionKey, 3));
|
|
18
|
+
* await dh.createSession({ system_prompt: '...', llm_model: 'keepwork-flash', tools: { fileOps: { enabled: true } } });
|
|
19
|
+
* await dh.send('Hello');
|
|
20
|
+
*
|
|
21
|
+
* initFromConfig (one-call setup from characterManager-style config):
|
|
22
|
+
* const dh = new DigitalHuman({ sdk, container });
|
|
23
|
+
* const info = await dh.initFromConfig({
|
|
24
|
+
* system_prompt: '你是一个友好的助手',
|
|
25
|
+
* llm_model: { model: 'keepwork-flash', temperature: 0.7, reasoning: false },
|
|
26
|
+
* videoActions: { '待机': { url: '...' }, '说话': { url: '...' } },
|
|
27
|
+
* bracketAction: { enabled: true, autoplay: true, duration: 3 },
|
|
28
|
+
* textToSpeech: { enabled: true, provider: 'speechRTC', voiceType: 'zh_female_cancan_mars_bigtts' },
|
|
29
|
+
* tools: { fileOps: { enabled: true, workspace: 'ws' }, web: { enabled: true } },
|
|
30
|
+
* avatar_only: false,
|
|
31
|
+
* });
|
|
32
|
+
* // bracketAction boolean => emit-only
|
|
33
|
+
* // bracketAction object => emit + optional autoplay
|
|
34
|
+
* // info = { session, config }
|
|
35
|
+
* // Full config (character, quick_replies, etc.) available via dh.characterConfig
|
|
36
|
+
*
|
|
37
|
+
* videoActions format (supports pipe-separated aliases):
|
|
38
|
+
* {
|
|
39
|
+
* '待机': { url: 'https://cdn.../model.model3.json' },
|
|
40
|
+
* 'talk': { url: 'https://cdn.../talk.mp4' },
|
|
41
|
+
* '高兴|happy': { url: 'https://cdn.../happy.mp4' },
|
|
42
|
+
* '难过|sad': { url: 'https://cdn.../sad.mp4' },
|
|
43
|
+
* }
|
|
44
|
+
* Built-in aliases (always available): you can specify either '待机' or 'idle' or '0' for the idle action,
|
|
45
|
+
* and '说话' or 'talk' or '1' for the talk action.
|
|
46
|
+
*
|
|
47
|
+
* playAction(actionKey, duration):
|
|
48
|
+
* dh.playAction('happy', 5); // play for 5s then back to idle
|
|
49
|
+
* dh.playAction('talk', -1); // play indefinitely
|
|
50
|
+
* dh.playAction(0); // switch to idle (via alias)
|
|
51
|
+
* Repeated calls with the same key reset the timer without restarting the action.
|
|
52
|
+
*
|
|
53
|
+
* loadConfig (one-call setup from a config URL, JSON string, or object):
|
|
54
|
+
* // Load from a .md file (YAML frontmatter = config, body = system_prompt):
|
|
55
|
+
* await dh.loadConfig('https://example.com/character.md');
|
|
56
|
+
* // Load from a .json or .yml URL:
|
|
57
|
+
* await dh.loadConfig('https://example.com/character.json');
|
|
58
|
+
* // Load from an inline JSON string:
|
|
59
|
+
* await dh.loadConfig('{"system_prompt":"Hi","llm_model":"keepwork-flash"}');
|
|
60
|
+
* // Load from a plain object (equivalent to initFromConfig):
|
|
61
|
+
* await dh.loadConfig({ system_prompt: 'Hi', llm_model: 'keepwork-flash' });
|
|
62
|
+
*
|
|
63
|
+
* Supported .md format (YAML frontmatter + markdown body as system_prompt):
|
|
64
|
+
* ---
|
|
65
|
+
* llm_model: keepwork-flash
|
|
66
|
+
* videoActions:
|
|
67
|
+
* 待机:
|
|
68
|
+
* url: "https://cdn.../model.model3.json"
|
|
69
|
+
* tools:
|
|
70
|
+
* fileOps:
|
|
71
|
+
* enabled: true
|
|
72
|
+
* workspace: myWorkspace
|
|
73
|
+
* bracketAction:
|
|
74
|
+
* enabled: true
|
|
75
|
+
* autoplay: true
|
|
76
|
+
* textToSpeech:
|
|
77
|
+
* enabled: true
|
|
78
|
+
* provider: speechRTC
|
|
79
|
+
* voiceType: zh_female_cancan_mars_bigtts
|
|
80
|
+
* voiceChat:
|
|
81
|
+
* appId: "..."
|
|
82
|
+
* ---
|
|
83
|
+
* 你是拉拉,一个友善的AI角色。请用简短、口语化的中文回复用户。
|
|
84
|
+
*/
|
|
85
|
+
type DHAny = any;
|
|
86
|
+
export default class DigitalHuman {
|
|
87
|
+
[key: string]: any;
|
|
88
|
+
/**
|
|
89
|
+
* @param {Object} options
|
|
90
|
+
* @param {Object} options.sdk - KeepworkSDK instance
|
|
91
|
+
* @param {HTMLElement} [options.container] - Container element for avatar rendering
|
|
92
|
+
* @param {Object} [options.config] - Initial configuration
|
|
93
|
+
*/
|
|
94
|
+
constructor({ sdk, container, config, subtitle }?: DHAny);
|
|
95
|
+
get on(): any;
|
|
96
|
+
get off(): any;
|
|
97
|
+
get emit(): any;
|
|
98
|
+
/**
|
|
99
|
+
* Register a slash command that can be intercepted by send().
|
|
100
|
+
* @param {string} name - Command name (without leading /)
|
|
101
|
+
* @param {Object} def
|
|
102
|
+
* @param {string} def.description - Short help text
|
|
103
|
+
* @param {boolean} [def.needsArg=true] - Whether the command requires an argument
|
|
104
|
+
* @param {function(string, Object):void|Promise<void>} def.handler - Receives (argString, thisDigitalHuman)
|
|
105
|
+
*/
|
|
106
|
+
registerCommand(name: DHAny, { description, needsArg, handler }: DHAny): void;
|
|
107
|
+
/**
|
|
108
|
+
* Unregister a slash command.
|
|
109
|
+
* @param {string} name
|
|
110
|
+
*/
|
|
111
|
+
unregisterCommand(name: DHAny): void;
|
|
112
|
+
/**
|
|
113
|
+
* List all registered slash commands.
|
|
114
|
+
* @returns {Array<{ name: string, description: string, needsArg: boolean }>}
|
|
115
|
+
*/
|
|
116
|
+
listCommands(): {
|
|
117
|
+
name: string;
|
|
118
|
+
description: any;
|
|
119
|
+
needsArg: any;
|
|
120
|
+
}[];
|
|
121
|
+
/**
|
|
122
|
+
* Try to dispatch a slash command from a user message string.
|
|
123
|
+
* @param {string} text
|
|
124
|
+
* @returns {{ handled: boolean, name?: string, result?: * }}
|
|
125
|
+
*/
|
|
126
|
+
tryCommand(text: DHAny): {
|
|
127
|
+
handled: boolean;
|
|
128
|
+
name?: undefined;
|
|
129
|
+
error?: undefined;
|
|
130
|
+
result?: undefined;
|
|
131
|
+
} | {
|
|
132
|
+
handled: boolean;
|
|
133
|
+
name: string;
|
|
134
|
+
error: string;
|
|
135
|
+
result?: undefined;
|
|
136
|
+
} | {
|
|
137
|
+
handled: boolean;
|
|
138
|
+
name: string;
|
|
139
|
+
result: any;
|
|
140
|
+
error?: undefined;
|
|
141
|
+
};
|
|
142
|
+
/** @private */
|
|
143
|
+
_registerBuiltinCommands(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Create the avatar DOM elements inside the container.
|
|
146
|
+
* @param {HTMLElement} [container] - Override container
|
|
147
|
+
*/
|
|
148
|
+
_createAvatarDOM(container?: DHAny): void;
|
|
149
|
+
setSubtitleConfig(config?: DHAny): any;
|
|
150
|
+
getSubtitleConfig(): any;
|
|
151
|
+
clearSubtitle(options?: DHAny): void;
|
|
152
|
+
showSubtitle(text: DHAny, options?: DHAny): void;
|
|
153
|
+
_getAudioEngine(): any;
|
|
154
|
+
_bindAudioResumeTarget(target: DHAny): void;
|
|
155
|
+
_clearAudioResumeBindings(): void;
|
|
156
|
+
static DEFAULT_VIDEO_ACTIONS: {
|
|
157
|
+
待机: {
|
|
158
|
+
url: string;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
static BUILTIN_ALIASES: DHAny;
|
|
162
|
+
/**
|
|
163
|
+
* Normalize videoActions: expand pipe-separated keys into individual entries
|
|
164
|
+
* and merge built-in aliases. Returns a new flat object.
|
|
165
|
+
* @param {Object} raw - e.g. { '待机|idle|0': { url }, '高兴|happy': { url } }
|
|
166
|
+
* @returns {Object} Normalized map keyed by every alias
|
|
167
|
+
*/
|
|
168
|
+
_normalizeVideoActions(raw: DHAny): any;
|
|
169
|
+
/**
|
|
170
|
+
* Resolve an action key through aliases to its config object.
|
|
171
|
+
* @param {string|number} key
|
|
172
|
+
* @returns {Object|undefined} The action config { url, ... }
|
|
173
|
+
*/
|
|
174
|
+
_resolveAction(key: DHAny): any;
|
|
175
|
+
/**
|
|
176
|
+
* Collect idle variant configs (idle2, idle3, …) from _videoActions.
|
|
177
|
+
* These are used for random idle animations when voice mode is off.
|
|
178
|
+
*/
|
|
179
|
+
_collectIdleVariants(): void;
|
|
180
|
+
/**
|
|
181
|
+
* Schedule a random idle variant to play after a debounce period.
|
|
182
|
+
* Called from switchToIdle() when conditions are met:
|
|
183
|
+
* - voice chat is NOT active, or DigitalHuman is inactive
|
|
184
|
+
* - there are idle variants available
|
|
185
|
+
* The main idle plays immediately; after DEEP_IDLE_DEBOUNCE_MS a random variant is picked.
|
|
186
|
+
* @param {number} [delayMs] - Override debounce duration (0 for immediate, e.g. on first load)
|
|
187
|
+
*/
|
|
188
|
+
_scheduleRandomIdle(delayMs?: DHAny): void;
|
|
189
|
+
/**
|
|
190
|
+
* Cancel any pending random idle scheduling.
|
|
191
|
+
*/
|
|
192
|
+
_cancelRandomIdle(): void;
|
|
193
|
+
/**
|
|
194
|
+
* Pick and play a random idle variant from the pool.
|
|
195
|
+
*/
|
|
196
|
+
_playRandomIdleVariant(): void;
|
|
197
|
+
/**
|
|
198
|
+
* Get all available actions as pipe-joined alias strings.
|
|
199
|
+
* Each entry is a string like 'idle|待机' or '写字|记录|writing'.
|
|
200
|
+
* Built-in alias keys are included for idle/talk entries.
|
|
201
|
+
* idle and talk entries (if present) are returned first.
|
|
202
|
+
* @returns {string[]}
|
|
203
|
+
*/
|
|
204
|
+
getActions(): string[];
|
|
205
|
+
/**
|
|
206
|
+
* Resolve normalized bracket-action options from request/session/config state.
|
|
207
|
+
* Boolean `true` enables event emission only; object form can also enable autoplay.
|
|
208
|
+
* Supported object keys: enabled, autoplay/autoPlay, duration/playDuration.
|
|
209
|
+
* Bracket scanning is always limited to the first 500 words of the text.
|
|
210
|
+
* @param {Object} [options]
|
|
211
|
+
* @returns {{ enabled: boolean, autoplay: boolean, duration: number }}
|
|
212
|
+
*/
|
|
213
|
+
_getBracketActionOptions(options: DHAny): {
|
|
214
|
+
enabled: boolean;
|
|
215
|
+
autoplay: boolean;
|
|
216
|
+
duration: number;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Whether LLM bracket-action scanning is enabled for the current request.
|
|
220
|
+
* Priority: request options -> session config -> character config -> constructor config.
|
|
221
|
+
* Supported keys: bracketAction / autoBracketAction.
|
|
222
|
+
* @param {Object} [options]
|
|
223
|
+
* @returns {boolean}
|
|
224
|
+
*/
|
|
225
|
+
_isBracketActionEnabled(options: DHAny): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Resolve summarization options from request/session/config state.
|
|
228
|
+
* Priority: request options -> summarizeAgent config -> session config -> character config -> constructor config.
|
|
229
|
+
*
|
|
230
|
+
* These options drive all DigitalHuman-owned summarization entry points:
|
|
231
|
+
* - manual `summarize()` calls
|
|
232
|
+
* - post-send auto checks (`trigger: 'auto'`)
|
|
233
|
+
* - idle timer checks (`trigger: 'silentTick'`)
|
|
234
|
+
*
|
|
235
|
+
* Startup history restore via keepHistory is intentionally excluded. Existing
|
|
236
|
+
* history is loaded into the session, but summarization is not auto-triggered
|
|
237
|
+
* just because restored messages already exceed the thresholds.
|
|
238
|
+
*
|
|
239
|
+
* Supported shapes:
|
|
240
|
+
* - `true` => enable with defaults (maxRounds=20, maxTextLength=8000, keepRecentRounds=3)
|
|
241
|
+
* - `{ enabled: true, maxRounds, maxTextLength, keepRecentRounds, prompt, model, enableTools }`
|
|
242
|
+
* - `summarizeAgent` config: presence implies enabled=true; thresholds and mode are read from it
|
|
243
|
+
*
|
|
244
|
+
* @param {Object} [options]
|
|
245
|
+
* @returns {{ enabled: boolean, maxRounds: number, maxTextLength: number, keepRecentRounds: number, prompt: string|undefined, model: string|undefined, enableTools: string[]|undefined, mode: string, async: boolean, silentTickInterval: number }}
|
|
246
|
+
*/
|
|
247
|
+
_getSummarizationOptions(options?: DHAny): {
|
|
248
|
+
enabled: boolean;
|
|
249
|
+
maxRounds: number;
|
|
250
|
+
maxTextLength: number;
|
|
251
|
+
keepRecentRounds: number;
|
|
252
|
+
prompt: any;
|
|
253
|
+
model: any;
|
|
254
|
+
enableTools: any;
|
|
255
|
+
mode: any;
|
|
256
|
+
async: boolean;
|
|
257
|
+
silentTickInterval: number;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Load and initialize a dedicated summarize agent from a config source.
|
|
261
|
+
* Delegates to the SummarizeAgent instance for session creation and CopilotTools override.
|
|
262
|
+
* @param {string|Object} source - Config URL, JSON string, or config object
|
|
263
|
+
* @returns {Promise<Object>} The parsed agent config
|
|
264
|
+
*/
|
|
265
|
+
loadSummarizeAgentConfig(source: DHAny): Promise<any>;
|
|
266
|
+
/**
|
|
267
|
+
* Send background context to both the text ChatSession and the voice RTC session.
|
|
268
|
+
* In text mode, context is queued via ChatSession.sendContext() and flushed
|
|
269
|
+
* automatically on the next ChatSession.send() or voice-to-text mirror commit.
|
|
270
|
+
* In voice mode, context is also sent immediately via the RTC binary channel.
|
|
271
|
+
*
|
|
272
|
+
* When `insertToHistory` is true, a fake user/assistant pair is also written
|
|
273
|
+
* into the session message list and persisted to the keepHistory files.
|
|
274
|
+
* The user message is the context text and the assistant reply is "(OK)".
|
|
275
|
+
* This pair is excluded from dialog summarization.
|
|
276
|
+
* @param {string} text - Context text to inject
|
|
277
|
+
* @param {Object} [options]
|
|
278
|
+
* @param {boolean} [options.insertToHistory=false] - Also persist as a Q/A pair in history
|
|
279
|
+
*/
|
|
280
|
+
sendContext(text: DHAny, options?: DHAny): void;
|
|
281
|
+
/**
|
|
282
|
+
* Handle an external send message. Optionally interrupts current speech/response,
|
|
283
|
+
* then sends the message through the normal send() flow.
|
|
284
|
+
* @private
|
|
285
|
+
* @param {Object} msg - { type: 'dh:send', text: string, interrupt?: boolean, options?: object }
|
|
286
|
+
*/
|
|
287
|
+
_handleExternalSend(msg: DHAny): Promise<void>;
|
|
288
|
+
/**
|
|
289
|
+
* Handle an external context message. Buffers context and optionally starts
|
|
290
|
+
* a debounce timer. Default debounce is Infinity (context only sent with
|
|
291
|
+
* next user message). Finite debounce auto-sends with "(continue)" after
|
|
292
|
+
* the specified milliseconds.
|
|
293
|
+
* @private
|
|
294
|
+
* @param {Object} msg - { type: 'dh:context', text: string, debounce?: number }
|
|
295
|
+
*/
|
|
296
|
+
_handleExternalContext(msg: DHAny): void;
|
|
297
|
+
/**
|
|
298
|
+
* Auto-flush buffered context by sending a "(continue)" user message.
|
|
299
|
+
* @private
|
|
300
|
+
*/
|
|
301
|
+
_autoFlushExternalContext(): Promise<void>;
|
|
302
|
+
/** Flush buffered context (cancel debounce timer, context already queued). @private */
|
|
303
|
+
_flushExternalContext(): void;
|
|
304
|
+
/** @private */
|
|
305
|
+
_normalizeVoiceHeartbeatConfig(value: DHAny, fallback?: DHAny): any;
|
|
306
|
+
/** @private */
|
|
307
|
+
_resolveVoiceHeartbeatConfig(preset?: DHAny, options?: DHAny): any;
|
|
308
|
+
/** @private */
|
|
309
|
+
_setupVoiceHeartbeat(config: DHAny): void;
|
|
310
|
+
/** @private */
|
|
311
|
+
_clearVoiceHeartbeat(options?: DHAny): void;
|
|
312
|
+
/** @private */
|
|
313
|
+
_isVoiceHeartbeatAgentIdle(): boolean;
|
|
314
|
+
/** @private */
|
|
315
|
+
_canRunVoiceHeartbeat(config?: any): boolean;
|
|
316
|
+
/** @private */
|
|
317
|
+
_scheduleVoiceHeartbeat(): void;
|
|
318
|
+
/** @private */
|
|
319
|
+
_scheduleVoiceHeartbeatAfter(delayMs: DHAny): void;
|
|
320
|
+
/** @private */
|
|
321
|
+
_resetVoiceHeartbeatActivity(): void;
|
|
322
|
+
/** @private */
|
|
323
|
+
_formatVoiceHeartbeatText(rawText: DHAny, meta: DHAny): string;
|
|
324
|
+
/**
|
|
325
|
+
* Trigger the voice heartbeat path immediately from app code.
|
|
326
|
+
* This is useful when the app already knows the current business state and
|
|
327
|
+
* wants to avoid asking the LLM to inspect the page with read_app.
|
|
328
|
+
* @param {string|Object} input - Explicit heartbeat text, or { text, reason, context, data }.
|
|
329
|
+
* @param {Object} [options]
|
|
330
|
+
* @returns {Promise<Object>}
|
|
331
|
+
*/
|
|
332
|
+
triggerVoiceHeartbeat(input?: DHAny, options?: DHAny): Promise<any>;
|
|
333
|
+
/** @private */
|
|
334
|
+
_sendVoiceHeartbeat({ trigger, rawText, meta, options }?: DHAny): Promise<any>;
|
|
335
|
+
/** @private */
|
|
336
|
+
_onVoiceHeartbeatTimeout(): Promise<void>;
|
|
337
|
+
/** @private */
|
|
338
|
+
_emitActiveState(reason?: string): void;
|
|
339
|
+
/** @private */
|
|
340
|
+
_clearInactiveVoiceStopTimer(): void;
|
|
341
|
+
/** @private */
|
|
342
|
+
_clearVoiceIdleTimer(): void;
|
|
343
|
+
/** @private */
|
|
344
|
+
_resetVoiceIdleTimer(): void;
|
|
345
|
+
/** @private */
|
|
346
|
+
_normalizeVoiceLifecycleConfig(value: DHAny, fallback?: DHAny): any;
|
|
347
|
+
/** @private */
|
|
348
|
+
_resolveVoiceLifecycleConfig(preset?: DHAny, options?: DHAny): any;
|
|
349
|
+
/** @private */
|
|
350
|
+
_isDocumentHidden(): boolean;
|
|
351
|
+
/** @private */
|
|
352
|
+
_emitVoiceLifecycleState(state: DHAny, extra?: DHAny): void;
|
|
353
|
+
/** @private */
|
|
354
|
+
_setupVoiceLifecycleHandlers(config: DHAny): void;
|
|
355
|
+
/** @private */
|
|
356
|
+
_clearVoiceLifecycleHandlers(): void;
|
|
357
|
+
/** @private */
|
|
358
|
+
_enterVoiceLifecycleStandby(reason?: string): Promise<void>;
|
|
359
|
+
/** @private */
|
|
360
|
+
_resumeVoiceLifecycleFromStandby(reason?: string): Promise<void>;
|
|
361
|
+
/** @private */
|
|
362
|
+
_stopVoiceConnectionForInactive(reason?: string): Promise<void>;
|
|
363
|
+
/** @private */
|
|
364
|
+
_scheduleInactiveVoiceStop(options?: DHAny): void;
|
|
365
|
+
/** @private */
|
|
366
|
+
_sendCurrentPageRouterWakeupIfNeeded(): Promise<boolean>;
|
|
367
|
+
/** @private */
|
|
368
|
+
_switchToInactiveIdle(): void;
|
|
369
|
+
/**
|
|
370
|
+
* Set whether the digital human is actively listening/speaking.
|
|
371
|
+
* This does not switch text/voice mode. Starting voice mode activates it;
|
|
372
|
+
* stopping voice mode makes it inactive.
|
|
373
|
+
* @param {boolean} active
|
|
374
|
+
* @param {Object} [options]
|
|
375
|
+
* @returns {Promise<Object>}
|
|
376
|
+
*/
|
|
377
|
+
setActive(active?: boolean, options?: DHAny): Promise<{
|
|
378
|
+
ok: boolean;
|
|
379
|
+
active: any;
|
|
380
|
+
changed: boolean;
|
|
381
|
+
}>;
|
|
382
|
+
/** @private */
|
|
383
|
+
_startPageRouterHeartbeat(page: DHAny, routerEntry: DHAny): void;
|
|
384
|
+
/**
|
|
385
|
+
* Immediately send heartbeat text. If text is omitted, use the active
|
|
386
|
+
* page router heartbeatText; if that is unavailable, send "[heartbeat]".
|
|
387
|
+
* @param {string} [text] - Explicit heartbeat text to send.
|
|
388
|
+
* @param {Object} [options] - send() options. Defaults keep heartbeat out of history and skips empty runCode output.
|
|
389
|
+
* @returns {Promise<Object>} Result metadata plus the send() response.
|
|
390
|
+
*/
|
|
391
|
+
sendHeartbeat(text: DHAny, options?: DHAny): Promise<{
|
|
392
|
+
ok: boolean;
|
|
393
|
+
sent: boolean;
|
|
394
|
+
skipped: boolean;
|
|
395
|
+
reason: string;
|
|
396
|
+
page: any;
|
|
397
|
+
text?: undefined;
|
|
398
|
+
data?: undefined;
|
|
399
|
+
} | {
|
|
400
|
+
ok: boolean;
|
|
401
|
+
sent: boolean;
|
|
402
|
+
page: string | null;
|
|
403
|
+
text: any;
|
|
404
|
+
data: any;
|
|
405
|
+
skipped?: undefined;
|
|
406
|
+
reason?: undefined;
|
|
407
|
+
}>;
|
|
408
|
+
/**
|
|
409
|
+
* Handle an AppPageOpened message. Looks up the page in _pageRouters,
|
|
410
|
+
* restarts the agent / sends wakeup text if configured, and manages
|
|
411
|
+
* page-scoped heartbeat text.
|
|
412
|
+
* @private
|
|
413
|
+
* @param {Object} msg - { type: 'dh:app-page-opened', page: string }
|
|
414
|
+
*/
|
|
415
|
+
_handleAppPageOpened(msg: DHAny): Promise<void>;
|
|
416
|
+
/**
|
|
417
|
+
* Trigger conversation summarization.
|
|
418
|
+
* This is the single DigitalHuman entry point for both manual and automatic
|
|
419
|
+
* summarization requests. Automatic callers can set `trigger` and
|
|
420
|
+
* `onlyWhenNeeded` to reuse the same queueing and threshold checks as manual
|
|
421
|
+
* summaries.
|
|
422
|
+
* Routes to the dedicated SummarizeAgent if configured, otherwise falls back
|
|
423
|
+
* to the built-in SummarizeTool. Returns immediately. Only one summarization
|
|
424
|
+
* runs at a time; subsequent calls are queued and merged so the latest
|
|
425
|
+
* options win.
|
|
426
|
+
*
|
|
427
|
+
* Behavior summary:
|
|
428
|
+
* - fire-and-forget: this method does not return the summary result
|
|
429
|
+
* - result delivery: listen for the `summarized` event
|
|
430
|
+
* - manual trigger: call `summarize()` with no gating flags
|
|
431
|
+
* - automatic trigger: call with `onlyWhenNeeded: true`; threshold checks are
|
|
432
|
+
* evaluated against the current session message history
|
|
433
|
+
* - duplicate suppression: automatic requests in the same threshold bucket are
|
|
434
|
+
* skipped until the conversation grows into a new bucket
|
|
435
|
+
* - queue merging: if a run is already active, a later request replaces the
|
|
436
|
+
* pending request so only the latest queued options are kept
|
|
437
|
+
* - startup behavior: restoring keepHistory content does not call summarize()
|
|
438
|
+
* automatically
|
|
439
|
+
*
|
|
440
|
+
* Listen for the 'summarized' event to receive the result.
|
|
441
|
+
* @param {Object} [options]
|
|
442
|
+
* @param {number} [options.keepRecentRounds=3] - Number of recent user+assistant pairs to preserve
|
|
443
|
+
* @param {string} [options.mode] - 'replace' (compress in place) or 'append' (return summary only)
|
|
444
|
+
* @param {string} [options.trigger='manual'] - Event trigger label such as 'manual', 'auto', or 'silentTick'
|
|
445
|
+
* @param {boolean} [options.onlyWhenNeeded=false] - Gate execution by maxRounds/maxTextLength thresholds
|
|
446
|
+
*/
|
|
447
|
+
summarize(options?: DHAny): void;
|
|
448
|
+
/**
|
|
449
|
+
* Collect summarization metrics from the live text session.
|
|
450
|
+
* System messages are excluded. `roundCount` is based on user messages only.
|
|
451
|
+
* `totalTextLength` counts string message content currently stored in the
|
|
452
|
+
* session and is used together with `maxTextLength` for auto-trigger gating.
|
|
453
|
+
* @returns {{ roundCount: number, totalTextLength: number }|null}
|
|
454
|
+
*/
|
|
455
|
+
_collectSummarizeMetrics(): {
|
|
456
|
+
roundCount: number;
|
|
457
|
+
totalTextLength: number;
|
|
458
|
+
} | null;
|
|
459
|
+
/**
|
|
460
|
+
* Build a stable auto-trigger signature for the current threshold bucket.
|
|
461
|
+
* Automatic summarization requests are skipped while the session remains in
|
|
462
|
+
* the same bucket, which prevents repeated summaries after every send or idle
|
|
463
|
+
* tick without new conversation growth.
|
|
464
|
+
* @param {{ roundCount: number, totalTextLength: number }|null} metrics
|
|
465
|
+
* @param {Object} [options]
|
|
466
|
+
* @returns {string|null}
|
|
467
|
+
*/
|
|
468
|
+
_getSummarizeAutoTriggerSignature(metrics: DHAny, options?: DHAny): string | null;
|
|
469
|
+
/**
|
|
470
|
+
* Decide whether a threshold-gated summarization request should run.
|
|
471
|
+
*
|
|
472
|
+
* This is only used when callers pass `onlyWhenNeeded: true`. Manual calls
|
|
473
|
+
* bypass this method and always attempt to summarize.
|
|
474
|
+
*
|
|
475
|
+
* Returns false when:
|
|
476
|
+
* - summarization is disabled by resolved config
|
|
477
|
+
* - there is no active AI session/message list
|
|
478
|
+
* - both `maxRounds` and `maxTextLength` thresholds are still below target
|
|
479
|
+
* - the current conversation is still in the same auto-trigger bucket as the
|
|
480
|
+
* last completed/attempted gated request
|
|
481
|
+
*
|
|
482
|
+
* Returns true once the conversation crosses into a new threshold bucket.
|
|
483
|
+
* @param {Object} [options]
|
|
484
|
+
* @returns {boolean}
|
|
485
|
+
*/
|
|
486
|
+
_shouldRunSummarize(options?: DHAny): boolean;
|
|
487
|
+
/**
|
|
488
|
+
* Start the DigitalHuman-owned silent-tick summarization timer.
|
|
489
|
+
*
|
|
490
|
+
* The timer does not summarize immediately on each tick. Instead it waits for
|
|
491
|
+
* `silentTickInterval` seconds of inactivity, then calls `summarize()` with
|
|
492
|
+
* `trigger: 'silentTick'` and `onlyWhenNeeded: true` so the same threshold
|
|
493
|
+
* gating and queue semantics are reused.
|
|
494
|
+
*/
|
|
495
|
+
_startSummarizeTimer(): void;
|
|
496
|
+
/** Stop the DigitalHuman-owned silent-tick summarization timer. */
|
|
497
|
+
_stopSummarizeTimer(): void;
|
|
498
|
+
/** Record the latest user/assistant activity time for silent-tick checks. */
|
|
499
|
+
_resetSummarizeActivity(): void;
|
|
500
|
+
/**
|
|
501
|
+
* Execute one summarization request and then drain any merged pending request.
|
|
502
|
+
*
|
|
503
|
+
* Result handling:
|
|
504
|
+
* - emits `summarized` on success or error
|
|
505
|
+
* - preserves the caller-provided `trigger` in the event payload
|
|
506
|
+
* - forwards the returned summary into `sendContext()` when available so later
|
|
507
|
+
* turns can reuse the compressed context
|
|
508
|
+
* - updates keepHistory cutoff state when the summarizer reports
|
|
509
|
+
* `summarizeBeginTime`
|
|
510
|
+
*
|
|
511
|
+
* This method is internal. External callers should always use `summarize()`.
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
_runSummarize(options: DHAny): Promise<void>;
|
|
515
|
+
/**
|
|
516
|
+
* Resolve non-RTC text-to-speech options from request/session/config state.
|
|
517
|
+
* Supported shapes:
|
|
518
|
+
* - `true` => enable SpeechRTC with defaults
|
|
519
|
+
* - `{ enabled: true, provider: 'speechRTC'|'speech', voiceType: '...' }`
|
|
520
|
+
* - `{ speechRTC: { voiceType: '...' } }`
|
|
521
|
+
* - `{ speech: { voiceType: '...' } }`
|
|
522
|
+
* Priority: request options -> session config -> character config -> constructor config.
|
|
523
|
+
* @param {Object} [options]
|
|
524
|
+
* @returns {{ enabled: boolean, provider: string, sessionOptions: Object }}
|
|
525
|
+
*/
|
|
526
|
+
_getTextToSpeechOptions(options: DHAny): {
|
|
527
|
+
enabled: boolean;
|
|
528
|
+
provider: string;
|
|
529
|
+
sessionOptions: any;
|
|
530
|
+
};
|
|
531
|
+
_normalizeAutoReadReplyValue(value: DHAny): boolean | undefined;
|
|
532
|
+
_getAutoReadReplySources(options: DHAny): any[];
|
|
533
|
+
_isAutoReadReplyEnabled(options?: DHAny): boolean;
|
|
534
|
+
/**
|
|
535
|
+
* Build SpeechRTC options for non-RTC text reply playback.
|
|
536
|
+
* Defaults to mp3 + manual playback so DigitalHuman can reuse lip sync.
|
|
537
|
+
* When bracketAction is enabled, bracketed action hints are excluded from
|
|
538
|
+
* spoken text unless the caller explicitly disables it via
|
|
539
|
+
* `textToSpeech.ignoreBracketText = false`.
|
|
540
|
+
* @param {Object} [options]
|
|
541
|
+
* @returns {Object}
|
|
542
|
+
*/
|
|
543
|
+
_buildTextSpeechRTCOptions(options?: DHAny): any;
|
|
544
|
+
_buildStreamingTextSpeechRTCOptions(options?: DHAny): any;
|
|
545
|
+
_resolveTextSpeechContent(text: DHAny, options?: DHAny, sessionOptions?: DHAny): string;
|
|
546
|
+
_resolveStreamingTextSpeechContent(text: DHAny, options?: DHAny, sessionOptions?: DHAny): string;
|
|
547
|
+
_buildSpeechAudioUrl(result: DHAny, options?: DHAny): string | null;
|
|
548
|
+
/**
|
|
549
|
+
* Resolve muteWhileSpeaking options from request/session/config state.
|
|
550
|
+
* When enabled, the mic is automatically muted while the avatar speaks
|
|
551
|
+
* (text TTS or voice chat remote audio) and unmuted when speech ends.
|
|
552
|
+
* A safety timer (`maxDuration`) guarantees the mic is never muted longer
|
|
553
|
+
* than the configured ceiling (default 5 s).
|
|
554
|
+
*
|
|
555
|
+
* Supported shapes:
|
|
556
|
+
* - `true` => enabled with defaults (maxDuration=5)
|
|
557
|
+
* - `{ enabled: true, maxDuration: 8 }`
|
|
558
|
+
*
|
|
559
|
+
* Priority: request options -> session config -> character config -> constructor config.
|
|
560
|
+
* @param {Object} [options]
|
|
561
|
+
* @returns {{ enabled: boolean, maxDuration: number }}
|
|
562
|
+
*/
|
|
563
|
+
_getMuteWhileSpeakingOptions(options: DHAny): {
|
|
564
|
+
enabled: boolean;
|
|
565
|
+
maxDuration: number;
|
|
566
|
+
};
|
|
567
|
+
/**
|
|
568
|
+
* Mute the microphone because the avatar started speaking.
|
|
569
|
+
* Does nothing if muteWhileSpeaking is disabled or already active.
|
|
570
|
+
* Starts a safety timer that auto-unmutes after maxDuration seconds.
|
|
571
|
+
* @param {Object} [options]
|
|
572
|
+
*/
|
|
573
|
+
_muteWhileSpeakingStart(options?: DHAny): void;
|
|
574
|
+
/**
|
|
575
|
+
* Unmute the microphone because the avatar stopped speaking.
|
|
576
|
+
* Does nothing if not currently auto-muted.
|
|
577
|
+
*/
|
|
578
|
+
_muteWhileSpeakingStop(): void;
|
|
579
|
+
_getComfortMessageForTool(toolName: DHAny): "" | "(记录中...)" | "(查询中...)";
|
|
580
|
+
_isAssistantTextSpeechPlaying(): boolean;
|
|
581
|
+
_triggerComfortMessage(toolName: DHAny, options: DHAny | undefined, sentTypes: DHAny, pendingMessages: DHAny): Promise<void>;
|
|
582
|
+
_startTextSpeechTurn(): Promise<any>;
|
|
583
|
+
_queueTextSpeech(text: DHAny, options?: DHAny, meta?: DHAny): boolean;
|
|
584
|
+
_drainTextSpeechQueue(): Promise<void>;
|
|
585
|
+
_restoreIdleAfterTextSpeech(requestId: DHAny): void;
|
|
586
|
+
_stopTextSpeechPlayback(): Promise<void>;
|
|
587
|
+
_isStreamingTextSpeechEnabled(options?: DHAny): boolean;
|
|
588
|
+
_setStreamingTextSpeechSpeaking(isSpeaking: DHAny, requestId: DHAny): void;
|
|
589
|
+
_handleStreamingTextSpeechAudioChunk(bytes: DHAny, requestId: DHAny): void;
|
|
590
|
+
_createStreamingTextSpeechState(options?: DHAny, meta?: DHAny): any;
|
|
591
|
+
_appendStreamingTextSpeech(text: DHAny, options?: DHAny, meta?: DHAny): Promise<boolean>;
|
|
592
|
+
_finishStreamingTextSpeech(text: DHAny, options?: DHAny, meta?: DHAny): Promise<any>;
|
|
593
|
+
_playAudioWithLipSyncUntilEnded(audioUrl: DHAny, callbacks?: DHAny): Promise<void>;
|
|
594
|
+
_speakTextResponseWithSpeechRTC(text: DHAny, options?: DHAny): Promise<any>;
|
|
595
|
+
_speakTextResponseWithSpeech(text: DHAny, options?: DHAny): Promise<any>;
|
|
596
|
+
_speakTextResponseNow(text: DHAny, options?: DHAny, meta?: DHAny): Promise<any>;
|
|
597
|
+
_speakTextResponse(text: DHAny, options?: DHAny): Promise<null>;
|
|
598
|
+
/**
|
|
599
|
+
* Find the best matching custom action alias for a bracketed LLM phrase.
|
|
600
|
+
* Matching is symmetric substring matching after lightweight normalization.
|
|
601
|
+
* Built-in idle/talk actions are ignored to avoid false positives.
|
|
602
|
+
* @param {string} bracketText
|
|
603
|
+
* @returns {{ actionKey: string, matchedAlias: string }|null}
|
|
604
|
+
*/
|
|
605
|
+
_findBracketActionMatch(bracketText: DHAny): {
|
|
606
|
+
actionKey: string;
|
|
607
|
+
matchedAlias: string;
|
|
608
|
+
} | null;
|
|
609
|
+
/**
|
|
610
|
+
* Scan text for bracketed action hints and emit a deduplicated bracketAction event.
|
|
611
|
+
* Only the first 500 words of the text are scanned.
|
|
612
|
+
* @param {string} text
|
|
613
|
+
* @param {Set<string>} seenMatches
|
|
614
|
+
* @param {Object} [meta]
|
|
615
|
+
* @param {{ enabled?: boolean, autoplay?: boolean, duration?: number }} [options]
|
|
616
|
+
*/
|
|
617
|
+
_emitBracketActionEvents(text: DHAny, seenMatches: DHAny, meta?: DHAny, options?: DHAny): void;
|
|
618
|
+
/**
|
|
619
|
+
* Initialize avatar rendering with the given video actions.
|
|
620
|
+
* Keys may contain pipe-separated aliases, e.g. '待机|idle|0': { url }.
|
|
621
|
+
* @param {Object} videoActions - { "待机|idle|0": { url }, "说话|talk|1": { url } }
|
|
622
|
+
* @param {Object} [options]
|
|
623
|
+
* @param {boolean} [options.avatarOnlyMode] - Full screen mode (no chat overlay)
|
|
624
|
+
*/
|
|
625
|
+
initAvatar(videoActions: DHAny, options?: DHAny): Promise<void>;
|
|
626
|
+
/**
|
|
627
|
+
* Get custom action alias groups, excluding idle/talk and numeric aliases.
|
|
628
|
+
* @returns {string[][]}
|
|
629
|
+
*/
|
|
630
|
+
_getCustomActionAliasGroups(): string[][];
|
|
631
|
+
/**
|
|
632
|
+
* Normalize action list language filter.
|
|
633
|
+
* @param {string} lang
|
|
634
|
+
* @returns {'en'|'zh'|null}
|
|
635
|
+
*/
|
|
636
|
+
_normalizeActionListLang(lang: DHAny): any;
|
|
637
|
+
/**
|
|
638
|
+
* Get comma-separated custom action aliases, optionally filtered by language.
|
|
639
|
+
* Supported language filters: enUS|zhCN|en|cn|English|Chinese.
|
|
640
|
+
* @param {string} [lang]
|
|
641
|
+
* @returns {string}
|
|
642
|
+
*/
|
|
643
|
+
_getActionList(lang: DHAny): string;
|
|
644
|
+
/**
|
|
645
|
+
* Register the 'digitalhuman' tool category on construction, then refresh
|
|
646
|
+
* its definitions after avatar actions become available.
|
|
647
|
+
*/
|
|
648
|
+
_registerDigitalHumanTool(): void;
|
|
649
|
+
/**
|
|
650
|
+
* Auto-register the `minigame` copilot tool category (idempotent per SDK) and
|
|
651
|
+
* subscribe this DigitalHuman to iframe events. Default `gameFinished` handling:
|
|
652
|
+
* 1. Emit a `minigameEvent` event with the raw iframe data.
|
|
653
|
+
* 2. Restart the agent so the LLM picks up any workspace changes made by the game.
|
|
654
|
+
* Hosts can override via `this.on('minigameEvent', handler)` or by setting
|
|
655
|
+
* `characterConfig.minigame.autoRestartAgent = false` to disable the restart.
|
|
656
|
+
*/
|
|
657
|
+
_registerMinigameTool(): void;
|
|
658
|
+
/**
|
|
659
|
+
* Close the minigame iframe overlay (if open) and restart the agent to default.
|
|
660
|
+
* @param {Object} [options]
|
|
661
|
+
* @param {string} [options.reason='user'] - Close reason passed to MinigameTools.close()
|
|
662
|
+
* @param {boolean} [options.restartAgent=true] - Whether to restart the agent after closing
|
|
663
|
+
* @returns {Promise<void>}
|
|
664
|
+
*/
|
|
665
|
+
closeMinigame(options?: DHAny): Promise<void>;
|
|
666
|
+
/** Forward user ASR subtitles into the active minigame iframe. */
|
|
667
|
+
_forwardUserVoiceInputToMinigame(data?: DHAny): void;
|
|
668
|
+
_checkVideoActionsAvailable(videoActions: DHAny): boolean;
|
|
669
|
+
_initializeVideos(): Promise<void>;
|
|
670
|
+
_loadIdleVideo(): Promise<any>;
|
|
671
|
+
_preloadTalkVideo(): Promise<any>;
|
|
672
|
+
_initializeWebp(): void;
|
|
673
|
+
/**
|
|
674
|
+
* Show a custom webp action by swapping the talk image source.
|
|
675
|
+
* @param {string} url - Webp image URL
|
|
676
|
+
*/
|
|
677
|
+
_playWebpAction(url: DHAny): void;
|
|
678
|
+
/**
|
|
679
|
+
* Compute the Live2D model's rendered screen-space rectangle.
|
|
680
|
+
* @returns {{ x: number, y: number, width: number, height: number, padding: number } | null}
|
|
681
|
+
*/
|
|
682
|
+
_getLive2DModelScreenRect(): {
|
|
683
|
+
x: number;
|
|
684
|
+
y: number;
|
|
685
|
+
width: number;
|
|
686
|
+
height: number;
|
|
687
|
+
padding: number;
|
|
688
|
+
} | null;
|
|
689
|
+
/**
|
|
690
|
+
* Show a webp overlay on top of the Live2D canvas for custom actions.
|
|
691
|
+
* Uses the Live2D model's actual rendered rect (which already includes
|
|
692
|
+
* scale/offsetY) to size and position the webp to match.
|
|
693
|
+
* @param {string} url - Webp image URL
|
|
694
|
+
*/
|
|
695
|
+
_playLive2DWebpOverlay(url: DHAny): void;
|
|
696
|
+
/**
|
|
697
|
+
* Hide the webp overlay and restore the Live2D canvas.
|
|
698
|
+
*/
|
|
699
|
+
_hideLive2DWebpOverlay(): void;
|
|
700
|
+
_initializeLive2D(): Promise<void>;
|
|
701
|
+
_ensureLive2DScripts(): Promise<void>;
|
|
702
|
+
_getLive2DLayoutTarget(): any;
|
|
703
|
+
_getLive2DViewportSize(): {
|
|
704
|
+
width: number;
|
|
705
|
+
height: number;
|
|
706
|
+
};
|
|
707
|
+
_syncLive2DViewport(force: DHAny): boolean;
|
|
708
|
+
_scheduleLive2DLayout(force?: DHAny): void;
|
|
709
|
+
_observeLive2DContainer(): void;
|
|
710
|
+
/**
|
|
711
|
+
* Get merged layout params (scale, offsetY) from idle action config + URL query.
|
|
712
|
+
* URL query params override config object props.
|
|
713
|
+
* offsetY is a fraction of viewport height (e.g. 0.2 = 20%).
|
|
714
|
+
* @returns {{ scale: number, offsetY: number }}
|
|
715
|
+
*/
|
|
716
|
+
_getIdleLayoutParams(): {
|
|
717
|
+
scale: any;
|
|
718
|
+
offsetY: any;
|
|
719
|
+
};
|
|
720
|
+
_layoutLive2D(): void;
|
|
721
|
+
_bindLive2DLipSync(): void;
|
|
722
|
+
/**
|
|
723
|
+
* Set mouth open value (0-1) for lip sync.
|
|
724
|
+
* @param {number} value - 0 (closed) to 1 (fully open)
|
|
725
|
+
*/
|
|
726
|
+
setMouthOpen(value: DHAny): void;
|
|
727
|
+
/**
|
|
728
|
+
* Play audio via Web Audio API with lip sync analysis.
|
|
729
|
+
* @param {string} audioUrl - URL of the audio to play
|
|
730
|
+
* @param {Function|Object} [callbacks] - Callback or { onStart, onEnded }
|
|
731
|
+
* @returns {Promise<AudioBufferSourceNode>}
|
|
732
|
+
*/
|
|
733
|
+
playAudioWithLipSync(audioUrl: DHAny, callbacks: DHAny): Promise<any>;
|
|
734
|
+
/** Stop audio-driven lip sync. */
|
|
735
|
+
stopAudioLipSync(): void;
|
|
736
|
+
/** Start smooth RTC lip sync animation loop. */
|
|
737
|
+
_startRtcLipSync(): void;
|
|
738
|
+
/** Stop RTC lip sync animation loop. */
|
|
739
|
+
_stopRtcLipSync(): void;
|
|
740
|
+
/** Switch avatar to idle state. */
|
|
741
|
+
switchToIdle(): void;
|
|
742
|
+
/** Switch avatar to talking state. */
|
|
743
|
+
switchToTalking(): void;
|
|
744
|
+
_performTalkTransition(): void;
|
|
745
|
+
/**
|
|
746
|
+
* Switch avatar to a named state. Supports aliases (e.g. 'idle', 'talk', 0, 1).
|
|
747
|
+
* @param {string|number} type
|
|
748
|
+
*/
|
|
749
|
+
switchVideo(type: DHAny): void;
|
|
750
|
+
/**
|
|
751
|
+
* Play a Live2D motion.
|
|
752
|
+
* @param {string[]} [preferredGroups=['Tap','TapBody','Idle']]
|
|
753
|
+
* @param {number} [priority=2]
|
|
754
|
+
*/
|
|
755
|
+
playMotion(preferredGroups: DHAny, priority: DHAny): void;
|
|
756
|
+
/**
|
|
757
|
+
* Play a named action from videoActions for a given duration, then return to idle.
|
|
758
|
+
* Supports aliases: '待机'/0 → 'idle', '说话'/1 → 'talk', plus any pipe-defined aliases.
|
|
759
|
+
* If called again with the same resolved action, only the duration timer is reset.
|
|
760
|
+
* @param {string|number} actionKey - Key in videoActions (e.g. '高兴', 'happy', 'talk', '说话', 1)
|
|
761
|
+
* @param {number} [duration=3] - Seconds to hold the action. -1 = stay indefinitely.
|
|
762
|
+
*/
|
|
763
|
+
playAction(actionKey: DHAny, duration?: number): void;
|
|
764
|
+
/**
|
|
765
|
+
* Load and play a one-off action video on the talk video element.
|
|
766
|
+
* @param {string} url - Video URL
|
|
767
|
+
*/
|
|
768
|
+
_playActionVideo(url: DHAny): void;
|
|
769
|
+
/** Get current avatar control state for host. */
|
|
770
|
+
getAvatarStatus(): {
|
|
771
|
+
enabled: boolean;
|
|
772
|
+
idleMediaType: any;
|
|
773
|
+
live2dMode: boolean;
|
|
774
|
+
live2dReady: boolean;
|
|
775
|
+
currentVideoType: any;
|
|
776
|
+
mouthOpen: number;
|
|
777
|
+
hostSessionActive: boolean;
|
|
778
|
+
};
|
|
779
|
+
getSession(): any;
|
|
780
|
+
/**
|
|
781
|
+
* Manually send the configured boot message through the text chat session.
|
|
782
|
+
* The boot input itself is excluded from keepHistory, while the assistant
|
|
783
|
+
* reply remains in the session like any other reply.
|
|
784
|
+
* @param {string} [bootMessage] - Override message; defaults to characterConfig.initial.bootMessage
|
|
785
|
+
* @param {Object} [options]
|
|
786
|
+
* @returns {Promise<{ finalText: string, parsedResponse: Object, mode: 'text', skipped?: boolean, reason?: string }>}
|
|
787
|
+
*/
|
|
788
|
+
sendBootMessage(bootMessage: DHAny, options?: DHAny): Promise<any>;
|
|
789
|
+
/**
|
|
790
|
+
* Enable remote control via postMessage. Listens for messages and calls methods on this instance.
|
|
791
|
+
* @param {Object} options
|
|
792
|
+
* @param {string} options.msgPrefix - Prefix for message types
|
|
793
|
+
* @param {Function} options.postToParent - Function to send messages back
|
|
794
|
+
* @param {Function} [options.setupToolProxy] - Optional hook to modify config before init
|
|
795
|
+
* @param {boolean} [options.forwardUserVoiceInputViaParentFrame] - Let the parent DigitalHumanFrame forward user voice text to minigames.
|
|
796
|
+
*/
|
|
797
|
+
enableRemoteControl(options?: DHAny): void;
|
|
798
|
+
_normalizeHostMouthValue(payload: DHAny): number | null;
|
|
799
|
+
/** Ensure Live2D model is ready (initializes if needed). */
|
|
800
|
+
ensureLive2DReady(): Promise<{
|
|
801
|
+
enabled: boolean;
|
|
802
|
+
idleMediaType: any;
|
|
803
|
+
live2dMode: boolean;
|
|
804
|
+
live2dReady: boolean;
|
|
805
|
+
currentVideoType: any;
|
|
806
|
+
mouthOpen: number;
|
|
807
|
+
hostSessionActive: boolean;
|
|
808
|
+
}>;
|
|
809
|
+
startHostLive2DCall(payload?: DHAny): Promise<{
|
|
810
|
+
enabled: boolean;
|
|
811
|
+
idleMediaType: any;
|
|
812
|
+
live2dMode: boolean;
|
|
813
|
+
live2dReady: boolean;
|
|
814
|
+
currentVideoType: any;
|
|
815
|
+
mouthOpen: number;
|
|
816
|
+
hostSessionActive: boolean;
|
|
817
|
+
}>;
|
|
818
|
+
updateHostLive2DCall(payload?: DHAny): Promise<{
|
|
819
|
+
enabled: boolean;
|
|
820
|
+
idleMediaType: any;
|
|
821
|
+
live2dMode: boolean;
|
|
822
|
+
live2dReady: boolean;
|
|
823
|
+
currentVideoType: any;
|
|
824
|
+
mouthOpen: number;
|
|
825
|
+
hostSessionActive: boolean;
|
|
826
|
+
}>;
|
|
827
|
+
stopHostLive2DCall(): {
|
|
828
|
+
enabled: boolean;
|
|
829
|
+
idleMediaType: any;
|
|
830
|
+
live2dMode: boolean;
|
|
831
|
+
live2dReady: boolean;
|
|
832
|
+
currentVideoType: any;
|
|
833
|
+
mouthOpen: number;
|
|
834
|
+
hostSessionActive: boolean;
|
|
835
|
+
};
|
|
836
|
+
/**
|
|
837
|
+
* Initialize the DigitalHuman from a characterManager-style config object.
|
|
838
|
+
* This is a convenience method that sets up avatar, AI session, and stores
|
|
839
|
+
* all character metadata in one call.
|
|
840
|
+
*
|
|
841
|
+
* The config object mirrors the format produced by characterManager's
|
|
842
|
+
* `buildCharacterConfig`, with the same nested structure:
|
|
843
|
+
*
|
|
844
|
+
* @param {Object} config - characterManager-style config (all fields stored in dh.characterConfig)
|
|
845
|
+
* @param {string} [config.system_prompt] - System prompt for LLM
|
|
846
|
+
* @param {boolean} [config.enable_system_prompt] - Whether system prompt is active (default true)
|
|
847
|
+
* @param {string|Object} [config.llm_model] - Model name string or { model, temperature, knowledgeUsername, knowledgeBaseCodes, reasoning }
|
|
848
|
+
* @param {Object} [config.videoActions] - { '待机': { url }, '说话': { url }, ... }
|
|
849
|
+
* @param {Object} [config.tools] - { fileOps: { enabled, workspace, ... }, web: { enabled }, ... }
|
|
850
|
+
* @param {Array} [config.searchPaths] - Search paths for readFile URL fallback: [{ prefix, baseUrl }]
|
|
851
|
+
* @param {boolean|Object} [config.bracketAction] - `true` emits bracketAction events; object form also supports autoplay/duration; parsing is limited to the first 500 words
|
|
852
|
+
* @param {boolean|Object} [config.textToSpeech] - Non-RTC assistant reply speech; `true` enables SpeechRTC defaults, object form accepts `speechRTC` or `speech` provider options. Set `autoReadReply: false` to keep manual TTS available but stop automatically reading assistant replies.
|
|
853
|
+
* @param {Object} [config.initial] - Initial greeting config
|
|
854
|
+
* @param {string} [config.initial.message] - Static welcome message (displayed directly)
|
|
855
|
+
* @param {string} [config.initial.bootMessage] - Boot message template; call sendBootMessage() manually after restoring any history
|
|
856
|
+
* @param {boolean} [config.avatar_only] - Avatar-only display mode
|
|
857
|
+
* @param {boolean|Object} [config.keepHistory] - Persist rounds to history.md; `true` or `{ historyLength, fileName, keepFullHistory }`
|
|
858
|
+
* @param {boolean} [config.keepFullHistory] - Also persist full daily history to history/history_YYYYMMDD.md
|
|
859
|
+
* @param {Object} [config.summarizeAgent] - Dedicated summarize agent config
|
|
860
|
+
* @param {string} [config.summarizeAgent.config] - URL or path to the agent's config file (YAML/JSON/MD)
|
|
861
|
+
* @param {number} [config.summarizeAgent.silentTickInterval] - Periodic summarization interval in seconds
|
|
862
|
+
* @param {number} [config.summarizeAgent.maxRounds] - Threshold: max conversation rounds before triggering
|
|
863
|
+
* @param {number} [config.summarizeAgent.maxTextLength] - Threshold: max total text length before triggering
|
|
864
|
+
* @param {number} [config.summarizeAgent.keepRecentRounds] - Number of recent rounds to preserve
|
|
865
|
+
* @param {string} [config.summarizeAgent.mode] - 'replace' (compress history) or 'append' (return summary only)
|
|
866
|
+
*
|
|
867
|
+
* @returns {Promise<Object>} { session, config, bootResponse? }
|
|
868
|
+
*/
|
|
869
|
+
initFromConfig(config?: DHAny): Promise<{
|
|
870
|
+
session: any;
|
|
871
|
+
config: any;
|
|
872
|
+
}>;
|
|
873
|
+
/**
|
|
874
|
+
* Detect format of a URL by extension (stripping query/fragment).
|
|
875
|
+
* @deprecated Use AgentConfig.detectFormat() instead.
|
|
876
|
+
*/
|
|
877
|
+
static _detectConfigFormat(url: DHAny): import("../core/AgentConfig").AgentConfigFormat | null;
|
|
878
|
+
/**
|
|
879
|
+
* Normalize a parsed config object.
|
|
880
|
+
* @deprecated Use AgentConfig.normalize() instead.
|
|
881
|
+
*/
|
|
882
|
+
static _normalizeConfig(config: DHAny): import("../core/AgentConfig").NormalizedAgentConfig;
|
|
883
|
+
/**
|
|
884
|
+
* Fetch and parse a DigitalHuman config from a URL, JSON string, or object.
|
|
885
|
+
* Delegates to AgentConfig.fetch().
|
|
886
|
+
*
|
|
887
|
+
* @param {string|Object} source - URL string, JSON string, or config object
|
|
888
|
+
* @returns {Promise<Object>} Parsed and normalized config object
|
|
889
|
+
*/
|
|
890
|
+
static fetchConfig(source: DHAny): Promise<import("../core/AgentConfig").NormalizedAgentConfig>;
|
|
891
|
+
/**
|
|
892
|
+
* Load a DigitalHuman config from a URL (JSON / YML / MD), inline JSON string, or object,
|
|
893
|
+
* then initialize the avatar and AI session in one call.
|
|
894
|
+
*
|
|
895
|
+
* This is the simplest way to set up a DigitalHuman — just point it at a config file:
|
|
896
|
+
* await dh.loadConfig('https://example.com/character.md');
|
|
897
|
+
*
|
|
898
|
+
* Equivalent to:
|
|
899
|
+
* const config = await DigitalHuman.fetchConfig(source);
|
|
900
|
+
* await dh.initFromConfig(config);
|
|
901
|
+
*
|
|
902
|
+
* @param {string|Object} source - URL string, JSON string, or config object
|
|
903
|
+
* @returns {Promise<Object>} Result of initFromConfig: { session, config }
|
|
904
|
+
*/
|
|
905
|
+
loadConfig(source: DHAny): Promise<{
|
|
906
|
+
session: any;
|
|
907
|
+
config: any;
|
|
908
|
+
}>;
|
|
909
|
+
/**
|
|
910
|
+
* Build LLM configuration from session config.
|
|
911
|
+
* @param {Object} [config] - Override config
|
|
912
|
+
* @returns {Object} LLM config for sdk.aiChat.createSession()
|
|
913
|
+
*/
|
|
914
|
+
_getLLMConfig(config: DHAny): any;
|
|
915
|
+
/**
|
|
916
|
+
* Apply FileOps workspace/pathPrefix configuration to a session.
|
|
917
|
+
* @param {Object} session - ChatSession
|
|
918
|
+
* @param {Object} [config] - Override config
|
|
919
|
+
*/
|
|
920
|
+
_applyFileOpsConfig(session: DHAny, config: DHAny): void;
|
|
921
|
+
/**
|
|
922
|
+
* Pass summarization YAML config to the CopilotTools `summarize` category
|
|
923
|
+
* so that `summarize_conversation` tool calls receive the configured prompt,
|
|
924
|
+
* model, enableTools, keepRecentRounds, and mode.
|
|
925
|
+
* @param {Object} [config]
|
|
926
|
+
*/
|
|
927
|
+
_applySummarizationToolConfig(config: DHAny): void;
|
|
928
|
+
/**
|
|
929
|
+
* Build daily full-history file path: history/history_YYYYMMDD.md
|
|
930
|
+
* @param {Date} [date]
|
|
931
|
+
* @returns {string}
|
|
932
|
+
*/
|
|
933
|
+
_getKeepHistoryDailyFileName(date?: Date): string;
|
|
934
|
+
/**
|
|
935
|
+
* Read a file via the session sandbox (respects tool proxy), falling back to direct store access.
|
|
936
|
+
* @param {string} fileName
|
|
937
|
+
* @returns {Promise<string>}
|
|
938
|
+
*/
|
|
939
|
+
_keepHistoryReadFile(fileName: DHAny): Promise<any>;
|
|
940
|
+
/**
|
|
941
|
+
* Create/overwrite a file via the session sandbox (respects tool proxy), falling back to direct store access.
|
|
942
|
+
* @param {string} fileName
|
|
943
|
+
* @param {string} content
|
|
944
|
+
* @returns {Promise<string>}
|
|
945
|
+
*/
|
|
946
|
+
_keepHistoryCreateFile(fileName: DHAny, content: DHAny): Promise<any>;
|
|
947
|
+
/**
|
|
948
|
+
* Format a timestamp as local wall-clock time for history comments.
|
|
949
|
+
* @param {number|Date|string} value
|
|
950
|
+
* @returns {string}
|
|
951
|
+
*/
|
|
952
|
+
_formatKeepHistoryTimestamp(value: DHAny): string;
|
|
953
|
+
/**
|
|
954
|
+
* Normalize timestamp values from history comments or in-memory message fields.
|
|
955
|
+
* @param {number|Date|string} value
|
|
956
|
+
* @returns {number|null}
|
|
957
|
+
*/
|
|
958
|
+
_parseKeepHistoryTimestamp(value: DHAny): number | null;
|
|
959
|
+
/**
|
|
960
|
+
* Convert messages into markdown blocks with per-message timestamps.
|
|
961
|
+
* @param {Array<Object>} targetMessages
|
|
962
|
+
* @returns {{ content: string, entries: Array<{ timestamp: number|null, markdown: string }> }}
|
|
963
|
+
*/
|
|
964
|
+
_buildKeepHistoryMarkdown(targetMessages: DHAny): {
|
|
965
|
+
content: string;
|
|
966
|
+
entries: {
|
|
967
|
+
timestamp: number | null;
|
|
968
|
+
markdown: string;
|
|
969
|
+
}[];
|
|
970
|
+
};
|
|
971
|
+
/**
|
|
972
|
+
* Read timestamped user blocks from a history markdown file.
|
|
973
|
+
* @param {string} md
|
|
974
|
+
* @returns {Array<{ timestamp: number|null, markdown: string }>}
|
|
975
|
+
*/
|
|
976
|
+
_parseKeepHistoryEntries(md: DHAny): {
|
|
977
|
+
timestamp: number | null;
|
|
978
|
+
markdown: string;
|
|
979
|
+
}[];
|
|
980
|
+
/**
|
|
981
|
+
* Initialize keepHistory on createSession. Reads existing history.md,
|
|
982
|
+
* parses it back into user/assistant messages, and injects them into the
|
|
983
|
+
* session.
|
|
984
|
+
*
|
|
985
|
+
* Important behavior: this only restores prior context. It does not call
|
|
986
|
+
* `summarize()` automatically, even if the restored conversation already
|
|
987
|
+
* exceeds summarization thresholds.
|
|
988
|
+
* @param {Object} config - createSession config
|
|
989
|
+
*/
|
|
990
|
+
_initKeepHistory(config: DHAny): Promise<void>;
|
|
991
|
+
/**
|
|
992
|
+
* Parse history.md markdown back into session messages.
|
|
993
|
+
* Expects `<!-- ts:YYYY-MM-DD HH:mm:ss -->` timestamps before ## User sections.
|
|
994
|
+
* If a message pair is older than 2 hours, the user message content is
|
|
995
|
+
* prefixed with `[YYYY-MM-DD HH:mm]` so the LLM has temporal context.
|
|
996
|
+
* @param {string} md - Raw markdown content
|
|
997
|
+
* @returns {Array<{ role: string, content: string, _ts?: number }>}
|
|
998
|
+
*/
|
|
999
|
+
_parseHistoryMd(md: DHAny): ({
|
|
1000
|
+
role: string;
|
|
1001
|
+
content: any;
|
|
1002
|
+
_ts: number;
|
|
1003
|
+
} | {
|
|
1004
|
+
role: string;
|
|
1005
|
+
content: any;
|
|
1006
|
+
_ts?: undefined;
|
|
1007
|
+
})[];
|
|
1008
|
+
/**
|
|
1009
|
+
* Save current conversation messages to history.md in the workspace.
|
|
1010
|
+
* Called after each message round completes.
|
|
1011
|
+
* Only saves the most recent `historyLength` rounds (user+assistant pairs).
|
|
1012
|
+
* @param {Object} [options]
|
|
1013
|
+
* @param {boolean} [options.skipDailyFile=false] - Skip daily file writes (used after summarization)
|
|
1014
|
+
*/
|
|
1015
|
+
_saveKeepHistory(options?: DHAny): Promise<void>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Called when any summarization completes (manual, auto, silentTick).
|
|
1018
|
+
* Updates the keepHistory cutoff so _saveKeepHistory won't re-save
|
|
1019
|
+
* messages that the summarize agent has already processed.
|
|
1020
|
+
* Also trims history.md to remove already-summarized content.
|
|
1021
|
+
* @param {Object} result - Summarization result with summarizeBeginTime
|
|
1022
|
+
*/
|
|
1023
|
+
_onSummarizeComplete(result: DHAny): void;
|
|
1024
|
+
/**
|
|
1025
|
+
* Keep exactly one system message at the start of the chat history.
|
|
1026
|
+
* This avoids losing the configured prompt when sessions are recreated or
|
|
1027
|
+
* when callers mix pre-seeded messages with DigitalHuman-managed prompts.
|
|
1028
|
+
* @param {string} prompt
|
|
1029
|
+
*/
|
|
1030
|
+
_syncSessionSystemPrompt(prompt: DHAny): void;
|
|
1031
|
+
/**
|
|
1032
|
+
* Create a new AI chat session.
|
|
1033
|
+
* @param {Object} config - Session configuration
|
|
1034
|
+
* @param {string} [config.system_prompt] - System prompt
|
|
1035
|
+
* @param {string|Object} [config.llm_model] - LLM model name or config object
|
|
1036
|
+
* @param {Object} [config.tools] - Tool configuration { fileOps: { enabled, workspace }, ... }
|
|
1037
|
+
* @param {boolean|Object} [config.bracketAction] - `true` emits bracketAction events; object form also supports autoplay/duration; parsing is limited to the first 500 words
|
|
1038
|
+
* @param {boolean|Object} [config.textToSpeech] - Non-RTC assistant reply speech; `true` enables SpeechRTC defaults, object form accepts `speechRTC` or `speech` provider options
|
|
1039
|
+
* @param {boolean|Object} [config.keepHistory] - Persist conversation to history.md in workspace; `true` or `{ historyLength, fileName, keepFullHistory }`
|
|
1040
|
+
* @param {boolean} [config.keepFullHistory] - Also persist full daily history to history/history_YYYYMMDD.md
|
|
1041
|
+
* @returns {Promise<Object>} The created ChatSession
|
|
1042
|
+
*/
|
|
1043
|
+
createSession(config?: DHAny): Promise<any>;
|
|
1044
|
+
/**
|
|
1045
|
+
* Unified send — auto-routes to voice or text session.
|
|
1046
|
+
*
|
|
1047
|
+
* When voice chat is active, sends via the RTC voice channel by default and
|
|
1048
|
+
* also records the user message into the canonical text ChatSession so history
|
|
1049
|
+
* stays unified. When voice chat is inactive, sends through the text AIChat
|
|
1050
|
+
* session (identical to the legacy sendMessage behaviour).
|
|
1051
|
+
*
|
|
1052
|
+
* @param {string|Array} userMessage - Text or multimodal content
|
|
1053
|
+
* @param {Object} [options]
|
|
1054
|
+
* @param {boolean} [options.voice] - Force voice (true) or text (false); auto-detect if omitted
|
|
1055
|
+
* @param {boolean} [options.awaitResponse] - Voice mode only: if true, wait for the assistant's complete subtitle turn before resolving
|
|
1056
|
+
* @param {boolean} [options.skipHistory] - Skip session/keepHistory persistence for this message round
|
|
1057
|
+
* @param {Array} [options.tools] - Additional tool definitions (text mode)
|
|
1058
|
+
* @param {string} [options.model] - Override model (text mode)
|
|
1059
|
+
* @param {boolean} [options.skipIfMessageTextEmpty] - Text mode: skip when runCode resolves to an empty string
|
|
1060
|
+
* @param {boolean|Object} [options.textToSpeech] - Override non-RTC assistant reply speech; object form accepts `speechRTC` or `speech` provider options. Set `autoReadReply: false` to disable automatic reply playback for this send.
|
|
1061
|
+
* @param {boolean|Object} [options.bracketAction] - Bracket action config
|
|
1062
|
+
* @returns {Promise<{ finalText: string, parsedResponse?: Object, mode: 'voice'|'text' }>}
|
|
1063
|
+
*/
|
|
1064
|
+
send(userMessage: DHAny, options?: DHAny): Promise<any>;
|
|
1065
|
+
_getUserMessageText(userMessage: DHAny): string;
|
|
1066
|
+
_emitUserMessage(userMessage: DHAny, mode?: string, extra?: DHAny): void;
|
|
1067
|
+
/**
|
|
1068
|
+
* Send a message through the voice RTC session.
|
|
1069
|
+
* Also mirrors the user message into the text ChatSession for unified history.
|
|
1070
|
+
* @private
|
|
1071
|
+
*/
|
|
1072
|
+
_sendViaVoice(userMessage: DHAny, options?: DHAny): Promise<{
|
|
1073
|
+
finalText: string;
|
|
1074
|
+
mode: string;
|
|
1075
|
+
skipped: boolean;
|
|
1076
|
+
reason: string | undefined;
|
|
1077
|
+
} | {
|
|
1078
|
+
finalText: unknown;
|
|
1079
|
+
mode: string;
|
|
1080
|
+
skipped?: undefined;
|
|
1081
|
+
reason?: undefined;
|
|
1082
|
+
}>;
|
|
1083
|
+
_beginTextSend(): {
|
|
1084
|
+
epoch: any;
|
|
1085
|
+
session: any;
|
|
1086
|
+
abortController: AbortController | null;
|
|
1087
|
+
canceled: boolean;
|
|
1088
|
+
reason: string;
|
|
1089
|
+
};
|
|
1090
|
+
_finishTextSend(state: DHAny): void;
|
|
1091
|
+
_isCurrentTextSend(state: DHAny): boolean;
|
|
1092
|
+
_cancelActiveTextSends(reason?: string): Promise<number>;
|
|
1093
|
+
_isTextSendAbort(error: DHAny): boolean;
|
|
1094
|
+
_clearQueuedTextSends(reason?: string): any;
|
|
1095
|
+
_sendViaText(userMessage: DHAny, options?: DHAny): Promise<any>;
|
|
1096
|
+
_drainTextSendQueue(): Promise<void>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Send a message through the text AIChat session (the full streaming path).
|
|
1099
|
+
* @private
|
|
1100
|
+
*/
|
|
1101
|
+
_sendViaTextNow(userMessage: DHAny, options?: DHAny): Promise<DHAny>;
|
|
1102
|
+
/**
|
|
1103
|
+
* Send a message via the text AI chat session with streaming callbacks emitted as events.
|
|
1104
|
+
* Backward-compatible alias — always uses the text path regardless of voice state.
|
|
1105
|
+
* @param {string|Array} userMessage - Text or multimodal content
|
|
1106
|
+
* @param {Object} [options]
|
|
1107
|
+
* @param {Array} [options.tools] - Additional tool definitions
|
|
1108
|
+
* @param {string} [options.model] - Override model for this request
|
|
1109
|
+
* @param {boolean} [options.runCode] - Process userMessage as template text, expanding ${...} expressions via sandbox
|
|
1110
|
+
* @param {boolean} [options.skipHistory] - Skip session/keepHistory persistence for this message round
|
|
1111
|
+
* @param {boolean|Object} [options.textToSpeech] - Override non-RTC assistant reply speech; object form accepts `speechRTC` or `speech` provider options
|
|
1112
|
+
* @param {boolean|Object} [options.bracketAction] - Override bracketAction behavior for this request; object form supports autoplay/duration; parsing is limited to the first 500 words
|
|
1113
|
+
* @returns {Promise<{ finalText: string, parsedResponse: Object }>}
|
|
1114
|
+
*/
|
|
1115
|
+
sendMessage(userMessage: DHAny, options?: DHAny): Promise<any>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Expand an inline system prompt using the iframe session's sandbox.
|
|
1118
|
+
* This ensures preview/debug views resolve ${...} the same way as the
|
|
1119
|
+
* actual in-iframe DigitalHuman session.
|
|
1120
|
+
* @param {string} text
|
|
1121
|
+
* @returns {Promise<string>}
|
|
1122
|
+
*/
|
|
1123
|
+
expandInlineSystemPrompt(text: DHAny): Promise<any>;
|
|
1124
|
+
/**
|
|
1125
|
+
* @returns {boolean} Whether voice chat is currently active
|
|
1126
|
+
*/
|
|
1127
|
+
get isActive(): any;
|
|
1128
|
+
/**
|
|
1129
|
+
* @returns {boolean} Whether voice chat is logically enabled, even if the RTC connection is paused while inactive
|
|
1130
|
+
*/
|
|
1131
|
+
get isVoiceChatModeActive(): any;
|
|
1132
|
+
get isVoiceChatActive(): boolean;
|
|
1133
|
+
/**
|
|
1134
|
+
* Start voice chat using AIChatRTC.
|
|
1135
|
+
* @param {Object} preset - Voice chat preset config (see AIChatRTC.createSession)
|
|
1136
|
+
* @param {string} preset.appId - VolcEngine AppId
|
|
1137
|
+
* @param {Object} [preset.agentConfig] - Agent config
|
|
1138
|
+
* @param {Object} [preset.config] - ASR/LLM/TTS/S2S config
|
|
1139
|
+
* @param {boolean|Object} [preset.bracketAction] - Apply bracketAction matching to AI messages; parsing is limited to the first 500 words
|
|
1140
|
+
* @param {string[]} [preset.enabledToolCategories] - Tool categories
|
|
1141
|
+
* @param {string} [preset.workspace] - Tool workspace
|
|
1142
|
+
* @returns {Promise<Object>} The RTC session
|
|
1143
|
+
*/
|
|
1144
|
+
/**
|
|
1145
|
+
* Default ASR/LLM/TTS config for voice chat (asr_llm_tts mode).
|
|
1146
|
+
* Used when `preset.config` is not provided in `startVoiceChat()`.
|
|
1147
|
+
*/
|
|
1148
|
+
static DEFAULT_VOICE_CHAT_CONFIG: {
|
|
1149
|
+
appId: string;
|
|
1150
|
+
agentUserId: string;
|
|
1151
|
+
agentConfig: {
|
|
1152
|
+
UserId: string;
|
|
1153
|
+
EnableConversationStateCallback: boolean;
|
|
1154
|
+
};
|
|
1155
|
+
config: {
|
|
1156
|
+
ASRConfig: {
|
|
1157
|
+
Provider: string;
|
|
1158
|
+
ProviderParams: {
|
|
1159
|
+
Mode: string;
|
|
1160
|
+
AppId: string;
|
|
1161
|
+
ApiResourceId: string;
|
|
1162
|
+
};
|
|
1163
|
+
};
|
|
1164
|
+
TTSConfig: {
|
|
1165
|
+
Provider: string;
|
|
1166
|
+
ProviderParams: {
|
|
1167
|
+
app: {
|
|
1168
|
+
appid: string;
|
|
1169
|
+
};
|
|
1170
|
+
audio: {
|
|
1171
|
+
voice_type: string;
|
|
1172
|
+
speech_rate: number;
|
|
1173
|
+
};
|
|
1174
|
+
ResourceId: string;
|
|
1175
|
+
};
|
|
1176
|
+
};
|
|
1177
|
+
LLMConfig: {
|
|
1178
|
+
Mode: string;
|
|
1179
|
+
EndPointId: string;
|
|
1180
|
+
VisionConfig: {
|
|
1181
|
+
Enable: boolean;
|
|
1182
|
+
};
|
|
1183
|
+
ThinkingType: string;
|
|
1184
|
+
Tools: never[];
|
|
1185
|
+
};
|
|
1186
|
+
SubtitleConfig: {
|
|
1187
|
+
SubtitleMode: number;
|
|
1188
|
+
};
|
|
1189
|
+
InterruptMode: number;
|
|
1190
|
+
};
|
|
1191
|
+
};
|
|
1192
|
+
/**
|
|
1193
|
+
* Build a complete voice chat preset by merging caller-supplied high-level
|
|
1194
|
+
* params (system_prompt, llm_model, workspace, tools, etc.) onto the
|
|
1195
|
+
* DEFAULT_VOICE_CHAT_CONFIG. If the caller already supplies `preset.config`
|
|
1196
|
+
* the default config block is skipped entirely so existing call-sites keep working.
|
|
1197
|
+
* @param {Object} preset - Caller-supplied preset
|
|
1198
|
+
* @returns {Object} Merged preset ready for AIChatRTC.createSession()
|
|
1199
|
+
*/
|
|
1200
|
+
_buildVoiceChatPreset(preset: DHAny): any;
|
|
1201
|
+
startVoiceChat(preset?: DHAny, options?: DHAny): Promise<DHAny>;
|
|
1202
|
+
/**
|
|
1203
|
+
* Stop voice chat.
|
|
1204
|
+
* @returns {Promise<void>}
|
|
1205
|
+
*/
|
|
1206
|
+
stopVoiceChat(): Promise<void>;
|
|
1207
|
+
handleAuthStateChange(change?: DHAny): Promise<any>;
|
|
1208
|
+
reloadForAuthChange(change?: DHAny): Promise<any>;
|
|
1209
|
+
/**
|
|
1210
|
+
* Restart the voice chat session with optional config overrides.
|
|
1211
|
+
* When possible, updates the active RTC agent in place via UpdateVoiceChat
|
|
1212
|
+
* so the room connection is kept alive. Falls back to a full restart if the
|
|
1213
|
+
* update API is unavailable or fails. Useful when the system prompt,
|
|
1214
|
+
* LLM config, or conversation history has changed (e.g. after
|
|
1215
|
+
* summarize-agent completes in replace mode, or when enabling vision).
|
|
1216
|
+
*
|
|
1217
|
+
* @param {Object} [configOverrides] - Partial preset overrides to deep-merge
|
|
1218
|
+
* into `_lastVoiceChatPreset`. Nested objects under `config` are merged
|
|
1219
|
+
* recursively; all other top-level keys are shallow-merged.
|
|
1220
|
+
* @returns {Promise<Object>} The new RTC session
|
|
1221
|
+
*/
|
|
1222
|
+
restartVoiceChat(configOverrides?: DHAny): Promise<any>;
|
|
1223
|
+
/** @private */
|
|
1224
|
+
_resolveRestartAgentPromptFile(promptFile: DHAny): string | null;
|
|
1225
|
+
/** @private */
|
|
1226
|
+
_cancelRestartAgentDebounce(result?: DHAny): boolean;
|
|
1227
|
+
/** @private */
|
|
1228
|
+
_getRestartAgentDedupeMs(options?: DHAny): number;
|
|
1229
|
+
/** @private */
|
|
1230
|
+
_getRestartAgentDedupeKey(promptFile: DHAny, tools?: DHAny[]): string | null;
|
|
1231
|
+
/** @private */
|
|
1232
|
+
_buildRestartAgentSkippedResult(promptFile: DHAny, tools: DHAny, reason: DHAny, extra?: DHAny): any;
|
|
1233
|
+
/**
|
|
1234
|
+
* Restart the agent session with an optional prompt file.
|
|
1235
|
+
* Handles both voice and text chat modes — stops voice if active,
|
|
1236
|
+
* re-initializes via initFromConfig, then restarts voice if it was active.
|
|
1237
|
+
*
|
|
1238
|
+
* @param {string} [promptFile] - URL or path to an agent config file (.json/.yml/.yaml/.md).
|
|
1239
|
+
* If empty, uses the current pageRouters entry agent first, then falls back to the current characterConfig.
|
|
1240
|
+
* @param {string[]} [tools] - Optional tool category override. Empty means inherit defaults.
|
|
1241
|
+
* @param {Object} [options]
|
|
1242
|
+
* @param {number} [options.debounceMs=0] - Delay empty-prompt restarts; cancelled by any later explicit prompt restart.
|
|
1243
|
+
* @param {boolean} [options.autoContinue=true] - Automatically send "(continue)" after a prompt-file restart.
|
|
1244
|
+
* @returns {Promise<Object>} { configSource, mode }
|
|
1245
|
+
*/
|
|
1246
|
+
restartAgent(promptFile: DHAny, tools: DHAny, options?: DHAny): Promise<any>;
|
|
1247
|
+
/** @private */
|
|
1248
|
+
_restartAgentImpl(promptFile: DHAny, tools: DHAny, options?: DHAny): Promise<{
|
|
1249
|
+
mode: string;
|
|
1250
|
+
loaded: boolean;
|
|
1251
|
+
configSource: any;
|
|
1252
|
+
workspace: any;
|
|
1253
|
+
mountFolder: any;
|
|
1254
|
+
toolCategories: string[];
|
|
1255
|
+
}>;
|
|
1256
|
+
/**
|
|
1257
|
+
* Send text during voice chat.
|
|
1258
|
+
* Also mirrors the user message into the canonical text ChatSession.
|
|
1259
|
+
* @param {string} text
|
|
1260
|
+
*/
|
|
1261
|
+
sendText(text: DHAny): void;
|
|
1262
|
+
/**
|
|
1263
|
+
* Send text to TTS (text-to-speech) and play it through the avatar.
|
|
1264
|
+
* - Voice chat active: delegates to RTCChatSession.sendTTS (binary/REST).
|
|
1265
|
+
* - Text mode: queues the text through the text-mode speech pipeline
|
|
1266
|
+
* (same as assistant responses) so the avatar speaks it out.
|
|
1267
|
+
* @param {string} text
|
|
1268
|
+
* @param {Object} [options]
|
|
1269
|
+
* @param {boolean} [options.useREST=false] - Voice mode only: use REST API instead of binary channel
|
|
1270
|
+
* @param {number} [options.interruptMode] - Voice mode only: REST interrupt priority
|
|
1271
|
+
*/
|
|
1272
|
+
sendTTS(text: DHAny, options?: DHAny): any;
|
|
1273
|
+
/**
|
|
1274
|
+
* Get the current RTC voice chat session (for advanced control).
|
|
1275
|
+
* @returns {Object|null}
|
|
1276
|
+
*/
|
|
1277
|
+
getVoiceChatSession(): any;
|
|
1278
|
+
/**
|
|
1279
|
+
* Wait until the voice chat session has received its first state event
|
|
1280
|
+
* (UNKNOWN/0 or higher). Resolves immediately if already ready, or if
|
|
1281
|
+
* no voice session is active.
|
|
1282
|
+
* @param {number} [timeout=10000] - Max milliseconds to wait
|
|
1283
|
+
* @returns {Promise<boolean>} true if ready, false if timed out or no session
|
|
1284
|
+
*/
|
|
1285
|
+
waitUntilVoiceReady(timeout?: number): Promise<unknown>;
|
|
1286
|
+
/**
|
|
1287
|
+
* Mirror a voice chat turn into the canonical text ChatSession's messages array.
|
|
1288
|
+
* This keeps the text session as the single source of truth for conversation history.
|
|
1289
|
+
* User messages are committed only in IO pairs:
|
|
1290
|
+
* - queue one or more user inputs
|
|
1291
|
+
* - on assistant reply, merge queued user inputs into one message, then append assistant message
|
|
1292
|
+
* @param {'user'|'assistant'} role
|
|
1293
|
+
* @param {string} content
|
|
1294
|
+
* @param {Object} [extras] - Optional: { tool_calls, tool_call_id, source, skipHistory }
|
|
1295
|
+
*/
|
|
1296
|
+
_mirrorVoiceToTextSession(role: DHAny, content: DHAny, extras?: DHAny): void;
|
|
1297
|
+
/**
|
|
1298
|
+
* Build UserPrompts for LLMConfig from normalized text-session history.
|
|
1299
|
+
* The result is always strict user/assistant pairs. If the sequence starts
|
|
1300
|
+
* with an assistant message, an empty user turn is inserted ahead of it.
|
|
1301
|
+
* Consecutive same-role turns are merged before pairing.
|
|
1302
|
+
* @param {number} historyLength - Number of user/assistant pairs to include
|
|
1303
|
+
* @returns {Array<{ Role: string, Content: string }>}
|
|
1304
|
+
*/
|
|
1305
|
+
_buildUserPromptsForVoice(historyLength?: number): any[];
|
|
1306
|
+
/** Wire RTCChatSession events to DigitalHuman events. */
|
|
1307
|
+
_wireVCSessionEvents(session: DHAny, bracketActionOptions?: DHAny): void;
|
|
1308
|
+
/** Attach volume-based lip sync to the RTC engine for smooth mouth animation. */
|
|
1309
|
+
_attachVolumeLipSync(session: DHAny): void;
|
|
1310
|
+
/** Clean up avatar state (reusable — does not remove DOM). */
|
|
1311
|
+
cleanupAvatar(): void;
|
|
1312
|
+
/** Fully destroy the DigitalHuman instance. */
|
|
1313
|
+
destroy(): Promise<void>;
|
|
1314
|
+
}
|
|
1315
|
+
export {};
|
|
1316
|
+
//# sourceMappingURL=DigitalHuman.d.ts.map
|