@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.d.mts CHANGED
@@ -96,6 +96,14 @@ interface MemoryUpdatedEvent {
96
96
  newMemories: MemoryData[];
97
97
  timestamp: string;
98
98
  }
99
+ interface CharacterAction {
100
+ /** Action name (e.g., "follow_user", "sit", "look_at") */
101
+ name: string;
102
+ /** Action parameters as key-value pairs */
103
+ params: Record<string, string>;
104
+ /** Message ID of the bot response that contained this action */
105
+ messageId: string;
106
+ }
99
107
  type EstuaryEventMap = {
100
108
  connected: (session: SessionInfo) => void;
101
109
  disconnected: (reason: string) => void;
@@ -109,6 +117,7 @@ type EstuaryEventMap = {
109
117
  authError: (error: string) => void;
110
118
  quotaExceeded: (data: QuotaExceededData) => void;
111
119
  cameraCaptureRequest: (request: CameraCaptureRequest) => void;
120
+ characterAction: (action: CharacterAction) => void;
112
121
  voiceStarted: () => void;
113
122
  voiceStopped: () => void;
114
123
  livekitConnected: (room: string) => void;
@@ -229,6 +238,7 @@ declare class EstuaryClient extends TypedEventEmitter<EstuaryEventMap> {
229
238
  private audioPlayer;
230
239
  private _memory;
231
240
  private _sessionInfo;
241
+ private actionParsers;
232
242
  constructor(config: EstuaryConfig);
233
243
  /** Memory API client for querying memories, graphs, and facts */
234
244
  get memory(): MemoryClient;
@@ -266,6 +276,7 @@ declare class EstuaryClient extends TypedEventEmitter<EstuaryEventMap> {
266
276
  get isVoiceActive(): boolean;
267
277
  private ensureConnected;
268
278
  private forwardSocketEvents;
279
+ private handleBotResponse;
269
280
  private handleBotVoice;
270
281
  }
271
282
 
@@ -289,4 +300,23 @@ declare class EstuaryError extends Error {
289
300
  constructor(code: ErrorCode, message: string, details?: unknown);
290
301
  }
291
302
 
292
- export { type BotResponse, type BotVoice, type CameraCaptureRequest, ConnectionState, type CoreFactsResponse, ErrorCode, EstuaryClient, type EstuaryConfig, EstuaryError, type EstuaryEventMap, type InterruptData, type LiveKitTokenResponse, MemoryClient, type MemoryData, type MemoryGraphOptions, type MemoryGraphResponse, type MemoryListOptions, type MemoryListResponse, type MemorySearchOptions, type MemorySearchResponse, type MemoryStatsResponse, type MemoryTimelineOptions, type MemoryTimelineResponse, type MemoryUpdatedEvent, type QuotaExceededData, type SessionInfo, type SttResponse, type VoiceManager, type VoiceTransport };
303
+ /**
304
+ * Parses `<action name="..." .../>` XML tags from bot response text.
305
+ *
306
+ * Designed for streaming: call `parse()` with the accumulated text on each
307
+ * chunk and it returns only newly-discovered actions since the last call.
308
+ */
309
+ interface ParsedAction {
310
+ name: string;
311
+ params: Record<string, string>;
312
+ }
313
+ /**
314
+ * One-shot parse: extract all actions and return clean text.
315
+ * Useful for non-streaming contexts.
316
+ */
317
+ declare function parseActions(text: string): {
318
+ actions: ParsedAction[];
319
+ cleanText: string;
320
+ };
321
+
322
+ export { type BotResponse, type BotVoice, type CameraCaptureRequest, type CharacterAction, ConnectionState, type CoreFactsResponse, ErrorCode, EstuaryClient, type EstuaryConfig, EstuaryError, type EstuaryEventMap, type InterruptData, type LiveKitTokenResponse, MemoryClient, type MemoryData, type MemoryGraphOptions, type MemoryGraphResponse, type MemoryListOptions, type MemoryListResponse, type MemorySearchOptions, type MemorySearchResponse, type MemoryStatsResponse, type MemoryTimelineOptions, type MemoryTimelineResponse, type MemoryUpdatedEvent, type ParsedAction, type QuotaExceededData, type SessionInfo, type SttResponse, type VoiceManager, type VoiceTransport, parseActions };
package/dist/index.js CHANGED
@@ -5033,7 +5033,11 @@ var init_livekit_voice = __esm({
5033
5033
  let RoomEvent;
5034
5034
  let Track;
5035
5035
  try {
5036
- const lk = await import('livekit-client');
5036
+ const specifier = ["livekit", "client"].join("-");
5037
+ const lk = await import(
5038
+ /* @vite-ignore */
5039
+ specifier
5040
+ );
5037
5041
  Room = lk.Room;
5038
5042
  RoomEvent = lk.RoomEvent;
5039
5043
  Track = lk.Track;
@@ -9306,6 +9310,53 @@ var Logger = class {
9306
9310
 
9307
9311
  // src/client.ts
9308
9312
  init_errors();
9313
+
9314
+ // src/utils/action-parser.ts
9315
+ var ACTION_TAG_RE = /<action\s+([^>]*?)\/>/gi;
9316
+ var ATTR_RE = /(\w+)\s*=\s*"([^"]*)"|(\w+)\s*=\s*'([^']*)'/g;
9317
+ function parseAttributes(attrString) {
9318
+ const attrs = {};
9319
+ let match;
9320
+ while ((match = ATTR_RE.exec(attrString)) !== null) {
9321
+ const key = match[1] ?? match[3];
9322
+ const value2 = match[2] ?? match[4];
9323
+ attrs[key] = value2;
9324
+ }
9325
+ return attrs;
9326
+ }
9327
+ var StreamingActionParser = class {
9328
+ emittedCount = 0;
9329
+ /**
9330
+ * Parse the accumulated response text and return any new actions found
9331
+ * since the last call. Also returns the text with all action tags stripped.
9332
+ */
9333
+ parse(accumulatedText) {
9334
+ const allActions = [];
9335
+ let match;
9336
+ ACTION_TAG_RE.lastIndex = 0;
9337
+ while ((match = ACTION_TAG_RE.exec(accumulatedText)) !== null) {
9338
+ const attrs = parseAttributes(match[1]);
9339
+ const name = attrs.name;
9340
+ if (name) {
9341
+ delete attrs.name;
9342
+ allActions.push({ name, params: attrs });
9343
+ }
9344
+ }
9345
+ const newActions = allActions.slice(this.emittedCount);
9346
+ this.emittedCount = allActions.length;
9347
+ const cleanText = accumulatedText.replace(ACTION_TAG_RE, "").replace(/\s{2,}/g, " ").trim();
9348
+ return { actions: newActions, cleanText };
9349
+ }
9350
+ reset() {
9351
+ this.emittedCount = 0;
9352
+ }
9353
+ };
9354
+ function parseActions(text) {
9355
+ const parser = new StreamingActionParser();
9356
+ return parser.parse(text);
9357
+ }
9358
+
9359
+ // src/client.ts
9309
9360
  var DEFAULT_SAMPLE_RATE = 16e3;
9310
9361
  var EstuaryClient = class extends TypedEventEmitter {
9311
9362
  config;
@@ -9315,6 +9366,7 @@ var EstuaryClient = class extends TypedEventEmitter {
9315
9366
  audioPlayer = null;
9316
9367
  _memory;
9317
9368
  _sessionInfo = null;
9369
+ actionParsers = /* @__PURE__ */ new Map();
9318
9370
  constructor(config) {
9319
9371
  super();
9320
9372
  this.config = config;
@@ -9450,15 +9502,17 @@ var EstuaryClient = class extends TypedEventEmitter {
9450
9502
  });
9451
9503
  this.socketManager.on("disconnected", (reason) => {
9452
9504
  this._sessionInfo = null;
9505
+ this.actionParsers.clear();
9453
9506
  this.emit("disconnected", reason);
9454
9507
  });
9455
9508
  this.socketManager.on("reconnecting", (attempt) => this.emit("reconnecting", attempt));
9456
9509
  this.socketManager.on("connectionStateChanged", (state) => this.emit("connectionStateChanged", state));
9457
- this.socketManager.on("botResponse", (response) => this.emit("botResponse", response));
9510
+ this.socketManager.on("botResponse", (response) => this.handleBotResponse(response));
9458
9511
  this.socketManager.on("botVoice", (voice) => this.handleBotVoice(voice));
9459
9512
  this.socketManager.on("sttResponse", (response) => this.emit("sttResponse", response));
9460
9513
  this.socketManager.on("interrupt", (data) => {
9461
9514
  this.audioPlayer?.clear();
9515
+ this.actionParsers.clear();
9462
9516
  this.emit("interrupt", data);
9463
9517
  });
9464
9518
  this.socketManager.on("error", (error) => this.emit("error", error));
@@ -9469,6 +9523,28 @@ var EstuaryClient = class extends TypedEventEmitter {
9469
9523
  this.socketManager.on("livekitDisconnected", () => this.emit("livekitDisconnected"));
9470
9524
  this.socketManager.on("memoryUpdated", (event) => this.emit("memoryUpdated", event));
9471
9525
  }
9526
+ handleBotResponse(response) {
9527
+ const { messageId } = response;
9528
+ if (!this.actionParsers.has(messageId)) {
9529
+ this.actionParsers.set(messageId, new StreamingActionParser());
9530
+ }
9531
+ const parser = this.actionParsers.get(messageId);
9532
+ const { actions, cleanText } = parser.parse(response.text);
9533
+ for (const action of actions) {
9534
+ this.emit("characterAction", {
9535
+ name: action.name,
9536
+ params: action.params,
9537
+ messageId
9538
+ });
9539
+ }
9540
+ this.emit("botResponse", {
9541
+ ...response,
9542
+ text: cleanText
9543
+ });
9544
+ if (response.isFinal) {
9545
+ this.actionParsers.delete(messageId);
9546
+ }
9547
+ }
9472
9548
  handleBotVoice(voice) {
9473
9549
  this.emit("botVoice", voice);
9474
9550
  this.audioPlayer?.enqueue(voice);
@@ -9496,5 +9572,6 @@ xmlhttprequest-ssl/lib/XMLHttpRequest.js:
9496
9572
 
9497
9573
  exports.ConnectionState = ConnectionState;
9498
9574
  exports.EstuaryClient = EstuaryClient;
9575
+ exports.parseActions = parseActions;
9499
9576
  //# sourceMappingURL=index.js.map
9500
9577
  //# sourceMappingURL=index.js.map