@estuary-ai/sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -3743,7 +3743,7 @@ async function createVoiceManager(transport, socketManager, sampleRate, logger)
3743
3743
  }
3744
3744
  if (transport === "livekit") {
3745
3745
  try {
3746
- const { LiveKitVoiceManager } = await import('./livekit-voice-2WOL2XRV.mjs');
3746
+ const { LiveKitVoiceManager } = await import('./livekit-voice-H6WZ44LM.mjs');
3747
3747
  return new LiveKitVoiceManager(socketManager, logger);
3748
3748
  } catch {
3749
3749
  logger.warn("livekit-client not installed, falling back to WebSocket voice");
@@ -3753,7 +3753,7 @@ async function createVoiceManager(transport, socketManager, sampleRate, logger)
3753
3753
  }
3754
3754
  if (transport === "auto") {
3755
3755
  try {
3756
- const { LiveKitVoiceManager } = await import('./livekit-voice-2WOL2XRV.mjs');
3756
+ const { LiveKitVoiceManager } = await import('./livekit-voice-H6WZ44LM.mjs');
3757
3757
  return new LiveKitVoiceManager(socketManager, logger);
3758
3758
  } catch {
3759
3759
  const { WebSocketVoiceManager } = await import('./websocket-voice-A4CK3UTM.mjs');
@@ -3989,6 +3989,51 @@ var Logger = class {
3989
3989
  }
3990
3990
  };
3991
3991
 
3992
+ // src/utils/action-parser.ts
3993
+ var ACTION_TAG_RE = /<action\s+([^>]*?)\/>/gi;
3994
+ var ATTR_RE = /(\w+)\s*=\s*"([^"]*)"|(\w+)\s*=\s*'([^']*)'/g;
3995
+ function parseAttributes(attrString) {
3996
+ const attrs = {};
3997
+ let match;
3998
+ while ((match = ATTR_RE.exec(attrString)) !== null) {
3999
+ const key = match[1] ?? match[3];
4000
+ const value2 = match[2] ?? match[4];
4001
+ attrs[key] = value2;
4002
+ }
4003
+ return attrs;
4004
+ }
4005
+ var StreamingActionParser = class {
4006
+ emittedCount = 0;
4007
+ /**
4008
+ * Parse the accumulated response text and return any new actions found
4009
+ * since the last call. Also returns the text with all action tags stripped.
4010
+ */
4011
+ parse(accumulatedText) {
4012
+ const allActions = [];
4013
+ let match;
4014
+ ACTION_TAG_RE.lastIndex = 0;
4015
+ while ((match = ACTION_TAG_RE.exec(accumulatedText)) !== null) {
4016
+ const attrs = parseAttributes(match[1]);
4017
+ const name = attrs.name;
4018
+ if (name) {
4019
+ delete attrs.name;
4020
+ allActions.push({ name, params: attrs });
4021
+ }
4022
+ }
4023
+ const newActions = allActions.slice(this.emittedCount);
4024
+ this.emittedCount = allActions.length;
4025
+ const cleanText = accumulatedText.replace(ACTION_TAG_RE, "").replace(/\s{2,}/g, " ").trim();
4026
+ return { actions: newActions, cleanText };
4027
+ }
4028
+ reset() {
4029
+ this.emittedCount = 0;
4030
+ }
4031
+ };
4032
+ function parseActions(text) {
4033
+ const parser = new StreamingActionParser();
4034
+ return parser.parse(text);
4035
+ }
4036
+
3992
4037
  // src/client.ts
3993
4038
  var DEFAULT_SAMPLE_RATE = 16e3;
3994
4039
  var EstuaryClient = class extends TypedEventEmitter {
@@ -3999,6 +4044,7 @@ var EstuaryClient = class extends TypedEventEmitter {
3999
4044
  audioPlayer = null;
4000
4045
  _memory;
4001
4046
  _sessionInfo = null;
4047
+ actionParsers = /* @__PURE__ */ new Map();
4002
4048
  constructor(config) {
4003
4049
  super();
4004
4050
  this.config = config;
@@ -4134,15 +4180,17 @@ var EstuaryClient = class extends TypedEventEmitter {
4134
4180
  });
4135
4181
  this.socketManager.on("disconnected", (reason) => {
4136
4182
  this._sessionInfo = null;
4183
+ this.actionParsers.clear();
4137
4184
  this.emit("disconnected", reason);
4138
4185
  });
4139
4186
  this.socketManager.on("reconnecting", (attempt) => this.emit("reconnecting", attempt));
4140
4187
  this.socketManager.on("connectionStateChanged", (state) => this.emit("connectionStateChanged", state));
4141
- this.socketManager.on("botResponse", (response) => this.emit("botResponse", response));
4188
+ this.socketManager.on("botResponse", (response) => this.handleBotResponse(response));
4142
4189
  this.socketManager.on("botVoice", (voice) => this.handleBotVoice(voice));
4143
4190
  this.socketManager.on("sttResponse", (response) => this.emit("sttResponse", response));
4144
4191
  this.socketManager.on("interrupt", (data) => {
4145
4192
  this.audioPlayer?.clear();
4193
+ this.actionParsers.clear();
4146
4194
  this.emit("interrupt", data);
4147
4195
  });
4148
4196
  this.socketManager.on("error", (error) => this.emit("error", error));
@@ -4153,12 +4201,34 @@ var EstuaryClient = class extends TypedEventEmitter {
4153
4201
  this.socketManager.on("livekitDisconnected", () => this.emit("livekitDisconnected"));
4154
4202
  this.socketManager.on("memoryUpdated", (event) => this.emit("memoryUpdated", event));
4155
4203
  }
4204
+ handleBotResponse(response) {
4205
+ const { messageId } = response;
4206
+ if (!this.actionParsers.has(messageId)) {
4207
+ this.actionParsers.set(messageId, new StreamingActionParser());
4208
+ }
4209
+ const parser = this.actionParsers.get(messageId);
4210
+ const { actions, cleanText } = parser.parse(response.text);
4211
+ for (const action of actions) {
4212
+ this.emit("characterAction", {
4213
+ name: action.name,
4214
+ params: action.params,
4215
+ messageId
4216
+ });
4217
+ }
4218
+ this.emit("botResponse", {
4219
+ ...response,
4220
+ text: cleanText
4221
+ });
4222
+ if (response.isFinal) {
4223
+ this.actionParsers.delete(messageId);
4224
+ }
4225
+ }
4156
4226
  handleBotVoice(voice) {
4157
4227
  this.emit("botVoice", voice);
4158
4228
  this.audioPlayer?.enqueue(voice);
4159
4229
  }
4160
4230
  };
4161
4231
 
4162
- export { ConnectionState, EstuaryClient };
4232
+ export { ConnectionState, EstuaryClient, parseActions };
4163
4233
  //# sourceMappingURL=index.mjs.map
4164
4234
  //# sourceMappingURL=index.mjs.map