@minded-ai/mindedjs 1.0.52 → 1.0.53-patch-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/agent.d.ts +17 -9
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +75 -5
  4. package/dist/agent.js.map +1 -1
  5. package/dist/cli/index.js +0 -0
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  10. package/dist/nodes/addPromptNode.js +1 -0
  11. package/dist/nodes/addPromptNode.js.map +1 -1
  12. package/dist/platform/config.d.ts +3 -0
  13. package/dist/platform/config.d.ts.map +1 -1
  14. package/dist/platform/config.js +18 -1
  15. package/dist/platform/config.js.map +1 -1
  16. package/dist/platform/mindedConnection.d.ts +4 -4
  17. package/dist/platform/mindedConnection.d.ts.map +1 -1
  18. package/dist/platform/mindedConnection.js +8 -5
  19. package/dist/platform/mindedConnection.js.map +1 -1
  20. package/dist/platform/mindedConnectionTypes.d.ts +55 -2
  21. package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
  22. package/dist/platform/mindedConnectionTypes.js +11 -2
  23. package/dist/platform/mindedConnectionTypes.js.map +1 -1
  24. package/dist/types/Agent.types.d.ts +17 -0
  25. package/dist/types/Agent.types.d.ts.map +1 -1
  26. package/dist/types/Agent.types.js.map +1 -1
  27. package/dist/types/Flows.types.d.ts +12 -3
  28. package/dist/types/Flows.types.d.ts.map +1 -1
  29. package/dist/types/Flows.types.js +2 -0
  30. package/dist/types/Flows.types.js.map +1 -1
  31. package/dist/types/Voice.types.d.ts +5 -0
  32. package/dist/types/Voice.types.d.ts.map +1 -0
  33. package/dist/types/Voice.types.js +3 -0
  34. package/dist/types/Voice.types.js.map +1 -0
  35. package/dist/voice/elevenLabsUtils.d.ts +70 -0
  36. package/dist/voice/elevenLabsUtils.d.ts.map +1 -0
  37. package/dist/voice/elevenLabsUtils.js +20 -0
  38. package/dist/voice/elevenLabsUtils.js.map +1 -0
  39. package/dist/voice/voiceSession.d.ts +47 -0
  40. package/dist/voice/voiceSession.d.ts.map +1 -0
  41. package/dist/voice/voiceSession.js +208 -0
  42. package/dist/voice/voiceSession.js.map +1 -0
  43. package/package.json +5 -2
  44. package/src/agent.ts +91 -15
  45. package/src/index.ts +4 -0
  46. package/src/nodes/addPromptNode.ts +1 -0
  47. package/src/platform/config.ts +21 -1
  48. package/src/platform/mindedConnection.ts +15 -9
  49. package/src/platform/mindedConnectionTypes.ts +66 -2
  50. package/src/types/Agent.types.ts +18 -0
  51. package/src/types/Flows.types.ts +11 -1
  52. package/src/types/Voice.types.ts +4 -0
  53. package/src/voice/elevenLabsUtils.ts +101 -0
  54. package/src/voice/voiceSession.ts +251 -0
package/src/agent.ts CHANGED
@@ -11,11 +11,11 @@ import { edgeFactory } from './edges/edgeFactory';
11
11
  import { AgentEventRequestPayloads, AgentEventResponsePayloads, AgentEvents } from './events/AgentEvents';
12
12
  import { z } from 'zod';
13
13
  import { MindedConnection } from './platform/mindedConnection';
14
- import { BaseMindedConnectionSocketMessage, MindedConnectionSocketMessageType, OnAppTrigger } from './platform/mindedConnectionTypes';
14
+ import { BaseMindedConnectionSocketMessage, InvokeMessage, MindedConnectionSocketMessageType, OnAppTrigger } from './platform/mindedConnectionTypes';
15
15
  import * as fs from 'fs';
16
16
  import * as path from 'path';
17
17
  import * as yaml from 'js-yaml';
18
- import { FlowHistoryType, MindedSDKConfig, TriggerInvocationHistory } from './types/Agent.types';
18
+ import { AgentInvokeParams, FlowHistoryType, MindedSDKConfig, TriggerInvocationHistory } from './types/Agent.types';
19
19
  import { createLlmInstance } from './llm/createLlmInstance';
20
20
  import { createCheckpointSaver } from './checkpointer/checkpointSaverFactory';
21
21
  import { getConfig } from './platform/config';
@@ -23,6 +23,8 @@ import { BaseMessage, HumanMessage } from '@langchain/core/messages';
23
23
  import triggerTypeToDefaultMessage from './triggers/triggerTypeToDefaultMessage';
24
24
  import appActionRunnerToolCreator from './internalTools/appActionRunnerTool';
25
25
  import { wait } from './utils/wait';
26
+ import { VoiceSession } from './voice/voiceSession';
27
+ import { BaseVoiceMessage, OnVoiceAudioOut } from './platform/mindedConnectionTypes';
26
28
 
27
29
  type CreateAgentParams<Memory> = {
28
30
  memorySchema: z.ZodSchema;
@@ -55,13 +57,14 @@ export class Agent {
55
57
  private flows!: Flow[];
56
58
  public tools!: Tool<any, any>[];
57
59
  private llm!: BaseLanguageModel;
58
- private mindedConnection: MindedConnection | null = null;
60
+ public mindedConnection: MindedConnection | null = null;
59
61
  // Langgraph memory saver. In memory for local development, Custom for Platform
60
62
  private checkpointer!: BaseCheckpointSaver;
61
63
  // Langgraph compiled graph
62
- private compiledGraph!: CompiledGraph;
64
+ public compiledGraph!: CompiledGraph;
63
65
  // Cache for secrets to avoid repeated API calls
64
66
  private secretsCache: Record<string, string> | null = null;
67
+ public config: MindedSDKConfig;
65
68
 
66
69
  // Event handlers storage keyed by event name. Handlers can optionally return a value.
67
70
  private eventHandlers: {
@@ -73,6 +76,9 @@ export class Agent {
73
76
  private initialized = false;
74
77
  private initPromise: Promise<void> | null = null;
75
78
 
79
+ // Add the voiceSessions property to the Agent class (place near other class fields)
80
+ public voiceSessions: Map<string, VoiceSession> = new Map();
81
+
76
82
  /**
77
83
  * Create a new Agent instance.
78
84
  *
@@ -108,6 +114,7 @@ export class Agent {
108
114
  const { memorySchema } = params;
109
115
  this.memorySchema = memorySchema;
110
116
  this.initPromise = this.init(params);
117
+ this.config = params.config;
111
118
  }
112
119
 
113
120
  private async init(params: CreateAgentParams<z.infer<typeof this.memorySchema>>): Promise<void> {
@@ -127,6 +134,17 @@ export class Agent {
127
134
  sessionId: trigger.sessionId,
128
135
  });
129
136
  });
137
+
138
+ this.mindedConnection.on(MindedConnectionSocketMessageType.INVOKE, async (message, callback) => {
139
+ const invokeMessage = message as InvokeMessage;
140
+ const result = await this.invoke({
141
+ triggerBody: invokeMessage.triggerBody,
142
+ triggerName: invokeMessage.triggerName,
143
+ appName: invokeMessage.appName,
144
+ sessionId: invokeMessage.sessionId,
145
+ });
146
+ callback(result);
147
+ });
130
148
  }
131
149
  const [, flows] = (await Promise.all([this.loadSecrets(), this.loadFlows(config.flows)])) as [Record<string, string>, Flow[]];
132
150
  this.flows = flows;
@@ -139,6 +157,10 @@ export class Agent {
139
157
  this.llm = createLlmInstance(config.llm);
140
158
  this.compiledGraph = this.initializeGraph();
141
159
  this.initialized = true;
160
+
161
+ if (params.config.voice) {
162
+ this.setupVoice();
163
+ }
142
164
  } catch (error) {
143
165
  this.initialized = false;
144
166
  throw error;
@@ -318,16 +340,11 @@ export class Agent {
318
340
  triggerName,
319
341
  sessionId,
320
342
  appName,
321
- }: {
322
- triggerBody: any;
323
- triggerName: string;
324
- sessionId?: string;
325
- appName?: string;
326
- }) {
343
+ }: AgentInvokeParams) {
327
344
  await this.waitForInitialization();
328
345
  let messages: Array<BaseMessage> = [];
329
346
  let memoryUpdate = {};
330
- if (triggerName === KnownTriggerNames.DASHBOARD_MESSAGE) {
347
+ if (triggerName === KnownTriggerNames.DASHBOARD_MESSAGE || triggerName === KnownTriggerNames.VOICE_MESSAGE) {
331
348
  messages.push(new HumanMessage(triggerBody.content));
332
349
  } else {
333
350
  const results = await this.emit(AgentEvents.TRIGGER_EVENT, {
@@ -362,8 +379,8 @@ export class Agent {
362
379
  },
363
380
  ];
364
381
  console.log(`Invoking trigger ${triggerName} with session ${sessionId}`);
365
- const config = { configurable: { thread_id: sessionId || uuidv4(), recursionLimit: 3 } };
366
- const state = await this.compiledGraph.getState(config);
382
+ const langraphConfig = this.getLangraphConfig(sessionId || uuidv4());
383
+ const state = await this.compiledGraph.getState(langraphConfig);
367
384
  // Resume interruption
368
385
  if (state.tasks?.[0]?.interrupts?.length > 0) {
369
386
  console.log('Resuming interruption');
@@ -371,13 +388,13 @@ export class Agent {
371
388
  new Command({
372
389
  resume: { memory: memoryUpdate, messages, history, triggerInvocations: [triggerInvocation] },
373
390
  }),
374
- config,
391
+ langraphConfig,
375
392
  );
376
393
  return res;
377
394
  } else {
378
395
  const res = await this.compiledGraph.invoke(
379
396
  { messages, memory: memoryUpdate, history, triggerInvocations: [triggerInvocation] },
380
- config,
397
+ langraphConfig,
381
398
  );
382
399
  return res;
383
400
  }
@@ -597,4 +614,63 @@ export class Agent {
597
614
  throw new Error(`Failed to fetch secrets: ${error instanceof Error ? error.message : 'Unknown error'}`);
598
615
  }
599
616
  }
617
+
618
+ public getLangraphConfig(sessionId: string): { configurable: { thread_id: string; recursionLimit: number } } {
619
+ return { configurable: { thread_id: sessionId, recursionLimit: 3 } };
620
+ }
621
+
622
+ private setupVoice(): void {
623
+ if (!this.mindedConnection) {
624
+ throw new Error('Minded connection is required');
625
+ }
626
+
627
+ const connection = this.mindedConnection;
628
+ const { dashboardConnected } = getConfig();
629
+
630
+ if (dashboardConnected) {
631
+ // Listen for voice session start
632
+ connection.on(MindedConnectionSocketMessageType.DASHBOARD_VOICE_SESSION_START, async (message) => {
633
+ const sessionStart = message as BaseVoiceMessage;
634
+ await this.startVoiceSession({ sessionId: sessionStart.sessionId });
635
+ });
636
+
637
+ // Listen for incoming audio from the platform
638
+ connection.on(MindedConnectionSocketMessageType.DASHBOARD_VOICE_USER_AUDIO, (message) => {
639
+ const audioMessage = message as OnVoiceAudioOut;
640
+ const voiceSession = this.voiceSessions.get(audioMessage.sessionId);
641
+ if (voiceSession) {
642
+ voiceSession.sendAudio(audioMessage.audioData);
643
+ } else {
644
+ console.warn({ message: 'Voice session not found for sessionId', sessionId: audioMessage.sessionId });
645
+ }
646
+ });
647
+
648
+ // Hangup / end session handler
649
+ connection.on(MindedConnectionSocketMessageType.DASHBOARD_VOICE_SESSION_END, (message) => {
650
+ const hangup = message as BaseVoiceMessage;
651
+ const voiceSession = this.voiceSessions.get(hangup.sessionId);
652
+ if (voiceSession) {
653
+ voiceSession.hangup();
654
+ } else {
655
+ console.warn({ message: 'Voice session not found for sessionId', sessionId: hangup.sessionId });
656
+ }
657
+ });
658
+ }
659
+
660
+ }
661
+
662
+ private async startVoiceSession(params: { sessionId: string }): Promise<VoiceSession> {
663
+ if (!this.config.voice) {
664
+ throw new Error('Voice configuration is required');
665
+ }
666
+ const voiceSession = new VoiceSession({
667
+ agent: this,
668
+ sessionId: params.sessionId,
669
+ firstMessage: this.config.voice.firstMessage,
670
+ voiceId: this.config.voice.voiceId,
671
+ });
672
+ await voiceSession.init();
673
+ this.voiceSessions.set(params.sessionId, voiceSession);
674
+ return voiceSession;
675
+ }
600
676
  }
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Agent } from './agent';
2
2
  import events from './events';
3
3
 
4
+ export type { ElevenLabsContext } from './types/Voice.types';
4
5
  export { Agent, events };
5
6
 
6
7
  export type {
@@ -17,8 +18,11 @@ export type {
17
18
  JunctionNode,
18
19
  ToolNode,
19
20
  AppToolNode,
21
+ VoiceTriggerNode,
22
+ WebhookTriggerNode,
20
23
  } from './types/Flows.types';
21
24
  export { NodeType, TriggerType, EdgeType, AppNodeMetadata, AppNodeMetadataType, NodeMetadata, KnownTriggerNames } from './types/Flows.types';
22
25
  export type { Tool } from './types/Tools.types';
23
26
  export { FlowHistoryType, FlowHistory, TriggerInvocationHistory, AppActionInvocationHistory } from './types/Agent.types';
27
+ export type { AgentInvokeParams } from './types/Agent.types';
24
28
  export type { Environment } from './types/Platform.types';
@@ -81,6 +81,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit }: AddPrompt
81
81
  memory: state.memory,
82
82
  sessionId: configurable.thread_id,
83
83
  });
84
+ console.log('AI Message', result.content);
84
85
  }
85
86
 
86
87
  return {
@@ -1,7 +1,9 @@
1
1
  import { resolve } from 'path';
2
2
  import { config } from 'dotenv';
3
3
  import { Environment } from '../types/Platform.types';
4
- config({ path: resolve(__dirname, '../../.env') });
4
+ const path = resolve(__dirname, '../../.env');
5
+ console.log(`Loading config from ${path}`);
6
+ config({ path });
5
7
 
6
8
  type MindedConfig = {
7
9
  baseUrl: string;
@@ -9,6 +11,9 @@ type MindedConfig = {
9
11
  token: string | null;
10
12
  runLocally: boolean;
11
13
  isDeployed: boolean;
14
+ dashboardConnected: boolean;
15
+ elevenLabsKey: string | null;
16
+ elevenLabsAgentId: string | null;
12
17
  };
13
18
 
14
19
  export const getConfig = (): MindedConfig => {
@@ -21,6 +26,9 @@ export const getConfig = (): MindedConfig => {
21
26
  token: process.env.MINDED_CONNECTION_TOKEN || '',
22
27
  runLocally: process.env.RUN_LOCALLY !== 'false',
23
28
  isDeployed: process.env.IS_DEPLOYED_AGENT === 'true',
29
+ dashboardConnected: false,
30
+ elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
31
+ elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || null,
24
32
  };
25
33
  case 'development':
26
34
  return {
@@ -29,6 +37,9 @@ export const getConfig = (): MindedConfig => {
29
37
  token: process.env.MINDED_CONNECTION_TOKEN || '',
30
38
  runLocally: process.env.RUN_LOCALLY === 'true',
31
39
  isDeployed: process.env.IS_DEPLOYED_AGENT === 'true',
40
+ dashboardConnected: true,
41
+ elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
42
+ elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'Iyr6DCOj80AdvVEVHSGt',
32
43
  };
33
44
  case 'sandbox-staging':
34
45
  return {
@@ -37,6 +48,9 @@ export const getConfig = (): MindedConfig => {
37
48
  token: process.env.MINDED_CONNECTION_TOKEN || '',
38
49
  runLocally: false,
39
50
  isDeployed: process.env.IS_DEPLOYED_AGENT === 'true',
51
+ elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
52
+ dashboardConnected: true,
53
+ elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye194psezr909nwec27m2t9',
40
54
  };
41
55
  case 'sandbox':
42
56
  return {
@@ -45,6 +59,9 @@ export const getConfig = (): MindedConfig => {
45
59
  token: process.env.MINDED_CONNECTION_TOKEN || '',
46
60
  runLocally: false,
47
61
  isDeployed: process.env.IS_DEPLOYED_AGENT === 'true',
62
+ elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
63
+ dashboardConnected: true,
64
+ elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye194psezr909nwec27m2t9',
48
65
  };
49
66
  case 'production':
50
67
  return {
@@ -53,6 +70,9 @@ export const getConfig = (): MindedConfig => {
53
70
  token: process.env.MINDED_CONNECTION_TOKEN || '',
54
71
  runLocally: false,
55
72
  isDeployed: process.env.IS_DEPLOYED_AGENT === 'true',
73
+ elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
74
+ dashboardConnected: false,
75
+ elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye1ajkaf17axpcxg220qwcm',
56
76
  };
57
77
  }
58
78
  };
@@ -1,26 +1,29 @@
1
1
  import { io, Socket } from 'socket.io-client';
2
- import { BaseMindedConnectionSocketMessage, MindedConnectionSocketMessageType } from './mindedConnectionTypes';
2
+ import { BaseMindedConnectionSocketMessage, MindedConnectionSocketMessageType, MindedConnectionSocketMessageTypeMap } from './mindedConnectionTypes';
3
3
  import { stringify } from 'flatted';
4
4
  import { getConfig } from './config';
5
5
 
6
6
  export class MindedConnection {
7
7
  private socket: Socket | null = null;
8
8
  listeners: {
9
- [key: string]: ((message: BaseMindedConnectionSocketMessage) => void)[];
9
+ [key: string]: ((message: BaseMindedConnectionSocketMessage, callback: (response: any) => void) => void)[];
10
10
  } = {};
11
11
 
12
12
  public get isConnected(): boolean {
13
13
  return this.socket?.connected ?? false;
14
14
  }
15
15
 
16
- public on = (event: MindedConnectionSocketMessageType, callback: (message: BaseMindedConnectionSocketMessage) => void) => {
16
+ public on = (event: MindedConnectionSocketMessageType, callback: (message: BaseMindedConnectionSocketMessage, callback: (response: any) => void) => void) => {
17
17
  if (!this.listeners[event]) {
18
18
  this.listeners[event] = [];
19
19
  }
20
20
  this.listeners[event].push(callback);
21
21
  };
22
22
 
23
- public emit = (event: MindedConnectionSocketMessageType, message: BaseMindedConnectionSocketMessage) => {
23
+ public emit = <E extends keyof MindedConnectionSocketMessageTypeMap>(
24
+ event: E,
25
+ message: MindedConnectionSocketMessageTypeMap[E]
26
+ ) => {
24
27
  if (this.socket) {
25
28
  this.socket.emit(event, message);
26
29
  }
@@ -34,7 +37,7 @@ export class MindedConnection {
34
37
  return new Promise((resolve, reject) => {
35
38
  // Set up timeout
36
39
  const timeout = setTimeout(() => {
37
- reject(new Error(`Acknowledgement timeout after ${timeoutMs}ms`));
40
+ reject(new Error(`Acknowledgement timeout after ${timeoutMs}ms; Message: ${message}`));
38
41
  }, timeoutMs);
39
42
 
40
43
  // Emit with acknowledgement callback
@@ -70,8 +73,8 @@ export class MindedConnection {
70
73
  });
71
74
 
72
75
  this.socket.on('connect_error', () => {
73
- console.error('Failed to connect to minded platform');
74
- reject(new Error('Failed to connect to minded platform'));
76
+ console.error('Minded connection error');
77
+ reject(new Error('Minded connection error'));
75
78
  });
76
79
 
77
80
  this.socket.on('disconnect', () => {
@@ -96,12 +99,15 @@ export class MindedConnection {
96
99
  });
97
100
 
98
101
  // Listen for specific message types
99
- this.socket.onAny((event, message) => {
102
+ this.socket.onAny((event, message, callback) => {
100
103
  if (this.listeners[event]) {
101
104
  this.listeners[event].forEach((listener) => {
102
- listener(message);
105
+ listener(message, callback);
103
106
  });
104
107
  }
108
+ else {
109
+ console.warn({ message: 'No listeners found for event', event });
110
+ }
105
111
  });
106
112
 
107
113
  // Handle process termination
@@ -7,16 +7,43 @@ import type {
7
7
  CheckpointTuple,
8
8
  } from '@langchain/langgraph-checkpoint';
9
9
  import type { RunnableConfig } from '@langchain/core/runnables';
10
+ import { AgentInvokeParams } from '../types/Agent.types';
10
11
 
11
12
  export enum MindedConnectionSocketMessageType {
12
13
  OnAppTrigger = 'on-app-trigger',
13
14
  OnAppAction = 'on-app-action',
15
+ GET_SECRETS = 'get-secrets',
16
+ GET_FLOWS = 'get-flows',
17
+ INVOKE = 'invoke',
18
+ // Checkpoints
14
19
  CHECKPOINT_GET_TUPLE = 'checkpoint-get-tuple',
15
20
  CHECKPOINT_PUT = 'checkpoint-put',
16
21
  CHECKPOINT_LIST = 'checkpoint-list',
17
22
  CHECKPOINT_PUT_WRITES = 'checkpoint-put-writes',
18
- GET_SECRETS = 'get-secrets',
19
- GET_FLOWS = 'get-flows',
23
+ // Voice
24
+ DASHBOARD_VOICE_USER_AUDIO = 'dashboard-voice-user-audio',
25
+ DASHBOARD_VOICE_AGENT_AUDIO = 'dashboard-voice-agent-audio',
26
+ DASHBOARD_VOICE_SESSION_START = 'dashboard-voice-session-start',
27
+ DASHBOARD_VOICE_SESSION_END = 'dashboard-voice-session-end',
28
+ DASHBOARD_VOICE_INTERRUPTION = 'dashboard-voice-interruption',
29
+ DASHBOARD_VOICE_AGENT_RESPONSE_CORRECTION = 'dashboard-voice-agent-response-correction',
30
+ }
31
+
32
+ export type MindedConnectionSocketMessageTypeMap = {
33
+ [MindedConnectionSocketMessageType.OnAppTrigger]: OnAppTrigger;
34
+ [MindedConnectionSocketMessageType.OnAppAction]: BaseMindedConnectionSocketMessage;
35
+ [MindedConnectionSocketMessageType.GET_SECRETS]: BaseMindedConnectionSocketMessage;
36
+ [MindedConnectionSocketMessageType.GET_FLOWS]: BaseMindedConnectionSocketMessage;
37
+ [MindedConnectionSocketMessageType.INVOKE]: InvokeMessage;
38
+ [MindedConnectionSocketMessageType.CHECKPOINT_GET_TUPLE]: OnCheckpointGetTuple;
39
+ [MindedConnectionSocketMessageType.CHECKPOINT_PUT]: OnCheckpointPut;
40
+ [MindedConnectionSocketMessageType.CHECKPOINT_LIST]: OnCheckpointList;
41
+ [MindedConnectionSocketMessageType.CHECKPOINT_PUT_WRITES]: OnCheckpointPutWrites;
42
+ [MindedConnectionSocketMessageType.DASHBOARD_VOICE_USER_AUDIO]: OnVoiceAudioIn;
43
+ [MindedConnectionSocketMessageType.DASHBOARD_VOICE_AGENT_AUDIO]: OnVoiceAudioOut;
44
+ [MindedConnectionSocketMessageType.DASHBOARD_VOICE_SESSION_START]: BaseVoiceMessage;
45
+ [MindedConnectionSocketMessageType.DASHBOARD_VOICE_SESSION_END]: OnVoiceSessionEnd;
46
+ [MindedConnectionSocketMessageType.DASHBOARD_VOICE_INTERRUPTION]: OnVoiceInterruption;
20
47
  }
21
48
 
22
49
  export interface BaseMindedConnectionSocketMessage {
@@ -66,3 +93,40 @@ export interface OnCheckpointList extends BaseMindedConnectionSocketMessage {
66
93
  export interface OnCheckpointListResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
67
94
  checkpoints?: CheckpointTuple[];
68
95
  }
96
+
97
+ export interface BaseVoiceMessage extends BaseMindedConnectionSocketMessage {
98
+ sessionId: string;
99
+ timestamp: number;
100
+ }
101
+
102
+ // Voice/Audio event interfaces
103
+ export interface OnVoiceAudioIn extends BaseVoiceMessage {
104
+ audioData: string; // base64 encoded audio data
105
+ }
106
+
107
+ export interface OnVoiceAudioOut extends BaseVoiceMessage {
108
+ audioData: string; // base64 encoded audio data
109
+ }
110
+
111
+ export interface OnVoiceMessageIn extends BaseVoiceMessage {
112
+ text: string;
113
+ }
114
+
115
+ export interface OnVoiceMessageOut extends BaseMindedConnectionSocketMessage {
116
+ sessionId: string;
117
+ text: string;
118
+ timestamp: number;
119
+ }
120
+
121
+ export interface OnVoiceInterruption extends BaseMindedConnectionSocketMessage {
122
+ sessionId: string;
123
+ timestamp: number;
124
+ }
125
+ export interface OnVoiceSessionEnd extends BaseMindedConnectionSocketMessage {
126
+ sessionId: string;
127
+ timestamp: number;
128
+ }
129
+
130
+ export interface InvokeMessage extends BaseMindedConnectionSocketMessage, AgentInvokeParams {
131
+ type: MindedConnectionSocketMessageType.INVOKE;
132
+ }
@@ -7,6 +7,24 @@ export type MindedSDKConfig = {
7
7
  flows: string[];
8
8
  llm: LLMConfig;
9
9
  tools: string[];
10
+ voice?: {
11
+ firstMessage: string;
12
+ voiceId?: string;
13
+ }
14
+ }
15
+
16
+ /**
17
+ * Parameters for the Agent invoke method
18
+ */
19
+ export interface AgentInvokeParams {
20
+ /** The payload/data associated with the trigger */
21
+ triggerBody: any;
22
+ /** The name/type of the trigger being invoked */
23
+ triggerName: string;
24
+ /** Optional session identifier for conversation continuity */
25
+ sessionId?: string;
26
+ /** Optional name of the application triggering the agent in case of an app trigger */
27
+ appName?: string;
10
28
  }
11
29
 
12
30
  export enum FlowHistoryType {
@@ -30,6 +30,7 @@ export enum TriggerType {
30
30
  APP = 'app',
31
31
  WEBHOOK = 'webhook',
32
32
  MANUAL = 'manual',
33
+ VOICE = 'voice',
33
34
  }
34
35
 
35
36
  export interface BaseTriggerNode extends BaseNode {
@@ -56,6 +57,14 @@ export interface WebhookTriggerNode extends BaseTriggerNode {
56
57
  triggerType: TriggerType.WEBHOOK;
57
58
  }
58
59
 
60
+ export interface VoiceTriggerNode extends BaseTriggerNode {
61
+ triggerType: TriggerType.VOICE;
62
+ /**
63
+ * Text that will be spoken as the very first message in a voice interaction.
64
+ */
65
+ firstMessage: string;
66
+ }
67
+
59
68
  export interface ManualTriggerNode extends BaseTriggerNode {
60
69
  triggerType: TriggerType.MANUAL;
61
70
  }
@@ -66,7 +75,7 @@ export interface PromptNode extends BaseNode {
66
75
  llmConfig?: LLMConfig;
67
76
  }
68
77
 
69
- export type TriggerNode = AppTriggerNode | WebhookTriggerNode | ManualTriggerNode;
78
+ export type TriggerNode = AppTriggerNode | WebhookTriggerNode | ManualTriggerNode | VoiceTriggerNode;
70
79
 
71
80
  export interface JunctionNode extends BaseNode {
72
81
  type: NodeType.JUNCTION;
@@ -153,4 +162,5 @@ export interface Flow {
153
162
  export enum KnownTriggerNames {
154
163
  WEBHOOK = 'webhook',
155
164
  DASHBOARD_MESSAGE = 'dashboard_message',
165
+ VOICE_MESSAGE = 'voice_message',
156
166
  }
@@ -0,0 +1,4 @@
1
+ export type ElevenLabsContext = {
2
+ sessionId: string;
3
+ mindedToken: string;
4
+ }
@@ -0,0 +1,101 @@
1
+ /** ElevenLabs LLM proxy request body shape */
2
+ export interface LLMRequestBody {
3
+ messages: Array<{
4
+ content: string;
5
+ role: string;
6
+ tool_call_id?: string;
7
+ }>;
8
+ model: string;
9
+ max_tokens: number;
10
+ stream: boolean;
11
+ temperature: number;
12
+ tools: null;
13
+ }
14
+
15
+ // ----------------- ElevenLabs WebSocket event types -----------------
16
+
17
+ interface BaseEvent {
18
+ type: string;
19
+ }
20
+
21
+ interface UserTranscriptEvent extends BaseEvent {
22
+ type: 'user_transcript';
23
+ user_transcription_event: {
24
+ user_transcript: string;
25
+ };
26
+ }
27
+
28
+ interface AgentResponseEvent extends BaseEvent {
29
+ type: 'agent_response';
30
+ agent_response_event: {
31
+ agent_response: string;
32
+ };
33
+ }
34
+
35
+ interface AudioResponseEvent extends BaseEvent {
36
+ type: 'audio';
37
+ audio_event: {
38
+ audio_base_64: string;
39
+ event_id: number;
40
+ };
41
+ }
42
+
43
+ interface InterruptionEvent extends BaseEvent {
44
+ type: 'interruption';
45
+ interruption_event: {
46
+ event_id: number;
47
+ };
48
+ }
49
+
50
+ interface PingEvent extends BaseEvent {
51
+ type: 'ping';
52
+ ping_event: {
53
+ event_id: number;
54
+ ping_ms: number;
55
+ };
56
+ }
57
+
58
+ interface ConversationInitiationMetadataEvent extends BaseEvent {
59
+ type: 'conversation_initiation_metadata';
60
+ conversation_initiation_metadata_event: {
61
+ conversation_id: string;
62
+ };
63
+ }
64
+
65
+ export interface AgentResponseCorrectionEvent extends BaseEvent {
66
+ type: 'agent_response_correction';
67
+ agent_response_correction_event: {
68
+ corrected_agent_response: string;
69
+ original_agent_response: string;
70
+ };
71
+ }
72
+
73
+ /** Union of all possible WebSocket events we care about */
74
+ export type ElevenLabsWebSocketEvent =
75
+ | UserTranscriptEvent
76
+ | AgentResponseEvent
77
+ | AudioResponseEvent
78
+ | InterruptionEvent
79
+ | PingEvent
80
+ | ConversationInitiationMetadataEvent
81
+ | AgentResponseCorrectionEvent;
82
+
83
+ // ----------------- ElevenLabs Utility Functions -----------------
84
+
85
+ /** Fetch signed URL from ElevenLabs API */
86
+ export const getSignedUrl = async ({ agentId, apiKey }: { agentId: string; apiKey: string }): Promise<string> => {
87
+ const response = await fetch(
88
+ `https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=${agentId}`,
89
+ {
90
+ method: 'GET',
91
+ headers: {
92
+ 'xi-api-key': apiKey,
93
+ },
94
+ },
95
+ );
96
+ if (!response.ok) {
97
+ throw new Error(`Failed to fetch signed url - status ${response.status}`);
98
+ }
99
+ const body = await response.json();
100
+ return body.signed_url;
101
+ };