@ai-ecoverse/slicc-spectrum 2.7.0 → 2.9.0

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-AIE26XNA.js";
9
+ } from "./chunk-OEIRN47D.js";
10
10
  import {
11
11
  Emitter
12
12
  } from "./chunk-T5NHW4KC.js";
package/dist/slicc-ui.js CHANGED
@@ -14414,48 +14414,6 @@ var o63 = class extends a8 {
14414
14414
  };
14415
14415
  e26("swc-icon-info-circle", o63);
14416
14416
 
14417
- // src/app/guard.ts
14418
- var prefixes = [
14419
- "sk-",
14420
- "sk_",
14421
- "rk_",
14422
- "pk_live",
14423
- "ghp_",
14424
- "gho_",
14425
- "ghu_",
14426
- "ghs_",
14427
- "ghr_",
14428
- "github_pat_",
14429
- "glpat-",
14430
- "xoxa-",
14431
- "xoxb-",
14432
- "xoxp-",
14433
- "xoxs-",
14434
- "AKIA",
14435
- "ASIA",
14436
- "AIza",
14437
- "npm_",
14438
- "pypi-",
14439
- "hf_",
14440
- "eyJ",
14441
- "-----BEGIN"
14442
- ];
14443
- var keyed = /(?:(?:[\w-]*(?:token|secret|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[\w-]*|\b(?:auth|authorization)\b)["']?\s*[:=]\s*|(?:^|\s)--?[\w-]*(?:token|secret|password|api-key|key)\s+|\bbearer\s+)/gi;
14444
- var word = /[^\s'"=:,;(){}[\]`]+/g;
14445
- function guard(text4, growing = false) {
14446
- let cut = text4.length;
14447
- for (const match of text4.matchAll(keyed)) cut = Math.min(cut, match.index + match[0].length);
14448
- for (const match of text4.matchAll(word)) {
14449
- const token = match[0];
14450
- const last = growing && match.index + token.length === text4.length;
14451
- const risky = prefixes.some(
14452
- (prefix) => token.startsWith(prefix) || last && token.length >= 2 && prefix.startsWith(token)
14453
- );
14454
- if (risky) cut = Math.min(cut, match.index);
14455
- }
14456
- return cut < text4.length ? `${text4.slice(0, cut).trimEnd()} \u2026` : text4;
14457
- }
14458
-
14459
14417
  // node_modules/mdast-util-to-string/lib/index.js
14460
14418
  var emptyOptions = {};
14461
14419
  function toString(value, options2) {
@@ -33316,6 +33274,69 @@ var signInCss = i`
33316
33274
  }
33317
33275
  `;
33318
33276
 
33277
+ // src/app/guard.ts
33278
+ var prefixes = [
33279
+ "sk-",
33280
+ "sk_",
33281
+ "rk_",
33282
+ "pk_live",
33283
+ "ghp_",
33284
+ "gho_",
33285
+ "ghu_",
33286
+ "ghs_",
33287
+ "ghr_",
33288
+ "github_pat_",
33289
+ "glpat-",
33290
+ "xoxa-",
33291
+ "xoxb-",
33292
+ "xoxp-",
33293
+ "xoxs-",
33294
+ "AKIA",
33295
+ "ASIA",
33296
+ "AIza",
33297
+ "npm_",
33298
+ "pypi-",
33299
+ "hf_",
33300
+ "eyJ",
33301
+ "-----BEGIN"
33302
+ ];
33303
+ var keyed = /(?:(?:[\w-]*(?:token|secret|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[\w-]*|\b(?:auth|authorization)\b)["']?\s*[:=]\s*|(?:^|\s)--?[\w-]*(?:token|secret|password|api-key|key)\s+|\bbearer\s+)/gi;
33304
+ var word = /[^\s'"=:,;(){}[\]`]+/g;
33305
+ function guard(text4, growing = false) {
33306
+ let cut = text4.length;
33307
+ for (const match of text4.matchAll(keyed)) cut = Math.min(cut, match.index + match[0].length);
33308
+ for (const match of text4.matchAll(word)) {
33309
+ const token = match[0];
33310
+ const last = growing && match.index + token.length === text4.length;
33311
+ const risky = prefixes.some(
33312
+ (prefix) => token.startsWith(prefix) || last && token.length >= 2 && prefix.startsWith(token)
33313
+ );
33314
+ if (risky) cut = Math.min(cut, match.index);
33315
+ }
33316
+ return cut < text4.length ? `${text4.slice(0, cut).trimEnd()} \u2026` : text4;
33317
+ }
33318
+
33319
+ // src/app/tool-title.ts
33320
+ var shellLead = /^(?:(?:git|npm|npx|pnpm|yarn|bun|node|deno|python3?|pip3?|curl|wget|ls|cd|cat|rm|mv|cp|chmod|chown|mkdir|touch|tar|zip|unzip|docker|kubectl|gh|wrangler|lsof|find|grep|rg|sed|awk|ssh|scp|rsync|make|cargo|go|ruby|perl|php|java|javac|swift|xcodebuild|brew|apt|yum|sudo|env|export|echo|printf|true|false|test|bash|sh|zsh|fish|source)(?=\s|$)|(?:\.\/))/;
33321
+ function rawTitle(title2) {
33322
+ const text4 = title2.trim();
33323
+ if (!text4) return false;
33324
+ if (text4.length > 80) return true;
33325
+ if (/[|;&><`]|\$\(|&&|\|\|/.test(text4)) return true;
33326
+ if (/^-[A-Za-z0-9]/.test(text4)) return true;
33327
+ if (/^[a-z]/.test(text4) && shellLead.test(text4)) return true;
33328
+ if (!/\s/.test(text4) && (/^[./~]/.test(text4) || /\.[A-Za-z0-9]+$/.test(text4))) return true;
33329
+ return false;
33330
+ }
33331
+ function headline(call) {
33332
+ const title2 = call.title.trim();
33333
+ const name = call.name.trim();
33334
+ const growing = call.status === "running";
33335
+ if (!title2) return guard(name, growing);
33336
+ if (rawTitle(title2)) return guard(`${name} ${title2}`.trim(), growing);
33337
+ return guard(title2, growing);
33338
+ }
33339
+
33319
33340
  // src/app/messages.ts
33320
33341
  var alone = { calls: [], live: false };
33321
33342
  var lickLabels = {
@@ -33569,9 +33590,6 @@ function step(call, context, id) {
33569
33590
  </div>`
33570
33591
  ];
33571
33592
  }
33572
- function headline(call) {
33573
- return guard(`${call.name} ${call.title}`.trim(), call.status === "running");
33574
- }
33575
33593
  function phase(status2, calls, live, said = false, stopped = false) {
33576
33594
  if (status2 === "stopped" || stopped) return "stopped";
33577
33595
  if (!calls.length) return status2 === "streaming" && !said ? "active" : null;
@@ -35288,7 +35306,19 @@ var SliccVaultValue = class extends i2 {
35288
35306
  };
35289
35307
 
35290
35308
  // src/app/composer.ts
35291
- var limit = 25 * 1024 * 1024;
35309
+ var limit = 100 * 1024 * 1024;
35310
+ function tooLarge(bytes) {
35311
+ return `Too large: attachments are limited to ${size3(bytes)}`;
35312
+ }
35313
+ function smallest(limits = {}) {
35314
+ return Math.min(limit, limits.image ?? limit, limits.text ?? limit, limits.file ?? limit);
35315
+ }
35316
+ function together(bytes) {
35317
+ return `These attachments add up to more than ${size3(bytes)}; send them in separate messages.`;
35318
+ }
35319
+ function carried(attachment2) {
35320
+ return attachment2.url !== void 0 || attachment2.text !== void 0 || attachment2.path === void 0;
35321
+ }
35292
35322
  var startingKey = "slicc-spectrum.starting";
35293
35323
  var names = (files) => files.map((file) => file.name).join(", ");
35294
35324
  function reattach(files) {
@@ -35512,9 +35542,9 @@ var commands = [
35512
35542
  name: "thinking",
35513
35543
  detail: "Set the thinking level",
35514
35544
  args: () => ["off", "low", "medium", "high"].map((value) => ({ value, label: value, detail: "" })),
35515
- run: (model, _id, arg) => {
35545
+ run: (model, id, arg) => {
35516
35546
  if (["off", "low", "medium", "high"].includes(arg))
35517
- model.settings.update({ thinking: arg });
35547
+ model.agent.setThinking(id, arg);
35518
35548
  }
35519
35549
  },
35520
35550
  {
@@ -36032,6 +36062,7 @@ var SliccComposer = class extends ThemedElement {
36032
36062
  }, linger);
36033
36063
  }
36034
36064
  updated(changed2) {
36065
+ this.#guard();
36035
36066
  if (changed2.has("popup"))
36036
36067
  this.renderRoot.querySelector('.item[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
36037
36068
  }
@@ -36143,11 +36174,42 @@ ${row.text}` : row.text;
36143
36174
  #busy() {
36144
36175
  return this.model?.agent.busy(this.#agent) ?? false;
36145
36176
  }
36177
+ #limits() {
36178
+ return this.model?.agent.attachmentLimits?.() ?? {};
36179
+ }
36180
+ #cap(attachment2) {
36181
+ return Math.min(limit, this.#limits()[attachment2.kind] ?? limit);
36182
+ }
36183
+ #over(attachment2) {
36184
+ return carried(attachment2) && attachment2.size > (attachment2.error ? limit : this.#cap(attachment2));
36185
+ }
36186
+ #problem(attachment2) {
36187
+ return attachment2.error ?? (this.#over(attachment2) ? tooLarge(this.#cap(attachment2)) : void 0);
36188
+ }
36189
+ #together() {
36190
+ const total = this.#limits().total;
36191
+ if (total === void 0) return null;
36192
+ const sum = this.attachments.filter((attachment2) => !attachment2.error && carried(attachment2)).reduce((bytes, attachment2) => bytes + attachment2.size, 0);
36193
+ return sum > total ? together(total) : null;
36194
+ }
36195
+ #blocked() {
36196
+ return this.attachments.some((attachment2) => this.#over(attachment2)) || !!this.#together();
36197
+ }
36198
+ #guard() {
36199
+ const field3 = this.#field;
36200
+ const blocked2 = this.#blocked();
36201
+ void field3.updateComplete.then(() => {
36202
+ const button = field3.shadowRoot.querySelector(
36203
+ ".swc-PromptField-send, .swc-PromptField-stop"
36204
+ );
36205
+ button.disabled = (field3.disabled || blocked2) && !field3.generating;
36206
+ });
36207
+ }
36146
36208
  send(mode2 = "send") {
36147
36209
  const model = this.model;
36148
36210
  const text4 = this.value.trim();
36149
36211
  const attachments = this.attachments.filter((attachment2) => !attachment2.error);
36150
- if (!model || !text4 && attachments.length === 0 || this.#held()) return;
36212
+ if (!model || !text4 && attachments.length === 0 || this.#held() || this.#blocked()) return;
36151
36213
  if (model.seat) {
36152
36214
  this.#propose(model, text4);
36153
36215
  return;
@@ -36203,7 +36265,7 @@ ${this.value}` : text4;
36203
36265
  added.push({
36204
36266
  ...base,
36205
36267
  kind: "file",
36206
- error: `Too large: attachments are limited to ${size3(limit)}`
36268
+ error: tooLarge(limit)
36207
36269
  });
36208
36270
  continue;
36209
36271
  }
@@ -36733,27 +36795,28 @@ ${this.value}` : text4;
36733
36795
  this.dictating = true;
36734
36796
  recognition.start();
36735
36797
  }
36736
- #thumbnail(attachment2) {
36737
- if (attachment2.kind === "image" && attachment2.url && !attachment2.error)
36798
+ #thumbnail(attachment2, problem) {
36799
+ if (attachment2.kind === "image" && attachment2.url && !problem)
36738
36800
  return b`<img slot="thumbnail" src=${attachment2.url} alt="" />`;
36739
- const icon = attachment2.error ? b`<swc-icon-alert-triangle></swc-icon-alert-triangle>` : attachment2.kind === "secret" ? b`<swc-icon-lock></swc-icon-lock>` : attachment2.kind === "text" ? b`<swc-icon-file-text></swc-icon-file-text>` : b`<swc-icon-file></swc-icon-file>`;
36740
- return b`<span slot="thumbnail" class="thumb" ?data-error=${!!attachment2.error} aria-hidden="true">${icon}</span>`;
36801
+ const icon = problem ? b`<swc-icon-alert-triangle></swc-icon-alert-triangle>` : attachment2.kind === "secret" ? b`<swc-icon-lock></swc-icon-lock>` : attachment2.kind === "text" ? b`<swc-icon-file-text></swc-icon-file-text>` : b`<swc-icon-file></swc-icon-file>`;
36802
+ return b`<span slot="thumbnail" class="thumb" ?data-error=${!!problem} aria-hidden="true">${icon}</span>`;
36741
36803
  }
36742
36804
  #attachment(attachment2) {
36743
- const detail = attachment2.error ? this.#errorDetail(attachment2.error) : attachment2.kind === "secret" ? "Secret" : size3(attachment2.size);
36805
+ const problem = this.#problem(attachment2);
36806
+ const detail = problem ? this.#errorDetail(problem) : attachment2.kind === "secret" ? "Secret" : size3(attachment2.size);
36744
36807
  return b`<swc-upload-attachment
36745
36808
  slot="attachment"
36746
36809
  type="card"
36747
36810
  dismissible
36748
36811
  data-id=${attachment2.id}
36749
36812
  data-kind=${attachment2.kind}
36750
- ?data-error=${!!attachment2.error}
36751
- title=${attachment2.error ?? attachment2.path ?? attachment2.name}
36813
+ ?data-error=${!!problem}
36814
+ title=${problem ?? attachment2.path ?? attachment2.name}
36752
36815
  @swc-upload-attachment-dismiss=${() => this.detach(attachment2.id)}
36753
36816
  >
36754
- ${this.#thumbnail(attachment2)}
36817
+ ${this.#thumbnail(attachment2, problem)}
36755
36818
  <span slot="title">${attachment2.name}</span>
36756
- <span slot="subtitle" class=${attachment2.error ? "failed" : ""} title=${attachment2.error ?? A}>${detail}</span>
36819
+ <span slot="subtitle" class=${problem ? "failed" : ""} title=${problem ?? A}>${detail}</span>
36757
36820
  </swc-upload-attachment>`;
36758
36821
  }
36759
36822
  #popup() {
@@ -36988,12 +37051,14 @@ ${this.value}` : text4;
36988
37051
  this.attachments.filter((attachment2) => !attachment2.error).map((attachment2) => attachment2.name)
36989
37052
  );
36990
37053
  const missing = (this.reattach ?? []).filter((file) => !back.has(file.name));
37054
+ const crowded = this.#together();
36991
37055
  return b`<div class="column" @drop=${this.#mark}>
36992
37056
  <span id="keys" class="sr" aria-hidden="true">${this.#instructions(busy)}</span>
36993
37057
  ${this.#hold()}
36994
37058
  ${this.#starters()}
36995
37059
  ${this.#queue()}
36996
37060
  ${this.#popup()}
37061
+ ${crowded ? b`<p class="send-error" role="alert" data-send-error="together"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${crowded}</span></p>` : A}
36997
37062
  <swc-prompt-field
36998
37063
  accessible-label="Message"
36999
37064
  loader=${this.#loader(busy)}
@@ -38556,7 +38621,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
38556
38621
  ${offered.length ? b`<sp-picker size="s" quiet label="Model" value=${agent.model} @change=${(event2) => model.agent.setModel(agent.id, event2.target.value)} @sp-opened=${this.#modelFilter.opened} @sp-closed=${this.#modelFilter.closed} @keydown=${this.#modelFilter.keys}>
38557
38622
  ${this.#modelFilter.items(offered)}
38558
38623
  </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>`}
38559
- <sp-picker size="s" quiet label="Thinking" value=${model.settings.get().thinking} @change=${(event2) => model.settings.update({ thinking: event2.target.value })}>
38624
+ <sp-picker size="s" quiet label="Thinking" value=${agent.thinking ?? model.settings.get().thinking} @change=${(event2) => model.agent.setThinking(agent.id, event2.target.value)}>
38560
38625
  <sp-menu-item value="off">No thinking</sp-menu-item>
38561
38626
  <sp-menu-item value="low">Think a little</sp-menu-item>
38562
38627
  <sp-menu-item value="medium">Think</sp-menu-item>
@@ -38645,7 +38710,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
38645
38710
  <swc-illustrated-message>
38646
38711
  <swc-icon-attach></swc-icon-attach>
38647
38712
  <h2 slot="heading">Drop files to attach</h2>
38648
- <span slot="description">Images, text and other files up to ${limit / 1024 / 1024} MB each join your next message. Folders can’t be attached.</span>
38713
+ <span slot="description">Images, text and other files up to ${Number((smallest(this.model?.agent.attachmentLimits?.()) / 1024 / 1024).toFixed(1))} MB each join your next message. Folders can’t be attached.</span>
38649
38714
  </swc-illustrated-message>
38650
38715
  </swc-dropzone>` : A}
38651
38716
  <p class="sr" role="status" data-announce="drop">${this.dropping ? "Drop to attach files to your message" : ""}</p>
@@ -39890,7 +39955,10 @@ function watchTitles(model, update) {
39890
39955
  const seen = /* @__PURE__ */ new Map();
39891
39956
  const check3 = (id) => {
39892
39957
  const agent = model.agent.list().find((candidate) => candidate.id === id);
39893
- if (!agent) return;
39958
+ if (!agent) {
39959
+ if (seen.delete(id)) update();
39960
+ return;
39961
+ }
39894
39962
  const title2 = agentTitle(model, agent);
39895
39963
  if (seen.get(id) === title2) return;
39896
39964
  seen.set(id, title2);
@@ -39898,7 +39966,12 @@ function watchTitles(model, update) {
39898
39966
  };
39899
39967
  const stops = [
39900
39968
  model.agent.on("messages", check3),
39901
- model.agent.on("message", ({ agentId }) => check3(agentId))
39969
+ model.agent.on("message", ({ agentId }) => check3(agentId)),
39970
+ model.agent.on("agents", (agents) => {
39971
+ const live = new Set(agents.map((agent) => agent.id));
39972
+ for (const id of seen.keys()) if (!live.has(id)) check3(id);
39973
+ for (const agent of agents) check3(agent.id);
39974
+ })
39902
39975
  ];
39903
39976
  return () => {
39904
39977
  for (const stop of stops) stop();
@@ -58060,9 +58133,14 @@ var SliccStatusLabel = class extends i2 {
58060
58133
  get #anchor() {
58061
58134
  return `${this.agent} ${this.calls[0]?.id ?? ""}`;
58062
58135
  }
58136
+ #needsLabel() {
58137
+ if (this.calls.length >= 2) return true;
58138
+ const only = this.calls[0];
58139
+ return !!only && rawTitle(only.title);
58140
+ }
58063
58141
  #ask() {
58064
58142
  const port = this.model?.agent;
58065
- if (this.calls.length < 2 || !port?.toolLabel) return;
58143
+ if (!this.#needsLabel() || !port?.toolLabel) return;
58066
58144
  const store2 = cache3(port);
58067
58145
  const key = this.#key;
58068
58146
  const anchor = this.#anchor;
@@ -58088,7 +58166,8 @@ var SliccStatusLabel = class extends i2 {
58088
58166
  return store2?.done.get(this.#key) ?? store2?.latest.get(this.#anchor) ?? "";
58089
58167
  }
58090
58168
  #wanted() {
58091
- const base = this.state === "complete" && this.#label() || this.text;
58169
+ if (this.state === "stopped") return this.text;
58170
+ const base = this.#label() || this.text;
58092
58171
  return base && this.note ? `${this.note} \xB7 ${base}` : base;
58093
58172
  }
58094
58173
  #cancel() {