@ai-ecoverse/slicc-spectrum 1.73.0 → 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
  }
@@ -30918,17 +30932,24 @@ function toolMessage(message, context = { color: "light", model: null }, extra =
30918
30932
  ${suggestion && context.suggest ? b`<swc-system-message>${shown4}${suggestions(suggestion, context)}</swc-system-message>` : shown4}
30919
30933
  </swc-conversation-turn>`;
30920
30934
  }
30935
+ var compactionTitles = {
30936
+ summarizing: "Context compacted",
30937
+ summarized: "Context compacted",
30938
+ fallback: "Compaction failed, transcript truncated",
30939
+ discarded: "Context discarded"
30940
+ };
30921
30941
  function event(label, content) {
30922
30942
  return b`<swc-conversation-turn type="system" class="event" accessible-label=${label}>${content}</swc-conversation-turn>`;
30923
30943
  }
30924
30944
  function system(message, handlers) {
30925
30945
  if (message.kind === "compaction") {
30926
- const title = message.title ?? "Context compacted";
30946
+ const failed2 = message.state === "fallback" || message.state === "discarded";
30947
+ const title = message.title ?? compactionTitles[message.state ?? "summarized"];
30927
30948
  return event(
30928
30949
  title,
30929
30950
  b`<div class="marker" role="status" data-id=${message.id} data-state=${message.state ?? "summarized"}>
30930
30951
  <span class="line"></span>
30931
- <span class="marker-text">${title} · ${message.state === "summarizing" ? b`<swc-progress-circle size="s" label="Summarizing"></swc-progress-circle>` : message.text}</span>
30952
+ <span class="marker-text">${failed2 ? b`<swc-icon-alert-diamond class="fault" size="xs" aria-hidden="true"></swc-icon-alert-diamond>` : A}${title}${message.state === "summarizing" ? b`<swc-progress-circle size="s" label="Summarizing"></swc-progress-circle>` : A}${message.text ? b`<span class="sr">. ${message.text}</span>` : A}</span>
30932
30953
  <span class="line"></span>
30933
30954
  </div>`
30934
30955
  );
@@ -30936,7 +30957,11 @@ function system(message, handlers) {
30936
30957
  if (message.kind === "notice") {
30937
30958
  return event(
30938
30959
  "Notice",
30939
- b`<div class="notice" role="note" data-id=${message.id}><strong>${message.title}</strong> ${message.text}</div>`
30960
+ b`<div class="marker notice" role="note" data-id=${message.id}>
30961
+ <span class="line"></span>
30962
+ <span class="marker-text"><span>${message.title}</span> ${message.text}</span>
30963
+ <span class="line"></span>
30964
+ </div>`
30940
30965
  );
30941
30966
  }
30942
30967
  return event(
@@ -31725,10 +31750,17 @@ var messageCss = i`
31725
31750
  margin-block-start: 0;
31726
31751
  }
31727
31752
  .marker-text {
31753
+ text-align: center;
31728
31754
  display: inline-flex;
31729
31755
  align-items: center;
31730
31756
  gap: var(--swc-spacing-75);
31731
31757
  }
31758
+ .marker-text .fault {
31759
+ color: var(--swc-negative-visual-color);
31760
+ }
31761
+ .marker .line {
31762
+ min-inline-size: var(--swc-spacing-300);
31763
+ }
31732
31764
  .marker .line,
31733
31765
  .day .line {
31734
31766
  flex: 1;
@@ -36069,7 +36101,8 @@ var SliccChat = class extends ThemedElement {
36069
36101
  min-height: 0;
36070
36102
  overflow-y: auto;
36071
36103
  container-type: inline-size;
36072
- 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));
36073
36106
  font-size: var(--swc-font-size-200);
36074
36107
  }
36075
36108
  @container (min-width: 600px) {
@@ -36182,6 +36215,11 @@ var SliccChat = class extends ThemedElement {
36182
36215
  return last?.role === "user" && last.id !== this.#tail && (last.origin ?? "user") === "user";
36183
36216
  }
36184
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
+ });
36185
36223
  #log() {
36186
36224
  return this.renderRoot.querySelector(".log");
36187
36225
  }
@@ -36236,8 +36274,20 @@ var SliccChat = class extends ThemedElement {
36236
36274
  const log = this.#log();
36237
36275
  this.#resize.observe(log);
36238
36276
  this.#resize.observe(log.firstElementChild);
36277
+ this.#attach();
36239
36278
  this.#refresh(true);
36240
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
+ }
36241
36291
  connectedCallback() {
36242
36292
  super.connectedCallback();
36243
36293
  globalThis.addEventListener("pointerup", this.#release, true);
@@ -36249,6 +36299,8 @@ var SliccChat = class extends ThemedElement {
36249
36299
  globalThis.removeEventListener("pointerup", this.#release, true);
36250
36300
  globalThis.removeEventListener("pointercancel", this.#release, true);
36251
36301
  this.#resize.disconnect();
36302
+ this.#fit.disconnect();
36303
+ this.#fitted = null;
36252
36304
  clearTimeout(this.#settle);
36253
36305
  }
36254
36306
  firstUpdated() {
@@ -37702,6 +37754,7 @@ var SliccComposer = class extends ThemedElement {
37702
37754
  attachments: { state: true },
37703
37755
  popup: { state: true },
37704
37756
  dictating: { state: true },
37757
+ erasing: { state: true },
37705
37758
  blocked: { state: true },
37706
37759
  sharing: { state: true },
37707
37760
  secretError: { state: true },
@@ -37715,6 +37768,7 @@ var SliccComposer = class extends ThemedElement {
37715
37768
  #next = 1;
37716
37769
  #abandon;
37717
37770
  #recognition = null;
37771
+ #erase;
37718
37772
  #keys = { capture: true, handleEvent: (event2) => this.#keydown(event2) };
37719
37773
  constructor() {
37720
37774
  super();
@@ -37722,6 +37776,7 @@ var SliccComposer = class extends ThemedElement {
37722
37776
  this.attachments = [];
37723
37777
  this.popup = null;
37724
37778
  this.dictating = false;
37779
+ this.erasing = false;
37725
37780
  this.blocked = false;
37726
37781
  this.sharing = false;
37727
37782
  this.secretError = null;
@@ -37733,11 +37788,49 @@ var SliccComposer = class extends ThemedElement {
37733
37788
  i`
37734
37789
  :host {
37735
37790
  display: block;
37736
- flex: none;
37791
+ position: absolute;
37792
+ left: 0;
37793
+ right: 0;
37794
+ bottom: 0;
37795
+ z-index: 2;
37737
37796
  padding: var(--swc-spacing-100) var(--swc-spacing-200) var(--swc-spacing-200);
37738
- background: var(--swc-background-layer-1-color);
37739
37797
  font-size: var(--swc-font-size-100);
37740
- 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
+ }
37741
37834
  }
37742
37835
  .column {
37743
37836
  max-width: 860px;
@@ -37845,28 +37938,6 @@ var SliccComposer = class extends ThemedElement {
37845
37938
  margin: var(--swc-spacing-75) auto 0;
37846
37939
  min-height: var(--swc-component-height-75);
37847
37940
  }
37848
- .hint {
37849
- display: flex;
37850
- flex: 1;
37851
- flex-wrap: wrap;
37852
- align-items: center;
37853
- min-width: 0;
37854
- max-block-size: var(--swc-component-height-75);
37855
- overflow: hidden;
37856
- font-size: var(--swc-font-size-75);
37857
- color: var(--swc-neutral-subdued-content-color-default);
37858
- }
37859
- .hint > span {
37860
- display: flex;
37861
- align-items: center;
37862
- block-size: var(--swc-component-height-75);
37863
- gap: var(--swc-spacing-50);
37864
- white-space: nowrap;
37865
- }
37866
- .hint > span + span::before {
37867
- content: '·';
37868
- padding-inline-start: var(--swc-spacing-75);
37869
- }
37870
37941
  .below swc-action-button {
37871
37942
  margin-inline-start: auto;
37872
37943
  }
@@ -37880,11 +37951,6 @@ var SliccComposer = class extends ThemedElement {
37880
37951
  --swc-action-button-content-color-down: var(--swc-gray-25);
37881
37952
  --swc-action-button-content-color-focus: var(--swc-gray-25);
37882
37953
  }
37883
- @media (pointer: coarse), (hover: none) {
37884
- .hint {
37885
- display: none;
37886
- }
37887
- }
37888
37954
  .popup {
37889
37955
  position: absolute;
37890
37956
  left: 0;
@@ -38019,6 +38085,8 @@ var SliccComposer = class extends ThemedElement {
38019
38085
  popover.triggerElement = field.shadowRoot.querySelector(
38020
38086
  ".swc-PromptField-upload"
38021
38087
  );
38088
+ const area = this.#textarea;
38089
+ area.ariaDescribedByElements = [this.renderRoot.querySelector("#keys")];
38022
38090
  });
38023
38091
  }
38024
38092
  subscribe(model) {
@@ -38343,6 +38411,7 @@ var SliccComposer = class extends ThemedElement {
38343
38411
  #keydown(event2) {
38344
38412
  const area = this.#textarea;
38345
38413
  if (event2.isComposing || !area || event2.composedPath()[0] !== area) return;
38414
+ if (event2.key === "Backspace" || event2.key === "Delete") this.#flash();
38346
38415
  const sendOnEnter = this.model?.settings.get().sendOnEnter ?? true;
38347
38416
  let handled = this.#popupKey(event2) || this.#historyKey(event2, area);
38348
38417
  if (!handled && event2.key === "Tab" && !event2.shiftKey && !this.value) {
@@ -38363,6 +38432,29 @@ var SliccComposer = class extends ThemedElement {
38363
38432
  if (handled) event2.preventDefault();
38364
38433
  if (handled || event2.key === "Enter") event2.stopPropagation();
38365
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
+ }
38366
38458
  #input(event2) {
38367
38459
  this.value = event2.detail.value;
38368
38460
  this.#history = -1;
@@ -38552,16 +38644,17 @@ var SliccComposer = class extends ThemedElement {
38552
38644
  const speech = "SpeechRecognition" in globalThis || "webkitSpeechRecognition" in globalThis;
38553
38645
  const held = this.#held();
38554
38646
  return b`<div class="column">
38647
+ <span id="keys" class="sr" aria-hidden="true">${this.#instructions(busy)}</span>
38555
38648
  ${this.#hold()}
38556
38649
  ${this.#queue()}
38557
38650
  ${this.#popup()}
38558
38651
  <swc-prompt-field
38559
38652
  label="Message"
38653
+ loader=${this.#loader(busy)}
38560
38654
  upload-label="Add"
38561
38655
  stop-label="Stop"
38562
38656
  send-label=${busy ? "Steer" : "Send"}
38563
38657
  max-rows="10"
38564
- animate-loader
38565
38658
  ?generating=${busy && !canSend}
38566
38659
  ?disabled=${!!held}
38567
38660
  placeholder=${held ? `Reconnecting to ${held}\u2026` : suggestion ? `${suggestion} (Tab)` : `Message ${agent?.name ?? ""}`}
@@ -38594,24 +38687,16 @@ var SliccComposer = class extends ThemedElement {
38594
38687
  input.value = "";
38595
38688
  }} />
38596
38689
  </div>
38597
- <div class="below">
38598
- <div class="hint">
38599
- <span><kbd>Enter</kbd> ${busy ? "steer" : "send"}</span>
38600
- ${busy ? b`<span><kbd>Ctrl+Enter</kbd> queue</span><span><kbd>Esc</kbd> stop</span>` : A}
38601
- <span><kbd>/</kbd> commands</span>
38602
- <span><kbd>@</kbd> mention</span>
38603
- <span><kbd>Shift+Enter</kbd> new line</span>
38604
- <span><kbd>↑</kbd> history</span>
38605
- </div>
38606
- ${speech ? b`<swc-action-button
38690
+ ${speech ? b`<div class="below">
38691
+ <swc-action-button
38607
38692
  size="s"
38608
38693
  quiet
38609
38694
  class=${this.dictating ? "selected" : ""}
38610
38695
  accessible-label=${this.dictating ? "Stop dictation" : "Dictate"}
38611
38696
  data-action="dictate"
38612
38697
  @click=${() => this.dictate()}
38613
- ><swc-icon-microphone slot="icon"></swc-icon-microphone></swc-action-button>` : A}
38614
- </div>`;
38698
+ ><swc-icon-microphone slot="icon"></swc-icon-microphone></swc-action-button>
38699
+ </div>` : A}`;
38615
38700
  }
38616
38701
  };
38617
38702