@ai-ecoverse/slicc-spectrum 1.7.0 → 1.8.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.
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  DummySettings,
6
6
  clock
7
- } from "./chunk-YWO2TNED.js";
7
+ } from "./chunk-43NIJXWH.js";
8
8
  import {
9
9
  Emitter
10
10
  } from "./chunk-T5NHW4KC.js";
package/dist/slicc-ui.js CHANGED
@@ -6976,13 +6976,13 @@ var SliccApp = class extends ThemedElement {
6976
6976
  const width = this.getBoundingClientRect().width;
6977
6977
  if (width > 0) this.screen = screenClass(width);
6978
6978
  }
6979
- updated() {
6980
- if (this.model && this.#started !== this.screen) this.#start(this.model);
6979
+ updated(changed) {
6980
+ if (!this.model) return;
6981
+ if (this.#started !== this.screen) this.#start(this.model);
6982
+ else if (changed.has("model")) this.#rebind(this.model);
6981
6983
  }
6982
- #start(model) {
6983
- const dock = this.dock;
6984
- this.#saving = false;
6985
- dock.factories = {
6984
+ #factories(model) {
6985
+ return {
6986
6986
  ...Object.fromEntries(this.surfaces.map((item2) => [item2.id, () => create(item2.tag, model)])),
6987
6987
  ...Object.fromEntries(
6988
6988
  Object.entries(documents).map(([kind, document2]) => [
@@ -6993,6 +6993,22 @@ var SliccApp = class extends ThemedElement {
6993
6993
  ...this.#offers("chat") ? { chat: (params) => create("slicc-chat", model, params) } : {},
6994
6994
  sprinkle: (params) => create("slicc-sprinkle", model, params)
6995
6995
  };
6996
+ }
6997
+ #rebind(model) {
6998
+ const dock = this.dock;
6999
+ dock.factories = this.#factories(model);
7000
+ for (const panel of dock.api.panels) {
7001
+ const element2 = dock.content(panel.id);
7002
+ if (element2 && "model" in element2) element2.model = model;
7003
+ }
7004
+ this.#prune();
7005
+ const agent = this.#active();
7006
+ if (agent && this.#offers("chat")) openChat(dock, agent, this.screen, false);
7007
+ }
7008
+ #start(model) {
7009
+ const dock = this.dock;
7010
+ this.#saving = false;
7011
+ dock.factories = this.#factories(model);
6996
7012
  dock.accepts = [dipType];
6997
7013
  this.dips.load(this.storage);
6998
7014
  const saved = this.#saved();
@@ -10104,10 +10120,17 @@ var accountStatus = {
10104
10120
  disconnected: ["neutral", "Not connected"]
10105
10121
  };
10106
10122
  var SliccSettings = class extends ModelElement {
10107
- static properties = { ...ModelElement.properties, pending: { state: true } };
10123
+ static properties = {
10124
+ ...ModelElement.properties,
10125
+ pending: { state: true },
10126
+ entering: { state: true },
10127
+ failure: { state: true }
10128
+ };
10108
10129
  constructor() {
10109
10130
  super();
10110
10131
  this.pending = /* @__PURE__ */ new Set();
10132
+ this.entering = null;
10133
+ this.failure = null;
10111
10134
  }
10112
10135
  static styles = [
10113
10136
  shared,
@@ -10171,6 +10194,21 @@ var SliccSettings = class extends ModelElement {
10171
10194
  .state .dot[data-variant='positive'] {
10172
10195
  background: var(--spectrum-positive-visual-color);
10173
10196
  }
10197
+ .key {
10198
+ display: flex;
10199
+ align-items: center;
10200
+ gap: 8px;
10201
+ padding: 8px 0 12px;
10202
+ border-bottom: 1px solid var(--spectrum-gray-200);
10203
+ }
10204
+ .key sp-textfield {
10205
+ flex: 1;
10206
+ }
10207
+ .failure {
10208
+ color: var(--spectrum-negative-content-color-default);
10209
+ font-size: var(--spectrum-font-size-75);
10210
+ padding: 4px 0;
10211
+ }
10174
10212
  `
10175
10213
  ];
10176
10214
  subscribe(model) {
@@ -10189,20 +10227,61 @@ var SliccSettings = class extends ModelElement {
10189
10227
  #checked(event) {
10190
10228
  return event.target.checked;
10191
10229
  }
10192
- async connect(id) {
10230
+ async connect(id, secret) {
10193
10231
  this.pending = /* @__PURE__ */ new Set([...this.pending, id]);
10232
+ this.failure = null;
10194
10233
  try {
10195
- await this.model?.settings.connect(id);
10234
+ await this.model?.settings.connect(id, secret);
10235
+ if (this.entering === id) this.entering = null;
10236
+ } catch (error) {
10237
+ this.failure = { id, message: error.message };
10196
10238
  } finally {
10197
10239
  this.pending = new Set([...this.pending].filter((candidate) => candidate !== id));
10198
10240
  }
10199
10241
  }
10242
+ #start(account) {
10243
+ if (account.auth !== "api-key") {
10244
+ void this.connect(account.id);
10245
+ return;
10246
+ }
10247
+ this.failure = null;
10248
+ this.entering = account.id;
10249
+ void this.updateComplete.then(() => this.focusOn(".key sp-textfield"));
10250
+ }
10251
+ #submit(event, id) {
10252
+ event.preventDefault();
10253
+ const field = event.currentTarget.querySelector(
10254
+ "sp-textfield"
10255
+ );
10256
+ const secret = field.value.trim();
10257
+ field.value = "";
10258
+ if (secret) void this.connect(id, secret);
10259
+ }
10260
+ #send(event) {
10261
+ event.currentTarget.closest("form")?.requestSubmit();
10262
+ }
10263
+ #enter(event) {
10264
+ if (event.key === "Enter") this.#send(event);
10265
+ }
10266
+ #cancel() {
10267
+ this.entering = null;
10268
+ this.failure = null;
10269
+ }
10270
+ #key(account) {
10271
+ if (this.entering !== account.id) return A;
10272
+ const busy = this.pending.has(account.id);
10273
+ return b`<form class="key" data-id=${account.id} @submit=${(event) => this.#submit(event, account.id)}>
10274
+ <sp-textfield size="m" type="password" autocomplete="off" label=${`${account.provider} API key`} placeholder="Paste the API key" @keydown=${(event) => this.#enter(event)}></sp-textfield>
10275
+ <sp-button size="s" variant="accent" ?pending=${busy} @click=${(event) => this.#send(event)}>Save</sp-button>
10276
+ <sp-button size="s" variant="secondary" treatment="outline" @click=${() => this.#cancel()}>Cancel</sp-button>
10277
+ </form>`;
10278
+ }
10200
10279
  #account(account) {
10201
10280
  const [variant, label] = accountStatus[account.status];
10202
10281
  const busy = this.pending.has(account.id);
10203
10282
  const action = account.status === "connected" ? b`<sp-button size="s" variant="secondary" treatment="outline" @click=${() => this.model?.settings.disconnect(account.id)}
10204
10283
  >Disconnect</sp-button
10205
- >` : b`<sp-button size="s" variant="secondary" ?pending=${busy} @click=${() => this.connect(account.id)}
10284
+ >` : b`<sp-button size="s" variant="secondary" ?pending=${busy} ?disabled=${this.entering === account.id} @click=${() => this.#start(account)}
10206
10285
  >${account.status === "expired" ? "Reconnect" : "Connect"}</sp-button
10207
10286
  >`;
10208
10287
  return b`<div class="account" data-id=${account.id}>
@@ -10210,7 +10289,9 @@ var SliccSettings = class extends ModelElement {
10210
10289
  <span class="identity">${account.identity || "\u2014"}</span>
10211
10290
  <span class="state"><span class="dot" data-variant=${variant}></span>${label}</span>
10212
10291
  ${action}
10213
- </div>`;
10292
+ </div>
10293
+ ${this.#key(account)}
10294
+ ${this.failure?.id === account.id ? b`<div class="failure" role="alert">${this.failure.message}</div>` : A}`;
10214
10295
  }
10215
10296
  render() {
10216
10297
  const settings = this.model?.settings;