@ai-ecoverse/slicc-spectrum 1.69.0 → 1.69.1

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.
@@ -6,7 +6,7 @@ import {
6
6
  DummySettings,
7
7
  clock,
8
8
  dummySettingsKey
9
- } from "./chunk-2PKRU2CL.js";
9
+ } from "./chunk-X4C3AZJT.js";
10
10
  import {
11
11
  Emitter
12
12
  } from "./chunk-T5NHW4KC.js";
package/dist/slicc-ui.js CHANGED
@@ -11447,8 +11447,8 @@ var SliccAgents = class extends ModelElement {
11447
11447
  return;
11448
11448
  }
11449
11449
  const current = port.active();
11450
- const stale = current === agent.id || !port.list().some((candidate) => candidate.id === current);
11451
- if (stale && agent.parentId) port.select(agent.parentId);
11450
+ const stale2 = current === agent.id || !port.list().some((candidate) => candidate.id === current);
11451
+ if (stale2 && agent.parentId) port.select(agent.parentId);
11452
11452
  await this.updateComplete;
11453
11453
  this.focus();
11454
11454
  }
@@ -11701,6 +11701,62 @@ async function grammar(kind, name, version2, remote = grammarCdn, importer = (ur
11701
11701
  throw failure2;
11702
11702
  }
11703
11703
 
11704
+ // src/app/models.ts
11705
+ var asked = /* @__PURE__ */ new WeakMap();
11706
+ var switched = /* @__PURE__ */ new WeakMap();
11707
+ var settling = /* @__PURE__ */ new WeakSet();
11708
+ function stale(model, id, offered) {
11709
+ if (offered.some((option2) => option2.id === id)) return false;
11710
+ const provider = id.split("/")[0];
11711
+ return !model.settings.accounts().some((account) => account.id === provider && account.status === "connected");
11712
+ }
11713
+ function fallbackModel(options) {
11714
+ const offered = chatModels(options);
11715
+ return offered.find((option2) => option2.default) ?? offered[0];
11716
+ }
11717
+ function controls(model) {
11718
+ const state3 = model.follow?.state();
11719
+ return !state3 || !!state3.access.control && state3.link === "connected";
11720
+ }
11721
+ function settleModels(model) {
11722
+ if (settling.has(model) || !controls(model)) return;
11723
+ settling.add(model);
11724
+ try {
11725
+ settle(model);
11726
+ } finally {
11727
+ settling.delete(model);
11728
+ }
11729
+ }
11730
+ function settle(model) {
11731
+ const offered = chatModels(model.settings.models());
11732
+ const pick = fallbackModel(offered);
11733
+ if (!pick) return;
11734
+ const requests = asked.get(model) ?? /* @__PURE__ */ new Map();
11735
+ asked.set(model, requests);
11736
+ const ask = (key2, from, apply2) => {
11737
+ if (!stale(model, from, offered)) {
11738
+ requests.delete(key2);
11739
+ return;
11740
+ }
11741
+ if (requests.get(key2) === pick.id) return;
11742
+ requests.set(key2, pick.id);
11743
+ apply2();
11744
+ };
11745
+ for (const agent of model.agent.list())
11746
+ if (!agent.frozen)
11747
+ ask(`agent:${agent.id}`, agent.model, () => model.agent.setModel(agent.id, pick.id));
11748
+ ask("settings", model.settings.get().model, () => {
11749
+ switched.set(model, { to: pick });
11750
+ model.settings.update({ model: pick.id });
11751
+ });
11752
+ }
11753
+ function modelSwitch(model) {
11754
+ return switched.get(model);
11755
+ }
11756
+ function forgetSwitch(model) {
11757
+ switched.delete(model);
11758
+ }
11759
+
11704
11760
  // node_modules/@adobe/spectrum-wc-icons/dist/Cloud.js
11705
11761
  function e82() {
11706
11762
  return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="var(--swc-icon-color, currentColor)" d="M15.407 17H3.717a3.456 3.456 0 0 1-3.45-3.452 3.45 3.45 0 0 1 2.323-3.25 4 4 0 0 1-.065-.702c0-2.18 1.81-3.953 4.034-3.953q.42 0 .831.087c.637-1.958 2.476-3.346 4.589-3.346a4.85 4.85 0 0 1 4.844 4.844q0 .659-.187 1.298a4.32 4.32 0 0 1 3.103 4.142A4.337 4.337 0 0 1 15.407 17M6.559 7.143c-1.397 0-2.534 1.1-2.534 2.453q.001.5.206.965a.75.75 0 0 1-.637 1.051 1.95 1.95 0 0 0-1.828 1.936c0 1.076.876 1.952 1.952 1.952h11.689a2.835 2.835 0 0 0 2.832-2.832 2.826 2.826 0 0 0-2.682-2.814.75.75 0 0 1-.625-1.095c.26-.5.39-1.015.39-1.531 0-1.844-1.5-3.344-3.344-3.344-1.662 0-3.08 1.252-3.297 2.912a.75.75 0 0 1-1.054.585 2.6 2.6 0 0 0-1.068-.238"/></svg>';
@@ -14932,11 +14988,11 @@ var TerminalPanels = class {
14932
14988
  }
14933
14989
  #ask(info, trigger2) {
14934
14990
  const body4 = "The shell and anything running in it stop. You can\u2019t undo this.";
14935
- const asked = this.#asking.then(
14991
+ const asked2 = this.#asking.then(
14936
14992
  () => confirm({ title: `Close ${info.title}?`, body: body4, action: "Close", trigger: trigger2 })
14937
14993
  );
14938
- this.#asking = asked;
14939
- return asked;
14994
+ this.#asking = asked2;
14995
+ return asked2;
14940
14996
  }
14941
14997
  activated(id) {
14942
14998
  if (terminalOf(id) !== null) this.#recent = id;
@@ -22976,9 +23032,14 @@ var SliccApp = class extends ThemedElement {
22976
23032
  }
22977
23033
  subscribe(model) {
22978
23034
  const update = () => this.requestUpdate();
23035
+ const settle2 = () => settleModels(model);
23036
+ queueMicrotask(settle2);
22979
23037
  return [
22980
23038
  ...super.subscribe(model),
23039
+ model.settings.on("settings", settle2),
23040
+ model.settings.on("accounts", settle2),
22981
23041
  model.agent.on("agents", () => {
23042
+ settle2();
22982
23043
  this.#prune();
22983
23044
  update();
22984
23045
  }),
@@ -23003,6 +23064,7 @@ var SliccApp = class extends ThemedElement {
23003
23064
  ...model.tabs ? [model.tabs.on("tabs", update)] : [],
23004
23065
  ...model.follow ? [
23005
23066
  model.follow.on("follow", () => {
23067
+ settle2();
23006
23068
  this.#followed(model);
23007
23069
  update();
23008
23070
  })
@@ -26142,6 +26204,7 @@ var navigation = /* @__PURE__ */ new Set([
26142
26204
  "PageUp",
26143
26205
  "PageDown"
26144
26206
  ]);
26207
+ var compactWidth = 560;
26145
26208
  var failed = (message) => message.role === "assistant" ? message.status === "error" : message.role === "system" && message.kind === "error";
26146
26209
  function carriesFiles(event2) {
26147
26210
  const types = [...event2.dataTransfer?.types ?? []];
@@ -26176,11 +26239,17 @@ document.addEventListener(
26176
26239
  true
26177
26240
  );
26178
26241
  var SliccChat = class extends ThemedElement {
26179
- static properties = { ...ThemedElement.properties, agent: {}, dropping: { state: true } };
26242
+ static properties = {
26243
+ ...ThemedElement.properties,
26244
+ agent: {},
26245
+ dropping: { state: true },
26246
+ compact: { state: true }
26247
+ };
26180
26248
  constructor() {
26181
26249
  super();
26182
26250
  this.agent = "";
26183
26251
  this.dropping = false;
26252
+ this.compact = false;
26184
26253
  this.addEventListener("dragenter", this.#over);
26185
26254
  this.addEventListener("dragover", this.#over);
26186
26255
  this.addEventListener("dragleave", this.#leave);
@@ -26234,7 +26303,7 @@ var SliccChat = class extends ThemedElement {
26234
26303
  }
26235
26304
  header {
26236
26305
  display: flex;
26237
- flex-wrap: wrap;
26306
+ flex-wrap: nowrap;
26238
26307
  align-items: center;
26239
26308
  gap: var(--swc-spacing-50) var(--swc-spacing-100);
26240
26309
  padding: var(--swc-spacing-75) var(--swc-spacing-200);
@@ -26246,15 +26315,23 @@ var SliccChat = class extends ThemedElement {
26246
26315
  }
26247
26316
  header sp-picker {
26248
26317
  --mod-picker-spacing-label-to-picker-quiet: calc(-1 * var(--swc-border-width-100));
26318
+ flex: none;
26249
26319
  min-width: 0;
26250
26320
  width: auto;
26251
26321
  }
26322
+ header sp-picker[label='Model'] {
26323
+ flex: 0 1 auto;
26324
+ }
26325
+ header swc-status-light,
26326
+ header swc-action-button {
26327
+ flex: none;
26328
+ }
26252
26329
  header swc-status-light {
26253
26330
  align-self: center;
26254
26331
  }
26255
26332
  header swc-meter {
26256
26333
  flex: 0 1 calc(var(--swc-spacing-400) * 6);
26257
- min-width: calc(var(--swc-spacing-400) * 4);
26334
+ min-width: calc(var(--swc-spacing-400) * 4.5);
26258
26335
  margin-inline-start: auto;
26259
26336
  }
26260
26337
  header .frozen,
@@ -26343,14 +26420,27 @@ var SliccChat = class extends ThemedElement {
26343
26420
  }
26344
26421
  };
26345
26422
  subscribe(model) {
26423
+ const settle2 = () => {
26424
+ settleModels(model);
26425
+ this.requestUpdate();
26426
+ };
26427
+ queueMicrotask(() => settleModels(model));
26428
+ const width = new ResizeObserver(([entry]) => {
26429
+ const size4 = entry.contentRect.width;
26430
+ this.compact = size4 > 0 && size4 < compactWidth;
26431
+ });
26432
+ width.observe(this);
26346
26433
  return [
26347
26434
  ...super.subscribe(model),
26435
+ () => width.disconnect(),
26436
+ model.settings.on("settings", settle2),
26437
+ model.settings.on("accounts", settle2),
26348
26438
  model.agent.on("active", () => {
26349
26439
  if (!this.agent) this.#refresh(true);
26350
26440
  }),
26351
- model.agent.on("agents", () => this.requestUpdate()),
26441
+ model.agent.on("agents", settle2),
26352
26442
  ...model.tabs ? [model.tabs.on("tabs", () => this.requestUpdate())] : [],
26353
- ...model.follow ? [model.follow.on("follow", () => this.requestUpdate())] : [],
26443
+ ...model.follow ? [model.follow.on("follow", settle2)] : [],
26354
26444
  model.agent.on("messages", (agentId) => {
26355
26445
  if (agentId === this.#id()) this.#refresh(this.#sent(agentId));
26356
26446
  }),
@@ -26524,10 +26614,11 @@ var SliccChat = class extends ThemedElement {
26524
26614
  <span class="model" data-model>${label ?? agent.model}</span>
26525
26615
  ${meter}`;
26526
26616
  }
26617
+ const offered = chatModels(model.settings.models());
26527
26618
  return b`${statusLight(agent.status)}
26528
- <sp-picker size="s" quiet label="Model" value=${agent.model} @change=${(event2) => model.agent.setModel(agent.id, event2.target.value)}>
26529
- ${chatModels(model.settings.models()).map((option2) => b`<sp-menu-item value=${option2.id}>${option2.label}<span slot="description">${option2.provider}</span></sp-menu-item>`)}
26530
- </sp-picker>
26619
+ ${offered.length ? b`<sp-picker size="s" quiet label="Model" value=${agent.model} @change=${(event2) => model.agent.setModel(agent.id, event2.target.value)}>
26620
+ ${offered.map((option2) => b`<sp-menu-item value=${option2.id}>${option2.label}<span slot="description">${option2.provider}</span></sp-menu-item>`)}
26621
+ </sp-picker>` : b`<swc-action-button size="s" quiet data-action="set-up-model" @click=${() => this.#action("settings")}>Set up a model</swc-action-button>`}
26531
26622
  <sp-picker size="s" quiet label="Thinking" value=${model.settings.get().thinking} @change=${(event2) => model.settings.update({ thinking: event2.target.value })}>
26532
26623
  <sp-menu-item value="off">No thinking</sp-menu-item>
26533
26624
  <sp-menu-item value="low">Think a little</sp-menu-item>
@@ -26535,7 +26626,7 @@ var SliccChat = class extends ThemedElement {
26535
26626
  <sp-menu-item value="high">Think hard</sp-menu-item>
26536
26627
  </sp-picker>
26537
26628
  ${meter}
26538
- <swc-action-button id="new-chat" size="s" quiet data-action="new-chat" ?disabled=${empty2} @click=${() => this.#newChat(agent)}><swc-icon-new slot="icon"></swc-icon-new>New conversation</swc-action-button>
26629
+ <swc-action-button id="new-chat" size="s" quiet data-action="new-chat" accessible-label=${this.compact ? "New conversation" : A} ?disabled=${empty2} @click=${() => this.#newChat(agent)}><swc-icon-new slot="icon"></swc-icon-new>${this.compact ? A : "New conversation"}</swc-action-button>
26539
26630
  <swc-tooltip for="new-chat" placement="bottom">${agent.kind === "cone" && model.agent.freeze ? "Start a new conversation. This one stays in the Freezer." : "Start a new conversation"}</swc-tooltip>`;
26540
26631
  }
26541
26632
  render() {
@@ -26547,7 +26638,7 @@ var SliccChat = class extends ThemedElement {
26547
26638
  const messages = agent ? this.model?.agent.messages(agent.id) ?? [] : [];
26548
26639
  this.#tail = messages.at(-1)?.id ?? "";
26549
26640
  return b`
26550
- <header>
26641
+ <header ?data-compact=${this.compact}>
26551
26642
  ${agent ? this.#meta(agent, !messages.length) : b`<span>No agent</span>`}
26552
26643
  </header>
26553
26644
  <slicc-notices .model=${this.model}></slicc-notices>
@@ -30492,6 +30583,9 @@ var SliccSettings = class extends ThemedElement {
30492
30583
  color: var(--swc-neutral-subdued-content-color-default);
30493
30584
  font-size: var(--swc-font-size-75);
30494
30585
  }
30586
+ .switched {
30587
+ grid-column: 2;
30588
+ }
30495
30589
  .failure,
30496
30590
  .problem {
30497
30591
  display: flex;
@@ -30510,6 +30604,9 @@ var SliccSettings = class extends ThemedElement {
30510
30604
  grid-template-columns: minmax(0, 1fr);
30511
30605
  gap: var(--swc-spacing-75);
30512
30606
  }
30607
+ .switched {
30608
+ grid-column: 1;
30609
+ }
30513
30610
  .accounts {
30514
30611
  grid-template-columns: minmax(0, 1fr) max-content;
30515
30612
  row-gap: var(--swc-spacing-400);
@@ -30540,10 +30637,15 @@ var SliccSettings = class extends ThemedElement {
30540
30637
  ];
30541
30638
  subscribe(model) {
30542
30639
  const update = () => this.requestUpdate();
30640
+ const settle2 = () => {
30641
+ settleModels(model);
30642
+ update();
30643
+ };
30644
+ queueMicrotask(() => settleModels(model));
30543
30645
  return [
30544
30646
  ...super.subscribe(model),
30545
- model.settings.on("settings", update),
30546
- model.settings.on("accounts", update),
30647
+ model.settings.on("settings", settle2),
30648
+ model.settings.on("accounts", settle2),
30547
30649
  ...model.vault ? [model.vault.on("status", update)] : []
30548
30650
  ];
30549
30651
  }
@@ -30553,6 +30655,15 @@ var SliccSettings = class extends ThemedElement {
30553
30655
  #update(patch) {
30554
30656
  this.model?.settings.update(patch);
30555
30657
  }
30658
+ #pickModel(event2) {
30659
+ forgetSwitch(this.model);
30660
+ this.#update({ model: this.#value(event2) });
30661
+ }
30662
+ #switched(current) {
30663
+ const note = modelSwitch(this.model);
30664
+ if (note?.to.id !== current) return A;
30665
+ return b`<p class="hint switched" role="status" data-switched>Switched to ${note.to.label} because the previous model's provider isn't set up.</p>`;
30666
+ }
30556
30667
  #value(event2) {
30557
30668
  return event2.target.value;
30558
30669
  }
@@ -30900,9 +31011,10 @@ var SliccSettings = class extends ThemedElement {
30900
31011
  <div class="rows">
30901
31012
  <div class="row">
30902
31013
  <span class="label" id="model">Model for new cones</span>
30903
- <sp-picker size="m" label="Model" aria-labelledby="model" value=${value.model} @change=${(e120) => this.#update({ model: this.#value(e120) })}>
31014
+ <sp-picker size="m" label="Model" aria-labelledby="model" value=${value.model} @change=${(e120) => this.#pickModel(e120)}>
30904
31015
  ${chatModels(settings.models()).map((option2) => b`<sp-menu-item value=${option2.id}>${option2.label}<span slot="description">${option2.provider}</span></sp-menu-item>`)}
30905
31016
  </sp-picker>
31017
+ ${this.#switched(value.model)}
30906
31018
  </div>
30907
31019
  <div class="row">
30908
31020
  <span class="label" id="thinking">Thinking</span>
@@ -31319,12 +31431,12 @@ var SliccSprinkle = class extends ThemedElement {
31319
31431
  const held = { port, id, ready: false, value: null };
31320
31432
  this.#held = held;
31321
31433
  this.#frame = { key: "", doc: "" };
31322
- const settle = (value) => {
31434
+ const settle2 = (value) => {
31323
31435
  held.value = value ?? null;
31324
31436
  held.ready = true;
31325
31437
  if (this.#held === held) this.requestUpdate();
31326
31438
  };
31327
- ask.call(port, id, "getState", []).then(settle, () => settle(null));
31439
+ ask.call(port, id, "getState", []).then(settle2, () => settle2(null));
31328
31440
  }
31329
31441
  willUpdate(changed) {
31330
31442
  super.willUpdate(changed);