obi-sdk 0.12.2 → 0.12.3

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.
@@ -0,0 +1,30 @@
1
+ import { ObiAssistantConfig } from "../types/sdk";
2
+ export interface ConfigLogEntry {
3
+ timestamp: number;
4
+ source: 'initial' | 'update';
5
+ previousConfig: ObiAssistantConfig | null;
6
+ newConfig: ObiAssistantConfig;
7
+ diff: ConfigDiff;
8
+ }
9
+ export interface ConfigDiff {
10
+ added: Record<string, any>;
11
+ modified: Record<string, {
12
+ from: any;
13
+ to: any;
14
+ }>;
15
+ removed: Record<string, any>;
16
+ }
17
+ export declare class ConfigLogger {
18
+ private history;
19
+ private currentConfig;
20
+ logInitialConfig(config: ObiAssistantConfig): void;
21
+ logConfigUpdate(newConfig: ObiAssistantConfig): void;
22
+ getHistory(): ConfigLogEntry[];
23
+ getLatest(): ObiAssistantConfig | null;
24
+ getDiff(index: number): ConfigDiff | null;
25
+ clear(): void;
26
+ getFormattedHistory(): string;
27
+ private deepClone;
28
+ private calculateDiff;
29
+ private isEqual;
30
+ }
@@ -0,0 +1,6 @@
1
+ import { O } from "./obi-widget-fa809230.js";
2
+ import "./types-e0297e7b.js";
3
+ export {
4
+ O as ObiWidget
5
+ };
6
+ //# sourceMappingURL=index-dfc59383.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-dfc59383.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -609,6 +609,12 @@ class ObiClient {
609
609
  params: { path: { id } }
610
610
  });
611
611
  }
612
+ async updateSession(id, data) {
613
+ return await this.client.PATCH("/sessions/{id}", {
614
+ params: { path: { id } },
615
+ body: data
616
+ });
617
+ }
612
618
  async getJoinToken(token, { skipIntro, user } = {}) {
613
619
  return await this.client.GET("/join-token", {
614
620
  params: {
@@ -632,6 +638,7 @@ class ObiSession {
632
638
  constructor({ sessionId, apiBaseUrl, user }) {
633
639
  this.currentState = SDKState.READY;
634
640
  this.livekitState = "speaking";
641
+ this.agentHasSpoken = false;
635
642
  this.assistantAudioContext = null;
636
643
  this.userAudioContext = null;
637
644
  this._assistantAudioTimer = null;
@@ -699,6 +706,12 @@ class ObiSession {
699
706
  if (this.currentState === SDKState.RESEARCHING || this.currentState === SDKState.PAUSED)
700
707
  return;
701
708
  const state = attributes["lk.agent.state"];
709
+ if (state === "speaking") {
710
+ this.agentHasSpoken = true;
711
+ }
712
+ if (!this.agentHasSpoken) {
713
+ return;
714
+ }
702
715
  const newState = z$2(state).with("listening", () => SDKState.USER_SPEAKING).with("speaking", () => SDKState.AGENT_SPEAKING).with("thinking", () => SDKState.THINKING).otherwise(() => void 0);
703
716
  if (!newState)
704
717
  return;
@@ -961,6 +974,7 @@ class ObiSession {
961
974
  this.emitter.emit("error", new Error("Missing room URL or token for reconnection"));
962
975
  return false;
963
976
  }
977
+ this.agentHasSpoken = true;
964
978
  await this.requestMicrophone();
965
979
  this.room = new Room({
966
980
  adaptiveStream: true,
@@ -987,6 +1001,41 @@ class ObiSession {
987
1001
  return false;
988
1002
  }
989
1003
  }
1004
+ /**
1005
+ * Update user information for the current session.
1006
+ * This method updates the user data and notifies the agent if connected.
1007
+ * @param user The new user information or undefined to clear user data
1008
+ * @throws Error if there is no running session
1009
+ */
1010
+ async updateUser(user) {
1011
+ if (!this.room) {
1012
+ throw new Error("Cannot update user: No active session");
1013
+ }
1014
+ const oldUser = this.user;
1015
+ this.user = user;
1016
+ try {
1017
+ await this.client.updateSession(this.sessionId, {
1018
+ user: user ? JSON.stringify(user) : void 0
1019
+ });
1020
+ if (this.room && this.room.localParticipant) {
1021
+ const userData = {
1022
+ type: "user_updated",
1023
+ user,
1024
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1025
+ };
1026
+ const jsonData = JSON.stringify(userData);
1027
+ const encoder = new TextEncoder();
1028
+ const data = encoder.encode(jsonData);
1029
+ await this.room.localParticipant.publishData(data, { reliable: true });
1030
+ }
1031
+ this.emitter.emit("userUpdated", user);
1032
+ } catch (error) {
1033
+ this.user = oldUser;
1034
+ console.error("Failed to update user:", error);
1035
+ this.emitter.emit("error", error instanceof Error ? error : new Error(String(error)));
1036
+ throw error;
1037
+ }
1038
+ }
990
1039
  }
991
1040
  const OBI_PRIMARY_COLOR = "#a10fff";
992
1041
  function hexToHsl(hex) {
@@ -15938,7 +15987,7 @@ function createSentryScope() {
15938
15987
  return event;
15939
15988
  },
15940
15989
  // Set release version if available
15941
- release: process.env.npm_package_version || "0.6.2"
15990
+ release: {}.VITE_NPM_PACKAGE_VERSION || "0.6.2"
15942
15991
  });
15943
15992
  const scope2 = new Scope();
15944
15993
  scope2.setClient(client);
@@ -17616,6 +17665,16 @@ class SessionStartModal extends i$1 {
17616
17665
  this.error = null;
17617
17666
  this.startAttempts = 0;
17618
17667
  }
17668
+ disconnectedCallback() {
17669
+ super.disconnectedCallback();
17670
+ this._resetState();
17671
+ console.log("[SessionStartModal] Disconnected and state reset.");
17672
+ }
17673
+ _resetState() {
17674
+ this.isLoading = false;
17675
+ this.error = null;
17676
+ this.startAttempts = 0;
17677
+ }
17619
17678
  async handleStart() {
17620
17679
  console.log("[SessionStartModal] Start button clicked", {
17621
17680
  sessionId: this.session?.id,
@@ -17695,14 +17754,18 @@ class SessionStartModal extends i$1 {
17695
17754
  setTimeout(() => {
17696
17755
  if (this.isConnected) {
17697
17756
  captureException(
17698
- new Error("Session start modal did not close after Continue was clicked"),
17757
+ new Error("Session start modal did not close after 'Continue' was clicked"),
17699
17758
  {
17700
17759
  componentName: "SessionStartModal",
17701
17760
  handlerName: "handleStart_timeout",
17702
17761
  sessionId: this.session?.id,
17703
- modalStillVisible: true
17762
+ modalIsStillConnected: true
17704
17763
  }
17705
17764
  );
17765
+ this.isLoading = false;
17766
+ this.showError(
17767
+ "Something went wrong starting the session. Please refresh the window and try again."
17768
+ );
17706
17769
  }
17707
17770
  }, 2e3);
17708
17771
  } catch (error) {
@@ -18530,7 +18593,6 @@ class ObiWidget extends i$1 {
18530
18593
  storedParams[key] = value;
18531
18594
  });
18532
18595
  }
18533
- localStorage.removeItem("obi-url-params");
18534
18596
  return storedParams[SESSION_URL_PARAM];
18535
18597
  }();
18536
18598
  if (!sessionId) {
@@ -18587,11 +18649,22 @@ class ObiWidget extends i$1 {
18587
18649
  }
18588
18650
  this.removeSessionUrlParams();
18589
18651
  }
18590
- handleConfigUpdate(event) {
18652
+ async handleConfigUpdate(event) {
18591
18653
  const customEvent = event;
18592
18654
  const updatedConfig = customEvent.detail;
18593
18655
  const needsInit = updatedConfig.isActive && !this.isActive;
18656
+ const oldUser = this.user;
18594
18657
  this.updateFromConfig();
18658
+ if (this.activeSession && updatedConfig.user !== void 0) {
18659
+ const newUser = updatedConfig.user;
18660
+ if (JSON.stringify(oldUser) !== JSON.stringify(newUser)) {
18661
+ try {
18662
+ await this.activeSession.updateUser(newUser);
18663
+ } catch (error) {
18664
+ console.error("Failed to update session user data:", error);
18665
+ }
18666
+ }
18667
+ }
18595
18668
  if (needsInit && !isCurrentUrlBlacklisted(this.urlBlacklist) && !this.activeSession) {
18596
18669
  this.sessionConnectionCheck();
18597
18670
  }
@@ -19025,4 +19098,4 @@ export {
19025
19098
  withSentryAsyncHandler as w,
19026
19099
  x
19027
19100
  };
19028
- //# sourceMappingURL=obi-widget-33113e44.js.map
19101
+ //# sourceMappingURL=obi-widget-fa809230.js.map