@ai-ecoverse/slicc-spectrum 1.28.0 → 1.28.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.
package/dist/slicc-ui.js CHANGED
@@ -13953,8 +13953,8 @@ function hint(port) {
13953
13953
  return "Preparing your agent. You can keep working; this panel closes when the agent is ready.";
13954
13954
  }
13955
13955
  function updatesStatus(items) {
13956
- const failed = items.filter((item2) => item2.state === "failed").length;
13957
- if (failed) return `${failed} failed`;
13956
+ const failed2 = items.filter((item2) => item2.state === "failed").length;
13957
+ if (failed2) return `${failed2} failed`;
13958
13958
  const busy = items.filter((item2) => running.has(item2.state)).length;
13959
13959
  if (busy) return `updating ${busy}`;
13960
13960
  if (items.some((item2) => item2.state === "ready" || item2.state === "available")) {
@@ -13970,13 +13970,13 @@ var UpdateVisibility = class {
13970
13970
  this.#boot = !ready;
13971
13971
  }
13972
13972
  change(port, layout = false) {
13973
- const failed = new Set(
13973
+ const failed2 = new Set(
13974
13974
  port.list().filter((item2) => item2.state === "failed").map((item2) => item2.id)
13975
13975
  );
13976
- const open = (this.#initial || layout) && this.#boot || [...failed].some((id) => !this.#failed.has(id));
13976
+ const open = (this.#initial || layout) && this.#boot || [...failed2].some((id) => !this.#failed.has(id));
13977
13977
  this.#initial = false;
13978
- this.#failed = failed;
13979
- if (this.#boot && port.ready() && failed.size === 0) {
13978
+ this.#failed = failed2;
13979
+ if (this.#boot && port.ready() && failed2.size === 0) {
13980
13980
  this.#boot = false;
13981
13981
  return "close";
13982
13982
  }
@@ -18807,6 +18807,10 @@ var actionLabels = {
18807
18807
  login: "Log in",
18808
18808
  "drop-turn": "Drop the last turn"
18809
18809
  };
18810
+ function actionLabel(action, handlers, messageId) {
18811
+ const count = action === "drop-turn" ? handlers.dropping(messageId) : 1;
18812
+ return count > 1 ? `Drop ${count} failed turns` : actionLabels[action];
18813
+ }
18810
18814
  function time(at) {
18811
18815
  return new Date(at).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" });
18812
18816
  }
@@ -18858,14 +18862,14 @@ function tool(call, color = "light") {
18858
18862
  </details>`;
18859
18863
  }
18860
18864
  function cluster(calls, open, color) {
18861
- const failed = calls.filter((call) => call.status === "error").length;
18865
+ const failed2 = calls.filter((call) => call.status === "error").length;
18862
18866
  const running2 = calls.some((call) => call.status === "running");
18863
18867
  return b`<details class="cluster" ?open=${open || running2}>
18864
18868
  <summary>
18865
18869
  <span class="chevron" aria-hidden="true">▸</span>
18866
18870
  <span class="title">${calls.length} steps</span>
18867
18871
  <span class="names">${[...new Set(calls.map((call) => call.name))].join(" \xB7 ")}</span>
18868
- ${failed ? b`<span class="state failed">${toolStates.error[1]}${failed} failed</span>` : A}
18872
+ ${failed2 ? b`<span class="state failed">${toolStates.error[1]}${failed2} failed</span>` : A}
18869
18873
  </summary>
18870
18874
  ${calls.map((call) => tool(call, color))}
18871
18875
  </details>`;
@@ -18987,7 +18991,7 @@ function part(entry, handlers, showThinking) {
18987
18991
  default:
18988
18992
  return b`<div class="error-card" role="alert">
18989
18993
  <div class="error-text"><span class="lead">${entry.message}</span>${entry.detail ? b`<span class="detail">${entry.detail}</span>` : A}</div>
18990
- ${entry.action ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action=${entry.action} ?disabled=${handlers.readOnly} @click=${() => handlers.action(entry.action)}>${actionLabels[entry.action]}</swc-button>` : A}
18994
+ ${entry.action ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action=${entry.action} ?disabled=${handlers.readOnly} @click=${() => handlers.action(entry.action)}>${actionLabel(entry.action, handlers, "")}</swc-button>` : A}
18991
18995
  </div>`;
18992
18996
  }
18993
18997
  }
@@ -19083,7 +19087,11 @@ function assistant(message, name, model, handlers, showThinking, suggestion = nu
19083
19087
  ${status(message)}
19084
19088
  ${parts(
19085
19089
  message.parts,
19086
- { ...handlers, action: (action) => handlers.action(action, message.id) },
19090
+ {
19091
+ ...handlers,
19092
+ action: (action) => handlers.action(action, message.id),
19093
+ dropping: () => handlers.dropping(message.id)
19094
+ },
19087
19095
  showThinking,
19088
19096
  message.status === "streaming"
19089
19097
  )}
@@ -19126,7 +19134,7 @@ function system(message, handlers) {
19126
19134
  "Error",
19127
19135
  b`<div class="error-card system-error" role="alert" data-id=${message.id}>
19128
19136
  <div class="error-text"><strong>${message.title}</strong><span>${message.text}</span></div>
19129
- ${message.action ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action=${message.action} ?disabled=${handlers.readOnly} @click=${() => handlers.action(message.action, message.id)}>${actionLabels[message.action]}</swc-button>` : A}
19137
+ ${message.action ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action=${message.action} ?disabled=${handlers.readOnly} @click=${() => handlers.action(message.action, message.id)}>${actionLabel(message.action, handlers, message.id)}</swc-button>` : A}
19130
19138
  </div>`
19131
19139
  );
19132
19140
  }
@@ -19699,6 +19707,20 @@ var navigation = /* @__PURE__ */ new Set([
19699
19707
  "PageUp",
19700
19708
  "PageDown"
19701
19709
  ]);
19710
+ var failed = (message) => message.role === "assistant" ? message.status === "error" : message.role === "system" && message.kind === "error";
19711
+ function failedTurns(messages, messageId) {
19712
+ const at = messages.findIndex((message) => message.id === messageId);
19713
+ const turns = messages.flatMap(
19714
+ (message, index) => message.role === "user" && index < at ? [index] : []
19715
+ );
19716
+ const ids = [messageId];
19717
+ for (let turn = turns.length - 1; turn > 0; turn--) {
19718
+ const error = messages.slice(turns[turn - 1], turns[turn]).find(failed);
19719
+ if (!error) break;
19720
+ ids.push(error.id);
19721
+ }
19722
+ return ids;
19723
+ }
19702
19724
  var touched = false;
19703
19725
  document.addEventListener(
19704
19726
  "pointerdown",
@@ -19791,6 +19813,7 @@ var SliccChat = class extends ThemedElement {
19791
19813
  answer: (questionId, answer) => this.model?.agent.answer(this.#id(), questionId, answer),
19792
19814
  resolve: (messageId, state) => this.model?.agent.resolveLick(this.#id(), messageId, state),
19793
19815
  action: (action, messageId) => this.#action(action, messageId),
19816
+ dropping: (messageId) => failedTurns(this.model.agent.messages(this.#id()), messageId).length,
19794
19817
  open: (path) => this.dispatchEvent(
19795
19818
  new CustomEvent("open-file", { detail: { path }, bubbles: true, composed: true })
19796
19819
  ),
@@ -19880,9 +19903,15 @@ var SliccChat = class extends ThemedElement {
19880
19903
  return this.model?.agent.list().find((agent) => agent.id === id);
19881
19904
  }
19882
19905
  async #rewind(id, messageId) {
19883
- const restored = await this.model?.agent.rewind?.(id, messageId);
19906
+ const messages = this.model?.agent.messages(id) ?? [];
19907
+ const at = messages.findIndex((message) => message.id === messageId);
19908
+ const latest = messages.findLast(
19909
+ (message, index) => index < at && message.role === "user"
19910
+ );
19911
+ const first2 = failedTurns(messages, messageId).at(-1);
19912
+ const restored = await this.model?.agent.rewind?.(id, first2);
19884
19913
  if (!restored) return;
19885
- this.renderRoot.querySelector("slicc-composer")?.restore(restored);
19914
+ this.renderRoot.querySelector("slicc-composer")?.restore(latest ? { text: latest.text, attachments: latest.attachments } : restored);
19886
19915
  }
19887
19916
  #action(action, messageId = "") {
19888
19917
  const model = this.model;
@@ -40697,7 +40726,7 @@ var File = class {
40697
40726
  if (this.editor != null) throw new Error("File.__completeEditSession: detach the editor before completing the session");
40698
40727
  const sessionAnnotationsCurrent = editSessionAnnotations?.current;
40699
40728
  let acceptedFile;
40700
- let failed = false;
40729
+ let failed2 = false;
40701
40730
  let failure2;
40702
40731
  if (editor == null) throw new Error("File.__completeEditSession: editor is required for completion");
40703
40732
  const completedFile = { ...editSessionFile };
@@ -40716,7 +40745,7 @@ var File = class {
40716
40745
  acceptedFile = completedFile;
40717
40746
  }
40718
40747
  } catch (error) {
40719
- failed = true;
40748
+ failed2 = true;
40720
40749
  failure2 = error;
40721
40750
  }
40722
40751
  if (installResult && acceptedFile != null) {
@@ -40728,7 +40757,7 @@ var File = class {
40728
40757
  this.fileRenderer.endEditSession(settledFile);
40729
40758
  if (renderedFile != null && settledFile != null && renderedFile !== settledFile && areFileTargetsEqual(renderedFile, settledFile)) this.renderedFile = settledFile;
40730
40759
  if (installResult && this.fileContainer != null) this.rerender();
40731
- if (failed) throw failure2;
40760
+ if (failed2) throw failure2;
40732
40761
  }
40733
40762
  applyDocumentChange(textDocument, newLineAnnotations) {
40734
40763
  const editSessionFile = this.editSession?.file;
@@ -46982,7 +47011,7 @@ var FileDiff = class {
46982
47011
  let acceptedDiff;
46983
47012
  let acceptedOldFile = null;
46984
47013
  let acceptedNewFile = null;
46985
- let failed = false;
47014
+ let failed2 = false;
46986
47015
  let failure2;
46987
47016
  if (editor == null) throw new Error("FileDiff.__completeEditSession: editor is required for completion");
46988
47017
  const completedDiff = cloneFileDiffMetadata(editSessionDiff);
@@ -47013,7 +47042,7 @@ var FileDiff = class {
47013
47042
  acceptedNewFile = event2.newFile;
47014
47043
  }
47015
47044
  } catch (error) {
47016
- failed = true;
47045
+ failed2 = true;
47017
47046
  failure2 = error;
47018
47047
  }
47019
47048
  if (installResult && acceptedDiff != null) {
@@ -47026,7 +47055,7 @@ var FileDiff = class {
47026
47055
  }
47027
47056
  this.editSession = void 0;
47028
47057
  if (installResult && this.fileContainer != null) this.rerender();
47029
- if (failed) throw failure2;
47058
+ if (failed2) throw failure2;
47030
47059
  }
47031
47060
  /**
47032
47061
  * Run the session-end recompute: restore recompute-shaped hunks (a