hanc-webrtc-widgets 2.0.2 → 2.1.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 +123 -460
- package/dist/hanc-webrtc-widgets.es.js +27994 -8129
- package/dist/hanc-webrtc-widgets.umd.js +4597 -494
- package/dist/src/components/floating-call/floating-call.d.ts +3 -72
- package/dist/src/components/index.d.ts +3 -0
- package/dist/src/components/inline-call/inline-call.d.ts +3 -65
- package/dist/src/components/orb-widget.d.ts +59 -0
- package/dist/src/components/pill-call/index.d.ts +1 -0
- package/dist/src/components/pill-call/pill-call.d.ts +4 -0
- package/dist/src/core/livekit-call-manager.d.ts +39 -0
- package/dist/src/orb/components/HancAiWidget.d.ts +120 -0
- package/dist/src/orb/components/index.d.ts +3 -0
- package/dist/src/orb/core/AudioAnalyzer.d.ts +68 -0
- package/dist/src/orb/core/LiveKitManager.d.ts +46 -0
- package/dist/src/orb/core/OrbRenderer.d.ts +86 -0
- package/dist/src/orb/core/SoundManager.d.ts +55 -0
- package/dist/src/orb/core/index.d.ts +8 -0
- package/dist/src/orb/index.d.ts +5 -0
- package/dist/src/orb/shaders/glow.glsl.d.ts +4 -0
- package/dist/src/orb/shaders/index.d.ts +3 -0
- package/dist/src/orb/shaders/orb.frag.glsl.d.ts +1 -0
- package/dist/src/orb/shaders/orb.vert.glsl.d.ts +1 -0
- package/package.json +4 -2
- package/dist/src/components/floating-call/styles.d.ts +0 -6
- package/dist/src/components/inline-call/styles.d.ts +0 -1
|
@@ -1,74 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare class FloatingCall extends LitElement {
|
|
4
|
-
static styles: import('lit').CSSResult[];
|
|
5
|
-
private callManager;
|
|
6
|
-
agentId: string;
|
|
7
|
-
voiceServiceUrl?: string;
|
|
8
|
-
/** New design API (optional, non-breaking) */
|
|
9
|
-
theme: ThemeName | 'custom';
|
|
10
|
-
visualStyle: VisualStyle;
|
|
11
|
-
position: WidgetPosition;
|
|
12
|
-
offsetX: number;
|
|
13
|
-
offsetY: number;
|
|
14
|
-
orbSize: number;
|
|
15
|
-
orbColor?: string;
|
|
16
|
-
orbColorLight?: string;
|
|
17
|
-
orbColorDark?: string;
|
|
18
|
-
hideButton: boolean;
|
|
19
|
-
buttonPosition: ButtonPosition;
|
|
20
|
-
activeOrbColor?: string;
|
|
21
|
-
activeOrbColorLight?: string;
|
|
22
|
-
activeOrbColorDark?: string;
|
|
23
|
-
buttonColor?: string;
|
|
24
|
-
buttonHoverColor?: string;
|
|
25
|
-
buttonActiveColor?: string;
|
|
26
|
-
buttonTextColor?: string;
|
|
27
|
-
minimized: boolean;
|
|
28
|
-
private callStatus;
|
|
29
|
-
private prefersLightScheme;
|
|
30
|
-
private colorSchemeQuery;
|
|
31
|
-
private renderer;
|
|
32
|
-
private audioSimTimer;
|
|
33
|
-
private audioSimFrameId;
|
|
34
|
-
private audioSimPhase;
|
|
35
|
-
private simulatedTargetLevel;
|
|
36
|
-
private simulatedCurrentLevel;
|
|
37
|
-
private baseColors;
|
|
38
|
-
private themeColors;
|
|
39
|
-
private baseAnimation;
|
|
40
|
-
private get callState();
|
|
1
|
+
import { HancAiOrbElement } from '../orb-widget';
|
|
2
|
+
export declare class FloatingCall extends HancAiOrbElement {
|
|
41
3
|
labelText: string;
|
|
42
|
-
|
|
43
|
-
buttonConnectingText: string;
|
|
44
|
-
buttonEndText: string;
|
|
45
|
-
private handleColorSchemeChange;
|
|
46
|
-
connectedCallback(): void;
|
|
47
|
-
disconnectedCallback(): void;
|
|
48
|
-
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
49
|
-
firstUpdated(): void;
|
|
50
|
-
private setupRenderer;
|
|
51
|
-
private setupColorSchemeListener;
|
|
52
|
-
private teardownColorSchemeListener;
|
|
53
|
-
private clamp;
|
|
54
|
-
private resolveColorValue;
|
|
55
|
-
private buildOrbPalette;
|
|
56
|
-
private getBaseOrbColors;
|
|
57
|
-
private getActiveSeedColor;
|
|
58
|
-
private getActiveColors;
|
|
59
|
-
private getButtonColors;
|
|
60
|
-
private updateButtonThemeVars;
|
|
61
|
-
private getAnimationForState;
|
|
62
|
-
private syncOrbAppearance;
|
|
63
|
-
private handleStatusChange;
|
|
64
|
-
/**
|
|
65
|
-
* Audio animation (MVP): simulate audio level while connected.
|
|
66
|
-
* Later you can replace this with real RMS from mic/remote track.
|
|
67
|
-
*/
|
|
68
|
-
private startAudioSimulation;
|
|
69
|
-
private stopAudioSimulation;
|
|
70
|
-
private toggleCall;
|
|
71
|
-
private get isActive();
|
|
72
|
-
private get buttonText();
|
|
73
|
-
render(): import('lit').TemplateResult<1>;
|
|
4
|
+
constructor();
|
|
74
5
|
}
|
|
@@ -1,66 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
static styles: import('lit').CSSResult[];
|
|
5
|
-
private callManager;
|
|
6
|
-
agentId: string;
|
|
7
|
-
voiceServiceUrl?: string;
|
|
8
|
-
/** New design API (optional, non-breaking) */
|
|
9
|
-
theme: ThemeName | 'custom';
|
|
10
|
-
visualStyle: VisualStyle;
|
|
11
|
-
orbSize: number;
|
|
12
|
-
orbColor?: string;
|
|
13
|
-
orbColorLight?: string;
|
|
14
|
-
orbColorDark?: string;
|
|
15
|
-
hideButton: boolean;
|
|
16
|
-
buttonPosition: ButtonPosition;
|
|
17
|
-
activeOrbColor?: string;
|
|
18
|
-
activeOrbColorLight?: string;
|
|
19
|
-
activeOrbColorDark?: string;
|
|
20
|
-
buttonColor?: string;
|
|
21
|
-
buttonHoverColor?: string;
|
|
22
|
-
buttonActiveColor?: string;
|
|
23
|
-
buttonTextColor?: string;
|
|
24
|
-
private callStatus;
|
|
25
|
-
private prefersLightScheme;
|
|
26
|
-
private colorSchemeQuery;
|
|
27
|
-
private renderer;
|
|
28
|
-
private audioSimTimer;
|
|
29
|
-
private audioSimFrameId;
|
|
30
|
-
private audioSimPhase;
|
|
31
|
-
private simulatedTargetLevel;
|
|
32
|
-
private simulatedCurrentLevel;
|
|
33
|
-
private baseColors;
|
|
34
|
-
private themeColors;
|
|
35
|
-
private baseAnimation;
|
|
36
|
-
private get callState();
|
|
37
|
-
buttonStartText: string;
|
|
38
|
-
buttonConnectingText: string;
|
|
39
|
-
buttonEndText: string;
|
|
40
|
-
private handleColorSchemeChange;
|
|
41
|
-
connectedCallback(): void;
|
|
42
|
-
disconnectedCallback(): void;
|
|
43
|
-
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
44
|
-
firstUpdated(): void;
|
|
45
|
-
private setupRenderer;
|
|
46
|
-
private setupColorSchemeListener;
|
|
47
|
-
private teardownColorSchemeListener;
|
|
48
|
-
private clamp;
|
|
49
|
-
private resolveColorValue;
|
|
50
|
-
private buildOrbPalette;
|
|
51
|
-
private getBaseOrbColors;
|
|
52
|
-
private getActiveSeedColor;
|
|
53
|
-
private getActiveColors;
|
|
54
|
-
private getButtonColors;
|
|
55
|
-
private updateButtonThemeVars;
|
|
56
|
-
private getAnimationForState;
|
|
57
|
-
private syncOrbAppearance;
|
|
58
|
-
private applyNeuralNetworkTuning;
|
|
59
|
-
private startAudioSimulation;
|
|
60
|
-
private stopAudioSimulation;
|
|
61
|
-
private handleStatusChange;
|
|
62
|
-
private toggleCall;
|
|
63
|
-
private get isActive();
|
|
64
|
-
private get buttonText();
|
|
65
|
-
render(): import('lit').TemplateResult<1>;
|
|
1
|
+
import { HancAiOrbElement } from '../orb-widget';
|
|
2
|
+
export declare class InlineCall extends HancAiOrbElement {
|
|
3
|
+
constructor();
|
|
66
4
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { HancAiWidgetConfig, WidgetMode } from '../orb/components';
|
|
3
|
+
type ColorPreset = 'indigo' | 'cyan' | 'emerald' | 'rose' | 'amber';
|
|
4
|
+
type ThemeMode = 'auto' | 'dark' | 'light';
|
|
5
|
+
export declare class HancAiOrbElement extends LitElement {
|
|
6
|
+
static styles: import('lit').CSSResult[];
|
|
7
|
+
agentId: string;
|
|
8
|
+
voiceServiceUrl?: string;
|
|
9
|
+
size: number;
|
|
10
|
+
mode: WidgetMode;
|
|
11
|
+
position: NonNullable<HancAiWidgetConfig['position']>;
|
|
12
|
+
buttonText?: string;
|
|
13
|
+
activeButtonText?: string;
|
|
14
|
+
connectingText?: string;
|
|
15
|
+
buttonStartText?: string;
|
|
16
|
+
buttonEndText?: string;
|
|
17
|
+
buttonConnectingText?: string;
|
|
18
|
+
enableSounds: boolean;
|
|
19
|
+
soundVolume: number;
|
|
20
|
+
colors?: string;
|
|
21
|
+
orbConfig?: string;
|
|
22
|
+
theme: ThemeMode;
|
|
23
|
+
colorPreset: ColorPreset;
|
|
24
|
+
private orbContainer?;
|
|
25
|
+
private currentState;
|
|
26
|
+
private widget;
|
|
27
|
+
private themeQuery;
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
disconnectedCallback(): void;
|
|
30
|
+
firstUpdated(): void;
|
|
31
|
+
protected updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
32
|
+
render(): import('lit').TemplateResult<1>;
|
|
33
|
+
/**
|
|
34
|
+
* Programmatically start a call
|
|
35
|
+
*/
|
|
36
|
+
startCall(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Programmatically end the call
|
|
39
|
+
*/
|
|
40
|
+
endCall(): Promise<void>;
|
|
41
|
+
private initializeWidget;
|
|
42
|
+
private destroyWidget;
|
|
43
|
+
private buildConfig;
|
|
44
|
+
private resolveColors;
|
|
45
|
+
private parseColors;
|
|
46
|
+
private parseOrbConfig;
|
|
47
|
+
private applyHostStyles;
|
|
48
|
+
private getButtonText;
|
|
49
|
+
private getActiveButtonText;
|
|
50
|
+
private getConnectingText;
|
|
51
|
+
private applyThemeToWidget;
|
|
52
|
+
private setupThemeListener;
|
|
53
|
+
private teardownThemeListener;
|
|
54
|
+
private handleThemeChange;
|
|
55
|
+
private getResolvedTheme;
|
|
56
|
+
}
|
|
57
|
+
export declare class HancAiOrb extends HancAiOrbElement {
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './pill-call';
|
|
@@ -3,6 +3,45 @@ type CallStatus = 'idle' | 'connecting' | 'connected' | 'agent-connected' | 'dis
|
|
|
3
3
|
interface MakeCallOptions {
|
|
4
4
|
agentId: string;
|
|
5
5
|
}
|
|
6
|
+
export interface LiveKitCallManagerEvents {
|
|
7
|
+
'status-changed': CustomEvent<CallStatus>;
|
|
8
|
+
'room-connected': CustomEvent<{
|
|
9
|
+
roomName: string;
|
|
10
|
+
identity: string;
|
|
11
|
+
}>;
|
|
12
|
+
'agent-connected': CustomEvent<{
|
|
13
|
+
participant: string;
|
|
14
|
+
}>;
|
|
15
|
+
'agent-disconnected': CustomEvent<{
|
|
16
|
+
participant: string;
|
|
17
|
+
}>;
|
|
18
|
+
'participant-connected': CustomEvent<{
|
|
19
|
+
participant: string;
|
|
20
|
+
isAgent: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
'participant-disconnected': CustomEvent<{
|
|
23
|
+
participant: string;
|
|
24
|
+
isAgent: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
'audio-track-added': CustomEvent<{
|
|
27
|
+
participant: string;
|
|
28
|
+
element: HTMLMediaElement;
|
|
29
|
+
}>;
|
|
30
|
+
'audio-track-removed': CustomEvent<{
|
|
31
|
+
participant: string;
|
|
32
|
+
}>;
|
|
33
|
+
'audio-playback-status-changed': CustomEvent<{
|
|
34
|
+
canPlayback: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
'microphone-enabled': Event;
|
|
37
|
+
'microphone-disabled': Event;
|
|
38
|
+
'audio-enabled': Event;
|
|
39
|
+
'call-ended': Event;
|
|
40
|
+
disconnected: Event;
|
|
41
|
+
error: CustomEvent<{
|
|
42
|
+
error: string | null;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
6
45
|
export declare class LiveKitCallManager extends EventTarget {
|
|
7
46
|
private room;
|
|
8
47
|
private callStatus;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { OrbColors, OrbConfig } from '../core/OrbRenderer';
|
|
2
|
+
import { CallState, CallStartEvent, CallEndEvent } from '../core/LiveKitManager';
|
|
3
|
+
export type WidgetMode = 'inline' | 'float' | 'pill';
|
|
4
|
+
export type WidgetState = CallState;
|
|
5
|
+
export interface HancAiWidgetConfig {
|
|
6
|
+
agentId?: string;
|
|
7
|
+
voiceServiceUrl?: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
colors?: Partial<OrbColors>;
|
|
10
|
+
buttonText?: string;
|
|
11
|
+
activeButtonText?: string;
|
|
12
|
+
connectingText?: string;
|
|
13
|
+
position?: 'center' | 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
14
|
+
mode?: WidgetMode;
|
|
15
|
+
orbConfig?: Partial<OrbConfig>;
|
|
16
|
+
enableSounds?: boolean;
|
|
17
|
+
soundVolume?: number;
|
|
18
|
+
onCallStart?: (event: CallStartEvent) => void;
|
|
19
|
+
onCallEnd?: (event: CallEndEvent) => void;
|
|
20
|
+
onStateChange?: (state: CallState, previousState: CallState) => void;
|
|
21
|
+
onError?: (error: Error) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare class HancAiWidget {
|
|
24
|
+
private container;
|
|
25
|
+
private orbContainer;
|
|
26
|
+
private button;
|
|
27
|
+
private buttonIcon;
|
|
28
|
+
private buttonText;
|
|
29
|
+
private orbRenderer;
|
|
30
|
+
private audioAnalyzer;
|
|
31
|
+
private liveKitManager;
|
|
32
|
+
private soundManager;
|
|
33
|
+
private config;
|
|
34
|
+
private state;
|
|
35
|
+
private animationId;
|
|
36
|
+
private audioSimPhase;
|
|
37
|
+
private isAgentMode;
|
|
38
|
+
private readonly defaultConfig;
|
|
39
|
+
constructor(container: HTMLElement | string, config?: HancAiWidgetConfig);
|
|
40
|
+
private initializeLiveKit;
|
|
41
|
+
private dispatchEvent;
|
|
42
|
+
private createWidget;
|
|
43
|
+
private getFloatOffsets;
|
|
44
|
+
private createStandardWidget;
|
|
45
|
+
private createPillWidget;
|
|
46
|
+
private handlePillMouseEnter;
|
|
47
|
+
private handlePillMouseLeave;
|
|
48
|
+
private createButton;
|
|
49
|
+
private getLogoIcon;
|
|
50
|
+
private getPhoneOffIcon;
|
|
51
|
+
private handleButtonHover;
|
|
52
|
+
private handleButtonLeave;
|
|
53
|
+
private handleMouseEnter;
|
|
54
|
+
private handleMouseLeave;
|
|
55
|
+
private handleClick;
|
|
56
|
+
/**
|
|
57
|
+
* Start a call to the AI agent
|
|
58
|
+
*/
|
|
59
|
+
startCall(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* End the current call
|
|
62
|
+
*/
|
|
63
|
+
endCall(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Connect to a real audio stream (for external WebRTC integration)
|
|
66
|
+
*/
|
|
67
|
+
connectAudioStream(stream: MediaStream): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Disconnect external audio stream
|
|
70
|
+
*/
|
|
71
|
+
disconnectAudioStream(): void;
|
|
72
|
+
private setState;
|
|
73
|
+
private updateUI;
|
|
74
|
+
private updatePillUI;
|
|
75
|
+
private addSpinnerAnimation;
|
|
76
|
+
private startIdleAnimation;
|
|
77
|
+
private startAudioSimulation;
|
|
78
|
+
private stopAudioSimulation;
|
|
79
|
+
private startRealAudioLoop;
|
|
80
|
+
/**
|
|
81
|
+
* Get current call state
|
|
82
|
+
*/
|
|
83
|
+
getState(): CallState;
|
|
84
|
+
/**
|
|
85
|
+
* Check if connected to an agent
|
|
86
|
+
*/
|
|
87
|
+
isConnected(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Set widget colors
|
|
90
|
+
*/
|
|
91
|
+
setColors(colors: Partial<OrbColors>): void;
|
|
92
|
+
/**
|
|
93
|
+
* Set glow settings (useful for light/dark theme switching)
|
|
94
|
+
*/
|
|
95
|
+
setGlowSettings(glowIntensity: number, idleGlowMultiplier: number): void;
|
|
96
|
+
/**
|
|
97
|
+
* Enable or disable call sounds
|
|
98
|
+
*/
|
|
99
|
+
setSoundsEnabled(enabled: boolean): void;
|
|
100
|
+
/**
|
|
101
|
+
* Set sound volume (0.0 - 1.0)
|
|
102
|
+
*/
|
|
103
|
+
setSoundVolume(volume: number): void;
|
|
104
|
+
/**
|
|
105
|
+
* Check if sounds are enabled
|
|
106
|
+
*/
|
|
107
|
+
isSoundsEnabled(): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Connect microphone for real audio input (demo mode)
|
|
110
|
+
*/
|
|
111
|
+
connectMicrophone(): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Disconnect microphone
|
|
114
|
+
*/
|
|
115
|
+
disconnectMicrophone(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Cleanup
|
|
118
|
+
*/
|
|
119
|
+
destroy(): void;
|
|
120
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface AudioData {
|
|
2
|
+
bass: number;
|
|
3
|
+
mid: number;
|
|
4
|
+
treble: number;
|
|
5
|
+
level: number;
|
|
6
|
+
waveform: Float32Array;
|
|
7
|
+
frequency: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
export interface AudioAnalyzerOptions {
|
|
10
|
+
fftSize?: number;
|
|
11
|
+
smoothingTimeConstant?: number;
|
|
12
|
+
minDecibels?: number;
|
|
13
|
+
maxDecibels?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class AudioAnalyzer {
|
|
16
|
+
private audioContext;
|
|
17
|
+
private analyser;
|
|
18
|
+
private source;
|
|
19
|
+
private frequencyData;
|
|
20
|
+
private waveformData;
|
|
21
|
+
private smoothedBass;
|
|
22
|
+
private smoothedMid;
|
|
23
|
+
private smoothedTreble;
|
|
24
|
+
private smoothedLevel;
|
|
25
|
+
private readonly smoothingFactor;
|
|
26
|
+
private readonly options;
|
|
27
|
+
constructor(options?: AudioAnalyzerOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Initialize analyzer with a MediaStream
|
|
30
|
+
*/
|
|
31
|
+
connectStream(stream: MediaStream): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Connect to an audio element
|
|
34
|
+
*/
|
|
35
|
+
connectAudioElement(element: HTMLAudioElement): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Get current audio analysis data
|
|
38
|
+
*/
|
|
39
|
+
getAudioData(): AudioData;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate bass, mid, treble from frequency data
|
|
42
|
+
*/
|
|
43
|
+
private calculateFrequencyBands;
|
|
44
|
+
/**
|
|
45
|
+
* Calculate overall audio level
|
|
46
|
+
*/
|
|
47
|
+
private calculateOverallLevel;
|
|
48
|
+
/**
|
|
49
|
+
* Get peak level (useful for visualization spikes)
|
|
50
|
+
*/
|
|
51
|
+
getPeakLevel(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Check if audio context is active
|
|
54
|
+
*/
|
|
55
|
+
isActive(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Cleanup resources
|
|
58
|
+
*/
|
|
59
|
+
disconnect(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get raw AudioContext for advanced usage
|
|
62
|
+
*/
|
|
63
|
+
getAudioContext(): AudioContext | null;
|
|
64
|
+
/**
|
|
65
|
+
* Get raw AnalyserNode for advanced usage
|
|
66
|
+
*/
|
|
67
|
+
getAnalyser(): AnalyserNode | null;
|
|
68
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type CallState = 'idle' | 'connecting' | 'active' | 'ending' | 'error';
|
|
2
|
+
export interface CallStartEvent {
|
|
3
|
+
agentId: string;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
}
|
|
6
|
+
export interface CallEndEvent {
|
|
7
|
+
agentId: string;
|
|
8
|
+
duration: number;
|
|
9
|
+
reason: 'user' | 'agent' | 'error';
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
export interface LiveKitConfig {
|
|
13
|
+
agentId: string;
|
|
14
|
+
voiceServiceUrl: string;
|
|
15
|
+
}
|
|
16
|
+
export interface LiveKitManagerCallbacks {
|
|
17
|
+
onStateChange?: (state: CallState, previousState: CallState) => void;
|
|
18
|
+
onCallStart?: (event: CallStartEvent) => void;
|
|
19
|
+
onCallEnd?: (event: CallEndEvent) => void;
|
|
20
|
+
onAudioTrack?: (stream: MediaStream) => void;
|
|
21
|
+
onError?: (error: Error) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare class LiveKitManager {
|
|
24
|
+
private callManager;
|
|
25
|
+
private config;
|
|
26
|
+
private callbacks;
|
|
27
|
+
private state;
|
|
28
|
+
private callStartTime;
|
|
29
|
+
private callEndReason;
|
|
30
|
+
private hasStarted;
|
|
31
|
+
private hasFinished;
|
|
32
|
+
private readonly eventHandlers;
|
|
33
|
+
constructor(callbacks?: LiveKitManagerCallbacks);
|
|
34
|
+
configure(config: LiveKitConfig): void;
|
|
35
|
+
getState(): CallState;
|
|
36
|
+
isConnected(): boolean;
|
|
37
|
+
connect(): Promise<void>;
|
|
38
|
+
disconnect(reason?: CallEndEvent['reason']): Promise<void>;
|
|
39
|
+
destroy(): void;
|
|
40
|
+
private attachEventHandlers;
|
|
41
|
+
private detachEventHandlers;
|
|
42
|
+
private handleStatus;
|
|
43
|
+
private handleError;
|
|
44
|
+
private finishCall;
|
|
45
|
+
private setState;
|
|
46
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { AudioData } from './AudioAnalyzer';
|
|
2
|
+
export interface OrbColors {
|
|
3
|
+
primary: string;
|
|
4
|
+
secondary: string;
|
|
5
|
+
accent: string;
|
|
6
|
+
glow: string;
|
|
7
|
+
atmosphere: string;
|
|
8
|
+
depth?: string;
|
|
9
|
+
highlight?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface OrbConfig {
|
|
12
|
+
size?: number;
|
|
13
|
+
segments?: number;
|
|
14
|
+
colors?: Partial<OrbColors>;
|
|
15
|
+
morphStrength?: number;
|
|
16
|
+
noiseScale?: number;
|
|
17
|
+
noiseSpeed?: number;
|
|
18
|
+
glowIntensity?: number;
|
|
19
|
+
idleGlowMultiplier?: number;
|
|
20
|
+
fresnelPower?: number;
|
|
21
|
+
rotationSpeed?: number;
|
|
22
|
+
audioReactivity?: number;
|
|
23
|
+
audioSmoothing?: number;
|
|
24
|
+
idleMorphMultiplier?: number;
|
|
25
|
+
colorContrast?: number;
|
|
26
|
+
}
|
|
27
|
+
export declare class OrbRenderer {
|
|
28
|
+
private container;
|
|
29
|
+
private scene;
|
|
30
|
+
private camera;
|
|
31
|
+
private renderer;
|
|
32
|
+
private orb;
|
|
33
|
+
private glowMesh;
|
|
34
|
+
private orbMaterial;
|
|
35
|
+
private glowMaterial;
|
|
36
|
+
private config;
|
|
37
|
+
private animationId;
|
|
38
|
+
private clock;
|
|
39
|
+
private isActive;
|
|
40
|
+
private targetRotation;
|
|
41
|
+
private currentRotation;
|
|
42
|
+
private audioValues;
|
|
43
|
+
private readonly canvasPadding;
|
|
44
|
+
constructor(container: HTMLElement, config?: OrbConfig);
|
|
45
|
+
private createOrb;
|
|
46
|
+
/**
|
|
47
|
+
* Update audio data with smoothing
|
|
48
|
+
*/
|
|
49
|
+
updateAudio(audioData: AudioData): void;
|
|
50
|
+
/**
|
|
51
|
+
* Set simulated audio values (for demo/testing)
|
|
52
|
+
*/
|
|
53
|
+
setSimulatedAudio(bass: number, mid: number, treble: number, level: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Set active state
|
|
56
|
+
*/
|
|
57
|
+
setActive(active: boolean): void;
|
|
58
|
+
/**
|
|
59
|
+
* Update colors
|
|
60
|
+
*/
|
|
61
|
+
setColors(colors: Partial<OrbColors>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Update glow intensity settings (useful for light/dark theme switching)
|
|
64
|
+
*/
|
|
65
|
+
setGlowSettings(glowIntensity: number, idleGlowMultiplier: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Start animation loop
|
|
68
|
+
*/
|
|
69
|
+
start(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Stop animation loop
|
|
72
|
+
*/
|
|
73
|
+
stop(): void;
|
|
74
|
+
private animate;
|
|
75
|
+
private handleResize;
|
|
76
|
+
private handleMouseMove;
|
|
77
|
+
private handleMouseLeave;
|
|
78
|
+
/**
|
|
79
|
+
* Get the canvas element
|
|
80
|
+
*/
|
|
81
|
+
getCanvas(): HTMLCanvasElement;
|
|
82
|
+
/**
|
|
83
|
+
* Cleanup resources
|
|
84
|
+
*/
|
|
85
|
+
destroy(): void;
|
|
86
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SoundManager - Programmatic melodic sound generation for call events
|
|
3
|
+
* Uses Web Audio API for zero-dependency sound synthesis
|
|
4
|
+
*/
|
|
5
|
+
export interface SoundConfig {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
volume: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class SoundManager {
|
|
10
|
+
private audioContext;
|
|
11
|
+
private config;
|
|
12
|
+
constructor(config?: Partial<SoundConfig>);
|
|
13
|
+
/**
|
|
14
|
+
* Initialize audio context (must be called from user interaction)
|
|
15
|
+
*/
|
|
16
|
+
private ensureContext;
|
|
17
|
+
/**
|
|
18
|
+
* Create an oscillator with envelope
|
|
19
|
+
*/
|
|
20
|
+
private createTone;
|
|
21
|
+
/**
|
|
22
|
+
* Play ascending melodic sound for call start
|
|
23
|
+
* C4 → E4 → G4 (C major chord arpeggio)
|
|
24
|
+
*/
|
|
25
|
+
playCallStartSound(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Play descending melodic sound for call end
|
|
28
|
+
* G4 → E4 → C4 (descending C major arpeggio)
|
|
29
|
+
*/
|
|
30
|
+
playCallEndSound(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Update configuration
|
|
33
|
+
*/
|
|
34
|
+
setConfig(config: Partial<SoundConfig>): void;
|
|
35
|
+
/**
|
|
36
|
+
* Enable or disable sounds
|
|
37
|
+
*/
|
|
38
|
+
setEnabled(enabled: boolean): void;
|
|
39
|
+
/**
|
|
40
|
+
* Set volume (0.0 - 1.0)
|
|
41
|
+
*/
|
|
42
|
+
setVolume(volume: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get current config
|
|
45
|
+
*/
|
|
46
|
+
getConfig(): SoundConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Check if sounds are enabled
|
|
49
|
+
*/
|
|
50
|
+
isEnabled(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Cleanup
|
|
53
|
+
*/
|
|
54
|
+
destroy(): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { AudioAnalyzer } from './AudioAnalyzer';
|
|
2
|
+
export type { AudioData, AudioAnalyzerOptions } from './AudioAnalyzer';
|
|
3
|
+
export { OrbRenderer } from './OrbRenderer';
|
|
4
|
+
export type { OrbConfig, OrbColors } from './OrbRenderer';
|
|
5
|
+
export { LiveKitManager } from './LiveKitManager';
|
|
6
|
+
export type { CallState, CallStartEvent, CallEndEvent, LiveKitConfig, LiveKitManagerCallbacks } from './LiveKitManager';
|
|
7
|
+
export { SoundManager } from './SoundManager';
|
|
8
|
+
export type { SoundConfig } from './SoundManager';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AudioAnalyzer, OrbRenderer, SoundManager } from './core';
|
|
2
|
+
export type { AudioData, AudioAnalyzerOptions, OrbConfig, OrbColors, SoundConfig } from './core';
|
|
3
|
+
export { HancAiWidget } from './components';
|
|
4
|
+
export type { HancAiWidgetConfig, WidgetState, WidgetMode } from './components';
|
|
5
|
+
export * from './shaders';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const glowVertexShader = "\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying float vIntensity;\n\nvoid main() {\n vNormal = normalize(normalMatrix * normal);\n vPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;\n\n // Scale up for glow halo\n vec3 pos = position * 1.3;\n\n // Pre-calculate view intensity for smooth falloff\n vec3 viewDir = normalize(-vPosition);\n vIntensity = pow(1.0 - abs(dot(viewDir, vNormal)), 1.5);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);\n}\n";
|
|
2
|
+
export declare const glowFragmentShader = "\nuniform float uTime;\nuniform float uAudioLevel;\nuniform vec3 uGlowColor;\nuniform float uGlowIntensity;\nuniform float uPulseSpeed;\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying float vIntensity;\n\nvoid main() {\n // Pulsing effect\n float pulse = sin(uTime * uPulseSpeed) * 0.1 + 0.9;\n pulse += uAudioLevel * 0.4;\n\n // Smooth radial glow using pre-calculated intensity\n float glow = vIntensity * uGlowIntensity * pulse;\n\n // Very soft falloff for diffuse glow\n glow = pow(glow, 0.8);\n glow *= smoothstep(0.0, 0.3, vIntensity);\n\n // Color with audio reactivity\n vec3 glowColor = uGlowColor * (1.0 + uAudioLevel * 0.5);\n\n // Softer alpha for more diffuse appearance\n gl_FragColor = vec4(glowColor, glow * 0.4);\n}\n";
|
|
3
|
+
export declare const atmosphereVertexShader = "\nvarying vec3 vNormal;\nvarying vec3 vPosition;\n\nvoid main() {\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n\n // Scale for outer atmosphere\n vec3 pos = position * 1.5;\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);\n}\n";
|
|
4
|
+
export declare const atmosphereFragmentShader = "\nuniform float uTime;\nuniform float uAudioLevel;\nuniform vec3 uAtmosphereColor;\nuniform float uAtmosphereIntensity;\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\n\nvoid main() {\n vec3 viewDirection = normalize(cameraPosition - vPosition);\n\n // Inverse fresnel for atmosphere (stronger at edges, fading to center)\n float intensity = pow(1.0 - max(dot(viewDirection, vNormal), 0.0), 3.0);\n\n // Audio pulsing\n float pulse = 1.0 + uAudioLevel * 0.4;\n\n // Breathing animation\n float breathing = sin(uTime * 0.5) * 0.1 + 0.9;\n\n float alpha = intensity * uAtmosphereIntensity * pulse * breathing;\n\n // Fade out at very edges\n alpha *= smoothstep(1.0, 0.3, intensity);\n\n vec3 color = uAtmosphereColor * (1.0 + uAudioLevel * 0.3);\n\n gl_FragColor = vec4(color, alpha * 0.4);\n}\n";
|