@ai-ecoverse/slicc-spectrum 1.10.0 → 1.12.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.
package/README.md CHANGED
@@ -134,7 +134,7 @@ Text is Adobe Clean and code Spectrum's Source Code Pro. Source Code Pro (OFL) i
134
134
  | `<slicc-app>` | The shell: header with the agent picker, the View menu and the theme switch, rails, a `<slicc-dock>`, and a status bar. Saves the dock layout per screen class to `storage` (default `localStorage`) under `layoutKey`. |
135
135
  | `<slicc-dock>` | Generic. [dockview-core](https://dockview.dev/) 8 with a theme mapped to Spectrum tokens, in its own shadow root. Panels come from `factories` (`name → (params) => HTMLElement`). `open`, `close`, `has`, `content`, `focusPanel`, `cycleGroup`, `cycleTab`, `toJSON`, `restore`, `clear`, and the full `api`. Tabs have a context menu (close, close others, float, maximize). Events: `layout-change`, `active-panel-change`, `panel-close`. |
136
136
  | `<slicc-agents>` | Cones with their scoops, status, context fill and unread count. Selecting one makes it the active agent. |
137
- | `<slicc-chat>` | One thread's conversation (its `agent`, or the active agent if unset), by day: user messages (with attachments, tagged as steered or follow-up by `delivered`, or delegated from another cone), assistant messages (Markdown with tables, task lists, quotes, code and images; thinking; tool calls, grouped into a collapsible cluster from three in a row; media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts; delegations; link previews; errors with a fix-it action), standalone tool results, system messages (compaction markers, error cards, notices) and licks, SLICC's events into a cone, on every channel. Permission requests are allowed or denied in place. |
137
+ | `<slicc-chat>` | One thread's conversation (its `agent`, or the active agent if unset), by day: user messages (with attachments, tagged as steered or follow-up by `delivered`, or delegated from another cone), assistant messages (Markdown with tables, task lists, quotes, code and images; thinking; tool calls, grouped into a collapsible cluster from three in a row; media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts; delegations; link previews; errors with a fix-it action; a content-filter stop offers **Drop the last turn**, which rewinds that turn and puts its prompt back into the composer), standalone tool results, system messages (compaction markers, error cards, notices) and licks, SLICC's events into a cone, on every channel. Permission requests are allowed or denied in place. |
138
138
  | `<slicc-composer>` | The message box. <kbd>Enter</kbd> sends, or steers a running reply: the message joins after the current tool round, without interrupting; <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>Enter</kbd> queues a follow-up that runs after the reply and can be withdrawn; <kbd>Shift</kbd>+<kbd>Enter</kbd> adds a line; <kbd>Tab</kbd> takes the suggested follow-up; <kbd>↑</kbd>/<kbd>↓</kbd> at the start or end walk this agent's history; <kbd>Esc</kbd> stops. `/` completes commands (`/clear`, `/compact`, `/model`, `/thinking`, `/scoop`, `/stop`, `/theme`) and their arguments, `@` mentions agents and files. Attach from the computer, from SLICC's files, a browser screenshot or a shared secret, or paste and drop files (25 MB each). Queued messages wait above it, to send now or drop. Model and thinking pickers, and dictation where the browser has speech recognition. Drafts are kept per agent. |
139
139
  | `<slicc-files>` | The file system as a `<slicc-file-tree>`, with pending changes as git status. Opening a file opens it in a tab. |
140
140
  | `<slicc-file-view>` | One file (`path`), highlighted, with its pending change and a link to the diff. |
@@ -162,7 +162,7 @@ Keys: <kbd>Alt</kbd>+<kbd>1</kbd>… opens and focuses a panel, <kbd>F6</kbd> an
162
162
 
163
163
  | Port | Later backed by | |
164
164
  | :--- | :--- | :--- |
165
- | `agent` | `@ai-ecoverse/slicc-agent` | Cones and scoops, the active agent, conversations, `send` (with attachments, as a send, a steer or a queued follow-up) and `stop`, the queue, suggestions, answers to questions, permission decisions, compaction, clearing, the model per agent and new scoops. Assistant messages stream: the same message is re-emitted as its parts grow and its tool calls go from `running` to `done`. |
165
+ | `agent` | `@ai-ecoverse/slicc-agent` | Cones and scoops, the active agent, conversations, `send` (with attachments, as a send, a steer or a queued follow-up) and `stop`, the queue, suggestions, answers to questions, permission decisions, compaction, clearing, the model per agent and new scoops. The optional `rewind(agentId, messageId)` drops the user turn before that message and everything after it, and resolves with the turn's prompt (text and attachments) for the composer, or `null`. Assistant messages stream: the same message is re-emitted as its parts grow and its tool calls go from `running` to `done`. |
166
166
  | `files` | slicc-kernel's OPFS | `list`, `read`, `write`, `remove`, and pending changes with their before and after text (`accept`, `revert`). |
167
167
  | `terminals` | slicc-kernel's terminal API | Terminal sessions; `backend(id)` returns a `TerminalBackend` for `<slicc-terminal>`. |
168
168
  | `browser` | `@ai-ecoverse/slicc-cdp` | Tabs, the active tab, `open`, `navigate`, `close`, `screenshot`. |
@@ -14,6 +14,19 @@ export function toKelvin(celsius: number): number {
14
14
  return Math.round((celsius + 273.15) * 100) / 100;
15
15
  }
16
16
  `;
17
+ function filtered() {
18
+ return [
19
+ {
20
+ type: "part",
21
+ part: {
22
+ type: "error",
23
+ message: "The model's content filter stopped this reply.",
24
+ detail: "Provider stopped with: content_filtered",
25
+ action: "drop-turn"
26
+ }
27
+ }
28
+ ];
29
+ }
17
30
  function test() {
18
31
  return [
19
32
  { type: "thinking", text: "Run the whole suite first, then look at anything that fails." },
@@ -190,6 +203,7 @@ function script(prompt, attachments = []) {
190
203
  const text = prompt.toLowerCase();
191
204
  const suggestion = suggestions.find(([pattern]) => pattern.test(text))?.[1] ?? "Run the tests";
192
205
  if (attachments.length > 0) return { steps: look(attachments), suggestion };
206
+ if (/\bforbidden\b/.test(text)) return { steps: filtered(), suggestion };
193
207
  if (/\b(ask|choose|decide)\b/.test(text)) return { steps: ask(), suggestion };
194
208
  if (/\btests?\b/.test(text)) return { steps: test(), suggestion };
195
209
  if (/\b(fix|edit|add|change)\b/.test(text)) return { steps: edit(), suggestion };
@@ -411,7 +425,7 @@ var DummyAgent = class extends Emitter {
411
425
  this.#post(agentId, reply);
412
426
  }
413
427
  }
414
- reply.status = run.stopped ? "stopped" : "done";
428
+ reply.status = run.stopped ? "stopped" : reply.parts.some((item) => item.type === "error") ? "error" : "done";
415
429
  reply.usage = {
416
430
  input: 1200 + prompt.length * 4,
417
431
  output: 180 + reply.parts.length * 60,
@@ -495,6 +509,25 @@ var DummyAgent = class extends Emitter {
495
509
  this.#changed();
496
510
  });
497
511
  }
512
+ async rewind(agentId, messageId) {
513
+ const messages = this.#messages.get(agentId);
514
+ const at3 = messages?.findIndex((message) => message.id === messageId) ?? -1;
515
+ if (!messages || at3 < 0) return null;
516
+ const turn = messages.slice(0, at3).findLastIndex((message) => message.role === "user");
517
+ if (turn < 0) return null;
518
+ const user = messages[turn];
519
+ messages.splice(turn);
520
+ messages.push({
521
+ id: `rewound-${Date.now()}`,
522
+ role: "system",
523
+ kind: "notice",
524
+ title: "Rewound 1 turn",
525
+ text: "Its prompt is back in the composer.",
526
+ createdAt: Date.now()
527
+ });
528
+ this.emit("messages", agentId);
529
+ return { text: user.text, ...user.attachments ? { attachments: user.attachments } : {} };
530
+ }
498
531
  clear(agentId) {
499
532
  if (!this.#messages.has(agentId)) return;
500
533
  this.stop(agentId);
@@ -2538,7 +2571,8 @@ function events() {
2538
2571
  },
2539
2572
  {
2540
2573
  type: "error",
2541
- message: "The model returned 413: the request is larger than its context window.",
2574
+ message: "The request is too large for this model.",
2575
+ detail: "The model returned 413: the request is larger than its context window.",
2542
2576
  action: "change-model"
2543
2577
  }
2544
2578
  ]