@ai-ecoverse/slicc-spectrum 1.94.1 → 1.95.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 +6 -4
- package/dist/{chunk-2R4DLSKG.js → chunk-QGY4KBEB.js} +21 -7
- package/dist/{chunk-2R4DLSKG.js.map → chunk-QGY4KBEB.js.map} +2 -2
- package/dist/slicc-dummy.js +7 -5
- package/dist/slicc-dummy.js.map +2 -2
- package/dist/slicc-kernel-model.js +1 -1
- package/dist/slicc-ui.js +11565 -4892
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/markdown.d.ts +1 -31
- package/dist/types/dummy/index.d.ts +4 -1
- package/dist/types/dummy/providers.d.ts +1 -1
- package/dist/types/dummy/settings.d.ts +3 -1
- package/dist/types/dummy.d.ts +1 -0
- package/dist/types/model/types.d.ts +2 -0
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -412,8 +412,9 @@ Without `store: 'vault'` or `vault.put`, the key goes to `connect(id, secret)` a
|
|
|
412
412
|
A `show-surface` whose `section` is an account id scrolls to that row and focuses its button, and `accounts` scrolls to the Accounts heading (`h2[data-section=accounts]`).
|
|
413
413
|
With a `vault` port, **Secrets** (`<slicc-secrets>`) follows.
|
|
414
414
|
With `providers()`, Accounts lists only the added providers (`.accounts[data-group=providers]`), connected first, then expired, signing in and not connected; each row adds **Remove** (`data-action="remove-account"`, a quiet delete icon named “Remove {provider}”) when the port has `remove`, which asks “Remove {provider}?” (“Its key is deleted from the vault. Models from it stop working.”, “Its sign-in is deleted from the vault…” for OAuth, only “Models from it stop working.” for a local one) with a destructive **Remove** and Cancel focused, then runs `vault.remove(vaultName, 'model')` for a vaulted key and `settings.remove(id)`, stopping with the vault's error inline when it refuses; Disconnect removes the same record and keeps the row.
|
|
415
|
-
|
|
416
|
-
|
|
415
|
+
Before the row goes, Remove closes its tooltip and waits for it: a Gen2 `swc-tooltip` that updates after its row is removed throws (`getRootNode().getElementById is not a function`), which a pointer click on Remove without the vault used to trigger.
|
|
416
|
+
An account with `blocked: 'cors-free-transport'`, which the port sets while the current transport can't reach it, says “Needs the SLICC extension or CLI, because the browser blocks direct requests to it.” under its row (`.notes [data-notice][data-blocked]`) with an inline **Set up** link (`data-action="setup-network"`) that sends `show-surface` `{ id: 'network', section: 'whole' }`, so Network opens at Get the whole web; its Connect, Reconnect and Save are disabled, and a connected one keeps its key and identity, reads **Unreachable** (a notice light with the word) and keeps Disconnect and Remove. When `blocked` clears, through the `accounts` and `providers` events, the notice and Set up go and everything enables again; `needs` alone shows nothing. An OAuth account that is signing in says “Continue in the sign-in window that opened.”, then, after `SliccChat.closedAfter`, “Closed the sign-in window? Cancel, then Log in again.” (`[data-signing]`).
|
|
417
|
+
**Add a provider** (`data-action="add-provider"`, a quiet button under the list) opens a modal picker (`dialog.picker[data-picker=pick]`): **Search providers** filters `providers()` in their order by every word of the name, id and description; each row (`.option[data-provider][data-auth][role=option]`) shows the name, the `description` and a hint (API key, Sign in, Endpoint and key, On this device), and, while it is `blocked`, “Needs the SLICC extension or CLI” with **Set up** (`.option[data-blocked]`); added providers read **Added**, and added and blocked ones can't be picked by click, Enter or Space (`aria-disabled`; the arrows still reach them, and Tab reaches Set up); no match reads “No provider matches “{q}”.”. Down arrow moves from the search to the rows, Up, Down, Home and End walk them, typing goes back to the search, Enter or Space picks, Enter in the search picks the first match that isn't added, and Escape closes and gives focus back to **Add a provider**.
|
|
417
418
|
Picking one opens **Add {name}** (`dialog.picker[data-picker=connect]`, `.step[data-step=<auth>]`): `api-key` and `fields` get the key form (the vault form when there is one, `vault.put(vaultName ?? recordName, key, undefined, { kind: 'model', provider: id })`), with the provider's `fields` and **Get a key** (`data-action="get-key"`, `keyUrl` in a new tab); **Connect** stays disabled until the key and the required fields are filled; a `customBase` field whose value is an `https:` URL is bound to the key's record after its `put` and before `connect`, with `vault.endpoints({ add: { model: [{ name, url }] } })` (`name` is the record's, `vaultName ?? recordName`; without a vault record nothing is bound) (a bare name, such as an Azure resource, isn't), a refusal shows on that field and `connect` doesn't run, a changed URL (against the field's `value`, else the one this page bound) is one call that removes the old and adds the new, and a bare value only removes the old; a rejected `connect` reverses that call and shows on that field when it names it as a whole word (or https, URL, port or userinfo); **Remove** leaves the URLs to `vault.remove`, which drops them with the record; the saved `value`s prefill the fields and count as filled; `oauth` gets **Sign in** (`data-action="sign-in"`), which calls `connect(id)` within the click, then reads “Signing in…” with Cancel and the same window hints; `local` says “SLICC connects to {name} on this device.” and offers **Connect**. **Back** returns to the list. A rejected `connect` shows its message inline and keeps the form and its fields, clearing only the key; once the account is `connected`, the picker closes and focus lands on its row.
|
|
418
419
|
Without `providers()`, Accounts is as before.
|
|
419
420
|
When the model for new cones was moved off a provider that isn't set up, a quiet note under its picker (`p[data-switched][role=status]`) says “Switched to {model} because the previous model's provider isn't set up.” until a model is picked.
|
|
@@ -731,7 +732,7 @@ Later backed by: local storage.
|
|
|
731
732
|
Theme, model, thinking level, composer and diff preferences, the models on offer, and accounts.
|
|
732
733
|
A model can say it is its provider's `default`.
|
|
733
734
|
Emit `settings` or `accounts` when the models on offer change.
|
|
734
|
-
The optional `providers()` returns the `ProviderOption`s that can be added (`{ id, name, description?, auth: 'api-key' | 'oauth' | 'fields' | 'local', fields?, keyUrl?, needs?, vaultName? }`, sorted by name, added ones included), with a `providers` event when they change; `id` is pi-ai's provider id and becomes the `Account.id`. With it, `accounts()` lists only added accounts, `connect(id, secret?, fields?)` adds one (`group: 'providers'`; a `fields` provider becomes an `api-key` account with `store: 'vault'` and only its non-secret `fields`), and the optional `remove(id)` drops one. `Account` adds `keyUrl`, `description` and `vaultName`, the vault record for its key (else pi-ai's environment-variable name).
|
|
735
|
+
The optional `providers()` returns the `ProviderOption`s that can be added (`{ id, name, description?, auth: 'api-key' | 'oauth' | 'fields' | 'local', fields?, keyUrl?, needs?, blocked?, vaultName? }`, sorted by name, added ones included), with a `providers` event when they change; `id` is pi-ai's provider id and becomes the `Account.id`. With it, `accounts()` lists only added accounts, `connect(id, secret?, fields?)` adds one (`group: 'providers'`; a `fields` provider becomes an `api-key` account with `store: 'vault'` and only its non-secret `fields`), and the optional `remove(id)` drops one. `Account` adds `keyUrl`, `description` and `vaultName`, the vault record for its key (else pi-ai's environment-variable name). `needs: 'cors-free-transport'` on either is static (the provider doesn't answer a browser); `blocked: 'cors-free-transport'` is live, set while the current transport can't reach it, and cleared by a `providers` and an `accounts` event when an extension or a linked slicc appears.
|
|
735
736
|
|
|
736
737
|
#### `changes` (optional)
|
|
737
738
|
|
|
@@ -980,7 +981,8 @@ Update this one to send prompts.", and shows a warning notice without a close bu
|
|
|
980
981
|
|
|
981
982
|
The kitchen sink's “docs-pass failed” card is an expired-session error for the invented `ai-adobe` account (Adobe AI, harbor-ops@example.com, `expired`, OAuth): **Log in** goes `signing-in`, then `connected` after a short wait, and the dummy records each `connect` in `settings.connects` (`{ id, gesture }`, whether `navigator.userActivation.isActive` was true at the call); inbox-triage's “Tickets connector” card names `mcp:tickets`, a token account, so its **Log in** opens Settings at that row; `createDummyModel({ login: 'fail' })` (`?login=fail` on `/ui/`) makes OAuth sign-ins reject with “The sign-in window was closed before it finished.”
|
|
982
983
|
`createDummyModel({ providers: 'none' })` (`?providers=none` on `/ui/`) starts with no model provider connected: `models()` offers only the models of connected accounts, and connecting OpenAI offers the invented GPT-6 and GPT-6 mini (its `default`).
|
|
983
|
-
`createDummyModel({ providers: 'all' })` (`?providers=all` on `/ui/`) adds `providers()` and `remove` with 14 invented providers (`providerFixtures` from `/dummy`): API keys for Anthropic, Cerebras, Groq, Mistral, OpenAI and OpenRouter, OAuth for Adobe AI, GitHub Copilot and OpenAI Codex, fields for Amazon Bedrock (region
|
|
984
|
+
`createDummyModel({ providers: 'all' })` (`?providers=all` on `/ui/`) adds `providers()` and `remove` with 14 invented providers (`providerFixtures` from `/dummy`): API keys for Anthropic, Cerebras, Groq, Mistral, OpenAI and OpenRouter, OAuth for Adobe AI, GitHub Copilot and OpenAI Codex, fields for Amazon Bedrock (region), Azure OpenAI (endpoint, a `customBase`, and deployment) and Cloudflare (account id, CORS-free, its own `vaultName`), and Ollama and LM Studio on this device; today's rows start as added, with Amazon Bedrock and a connected Ollama (`providerAccounts(accounts)`, `providerAccount(option)`). `connect` adds a provider and drops it again when it fails or is cancelled, a key or field starting with `bad` is refused (“{name} didn’t accept that key.”), an endpoint without `https://` is refused, and `remove` drops it.
|
|
985
|
+
`createDummyModel({ providers: 'all', transport: 'none' })` (`?providers=all&transport=none`) has no CORS-free transport: every provider with `needs` is also `blocked`, and Cloudflare starts connected, so it reads Unreachable. `model.settings.setTransport('extension')` (or `'link'`) clears `blocked` live, with a `providers` and an `accounts` event, and `setTransport('none')` sets it again.
|
|
984
986
|
|
|
985
987
|
`createDummyModel({ monitor: 'agent' })` (`?monitor=agent` on `/ui/`) adds the agent's Tasks (a tree by `depth`), Processes and Recent problems sections to the monitor, and its Running vital.
|
|
986
988
|
Like slicc-agent's snapshot, the dummy's vitals are the budget, Spend, Active agents, Processes and Process memory (both with a `series`) and Fullest context.
|
|
@@ -1568,7 +1568,6 @@ var options = [
|
|
|
1568
1568
|
description: "Claude and more through AWS",
|
|
1569
1569
|
auth: "fields",
|
|
1570
1570
|
keyUrl: "https://console.aws.example/bedrock/api-keys",
|
|
1571
|
-
needs: "cors-free-transport",
|
|
1572
1571
|
fields: accounts.find((account) => account.id === "amazon-bedrock")?.fields
|
|
1573
1572
|
},
|
|
1574
1573
|
{
|
|
@@ -1692,10 +1691,11 @@ function providerAccount(option) {
|
|
|
1692
1691
|
...option.keyUrl ? { keyUrl: option.keyUrl } : {},
|
|
1693
1692
|
...option.description ? { description: option.description } : {},
|
|
1694
1693
|
...option.needs ? { needs: option.needs } : {},
|
|
1694
|
+
...option.blocked ? { blocked: option.blocked } : {},
|
|
1695
1695
|
...option.vaultName ? { vaultName: option.vaultName } : {}
|
|
1696
1696
|
};
|
|
1697
1697
|
}
|
|
1698
|
-
function providerAccounts(rows) {
|
|
1698
|
+
function providerAccounts(rows, transport) {
|
|
1699
1699
|
const added = (id, patch) => ({
|
|
1700
1700
|
...providerAccount(providerFixtures.find((option) => option.id === id)),
|
|
1701
1701
|
...patch
|
|
@@ -1709,6 +1709,7 @@ function providerAccounts(rows) {
|
|
|
1709
1709
|
return [
|
|
1710
1710
|
...providers,
|
|
1711
1711
|
added("ollama", { status: "connected", identity: "On this device" }),
|
|
1712
|
+
...transport ? [added("cloudflare", { status: "connected", identity: "API key" })] : [],
|
|
1712
1713
|
...servers
|
|
1713
1714
|
];
|
|
1714
1715
|
}
|
|
@@ -1746,13 +1747,17 @@ var DummySettings = class extends Emitter {
|
|
|
1746
1747
|
#signIns = /* @__PURE__ */ new Map();
|
|
1747
1748
|
#gated;
|
|
1748
1749
|
#fails;
|
|
1750
|
+
#transport;
|
|
1751
|
+
#options = [];
|
|
1749
1752
|
connects = [];
|
|
1750
1753
|
providers;
|
|
1751
1754
|
remove;
|
|
1752
|
-
constructor(defaults2, models2, accounts2, storage, clock2, keys = [dummySettingsKey], gated = false, login, providers) {
|
|
1755
|
+
constructor(defaults2, models2, accounts2, storage, clock2, keys = [dummySettingsKey], gated = false, login, providers, transport) {
|
|
1753
1756
|
super();
|
|
1757
|
+
this.#transport = transport;
|
|
1754
1758
|
if (providers) {
|
|
1755
|
-
this
|
|
1759
|
+
this.#options = providers;
|
|
1760
|
+
this.providers = () => this.#transport === "none" ? providers.map((option) => this.#block(option)) : providers;
|
|
1756
1761
|
this.remove = async (id) => this.#drop(id);
|
|
1757
1762
|
}
|
|
1758
1763
|
this.#fails = login === "fail";
|
|
@@ -1788,7 +1793,16 @@ var DummySettings = class extends Emitter {
|
|
|
1788
1793
|
return this.#models.filter((option) => live.has(option.provider));
|
|
1789
1794
|
}
|
|
1790
1795
|
accounts() {
|
|
1791
|
-
return this.#accounts.map((account) => ({ ...account }));
|
|
1796
|
+
return this.#accounts.map((account) => this.#block({ ...account }));
|
|
1797
|
+
}
|
|
1798
|
+
#block(row) {
|
|
1799
|
+
if (this.#transport !== "none" || !row.needs) return row;
|
|
1800
|
+
return { ...row, blocked: row.needs };
|
|
1801
|
+
}
|
|
1802
|
+
setTransport(transport) {
|
|
1803
|
+
this.#transport = transport;
|
|
1804
|
+
if (this.providers) this.emit("providers", this.providers());
|
|
1805
|
+
this.emit("accounts", this.accounts());
|
|
1792
1806
|
}
|
|
1793
1807
|
#set(id, patch) {
|
|
1794
1808
|
this.#accounts = this.#accounts.map(
|
|
@@ -1802,7 +1816,7 @@ var DummySettings = class extends Emitter {
|
|
|
1802
1816
|
this.emit("accounts", this.accounts());
|
|
1803
1817
|
}
|
|
1804
1818
|
#add(id) {
|
|
1805
|
-
const option = this.
|
|
1819
|
+
const option = this.#options.find((candidate) => candidate.id === id);
|
|
1806
1820
|
if (!option || this.#accounts.some((account) => account.id === id)) return false;
|
|
1807
1821
|
this.#accounts = [...this.#accounts, providerAccount(option)];
|
|
1808
1822
|
this.emit("accounts", this.accounts());
|
|
@@ -1894,4 +1908,4 @@ export {
|
|
|
1894
1908
|
dummySettingsKey,
|
|
1895
1909
|
DummySettings
|
|
1896
1910
|
};
|
|
1897
|
-
//# sourceMappingURL=chunk-
|
|
1911
|
+
//# sourceMappingURL=chunk-QGY4KBEB.js.map
|