obi-sdk 0.12.2 → 0.12.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.
@@ -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-870d3568.js";
2
+ import "./types-f38a47f6.js";
3
+ export {
4
+ O as ObiWidget
5
+ };
6
+ //# sourceMappingURL=index-07f9b60c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-07f9b60c.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,4 +1,4 @@
1
- import { S as SDKState, E as EventEmitter, R as RoomEvent, T as Track, z as z$2, a as Room, A as API_BASE_URL, N as N$1 } from "./types-e0297e7b.js";
1
+ import { S as SDKState, E as EventEmitter, R as RoomEvent, T as Track, z as z$2, a as Room, A as API_BASE_URL, N as N$1 } from "./types-f38a47f6.js";
2
2
  const PATH_PARAM_RE = /\{[^{}]+\}/g;
3
3
  function randomID() {
4
4
  return Math.random().toString(36).slice(2, 11);
@@ -419,198 +419,204 @@ class ObiClient {
419
419
  }
420
420
  // Auth endpoints
421
421
  async getAuthUrl(type) {
422
- return await this.client.GET("/auth/{type}", {
422
+ return await this.client.GET("/api/auth/{type}", {
423
423
  params: { path: { type } }
424
424
  });
425
425
  }
426
426
  async getConnectUrl(type) {
427
- return await this.client.GET("/connect/{type}", {
427
+ return await this.client.GET("/api/connect/{type}", {
428
428
  params: { path: { type } }
429
429
  });
430
430
  }
431
431
  async logout() {
432
- return await this.client.POST("/logout");
432
+ return await this.client.POST("/api/logout");
433
433
  }
434
434
  async getCurrentUser() {
435
- return await this.client.GET("/me");
435
+ return await this.client.GET("/api/me");
436
436
  }
437
437
  // Files
438
438
  async createPresignedUploadUrl(data) {
439
- return await this.client.POST("/files", {
439
+ return await this.client.POST("/api/files", {
440
440
  body: data
441
441
  });
442
442
  }
443
443
  // Knowledge blocks
444
444
  async createKnowledgeBlock(data) {
445
- return await this.client.POST("/knowledge", {
445
+ return await this.client.POST("/api/knowledge", {
446
446
  body: data
447
447
  });
448
448
  }
449
449
  // Onboardees
450
450
  async listOnboardees() {
451
- return await this.client.GET("/onboardees");
451
+ return await this.client.GET("/api/onboardees");
452
452
  }
453
453
  async getOnboardee(id) {
454
- return await this.client.GET("/onboardees/{id}", {
455
- params: { path: { id } }
456
- });
457
- }
458
- async getOnboardeeWhitelistedDomains(id) {
459
- return await this.client.GET("/onboardees/{id}/whitelisted-domains", {
454
+ return await this.client.GET("/api/onboardees/{id}", {
460
455
  params: { path: { id } }
461
456
  });
462
457
  }
463
458
  async getOnboardeeWidgetConfig(id, signal) {
464
- return await this.client.GET("/onboardees/{id}/config", {
459
+ return await this.client.GET("/api/onboardees/{id}/config", {
465
460
  params: { path: { id } },
466
461
  signal
467
462
  });
468
463
  }
469
464
  // Plans
470
465
  async listPlans() {
471
- return await this.client.GET("/plans");
466
+ return await this.client.GET("/api/plans");
472
467
  }
473
468
  // Products
474
469
  async listProducts() {
475
- return await this.client.GET("/products");
470
+ return await this.client.GET("/api/products");
471
+ }
472
+ async getProduct(id) {
473
+ return await this.client.GET("/api/products/{id}", {
474
+ params: { path: { id } }
475
+ });
476
476
  }
477
477
  async createProduct(data) {
478
- return await this.client.POST("/products", {
478
+ return await this.client.POST("/api/products", {
479
479
  body: data
480
480
  });
481
481
  }
482
482
  async updateProduct(id, data) {
483
- return await this.client.PATCH("/products/{id}", {
483
+ return await this.client.PATCH("/api/products/{id}", {
484
484
  params: { path: { id } },
485
485
  body: data
486
486
  });
487
487
  }
488
488
  async createPlan(data) {
489
- return await this.client.POST("/plans", {
489
+ return await this.client.POST("/api/plans", {
490
490
  body: data
491
491
  });
492
492
  }
493
493
  async getPlan(id) {
494
- return await this.client.GET("/plans/{id}", {
494
+ return await this.client.GET("/api/plans/{id}", {
495
495
  params: { path: { id } }
496
496
  });
497
497
  }
498
498
  async replacePlan(id, data) {
499
- return await this.client.PUT("/plans/{id}", {
499
+ return await this.client.PUT("/api/plans/{id}", {
500
500
  params: { path: { id } },
501
501
  body: data
502
502
  });
503
503
  }
504
504
  async updatePlan(id, data) {
505
- return await this.client.PATCH("/plans/{id}", {
505
+ return await this.client.PATCH("/api/plans/{id}", {
506
506
  params: { path: { id } },
507
507
  body: data
508
508
  });
509
509
  }
510
510
  async getPlanVideoUrl(id) {
511
- return await this.client.GET("/plans/{id}/video-url", {
511
+ return await this.client.GET("/api/plans/{id}/video-url", {
512
512
  params: { path: { id } }
513
513
  });
514
514
  }
515
515
  async deletePlan(id) {
516
- return await this.client.DELETE("/admin/plans/{id}", {
516
+ return await this.client.DELETE("/api/admin/plans/{id}", {
517
517
  params: { path: { id } }
518
518
  });
519
519
  }
520
520
  async publishPlanRevision(id, data) {
521
- return await this.client.POST("/plans/{id}/publish", {
521
+ return await this.client.POST("/api/plans/{id}/publish", {
522
522
  params: { path: { id } },
523
523
  body: data
524
524
  });
525
525
  }
526
526
  async listPlanRevisions(id) {
527
- return await this.client.GET("/plans/{id}/revisions", {
527
+ return await this.client.GET("/api/plans/{id}/revisions", {
528
528
  params: { path: { id } }
529
529
  });
530
530
  }
531
531
  async getRevisionNavigationIndex(revisionId) {
532
- return await this.client.GET("/revisions/{id}/navigation-index", {
532
+ return await this.client.GET("/api/revisions/{id}/navigation-index", {
533
533
  params: { path: { id: revisionId } }
534
534
  });
535
535
  }
536
536
  async replaceRevisionNavigationIndex(revisionId, data) {
537
- return await this.client.PUT("/revisions/{id}/navigation-index", {
537
+ return await this.client.PUT("/api/revisions/{id}/navigation-index", {
538
538
  params: { path: { id: revisionId } },
539
539
  body: data
540
540
  });
541
541
  }
542
542
  async getRevisionFAQ(revisionId) {
543
- return await this.client.GET("/revisions/{id}/faq", {
543
+ return await this.client.GET("/api/revisions/{id}/faq", {
544
544
  params: { path: { id: revisionId } }
545
545
  });
546
546
  }
547
547
  async replaceRevisionFAQ(revisionId, data) {
548
- return await this.client.PUT("/revisions/{id}/faq", {
548
+ return await this.client.PUT("/api/revisions/{id}/faq", {
549
549
  params: { path: { id: revisionId } },
550
550
  body: data
551
551
  });
552
552
  }
553
553
  async listRevisionKnowledgeBlocks(revisionId) {
554
- return await this.client.GET("/revisions/{id}/knowledge-blocks", {
554
+ return await this.client.GET("/api/revisions/{id}/knowledge-blocks", {
555
555
  params: { path: { id: revisionId } }
556
556
  });
557
557
  }
558
558
  async replaceRevisionKnowledgeBlocks(revisionId, data) {
559
- return await this.client.PUT("/revisions/{id}/knowledge-blocks", {
559
+ return await this.client.PUT("/api/revisions/{id}/knowledge-blocks", {
560
560
  params: { path: { id: revisionId } },
561
561
  body: data
562
562
  });
563
563
  }
564
564
  async createRevisionKnowledgeBlock(revisionId, data) {
565
- return await this.client.POST("/revisions/{id}/knowledge-blocks", {
565
+ return await this.client.POST("/api/revisions/{id}/knowledge-blocks", {
566
566
  params: { path: { id: revisionId } },
567
567
  body: data
568
568
  });
569
569
  }
570
570
  async updateRevisionKnowledgeBlock(revisionId, blockId, data) {
571
- return await this.client.PUT("/revisions/{id}/knowledge-blocks/{blockId}", {
571
+ return await this.client.PUT("/api/revisions/{id}/knowledge-blocks/{blockId}", {
572
572
  params: { path: { id: revisionId, blockId } },
573
573
  body: data
574
574
  });
575
575
  }
576
576
  async deleteRevisionKnowledgeBlock(revisionId, blockId) {
577
- return await this.client.DELETE("/revisions/{id}/knowledge-blocks/{blockId}", {
577
+ return await this.client.DELETE("/api/revisions/{id}/knowledge-blocks/{blockId}", {
578
578
  params: { path: { id: revisionId, blockId } }
579
579
  });
580
580
  }
581
581
  // Sessions
582
582
  async listSessions(token) {
583
- return await this.client.GET("/sessions", {
584
- params: { query: token ? { token } : {} }
583
+ return await this.client.GET("/api/sessions", {
584
+ params: { query: { token } }
585
585
  });
586
586
  }
587
587
  async createSession(data) {
588
- return await this.client.POST("/sessions", {
588
+ return await this.client.POST("/api/sessions", {
589
589
  body: data
590
590
  });
591
591
  }
592
592
  async getSession(id) {
593
- return await this.client.GET("/sessions/{id}", {
593
+ return await this.client.GET("/api/sessions/{id}", {
594
594
  params: { path: { id } }
595
595
  });
596
596
  }
597
597
  async startSession(id, token) {
598
- return await this.client.GET("/sessions/{id}/start-session", {
599
- params: { path: { id }, query: token ? { token } : {} }
598
+ return await this.client.GET("/api/sessions/{id}/start-session", {
599
+ params: { path: { id }, query: { token } }
600
600
  });
601
601
  }
602
602
  async getSessionRecording(id) {
603
- return await this.client.GET("/sessions/{id}/recording", {
603
+ return await this.client.GET("/api/sessions/{id}/recording", {
604
604
  params: { path: { id } }
605
605
  });
606
606
  }
607
607
  async getSessionProductUrl(id) {
608
- return await this.client.GET("/sessions/{id}/product-url", {
608
+ return await this.client.GET("/api/sessions/{id}/product-url", {
609
609
  params: { path: { id } }
610
610
  });
611
611
  }
612
+ async updateSession(id, data) {
613
+ return await this.client.PATCH("/api/sessions/{id}", {
614
+ params: { path: { id } },
615
+ body: data
616
+ });
617
+ }
612
618
  async getJoinToken(token, { skipIntro, user } = {}) {
613
- return await this.client.GET("/join-token", {
619
+ return await this.client.GET("/api/join-token", {
614
620
  params: {
615
621
  query: {
616
622
  token,
@@ -627,11 +633,12 @@ class ObiClient {
627
633
  return this.client;
628
634
  }
629
635
  }
630
- const DEFAULT_API_BASE_URL = "https://app.coragents.ai/api";
636
+ const DEFAULT_API_BASE_URL = "https://app.coragents.ai";
631
637
  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);
@@ -16601,6 +16650,11 @@ class CourseList extends i$1 {
16601
16650
  this.selectedCourseId = null;
16602
16651
  this.loading = false;
16603
16652
  this.error = "";
16653
+ this.searchTerm = "";
16654
+ }
16655
+ handleSearch(event) {
16656
+ const input = event.currentTarget;
16657
+ this.searchTerm = input.value;
16604
16658
  }
16605
16659
  render() {
16606
16660
  if (this.loading) {
@@ -16612,9 +16666,37 @@ class CourseList extends i$1 {
16612
16666
  if (!this.courses || this.courses.length === 0) {
16613
16667
  return x`<div class="empty">No courses available</div>`;
16614
16668
  }
16669
+ const filteredCourses = this.courses.filter(
16670
+ (course) => course.name.toLowerCase().includes(this.searchTerm.toLowerCase()) || (course.description || "").toLowerCase().includes(this.searchTerm.toLowerCase())
16671
+ );
16615
16672
  return x`
16673
+ <div class="controls">
16674
+ <div class="tabs">
16675
+ <button class="tab active">All</button>
16676
+ </div>
16677
+ <div class="filter">
16678
+ <svg
16679
+ width="14"
16680
+ height="14"
16681
+ viewBox="0 0 14 14"
16682
+ fill="none"
16683
+ xmlns="http://www.w3.org/2000/svg"
16684
+ >
16685
+ <path
16686
+ d="M10.0417 8.75002H9.42087L9.20004 8.53502C9.96921 7.63585 10.4417 6.47502 10.4417 5.20835C10.4417 2.56085 8.32254 0.441681 5.67504 0.441681C3.02754 0.441681 0.908374 2.56085 0.908374 5.20835C0.908374 7.85585 3.02754 9.97502 5.67504 9.97502C6.94171 9.97502 8.10254 9.50252 9.00171 8.73335L9.22671 8.95418V9.57502L13.2167 13.5592L14.375 12.4008L10.0417 8.75002ZM5.67504 8.75002C3.72754 8.75002 2.15837 7.18085 2.15837 5.20835C2.15837 3.23585 3.72754 1.66668 5.67504 1.66668C7.62254 1.66668 9.19171 3.23585 9.19171 5.20835C9.19171 7.18085 7.62254 8.75002 5.67504 8.75002Z"
16687
+ fill="#6B7280"
16688
+ />
16689
+ </svg>
16690
+ <input
16691
+ type="text"
16692
+ placeholder="Search..."
16693
+ .value=${this.searchTerm}
16694
+ @input=${this.handleSearch}
16695
+ />
16696
+ </div>
16697
+ </div>
16616
16698
  <div class="course-grid">
16617
- ${this.courses.sort((a2, b2) => (a2.order || 0) - (b2.order || 0)).map((course) => {
16699
+ ${filteredCourses.sort((a2, b2) => (a2.order || 0) - (b2.order || 0)).map((course) => {
16618
16700
  const isSelected = course.id === this.selectedCourseId;
16619
16701
  return x`
16620
16702
  <obi-course
@@ -16640,12 +16722,81 @@ CourseList.styles = i$4`
16640
16722
  display: grid;
16641
16723
  grid-template-columns: 1fr 1fr 1fr;
16642
16724
  gap: 4px;
16643
- padding: 12px 0px;
16725
+ padding: 0;
16644
16726
  flex: 1 0 0;
16645
16727
  align-self: stretch;
16646
16728
  min-height: 364px; /* Ensure minimum 2 rows: 2 * 180px + 4px gap */
16647
16729
  }
16648
16730
 
16731
+ .controls {
16732
+ display: flex;
16733
+ justify-content: space-between;
16734
+ align-items: center;
16735
+ margin-bottom: 12px;
16736
+ }
16737
+
16738
+ .tabs {
16739
+ display: flex;
16740
+ gap: 10px;
16741
+ }
16742
+
16743
+ .tab {
16744
+ display: flex;
16745
+ padding: var(--spacing-1-5, 6px) var(--spacing-3, 12px);
16746
+ justify-content: center;
16747
+ align-items: center;
16748
+ align-self: stretch;
16749
+ border: none;
16750
+ background: none;
16751
+ cursor: pointer;
16752
+ font-family: Satoshi;
16753
+ font-size: 16px;
16754
+ font-weight: 500;
16755
+ color: rgba(0, 0, 0, 0.4);
16756
+ border-bottom: 2px solid transparent;
16757
+ transition: all 0.2s;
16758
+ }
16759
+
16760
+ .tab.active {
16761
+ color: #000;
16762
+ border-bottom: 2px solid var(--obi-primary);
16763
+ }
16764
+
16765
+ .tab:hover {
16766
+ color: #000;
16767
+ }
16768
+
16769
+ .filter {
16770
+ position: relative;
16771
+ display: flex;
16772
+ align-items: center;
16773
+ width: 336px;
16774
+ height: var(--width-w-10, 40px);
16775
+ }
16776
+
16777
+ .filter input {
16778
+ padding: 8px 12px 8px 36px;
16779
+ border-radius: var(--border-radius-default, 6px);
16780
+ border: 1px solid rgba(0, 0, 0, 0.1);
16781
+ background: #fff;
16782
+ font-family: Satoshi;
16783
+ font-size: 14px;
16784
+ line-height: 20px;
16785
+ width: 100%;
16786
+ height: 100%;
16787
+ box-sizing: border-box;
16788
+ }
16789
+
16790
+ .filter input::placeholder {
16791
+ color: rgba(0, 0, 0, 0.4);
16792
+ }
16793
+
16794
+ .filter svg {
16795
+ position: absolute;
16796
+ left: 12px;
16797
+ pointer-events: none;
16798
+ }
16799
+
16649
16800
  @media (max-width: 767px) {
16650
16801
  .course-grid {
16651
16802
  grid-template-columns: 1fr;
@@ -16677,6 +16828,9 @@ __decorateClass$5([
16677
16828
  __decorateClass$5([
16678
16829
  n$2({ type: String })
16679
16830
  ], CourseList.prototype, "error", 2);
16831
+ __decorateClass$5([
16832
+ n$2({ type: String })
16833
+ ], CourseList.prototype, "searchTerm", 2);
16680
16834
  if (!customElements.get("obi-course")) {
16681
16835
  customElements.define("obi-course", Course);
16682
16836
  }
@@ -16855,7 +17009,8 @@ class CourseModal extends i$1 {
16855
17009
  Sessions are securely recorded for quality improvement purposes.
16856
17010
  </p>
16857
17011
  </div>
16858
- <div class="powered-by-container">
17012
+
17013
+ <!-- <div class="powered-by-container">
16859
17014
  <a href="https://getcor.ai/" target="_blank" class="powered-by-link">
16860
17015
  <div style="display: flex; align-items: end; gap: 4px;">
16861
17016
  <p class="powered-by">Powered by</p>
@@ -16873,7 +17028,7 @@ class CourseModal extends i$1 {
16873
17028
  </svg>
16874
17029
  </div>
16875
17030
  </a>
16876
- </div>
17031
+ </div> -->
16877
17032
  </div>
16878
17033
  `;
16879
17034
  }
@@ -16932,6 +17087,27 @@ CourseModal.styles = i$4`
16932
17087
  overflow-y: auto;
16933
17088
  width: 100%;
16934
17089
  min-height: 0;
17090
+ max-height: 424px; /* 2 rows (2 * 180px) + controls height (~60px) + gap (4px) */
17091
+ padding-right: 3px; /* Space for scrollbar + gap from border */
17092
+ box-sizing: border-box;
17093
+ }
17094
+
17095
+ .course-list-wrapper::-webkit-scrollbar {
17096
+ width: 3px;
17097
+ }
17098
+
17099
+ .course-list-wrapper::-webkit-scrollbar-track {
17100
+ background: transparent;
17101
+ }
17102
+
17103
+ .course-list-wrapper::-webkit-scrollbar-thumb {
17104
+ background-color: #000;
17105
+ border-radius: 2px;
17106
+ min-height: 20px; /* Ensure minimum height for proper rounding */
17107
+ }
17108
+
17109
+ .course-list-wrapper::-webkit-scrollbar-thumb:hover {
17110
+ background-color: #333;
16935
17111
  }
16936
17112
 
16937
17113
  .container:hover {
@@ -17616,6 +17792,16 @@ class SessionStartModal extends i$1 {
17616
17792
  this.error = null;
17617
17793
  this.startAttempts = 0;
17618
17794
  }
17795
+ disconnectedCallback() {
17796
+ super.disconnectedCallback();
17797
+ this._resetState();
17798
+ console.log("[SessionStartModal] Disconnected and state reset.");
17799
+ }
17800
+ _resetState() {
17801
+ this.isLoading = false;
17802
+ this.error = null;
17803
+ this.startAttempts = 0;
17804
+ }
17619
17805
  async handleStart() {
17620
17806
  console.log("[SessionStartModal] Start button clicked", {
17621
17807
  sessionId: this.session?.id,
@@ -17695,14 +17881,18 @@ class SessionStartModal extends i$1 {
17695
17881
  setTimeout(() => {
17696
17882
  if (this.isConnected) {
17697
17883
  captureException(
17698
- new Error("Session start modal did not close after Continue was clicked"),
17884
+ new Error("Session start modal did not close after 'Continue' was clicked"),
17699
17885
  {
17700
17886
  componentName: "SessionStartModal",
17701
17887
  handlerName: "handleStart_timeout",
17702
17888
  sessionId: this.session?.id,
17703
- modalStillVisible: true
17889
+ modalIsStillConnected: true
17704
17890
  }
17705
17891
  );
17892
+ this.isLoading = false;
17893
+ this.showError(
17894
+ "Something went wrong starting the session. Please refresh the window and try again."
17895
+ );
17706
17896
  }
17707
17897
  }, 2e3);
17708
17898
  } catch (error) {
@@ -18530,7 +18720,6 @@ class ObiWidget extends i$1 {
18530
18720
  storedParams[key] = value;
18531
18721
  });
18532
18722
  }
18533
- localStorage.removeItem("obi-url-params");
18534
18723
  return storedParams[SESSION_URL_PARAM];
18535
18724
  }();
18536
18725
  if (!sessionId) {
@@ -18587,11 +18776,22 @@ class ObiWidget extends i$1 {
18587
18776
  }
18588
18777
  this.removeSessionUrlParams();
18589
18778
  }
18590
- handleConfigUpdate(event) {
18779
+ async handleConfigUpdate(event) {
18591
18780
  const customEvent = event;
18592
18781
  const updatedConfig = customEvent.detail;
18593
18782
  const needsInit = updatedConfig.isActive && !this.isActive;
18783
+ const oldUser = this.user;
18594
18784
  this.updateFromConfig();
18785
+ if (this.activeSession && updatedConfig.user !== void 0) {
18786
+ const newUser = updatedConfig.user;
18787
+ if (JSON.stringify(oldUser) !== JSON.stringify(newUser)) {
18788
+ try {
18789
+ await this.activeSession.updateUser(newUser);
18790
+ } catch (error) {
18791
+ console.error("Failed to update session user data:", error);
18792
+ }
18793
+ }
18794
+ }
18595
18795
  if (needsInit && !isCurrentUrlBlacklisted(this.urlBlacklist) && !this.activeSession) {
18596
18796
  this.sessionConnectionCheck();
18597
18797
  }
@@ -19025,4 +19225,4 @@ export {
19025
19225
  withSentryAsyncHandler as w,
19026
19226
  x
19027
19227
  };
19028
- //# sourceMappingURL=obi-widget-33113e44.js.map
19228
+ //# sourceMappingURL=obi-widget-870d3568.js.map