@ai-ecoverse/slicc-spectrum 2.7.0 → 2.8.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 +4 -4
- package/dist/slicc-dummy.js +8 -0
- package/dist/slicc-dummy.js.map +2 -2
- package/dist/slicc-ui.js +84 -52
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/tool-title.d.ts +3 -0
- package/dist/types/dummy/agent.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -280,15 +280,15 @@ Files dragged anywhere over the pane (not text, links or the dock's own drags) s
|
|
|
280
280
|
A message's time shows only when it is at least two minutes newer than the last time shown, and the first one after each day separator always shows; a hidden time stays for screen readers (`time.sr` with `datetime`, or `.sr` on licks and cards), and a meta row left empty isn't rendered.
|
|
281
281
|
User messages (with attachments and a quiet timestamp, `time.when`, by that rule; the reader's own carry no name or delivery tag, while `data-mode` and `data-delivered` still say how they went; a message from another cone, a follower or a guest says who sent it, and an agent's request carries its name and an Agent badge; a message from another agent, an agent's request or a message `from` a cone (`origin` `agent`, or `from` set without `origin` `follower` or `guest`), is `[data-remote]`: a subtle indigo bubble and a 🤖 pill on its bottom edge, `aria-hidden` since the byline names the sender; people, the reader included, never get it), assistant messages (with the time by that rule, and the model only on the first reply and whenever it changes from the previous one, `.meta .model` with the usage as its tooltip; without a model the usage is the time's tooltip, and with neither it is the reply's own (`.reply[title]`); the turn always carries the usage as its `aria-description`; the cone's name isn't repeated; Markdown with tables, task lists, quotes, code and images, fenced code highlighted like the Files view (below); thinking; tool calls, as the steps of the reply's response status (below); media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts (as decision cards, below); delegations; link previews; errors with a fix-it action, as a grey card (`.error-card[role=alert]`, `data-id` on system errors) inset by a wide margin on each side, a narrower one under 480 px: a red alert icon, the title in bold, the detail subdued and the action on the right, or under the detail below 360 px, announced as "Error: " and the title; an error with `action: 'login'` and an `account` (an `Account.id`) signs that account in: **Log in** calls `settings.connect(account)` synchronously in the click when the account is OAuth or needs no secret or fields, so a sign-in pop-up opens within the user gesture, and otherwise, or when `accounts()` doesn't have it, opens Settings at its row; the card follows the account's status from `accounts` (`data-login` is `idle`, `signing-in` or `connected`): while it is `signing-in` or `connect` is pending, **Log in** is pending and reads “Signing in…”, for an OAuth account the detail reads “Continue in the sign-in window that opened.” and, after `SliccChat.closedAfter` (20 s, since a closed window can't be detected), “Closed the sign-in window? Cancel, then Log in again.”, with **Cancel** (`data-action="cancel-login"`) when the port has `cancel`; once `connected`, the card is no longer an alert: a neutral info icon in the detail colour replaces the red one, the "Error: " prefix goes, the title reads “Signed in to {provider} again.” (the account's `provider`), the detail reads “Signed in. Retry to send it again.” (a polite status) and the button becomes **Retry**, which sends the last prompt again only when clicked; a rejected `connect` shows its message as negative help text (`[data-error=login]`), keeps **Log in** and adds a quiet **Open settings** (`data-action="settings"`) to that account; without an `account`, **Log in** opens Settings at Accounts, and watch-only and guest seats keep their gating; a content-filter stop offers **Drop the last turn**, which rewinds that turn and puts its prompt back into the composer; when the turns right before it failed too, the button reads **Drop N failed turns** and rewinds to before the first of them, putting the latest prompt back), system messages (error cards; compactions and notices, rewinds and model changes included, as full-width dividers with a line on each side, like the day: a compaction shows only its title, its `text` kept for screen readers, one that lost messages (`state: 'fallback'`, by default "Compaction failed, transcript truncated", or `discarded`, "Context discarded") an alert icon in the negative colour, and a notice its title and text on one line, `role="note"`; a divider that wraps keeps a short line on each side) and licks, SLICC's events into a cone, on every channel, on the right (`.lick-turn`): a byline with the title and the time by the two-minute rule, then a dashed box (`.lick[data-id][data-channel]`) with the text and the count (×3); emoji pills on its bottom edge (`.reactions .reaction`, `aria-hidden`, each named by its `title`) give the channel (⏰ Schedule, 🪝 Webhook, ✨ Sprinkle, 💬 Cone message, …; a channel spectrum does not know falls back to 📎 Notice) and the outcome (👍 Allowed, 👎 Denied, also said in the box's hidden text).
|
|
282
282
|
A lick with a body is a `details.lick` whose head (`summary.lick-head`, with a quiet chevron that turns when open) toggles it with a click, <kbd>Enter</kbd> or <kbd>Space</kbd>; clicking the body doesn't close it.
|
|
283
|
-
A reply's tool calls are the steps of its response status (`swc-response-status[slot=status]`, `data-id` the reply's), at the top of the reply: one `swc-response-status-step` per call (`id` `run-` and the call's id, `data-tool`, `data-status`, `data-kind`, and `data-id` the message the call came from), labelled with the tool and
|
|
283
|
+
A reply's tool calls are the steps of its response status (`swc-response-status[slot=status]`, `data-id` the reply's), at the top of the reply: one `swc-response-status-step` per call (`id` `run-` and the call's id, `data-tool`, `data-status`, `data-kind`, and `data-id` the message the call came from), labelled with a human `title` when the agent sent one (without repeating the tool name), or with the tool name and a raw title when the title still looks like a command or path, `active` while it runs, `complete` when done and `stopped` when it failed or was cancelled, which its label says in words (" · Failed", " · Cancelled").
|
|
284
284
|
The status keeps `data-action="open-cluster"` and each step `data-action="open-run"` with `data-target` the call's id: clicking the host from script opens it, as the old strip's buttons did, and opening a step opens its status too.
|
|
285
285
|
A step whose call has anything to show labels itself with a button (`.run-toggle`, `aria-expanded`, `aria-controls`) that opens the call under the step's row, at the full width of the column and indented to the step's text, in our own region (`.run-detail#detail-` and the call's id, `role="listitem"`, `hidden` while closed, `data-target` the call's id), not in Spectrum's 340 px description; the step carries `data-open` while it's open. The region is the call: its input (a shell command after `$`), an edit's `diff` shown as a diff view, its output, both kept on their lines and scrolling sideways rather than wrapping, with its ANSI styles shown (bold, dim, italic, underline, inverse, and the 16, 256 and truecolor foregrounds and backgrounds; the 16 foregrounds come from `--slicc-terminal-color-0` to `-15` when an embedder sets them, else the terminal panel's light tokens, which adapt in dark (so a card in dark uses Spectrum's colors, not the panel's VS Code ones); the 16 backgrounds are Spectrum's subtle tints under the default text, black a solid grey under the lightest grey, so text keeps 4.5:1; a 256 or truecolor background shows as a tint, blended toward the card (12% in light, 25% in dark), and one too close to the card to see, such as white on a light card, gets a grey tint toward the card's text instead; a 256 or truecolor foreground keeps its hue but moves toward black or white until it has 4.5:1 on the card or its tint, and other text on such a tint takes the card's text colour under the same floor; the card and its text colour are read once for light and once for dark, so the colours follow the theme through `light-dark()`, and a chat that can't read them (outside the Spectrum theme, where it shows the colours as sent) tries again only when it reconnects or the theme changes; dim subdues default text and turns a bright color into its normal one) and every other escape stripped, a partial escape at the end of streamed output waiting for the rest (the model still sees the raw bytes, and a copy gets the text without escapes), an `image`, such as a screenshot, an optional `meta` such as a timeout, the time a joined call ran ("Ran at 16:12", `.ran`, by the two-minute rule), and its `notes` (`{ severity, text }`, such as "Exited with code 5" or "Full output in /tmp/…") as lines under the output, `li[data-note][data-severity]`: `error` with an alert icon in the negative colour, `warn` with an alert icon and `info` with an info icon, both subdued.
|
|
286
|
-
The status's header is always one line: while the reply streams or the agent works on the run, it is `active`, with the
|
|
287
|
-
Done, the status stays as `complete`, also when a call never left `running` (the step stays `active`): one call reads as its tool and
|
|
286
|
+
The status's header is always one line: while the reply streams or the agent works on the run, it is `active`, with the model's cluster label when one has arrived (or the last one for this run), else the running call's human title (or the last call), and that call's kind as its loader, and each label stays for at least a second before the next one replaces it, so streamed arguments don't make it flicker; a reply without calls shows "Generating response" only until its first text or visible thinking.
|
|
287
|
+
Done, the status stays as `complete`, also when a call never left `running` (the step stays `active`): one call reads as its human title, or the tool and a raw title, more as the model's label for them or, until there is one, a count of the two most common kinds and the rest, such as "3 commands, 1 read" or "5 commands, 4 agent steps and 9 more", led by any failures ("1 failed, 1 cancelled · "), so the one-line header never cuts them off; a stopped reply says so (its label slot stays empty so Spectrum can show that).
|
|
288
288
|
Every call of a reply is in its one status, above its text; a later reply with text starts a new run, while a standalone tool message or a reply with only tool calls, streaming or done, joins the status of the run before it on the same day (hidden thinking and source links don't count as text), so a turn never collapses when its calls finish and past messages never move down.
|
|
289
289
|
A label never shows what may be a secret: after a sensitive key (`token`, `secret`, `password`, `api_key`, `Authorization` and the like) with `=`, `:` or a flag's space, at a word that starts with a known secret prefix (`ghp_`, `sk-`, `AKIA`, `xoxb-`, `eyJ` and others), or, while the call runs, at a last word that could still grow into one, it ends in "…"; the step's description shows the call as the agent sent it.
|
|
290
290
|
Spectrum notes: a step's description is at most 340 px wide (`.swc-ResponseStatusStep-detail` has no part or custom property for it), which is why a call opens in our own full-width region instead; a public hook for that width would let it use Spectrum's description. Two Spectrum behaviours are worked around: the header label is one line on a token line height (`--_swc-response-status-label-line-size` and `line-height: 0` on the status), because its cross-fade otherwise lays the label out 1.4 px off its settled place; and the label slot is never empty while active, because Spectrum then shows the running step's own label, which changes with every streamed chunk.
|
|
291
|
-
The label for two or more calls comes from the agent port's optional `toolLabel(agentId, callIds)`, asked once for each agent port, agent and set of calls; while a growing run waits for its new label, it keeps its last one.
|
|
291
|
+
The label for two or more calls, and for a single call whose title still looks like a raw command, comes from the agent port's optional `toolLabel(agentId, callIds)`, asked once for each agent port, agent and set of calls while the run is active or done; while a growing run waits for its new label, it keeps its last one.
|
|
292
292
|
Open licks, statuses and steps hold for every view of the chat on the same model, so a layout switch keeps them.
|
|
293
293
|
A lick's `severity` (`warn` or `error`) adds an alert icon to its byline, a coloured edge to its box and a spoken prefix.
|
|
294
294
|
A lick's optional `summary` (one plain line) replaces its `text` in the box and wraps instead of being cut, and its optional `report` (a file path) adds **Open the report** (`data-action="open-report"`, which fires `open-file` with the path) to the expanded lick, so a lick with only a `report` expands too.
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -2073,6 +2073,7 @@ var labels = {
|
|
|
2073
2073
|
"Count the routes": "Walk through every kind of tool",
|
|
2074
2074
|
"Ask the API for Lisbon": "Compare the docs with the live API",
|
|
2075
2075
|
"Switch the page to Celsius": "Move the forecast docs to Celsius, then build and test the site",
|
|
2076
|
+
"git status --short": "Summarise the working tree",
|
|
2076
2077
|
[fixtures(`${repro}/round2/fixtures`)]: replayLabel
|
|
2077
2078
|
};
|
|
2078
2079
|
function label(title) {
|
|
@@ -2725,6 +2726,13 @@ var DummyAgent = class extends Emitter {
|
|
|
2725
2726
|
starting() {
|
|
2726
2727
|
return this.#starting;
|
|
2727
2728
|
}
|
|
2729
|
+
setTitle(agentId, title) {
|
|
2730
|
+
const agent = this.#agent(agentId);
|
|
2731
|
+
if (!agent) return;
|
|
2732
|
+
if (title === void 0) delete agent.title;
|
|
2733
|
+
else agent.title = title;
|
|
2734
|
+
this.#changed();
|
|
2735
|
+
}
|
|
2728
2736
|
setStarting(line) {
|
|
2729
2737
|
this.#arrival++;
|
|
2730
2738
|
this.#starting = line || null;
|