@ai-ecoverse/slicc-spectrum 1.27.1 → 1.27.3
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 +2 -2
- package/dist/slicc-ui.js +18 -7
- package/dist/slicc-ui.js.map +2 -2
- package/dist/types/app/composer.d.ts +2 -0
- package/dist/types/model/types.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -135,7 +135,7 @@ Text is Adobe Clean Spectrum VF, falling back to Adobe Clean, and code is Spectr
|
|
|
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
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, each with its input (a shell command after `$`), an optional `meta` such as a timeout, and an edit's `diff` shown as a diff view; 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; a lick's `severity` (`warn` or `error`) turns its channel badge into a notice or negative one with an alert icon. Permission requests are allowed or denied in place. |
|
|
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. |
|
|
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`, `/freeze` when the port can freeze, `/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. With `files.mountFolder`, **Mount a folder…** (`data-action="mount-folder"`) mounts a local folder, then selects and expands it in the tree; with `files.mounts`, a **Mounted** strip lists the mount points, each with **Eject** (`data-action="eject"`, `data-path` the mount point) when the port has `eject`. A failed mount or eject shows its message under the bar. |
|
|
140
140
|
| `<slicc-file-view>` | One file (`path`), highlighted, with its pending change and a link to the diff. |
|
|
141
141
|
| `<slicc-changes>` | Pending changes with their author. Opens the diff, accepts or reverts one change or all of them. |
|
|
@@ -194,7 +194,7 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
194
194
|
|
|
195
195
|
| Port | Later backed by | |
|
|
196
196
|
| :--- | :--- | :--- |
|
|
197
|
-
| `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`. The optional `drop(agentId)` removes a scoop (its files stay), and `createCone(name)` resolves with a new cone; the dummy rejects a cone name that is taken. Assistant messages stream: the same message is re-emitted as its parts grow and its tool calls go from `running` to `done`. |
|
|
197
|
+
| `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`. The optional `drop(agentId)` removes a scoop (its files stay), and `createCone(name)` resolves with a new cone; the dummy rejects a cone name that is taken. `freeze(agentId)` is optional too: without it, `/freeze` and the Freezer's freeze button don't show. Assistant messages stream: the same message is re-emitted as its parts grow and its tool calls go from `running` to `done`. |
|
|
198
198
|
| `files` | slicc-kernel's OPFS | `list`, `read`, `write`, `remove`, and pending changes with their before and after text (`accept`, `revert`). The optional `mountFolder()` asks for a local folder and resolves with its mount point (for example `/mnt/photos`), or `null` when the user cancels; the panel calls it synchronously in the click, so the port can call `showDirectoryPicker()`. The optional `mounts()` lists the mount points, and `eject(path)` unmounts one (the folder stays on disk). The port emits `mounts` and then `files` after every mount and eject, including those made from the shell. |
|
|
199
199
|
| `terminals` | slicc-kernel's terminal API | Terminal sessions; `backend(id)` returns a `TerminalBackend` for `<slicc-terminal>`. |
|
|
200
200
|
| `browser` | `@ai-ecoverse/slicc-cdp` | Tabs, the active tab, `open`, `navigate`, `close`, `screenshot`. |
|
package/dist/slicc-ui.js
CHANGED
|
@@ -19815,15 +19815,20 @@ var SliccChat = class extends ThemedElement {
|
|
|
19815
19815
|
}),
|
|
19816
19816
|
model.agent.on("agents", () => this.requestUpdate()),
|
|
19817
19817
|
model.agent.on("messages", (agentId) => {
|
|
19818
|
-
if (agentId === this.#id()) this.#refresh(
|
|
19818
|
+
if (agentId === this.#id()) this.#refresh(this.#sent(agentId));
|
|
19819
19819
|
}),
|
|
19820
19820
|
model.agent.on("message", ({ agentId }) => {
|
|
19821
|
-
if (agentId === this.#id()) this.#refresh(
|
|
19821
|
+
if (agentId === this.#id()) this.#refresh(this.#sent(agentId));
|
|
19822
19822
|
})
|
|
19823
19823
|
];
|
|
19824
19824
|
}
|
|
19825
19825
|
#stuck = true;
|
|
19826
19826
|
#last = 0;
|
|
19827
|
+
#tail = "";
|
|
19828
|
+
#sent(agentId) {
|
|
19829
|
+
const last = this.model?.agent.messages(agentId).at(-1);
|
|
19830
|
+
return last?.role === "user" && last.id !== this.#tail && (last.origin ?? "user") === "user";
|
|
19831
|
+
}
|
|
19827
19832
|
#resize = new ResizeObserver(() => this.#pin());
|
|
19828
19833
|
#log() {
|
|
19829
19834
|
return this.renderRoot.querySelector(".log");
|
|
@@ -19967,6 +19972,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
19967
19972
|
const agent = this.#agent();
|
|
19968
19973
|
this.#handlers.readOnly = !!agent?.frozen;
|
|
19969
19974
|
const messages = agent ? this.model?.agent.messages(agent.id) ?? [] : [];
|
|
19975
|
+
this.#tail = messages.at(-1)?.id ?? "";
|
|
19970
19976
|
return b`
|
|
19971
19977
|
<header>
|
|
19972
19978
|
${agent ? this.#meta(agent) : b`<span>No agent</span>`}
|
|
@@ -20837,6 +20843,9 @@ e25("swc-icon-clock", o60);
|
|
|
20837
20843
|
|
|
20838
20844
|
// src/app/composer.ts
|
|
20839
20845
|
var limit = 25 * 1024 * 1024;
|
|
20846
|
+
function available(model) {
|
|
20847
|
+
return commands.filter((command) => command.available?.(model) ?? true);
|
|
20848
|
+
}
|
|
20840
20849
|
var commands = [
|
|
20841
20850
|
{
|
|
20842
20851
|
name: "clear",
|
|
@@ -20877,7 +20886,8 @@ var commands = [
|
|
|
20877
20886
|
{
|
|
20878
20887
|
name: "freeze",
|
|
20879
20888
|
detail: "Archive this cone and its scoops in the freezer",
|
|
20880
|
-
|
|
20889
|
+
available: (model) => typeof model.agent.freeze === "function",
|
|
20890
|
+
run: (model, id) => model.agent.freeze?.(id)
|
|
20881
20891
|
},
|
|
20882
20892
|
{
|
|
20883
20893
|
name: "theme",
|
|
@@ -21200,7 +21210,7 @@ var SliccComposer = class extends ModelElement {
|
|
|
21200
21210
|
const attachments = this.attachments.filter((attachment2) => !attachment2.error);
|
|
21201
21211
|
if (!model || !text2 && attachments.length === 0) return;
|
|
21202
21212
|
const command = text2.match(/^\/(\w+)(?:\s+(.*))?$/);
|
|
21203
|
-
const known = command &&
|
|
21213
|
+
const known = command && available(model).find((candidate) => candidate.name === command[1]);
|
|
21204
21214
|
this.value = "";
|
|
21205
21215
|
this.attachments = [];
|
|
21206
21216
|
this.popup = null;
|
|
@@ -21293,12 +21303,13 @@ var SliccComposer = class extends ModelElement {
|
|
|
21293
21303
|
#choices(kind, query) {
|
|
21294
21304
|
const model = this.model;
|
|
21295
21305
|
if (kind === "command") {
|
|
21296
|
-
const
|
|
21306
|
+
const usable = available(model);
|
|
21307
|
+
const builtins = usable.map((command) => ({
|
|
21297
21308
|
value: command.name,
|
|
21298
21309
|
label: `/${command.name}`,
|
|
21299
21310
|
detail: command.detail
|
|
21300
21311
|
}));
|
|
21301
|
-
const own4 = model.agent.commands(this.#agent).filter((command) => !
|
|
21312
|
+
const own4 = model.agent.commands(this.#agent).filter((command) => !usable.some((builtin) => builtin.name === command.name)).map((command) => ({
|
|
21302
21313
|
value: command.name,
|
|
21303
21314
|
label: `/${command.name}`,
|
|
21304
21315
|
detail: command.description,
|
|
@@ -21715,7 +21726,7 @@ var SliccFreezer = class extends ModelElement {
|
|
|
21715
21726
|
const active = model?.agent.list().find((agent) => agent.id === model.agent.active());
|
|
21716
21727
|
return b`<div class="bar">
|
|
21717
21728
|
<span>${cones.length} frozen ${cones.length === 1 ? "cone" : "cones"}</span><span class="spacer"></span>
|
|
21718
|
-
${active?.kind === "cone" && !active.frozen ? b`<swc-action-button size="s" quiet @click=${() => model
|
|
21729
|
+
${active?.kind === "cone" && !active.frozen && model?.agent.freeze ? b`<swc-action-button size="s" quiet @click=${() => model.agent.freeze?.(active.id)}>Freeze ${active.name}</swc-action-button>` : ""}
|
|
21719
21730
|
</div>
|
|
21720
21731
|
<div class="list">
|
|
21721
21732
|
${cones.length ? cones.map((cone) => this.#card(cone)) : b`<div class="note">Nothing frozen. Freeze a cone to archive it with its scoops.</div>`}
|