@ai-ecoverse/slicc-spectrum 1.73.1 → 1.73.2

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/slicc-ui.js CHANGED
@@ -30847,6 +30847,20 @@ function user(message, stamp = true) {
30847
30847
  </div>
30848
30848
  </swc-conversation-turn>`;
30849
30849
  }
30850
+ var toolLoaders = {
30851
+ edit: "pencil",
30852
+ read: "page",
30853
+ search: "mag",
30854
+ browser: "eye"
30855
+ };
30856
+ function statusLoader(message) {
30857
+ if (message.parts.at(-1)?.type !== "tool") return "aiLogo";
30858
+ const running2 = message.parts.findLast(
30859
+ (part2) => part2.type === "tool" && part2.tool.status === "running"
30860
+ );
30861
+ if (running2?.type !== "tool") return "aiLogo";
30862
+ return toolLoaders[toolKind(running2.tool.name).id] ?? "hourglass";
30863
+ }
30850
30864
  var people = /* @__PURE__ */ new Set(["follower", "guest"]);
30851
30865
  function byline(message, who2, stamp) {
30852
30866
  if (!who2 && !stamp) return A;
@@ -30861,7 +30875,7 @@ function status(message) {
30861
30875
  }
30862
30876
  if (message.status !== "streaming") return A;
30863
30877
  const calls = message.parts.flatMap((entry) => entry.type === "tool" ? [entry.tool] : []);
30864
- return b`<swc-response-status slot="status" status="active">
30878
+ return b`<swc-response-status slot="status" status="active" loader=${statusLoader(message)}>
30865
30879
  ${calls.map((call) => b`<swc-response-status-step status=${stepStates[call.status]}><span slot="label">${call.name} ${call.title}</span></swc-response-status-step>`)}
30866
30880
  </swc-response-status>`;
30867
30881
  }
@@ -36087,7 +36101,8 @@ var SliccChat = class extends ThemedElement {
36087
36101
  min-height: 0;
36088
36102
  overflow-y: auto;
36089
36103
  container-type: inline-size;
36090
- padding: var(--swc-spacing-400) var(--swc-spacing-300) var(--swc-spacing-500);
36104
+ padding: var(--swc-spacing-400) var(--swc-spacing-300) calc(var(--composer-height, 0px) + var(--swc-spacing-500));
36105
+ scroll-padding-block-end: calc(var(--composer-height, 0px) + var(--swc-spacing-200));
36091
36106
  font-size: var(--swc-font-size-200);
36092
36107
  }
36093
36108
  @container (min-width: 600px) {
@@ -36200,6 +36215,11 @@ var SliccChat = class extends ThemedElement {
36200
36215
  return last?.role === "user" && last.id !== this.#tail && (last.origin ?? "user") === "user";
36201
36216
  }
36202
36217
  #resize = new ResizeObserver(() => this.#pin());
36218
+ #fitted = null;
36219
+ #fit = new ResizeObserver(([entry]) => {
36220
+ this.style.setProperty("--composer-height", `${entry.target.offsetHeight}px`);
36221
+ this.#pin();
36222
+ });
36203
36223
  #log() {
36204
36224
  return this.renderRoot.querySelector(".log");
36205
36225
  }
@@ -36254,8 +36274,20 @@ var SliccChat = class extends ThemedElement {
36254
36274
  const log = this.#log();
36255
36275
  this.#resize.observe(log);
36256
36276
  this.#resize.observe(log.firstElementChild);
36277
+ this.#attach();
36257
36278
  this.#refresh(true);
36258
36279
  }
36280
+ #attach() {
36281
+ const composer = this.renderRoot.querySelector("slicc-composer");
36282
+ if (composer === this.#fitted) return;
36283
+ this.#fit.disconnect();
36284
+ this.#fitted = composer;
36285
+ if (composer) this.#fit.observe(composer);
36286
+ else this.style.setProperty("--composer-height", "0px");
36287
+ }
36288
+ updated() {
36289
+ this.#attach();
36290
+ }
36259
36291
  connectedCallback() {
36260
36292
  super.connectedCallback();
36261
36293
  globalThis.addEventListener("pointerup", this.#release, true);
@@ -36267,6 +36299,8 @@ var SliccChat = class extends ThemedElement {
36267
36299
  globalThis.removeEventListener("pointerup", this.#release, true);
36268
36300
  globalThis.removeEventListener("pointercancel", this.#release, true);
36269
36301
  this.#resize.disconnect();
36302
+ this.#fit.disconnect();
36303
+ this.#fitted = null;
36270
36304
  clearTimeout(this.#settle);
36271
36305
  }
36272
36306
  firstUpdated() {
@@ -37720,6 +37754,7 @@ var SliccComposer = class extends ThemedElement {
37720
37754
  attachments: { state: true },
37721
37755
  popup: { state: true },
37722
37756
  dictating: { state: true },
37757
+ erasing: { state: true },
37723
37758
  blocked: { state: true },
37724
37759
  sharing: { state: true },
37725
37760
  secretError: { state: true },
@@ -37733,6 +37768,7 @@ var SliccComposer = class extends ThemedElement {
37733
37768
  #next = 1;
37734
37769
  #abandon;
37735
37770
  #recognition = null;
37771
+ #erase;
37736
37772
  #keys = { capture: true, handleEvent: (event2) => this.#keydown(event2) };
37737
37773
  constructor() {
37738
37774
  super();
@@ -37740,6 +37776,7 @@ var SliccComposer = class extends ThemedElement {
37740
37776
  this.attachments = [];
37741
37777
  this.popup = null;
37742
37778
  this.dictating = false;
37779
+ this.erasing = false;
37743
37780
  this.blocked = false;
37744
37781
  this.sharing = false;
37745
37782
  this.secretError = null;
@@ -37751,11 +37788,49 @@ var SliccComposer = class extends ThemedElement {
37751
37788
  i`
37752
37789
  :host {
37753
37790
  display: block;
37754
- flex: none;
37791
+ position: absolute;
37792
+ left: 0;
37793
+ right: 0;
37794
+ bottom: 0;
37795
+ z-index: 2;
37755
37796
  padding: var(--swc-spacing-100) var(--swc-spacing-200) var(--swc-spacing-200);
37756
- background: var(--swc-background-layer-1-color);
37757
37797
  font-size: var(--swc-font-size-100);
37758
- position: relative;
37798
+ }
37799
+ :host::before {
37800
+ content: '';
37801
+ position: absolute;
37802
+ top: -72px;
37803
+ left: 0;
37804
+ right: 0;
37805
+ bottom: 0;
37806
+ z-index: -1;
37807
+ pointer-events: none;
37808
+ background: color-mix(in srgb, var(--swc-background-layer-1-color) 72%, transparent);
37809
+ backdrop-filter: blur(16px) saturate(1.4);
37810
+ -webkit-backdrop-filter: blur(16px) saturate(1.4);
37811
+ mask-image: linear-gradient(to bottom, transparent, black 72px);
37812
+ -webkit-mask-image: linear-gradient(to bottom, transparent, black 72px);
37813
+ }
37814
+ @media (prefers-reduced-transparency: reduce) {
37815
+ :host::before {
37816
+ top: 0;
37817
+ background: var(--swc-background-layer-1-color);
37818
+ backdrop-filter: none;
37819
+ -webkit-backdrop-filter: none;
37820
+ mask-image: none;
37821
+ -webkit-mask-image: none;
37822
+ }
37823
+ }
37824
+ @media (forced-colors: active) {
37825
+ :host::before {
37826
+ top: 0;
37827
+ background: Canvas;
37828
+ backdrop-filter: none;
37829
+ -webkit-backdrop-filter: none;
37830
+ mask-image: none;
37831
+ -webkit-mask-image: none;
37832
+ border-block-start: var(--swc-border-width-100) solid CanvasText;
37833
+ }
37759
37834
  }
37760
37835
  .column {
37761
37836
  max-width: 860px;
@@ -37863,28 +37938,6 @@ var SliccComposer = class extends ThemedElement {
37863
37938
  margin: var(--swc-spacing-75) auto 0;
37864
37939
  min-height: var(--swc-component-height-75);
37865
37940
  }
37866
- .hint {
37867
- display: flex;
37868
- flex: 1;
37869
- flex-wrap: wrap;
37870
- align-items: center;
37871
- min-width: 0;
37872
- max-block-size: var(--swc-component-height-75);
37873
- overflow: hidden;
37874
- font-size: var(--swc-font-size-75);
37875
- color: var(--swc-neutral-subdued-content-color-default);
37876
- }
37877
- .hint > span {
37878
- display: flex;
37879
- align-items: center;
37880
- block-size: var(--swc-component-height-75);
37881
- gap: var(--swc-spacing-50);
37882
- white-space: nowrap;
37883
- }
37884
- .hint > span + span::before {
37885
- content: '·';
37886
- padding-inline-start: var(--swc-spacing-75);
37887
- }
37888
37941
  .below swc-action-button {
37889
37942
  margin-inline-start: auto;
37890
37943
  }
@@ -37898,11 +37951,6 @@ var SliccComposer = class extends ThemedElement {
37898
37951
  --swc-action-button-content-color-down: var(--swc-gray-25);
37899
37952
  --swc-action-button-content-color-focus: var(--swc-gray-25);
37900
37953
  }
37901
- @media (pointer: coarse), (hover: none) {
37902
- .hint {
37903
- display: none;
37904
- }
37905
- }
37906
37954
  .popup {
37907
37955
  position: absolute;
37908
37956
  left: 0;
@@ -38037,6 +38085,8 @@ var SliccComposer = class extends ThemedElement {
38037
38085
  popover.triggerElement = field.shadowRoot.querySelector(
38038
38086
  ".swc-PromptField-upload"
38039
38087
  );
38088
+ const area = this.#textarea;
38089
+ area.ariaDescribedByElements = [this.renderRoot.querySelector("#keys")];
38040
38090
  });
38041
38091
  }
38042
38092
  subscribe(model) {
@@ -38361,6 +38411,7 @@ var SliccComposer = class extends ThemedElement {
38361
38411
  #keydown(event2) {
38362
38412
  const area = this.#textarea;
38363
38413
  if (event2.isComposing || !area || event2.composedPath()[0] !== area) return;
38414
+ if (event2.key === "Backspace" || event2.key === "Delete") this.#flash();
38364
38415
  const sendOnEnter = this.model?.settings.get().sendOnEnter ?? true;
38365
38416
  let handled = this.#popupKey(event2) || this.#historyKey(event2, area);
38366
38417
  if (!handled && event2.key === "Tab" && !event2.shiftKey && !this.value) {
@@ -38381,6 +38432,29 @@ var SliccComposer = class extends ThemedElement {
38381
38432
  if (handled) event2.preventDefault();
38382
38433
  if (handled || event2.key === "Enter") event2.stopPropagation();
38383
38434
  }
38435
+ #flash() {
38436
+ if (!this.value) return;
38437
+ this.erasing = true;
38438
+ clearTimeout(this.#erase);
38439
+ this.#erase = setTimeout(() => this.erasing = false, 700);
38440
+ }
38441
+ #loader(busy) {
38442
+ if (busy) return "aiLogo";
38443
+ if (this.dictating) return "microphone";
38444
+ if (this.erasing) return "brush";
38445
+ return this.value ? "pencil" : "aiLogo";
38446
+ }
38447
+ #instructions(busy) {
38448
+ const enter = this.model?.settings.get().sendOnEnter ?? true;
38449
+ const keys = enter ? [`Enter ${busy ? "steers" : "sends"}`, ...busy ? ["Ctrl+Enter queues"] : []] : [`Ctrl+Enter ${busy ? "queues" : "sends"}`];
38450
+ if (busy) keys.push("Escape stops");
38451
+ keys.push(
38452
+ `${enter ? "Shift+Enter" : "Enter"} adds a new line`,
38453
+ "/ lists commands",
38454
+ "@ mentions"
38455
+ );
38456
+ return `${keys.join(", ")}.`;
38457
+ }
38384
38458
  #input(event2) {
38385
38459
  this.value = event2.detail.value;
38386
38460
  this.#history = -1;
@@ -38570,16 +38644,17 @@ var SliccComposer = class extends ThemedElement {
38570
38644
  const speech = "SpeechRecognition" in globalThis || "webkitSpeechRecognition" in globalThis;
38571
38645
  const held = this.#held();
38572
38646
  return b`<div class="column">
38647
+ <span id="keys" class="sr" aria-hidden="true">${this.#instructions(busy)}</span>
38573
38648
  ${this.#hold()}
38574
38649
  ${this.#queue()}
38575
38650
  ${this.#popup()}
38576
38651
  <swc-prompt-field
38577
38652
  label="Message"
38653
+ loader=${this.#loader(busy)}
38578
38654
  upload-label="Add"
38579
38655
  stop-label="Stop"
38580
38656
  send-label=${busy ? "Steer" : "Send"}
38581
38657
  max-rows="10"
38582
- animate-loader
38583
38658
  ?generating=${busy && !canSend}
38584
38659
  ?disabled=${!!held}
38585
38660
  placeholder=${held ? `Reconnecting to ${held}\u2026` : suggestion ? `${suggestion} (Tab)` : `Message ${agent?.name ?? ""}`}
@@ -38612,24 +38687,16 @@ var SliccComposer = class extends ThemedElement {
38612
38687
  input.value = "";
38613
38688
  }} />
38614
38689
  </div>
38615
- <div class="below">
38616
- <div class="hint">
38617
- <span><kbd>Enter</kbd> ${busy ? "steer" : "send"}</span>
38618
- ${busy ? b`<span><kbd>Ctrl+Enter</kbd> queue</span><span><kbd>Esc</kbd> stop</span>` : A}
38619
- <span><kbd>/</kbd> commands</span>
38620
- <span><kbd>@</kbd> mention</span>
38621
- <span><kbd>Shift+Enter</kbd> new line</span>
38622
- <span><kbd>↑</kbd> history</span>
38623
- </div>
38624
- ${speech ? b`<swc-action-button
38690
+ ${speech ? b`<div class="below">
38691
+ <swc-action-button
38625
38692
  size="s"
38626
38693
  quiet
38627
38694
  class=${this.dictating ? "selected" : ""}
38628
38695
  accessible-label=${this.dictating ? "Stop dictation" : "Dictate"}
38629
38696
  data-action="dictate"
38630
38697
  @click=${() => this.dictate()}
38631
- ><swc-icon-microphone slot="icon"></swc-icon-microphone></swc-action-button>` : A}
38632
- </div>`;
38698
+ ><swc-icon-microphone slot="icon"></swc-icon-microphone></swc-action-button>
38699
+ </div>` : A}`;
38633
38700
  }
38634
38701
  };
38635
38702