@tutti-os/agent-gui 0.0.91 → 0.0.92

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.js CHANGED
@@ -16874,6 +16874,9 @@ var styles = {
16874
16874
  emptyHeroCarousel: "agent-gui-node__empty-hero-carousel",
16875
16875
  emptyHeroCarouselCanvas: "agent-gui-node__empty-hero-carousel-canvas",
16876
16876
  emptyHeroCarouselItem: "agent-gui-node__empty-hero-carousel-item",
16877
+ emptyHeroCarouselLayer: "agent-gui-node__empty-hero-carousel-layer",
16878
+ emptyHeroCarouselPlaceholder: "agent-gui-node__empty-hero-carousel-placeholder",
16879
+ emptyHeroCarouselStage: "agent-gui-node__empty-hero-carousel-stage",
16877
16880
  emptyHeroIconEffect: "agent-gui-node__empty-hero-icon-effect",
16878
16881
  emptyHeroIconRail: "agent-gui-node__empty-hero-icon-rail",
16879
16882
  emptyHeroIconRailItem: "agent-gui-node__empty-hero-icon-rail-item",
@@ -17155,19 +17158,35 @@ import {
17155
17158
  import * as THREE from "three";
17156
17159
  var CAMERA_FOV_DEG = 14;
17157
17160
  var CAMERA_Z = 7.5;
17158
- var WHEEL_TARGET_SLOTS = 21;
17159
- var TILE_SPACING = 1.35;
17160
- var UNFOCUSED_OPACITY = 0.55;
17161
- var SPRING_STIFFNESS = 90;
17162
- var SPRING_DAMPING_RATIO = 0.62;
17161
+ var WHEEL_TARGET_SLOTS = 40;
17162
+ var TILE_SPACING = 1.55;
17163
+ var VISIBLE_ARC_CURVATURE = 0.9;
17164
+ var MIN_RECORD_OPACITY = 0.22;
17165
+ var RECORD_FADE_RANGE_SLOTS = 4.5;
17166
+ var RECORD_FADE_CURVE = 1.45;
17167
+ var SPRING_STIFFNESS = 120;
17168
+ var SPRING_DAMPING_RATIO = 0.78;
17169
+ var SPRING_MIN_LAUNCH_VELOCITY = 2.6;
17163
17170
  var SPRING_SETTLE_EPSILON = 1e-3;
17164
17171
  var SPRING_SETTLE_VELOCITY = 0.02;
17172
+ var MAX_FRAME_DELTA_SECONDS = 0.032;
17165
17173
  var TEXTURE_SIZE = 256;
17166
- var TEXTURE_CORNER_RADIUS = 0.05;
17167
17174
  var BADGE_CORNER_RADIUS = 0.5;
17168
17175
  var BADGE_DIAMETER = 0.36;
17169
17176
  var BADGE_OFFSET = 0.4;
17170
17177
  var MAX_PIXEL_RATIO = 2;
17178
+ var RECORD_RADIUS_RATIO = 0.47;
17179
+ var RECORD_LABEL_RADIUS_RATIO = 0.41;
17180
+ var RECORD_SPINDLE_RADIUS_RATIO = 0.035;
17181
+ var RECORD_SPIN_SECONDS = 7;
17182
+ var RECORD_MODEL_SCALE = 1.3;
17183
+ var RECORD_MODEL_RADIUS = 0.475;
17184
+ var RECORD_MODEL_THICKNESS = 0.065;
17185
+ var RECORD_MODEL_TILT_X = -0.11;
17186
+ var RECORD_MODEL_SIDE_TILT_FACTOR = 0.18;
17187
+ var RECORD_MODEL_MAX_SIDE_TILT = 0.16;
17188
+ var RECORD_RENDER_RANGE_SLOTS = 3.4;
17189
+ var RECORD_EDGE_SEGMENTS = 48;
17171
17190
  function ringOffset(index, scroll, count) {
17172
17191
  if (count <= 1) {
17173
17192
  return index - scroll;
@@ -17181,7 +17200,114 @@ function ringOffset(index, scroll, count) {
17181
17200
  }
17182
17201
  return offset;
17183
17202
  }
17184
- function roundedIconTexture(image, onReadyRender, cornerRadius = TEXTURE_CORNER_RADIUS) {
17203
+ function vinylRecordTexture(image, onReadyRender) {
17204
+ const canvas = document.createElement("canvas");
17205
+ canvas.width = TEXTURE_SIZE;
17206
+ canvas.height = TEXTURE_SIZE;
17207
+ const context = canvas.getContext("2d");
17208
+ if (context) {
17209
+ const center = TEXTURE_SIZE / 2;
17210
+ const recordRadius = TEXTURE_SIZE * RECORD_RADIUS_RATIO;
17211
+ const labelRadius = recordRadius * RECORD_LABEL_RADIUS_RATIO;
17212
+ context.clearRect(0, 0, TEXTURE_SIZE, TEXTURE_SIZE);
17213
+ context.save();
17214
+ context.beginPath();
17215
+ context.arc(center, center, recordRadius, 0, Math.PI * 2);
17216
+ context.clip();
17217
+ const recordFill = context.createRadialGradient(
17218
+ center * 0.92,
17219
+ center * 0.88,
17220
+ labelRadius,
17221
+ center,
17222
+ center,
17223
+ recordRadius
17224
+ );
17225
+ recordFill.addColorStop(0, "rgb(26 26 27)");
17226
+ recordFill.addColorStop(0.54, "rgb(5 5 6)");
17227
+ recordFill.addColorStop(0.82, "rgb(18 18 19)");
17228
+ recordFill.addColorStop(1, "rgb(3 3 4)");
17229
+ context.fillStyle = recordFill;
17230
+ context.fillRect(0, 0, TEXTURE_SIZE, TEXTURE_SIZE);
17231
+ for (let radius = labelRadius + 4; radius < recordRadius - 3; radius += 3.5) {
17232
+ const grooveIndex = Math.round((radius - labelRadius) / 3.5);
17233
+ context.beginPath();
17234
+ context.arc(center, center, radius, 0, Math.PI * 2);
17235
+ context.strokeStyle = grooveIndex % 3 === 0 ? "rgb(255 255 255 / 0.12)" : "rgb(255 255 255 / 0.055)";
17236
+ context.lineWidth = grooveIndex % 3 === 0 ? 0.7 : 0.45;
17237
+ context.stroke();
17238
+ }
17239
+ context.save();
17240
+ context.translate(center, center);
17241
+ context.rotate(-Math.PI / 4);
17242
+ const sheen = context.createLinearGradient(
17243
+ -recordRadius,
17244
+ 0,
17245
+ recordRadius,
17246
+ 0
17247
+ );
17248
+ sheen.addColorStop(0, "rgb(255 255 255 / 0)");
17249
+ sheen.addColorStop(0.42, "rgb(255 255 255 / 0.02)");
17250
+ sheen.addColorStop(0.5, "rgb(255 255 255 / 0.18)");
17251
+ sheen.addColorStop(0.58, "rgb(255 255 255 / 0.02)");
17252
+ sheen.addColorStop(1, "rgb(255 255 255 / 0)");
17253
+ context.fillStyle = sheen;
17254
+ context.fillRect(
17255
+ -recordRadius,
17256
+ -recordRadius,
17257
+ recordRadius * 2,
17258
+ recordRadius * 2
17259
+ );
17260
+ context.restore();
17261
+ context.restore();
17262
+ context.save();
17263
+ context.beginPath();
17264
+ context.arc(center, center, labelRadius, 0, Math.PI * 2);
17265
+ context.clip();
17266
+ const scale = Math.max(
17267
+ labelRadius * 2 / image.width,
17268
+ labelRadius * 2 / image.height
17269
+ );
17270
+ const width = image.width * scale;
17271
+ const height = image.height * scale;
17272
+ context.drawImage(
17273
+ image,
17274
+ center - width / 2,
17275
+ center - height / 2,
17276
+ width,
17277
+ height
17278
+ );
17279
+ context.restore();
17280
+ context.beginPath();
17281
+ context.arc(center, center, labelRadius, 0, Math.PI * 2);
17282
+ context.strokeStyle = "rgb(255 255 255 / 0.2)";
17283
+ context.lineWidth = 1;
17284
+ context.stroke();
17285
+ context.beginPath();
17286
+ context.arc(
17287
+ center,
17288
+ center,
17289
+ recordRadius * RECORD_SPINDLE_RADIUS_RATIO,
17290
+ 0,
17291
+ Math.PI * 2
17292
+ );
17293
+ context.fillStyle = "rgb(5 5 6)";
17294
+ context.fill();
17295
+ context.strokeStyle = "rgb(255 255 255 / 0.18)";
17296
+ context.lineWidth = 0.75;
17297
+ context.stroke();
17298
+ context.beginPath();
17299
+ context.arc(center, center, recordRadius - 0.75, 0, Math.PI * 2);
17300
+ context.strokeStyle = "rgb(255 255 255 / 0.32)";
17301
+ context.lineWidth = 1.25;
17302
+ context.stroke();
17303
+ }
17304
+ const texture = new THREE.CanvasTexture(canvas);
17305
+ texture.colorSpace = THREE.SRGBColorSpace;
17306
+ texture.anisotropy = 4;
17307
+ onReadyRender();
17308
+ return texture;
17309
+ }
17310
+ function roundedIconTexture(image, onReadyRender, cornerRadius) {
17185
17311
  const canvas = document.createElement("canvas");
17186
17312
  canvas.width = TEXTURE_SIZE;
17187
17313
  canvas.height = TEXTURE_SIZE;
@@ -17224,8 +17350,11 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17224
17350
  renderer;
17225
17351
  scene;
17226
17352
  camera;
17353
+ edgeGeometry;
17354
+ faceGeometry;
17227
17355
  raycaster = new THREE.Raycaster();
17228
17356
  tiles = [];
17357
+ textures = /* @__PURE__ */ new Set();
17229
17358
  // Number of distinct agents; the wheel holds agentCount * repeats tiles
17230
17359
  // (the icon sequence repeated), and scroll/target count TILE slots.
17231
17360
  agentCount;
@@ -17237,8 +17366,12 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17237
17366
  scroll = 0;
17238
17367
  target = 0;
17239
17368
  velocity = 0;
17240
- frameHandle = null;
17369
+ renderFrameHandle = null;
17370
+ springFrameHandle = null;
17371
+ recordSpinFrameHandle = null;
17241
17372
  lastFrameAt = null;
17373
+ lastRecordSpinFrameAt = null;
17374
+ hoveredTile = null;
17242
17375
  disposed = false;
17243
17376
  constructor(options) {
17244
17377
  this.agentCount = options.items.length;
@@ -17258,29 +17391,78 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17258
17391
  this.scene = new THREE.Scene();
17259
17392
  this.camera = new THREE.PerspectiveCamera(CAMERA_FOV_DEG, 1, 0.1, 50);
17260
17393
  this.camera.position.set(0, 0, CAMERA_Z);
17394
+ this.scene.add(new THREE.AmbientLight(16777215, 1.25));
17395
+ const keyLight = new THREE.DirectionalLight(16777215, 2.4);
17396
+ keyLight.position.set(-2.5, 3.5, 5);
17397
+ this.scene.add(keyLight);
17398
+ const rimLight = new THREE.DirectionalLight(10467327, 0.9);
17399
+ rimLight.position.set(4, -1.5, 2.5);
17400
+ this.scene.add(rimLight);
17401
+ this.faceGeometry = new THREE.PlaneGeometry(1, 1);
17402
+ this.edgeGeometry = new THREE.CylinderGeometry(
17403
+ RECORD_MODEL_RADIUS,
17404
+ RECORD_MODEL_RADIUS,
17405
+ RECORD_MODEL_THICKNESS,
17406
+ RECORD_EDGE_SEGMENTS,
17407
+ 1,
17408
+ true
17409
+ );
17261
17410
  for (let slot = 0; slot < this.tileCount; slot++) {
17262
- const geometry = new THREE.PlaneGeometry(1, 1);
17263
- const material = new THREE.MeshBasicMaterial({
17411
+ const agentIndex = slot % this.agentCount;
17412
+ const poseGroup = new THREE.Group();
17413
+ const recordGroup = new THREE.Group();
17414
+ recordGroup.scale.setScalar(RECORD_MODEL_SCALE);
17415
+ const faceMaterial = new THREE.MeshBasicMaterial({
17264
17416
  transparent: true,
17265
17417
  depthWrite: false,
17266
17418
  visible: false
17267
17419
  });
17268
- const mesh = new THREE.Mesh(geometry, material);
17269
- mesh.userData.agentIndex = slot % this.agentCount;
17420
+ const faceMesh = new THREE.Mesh(this.faceGeometry, faceMaterial);
17421
+ faceMesh.position.z = RECORD_MODEL_THICKNESS / 2 + 2e-3;
17422
+ faceMesh.userData.agentIndex = agentIndex;
17423
+ const edgeMaterial = new THREE.MeshStandardMaterial({
17424
+ color: 460552,
17425
+ metalness: 0.42,
17426
+ roughness: 0.28,
17427
+ transparent: true,
17428
+ depthWrite: false
17429
+ });
17430
+ const edgeMesh = new THREE.Mesh(this.edgeGeometry, edgeMaterial);
17431
+ edgeMesh.rotation.x = Math.PI / 2;
17270
17432
  const badgeMaterial = new THREE.MeshBasicMaterial({
17271
17433
  transparent: true,
17272
17434
  depthWrite: false,
17273
- visible: false
17435
+ // The solid circle is the owner marker's asset-independent fallback.
17436
+ // Keep it visible while the optional remote avatar is loading or when
17437
+ // that avatar cannot safely become a WebGL texture.
17438
+ visible: options.items[slot % this.agentCount]?.badge != null
17274
17439
  });
17275
17440
  const badgeMesh = new THREE.Mesh(
17276
17441
  new THREE.CircleGeometry(BADGE_DIAMETER / 2, 32),
17277
17442
  badgeMaterial
17278
17443
  );
17279
- badgeMesh.position.set(BADGE_OFFSET, -BADGE_OFFSET, 0.01);
17280
- badgeMesh.userData.agentIndex = slot % this.agentCount;
17281
- mesh.add(badgeMesh);
17282
- this.scene.add(mesh);
17283
- this.tiles.push({ badgeMesh, mesh });
17444
+ badgeMesh.position.set(
17445
+ BADGE_OFFSET,
17446
+ -BADGE_OFFSET,
17447
+ RECORD_MODEL_THICKNESS / 2 + 0.01
17448
+ );
17449
+ badgeMesh.userData.agentIndex = agentIndex;
17450
+ recordGroup.add(edgeMesh, faceMesh);
17451
+ poseGroup.add(recordGroup, badgeMesh);
17452
+ poseGroup.visible = false;
17453
+ poseGroup.userData.agentIndex = agentIndex;
17454
+ this.scene.add(poseGroup);
17455
+ this.tiles.push({
17456
+ badgeMesh,
17457
+ edgeMaterial,
17458
+ edgeMesh,
17459
+ faceMaterial,
17460
+ faceMesh,
17461
+ poseGroup,
17462
+ ready: false,
17463
+ recordGroup,
17464
+ rotation: 0
17465
+ });
17284
17466
  }
17285
17467
  options.items.forEach((item, agentIndex) => {
17286
17468
  const loadedImage = options.loadedImages?.[agentIndex] ?? null;
@@ -17308,6 +17490,7 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17308
17490
  }
17309
17491
  });
17310
17492
  this.applyPoses();
17493
+ this.startRecordSpin();
17311
17494
  }
17312
17495
  setSize(width, height) {
17313
17496
  if (this.disposed || width <= 0 || height <= 0) {
@@ -17330,6 +17513,7 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17330
17513
  // icon sequence repeats); returns the normalized agent index.
17331
17514
  stepBy(direction) {
17332
17515
  this.target += direction;
17516
+ this.primeSpringMotion();
17333
17517
  this.animate();
17334
17518
  return this.targetIndex();
17335
17519
  }
@@ -17358,6 +17542,7 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17358
17542
  }
17359
17543
  this.target += best ?? 0;
17360
17544
  if (animateMove) {
17545
+ this.primeSpringMotion();
17361
17546
  this.animate();
17362
17547
  return;
17363
17548
  }
@@ -17368,6 +17553,26 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17368
17553
  }
17369
17554
  // Canvas-relative pointer coordinates -> agent index, or null.
17370
17555
  pick(x, y, width, height) {
17556
+ const tile = this.pickTile(x, y, width, height);
17557
+ const index = tile?.poseGroup.userData.agentIndex;
17558
+ return typeof index === "number" ? index : null;
17559
+ }
17560
+ // Gives playback to the record beneath the pointer. When no record is
17561
+ // hovered, playback returns to the record nearest the center.
17562
+ hover(x, y, width, height) {
17563
+ const tile = this.pickTile(x, y, width, height);
17564
+ if (tile !== this.hoveredTile) {
17565
+ this.hoveredTile = tile;
17566
+ this.startRecordSpin();
17567
+ }
17568
+ const index = tile?.poseGroup.userData.agentIndex;
17569
+ return typeof index === "number" ? index : null;
17570
+ }
17571
+ clearHover() {
17572
+ this.hoveredTile = null;
17573
+ this.startRecordSpin();
17574
+ }
17575
+ pickTile(x, y, width, height) {
17371
17576
  if (this.disposed || width <= 0 || height <= 0) {
17372
17577
  return null;
17373
17578
  }
@@ -17377,35 +17582,52 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17377
17582
  );
17378
17583
  this.raycaster.setFromCamera(pointer, this.camera);
17379
17584
  const meshes = this.tiles.filter(
17380
- (tile) => tile.mesh.material.visible && tile.mesh.material.opacity > 0.05
17585
+ (tile) => tile.poseGroup.visible && tile.faceMaterial.visible && tile.faceMaterial.opacity > 0.05
17381
17586
  ).flatMap(
17382
- (tile) => tile.badgeMesh.material.visible ? [tile.mesh, tile.badgeMesh] : [tile.mesh]
17587
+ (tile) => tile.badgeMesh.material.visible ? [tile.faceMesh, tile.badgeMesh] : [tile.faceMesh]
17383
17588
  );
17384
17589
  const hit = this.raycaster.intersectObjects(meshes, false)[0];
17385
- const index = hit?.object.userData.agentIndex;
17386
- return typeof index === "number" ? index : null;
17590
+ if (!hit) {
17591
+ return null;
17592
+ }
17593
+ return this.tiles.find(
17594
+ (tile) => tile.faceMesh === hit.object || tile.badgeMesh === hit.object
17595
+ ) ?? null;
17387
17596
  }
17388
17597
  dispose() {
17389
17598
  this.disposed = true;
17390
- if (this.frameHandle !== null) {
17391
- cancelAnimationFrame(this.frameHandle);
17392
- this.frameHandle = null;
17599
+ if (this.renderFrameHandle !== null) {
17600
+ cancelAnimationFrame(this.renderFrameHandle);
17601
+ this.renderFrameHandle = null;
17602
+ }
17603
+ if (this.springFrameHandle !== null) {
17604
+ cancelAnimationFrame(this.springFrameHandle);
17605
+ this.springFrameHandle = null;
17606
+ }
17607
+ if (this.recordSpinFrameHandle !== null) {
17608
+ cancelAnimationFrame(this.recordSpinFrameHandle);
17609
+ this.recordSpinFrameHandle = null;
17393
17610
  }
17394
17611
  for (const image of this.images) {
17395
17612
  image.onload = null;
17613
+ image.onerror = null;
17396
17614
  if (this.ownedImages.has(image)) {
17397
17615
  image.src = "";
17398
17616
  }
17399
17617
  }
17400
17618
  this.ownedImages.clear();
17401
17619
  for (const tile of this.tiles) {
17402
- tile.mesh.geometry.dispose();
17403
- tile.mesh.material.map?.dispose();
17404
- tile.mesh.material.dispose();
17405
17620
  tile.badgeMesh.geometry.dispose();
17406
- tile.badgeMesh.material.map?.dispose();
17407
17621
  tile.badgeMesh.material.dispose();
17622
+ tile.faceMaterial.dispose();
17623
+ tile.edgeMaterial.dispose();
17408
17624
  }
17625
+ for (const texture of this.textures) {
17626
+ texture.dispose();
17627
+ }
17628
+ this.textures.clear();
17629
+ this.faceGeometry.dispose();
17630
+ this.edgeGeometry.dispose();
17409
17631
  this.renderer.dispose();
17410
17632
  }
17411
17633
  prefersReducedMotion() {
@@ -17423,17 +17645,31 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17423
17645
  this.onSettle(this.targetIndex());
17424
17646
  return;
17425
17647
  }
17426
- if (this.frameHandle === null) {
17648
+ if (this.springFrameHandle === null) {
17649
+ if (this.renderFrameHandle !== null) {
17650
+ cancelAnimationFrame(this.renderFrameHandle);
17651
+ this.renderFrameHandle = null;
17652
+ }
17427
17653
  this.lastFrameAt = null;
17428
- this.frameHandle = requestAnimationFrame(this.frame);
17654
+ this.springFrameHandle = requestAnimationFrame(this.frame);
17655
+ }
17656
+ }
17657
+ primeSpringMotion() {
17658
+ const delta = this.target - this.scroll;
17659
+ const direction = Math.sign(delta);
17660
+ if (direction === 0) {
17661
+ return;
17662
+ }
17663
+ if (this.velocity * direction < SPRING_MIN_LAUNCH_VELOCITY) {
17664
+ this.velocity = direction * SPRING_MIN_LAUNCH_VELOCITY;
17429
17665
  }
17430
17666
  }
17431
17667
  frame = (now) => {
17432
- this.frameHandle = null;
17668
+ this.springFrameHandle = null;
17433
17669
  if (this.disposed) {
17434
17670
  return;
17435
17671
  }
17436
- const dt = this.lastFrameAt === null ? 1 / 60 : Math.min((now - this.lastFrameAt) / 1e3, 0.05);
17672
+ const dt = this.lastFrameAt === null ? 1 / 60 : Math.min((now - this.lastFrameAt) / 1e3, MAX_FRAME_DELTA_SECONDS);
17437
17673
  this.lastFrameAt = now;
17438
17674
  const delta = this.target - this.scroll;
17439
17675
  if (Math.abs(delta) <= SPRING_SETTLE_EPSILON && Math.abs(this.velocity) <= SPRING_SETTLE_VELOCITY) {
@@ -17449,14 +17685,54 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17449
17685
  this.scroll += this.velocity * dt;
17450
17686
  this.applyPoses();
17451
17687
  this.renderer.render(this.scene, this.camera);
17452
- this.frameHandle = requestAnimationFrame(this.frame);
17688
+ this.springFrameHandle = requestAnimationFrame(this.frame);
17689
+ };
17690
+ startRecordSpin() {
17691
+ if (this.disposed || this.prefersReducedMotion() || this.recordSpinFrameHandle !== null) {
17692
+ return;
17693
+ }
17694
+ this.lastRecordSpinFrameAt = null;
17695
+ this.recordSpinFrameHandle = requestAnimationFrame(this.recordSpinFrame);
17696
+ }
17697
+ recordSpinFrame = (now) => {
17698
+ this.recordSpinFrameHandle = null;
17699
+ const spinningTile = this.hoveredTile ?? this.centerTile();
17700
+ if (this.disposed || !spinningTile || this.prefersReducedMotion()) {
17701
+ return;
17702
+ }
17703
+ const dt = this.lastRecordSpinFrameAt === null ? 1 / 60 : Math.min(
17704
+ (now - this.lastRecordSpinFrameAt) / 1e3,
17705
+ MAX_FRAME_DELTA_SECONDS
17706
+ );
17707
+ this.lastRecordSpinFrameAt = now;
17708
+ spinningTile.rotation = (spinningTile.rotation + Math.PI * 2 * dt / RECORD_SPIN_SECONDS) % (Math.PI * 2);
17709
+ if (this.springFrameHandle === null) {
17710
+ this.applyPoses();
17711
+ this.renderer.render(this.scene, this.camera);
17712
+ }
17713
+ this.recordSpinFrameHandle = requestAnimationFrame(this.recordSpinFrame);
17453
17714
  };
17715
+ centerTile() {
17716
+ let centeredTile = null;
17717
+ let centeredOffset = Number.POSITIVE_INFINITY;
17718
+ this.tiles.forEach((tile, index) => {
17719
+ if (!tile.ready) {
17720
+ return;
17721
+ }
17722
+ const offset = Math.abs(ringOffset(index, this.scroll, this.tileCount));
17723
+ if (offset < centeredOffset) {
17724
+ centeredTile = tile;
17725
+ centeredOffset = offset;
17726
+ }
17727
+ });
17728
+ return centeredTile;
17729
+ }
17454
17730
  requestRender() {
17455
- if (this.disposed || this.frameHandle !== null) {
17731
+ if (this.disposed || this.renderFrameHandle !== null || this.springFrameHandle !== null) {
17456
17732
  return;
17457
17733
  }
17458
- this.frameHandle = requestAnimationFrame(() => {
17459
- this.frameHandle = null;
17734
+ this.renderFrameHandle = requestAnimationFrame(() => {
17735
+ this.renderFrameHandle = null;
17460
17736
  if (!this.disposed) {
17461
17737
  this.renderer.render(this.scene, this.camera);
17462
17738
  }
@@ -17466,53 +17742,124 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
17466
17742
  if (this.disposed) {
17467
17743
  return;
17468
17744
  }
17469
- const texture = roundedIconTexture(image, () => this.requestRender());
17745
+ const texture = vinylRecordTexture(image, () => this.requestRender());
17746
+ this.textures.add(texture);
17470
17747
  for (const tile of this.tiles) {
17471
- if (tile.mesh.userData.agentIndex === agentIndex) {
17472
- tile.mesh.material.map = texture;
17473
- tile.mesh.material.visible = true;
17474
- tile.mesh.material.needsUpdate = true;
17748
+ if (tile.poseGroup.userData.agentIndex === agentIndex) {
17749
+ tile.faceMaterial.map = texture;
17750
+ tile.faceMaterial.visible = true;
17751
+ tile.faceMaterial.needsUpdate = true;
17752
+ tile.ready = true;
17475
17753
  }
17476
17754
  }
17755
+ this.applyPoses();
17756
+ this.startRecordSpin();
17477
17757
  }
17478
17758
  loadBadgeImage(badgeUrl, agentIndex) {
17479
17759
  const image = new Image();
17760
+ image.crossOrigin = "anonymous";
17480
17761
  image.decoding = "async";
17481
17762
  image.loading = "eager";
17482
17763
  this.ownedImages.add(image);
17483
17764
  this.images.push(image);
17765
+ let settled = false;
17766
+ const keepFallback = () => {
17767
+ if (settled) {
17768
+ return;
17769
+ }
17770
+ settled = true;
17771
+ this.requestRender();
17772
+ };
17773
+ const applyDecodedImage = () => {
17774
+ if (settled) {
17775
+ return;
17776
+ }
17777
+ settled = true;
17778
+ this.applyBadgeImageTexture(image, agentIndex);
17779
+ };
17484
17780
  image.onload = () => {
17485
17781
  if (this.disposed) {
17486
17782
  return;
17487
17783
  }
17488
- const texture = roundedIconTexture(
17784
+ let decode;
17785
+ try {
17786
+ decode = image.decode?.();
17787
+ } catch {
17788
+ keepFallback();
17789
+ return;
17790
+ }
17791
+ if (decode) {
17792
+ void decode.then(applyDecodedImage).catch(keepFallback);
17793
+ return;
17794
+ }
17795
+ applyDecodedImage();
17796
+ };
17797
+ image.onerror = keepFallback;
17798
+ image.src = badgeUrl;
17799
+ }
17800
+ applyBadgeImageTexture(image, agentIndex) {
17801
+ if (this.disposed) {
17802
+ return;
17803
+ }
17804
+ let texture = null;
17805
+ try {
17806
+ texture = roundedIconTexture(
17489
17807
  image,
17490
17808
  () => this.requestRender(),
17491
17809
  BADGE_CORNER_RADIUS
17492
17810
  );
17493
- for (const tile of this.tiles) {
17494
- if (tile.mesh.userData.agentIndex === agentIndex) {
17495
- tile.badgeMesh.material.map = texture;
17496
- tile.badgeMesh.material.visible = true;
17497
- tile.badgeMesh.material.needsUpdate = true;
17498
- }
17499
- }
17811
+ this.renderer.initTexture(texture);
17812
+ } catch {
17813
+ texture?.dispose();
17500
17814
  this.requestRender();
17501
- };
17502
- image.src = badgeUrl;
17815
+ return;
17816
+ }
17817
+ this.textures.add(texture);
17818
+ for (const tile of this.tiles) {
17819
+ if (tile.poseGroup.userData.agentIndex === agentIndex) {
17820
+ tile.badgeMesh.material.map = texture;
17821
+ tile.badgeMesh.material.visible = true;
17822
+ tile.badgeMesh.material.needsUpdate = true;
17823
+ }
17824
+ }
17825
+ this.requestRender();
17503
17826
  }
17504
17827
  applyPoses() {
17505
17828
  const step = Math.PI * 2 / Math.max(this.tileCount, 1);
17506
17829
  this.tiles.forEach((tile, index) => {
17507
17830
  const offset = ringOffset(index, this.scroll, this.tileCount);
17831
+ const visible = tile.ready && Math.abs(offset) <= RECORD_RENDER_RANGE_SLOTS;
17832
+ tile.poseGroup.visible = visible;
17833
+ if (!visible) {
17834
+ return;
17835
+ }
17508
17836
  const angle = offset * step;
17509
17837
  const x = this.wheelRadius * Math.sin(angle);
17510
- const y = this.wheelRadius * (Math.cos(angle) - 1);
17511
- tile.mesh.position.set(x, y, 0);
17512
- tile.mesh.rotation.z = -angle;
17513
- const focus = THREE.MathUtils.clamp(1 - Math.abs(offset), 0, 1);
17514
- tile.mesh.material.opacity = UNFOCUSED_OPACITY + (1 - UNFOCUSED_OPACITY) * focus;
17515
- tile.badgeMesh.material.opacity = tile.mesh.material.opacity;
17838
+ const y = this.wheelRadius * (Math.cos(angle) - 1) * VISIBLE_ARC_CURVATURE;
17839
+ tile.poseGroup.position.set(x, y, 0);
17840
+ const fadeProgress = THREE.MathUtils.clamp(
17841
+ 1 - Math.abs(offset) / RECORD_FADE_RANGE_SLOTS,
17842
+ 0,
17843
+ 1
17844
+ );
17845
+ const rangeOpacity = Math.pow(
17846
+ THREE.MathUtils.smoothstep(fadeProgress, 0, 1),
17847
+ RECORD_FADE_CURVE
17848
+ );
17849
+ tile.poseGroup.rotation.set(
17850
+ RECORD_MODEL_TILT_X,
17851
+ THREE.MathUtils.clamp(
17852
+ -angle * RECORD_MODEL_SIDE_TILT_FACTOR,
17853
+ -RECORD_MODEL_MAX_SIDE_TILT,
17854
+ RECORD_MODEL_MAX_SIDE_TILT
17855
+ ),
17856
+ -angle * VISIBLE_ARC_CURVATURE
17857
+ );
17858
+ tile.recordGroup.rotation.z = -tile.rotation;
17859
+ const opacity = MIN_RECORD_OPACITY + (1 - MIN_RECORD_OPACITY) * rangeOpacity;
17860
+ tile.faceMaterial.opacity = opacity;
17861
+ tile.edgeMaterial.opacity = opacity;
17862
+ tile.badgeMesh.material.opacity = opacity;
17516
17863
  });
17517
17864
  }
17518
17865
  };
@@ -17719,6 +18066,7 @@ var AgentGUIHeroAgentCarousel = memo2(
17719
18066
  null
17720
18067
  );
17721
18068
  const suppressClickRef = useRef5(false);
18069
+ const pointerActivatedIndexRef = useRef5(null);
17722
18070
  const handlePointerDown = (event) => {
17723
18071
  if (!interactive || event.button !== 0) {
17724
18072
  return;
@@ -17740,6 +18088,7 @@ var AgentGUIHeroAgentCarousel = memo2(
17740
18088
  }
17741
18089
  drag.anchorX = event.clientX;
17742
18090
  suppressClickRef.current = true;
18091
+ pointerActivatedIndexRef.current = null;
17743
18092
  stepBy(deltaX < 0 ? 1 : -1);
17744
18093
  };
17745
18094
  const handlePointerEnd = (event) => {
@@ -17752,6 +18101,7 @@ var AgentGUIHeroAgentCarousel = memo2(
17752
18101
  return;
17753
18102
  }
17754
18103
  suppressClickRef.current = false;
18104
+ pointerActivatedIndexRef.current = null;
17755
18105
  event.preventDefault();
17756
18106
  event.stopPropagation();
17757
18107
  };
@@ -17782,18 +18132,53 @@ var AgentGUIHeroAgentCarousel = memo2(
17782
18132
  rect.height
17783
18133
  );
17784
18134
  };
18135
+ const activateOnPointerDown = (index, event) => {
18136
+ if (event.button !== 0) {
18137
+ return;
18138
+ }
18139
+ pointerActivatedIndexRef.current = index;
18140
+ handleItemClick(index);
18141
+ };
18142
+ const activateOnClick = (index) => {
18143
+ if (pointerActivatedIndexRef.current === index) {
18144
+ pointerActivatedIndexRef.current = null;
18145
+ return;
18146
+ }
18147
+ pointerActivatedIndexRef.current = null;
18148
+ handleItemClick(index);
18149
+ };
18150
+ const handleCanvasPointerDown = (event) => {
18151
+ const index = pickAt(event);
18152
+ if (index !== null) {
18153
+ activateOnPointerDown(index, event);
18154
+ }
18155
+ };
17785
18156
  const handleCanvasClick = (event) => {
17786
18157
  const index = pickAt(event);
17787
18158
  if (index !== null) {
17788
- handleItemClick(index);
18159
+ activateOnClick(index);
17789
18160
  }
17790
18161
  };
17791
18162
  const handleCanvasHover = (event) => {
18163
+ const scene = sceneRef.current;
17792
18164
  const canvas = canvasRef.current;
17793
- if (!canvas) {
18165
+ if (!scene || !canvas) {
17794
18166
  return;
17795
18167
  }
17796
- canvas.style.cursor = pickAt(event) !== null ? "pointer" : "";
18168
+ const rect = canvas.getBoundingClientRect();
18169
+ const hoveredIndex = scene.hover(
18170
+ event.clientX - rect.left,
18171
+ event.clientY - rect.top,
18172
+ rect.width,
18173
+ rect.height
18174
+ );
18175
+ canvas.style.cursor = hoveredIndex !== null ? "pointer" : "";
18176
+ };
18177
+ const handleCanvasLeave = () => {
18178
+ sceneRef.current?.clearHover();
18179
+ if (canvasRef.current) {
18180
+ canvasRef.current.style.cursor = "";
18181
+ }
17797
18182
  };
17798
18183
  return /* @__PURE__ */ jsxs9(
17799
18184
  "div",
@@ -17818,7 +18203,9 @@ var AgentGUIHeroAgentCarousel = memo2(
17818
18203
  "aria-hidden": "true",
17819
18204
  className: AgentGUINode_styles_default.emptyHeroCarouselCanvas,
17820
18205
  onClick: interactive ? handleCanvasClick : void 0,
17821
- onPointerMove: interactive ? handleCanvasHover : void 0
18206
+ onPointerDown: interactive ? handleCanvasPointerDown : void 0,
18207
+ onPointerMove: interactive ? handleCanvasHover : void 0,
18208
+ onPointerLeave: interactive ? handleCanvasLeave : void 0
17822
18209
  }
17823
18210
  ),
17824
18211
  items.map((item, index) => {
@@ -17838,7 +18225,8 @@ var AgentGUIHeroAgentCarousel = memo2(
17838
18225
  "aria-label": label,
17839
18226
  "aria-pressed": isCenter,
17840
18227
  title: item.label,
17841
- onClick: () => handleItemClick(index),
18228
+ onPointerDown: (event) => activateOnPointerDown(index, event),
18229
+ onClick: () => activateOnClick(index),
17842
18230
  children: item.label
17843
18231
  },
17844
18232
  key
@@ -28924,7 +29312,7 @@ var AgentGUIDetailPane = memo3(function AgentGUIDetailPane2({
28924
29312
  emptyHeroProviderLabel
28925
29313
  ) : emptyHeroBaseLabel;
28926
29314
  const emptyHeroAvatarPresentations = useMemo11(
28927
- () => viewModel.conversationFilter.kind === "all" ? viewModel.agentTargets.map(projectAgentGUIAgentTargetAvatar) : viewModel.selectedAgentTarget ? [projectAgentGUIAgentTargetAvatar(viewModel.selectedAgentTarget)] : [
29315
+ () => viewModel.agentTargets.length > 0 ? viewModel.agentTargets.map(projectAgentGUIAgentTargetAvatar) : viewModel.selectedAgentTarget ? [projectAgentGUIAgentTargetAvatar(viewModel.selectedAgentTarget)] : [
28928
29316
  createFallbackAgentGUIAgentAvatar({
28929
29317
  provider: emptyHeroProvider,
28930
29318
  label: emptyHeroProviderLabel,
@@ -28934,7 +29322,6 @@ var AgentGUIDetailPane = memo3(function AgentGUIDetailPane2({
28934
29322
  [
28935
29323
  emptyHeroProvider,
28936
29324
  emptyHeroProviderLabel,
28937
- viewModel.conversationFilter.kind,
28938
29325
  viewModel.agentTargets,
28939
29326
  viewModel.selectedAgentTarget
28940
29327
  ]
@@ -29355,7 +29742,7 @@ var AgentGUIDetailPane = memo3(function AgentGUIDetailPane2({
29355
29742
  disabledAgentTarget.provider
29356
29743
  ),
29357
29744
  unavailableReason: disabledAgentTarget.unavailableReason ?? null
29358
- }) }) : emptyProviderReadinessGate ? shouldRenderProviderReadinessGateState ? /* @__PURE__ */ jsx35(Fragment9, { children: renderProviderReadinessGateState?.({
29745
+ }) }) : emptyProviderReadinessGate && shouldRenderProviderReadinessGateState ? /* @__PURE__ */ jsx35(Fragment9, { children: renderProviderReadinessGateState?.({
29359
29746
  provider: emptyHeroProvider,
29360
29747
  providerLabel: emptyHeroProviderLabel || resolveAgentGuiWorkbenchProviderLabel(emptyHeroProvider),
29361
29748
  target: viewModel.selectedAgentTarget ?? null,
@@ -29363,42 +29750,53 @@ var AgentGUIDetailPane = memo3(function AgentGUIDetailPane2({
29363
29750
  gate: emptyProviderReadinessGate,
29364
29751
  showAllProviders: viewModel.conversationFilter.kind === "all"
29365
29752
  }) }) : /* @__PURE__ */ jsx35(
29366
- AgentGUIProviderReadinessGatePane,
29753
+ AgentGUIEmptyHeroCarouselStage,
29367
29754
  {
29368
- provider: emptyHeroProvider,
29369
- gate: emptyProviderReadinessGate,
29370
- showAllProviders: viewModel.conversationFilter.kind === "all",
29371
- emptyLabel: emptyHeroLabel,
29372
- emptyProvider: emptyHeroProviderLabel,
29373
- agentTargets: composerAgentTargets,
29374
- selectedAgentTarget: viewModel.selectedAgentTarget,
29755
+ activeAgentTargetId: viewModel.selectedAgentTarget?.agentTargetId ?? viewModel.selectedAgentTarget?.targetId,
29756
+ items: emptyHeroAvatarPresentations,
29375
29757
  onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
29376
29758
  providerSelectLabel: labels.providerSwitchLabel,
29377
- labels
29378
- }
29379
- ) : /* @__PURE__ */ jsx35(
29380
- AgentGUIEmptyHeroPane,
29381
- {
29382
- provider: emptyHeroProvider,
29383
- emptyLabel: emptyHeroLabel,
29384
- emptyProvider: emptyHeroProviderLabel,
29385
- avatarPresentations: emptyHeroAvatarPresentations,
29386
- inlineNoticeChrome,
29387
- isRespondingApproval: viewModel.isRespondingApproval,
29388
- onSubmitApprovalOption: submitApprovalOption,
29389
- onRetryActivation: retryActivation,
29390
- onAuthLogin: authLogin,
29391
- onContinueInNewConversation: continueInNewConversation,
29392
- onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
29393
- agentTargets: composerAgentTargets,
29394
- selectedAgentTarget: viewModel.selectedAgentTarget,
29395
- chromeLabels,
29396
- composerProps: emptyHeroComposerProps,
29397
- providerSelectLabel: labels.providerSwitchLabel,
29398
- suggestions: labels.homeSuggestions ?? EMPTY_HOME_SUGGESTIONS,
29399
- suggestionsCloseLabel: labels.homeSuggestionsClose,
29400
- onSelectSuggestion: handleSelectHomeSuggestion,
29401
- onSelectSuggestionAction: handleHomeSuggestionAction
29759
+ children: emptyProviderReadinessGate ? /* @__PURE__ */ jsx35(
29760
+ AgentGUIProviderReadinessGatePane,
29761
+ {
29762
+ provider: emptyHeroProvider,
29763
+ gate: emptyProviderReadinessGate,
29764
+ showAllProviders: viewModel.conversationFilter.kind === "all",
29765
+ carouselMountedExternally: emptyHeroAvatarPresentations.length > 1,
29766
+ emptyLabel: emptyHeroLabel,
29767
+ emptyProvider: emptyHeroProviderLabel,
29768
+ agentTargets: composerAgentTargets,
29769
+ selectedAgentTarget: viewModel.selectedAgentTarget,
29770
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
29771
+ providerSelectLabel: labels.providerSwitchLabel,
29772
+ labels
29773
+ }
29774
+ ) : /* @__PURE__ */ jsx35(
29775
+ AgentGUIEmptyHeroPane,
29776
+ {
29777
+ provider: emptyHeroProvider,
29778
+ emptyLabel: emptyHeroLabel,
29779
+ emptyProvider: emptyHeroProviderLabel,
29780
+ avatarPresentations: emptyHeroAvatarPresentations,
29781
+ carouselMountedExternally: emptyHeroAvatarPresentations.length > 1,
29782
+ inlineNoticeChrome,
29783
+ isRespondingApproval: viewModel.isRespondingApproval,
29784
+ onSubmitApprovalOption: submitApprovalOption,
29785
+ onRetryActivation: retryActivation,
29786
+ onAuthLogin: authLogin,
29787
+ onContinueInNewConversation: continueInNewConversation,
29788
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
29789
+ agentTargets: composerAgentTargets,
29790
+ selectedAgentTarget: viewModel.selectedAgentTarget,
29791
+ chromeLabels,
29792
+ composerProps: emptyHeroComposerProps,
29793
+ providerSelectLabel: labels.providerSwitchLabel,
29794
+ suggestions: labels.homeSuggestions ?? EMPTY_HOME_SUGGESTIONS,
29795
+ suggestionsCloseLabel: labels.homeSuggestionsClose,
29796
+ onSelectSuggestion: handleSelectHomeSuggestion,
29797
+ onSelectSuggestionAction: handleHomeSuggestionAction
29798
+ }
29799
+ )
29402
29800
  }
29403
29801
  ) : /* @__PURE__ */ jsx35(
29404
29802
  AgentGUIConversationTimelinePane,
@@ -29538,11 +29936,35 @@ function useOptionalStableEventCallback(callback) {
29538
29936
  }, [callback != null]);
29539
29937
  }
29540
29938
  var EMPTY_HOME_SUGGESTIONS = Object.freeze([]);
29939
+ var AgentGUIEmptyHeroCarouselStage = memo3(
29940
+ function AgentGUIEmptyHeroCarouselStage2({
29941
+ activeAgentTargetId,
29942
+ children,
29943
+ items,
29944
+ onProviderSelect,
29945
+ providerSelectLabel
29946
+ }) {
29947
+ "use memo";
29948
+ return /* @__PURE__ */ jsxs22("div", { className: AgentGUINode_styles_default.emptyHeroCarouselStage, children: [
29949
+ items.length > 1 ? /* @__PURE__ */ jsx35("div", { className: AgentGUINode_styles_default.emptyHeroCarouselLayer, children: /* @__PURE__ */ jsx35(
29950
+ AgentGUIHeroAgentCarousel,
29951
+ {
29952
+ activeAgentTargetId,
29953
+ items,
29954
+ onProviderSelect,
29955
+ providerSelectLabel
29956
+ }
29957
+ ) }) : null,
29958
+ children
29959
+ ] });
29960
+ }
29961
+ );
29541
29962
  var AgentGUIEmptyHeroPane = memo3(function AgentGUIEmptyHeroPane2({
29542
29963
  provider,
29543
29964
  emptyLabel,
29544
29965
  emptyProvider,
29545
29966
  avatarPresentations,
29967
+ carouselMountedExternally = false,
29546
29968
  inlineNoticeChrome,
29547
29969
  isRespondingApproval,
29548
29970
  onSubmitApprovalOption,
@@ -29571,23 +29993,29 @@ var AgentGUIEmptyHeroPane = memo3(function AgentGUIEmptyHeroPane2({
29571
29993
  (avatar) => `${avatar.agentTargetId}:${avatar.iconUrl}:${avatar.badge?.iconUrl ?? ""}`
29572
29994
  ).join("|");
29573
29995
  return /* @__PURE__ */ jsx35("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs22("div", { className: AgentGUINode_styles_default.emptyHeroBody, children: [
29574
- /* @__PURE__ */ jsx35("div", { className: AgentGUINode_styles_default.emptyHeroIconSlot, children: heroAvatarPresentations.length > 1 ? /* @__PURE__ */ jsx35(
29575
- AgentGUIHeroAgentCarousel,
29576
- {
29577
- activeAgentTargetId: selectedAgentTarget?.agentTargetId ?? selectedAgentTarget?.targetId,
29578
- items: heroAvatarPresentations,
29579
- onProviderSelect,
29580
- providerSelectLabel
29581
- },
29582
- heroIconAnimationKey
29583
- ) : /* @__PURE__ */ jsx35(
29584
- AgentGUIAgentAvatarVisual,
29996
+ /* @__PURE__ */ jsx35(
29997
+ "div",
29585
29998
  {
29586
- className: AgentGUINode_styles_default.emptyHeroIconEffect,
29587
- presentation: heroAvatarPresentations[0]
29588
- },
29589
- heroIconAnimationKey
29590
- ) }),
29999
+ className: AgentGUINode_styles_default.emptyHeroIconSlot,
30000
+ "data-carousel-placeholder": carouselMountedExternally || void 0,
30001
+ children: carouselMountedExternally ? null : heroAvatarPresentations.length > 1 ? /* @__PURE__ */ jsx35(
30002
+ AgentGUIHeroAgentCarousel,
30003
+ {
30004
+ activeAgentTargetId: selectedAgentTarget?.agentTargetId ?? selectedAgentTarget?.targetId,
30005
+ items: heroAvatarPresentations,
30006
+ onProviderSelect,
30007
+ providerSelectLabel
30008
+ }
30009
+ ) : /* @__PURE__ */ jsx35(
30010
+ AgentGUIAgentAvatarVisual,
30011
+ {
30012
+ className: AgentGUINode_styles_default.emptyHeroIconEffect,
30013
+ presentation: heroAvatarPresentations[0]
30014
+ },
30015
+ heroIconAnimationKey
30016
+ )
30017
+ }
30018
+ ),
29591
30019
  /* @__PURE__ */ jsx35("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: /* @__PURE__ */ jsx35(
29592
30020
  EmptyHeroTitle,
29593
30021
  {
@@ -29634,6 +30062,7 @@ var AgentGUIProviderReadinessGatePane = memo3(
29634
30062
  selectedAgentTarget,
29635
30063
  onProviderSelect,
29636
30064
  providerSelectLabel,
30065
+ carouselMountedExternally = false,
29637
30066
  labels
29638
30067
  }) {
29639
30068
  "use memo";
@@ -29657,7 +30086,13 @@ var AgentGUIProviderReadinessGatePane = memo3(
29657
30086
  "data-testid": "agent-gui-provider-readiness-gate",
29658
30087
  role: "status",
29659
30088
  children: [
29660
- showAllProviders ? /* @__PURE__ */ jsx35(
30089
+ carouselMountedExternally ? /* @__PURE__ */ jsx35(
30090
+ "div",
30091
+ {
30092
+ "aria-hidden": "true",
30093
+ className: AgentGUINode_styles_default.emptyHeroCarouselPlaceholder
30094
+ }
30095
+ ) : showAllProviders ? /* @__PURE__ */ jsx35(
29661
30096
  AgentGUIHeroAgentCarousel,
29662
30097
  {
29663
30098
  activeAgentTargetId: selectedAgentTarget?.agentTargetId ?? selectedAgentTarget?.targetId,